[sr-dev] git:master: sca: move SUBSCRIBE response handling to sca_subscription_reply

Andrew Mortensen admorten at isc.upenn.edu
Fri Mar 8 04:58:26 CET 2013


Module: sip-router
Branch: master
Commit: d528c27b6fa69530bfde4a6ce83c5d4dcc6499a5
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=d528c27b6fa69530bfde4a6ce83c5d4dcc6499a5

Author: Andrew Mortensen <admorten at isc.upenn.edu>
Committer: Andrew Mortensen <admorten at 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 * );




More information about the sr-dev mailing list