Pārlūkot izejas kodu

modules/sca: detect when an AoR is no longer SCA.

Don't, for example, create an appearance for callees that do not send
a Call-Info header, and whose AoR also has no subscribers.
Andrew Mortensen 12 gadi atpakaļ
vecāks
revīzija
97653df1d9
2 mainītis faili ar 66 papildinājumiem un 5 dzēšanām
  1. 22 5
      modules/sca/sca_call_info.c
  2. 44 0
      modules/sca/sca_subscribe.c

+ 22 - 5
modules/sca/sca_call_info.c

@@ -1946,11 +1946,6 @@ sca_call_info_update( sip_msg_t *msg, char *p1, char *p2 )
     /* reset rc to -1 so we don't end up returning 0 to the script */
     /* reset rc to -1 so we don't end up returning 0 to the script */
     rc = -1;
     rc = -1;
 
 
-    if ( sca_call_info_header_remove( msg ) < 0 ) {
-	LM_ERR( "Failed to remove Call-Info header" );
-	return( -1 );
-    }
-
     /* reconcile mismatched Contact users and To/From URIs */
     /* reconcile mismatched Contact users and To/From URIs */
     if ( msg->first_line.type == SIP_REQUEST ) {
     if ( msg->first_line.type == SIP_REQUEST ) {
 	if ( sca_create_canonical_aor( msg, &from_aor ) < 0 ) {
 	if ( sca_create_canonical_aor( msg, &from_aor ) < 0 ) {
@@ -1982,6 +1977,28 @@ sca_call_info_update( sip_msg_t *msg, char *p1, char *p2 )
     if ( sca_uri_is_shared_appearance( sca, &to_aor )) {
     if ( sca_uri_is_shared_appearance( sca, &to_aor )) {
 	call_info.ua_shared |= SCA_CALL_INFO_SHARED_CALLEE;
 	call_info.ua_shared |= SCA_CALL_INFO_SHARED_CALLEE;
     }
     }
+
+    if ( call_info_hdr == NULL ) {
+	if ( SCA_CALL_INFO_IS_SHARED_CALLER( &call_info ) &&
+		msg->first_line.type == SIP_REQUEST ) {
+	    if ( !sca_subscription_aor_has_subscribers(
+				SCA_EVENT_TYPE_CALL_INFO, &from_aor )) {
+		call_info.ua_shared &= ~SCA_CALL_INFO_SHARED_CALLER;
+	    }
+	} else if ( SCA_CALL_INFO_IS_SHARED_CALLEE( &call_info ) &&
+		msg->first_line.type == SIP_REPLY ) {
+	    if ( !sca_subscription_aor_has_subscribers(
+				SCA_EVENT_TYPE_CALL_INFO, &to_aor )) {
+		call_info.ua_shared &= ~SCA_CALL_INFO_SHARED_CALLEE;
+	    }
+	}
+    }
+
+    if ( sca_call_info_header_remove( msg ) < 0 ) {
+	LM_ERR( "Failed to remove Call-Info header" );
+	return( -1 );
+    }
+
     if ( call_info.ua_shared == SCA_CALL_INFO_SHARED_NONE ) {
     if ( call_info.ua_shared == SCA_CALL_INFO_SHARED_NONE ) {
 	LM_DBG( "Neither %.*s nor %.*s are SCA AoRs",
 	LM_DBG( "Neither %.*s nor %.*s are SCA AoRs",
 		STR_FMT( &from_aor ), STR_FMT( &to_aor ));
 		STR_FMT( &from_aor ), STR_FMT( &to_aor ));

+ 44 - 0
modules/sca/sca_subscribe.c

@@ -558,6 +558,50 @@ sca_subscription_db_update_timer( unsigned int ticks, void *param )
     }
     }
 }
 }
 
 
+    int
+sca_subscription_aor_has_subscribers( int event, str *aor )
+{
+    sca_hash_slot	*slot;
+    sca_hash_entry	*e;
+    sca_subscription	*sub;
+    str			sub_key = STR_NULL;
+    char		*event_name;
+    int			len;
+    int			subscribers = 0;
+    int			slot_idx = -1;
+
+    event_name = sca_event_name_from_type( event );
+    len = aor->len + strlen( event_name );
+    sub_key.s = (char *)pkg_malloc( len );
+    if ( sub_key.s == NULL ) {
+	LM_ERR( "Failed to pkg_malloc key to look up %s "
+		"subscription for %.*s", event_name, STR_FMT( aor ));
+	return( -1 );
+    }
+    SCA_STR_COPY( &sub_key, aor );
+    SCA_STR_APPEND_CSTR( &sub_key, event_name );
+
+    slot_idx = sca_hash_table_index_for_key( sca->subscriptions, &sub_key );
+    pkg_free( sub_key.s );
+    sub_key.len = 0;
+
+    slot = sca_hash_table_slot_for_index( sca->subscriptions, slot_idx );
+    sca_hash_table_lock_index( sca->subscriptions, slot_idx );
+
+    for ( e = slot->entries; e != NULL; e = e->next ) {
+	sub = (sca_subscription *)e->value;
+
+	if ( SCA_STR_EQ( &sub->target_aor, aor )) {
+	    subscribers = 1;
+	    break;
+	}
+    }
+
+    sca_hash_table_unlock_index( sca->subscriptions, slot_idx );
+
+    return( subscribers );
+}
+
     sca_subscription *
     sca_subscription *
 sca_subscription_create( str *aor, int event, str *subscriber,
 sca_subscription_create( str *aor, int event, str *subscriber,
 	unsigned int notify_cseq, unsigned int subscribe_cseq, int expire_delta,
 	unsigned int notify_cseq, unsigned int subscribe_cseq, int expire_delta,