From: Sipwise Development Team <support@sipwise.com>
Date: Thu, 26 Mar 2020 10:06:46 +0100
Subject: sca-fix-pickup-when-upstream-flow

---
 src/modules/sca/sca_call_info.c | 47 ++++++++++++++++++++++++++---------------
 1 file changed, 30 insertions(+), 17 deletions(-)

diff --git a/src/modules/sca/sca_call_info.c b/src/modules/sca/sca_call_info.c
index 8734d3a..ed43fe2 100644
--- a/src/modules/sca/sca_call_info.c
+++ b/src/modules/sca/sca_call_info.c
@@ -947,6 +947,13 @@ int sca_call_info_invite_request_handler(sip_msg_t *msg,
 	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;
+	}
 
 	LM_DBG("For From-AOR %.*s To-AOR: %.*s: From: <%.*s> To: <%.*s> "
 		   "Contact: <%.*s> Call-Info: appearance-index=%d\n",
@@ -960,7 +967,7 @@ int sca_call_info_invite_request_handler(sip_msg_t *msg,
 			< 0) {
 		LM_ERR("sca_call_info_invite_request_handler: failed to register "
 			   "callback for INVITE %.*s ACK\n",
-				STR_FMT(from_aor));
+				STR_FMT(target_aor));
 		goto done;
 	}
 
@@ -978,7 +985,7 @@ int sca_call_info_invite_request_handler(sip_msg_t *msg,
 			< 0) {
 		LM_ERR("sca_call_info_invite_request_handler: failed to register "
 			   "callback for INVITE %.*s ACK\n",
-				STR_FMT(from_aor));
+				STR_FMT(target_aor));
 		goto done;
 	}
 
@@ -1011,16 +1018,16 @@ int sca_call_info_invite_request_handler(sip_msg_t *msg,
 	}
 
 	if(sca_appearance_update_index(
-			   sca, from_aor, call_info->index, state, NULL, NULL, &dialog)
+			   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\n",
-				STR_FMT(from_aor), call_info->index, STR_FMT(&state_str));
+				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\n",
-				STR_FMT(from_aor));
+				STR_FMT(target_aor));
 		goto done;
 	}
 
@@ -1365,6 +1372,7 @@ void 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 = NULL;
 
 	memset(&from, 0, sizeof(from));
 	memset(&to, 0, sizeof(to));
@@ -1378,19 +1386,24 @@ void sca_call_info_ack_from_handler(sip_msg_t *msg, str *from_aor, str *to_aor)
 		goto done;
 	}
 
-	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.hdr->tag_value;
-		} else {
-			tag = &from.hdr->tag_value;
-		}
+	if(sca->rr_api->is_direction(msg, RR_FLOW_UPSTREAM) == 0) {
+		LM_DBG("upstream direction detected\n");
+		target_aor = to_aor;
+		tag = &to.hdr->tag_value;
+	} else {
+		target_aor = from_aor;
+		tag = &from.hdr->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, from_aor, &msg->callid->body, tag, NULL, slot_idx);
+				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>\n",
-					STR_FMT(from_aor), STR_FMT(&msg->callid->body),
+					STR_FMT(target_aor), STR_FMT(&msg->callid->body),
 					STR_FMT(tag));
 			goto done;
 		}
@@ -1418,10 +1431,10 @@ 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\n",
-						STR_FMT(from_aor));
+						STR_FMT(target_aor));
 			}
 		}
 	}
