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 <[email protected]>
Committer: Andrew Mortensen <[email protected]>
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 * );
 


_______________________________________________
sr-dev mailing list
[email protected]
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev

Reply via email to