فهرست منبع

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.
Andrew Mortensen 12 سال پیش
والد
کامیت
1ef4587612
3فایلهای تغییر یافته به همراه101 افزوده شده و 49 حذف شده
  1. 28 49
      modules/sca/sca_call_info.c
  2. 71 0
      modules/sca/sca_util.c
  3. 2 0
      modules/sca/sca_util.h

+ 28 - 49
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 */

+ 71 - 0
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 )

+ 2 - 0
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 * );