Ejemplo n.º 1
0
static pjsip_sub_state_hdr* 
pjsip_sub_state_hdr_clone(pj_pool_t *pool, 
			  const pjsip_sub_state_hdr *rhs)
{
    pjsip_sub_state_hdr *hdr = pjsip_sub_state_hdr_create(pool);
    pj_strdup(pool, &hdr->sub_state, &rhs->sub_state);
    pj_strdup(pool, &hdr->reason_param, &rhs->reason_param);
    hdr->retry_after = rhs->retry_after;
    hdr->expires_param = rhs->expires_param;
    pjsip_param_clone(pool, &hdr->other_param, &rhs->other_param);
    return hdr;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
0
/*
 * Parse Subscription-State header.
 */
static pjsip_hdr* parse_hdr_sub_state( pjsip_parse_ctx *ctx )
{
    pjsip_sub_state_hdr *hdr = pjsip_sub_state_hdr_create(ctx->pool);
    const pj_str_t reason = { "reason", 6 },
		   expires = { "expires", 7 },
		   retry_after = { "retry-after", 11 };
    const pjsip_parser_const_t *pc = pjsip_parser_const();

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

    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, &reason) == 0) {
	    hdr->reason_param = pvalue;

	} else if (pj_stricmp(&pname, &expires) == 0) {
	    hdr->expires_param = pj_strtoul(&pvalue);

	} else if (pj_stricmp(&pname, &retry_after) == 0) {
	    hdr->retry_after = pj_strtoul(&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;
}
Ejemplo n.º 4
0
/*
 * Send notify.
 */
PJ_DEF(pj_status_t) pjsip_event_sub_notify(pjsip_event_sub *sub,
					   pjsip_event_sub_state new_state,
					   const pj_str_t *reason,
					   pjsip_msg_body *body)
{
    pjsip_tx_data *tdata;
    pjsip_sub_state_hdr *ss_hdr;
    const pjsip_route_hdr *route;
    pj_time_val now;
    pj_status_t status;
    pjsip_event_sub_state old_state = sub->state;

    pj_gettimeofday(&now);

    pj_assert(sub->role == PJSIP_ROLE_UAS);
    if (sub->role != PJSIP_ROLE_UAS)
	return -1;

    PJ_LOG(4,(THIS_FILE, "event_sub%p (%s): sending NOTIFY", 
			 sub, state[new_state].ptr));

    /* Lock subscription. */
    pj_mutex_lock(sub->mutex);

    /* Can not send NOTIFY if current state is NULL. We can accept TERMINATED. */
    if (sub->state==PJSIP_EVENT_SUB_STATE_NULL) {
	pj_assert(0);
	pj_mutex_unlock(sub->mutex);
	return -1;
    }

    /* Update state no matter what. */
    sub_set_state(sub, new_state);

    /* Create transmit data. */
    tdata = pjsip_endpt_create_request_from_hdr( sub->endpt,
						 &NOTIFY,
						 sub->to->uri,
						 sub->from, sub->to,
						 sub->contact, sub->call_id,
						 sub->cseq++,
						 NULL);
    if (!tdata) {
	pj_mutex_unlock(sub->mutex);
	return -1;
    }

    /* Add Event header. */
    pjsip_msg_add_hdr(tdata->msg, pjsip_hdr_shallow_clone(tdata->pool, sub->event));

    /* Add Subscription-State header. */
    ss_hdr = pjsip_sub_state_hdr_create(tdata->pool);
    ss_hdr->sub_state = state[new_state];
    ss_hdr->expires_param = sub->expiry_time.sec - now.sec;
    if (ss_hdr->expires_param < 0)
	ss_hdr->expires_param = 0;
    if (reason)
	pj_strdup(tdata->pool, &ss_hdr->reason_param, reason);
    pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)ss_hdr);

    /* Add Allow-Events header. */
    pjsip_msg_add_hdr( tdata->msg, 
		       pjsip_hdr_shallow_clone(tdata->pool, mgr.allow_events));

    /* Add authentication */
    pjsip_auth_init_req( sub->pool, tdata, &sub->auth_sess,
			 sub->cred_cnt, sub->cred_info);

    /* Route set. */
    route = sub->route_set.next;
    while (route != &sub->route_set) {
	pj_list_insert_before( &tdata->msg->hdr,
			       pjsip_hdr_shallow_clone(tdata->pool, route));
	route = route->next;
    }

    /* Attach body. */
    tdata->msg->body = body;

    /* That's it, send! */
    status = pjsip_endpt_send_request( sub->endpt, tdata, -1, sub, &on_notify_response);
    if (status == 0)
	sub->pending_tsx++;

    /* If terminated notify application. */
    if (new_state!=old_state && new_state==PJSIP_EVENT_SUB_STATE_TERMINATED) {
	if (sub->cb.on_sub_terminated) {
	    sub->pending_tsx++;
	    (*sub->cb.on_sub_terminated)(sub, reason);
	    sub->pending_tsx--;
	}
    }

    /* Unlock subscription. */
    pj_mutex_unlock(sub->mutex);

    if (status != 0) {
	PJ_LOG(4,(THIS_FILE, "event_sub%p (%s): failed to send NOTIFY", 
			     sub, state[sub->state].ptr));
    }

    if (sub->delete_flag && sub->pending_tsx <= 0) {
	pjsip_event_sub_destroy(sub);
    }
    return status;
}