Module: sip-router
Branch: admorten/sca
Commit: 55dd3bb2f1f4c5675686d49012fcbe08f086d489
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=55dd3bb…
Author: Andrew Mortensen <admorten(a)isc.upenn.edu>
Committer: Andrew Mortensen <admorten(a)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 ),