Module: sip-router Branch: admorten/sca Commit: ceb7f0fa3c0da824cdd175de5fa6c17f26408131 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=ceb7f0fa...
Author: Andrew Mortensen admorten@isc.upenn.edu Committer: Andrew Mortensen admorten@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 * );