From: Sipwise Development Team <support@sipwise.com>
Date: Thu, 26 Mar 2020 10:06:46 +0100
Subject: sca-call-info-unsubscribe

---
 src/modules/sca/sca_subscribe.c | 28 ++++++++++++++++++++++++++--
 1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/src/modules/sca/sca_subscribe.c b/src/modules/sca/sca_subscribe.c
index 14c6062..86d348d 100644
--- a/src/modules/sca/sca_subscribe.c
+++ b/src/modules/sca/sca_subscribe.c
@@ -1160,6 +1160,8 @@ int ki_sca_handle_subscribe(sip_msg_t *msg, str *uri_to, str *uri_from)
 	int released = 0;
 	int_str val;
 	sca_to_body_t tmp_to;
+	sca_hash_slot *slot = NULL;
+	sca_hash_entry *ent = NULL;
 
 	memset(&tmp_to, 0, sizeof(tmp_to));
 	if(parse_headers(msg, HDR_EOH_F, 0) < 0) {
@@ -1252,12 +1254,17 @@ int ki_sca_handle_subscribe(sip_msg_t *msg, str *uri_to, str *uri_from)
 		}
 	}
 
+	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,
@@ -1314,10 +1321,25 @@ int ki_sca_handle_subscribe(sip_msg_t *msg, str *uri_to, str *uri_from)
 					LM_INFO("sca_handle_subscribe: released %d appearances "
 							"for subscriber %.*s\n",
 							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(
@@ -1356,6 +1378,8 @@ int ki_sca_handle_subscribe(sip_msg_t *msg, str *uri_to, str *uri_from)
 			// we got an in-dialog SUBSCRIBE with an "Expires: 0" header,
 			// 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;
 		}
 	}
