TT#2386 sca: improvements

* [to|from]_avp module parameters
* sca_call_info_update() fallback if no Contact
  header is present
* implement unsubscribe for call-info
* use rr is_direction() to select tag for search
* fix core on RPC command release_appearance
* fix on-hold detection when direction is upstream

Change-Id: I29c71374da6ae918b82a32987e5d9a52a252e478
changes/22/12122/45
Victor Seva 8 years ago
parent 6fd6b73361
commit ce8bc30492

@ -53,6 +53,14 @@ sipwise/utils-kamctl-refresh-dbschema.patch
sipwise/sca-use-To-header-if-in-dialog-as-target.patch
sipwise/sca-fix-sca_call_info_update-params.patch
sipwise/sca-use-onhold_bflag-value-only-when-set.patch
sipwise/sca-line-seize.patch
sipwise/sca-fallback-if-no-contact.patch
sipwise/sca-call-info-unsubscribe.patch
sipwise/sca-rr-is-direction.patch
sipwise/sca-fix-core-when-release_appearance-RPC-command-par.patch
sipwise/sca-fix-pickup-when-upstream-flow.patch
sipwise/sca-fix-on-hold-detection-when-upstream-flow.patch
sipwise/sca-debug.patch
##
sipwise/tm-deep-cloning-of-the-request-for-fake-environment.patch
sipwise/core-parser-reset_path_vector-remove-check-for-msg-m.patch

@ -0,0 +1,76 @@
From: Victor Seva <vseva@sipwise.com>
Date: Thu, 13 Apr 2017 13:04:27 +0200
Subject: sca: implement subscribe deletion with expires=0 for call-info
Change-Id: I8cb4bb0db057f5f5754c5148a291029aaf30082d
---
modules/sca/sca_subscribe.c | 27 ++++++++++++++++++++++++---
1 file changed, 24 insertions(+), 3 deletions(-)
diff --git a/modules/sca/sca_subscribe.c b/modules/sca/sca_subscribe.c
index 3b92162..0022420 100644
--- a/modules/sca/sca_subscribe.c
+++ b/modules/sca/sca_subscribe.c
@@ -1180,6 +1180,8 @@ sca_handle_subscribe( sip_msg_t *msg, str *uri_to, str *uri_from )
int released = 0;
int_str val;
struct to_body *tmp_to;
+ sca_hash_slot *slot = NULL;
+ sca_hash_entry *ent = NULL;
if ( parse_headers( msg, HDR_EOH_F, 0 ) < 0 ) {
LM_ERR( "header parsing failed: bad request" );
@@ -1265,13 +1267,17 @@ sca_handle_subscribe( sip_msg_t *msg, str *uri_to, str *uri_from )
goto done;
}
}
-
+ slot = sca_hash_table_slot_for_index( sca->subscriptions, idx );
sca_hash_table_lock_index( sca->subscriptions, idx );
- sub = sca_hash_table_index_kv_find_unsafe( sca->subscriptions, idx,
- &req_sub.subscriber );
+ ent = sca_hash_table_slot_kv_find_entry_unsafe( slot, &req_sub.subscriber );
+ if (ent!=NULL) {
+ sub = (sca_subscription *)ent->value;
+ }
if ( sub != NULL ) {
+ LM_DBG("sca_handle_subscribe: subscription[%.*s] found\n",
+ STR_FMT(&req_sub.subscriber));
/* this will remove the subscription if expires == 0 */
if ( sca_subscription_update_unsafe( sca, sub, &req_sub, idx ) < 0 ) {
SCA_SUB_REPLY_ERROR( sca, 500, "Internal Server Error - "
@@ -1323,10 +1329,24 @@ sca_handle_subscribe( sip_msg_t *msg, str *uri_to, str *uri_from )
LM_INFO( "sca_handle_subscribe: released %d appearances "
"for subscriber %.*s", released,
STR_FMT( &req_sub.subscriber ));
+ } else {
+ LM_DBG("sca_handle_subscribe: subscriber[%.*s] doesn't "
+ "own any active appearances using target[%.*s]\n",
+ STR_FMT(&req_sub.subscriber),
+ STR_FMT(&req_sub.target_aor));
}
}
+ if( req_sub.expires == 0 ) {
+ ent = sca_hash_table_slot_unlink_entry_unsafe( slot, ent );
+ sub->expires = 0;
+ sub->dialog.notify_cseq += 1;
+ sub->state = SCA_SUBSCRIPTION_STATE_TERMINATED;
+ if(ent) sca_hash_entry_free( ent );
+ }
}
} else {
+ LM_DBG("sca_handle_subscribe: subscription[%.*s] not found\n",
+ STR_FMT(&req_sub.subscriber));
/* in-dialog request, but we didn't find it. */
if ( !SCA_STR_EMPTY( to_tag )) {
SCA_SUB_REPLY_ERROR( sca, 481,
@@ -1362,6 +1382,7 @@ sca_handle_subscribe( sip_msg_t *msg, str *uri_to, str *uri_from )
* but the dialog wasn't in our table. just reply with the
* subscription info we got, without saving or creating anything.
*/
+ LM_DBG("sca_handle_subscribe: expires=0 in-dialog but dialog not found\n");
sub = &req_sub;
}
}

@ -0,0 +1,222 @@
From: Victor Seva <vseva@sipwise.com>
Date: Tue, 18 Apr 2017 08:52:38 +0200
Subject: sca: debug output
Change-Id: Ib51bb44728ad9705e4e0fcc90e5d0e1873cb30d3
---
modules/sca/sca_appearance.c | 6 ++++++
modules/sca/sca_call_info.c | 46 +++++++++++++++++++++++++++++++++++++++++---
modules/sca/sca_dialog.c | 10 ++++++++++
3 files changed, 59 insertions(+), 3 deletions(-)
diff --git a/modules/sca/sca_appearance.c b/modules/sca/sca_appearance.c
index e0ba91e..a0585bc 100644
--- a/modules/sca/sca_appearance.c
+++ b/modules/sca/sca_appearance.c
@@ -1212,7 +1212,12 @@ sca_appearance_for_dialog_unsafe( sca_mod *scam, str *aor, sca_dialog *dialog,
return( NULL );
}
+ LM_DBG("search for call_id[%.*s] from_tag[%.*s]\n",
+ STR_FMT(&dialog->call_id), STR_FMT(&dialog->from_tag));
for ( app = app_list->appearances; app != NULL; app = app->next ) {
+ LM_DBG("app.call_id[%.*s] app.from_tag[%.*s] app.to_tag[%.*s]\n",
+ STR_FMT(&app->dialog.call_id), STR_FMT(&app->dialog.from_tag),
+ STR_FMT(&app->dialog.to_tag));
if ( SCA_STR_EQ( &app->dialog.call_id, &dialog->call_id ) &&
SCA_STR_EQ( &app->dialog.from_tag, &dialog->from_tag )) {
#ifdef notdef
@@ -1222,6 +1227,7 @@ sca_appearance_for_dialog_unsafe( sca_mod *scam, str *aor, sca_dialog *dialog,
continue;
}
#endif /* notdef */
+ LM_DBG("%.*s appearance-index %d found\n", STR_FMT(aor), app->index);
break;
}
}
diff --git a/modules/sca/sca_call_info.c b/modules/sca/sca_call_info.c
index 9ed63fd..0504ba6 100644
--- a/modules/sca/sca_call_info.c
+++ b/modules/sca/sca_call_info.c
@@ -1002,6 +1002,7 @@ sca_call_info_invite_request_handler( sip_msg_t *msg, sca_call_info *call_info,
if ( !upstream && !SCA_CALL_INFO_IS_SHARED_CALLER( call_info )) {
/* caller isn't SCA, no more to do. update callee in reply handler. */
+ LM_DBG("caller isn't SCA, no more to do. update callee in reply handler\n");
rc = 1;
goto done;
}
@@ -1019,6 +1020,7 @@ sca_call_info_invite_request_handler( sip_msg_t *msg, sca_call_info *call_info,
}
if ( sca_call_is_held( msg )) {
+ LM_DBG("call_is_held\n");
state = SCA_APPEARANCE_STATE_HELD;
if ( call_info->state == SCA_APPEARANCE_STATE_HELD_PRIVATE ) {
state = SCA_APPEARANCE_STATE_HELD_PRIVATE;
@@ -1027,14 +1029,18 @@ sca_call_info_invite_request_handler( sip_msg_t *msg, sca_call_info *call_info,
}
} else if ( !SCA_STR_EMPTY( &to->tag_value )) {
/* this is a reINVITE from an SCA line that put the call on hold */
+ LM_DBG("reINVITE from an SCA line that put the call on hold\n");
state = SCA_APPEARANCE_STATE_ACTIVE;
} else if ( sca_call_info_is_line_seize_reinvite( msg, call_info,
from, to, from_aor, to_aor )) {
+ LM_DBG("line_seize_reinvite\n");
rc = sca_call_info_seize_held_call( msg, call_info, from, to,
from_aor, to_aor, contact_uri );
if ( rc <= 0 ) {
goto done;
}
+ } else {
+ LM_DBG("Initial INVITE\n");
}
/* otherwise, this is an initial INVITE */
@@ -1236,11 +1242,19 @@ sca_call_info_invite_reply_200_handler( sip_msg_t *msg,
int rc = -1;
if ( SCA_CALL_INFO_IS_SHARED_CALLEE( call_info )) {
+ LM_DBG("SCA_CALL_INFO_IS_SHARED_CALLEE\n");
+ if(sca->rr_api->is_direction(msg, RR_FLOW_DOWNSTREAM)==0) {
+ LM_DBG("downstream detected\n");
+ }
+ if(sca->rr_api->is_direction(msg, RR_FLOW_UPSTREAM)==0) {
+ LM_DBG("upstream detected\n");
+ }
rc = sca_call_info_uri_update( to_aor, call_info, from, to,
contact_uri, &msg->callid->body );
}
if ( !SCA_CALL_INFO_IS_SHARED_CALLER( call_info )) {
+ LM_DBG("NOT SCA_CALL_INFO_IS_SHARED_CALLER\n");
goto done;
}
@@ -1269,6 +1283,8 @@ sca_call_info_invite_reply_200_handler( sip_msg_t *msg,
&msg->callid->body, &from->tag_value, NULL, slot_idx );
if ( app == NULL ) {
/* no SCA line is involved with this call */
+ LM_DBG("no SCA line is involved with this call[%.*s]\n",
+ STR_FMT(from_aor));
rc = 1;
goto done;
}
@@ -1433,6 +1449,8 @@ sca_call_info_ack_from_handler( sip_msg_t *msg, str *from_aor, str *to_aor )
/* can't send NOTIFYs until we unlock the slot below */
}
+ } else {
+ LM_DBG("from_aor[%.*s] not shared appearance\n", STR_FMT(from_aor));
}
done:
@@ -1586,7 +1604,11 @@ sca_call_info_bye_handler( sip_msg_t *msg, sca_call_info *call_info,
str *tag = NULL;
if ( msg->first_line.type == SIP_REQUEST ) {
+ LM_DBG("SIP_REQUEST\n");
if ( SCA_CALL_INFO_IS_SHARED_CALLER( call_info )) {
+ LM_DBG("SCA_CALL_INFO_IS_SHARED_CALLER "
+ "from_aor[%.*s] to_aor[%.*s]\n",
+ STR_FMT(from_aor), STR_FMT(to_aor));
slot_idx = sca_uri_lock_shared_appearance( sca, from_aor );
if ( slot_idx < 0 ) {
LM_ERR( "sca_call_info_bye_handler: failed to acquire "
@@ -1640,7 +1662,11 @@ sca_call_info_bye_handler( sip_msg_t *msg, sca_call_info *call_info,
goto done;
}
}
- }
+ } else {
+ LM_DBG("NOT SCA_CALL_INFO_IS_SHARED_CALLER "
+ "from_aor[%.*s] to_aor[%.*s]\n",
+ STR_FMT(from_aor), STR_FMT(to_aor));
+ }
if ( slot_idx >= 0 ) {
sca_hash_table_unlock_index( sca->appearances, slot_idx );
@@ -1695,6 +1721,7 @@ sca_call_info_bye_handler( sip_msg_t *msg, sca_call_info *call_info,
}
}
} else {
+ LM_DBG("SIP_REPLY\n");
/* this is just a backup to catch anything missed on the BYE request */
if ( SCA_CALL_INFO_IS_SHARED_CALLEE( call_info )) {
slot_idx = sca_hash_table_index_for_key( sca->appearances, to_aor );
@@ -2079,29 +2106,42 @@ sca_call_info_update( sip_msg_t *msg, char *p1, str *uri_to, str *uri_from )
if ( sca_uri_is_shared_appearance( sca, &from_aor )) {
if (( update_mask & SCA_CALL_INFO_SHARED_CALLER )) {
call_info.ua_shared |= SCA_CALL_INFO_SHARED_CALLER;
+ LM_DBG("SCA_CALL_INFO_SHARED_CALLER[%.*s]\n",
+ STR_FMT(&from_aor));
}
}
if ( sca_uri_is_shared_appearance( sca, &to_aor )) {
if (( update_mask & SCA_CALL_INFO_SHARED_CALLEE )) {
call_info.ua_shared |= SCA_CALL_INFO_SHARED_CALLEE;
+ LM_DBG("SCA_CALL_INFO_SHARED_CALLEE[%.*s]\n",
+ STR_FMT(&to_aor));
}
}
if ( call_info_hdr == NULL ) {
+ LM_DBG("call_info_hdr is NULL\n");
if ( SCA_CALL_INFO_IS_SHARED_CALLER( &call_info ) &&
msg->first_line.type == SIP_REQUEST ) {
+ LM_DBG("SCA_CALL_INFO_IS_SHARED_CALLER && SIP_REQUEST\n");
if ( !sca_subscription_aor_has_subscribers(
SCA_EVENT_TYPE_CALL_INFO, &from_aor )) {
call_info.ua_shared &= ~SCA_CALL_INFO_SHARED_CALLER;
sca_appearance_unregister( sca, &from_aor );
- }
+ } else {
+ LM_DBG("from_aor[%.*s] has subscribers\n",
+ STR_FMT(&from_aor));
+ }
} else if ( SCA_CALL_INFO_IS_SHARED_CALLEE( &call_info ) &&
msg->first_line.type == SIP_REPLY ) {
+ LM_DBG("SCA_CALL_INFO_IS_SHARED_CALLEE && SIP_REPLY\n");
if ( !sca_subscription_aor_has_subscribers(
SCA_EVENT_TYPE_CALL_INFO, &to_aor )) {
call_info.ua_shared &= ~SCA_CALL_INFO_SHARED_CALLEE;
sca_appearance_unregister( sca, &to_aor );
- }
+ } else {
+ LM_DBG("to_aor[%.*s] has subscribers\n",
+ STR_FMT(&from_aor));
+ }
}
}
diff --git a/modules/sca/sca_dialog.c b/modules/sca/sca_dialog.c
index 9faf9e7..f31ae67 100644
--- a/modules/sca/sca_dialog.c
+++ b/modules/sca/sca_dialog.c
@@ -43,6 +43,9 @@ sca_dialog_build_from_tags( sca_dialog *dialog, int maxlen, str *call_id,
return( -1 );
}
+ LM_DBG("call-id:%.*s from_tag:%.*s to_tag:%.*s\n",
+ STR_FMT(call_id), STR_FMT(from_tag), STR_FMT(to_tag));
+
memcpy( dialog->id.s, call_id->s, call_id->len );
dialog->call_id.s = dialog->id.s;
dialog->call_id.len = call_id->len;
@@ -56,9 +59,16 @@ sca_dialog_build_from_tags( sca_dialog *dialog, int maxlen, str *call_id,
to_tag->s, to_tag->len );
dialog->to_tag.s = dialog->id.s + call_id->len + from_tag->len;
dialog->to_tag.len = to_tag->len;
+ } else {
+ dialog->to_tag.s = NULL;
+ dialog->to_tag.len = 0;
}
dialog->id.len = len;
+ LM_DBG("id:%.*s call-id:%.*s from_tag:%.*s to_tag:%.*s\n",
+ STR_FMT(&dialog->id), STR_FMT(&dialog->call_id),
+ STR_FMT(&dialog->from_tag), STR_FMT(&dialog->to_tag));
+
return( len );
}

@ -0,0 +1,38 @@
From: Victor Seva <vseva@sipwise.com>
Date: Thu, 30 Mar 2017 10:16:00 +0200
Subject: sca: sca_call_info_update() fallback to default owner if no Contact
header is present
Change-Id: I6a3f5b4c6786bf804bd10987863edf954e41f69b
---
modules/sca/sca_call_info.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/modules/sca/sca_call_info.c b/modules/sca/sca_call_info.c
index 734fbe2..5592a68 100644
--- a/modules/sca/sca_call_info.c
+++ b/modules/sca/sca_call_info.c
@@ -1976,9 +1976,6 @@ sca_call_info_update( sip_msg_t *msg, char *p1, str *uri_to, str *uri_from )
rc = -1;
goto done;
}
- } else if ( rc < 0 ) {
- LM_ERR( "Bad Contact" );
- goto done;
}
/* reset rc to -1 so we don't end up returning 0 to the script */
rc = -1;
@@ -2025,6 +2022,13 @@ sca_call_info_update( sip_msg_t *msg, char *p1, str *uri_to, str *uri_from )
LM_DBG("to_aor[%.*s] from_aor[%.*s]\n",
STR_FMT(&to_aor), STR_FMT(&from_aor));
+ if(contact_uri.s==NULL) {
+ contact_uri.s = "sip:127.0.0.1:5085;transport=udp";
+ contact_uri.len = strlen(contact_uri.s);
+ LM_DBG("No Contact header, using default owner[%.*s]\n",
+ STR_FMT(&contact_uri));
+ }
+
/* early check to see if we're dealing with any SCA endpoints */
if ( sca_uri_is_shared_appearance( sca, &from_aor )) {
if (( update_mask & SCA_CALL_INFO_SHARED_CALLER )) {

@ -0,0 +1,38 @@
From: Victor Seva <vseva@sipwise.com>
Date: Thu, 8 Jun 2017 12:34:15 +0200
Subject: sca: fix core when release_appearance RPC command parameter has
wrong index
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 8bit
> #0 0x00007fd8bba5a067 in raise () from /lib/x86_64-linux-gnu/libc.so.6
> #1 0x00007fd8bba5b448 in abort () from /lib/x86_64-linux-gnu/libc.so.6
> #2 0x00007fd8bba53266 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
> #3 0x00007fd8bba53312 in __assert_fail () from /lib/x86_64-linux-gnu/libc.so.6
> #4 0x00007fd8a4b16328 in sca_appearance_list_unlink_index (app_list=0x7fd8a603c528, idx=0) at sca_appearance.c:254
> #5 0x00007fd8a4ae0372 in sca_rpc_release_appearance (rpc=0x7fd8b1162300 <binrpc_callbacks>, ctx=0x7ffc2ce9eef0) at sca_rpc.c:504
> #6 0x00007fd8b0f38abb in process_rpc_req (buf=0x1e5e744 "\241\003\067oZ\274Ƒ\027sca.release_appearance", size=12344, bytes_needed=0x7ffc2ce9effc, sh=0xfefefefefefefe00,
> saved_state=0xfefefefefefefe00) at binrpc_run.c:675
Change-Id: Ied94a9872fa41ee5d6432380c549076da2fd6239
---
modules/sca/sca_rpc.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/modules/sca/sca_rpc.c b/modules/sca/sca_rpc.c
index 5e6873b..cac8465 100644
--- a/modules/sca/sca_rpc.c
+++ b/modules/sca/sca_rpc.c
@@ -482,6 +482,11 @@ sca_rpc_release_appearance( rpc_t *rpc, void *ctx )
return;
}
+ if (app_idx <= 0) {
+ rpc->fault(ctx, 500, "appearance-index must be > 0");
+ return;
+ }
+
if (( ht = sca->appearances ) == NULL ) {
rpc->fault( ctx, 500, "No active appearances" );
return;

@ -0,0 +1,36 @@
From: Victor Seva <vseva@sipwise.com>
Date: Fri, 9 Jun 2017 13:54:04 +0200
Subject: sca: fix on-hold detection when upstream flow
Change-Id: I0c7186c0e749b47254e4b34468b044286a413876
---
modules/sca/sca_call_info.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/modules/sca/sca_call_info.c b/modules/sca/sca_call_info.c
index 370fcc2..9ed63fd 100644
--- a/modules/sca/sca_call_info.c
+++ b/modules/sca/sca_call_info.c
@@ -980,11 +980,13 @@ sca_call_info_invite_request_handler( sip_msg_t *msg, sca_call_info *call_info,
int state = SCA_APPEARANCE_STATE_UNKNOWN;
int rc = -1;
str *target_aor = from_aor;
+ int upstream = 0;
if(SCA_CALL_INFO_IS_SHARED_CALLEE( call_info ) &&
sca->rr_api->is_direction(msg, RR_FLOW_UPSTREAM)==0) {
LM_DBG("callee is SCA and direction is 'upstream'\n");
target_aor = to_aor;
+ upstream = 1;
}
/*
@@ -998,7 +1000,7 @@ sca_call_info_invite_request_handler( sip_msg_t *msg, sca_call_info *call_info,
goto done;
}
- if ( !SCA_CALL_INFO_IS_SHARED_CALLER( call_info )) {
+ if ( !upstream && !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;

@ -0,0 +1,120 @@
From: Victor Seva <vseva@sipwise.com>
Date: Thu, 8 Jun 2017 16:13:03 +0200
Subject: sca: fix pickup when upstream flow
Change-Id: Ibed4c626573e3ac6d0fdc43a0f83954f17e60283
---
modules/sca/sca_call_info.c | 47 +++++++++++++++++++++++++++++----------------
1 file changed, 30 insertions(+), 17 deletions(-)
diff --git a/modules/sca/sca_call_info.c b/modules/sca/sca_call_info.c
index cbd9b9b..370fcc2 100644
--- a/modules/sca/sca_call_info.c
+++ b/modules/sca/sca_call_info.c
@@ -979,6 +979,13 @@ sca_call_info_invite_request_handler( sip_msg_t *msg, sca_call_info *call_info,
str state_str = STR_NULL;
int state = SCA_APPEARANCE_STATE_UNKNOWN;
int rc = -1;
+ str *target_aor = from_aor;
+
+ if(SCA_CALL_INFO_IS_SHARED_CALLEE( call_info ) &&
+ sca->rr_api->is_direction(msg, RR_FLOW_UPSTREAM)==0) {
+ LM_DBG("callee is SCA and direction is 'upstream'\n");
+ target_aor = to_aor;
+ }
/*
* if we get here, one of the legs is an SCA endpoint. we want to know
@@ -987,7 +994,7 @@ sca_call_info_invite_request_handler( sip_msg_t *msg, sca_call_info *call_info,
if ( sca->tm_api->register_tmcb( msg, NULL, TMCB_E2EACK_IN,
sca_call_info_ack_cb, NULL, NULL ) < 0 ) {
LM_ERR( "sca_call_info_invite_request_handler: failed to register "
- "callback for INVITE %.*s ACK", STR_FMT( from_aor ));
+ "callback for INVITE %.*s ACK", STR_FMT( target_aor ));
goto done;
}
@@ -1005,7 +1012,7 @@ sca_call_info_invite_request_handler( sip_msg_t *msg, sca_call_info *call_info,
if ( sca->tm_api->register_tmcb( msg, NULL, TMCB_RESPONSE_READY,
sca_call_info_response_ready_cb, NULL, NULL ) < 0 ) {
LM_ERR( "sca_call_info_invite_request_handler: failed to register "
- "callback for INVITE %.*s ACK", STR_FMT( from_aor ));
+ "callback for INVITE %.*s ACK", STR_FMT( target_aor ));
goto done;
}
@@ -1036,17 +1043,17 @@ sca_call_info_invite_request_handler( sip_msg_t *msg, sca_call_info *call_info,
return( -1 );
}
- if ( sca_appearance_update_index( sca, from_aor, call_info->index,
+ if ( sca_appearance_update_index( sca, target_aor, call_info->index,
state, NULL, NULL, &dialog ) != SCA_APPEARANCE_OK ) {
sca_appearance_state_to_str( state, &state_str );
LM_ERR( "Failed to update %.*s appearance-index %d to %.*s",
- STR_FMT( from_aor ), call_info->index,
+ STR_FMT( target_aor ), call_info->index,
STR_FMT( &state_str ));
}
- if ( sca_notify_call_info_subscribers( sca, from_aor ) < 0 ) {
+ if ( sca_notify_call_info_subscribers( sca, target_aor ) < 0 ) {
LM_ERR( "Failed to call-info NOTIFY %.*s subscribers on INVITE",
- STR_FMT( from_aor ));
+ STR_FMT( target_aor ));
goto done;
}
@@ -1373,6 +1380,7 @@ sca_call_info_ack_from_handler( sip_msg_t *msg, str *from_aor, str *to_aor )
str *tag;
int slot_idx = -1;
int state = SCA_APPEARANCE_STATE_IDLE;
+ str *target_aor;
if ( sca_get_msg_from_header( msg, &from ) < 0 ) {
LM_ERR( "sca_call_info_ack_cb: failed to get From-header" );
@@ -1383,18 +1391,23 @@ sca_call_info_ack_from_handler( sip_msg_t *msg, str *from_aor, str *to_aor )
return;
}
- if ( sca_uri_lock_if_shared_appearance( sca, from_aor, &slot_idx )) {
- if(sca->rr_api->is_direction(msg, RR_FLOW_UPSTREAM)==0) {
- LM_DBG("upstream direction detected\n");
- tag = &to->tag_value;
- } else {
- tag = &from->tag_value;
- }
- app = sca_appearance_for_tags_unsafe( sca, from_aor,
+ if(sca->rr_api->is_direction(msg, RR_FLOW_UPSTREAM)==0) {
+ LM_DBG("upstream direction detected\n");
+ target_aor = to_aor;
+ tag = &to->tag_value;
+ } else {
+ target_aor = from_aor;
+ tag = &from->tag_value;
+ }
+
+ LM_DBG("target_aor[%.*s]\n", STR_FMT(target_aor));
+
+ if ( sca_uri_lock_if_shared_appearance( sca, target_aor, &slot_idx )) {
+ app = sca_appearance_for_tags_unsafe( sca, target_aor,
&msg->callid->body, tag, NULL, slot_idx );
if ( app == NULL ) {
LM_ERR( "sca_call_info_ack_cb: No appearance for %.*s matching "
- "call-id <%.*s> and from-tag <%.*s>", STR_FMT( from_aor ),
+ "call-id <%.*s> and from-tag <%.*s>", STR_FMT( target_aor ),
STR_FMT( &msg->callid->body ), STR_FMT( tag ));
goto done;
}
@@ -1425,9 +1438,9 @@ done:
sca_hash_table_unlock_index( sca->appearances, slot_idx );
if ( state != SCA_APPEARANCE_STATE_IDLE ) {
- if ( sca_notify_call_info_subscribers( sca, from_aor ) < 0 ) {
+ if ( sca_notify_call_info_subscribers( sca, target_aor ) < 0 ) {
LM_ERR( "Failed to call-info NOTIFY %.*s subscribers on INVITE",
- STR_FMT( from_aor ));
+ STR_FMT( target_aor ));
}
}
}

@ -0,0 +1,629 @@
From: Sipwise Development Team <support@sipwise.com>
Date: Thu, 16 Mar 2017 15:45:42 +0100
Subject: sca: [to|from]_avp module parameters
Change-Id: Ie7b09e95dd975fc549b1bb26e34663370200be0a
---
modules/sca/sca.c | 102 +++++++++++++++++++++++++++++-
modules/sca/sca.h | 6 ++
modules/sca/sca_call_info.c | 77 ++++++++++-------------
modules/sca/sca_subscribe.c | 52 +++++++++-------
modules/sca/sca_subscribe.h | 2 +-
modules/sca/sca_util.c | 148 +++++++++++++++++++++++++-------------------
6 files changed, 255 insertions(+), 132 deletions(-)
diff --git a/modules/sca/sca.c b/modules/sca/sca.c
index 9e03f6f..99d2ac1 100644
--- a/modules/sca/sca.c
+++ b/modules/sca/sca.c
@@ -47,11 +47,22 @@ db_func_t dbf; /* db api */
struct tm_binds tmb; /* tm functions for sending messages */
sl_api_t slb; /* sl callback, function for getting to-tag */
+/* avps */
+unsigned short from_uri_avp_type;
+int_str from_uri_avp;
+unsigned short to_uri_avp_type;
+int_str to_uri_avp;
+
/* PROTOTYPES */
static int sca_mod_init( void );
static int sca_child_init( int );
static void sca_mod_destroy( void );
static int sca_set_config( sca_mod * );
+static int sca_handle_subscribe_0_f(sip_msg_t* msg);
+static int sca_handle_subscribe_1_f(sip_msg_t* msg, char*);
+static int sca_handle_subscribe_2_f(sip_msg_t* msg, char*, char *);
+int fixup_hs(void **, int);
+int fixup_free_hs(void **param, int param_no);
static int sca_call_info_update_0_f(sip_msg_t* msg);
static int sca_call_info_update_1_f(sip_msg_t* msg, char*);
static int sca_call_info_update_2_f(sip_msg_t* msg, char* , char*);
@@ -61,7 +72,12 @@ int fixup_free_ciu(void **param, int param_no);
/* EXPORTED COMMANDS */
static cmd_export_t cmds[] = {
- { "sca_handle_subscribe", (cmd_function)sca_handle_subscribe, 0, NULL, NULL, REQUEST_ROUTE },
+ { "sca_handle_subscribe", (cmd_function)sca_handle_subscribe_0_f, 0,
+ NULL, NULL, REQUEST_ROUTE },
+ { "sca_handle_subscribe", (cmd_function)sca_handle_subscribe_1_f, 1,
+ fixup_hs, fixup_free_hs, REQUEST_ROUTE },
+ { "sca_handle_subscribe", (cmd_function)sca_handle_subscribe_2_f, 2,
+ fixup_hs, fixup_free_hs, REQUEST_ROUTE },
{ "sca_call_info_update", (cmd_function)sca_call_info_update_0_f, 0, NULL, NULL,
REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE },
{"sca_call_info_update", (cmd_function)sca_call_info_update_1_f, 1,
@@ -112,6 +128,8 @@ int line_seize_max_expires = 15;
int purge_expired_interval = 120;
int onhold_bflag = -1;
str server_address = STR_NULL;
+str from_uri_avp_param = STR_NULL;
+str to_uri_avp_param = STR_NULL;
static param_export_t params[] = {
{ "outbound_proxy", PARAM_STR, &outbound_proxy },
@@ -125,6 +143,8 @@ static param_export_t params[] = {
{ "purge_expired_interval", INT_PARAM, &purge_expired_interval },
{"onhold_bflag", INT_PARAM, &onhold_bflag},
{"server_address", PARAM_STR, &server_address},
+ {"from_uri_avp", PARAM_STR, &from_uri_avp_param},
+ {"to_uri_avp", PARAM_STR, &to_uri_avp_param},
{ NULL, 0, NULL },
};
@@ -301,6 +321,31 @@ sca_child_init( int rank )
return( 0 );
}
+static int
+sca_process_avps(str *avp_param, int_str *avp, unsigned short *avp_type)
+{
+ pv_spec_t *avp_spec;
+ unsigned short avp_flags;
+
+ if (avp_param && avp_param->len > 0) {
+ avp_spec = pv_cache_get(avp_param);
+ if (avp_spec==NULL|| avp_spec->type!=PVT_AVP) {
+ LM_ERR("malformed or non AVP definition <%.*s>\n", STR_FMT(avp_param));
+ return -1;
+ }
+
+ if (pv_get_avp_name(0, &(avp_spec->pvp), avp, &avp_flags) != 0) {
+ LM_ERR("invalid AVP definition <%.*s>\n", STR_FMT(avp_param));
+ return -1;
+ }
+ *avp_type = avp_flags;
+ } else {
+ avp->s.s = NULL;
+ avp->s.len = 0;
+ }
+ return 0;
+}
+
static int
sca_mod_init( void )
{
@@ -363,6 +408,11 @@ sca_mod_init( void )
*/
register_dummy_timers( 1 );
+ if(sca_process_avps(&from_uri_avp_param, &from_uri_avp, &from_uri_avp_type)<0 ||
+ sca_process_avps(&to_uri_avp_param, &to_uri_avp, &to_uri_avp_type)<0) {
+ goto error;
+ }
+
LM_INFO( "initialized" );
return( 0 );
@@ -402,6 +452,56 @@ sca_mod_destroy( void )
sca_db_disconnect();
}
+static int sca_handle_subscribe_0_f(sip_msg_t* msg) {
+ return sca_handle_subscribe(msg, NULL, NULL);
+}
+static int sca_handle_subscribe_1_f(sip_msg_t* msg, char* p1) {
+ str uri_to = STR_NULL;
+ if(get_str_fparam(&uri_to, msg, (gparam_p)p1)!=0)
+ {
+ LM_ERR("unable to get value from param pvar_to\n");
+ return -1;
+ }
+ return sca_handle_subscribe(msg, &uri_to, NULL);
+}
+static int sca_handle_subscribe_2_f(sip_msg_t* msg, char* p1, char* p2) {
+ str uri_to = STR_NULL;
+ str uri_from = STR_NULL;
+ if(get_str_fparam(&uri_to, msg, (gparam_p)p1)!=0)
+ {
+ LM_ERR("unable to get value from param pvar_to\n");
+ return -1;
+ }
+ if(get_str_fparam(&uri_from, msg, (gparam_p)p2)!=0)
+ {
+ LM_ERR("unable to get value from param pvar_from\n");
+ return -1;
+ }
+return sca_handle_subscribe(msg, &uri_to, &uri_from);
+}
+
+int fixup_hs(void **param, int param_no)
+{
+ switch (param_no) {
+ case 1:
+ case 2:
+ return fixup_spve_null(param, 1);
+ default:
+ return E_UNSPEC;
+ }
+}
+
+int fixup_free_hs(void **param, int param_no)
+{
+ switch (param_no) {
+ case 1:
+ case 2:
+ return fixup_free_spve_null(param, 1);
+ default:
+ return E_UNSPEC;
+ }
+}
+
static int sca_call_info_update_0_f(sip_msg_t* msg) {
return sca_call_info_update(msg, NULL, NULL, NULL);
}
diff --git a/modules/sca/sca.h b/modules/sca/sca.h
index abcbe56..69fed94 100644
--- a/modules/sca/sca.h
+++ b/modules/sca/sca.h
@@ -55,4 +55,10 @@ typedef struct _sca_mod sca_mod;
extern sca_mod *sca;
+/* avps */
+extern unsigned short from_uri_avp_type;
+extern int_str from_uri_avp;
+extern unsigned short to_uri_avp_type;
+extern int_str to_uri_avp;
+
#endif /* SCA_H */
diff --git a/modules/sca/sca_call_info.c b/modules/sca/sca_call_info.c
index d46c65d..734fbe2 100644
--- a/modules/sca/sca_call_info.c
+++ b/modules/sca/sca_call_info.c
@@ -1874,12 +1874,12 @@ sca_call_info_update( sip_msg_t *msg, char *p1, str *uri_to, str *uri_from )
str to_aor = STR_NULL;
str contact_uri = STR_NULL;
int aor_flags = SCA_CALL_INFO_UPDATE_FLAG_DEFAULT;
- int to_body_flags = SCA_CALL_INFO_UPDATE_FLAG_DEFAULT;
int n_dispatch;
int i;
int method;
int rc = -1;
int update_mask = SCA_CALL_INFO_SHARED_BOTH;
+ int_str val;
method = sca_get_msg_method( msg );
@@ -1931,6 +1931,9 @@ sca_call_info_update( sip_msg_t *msg, char *p1, str *uri_to, str *uri_from )
}
}
+ delete_avp(from_uri_avp_type|AVP_VAL_STR, from_uri_avp);
+ delete_avp(to_uri_avp_type|AVP_VAL_STR, to_uri_avp);
+
memset( &call_info, 0, sizeof( sca_call_info ));
call_info_hdr = sca_call_info_header_find( msg->headers );
if ( !SCA_HEADER_EMPTY( call_info_hdr )) {
@@ -1943,36 +1946,22 @@ sca_call_info_update( sip_msg_t *msg, char *p1, str *uri_to, str *uri_from )
}
if (uri_from != NULL) {
- if(sca_build_to_body_from_uri(msg, &from, uri_from)<0){
- LM_ERR( "Bad From uri from param\n" );
- return( -1 );
- }
+ val.s.s = uri_from->s;
+ val.s.len = uri_from->len;
+ add_avp(from_uri_avp_type|AVP_VAL_STR, from_uri_avp, val);
LM_DBG("from[%.*s] param\n", STR_FMT(uri_from));
- to_body_flags |= SCA_CALL_INFO_UPDATE_FLAG_FROM_ALLOC;
- 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;
- }
}
- else if ( sca_get_msg_from_header( msg, &from ) < 0 ) {
- LM_ERR( "Bad From header" );
+ if ( sca_get_msg_from_header( msg, &from ) < 0 ) {
+ LM_ERR( "Bad From header" );
return( -1 );
}
if (uri_to != NULL) {
- if(sca_build_to_body_from_uri(msg, &to, uri_to)<0){
- LM_ERR( "Bad From uri to param\n" );
- goto done;
- }
+ val.s.s = uri_to->s;
+ val.s.len = uri_to->len;
+ add_avp(to_uri_avp_type|AVP_VAL_STR, to_uri_avp, val);
LM_DBG("to[%.*s] param\n", STR_FMT(uri_to));
- to_body_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_get_msg_to_header( msg, &to ) < 0 ) {
+ if ( sca_get_msg_to_header( msg, &to ) < 0 ) {
LM_ERR( "Bad To header" );
goto done;
}
@@ -2001,27 +1990,35 @@ sca_call_info_update( sip_msg_t *msg, char *p1, str *uri_to, str *uri_from )
goto done;
}
aor_flags |= SCA_CALL_INFO_UPDATE_FLAG_FROM_ALLOC;
- }
- if(uri_to==NULL) {
- 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(uri_from==NULL) {
+ } 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 ));
+ STR_FMT( &from->uri ));
goto done;
}
}
+ 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(uri_to==NULL) {
if ( sca_create_canonical_aor( msg, &to_aor ) < 0 ) {
goto done;
}
aor_flags |= SCA_CALL_INFO_UPDATE_FLAG_TO_ALLOC;
+ } else {
+ 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;
+ }
}
}
@@ -2088,15 +2085,5 @@ done:
pkg_free( to_aor.s );
}
}
- if (( to_body_flags & SCA_CALL_INFO_UPDATE_FLAG_FROM_ALLOC )) {
- if ( from != NULL ) {
- free_to( from );
- }
- }
- if (( to_body_flags & SCA_CALL_INFO_UPDATE_FLAG_TO_ALLOC )) {
- if ( to != NULL ) {
- free_to( to );
- }
- }
return( rc );
}
diff --git a/modules/sca/sca_subscribe.c b/modules/sca/sca_subscribe.c
index 25fac54..3b92162 100644
--- a/modules/sca/sca_subscribe.c
+++ b/modules/sca/sca_subscribe.c
@@ -1043,10 +1043,6 @@ sca_subscription_from_request( sca_mod *scam, sip_msg_t *msg, int event_type,
expires = max_expires;
}
- if ( SCA_HEADER_EMPTY( msg->to )) {
- LM_ERR( "Empty To header" );
- goto error;
- }
if ( SCA_HEADER_EMPTY( msg->callid )) {
LM_ERR( "Empty Call-ID header" );
goto error;
@@ -1068,30 +1064,18 @@ sca_subscription_from_request( sca_mod *scam, sip_msg_t *msg, int event_type,
goto error;
}
- if ( SCA_HEADER_EMPTY( msg->from )) {
- LM_ERR( "Empty From header" );
- goto error;
- }
- if ( parse_from_header( msg ) < 0 ) {
+ if ( sca_get_msg_from_header( msg, &from ) < 0 ) {
LM_ERR( "Bad From header" );
goto error;
}
- from = (struct to_body *)msg->from->parsed;
if ( SCA_STR_EMPTY( &from->tag_value )) {
LM_ERR( "No from-tag in From header" );
goto error;
}
- if (( to = (struct to_body *)msg->to->parsed ) == NULL ) {
- parse_to( msg->to->body.s,
- msg->to->body.s + msg->to->body.len + 1, /* end of buffer */
- &tmp_to );
-
- if ( tmp_to.error != PARSE_OK ) {
- LM_ERR( "Bad To header" );
- goto error;
- }
- to = &tmp_to;
+ if ( sca_get_msg_to_header( msg, &to ) < 0 ) {
+ LM_ERR( "Bad To header" );
+ goto error;
}
if (parse_sip_msg_uri(msg) < 0) {
@@ -1179,7 +1163,7 @@ error:
}
int
-sca_handle_subscribe( sip_msg_t *msg, char *p1, char *p2 )
+sca_handle_subscribe( sip_msg_t *msg, str *uri_to, str *uri_from )
{
sca_subscription req_sub;
sca_subscription *sub = NULL;
@@ -1194,6 +1178,8 @@ sca_handle_subscribe( sip_msg_t *msg, char *p1, char *p2 )
int idx = -1;
int rc = -1;
int released = 0;
+ int_str val;
+ struct to_body *tmp_to;
if ( parse_headers( msg, HDR_EOH_F, 0 ) < 0 ) {
LM_ERR( "header parsing failed: bad request" );
@@ -1218,6 +1204,20 @@ sca_handle_subscribe( sip_msg_t *msg, char *p1, char *p2 )
return( -1 );
}
+ delete_avp(from_uri_avp_type|AVP_VAL_STR, from_uri_avp);
+ delete_avp(to_uri_avp_type|AVP_VAL_STR, to_uri_avp);
+ if (uri_from != NULL) {
+ val.s.s = uri_from->s;
+ val.s.len = uri_from->len;
+ add_avp(from_uri_avp_type|AVP_VAL_STR, from_uri_avp, val);
+ LM_DBG("from[%.*s] param\n", STR_FMT(uri_from));
+ }
+ if (uri_to != NULL) {
+ val.s.s = uri_to->s;
+ val.s.len = uri_to->len;
+ add_avp(to_uri_avp_type|AVP_VAL_STR, to_uri_avp, val);
+ LM_DBG("to[%.*s] param\n", STR_FMT(uri_to));
+ }
if ( sca_subscription_from_request( sca, msg, event_type, &req_sub ) < 0 ) {
SCA_SUB_REPLY_ERROR( sca, 400,
"Bad Shared Call Appearance Request", msg );
@@ -1231,7 +1231,15 @@ sca_handle_subscribe( sip_msg_t *msg, char *p1, char *p2 )
sca_subscription_print( &req_sub );
/* check to see if the message has a to-tag */
- to_tag = &(get_to( msg )->tag_value);
+ if(uri_to!=NULL) {
+ if ( sca_get_msg_to_header( msg, &tmp_to ) < 0 ) {
+ LM_ERR( "Bad To header" );
+ return( -1 );
+ }
+ to_tag = &(tmp_to->tag_value);
+ } else {
+ to_tag = &(get_to( msg )->tag_value);
+ }
/* XXX should lock starting here and use unsafe methods below? */
diff --git a/modules/sca/sca_subscribe.h b/modules/sca/sca_subscribe.h
index a3688de..6e4b381 100644
--- a/modules/sca/sca_subscribe.h
+++ b/modules/sca/sca_subscribe.h
@@ -75,7 +75,7 @@ extern const str SCA_METHOD_SUBSCRIBE;
sca_subscription_reply((mod), (scode), (smsg), \
SCA_EVENT_TYPE_CALL_INFO, -1, (sreply))
-int sca_handle_subscribe( sip_msg_t *, char *, char * );
+int sca_handle_subscribe( sip_msg_t *, str *, str * );
int sca_subscription_reply( sca_mod *, int, char *, int, int, sip_msg_t * );
int sca_subscription_from_db_result( db1_res_t *, sca_subscription * );
diff --git a/modules/sca/sca_util.c b/modules/sca/sca_util.c
index 32a20bc..a3476d8 100644
--- a/modules/sca/sca_util.c
+++ b/modules/sca/sca_util.c
@@ -116,94 +116,116 @@ sca_get_msg_cseq_method( sip_msg_t *msg )
/* caller needs to call free_to for *body */
int
-sca_build_to_body_from_uri(sip_msg_t *msg, struct to_body **body, str *uri)
+sca_parse_uri(struct to_body *body, str *uri)
{
- assert( msg != NULL );
assert( body != NULL );
assert( uri != NULL );
- *body = pkg_malloc(sizeof(struct to_body));
- if(*body == NULL) {
- LM_ERR("cannot allocate pkg memory\n");
- return(-1);
- }
-
- parse_to(uri->s, uri->s + uri->len + 1, *body);
- if ((*body)->error != PARSE_OK) {
+ parse_to(uri->s, uri->s + uri->len + 1, body);
+ if (body->error != PARSE_OK) {
LM_ERR("Bad uri value[%.*s]\n", STR_FMT(uri));
- free_to(*body);
return(-1);
}
return (0);
}
- int
-sca_get_msg_from_header( sip_msg_t *msg, struct to_body **from )
-{
- struct to_body *f;
+int
+sca_get_avp_value(unsigned short avp_type, int_str avp, str *result) {
+ int_str val;
+ struct usr_avp *_avp;
+
+ assert(result != NULL);
+
+ if (avp.s.len > 0) {
+ _avp = search_first_avp(avp_type, avp, &val, 0);
+ if(_avp) {
+ result->s = val.s.s;
+ result->len = val.s.len;
+ return 0;
+ }
+ }
+ return -1;
+}
+
+int
+sca_get_msg_from_header( sip_msg_t *msg, struct to_body **from ) {
+ struct to_body *f;
+ static struct to_body sf;
+ str uri = STR_NULL;
- assert( msg != NULL );
assert( from != NULL );
- if ( SCA_HEADER_EMPTY( msg->from )) {
- LM_ERR( "Empty From header" );
- return( -1 );
- }
- if ( parse_from_header( msg ) < 0 ) {
- LM_ERR( "Bad From header" );
- return( -1 );
- }
- f = get_from( msg );
- if ( SCA_STR_EMPTY( &f->tag_value )) {
- LM_ERR( "Bad From header: no tag parameter" );
- return( -1 );
- }
+ if(sca_get_avp_value(from_uri_avp_type, from_uri_avp, &uri)<0) {
+ assert( msg != NULL );
+ if ( SCA_HEADER_EMPTY( msg->from )) {
+ LM_ERR( "Empty From header" );
+ return( -1 );
+ }
+ if ( parse_from_header( msg ) < 0 ) {
+ LM_ERR( "Bad From header" );
+ return( -1 );
+ }
+ f = get_from( msg );
+ if ( SCA_STR_EMPTY( &f->tag_value )) {
+ LM_ERR( "Bad From header: no tag parameter" );
+ return( -1 );
+ }
- /* ensure the URI is parsed for future use */
- if ( parse_uri( f->uri.s, f->uri.len, GET_FROM_PURI( msg )) < 0 ) {
- LM_ERR( "Failed to parse From URI %.*s", STR_FMT( &f->uri ));
- return( -1 );
+ /* ensure the URI is parsed for future use */
+ if ( parse_uri( f->uri.s, f->uri.len, GET_FROM_PURI( msg )) < 0 ) {
+ LM_ERR( "Failed to parse From URI %.*s", STR_FMT( &f->uri ));
+ return( -1 );
+ }
+ *from = f;
+ } else {
+ LM_DBG("using $avp(%.*s)[%.*s] as from uri\n",
+ STR_FMT(&from_uri_avp.s), STR_FMT(&uri));
+ if(sca_parse_uri(&sf, &uri)<0) return -1;
+ *from = &sf;
}
-
- *from = f;
-
- return( 0 );
+ return ( 0 );
}
- int
+int
sca_get_msg_to_header( sip_msg_t *msg, struct to_body **to )
{
- struct to_body parsed_to;
+ static struct to_body parsed_to;
struct to_body *t = NULL;
+ str uri = STR_NULL;
- assert( msg != NULL );
assert( to != NULL );
+ if(sca_get_avp_value(to_uri_avp_type, to_uri_avp, &uri)<0) {
+ assert( msg != NULL );
- if ( SCA_HEADER_EMPTY( msg->to )) {
- LM_ERR( "Empty To header" );
- return( -1 );
- }
- t = get_to( msg );
- if ( t == NULL ) {
- parse_to( msg->to->body.s,
- msg->to->body.s + msg->to->body.len + 1, /* end of buffer */
- &parsed_to );
- if ( parsed_to.error != PARSE_OK ) {
- LM_ERR( "Bad To header" );
- return( -1 );
- }
- t = &parsed_to;
- }
+ if ( SCA_HEADER_EMPTY( msg->to )) {
+ LM_ERR( "Empty To header" );
+ return( -1 );
+ }
+ t = get_to( msg );
+ if ( t == NULL ) {
+ parse_to( msg->to->body.s,
+ msg->to->body.s + msg->to->body.len + 1, /* end of buffer */
+ &parsed_to );
+ if ( parsed_to.error != PARSE_OK ) {
+ LM_ERR( "Bad To header" );
+ return( -1 );
+ }
+ t = &parsed_to;
+ }
- /* ensure the URI is parsed for future use */
- if ( parse_uri( t->uri.s, t->uri.len, GET_TO_PURI( msg )) < 0 ) {
- LM_ERR( "Failed to parse To URI %.*s", STR_FMT( &t->uri ));
- return( -1 );
+ /* ensure the URI is parsed for future use */
+ if ( parse_uri( t->uri.s, t->uri.len, GET_TO_PURI( msg )) < 0 ) {
+ LM_ERR( "Failed to parse To URI %.*s", STR_FMT( &t->uri ));
+ return( -1 );
+ }
+ *to = t;
+ } else {
+ LM_DBG("using $avp(%.*s)[%.*s] as to uri\n",
+ STR_FMT(&to_uri_avp.s), STR_FMT(&uri));
+ if(sca_parse_uri(&parsed_to, &uri)<0) return -1;
+ *to = &parsed_to;
}
-
- *to = t;
-
- return( 0 );
+ return ( 0 );
}
/* count characters requiring escape as defined by escape_common */

@ -0,0 +1,183 @@
From: Victor Seva <vseva@sipwise.com>
Date: Thu, 20 Apr 2017 12:19:08 +0200
Subject: sca: use rr is_direction() to detect which tag to use for search
Change-Id: I17ac925867ce5897b7db93729a4e29edcefe922a
---
modules/sca/sca.c | 10 +++++++++-
modules/sca/sca.h | 1 +
modules/sca/sca_call_info.c | 47 +++++++++++++++++++++++++++++++++++++--------
modules/sca/sca_common.h | 1 +
4 files changed, 50 insertions(+), 9 deletions(-)
diff --git a/modules/sca/sca.c b/modules/sca/sca.c
index 99d2ac1..f8010e9 100644
--- a/modules/sca/sca.c
+++ b/modules/sca/sca.c
@@ -45,7 +45,9 @@ sca_mod *sca = NULL;
/* EXTERNAL API */
db_func_t dbf; /* db api */
struct tm_binds tmb; /* tm functions for sending messages */
-sl_api_t slb; /* sl callback, function for getting to-tag */
+struct rr_binds rrb; /* rr functions for detecting direction */
+sl_api_t slb; /* sl callback, function for getting to-tag */
+
/* avps */
unsigned short from_uri_avp_type;
@@ -377,6 +379,12 @@ sca_mod_init( void )
}
sca->tm_api = &tmb;
+ if ( load_rr_api( &rrb ) != 0 ) {
+ LM_ERR( "Failed to initialize required rr API" );
+ goto error;
+ }
+ sca->rr_api = &rrb;
+
if ( sca_bind_sl( sca, &slb ) != 0 ) {
LM_ERR( "Failed to initialize required sl API" );
goto error;
diff --git a/modules/sca/sca.h b/modules/sca/sca.h
index 69fed94..3dee96b 100644
--- a/modules/sca/sca.h
+++ b/modules/sca/sca.h
@@ -49,6 +49,7 @@ struct _sca_mod {
db_func_t *db_api;
struct tm_binds *tm_api;
+ struct rr_binds *rr_api;
sl_api_t *sl_api;
};
typedef struct _sca_mod sca_mod;
diff --git a/modules/sca/sca_call_info.c b/modules/sca/sca_call_info.c
index 5592a68..cbd9b9b 100644
--- a/modules/sca/sca_call_info.c
+++ b/modules/sca/sca_call_info.c
@@ -1370,6 +1370,7 @@ sca_call_info_ack_from_handler( sip_msg_t *msg, str *from_aor, str *to_aor )
sca_appearance *app;
struct to_body *from;
struct to_body *to;
+ str *tag;
int slot_idx = -1;
int state = SCA_APPEARANCE_STATE_IDLE;
@@ -1383,15 +1384,21 @@ sca_call_info_ack_from_handler( sip_msg_t *msg, str *from_aor, str *to_aor )
}
if ( sca_uri_lock_if_shared_appearance( sca, from_aor, &slot_idx )) {
+ if(sca->rr_api->is_direction(msg, RR_FLOW_UPSTREAM)==0) {
+ LM_DBG("upstream direction detected\n");
+ tag = &to->tag_value;
+ } else {
+ tag = &from->tag_value;
+ }
app = sca_appearance_for_tags_unsafe( sca, from_aor,
- &msg->callid->body, &from->tag_value, NULL, slot_idx );
+ &msg->callid->body, tag, NULL, slot_idx );
if ( app == NULL ) {
LM_ERR( "sca_call_info_ack_cb: No appearance for %.*s matching "
"call-id <%.*s> and from-tag <%.*s>", STR_FMT( from_aor ),
- STR_FMT( &msg->callid->body ), STR_FMT( &from->tag_value ));
+ STR_FMT( &msg->callid->body ), STR_FMT( tag ));
goto done;
}
-
+
/*
* Polycom's music-on-hold implementation uses an INVITE with
* an empty body to get the remote party's SDP info, then INVITEs
@@ -1430,11 +1437,12 @@ done:
void
sca_call_info_ack_cb( struct cell *t, int type, struct tmcb_params *params )
{
- struct to_body *to;
+ struct to_body *to, *from;
sca_appearance *app = NULL;
str from_aor = STR_NULL;
str to_aor = STR_NULL;
int slot_idx = -1;
+ str *tag;
if ( !(type & TMCB_E2EACK_IN)) {
return;
@@ -1463,8 +1471,18 @@ sca_call_info_ack_cb( struct cell *t, int type, struct tmcb_params *params )
}
/* on ACK, ensure SCA callee state is promoted to ACTIVE. */
+ if(sca->rr_api->is_direction(params->req, RR_FLOW_UPSTREAM)==0) {
+ LM_DBG("upstream direction detected\n");
+ if ( sca_get_msg_from_header( params->req, &from ) < 0 ) {
+ LM_ERR( "failed to get From-header" );
+ goto done;
+ }
+ tag = &from->tag_value;
+ } else {
+ tag = &to->tag_value;
+ }
app = sca_appearance_for_tags_unsafe( sca, &to_aor,
- &params->req->callid->body, &to->tag_value, NULL, slot_idx );
+ &params->req->callid->body, tag, NULL, slot_idx );
if ( app && app->state == SCA_APPEARANCE_STATE_ACTIVE_PENDING ) {
LM_DBG( "promoting %.*s appearance-index %d to active",
STR_FMT( &to_aor ), app->index );
@@ -1550,6 +1568,7 @@ sca_call_info_bye_handler( sip_msg_t *msg, sca_call_info *call_info,
sca_appearance *app = NULL;
int slot_idx = -1;
int rc = -1;
+ str *tag = NULL;
if ( msg->first_line.type == SIP_REQUEST ) {
if ( SCA_CALL_INFO_IS_SHARED_CALLER( call_info )) {
@@ -1567,15 +1586,21 @@ sca_call_info_bye_handler( sip_msg_t *msg, sca_call_info *call_info,
}
if ( app == NULL ) {
/* try to find it by tags */
+ if(sca->rr_api->is_direction(msg, RR_FLOW_UPSTREAM)==0) {
+ LM_DBG("upstream direction detected\n");
+ tag = &to->tag_value;
+ } else {
+ tag = &from->tag_value;
+ }
app = sca_appearance_for_tags_unsafe( sca, from_aor,
- &msg->callid->body, &from->tag_value, NULL, slot_idx );
+ &msg->callid->body, tag, 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 ));
+ STR_FMT( tag ));
goto done;
}
@@ -1615,8 +1640,14 @@ sca_call_info_bye_handler( sip_msg_t *msg, sca_call_info *call_info,
goto done;
}
+ if(sca->rr_api->is_direction(msg, RR_FLOW_UPSTREAM)==0) {
+ LM_DBG("upstream direction detected\n");
+ tag = &from->tag_value;
+ } else {
+ tag = &to->tag_value;
+ }
app = sca_appearance_for_tags_unsafe( sca, to_aor,
- &msg->callid->body, &to->tag_value,
+ &msg->callid->body, tag,
NULL, slot_idx );
if ( app == NULL ) {
LM_INFO( "sca_call_info_bye_handler: no in-use callee "
diff --git a/modules/sca/sca_common.h b/modules/sca/sca_common.h
index 8b9db4a..2fbcc63 100644
--- a/modules/sca/sca_common.h
+++ b/modules/sca/sca_common.h
@@ -49,6 +49,7 @@
/* bound API headers */
#include "../../modules/sl/sl.h"
#include "../../modules/tm/tm_load.h"
+#include "../../modules/rr/api.h"
/* convenience macros */
Loading…
Cancel
Save