Module: sip-router
Branch: master
Commit: 287cccf2af17e5f2f8fe09c41025b4d27bb4fda9
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=287cccf…
Author: Andrew Mortensen <admorten(a)isc.upenn.edu>
Committer: Andrew Mortensen <admorten(a)isc.upenn.edu>
Date: Fri Mar 15 17:01:23 2013 -0400
modules/sca: process BYE without Call-Info from shared line.
- Ciscos & Aastras don't seem include Call-Info header in BYE. Look up
dialog by tags and release associated appearance-index.
---
modules/sca/sca_call_info.c | 68 ++++++++++++++++++++++++------------------
modules/sca/sca_call_info.h | 22 ++++++++++++++
2 files changed, 61 insertions(+), 29 deletions(-)
diff --git a/modules/sca/sca_call_info.c b/modules/sca/sca_call_info.c
index dee4f87..7444bf9 100644
--- a/modules/sca/sca_call_info.c
+++ b/modules/sca/sca_call_info.c
@@ -842,7 +842,7 @@ sca_call_info_is_line_seize_reinvite( sip_msg_t *msg, sca_call_info
*call_info,
* a Call-Info header is present
*/
- if ( call_info == NULL ) {
+ if ( SCA_CALL_INFO_EMPTY( call_info )) {
return( 0 );
}
if ( !SCA_STR_EMPTY( &to->tag_value )) {
@@ -961,7 +961,7 @@ sca_call_info_invite_request_handler( sip_msg_t *msg, sca_call_info
*call_info,
goto done;
}
- if ( call_info == NULL ) {
+ if ( !SCA_CALL_INFO_IS_SHARED_CALLER( call_info )) {
/* caller isn't SCA, no more to do. update callee in reply handler. */
rc = 1;
goto done;
@@ -979,7 +979,6 @@ sca_call_info_invite_request_handler( sip_msg_t *msg, sca_call_info
*call_info,
goto done;
}
-
if ( sca_call_is_held( msg )) {
state = SCA_APPEARANCE_STATE_HELD;
if ( call_info->state == SCA_APPEARANCE_STATE_HELD_PRIVATE ) {
@@ -1204,13 +1203,12 @@ sca_call_info_invite_reply_200_handler( sip_msg_t *msg,
int slot_idx = -1;
int rc = -1;
- if ( call_info != NULL ) {
- /* this implies To-AoR is SCA */
+ if ( SCA_CALL_INFO_IS_SHARED_CALLEE( call_info )) {
rc = sca_call_info_uri_update( to_aor, call_info, from, to,
contact_uri, &msg->callid->body );
}
- if ( !sca_uri_is_shared_appearance( sca, from_aor )) {
+ if ( !SCA_CALL_INFO_IS_SHARED_CALLER( call_info )) {
goto done;
}
@@ -1519,7 +1517,7 @@ sca_call_info_bye_handler( sip_msg_t *msg, sca_call_info
*call_info,
int rc = -1;
if ( msg->first_line.type == SIP_REQUEST ) {
- if ( call_info != NULL ) {
+ if ( SCA_CALL_INFO_IS_SHARED_CALLER( call_info )) {
slot_idx = sca_uri_lock_shared_appearance( sca, from_aor );
if ( slot_idx < 0 ) {
LM_ERR( "sca_call_info_bye_handler: failed to acquire "
@@ -1528,13 +1526,26 @@ sca_call_info_bye_handler( sip_msg_t *msg, sca_call_info
*call_info,
goto done;
}
- app = sca_appearance_for_index_unsafe( sca, from_aor,
- call_info->index, slot_idx );
- if ( app == NULL ) {
- LM_ERR( "sca_call_info_bye_handler: %.*s "
- "appearance-index %d is not active",
- STR_FMT( from_aor ), call_info->index );
- goto done;
+ if ( call_info->index != SCA_CALL_INFO_APPEARANCE_INDEX_ANY ) {
+ app = sca_appearance_for_index_unsafe( sca, from_aor,
+ call_info->index, slot_idx );
+ if ( app == NULL ) {
+ LM_ERR( "sca_call_info_bye_handler: %.*s "
+ "appearance-index %d is not active",
+ STR_FMT( from_aor ), call_info->index );
+ goto done;
+ }
+ } else {
+ app = sca_appearance_for_tags_unsafe( sca, from_aor,
+ &msg->callid->body, &from->tag_value, NULL, slot_idx );
+ if ( app == NULL ) {
+ LM_ERR( "sca_call_info_bye_handler: %.*s "
+ "dialog leg %.*s;%.*s is not active",
+ STR_FMT( from_aor ),
+ STR_FMT( &msg->callid->body ),
+ STR_FMT( &from->tag_value ));
+ goto done;
+ }
}
if ( SCA_STR_EQ( &app->dialog.call_id, &msg->callid->body )) {
@@ -1600,7 +1611,7 @@ sca_call_info_bye_handler( sip_msg_t *msg, sca_call_info
*call_info,
}
}
} else {
- if ( call_info != NULL ) {
+ if ( SCA_CALL_INFO_IS_SHARED_CALLEE( call_info )) {
slot_idx = sca_hash_table_index_for_key( sca->appearances, to_aor );
sca_hash_table_lock_index( sca->appearances, slot_idx );
@@ -1664,7 +1675,7 @@ sca_call_info_cancel_handler( sip_msg_t *msg, sca_call_info
*call_info,
* find appearance by dialog if Call-Info not present.
*/
/* XXX also handle CANCEL w/ Call-Info header? Some UAs might send it */
- if ( sca_uri_is_shared_appearance( sca, from_aor )) {
+ if ( SCA_CALL_INFO_IS_SHARED_CALLER( call_info )) {
app = sca_appearance_unlink_by_tags( sca, from_aor,
&msg->callid->body, &from->tag_value, NULL );
if ( app ) {
@@ -1806,7 +1817,7 @@ struct sca_call_info_dispatch call_info_dispatch[] = {
int
sca_call_info_update( sip_msg_t *msg, char *p1, char *p2 )
{
- sca_call_info call_info, *call_info_p = NULL;
+ sca_call_info call_info;
hdr_field_t *call_info_hdr;
struct to_body *from;
struct to_body *to;
@@ -1848,8 +1859,6 @@ sca_call_info_update( sip_msg_t *msg, char *p1, char *p2 )
STR_FMT( &call_info_hdr->body ));
return( -1 );
}
-
- call_info_p = &call_info;
}
if ( sca_get_msg_from_header( msg, &from ) < 0 ) {
@@ -1925,18 +1934,19 @@ sca_call_info_update( sip_msg_t *msg, char *p1, char *p2 )
}
/* early check to see if we're dealing with any SCA endpoints */
- if ( call_info_p == NULL ) {
- /* no Call-Info header in packet, check if AoRs are SCA */
-
- if ( !sca_uri_is_shared_appearance( sca, &from_aor ) &&
- !sca_uri_is_shared_appearance( sca, &to_aor )) {
- LM_DBG( "Neither %.*s nor %.*s are SCA AoRs",
- STR_FMT( &from_aor ), STR_FMT( &to_aor ));
- goto done;
- }
+ if ( sca_uri_is_shared_appearance( sca, &from_aor )) {
+ call_info.ua_shared |= SCA_CALL_INFO_SHARED_CALLER;
+ }
+ if ( sca_uri_is_shared_appearance( sca, &to_aor )) {
+ call_info.ua_shared |= SCA_CALL_INFO_SHARED_CALLEE;
+ }
+ if ( call_info.ua_shared == SCA_CALL_INFO_SHARED_NONE ) {
+ LM_DBG( "Neither %.*s nor %.*s are SCA AoRs",
+ STR_FMT( &from_aor ), STR_FMT( &to_aor ));
+ goto done;
}
- rc = call_info_dispatch[ i ].handler( msg, call_info_p, from, to,
+ rc = call_info_dispatch[ i ].handler( msg, &call_info, from, to,
&from_aor, &to_aor, &contact_uri );
if ( rc < 0 ) {
LM_ERR( "Failed to update Call-Info state for %.*s",
diff --git a/modules/sca/sca_call_info.h b/modules/sca/sca_call_info.h
index b62207e..80d1265 100644
--- a/modules/sca/sca_call_info.h
+++ b/modules/sca/sca_call_info.h
@@ -30,14 +30,36 @@
/* pass to sca_notify_subscriber to include all appearances in Call-Info hdr */
#define SCA_CALL_INFO_APPEARANCE_INDEX_ANY 0
+enum {
+ SCA_CALL_INFO_SHARED_NONE = 0,
+ SCA_CALL_INFO_SHARED_CALLER = (1 << 0),
+ SCA_CALL_INFO_SHARED_CALLEE = (1 << 1),
+};
+
struct _sca_call_info {
str sca_uri;
int index;
int state;
str uri;
+
+ /* mask tracking which endpoints in a call are shared */
+ int ua_shared;
};
typedef struct _sca_call_info sca_call_info;
+#define SCA_CALL_INFO_EMPTY( ci1 ) \
+ (!(ci1) && ((ci1)->index == SCA_CALL_INFO_APPEARANCE_INDEX_ANY && \
+ (ci1)->state == SCA_APPEARANCE_STATE_UNKNOWN))
+
+#define SCA_CALL_INFO_IS_SHARED_CALLER( ci1 ) \
+ (!SCA_CALL_INFO_EMPTY((ci1)) && \
+ (((sca_call_info *)(ci1))->ua_shared & SCA_CALL_INFO_SHARED_CALLER))
+
+#define SCA_CALL_INFO_IS_SHARED_CALLEE( ci1 ) \
+ (!SCA_CALL_INFO_EMPTY((ci1)) && \
+ (((sca_call_info *)(ci1))->ua_shared & SCA_CALL_INFO_SHARED_CALLEE))
+
+
extern const str SCA_CALL_INFO_HEADER_STR;