/* * send a call-info NOTIFY to all subscribers to a given SCA AoR. */ int sca_notify_call_info_subscribers(sca_mod *scam, str *subscription_aor) { sca_hash_slot *slot; sca_hash_entry *e; sca_subscription *sub; str headers = STR_NULL; str hash_key = STR_NULL; char hdrbuf[SCA_HEADERS_MAX_LEN]; char keybuf[512]; char *event_name; int slot_idx; int rc = -1; assert(scam->subscriptions != NULL); assert(!SCA_STR_EMPTY(subscription_aor)); LM_DBG("Notifying ALL subscribers of AOR %.*s due to a SUBSCRIBTION request\n", STR_FMT(subscription_aor)); event_name = sca_event_name_from_type(SCA_EVENT_TYPE_CALL_INFO); if (subscription_aor->len + strlen(event_name) >= sizeof(keybuf)) { LM_ERR("Hash key %.*s + %s is too long\n", STR_FMT(subscription_aor), event_name); return (-1); } hash_key.s = keybuf; SCA_STR_COPY(&hash_key, subscription_aor); SCA_STR_APPEND_CSTR(&hash_key, event_name); slot_idx = sca_hash_table_index_for_key(scam->subscriptions, &hash_key); slot = sca_hash_table_slot_for_index(scam->subscriptions, slot_idx); sca_hash_table_lock_index(scam->subscriptions, slot_idx); for (e = slot->entries; e != NULL; e = e->next) { sub = (sca_subscription *) e->value; if (!SCA_STR_EQ(subscription_aor, &sub->target_aor)) { continue; } if (headers.len == 0) { headers.s = hdrbuf; if (sca_notify_build_headers_from_info(&headers, sizeof(hdrbuf), scam, sub, SCA_CALL_INFO_APPEARANCE_INDEX_ANY) < 0) { LM_ERR("Failed to build NOTIFY headers\n"); goto done; } } // XXX would like this to be wrapped in one location sub->dialog.notify_cseq += 1; if (sca_notify_subscriber_internal(scam, sub, &headers) < 0) { goto done; } } rc = 1; done: sca_hash_table_unlock_index(scam->subscriptions, slot_idx); return (rc); }
int sca_create_canonical_aor_for_ua( sip_msg_t *msg, str *c_aor, int ua_opts ) { struct to_body *tf = NULL; sip_uri_t c_uri; str tf_aor = STR_NULL; str contact_uri = STR_NULL; int rc = -1; assert( msg != NULL ); assert( c_aor != NULL ); memset( c_aor, 0, sizeof( str )); if (( ua_opts & SCA_AOR_TYPE_AUTO )) { if ( msg->first_line.type == SIP_REQUEST ) { ua_opts = SCA_AOR_TYPE_UAC; } else { ua_opts = SCA_AOR_TYPE_UAS; } } if (( ua_opts & SCA_AOR_TYPE_UAC )) { if ( sca_get_msg_from_header( msg, &tf ) < 0 ) { LM_ERR( "sca_create_canonical_aor: failed to get From header" ); goto done; } } else { if ( sca_get_msg_to_header( msg, &tf ) < 0 ) { LM_ERR( "sca_create_canonical_aor: failed to get To header" ); goto done; } } if ( sca_uri_extract_aor( &tf->uri, &tf_aor ) < 0 ) { LM_ERR( "sca_create_canonical_aor: failed to extract AoR from " "URI <%.*s>", STR_FMT( &tf->uri )); goto done; } memset( &c_uri, 0, sizeof( sip_uri_t )); if (( rc = sca_get_msg_contact_uri( msg, &contact_uri )) < 0 ) { LM_ERR( "sca_create_canonical_aor: failed to get contact URI from " "Contact <%.*s>", STR_FMT( &msg->contact->body )); goto done; } if ( rc > 0 ) { if ( parse_uri( contact_uri.s, contact_uri.len, &c_uri ) < 0 ) { LM_ERR( "sca_create_canonical_aor: failed to parse Contact URI " "<%.*s>", STR_FMT( &contact_uri )); rc = -1; goto done; } } if ( SCA_STR_EMPTY( &c_uri.user ) || SCA_STR_EQ( &c_uri.user, &tf->parsed_uri.user )) { /* empty contact header or Contact user matches To/From AoR */ c_aor->s = (char *)pkg_malloc( tf_aor.len ); c_aor->len = tf_aor.len; memcpy( c_aor->s, tf_aor.s, tf_aor.len ); } else { /* Contact user and To/From user mismatch */ if ( sca_aor_create_from_info( c_aor, c_uri.type, &c_uri.user, &tf->parsed_uri.host, &tf->parsed_uri.port ) < 0 ) { LM_ERR( "sca_create_canonical_aor: failed to create AoR from " "Contact <%.*s> and URI <%.*s>", STR_FMT( &contact_uri ), STR_FMT( &tf_aor )); goto done; } } rc = 1; done: return( rc ); }