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