[sr-dev] git:admorten/sca: modules/sca: reconcile Contact and From URIs in ACK callback.

Andrew Mortensen admorten at isc.upenn.edu
Wed May 15 22:22:27 CEST 2013


Module: sip-router
Branch: admorten/sca
Commit: 0794a8ebc69771f8c0ffcc72d7eaca13f2e6e566
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=0794a8ebc69771f8c0ffcc72d7eaca13f2e6e566

Author: Andrew Mortensen <admorten at isc.upenn.edu>
Committer: Andrew Mortensen <admorten at isc.upenn.edu>
Date:   Wed May 15 16:13:23 2013 -0400

modules/sca: reconcile Contact and From URIs in ACK callback.

- fix Music-on-Hold in Polycoms when SCA caller has MoH enabled and SCA callee
  does SCA hold/pickup with identical To & From URIs. Previously, module would
  end up looking up an appearance for callee in ACK callback instead of caller.

---

 modules/sca/sca_call_info.c |   77 +++++++++++++++---------------------------
 modules/sca/sca_util.c      |   71 +++++++++++++++++++++++++++++++++++++++
 modules/sca/sca_util.h      |    2 +
 3 files changed, 101 insertions(+), 49 deletions(-)

diff --git a/modules/sca/sca_call_info.c b/modules/sca/sca_call_info.c
index 83ac855..344ea27 100644
--- a/modules/sca/sca_call_info.c
+++ b/modules/sca/sca_call_info.c
@@ -1441,7 +1441,6 @@ done:
     void
 sca_call_info_ack_cb( struct cell *t, int type, struct tmcb_params *params )
 {
-    struct to_body	*from;
     struct to_body	*to;
     str			from_aor = STR_NULL;
     str			to_aor = STR_NULL;
@@ -1450,24 +1449,18 @@ sca_call_info_ack_cb( struct cell *t, int type, struct tmcb_params *params )
 	return;
     }
 
-    if ( sca_get_msg_from_header( params->req, &from ) < 0 ) {
-	LM_ERR( "sca_call_info_ack_cb: failed to get From-header" );
-	return;
-    }
-    if ( sca_uri_extract_aor( &from->uri, &from_aor ) < 0 ) {
-	LM_ERR( "sca_call_info_ack_cb: failed to extract From AoR from %.*s",
-		STR_FMT( &from->uri ));
+    if ( sca_create_canonical_aor( params->req, &from_aor ) < 0 ) {
 	return;
     }
 
     if ( sca_get_msg_to_header( params->req, &to ) < 0 ) {
 	LM_ERR( "sca_call_info_ack_cb: failed to get To-header" );
-	return;
+	goto done;
     }
     if ( sca_uri_extract_aor( &to->uri, &to_aor ) < 0 ) {
 	LM_ERR( "sca_call_info_ack_cb: failed to extract To AoR from %.*s",
 		STR_FMT( &to->uri ));
-	return;
+	goto done;
     }
 
     sca_call_info_ack_from_handler( params->req, &from_aor, &to_aor );
@@ -1475,15 +1468,19 @@ sca_call_info_ack_cb( struct cell *t, int type, struct tmcb_params *params )
     if ( !sca_uri_is_shared_appearance( sca, &to_aor )) {
 	LM_DBG( "sca_call_info_ack_cb: %.*s is not a shared appearance",
 		STR_FMT( &to_aor ));
-	return;
+	goto done;
     }
 
     if ( sca_notify_call_info_subscribers( sca, &to_aor ) < 0 ) {
 	LM_ERR( "sca_call_info_ack_cb: failed to call-info "
 		"NOTIFY %.*s subscribers", STR_FMT( &to_aor ));
-	return;
+	goto done;
     }
 
+done:
+    if ( from_aor.s != NULL ) {
+	pkg_free( from_aor.s );
+    }
 }
 
     static int
@@ -1939,45 +1936,27 @@ sca_call_info_update( sip_msg_t *msg, char *p1, char *p2 )
     }
 
     /* reconcile mismatched Contact users and To/From URIs */
-    if ( sca_uri_extract_aor( &from->uri, &from_aor ) < 0 ) {
-	LM_ERR( "sca_uri_extract_aor failed to extract AoR from From URI %.*s",
-		STR_FMT( &from->uri ));
-	goto done;
-    }
-    if ( sca_uri_extract_aor( &to->uri, &to_aor ) < 0 ) {
-	LM_ERR( "sca_uri_extract_aor failed to extract AoR from To URI %.*s",
-		STR_FMT( &to->uri ));
-	goto done;
-    }
-
-    if ( !SCA_STR_EMPTY( &c_uri.user )) {
-	if ( msg->first_line.type == SIP_REQUEST ) {
-	    if ( !SCA_STR_EQ( &c_uri.user, &GET_FROM_PURI( msg )->user )) {
-		if ( sca_aor_create_from_info( &from_aor, c_uri.type,
-			&c_uri.user, &GET_FROM_PURI( msg )->host,
-			&GET_FROM_PURI( msg )->port ) < 0 ) {
-		    LM_ERR( "sca_aor_create_from_info from Contact %.*s "
-			    "and From URI %.*s failed",
-			    STR_FMT( &contact_uri ), STR_FMT( &from->uri ));
-		    goto done;
-		}
-
-		aor_flags |= SCA_CALL_INFO_UPDATE_FLAG_FROM_ALLOC;
-	    }
-	} else {
-	    if ( !SCA_STR_EQ( &c_uri.user, &GET_TO_PURI( msg )->user )) {
-		if ( sca_aor_create_from_info( &to_aor, c_uri.type,
-			&c_uri.user, &GET_TO_PURI( msg )->host,
-			&GET_TO_PURI( msg )->port ) < 0 ) {
-		    LM_ERR( "sca_aor_create_from_info from Contact %.*s "
-			    "and To URI %.*s failed", STR_FMT( &contact_uri ),
-			    STR_FMT( &from->uri ));
-		    goto done;
-		} 
+    if ( msg->first_line.type == SIP_REQUEST ) {
+	if ( sca_create_canonical_aor( msg, &from_aor ) < 0 ) {
+	    return( -1 );
+	}
+	aor_flags |= SCA_CALL_INFO_UPDATE_FLAG_FROM_ALLOC;
 
-		aor_flags |= SCA_CALL_INFO_UPDATE_FLAG_TO_ALLOC;
-	    }
+	if ( sca_uri_extract_aor( &to->uri, &to_aor ) < 0 ) {
+	    LM_ERR( "Failed to extract AoR from To URI %.*s",
+		    STR_FMT( &to->uri ));
+	    goto done;
+	}
+    } else {
+	if ( sca_uri_extract_aor( &from->uri, &from_aor ) < 0 ) {
+	    LM_ERR( "Failed to extract AoR from From URI %.*s",
+		    STR_FMT( &from->uri ));
+	    goto done;
+	}
+	if ( sca_create_canonical_aor( msg, &to_aor ) < 0 ) {
+	    return( -1 );
 	}
+	aor_flags |= SCA_CALL_INFO_UPDATE_FLAG_TO_ALLOC;
     }
 
     /* early check to see if we're dealing with any SCA endpoints */
diff --git a/modules/sca/sca_util.c b/modules/sca/sca_util.c
index ad050bc..a9f959e 100644
--- a/modules/sca/sca_util.c
+++ b/modules/sca/sca_util.c
@@ -339,6 +339,77 @@ sca_aor_create_from_info( str *aor, uri_type type, str *user, str *domain,
     return( aor->len );
 }
 
+    int
+sca_create_canonical_aor( sip_msg_t *msg, str *c_aor )
+{
+    struct to_body	*tf = NULL;
+    sip_uri_t		c_uri;
+    str			tf_aor = STR_NULL;
+    str			contact_uri = STR_NULL;
+    int			rc = -1;
+
+    assert( msg != NULL );
+    assert( c_aor != NULL );
+
+    memset( c_aor, 0, sizeof( str ));
+
+    if ( msg->first_line.type == SIP_REQUEST ) {
+	if ( sca_get_msg_from_header( msg, &tf ) < 0 ) {
+	    LM_ERR( "sca_create_canonical_aor: failed to get From header" );
+	    goto done;
+	}
+    } else {
+	if ( sca_get_msg_to_header( msg, &tf ) < 0 ) {
+	    LM_ERR( "sca_create_canonical_aor: failed to get To header" );
+	    goto done;
+	}
+    }
+
+    if ( sca_uri_extract_aor( &tf->uri, &tf_aor ) < 0 ) {
+	LM_ERR( "sca_create_canonical_aor: failed to extract AoR from "
+		"URI <%.*s>", STR_FMT( &tf->uri ));
+	goto done;
+    }
+
+    memset( &c_uri, 0, sizeof( sip_uri_t ));
+    if (( rc = sca_get_msg_contact_uri( msg, &contact_uri )) < 0 ) {
+	LM_ERR( "sca_create_canonical_aor: failed to get contact URI from "
+		"Contact <%.*s>", STR_FMT( &msg->contact->body ));
+	goto done;
+    }
+    if ( rc > 0 ) {
+	if ( parse_uri( contact_uri.s, contact_uri.len, &c_uri ) < 0 ) {
+	    LM_ERR( "sca_create_canonical_aor: failed to parse Contact URI "
+		    "<%.*s>", STR_FMT( &contact_uri ));
+	    rc = -1;
+	    goto done;
+	}
+    }
+
+    if ( SCA_STR_EMPTY( &c_uri.user ) ||
+	    SCA_STR_EQ( &c_uri.user, &tf->parsed_uri.user )) {
+	/* empty contact header or Contact user matches To/From AoR */
+	c_aor->s = (char *)pkg_malloc( tf_aor.len );
+	c_aor->len = tf_aor.len;
+	memcpy( c_aor->s, tf_aor.s, tf_aor.len );
+    } else {
+	/* Contact user and To/From user mismatch */
+	if ( sca_aor_create_from_info( c_aor, c_uri.type,
+		&c_uri.user, &tf->parsed_uri.host,
+		&tf->parsed_uri.port ) < 0 ) {
+	    LM_ERR( "sca_create_canonical_aor: failed to create AoR from "
+		    "Contact <%.*s> and URI <%.*s>",
+		    STR_FMT( &contact_uri ), STR_FMT( &tf_aor ));
+	    goto done;
+	}
+    }
+
+    rc = 1;
+
+done:
+    return( rc );
+}
+
 /* XXX this considers any held stream to mean the call is on hold. correct? */
     int
 sca_call_is_held( sip_msg_t *msg )
diff --git a/modules/sca/sca_util.h b/modules/sca/sca_util.h
index 30dcf78..012148b 100644
--- a/modules/sca/sca_util.h
+++ b/modules/sca/sca_util.h
@@ -55,6 +55,8 @@ int	sca_uri_build_aor( str *, int, str *, str * );
 
 int	sca_aor_create_from_info( str *, uri_type, str *, str *, str * );
 
+int	sca_create_canonical_aor( sip_msg_t *, str * );
+
 /* convenient call hold detection */
 int	sca_call_is_held( sip_msg_t * );
 




More information about the sr-dev mailing list