Esempio n. 1
0
/*
 * Parse Event header.
 */
static pjsip_hdr *parse_hdr_event(pjsip_parse_ctx *ctx)
{
    pjsip_event_hdr *hdr = pjsip_event_hdr_create(ctx->pool);
    const pj_str_t id_param = { "id", 2 };
    const pjsip_parser_const_t *pc = pjsip_parser_const();

    pj_scan_get(ctx->scanner, &pc->pjsip_TOKEN_SPEC, &hdr->event_type);

    while (*ctx->scanner->curptr == ';') {
	pj_str_t pname, pvalue;

	pj_scan_get_char(ctx->scanner);
	pjsip_parse_param_imp(ctx->scanner, ctx->pool, &pname, &pvalue, 0);

	if (pj_stricmp(&pname, &id_param)==0) {
	    hdr->id_param = pvalue;
	} else {
	    pjsip_param *param = PJ_POOL_ALLOC_T(ctx->pool, pjsip_param);
	    param->name = pname;
	    param->value = pvalue;
	    pj_list_push_back(&hdr->other_param, param);
	}
    }
    pjsip_parse_end_hdr_imp( ctx->scanner );
    return (pjsip_hdr*)hdr;
}
Esempio n. 2
0
static pjsip_event_hdr* pjsip_event_hdr_clone( pj_pool_t *pool, 
					       const pjsip_event_hdr *rhs)
{
    pjsip_event_hdr *hdr = pjsip_event_hdr_create(pool);
    pj_strdup(pool, &hdr->event_type, &rhs->event_type);
    pj_strdup(pool, &hdr->id_param, &rhs->id_param);
    pjsip_param_clone(pool, &hdr->other_param, &rhs->other_param);
    return hdr;
}
Esempio n. 3
0
static int send_unsolicited_mwi_notify_to_contact(void *obj, void *arg, int flags)
{
	struct unsolicited_mwi_data *mwi_data = arg;
	struct mwi_subscription *sub = mwi_data->sub;
	struct ast_sip_endpoint *endpoint = mwi_data->endpoint;
	pjsip_evsub_state state = mwi_data->state;
	const struct ast_sip_body *body = mwi_data->body;
	struct ast_sip_contact *contact = obj;
	const char *state_name;
	pjsip_tx_data *tdata;
	pjsip_sub_state_hdr *sub_state;
	pjsip_event_hdr *event;
	const pjsip_hdr *allow_events = pjsip_evsub_get_allow_events_hdr(NULL);

	if (ast_sip_create_request("NOTIFY", NULL, endpoint, NULL, contact, &tdata)) {
		ast_log(LOG_WARNING, "Unable to create unsolicited NOTIFY request to endpoint %s URI %s\n", sub->id, contact->uri);
		return 0;
	}

	if (!ast_strlen_zero(endpoint->subscription.mwi.fromuser)) {
		pjsip_fromto_hdr *from = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_FROM, NULL);
		pjsip_name_addr *from_name_addr = (pjsip_name_addr *) from->uri;
		pjsip_sip_uri *from_uri = pjsip_uri_get_uri(from_name_addr->uri);

		pj_strdup2(tdata->pool, &from_uri->user, endpoint->subscription.mwi.fromuser);
	}

	switch (state) {
	case PJSIP_EVSUB_STATE_ACTIVE:
		state_name = "active";
		break;
	case PJSIP_EVSUB_STATE_TERMINATED:
	default:
		state_name = "terminated";
		break;
	}

	sub_state = pjsip_sub_state_hdr_create(tdata->pool);
	pj_cstr(&sub_state->sub_state, state_name);
	pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *) sub_state);

	event = pjsip_event_hdr_create(tdata->pool);
	pj_cstr(&event->event_type, "message-summary");
	pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *) event);

	pjsip_msg_add_hdr(tdata->msg, pjsip_hdr_shallow_clone(tdata->pool, allow_events));
	ast_sip_add_body(tdata, body);
	ast_sip_send_request(tdata, NULL, endpoint, NULL, NULL);

	return 0;
}
Esempio n. 4
0
/*
 * Create transferee (receiver of REFER request).
 *
 */
PJ_DEF(pj_status_t) pjsip_xfer_create_uas( pjsip_dialog *dlg,
					   const pjsip_evsub_user *user_cb,
					   pjsip_rx_data *rdata,
					   pjsip_evsub **p_evsub )
{
    pjsip_evsub *sub;
    pjsip_xfer *xfer;
    const pj_str_t STR_EVENT = {"Event", 5 };
    pjsip_event_hdr *event_hdr;
    pj_status_t status;

    /* Check arguments */
    PJ_ASSERT_RETURN(dlg && rdata && p_evsub, PJ_EINVAL);

    /* Must be request message */
    PJ_ASSERT_RETURN(rdata->msg_info.msg->type == PJSIP_REQUEST_MSG,
		     PJSIP_ENOTREQUESTMSG);

    /* Check that request is REFER */
    PJ_ASSERT_RETURN(pjsip_method_cmp(&rdata->msg_info.msg->line.req.method,
				      pjsip_get_refer_method())==0,
		     PJSIP_ENOTREFER);

    /* Lock dialog */
    pjsip_dlg_inc_lock(dlg);

    /* The evsub framework expects an Event header in the request,
     * while a REFER request conveniently doesn't have one (pun intended!).
     * So create a dummy Event header.
     */
    if (pjsip_msg_find_hdr_by_name(rdata->msg_info.msg,
				   &STR_EVENT, NULL)==NULL)
    {
	event_hdr = pjsip_event_hdr_create(rdata->tp_info.pool);
	event_hdr->event_type = STR_REFER;
	pjsip_msg_add_hdr(rdata->msg_info.msg, (pjsip_hdr*)event_hdr);
    }

    /* Create server subscription */
    status = pjsip_evsub_create_uas( dlg, &xfer_user, rdata, 
				     PJSIP_EVSUB_NO_EVENT_ID, &sub);
    if (status != PJ_SUCCESS)
	goto on_return;

    /* Create server xfer subscription */
    xfer = PJ_POOL_ZALLOC_T(dlg->pool, pjsip_xfer);
    xfer->dlg = dlg;
    xfer->sub = sub;
    if (user_cb)
	pj_memcpy(&xfer->user_cb, user_cb, sizeof(pjsip_evsub_user));

    /* Attach to evsub */
    pjsip_evsub_set_mod_data(sub, mod_xfer.id, xfer);

    /* Done: */
    *p_evsub = sub;

on_return:
    pjsip_dlg_dec_lock(dlg);
    return status;
}
Esempio n. 5
0
/*
 * Create UAC subscription.
 */
PJ_DEF(pjsip_event_sub*) pjsip_event_sub_create( pjsip_endpoint *endpt,
						 const pj_str_t *from,
						 const pj_str_t *to,
						 const pj_str_t *event,
						 int expires,
						 int accept_cnt,
						 const pj_str_t accept[],
						 void *user_data,
						 const pjsip_event_sub_cb *cb)
{
    pjsip_tx_data *tdata;
    pj_pool_t *pool;
    const pjsip_hdr *hdr;
    pjsip_event_sub *sub;
    PJ_USE_EXCEPTION;

    PJ_LOG(5,(THIS_FILE, "Creating event subscription %.*s to %.*s",
			 event->slen, event->ptr, to->slen, to->ptr));

    /* Create pool for the event subscription. */
    pool = pjsip_endpt_create_pool(endpt, "esub", SUB_POOL_SIZE, SUB_POOL_INC);
    if (!pool) {
	return NULL;
    }

    /* Init subscription. */
    sub = pj_pool_calloc(pool, 1, sizeof(*sub));
    sub->pool = pool;
    sub->endpt = endpt;
    sub->role = PJSIP_ROLE_UAC;
    sub->state = PJSIP_EVENT_SUB_STATE_PENDING;
    sub->state_str = state[sub->state];
    sub->user_data = user_data;
    sub->timer.id = 0;
    sub->default_interval = expires;
    pj_memcpy(&sub->cb, cb, sizeof(*cb));
    pj_list_init(&sub->auth_sess);
    pj_list_init(&sub->route_set);
    sub->mutex = pj_mutex_create(pool, "esub", PJ_MUTEX_RECURSE);
    if (!sub->mutex) {
	pjsip_endpt_destroy_pool(endpt, pool);
	return NULL;
    }

    /* The easiest way to parse the parameters is to create a dummy request! */
    tdata = pjsip_endpt_create_request( endpt, &SUBSCRIBE, to, from, to, from,
					NULL, -1, NULL);
    if (!tdata) {
	pj_mutex_destroy(sub->mutex);
	pjsip_endpt_destroy_pool(endpt, pool);
	return NULL;
    }

    /* 
     * Duplicate headers in the request to our structure. 
     */
    PJ_TRY {
	int i;

	/* From */
	hdr = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_FROM, NULL);
	pj_assert(hdr != NULL);
	sub->from = pjsip_hdr_clone(pool, hdr);
        
	/* To */
	hdr = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_TO, NULL);
	pj_assert(hdr != NULL);
	sub->to = pjsip_hdr_clone(pool, hdr);

	/* Contact. */
	sub->contact = pjsip_contact_hdr_create(pool);
	sub->contact->uri = sub->from->uri;

	/* Call-ID */
	hdr = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CALL_ID, NULL);
	pj_assert(hdr != NULL);
	sub->call_id = pjsip_hdr_clone(pool, hdr);

	/* CSeq */
	sub->cseq = pj_rand() % 0xFFFF;

	/* Event. */
	sub->event = pjsip_event_hdr_create(sub->pool);
	pj_strdup(pool, &sub->event->event_type, event);

	/* Expires. */
	sub->uac_expires = pjsip_expires_hdr_create(pool);
	sub->uac_expires->ivalue = expires;

	/* Accept. */
	sub->local_accept = pjsip_accept_hdr_create(pool);
	for (i=0; i<accept_cnt && i < PJSIP_MAX_ACCEPT_COUNT; ++i) {
	    sub->local_accept->count++;
	    pj_strdup(sub->pool, &sub->local_accept->values[i], &accept[i]);
	}

	/* Register to hash table. */
	create_subscriber_key( &sub->key, pool, PJSIP_ROLE_UAC, 
			       &sub->call_id->id, &sub->from->tag);
	pj_mutex_lock( mgr.mutex );
	pj_hash_set( pool, mgr.ht, sub->key.ptr, sub->key.slen, sub);
	pj_mutex_unlock( mgr.mutex );

    }
    PJ_DEFAULT {
	PJ_LOG(4,(THIS_FILE, "event_sub%p (%s): caught exception %d during init", 
			     sub, state[sub->state].ptr, PJ_GET_EXCEPTION()));

	pjsip_tx_data_dec_ref(tdata);
	pj_mutex_destroy(sub->mutex);
	pjsip_endpt_destroy_pool(endpt, sub->pool);
	return NULL;
    }
    PJ_END;

    /* All set, delete temporary transmit data as we don't need it. */
    pjsip_tx_data_dec_ref(tdata);

    PJ_LOG(4,(THIS_FILE, "event_sub%p (%s): client created, target=%.*s, event=%.*s",
			 sub, state[sub->state].ptr,
			 to->slen, to->ptr, event->slen, event->ptr));

    return sub;
}