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