[sr-dev] git:admorten/sca: modules/sca: clear appearance on receipt of out-of-dialog SUBSCRIBE

Andrew Mortensen admorten at isc.upenn.edu
Thu Jun 13 21:39:23 CEST 2013


Module: sip-router
Branch: admorten/sca
Commit: 55dd3bb2f1f4c5675686d49012fcbe08f086d489
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=55dd3bb2f1f4c5675686d49012fcbe08f086d489

Author: Andrew Mortensen <admorten at isc.upenn.edu>
Committer: Andrew Mortensen <admorten at isc.upenn.edu>
Date:   Thu Jun 13 15:34:00 2013 -0400

modules/sca: clear appearance on receipt of out-of-dialog SUBSCRIBE

- If a call-info SUBSCRIBE with no To-tag arrives from a subscriber
  with an active subscription, release any appearances owned by the
  subscriber, on the assumption that the subscriber has lost track
  of SCA (reboot, power/network loss).

---

 modules/sca/sca_appearance.c |   54 ++++++++++++++++++++++++++++++++++++++++++
 modules/sca/sca_appearance.h |    1 +
 modules/sca/sca_subscribe.c  |   22 ++++++++++++++++-
 3 files changed, 76 insertions(+), 1 deletions(-)

diff --git a/modules/sca/sca_appearance.c b/modules/sca/sca_appearance.c
index 7904abb..22d8413 100644
--- a/modules/sca/sca_appearance.c
+++ b/modules/sca/sca_appearance.c
@@ -1087,6 +1087,60 @@ done:
     return( rc );
 }
 
+    int
+sca_appearance_owner_release_all( str *aor, str *owner )
+{
+    sca_appearance_list	*app_list = NULL;
+    sca_appearance	*app, **cur_app, **tmp_app;
+    sca_hash_slot	*slot;
+    sca_hash_entry	*ent;
+    int			slot_idx = -1;
+    int			released = -1;
+
+    slot_idx = sca_uri_lock_shared_appearance( sca, aor );
+    slot = sca_hash_table_slot_for_index( sca->appearances, slot_idx );
+
+    for ( ent = slot->entries; ent != NULL; ent = ent->next ) {
+	if ( ent->compare( aor, ent->value ) == 0 ) {
+	    app_list = (sca_appearance_list *)ent->value;
+	    break;
+	}
+    }
+
+    released = 0;
+
+    if ( app_list == NULL ) {
+	LM_DBG( "sca_appearance_owner_release_all: No appearances for %.*s",
+		STR_FMT( aor ));
+	goto done;
+    }
+
+    for ( cur_app = &app_list->appearances; *cur_app != NULL;
+		cur_app = tmp_app ) {
+	tmp_app = &(*cur_app)->next;
+
+	if ( !SCA_STR_EQ( owner, &(*cur_app)->owner )) {
+	    continue;
+	}
+
+	app = *cur_app;
+	*cur_app = (*cur_app)->next;
+	tmp_app = cur_app;
+
+	if ( app ) {
+	    sca_appearance_free( app );
+	    released++;
+	}
+    }
+
+done:
+    if ( slot_idx >= 0 ) {
+	sca_hash_table_unlock_index( sca->appearances, slot_idx );
+    }
+
+    return( released );
+}
+
     sca_appearance *
 sca_appearance_for_index_unsafe( sca_mod *scam, str *aor, int app_idx,
 	int slot_idx )
diff --git a/modules/sca/sca_appearance.h b/modules/sca/sca_appearance.h
index a1feab7..74d6b39 100644
--- a/modules/sca/sca_appearance.h
+++ b/modules/sca/sca_appearance.h
@@ -140,6 +140,7 @@ int	sca_appearance_update_unsafe( sca_appearance *, int, str *, str *,
 int	sca_appearance_update_index( sca_mod *, str *, int, int, str *,
 					str *, sca_dialog * );
 int	sca_appearance_release_index( sca_mod *, str *, int );
+int	sca_appearance_owner_release_all( str *, str * );
 int	sca_appearance_state_for_index( sca_mod *, str *, int );
 sca_appearance	*sca_appearance_for_index_unsafe( sca_mod *, str *, int, int );
 sca_appearance	*sca_appearance_for_dialog_unsafe( sca_mod *, str *,
diff --git a/modules/sca/sca_subscribe.c b/modules/sca/sca_subscribe.c
index cf8feb7..1b8107e 100644
--- a/modules/sca/sca_subscribe.c
+++ b/modules/sca/sca_subscribe.c
@@ -1120,6 +1120,7 @@ sca_handle_subscribe( sip_msg_t *msg, char *p1, char *p2 )
     int			app_idx = SCA_CALL_INFO_APPEARANCE_INDEX_ANY;
     int			idx = -1;
     int			rc = -1;
+    int			released = 0;
 
     if ( parse_headers( msg, HDR_EOH_F, 0 ) < 0 ) {
 	LM_ERR( "header parsing failed: bad request" );
@@ -1227,6 +1228,22 @@ sca_handle_subscribe( sip_msg_t *msg, char *p1, char *p2 )
 		}
 		req_sub.index = app_idx;
 	    }
+	} else {
+	    if ( SCA_STR_EMPTY( to_tag )) {
+		/*
+		 * if the subscriber owns any active appearances, clear them.
+		 * we assume that an out-of-dialog SUBSCRIBE for a subscriber
+		 * with active appearances is indicative of a reboot.
+		 */
+		released = sca_appearance_owner_release_all(
+						&req_sub.target_aor,
+						&req_sub.subscriber );
+		if ( released ) {
+		    LM_INFO( "sca_handle_subscribe: released %d appearances "
+				"for subscriber %.*s", released,
+				STR_FMT( &req_sub.subscriber ));
+		}
+	    }
 	}
     } else {
 	/* in-dialog request, but we didn't find it. */
@@ -1268,6 +1285,9 @@ sca_handle_subscribe( sip_msg_t *msg, char *p1, char *p2 )
 	}
     }
 
+    sca_hash_table_unlock_index( sca->subscriptions, idx );
+    idx = -1;
+
     status = sca_ok_status_for_event( event_type );
     status_text = sca_ok_text_for_event( event_type );
     if ( sca_subscription_reply( sca, status, status_text, event_type,
@@ -1287,7 +1307,7 @@ sca_handle_subscribe( sip_msg_t *msg, char *p1, char *p2 )
 	goto done;
     }
 
-    if ( req_sub.event == SCA_EVENT_TYPE_LINE_SEIZE ) {
+    if ( req_sub.event == SCA_EVENT_TYPE_LINE_SEIZE || released ) {
 	if ( sca_notify_call_info_subscribers( sca, &req_sub.target_aor) < 0 ) {
 	    LM_ERR( "SCA %s NOTIFY to all %.*s subscribers failed",
 		    sca_event_name_from_type( req_sub.event ),




More information about the sr-dev mailing list