Module: sip-router
Branch: master
Commit: d528c27b6fa69530bfde4a6ce83c5d4dcc6499a5
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=d528c27…
Author: Andrew Mortensen <admorten(a)isc.upenn.edu>
Committer: Andrew Mortensen <admorten(a)isc.upenn.edu>
Date: Sun Mar 3 17:01:53 2013 -0500
sca: move SUBSCRIBE response handling to sca_subscription_reply
- create necessary headers, pass to newly generic sca_reply function.
---
modules/sca/sca_subscribe.c | 102 +++++++++++++++++++++++++++++++++----------
modules/sca/sca_subscribe.h | 5 ++
2 files changed, 83 insertions(+), 24 deletions(-)
diff --git a/modules/sca/sca_subscribe.c b/modules/sca/sca_subscribe.c
index 6337eba..904a3c5 100644
--- a/modules/sca/sca_subscribe.c
+++ b/modules/sca/sca_subscribe.c
@@ -1108,34 +1108,35 @@ sca_handle_subscribe( sip_msg_t *msg, char *p1, char *p2 )
if ( parse_headers( msg, HDR_EOH_F, 0 ) < 0 ) {
LM_ERR( "header parsing failed: bad request" );
- SCA_REPLY_ERROR( sca, 400, "Bad Request", msg );
+ SCA_SUB_REPLY_ERROR( sca, 400, "Bad Request", msg );
return( -1 );
}
if ( !STR_EQ( REQ_LINE( msg ).method, SCA_METHOD_SUBSCRIBE )) {
LM_ERR( "bad request method %.*s", STR_FMT( &REQ_LINE( msg ).method ));
- SCA_REPLY_ERROR( sca, 500, "Internal server error - config", msg );
+ SCA_SUB_REPLY_ERROR( sca, 500, "Internal server error - config", msg );
return( -1 );
}
if ( SCA_HEADER_EMPTY( msg->event )) {
- SCA_REPLY_ERROR( sca, 400, "Missing Event", msg );
+ SCA_SUB_REPLY_ERROR( sca, 400, "Missing Event", msg );
return( -1 );
}
event_type = sca_event_from_str( &msg->event->body );
if ( event_type == SCA_EVENT_TYPE_UNKNOWN ) {
- SCA_REPLY_ERROR( sca, 400, "Bad Event", msg );
+ SCA_SUB_REPLY_ERROR( sca, 400, "Bad Event", msg );
return( -1 );
}
if ( sca_subscription_from_request( sca, msg, event_type, &req_sub ) < 0 ) {
- SCA_REPLY_ERROR( sca, 400, "Bad Shared Call Appearance Request", msg );
+ SCA_SUB_REPLY_ERROR( sca, 400,
+ "Bad Shared Call Appearance Request", msg );
return( -1 );
}
if ( sca_subscription_copy_subscription_key( &req_sub, &sub_key ) < 0 ) {
- SCA_REPLY_ERROR( sca, 500,
- "Internal Server Error - copy dialog id", msg );
+ SCA_SUB_REPLY_ERROR( sca, 500, "Internal Server Error - "
+ "copy dialog id", msg );
goto done;
}
sca_subscription_print( &req_sub );
@@ -1156,13 +1157,13 @@ sca_handle_subscribe( sip_msg_t *msg, char *p1, char *p2 )
if ( call_info_hdr ) {
if ( sca_call_info_body_parse( &call_info_hdr->body,
&call_info ) < 0 ) {
- SCA_REPLY_ERROR( sca, 400, "Bad Request - "
+ SCA_SUB_REPLY_ERROR( sca, 400, "Bad Request - "
"Invalid Call-Info header", msg );
goto done;
}
app_idx = call_info.index;
} else {
- SCA_REPLY_ERROR( sca, 400, "Bad Request - "
+ SCA_SUB_REPLY_ERROR( sca, 400, "Bad Request - "
"missing Call-Info header", msg );
goto done;
}
@@ -1176,8 +1177,8 @@ sca_handle_subscribe( sip_msg_t *msg, char *p1, char *p2 )
if ( sub != NULL ) {
/* this will remove the subscription if expires == 0 */
if ( sca_subscription_update_unsafe( sca, sub, &req_sub, idx ) < 0 ) {
- SCA_REPLY_ERROR( sca, 500,
- "Internal Server Error - update subscription", msg );
+ SCA_SUB_REPLY_ERROR( sca, 500, "Internal Server Error - "
+ "update subscription", msg );
goto done;
}
@@ -1185,15 +1186,15 @@ sca_handle_subscribe( sip_msg_t *msg, char *p1, char *p2 )
if ( req_sub.expires == 0 ) {
/* release the seized appearance */
if ( call_info_hdr == NULL ) {
- SCA_REPLY_ERROR( sca, 400, "Bad Request - "
+ SCA_SUB_REPLY_ERROR( sca, 400, "Bad Request - "
"missing Call-Info header", msg );
goto done;
}
if ( sca_appearance_release_index( sca, &req_sub.target_aor,
call_info.index ) != SCA_APPEARANCE_OK ) {
- SCA_REPLY_ERROR( sca, 500, "Internal Server Error - "
- "release seized line", msg );
+ SCA_SUB_REPLY_ERROR( sca, 500, "Internal Server Error - "
+ "release seized line", msg );
goto done;
}
} else if ( SCA_STR_EMPTY( to_tag )) {
@@ -1201,11 +1202,12 @@ sca_handle_subscribe( sip_msg_t *msg, char *p1, char *p2 )
app_idx = sca_appearance_seize_index( sca, &req_sub.target_aor,
app_idx, &req_sub.subscriber );
if ( app_idx == SCA_APPEARANCE_INDEX_UNAVAILABLE ) {
- SCA_REPLY_ERROR( sca, 480, "Temporarily Unavailable", msg );
+ SCA_SUB_REPLY_ERROR( sca, 480,
+ "Temporarily Unavailable", msg );
goto done;
} else if ( app_idx < 0 ) {
- SCA_REPLY_ERROR( sca, 500, "Internal Server Error - "
- "seize appearance index", msg );
+ SCA_SUB_REPLY_ERROR( sca, 500,
+ "Internal Server Error - seize appearance index", msg );
goto done;
}
req_sub.index = app_idx;
@@ -1214,7 +1216,7 @@ sca_handle_subscribe( sip_msg_t *msg, char *p1, char *p2 )
} else {
/* in-dialog request, but we didn't find it. */
if ( !SCA_STR_EMPTY( to_tag )) {
- SCA_REPLY_ERROR( sca, 481,
+ SCA_SUB_REPLY_ERROR( sca, 481,
"Call Leg/Transaction Does Not Exist", msg );
goto done;
}
@@ -1224,10 +1226,11 @@ sca_handle_subscribe( sip_msg_t *msg, char *p1, char *p2 )
app_idx = sca_appearance_seize_index( sca, &req_sub.target_aor,
app_idx, &req_sub.subscriber );
if ( app_idx == SCA_APPEARANCE_INDEX_UNAVAILABLE ) {
- SCA_REPLY_ERROR( sca, 480, "Temporarily Unavailable", msg );
+ SCA_SUB_REPLY_ERROR( sca, 480,
+ "Temporarily Unavailable", msg );
goto done;
} else if ( app_idx < 0 ) {
- SCA_REPLY_ERROR( sca, 500, "Internal Server Error - "
+ SCA_SUB_REPLY_ERROR( sca, 500, "Internal Server Error - "
"seize appearance index", msg );
goto done;
}
@@ -1236,8 +1239,8 @@ sca_handle_subscribe( sip_msg_t *msg, char *p1, char *p2 )
if ( sca_subscription_save_unsafe( sca, &req_sub, idx,
SCA_SUBSCRIPTION_CREATE_OPT_DEFAULT ) < 0 ) {
- SCA_REPLY_ERROR( sca, 500,
- "Internal Server Error - save subscription", msg );
+ SCA_SUB_REPLY_ERROR( sca, 500, "Internal Server Error - "
+ "save subscription", msg );
goto done;
}
} else {
@@ -1252,9 +1255,9 @@ sca_handle_subscribe( sip_msg_t *msg, char *p1, char *p2 )
status = sca_ok_status_for_event( event_type );
status_text = sca_ok_text_for_event( event_type );
- if ( sca_reply( sca, status, status_text, event_type,
+ if ( sca_subscription_reply( sca, status, status_text, event_type,
req_sub.expires, msg ) < 0 ) {
- SCA_REPLY_ERROR( sca, 500, "Internal server error", msg );
+ SCA_SUB_REPLY_ERROR( sca, 500, "Internal server error", msg );
goto done;
}
@@ -1296,6 +1299,57 @@ done:
}
int
+sca_subscription_reply( sca_mod *scam, int status_code, char *status_msg,
+ int event_type, int expires, sip_msg_t *msg )
+{
+ str extra_headers = STR_NULL;
+ char hdr_buf[ 1024 ];
+ int len;
+
+ if ( event_type != SCA_EVENT_TYPE_CALL_INFO &&
+ event_type != SCA_EVENT_TYPE_LINE_SEIZE ) {
+ LM_ERR( "sca_subscription_reply: unrecognized event type %d",
+ event_type );
+ return( -1 );
+ }
+
+ if ( status_code < 300 ) {
+ /* Add Event, Contact, Allow-Events and Expires headers */
+ extra_headers.s = hdr_buf;
+ len = snprintf( extra_headers.s, sizeof( hdr_buf ),
+ "Event: %s%s", sca_event_name_from_type( event_type ), CRLF );
+ if ( len >= sizeof( hdr_buf ) || len < 0 ) {
+ LM_ERR( "sca_subscription_reply: extra headers too long" );
+ return( -1 );
+ }
+ extra_headers.len = len;
+
+ SCA_STR_APPEND_CSTR( &extra_headers, "Contact: " );
+ SCA_STR_APPEND( &extra_headers, &REQ_LINE( msg ).uri );
+ SCA_STR_APPEND_CSTR( &extra_headers, CRLF );
+
+ SCA_STR_COPY_CSTR( &extra_headers,
+ "Allow-Events: call-info, line-seize" CRLF );
+
+ len = snprintf( extra_headers.s + extra_headers.len,
+ sizeof( hdr_buf ) - extra_headers.len,
+ "Expires: %d%s", expires, CRLF );
+ if ( len >= sizeof( hdr_buf ) || len < 0 ) {
+ LM_ERR( "sca_subscription_reply: extra headers too long" );
+ return( -1 );
+ }
+ } else if ( status_code == 480 ) {
+ /* tell loser of line-seize SUBSCRIBE race to try again shortly */
+ extra_headers.s = hdr_buf;
+ len = snprintf( extra_headers.s, sizeof( hdr_buf ),
+ "Retry-After: %d%s", 1, CRLF );
+ extra_headers.len = len;
+ }
+
+ return( sca_reply( scam, status_code, status_msg, &extra_headers, msg ));
+}
+
+ int
sca_subscription_terminate( sca_mod *scam, str *aor, int event,
str *subscriber, int termination_state, int opts )
{
diff --git a/modules/sca/sca_subscribe.h b/modules/sca/sca_subscribe.h
index 2d36248..e238bf3 100644
--- a/modules/sca/sca_subscribe.h
+++ b/modules/sca/sca_subscribe.h
@@ -74,7 +74,12 @@ extern const str SCA_METHOD_SUBSCRIBE;
((sub1)->state >= SCA_SUBSCRIPTION_STATE_TERMINATED && \
(sub1)->state <= SCA_SUBSCRIPTION_STATE_TERMINATED_TIMEOUT )
+#define SCA_SUB_REPLY_ERROR( mod, scode, smsg, sreply ) \
+ sca_subscription_reply((mod), (scode), (smsg), \
+ SCA_EVENT_TYPE_CALL_INFO, -1, (sreply))
+
int sca_handle_subscribe( sip_msg_t *, char *, char * );
+int sca_subscription_reply( sca_mod *, int, char *, int, int, sip_msg_t * );
int sca_subscription_from_db_result( db1_res_t *, sca_subscription * );
int sca_subscriptions_restore_from_db( sca_mod * );