Ejemplo n.º 1
0
/*
 * 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);
}
Ejemplo n.º 2
0
    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 );
}