Beispiel #1
0
void dialog_publish_multi(char *state, struct str_list* ruris, str *entity, str *peer, str *callid,
	unsigned int initiator, unsigned int lifetime, str *localtag, str *remotetag,
	str *localtarget, str *remotetarget, unsigned short do_pubruri_localcheck) {

	while(ruris) {
		LM_INFO("CALLING dialog_publish for URI %.*s\n",ruris->s.len, ruris->s.s);
		dialog_publish(state,&(ruris->s),entity,peer,callid,initiator,lifetime,localtag,remotetag,localtarget,remotetarget,do_pubruri_localcheck);
		ruris=ruris->next;
	}

}
Beispiel #2
0
int dialoginfo_set(struct sip_msg* msg, char* flag_pv, char* str2)
{
	struct dlg_cell * dlg;
	str peer_uri= {0, 0}; /* constructed from TO display name and RURI */
	struct to_body* from, peer_to_body, FROM, *to;
	str* ruri;
	int len =0,ret=-1;
	char flag= DLG_PUB_AB;
	static char buf[256];
	int buf_len= 255;
	str flag_str;
	char caller_buf[256], callee_buf[256];
	pv_value_t tok;

	peer_to_body.param_lst = FROM.param_lst = NULL;

	if (msg->REQ_METHOD != METHOD_INVITE)
		return 1;

	if(dlg_api.create_dlg(msg,0)< 0)
	{
		LM_ERR("Failed to create dialog\n");
		return -1;
	}

	dlg = dlg_api.get_dlg();

	LM_DBG("new INVITE dialog created: from=%.*s\n",
		dlg->from_uri.len, dlg->from_uri.s);

	from = get_from(msg);
	/* if defined overwrite */
	if(caller_spec_param.s) /* if parameter defined */
	{
		memset(&tok, 0, sizeof(pv_value_t));
		if(pv_get_spec_value(msg, &caller_spec, &tok) < 0)  /* if value set */
		{
			LM_ERR("Failed to get caller value\n");
			return -1;
		}
		if(tok.flags&PV_VAL_STR)
		{
			str caller_str;
			if(tok.rs.len + CRLF_LEN > buf_len)
			{
				LM_ERR("Buffer overflow");
				return -1;
			}
			trim(&tok.rs);
			memcpy(caller_buf, tok.rs.s, tok.rs.len);
			len = tok.rs.len;
			if(strncmp(tok.rs.s+len-CRLF_LEN, CRLF, CRLF_LEN))
			{
				memcpy(caller_buf + len, CRLF, CRLF_LEN);
				len+= CRLF_LEN;
			}

			parse_to(caller_buf, caller_buf+len , &FROM);
			if(FROM.error != PARSE_OK)
			{
				LM_ERR("Failed to parse caller specification - not a valid uri\n");
				goto end;
			}
			from = &FROM;
			caller_str.s = caller_buf;
			caller_str.len = len;
			LM_DBG("caller: %*s- len= %d\n", len, caller_buf, len);
			/* store caller in a dlg variable */
			if(dlg_api.store_dlg_value(dlg, &entity_dlg_var, &caller_str)< 0)
			{
				LM_ERR("Failed to store dialog ruri\n");
				goto end;
			}
		}
	}

	peer_uri.s = callee_buf;
	if(callee_spec_param.s)
	{
		memset(&tok, 0, sizeof(pv_value_t));
		if(pv_get_spec_value(msg, &callee_spec, &tok) < 0)
		{
			LM_ERR("Failed to get callee value\n");
			goto end;
		}
		if(tok.flags&PV_VAL_STR)
		{
			if(tok.rs.len + CRLF_LEN > buf_len)
			{
				LM_ERR("Buffer overflow");
				goto end;
			}
			trim(&tok.rs);
			memcpy(peer_uri.s, tok.rs.s, tok.rs.len);
			len = tok.rs.len;
			if(strncmp(tok.rs.s+len-CRLF_LEN, CRLF, CRLF_LEN))
			{
				memcpy(peer_uri.s + len, CRLF, CRLF_LEN);
				len+= CRLF_LEN;
			}
			peer_uri.len = len;
		}
		else
			goto default_callee;
	}
	else
	{
default_callee:
		ruri = GET_RURI(msg);
		to = get_to(msg);
		len= to->display.len + 2 + ruri->len + CRLF_LEN;
		if(len > buf_len)
		{
			LM_ERR("Buffer overflow\n");
			goto end;
		}
		len = 0;
		if(to->display.len && to->display.s)
		{
			memcpy(peer_uri.s, to->display.s, to->display.len);
			peer_uri.s[to->display.len]='<';
			len = to->display.len + 1;
		}
		memcpy(peer_uri.s + len, ruri->s, ruri->len);
		len+= ruri->len;
		if(to->display.len)
		{
			peer_uri.s[len++]='>';
		}
		memcpy(peer_uri.s + len, CRLF, CRLF_LEN);
		len+= CRLF_LEN;
		peer_uri.len = len;
	}
	LM_DBG("Peer uri = %.*s\n", peer_uri.len, peer_uri.s);

	parse_to(peer_uri.s, peer_uri.s+peer_uri.len, &peer_to_body);
	if(peer_to_body.error != PARSE_OK)
	{
		LM_ERR("Failed to peer uri [%.*s]\n", peer_uri.len, peer_uri.s);
		goto end;
	}

	/* store peer uri in dialog structure */
	if(dlg_api.store_dlg_value(dlg, &peer_dlg_var, &peer_uri)< 0)
	{
		LM_ERR("Failed to store dialog ruri\n");
		goto end;
	}

	/* store flag, if defined  */
	if(flag_pv)
	{
		if(pv_printf(msg, (pv_elem_t*)flag_pv, buf, &buf_len)<0)
		{
			LM_ERR("cannot print the format\n");
			goto end;
		}

		if(!check_flag(buf, buf_len))
		{
			LM_ERR("Wrong value for flag\n");
			goto end;
		}
		flag = buf[0];
		flag_str.s = buf;
		flag_str.len = buf_len;
		if(dlg_api.store_dlg_value(dlg, &flag_dlg_var, &flag_str)< 0)
		{
			LM_ERR("Failed to store dialog ruri\n");
			goto end;
		}
	}

	/* register dialog callbacks which triggers sending PUBLISH */
	if (dlg_api.register_dlgcb(dlg,
		DLGCB_FAILED| DLGCB_CONFIRMED | DLGCB_TERMINATED | DLGCB_EXPIRED |
		DLGCB_RESPONSE_WITHIN | DLGCB_EARLY,
		__dialog_sendpublish, 0, 0) != 0) {
		LM_ERR("cannot register callback for interesting dialog types\n");
		goto end;
	}

#ifdef PUA_DIALOGINFO_DEBUG
	/* dialog callback testing (registered last to be executed first) */
	if (dlg_api.register_dlgcb(dlg,
		DLGCB_FAILED| DLGCB_CONFIRMED | DLGCB_REQ_WITHIN | DLGCB_TERMINATED |
		DLGCB_EXPIRED | DLGCB_EARLY | DLGCB_RESPONSE_FWDED |
		DLGCB_RESPONSE_WITHIN  | DLGCB_MI_CONTEXT | DLGCB_DESTROY,
		__dialog_cbtest, NULL, NULL) != 0) {
		LM_ERR("cannot register callback for all dialog types\n");
		goto end;
	}
#endif

        if(publish_on_trying) {
	        if(flag == DLG_PUB_A || flag == DLG_PUB_AB)
		        dialog_publish("trying", from, &peer_to_body, &(dlg->callid), 1, DEFAULT_CREATED_LIFETIME, 0, 0);

	        if(flag == DLG_PUB_B || flag == DLG_PUB_AB)
		        dialog_publish("trying", &peer_to_body, from, &(dlg->callid), 0, DEFAULT_CREATED_LIFETIME, 0, 0);
        }

	ret=1;
end:
	if (peer_to_body.param_lst)
		free_to_params(&peer_to_body);
	if (FROM.param_lst)
		free_to_params(&FROM);
	return ret;
}
Beispiel #3
0
static void
__dialog_sendpublish(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params)
{
	str tag = {0,0};
	struct to_body from;
	str peer_uri= {0, 0};
	char flag = DLG_PUB_AB;
	str flag_str;
	struct to_body peer_to_body;
	str entity_uri= {0, 0};
	int buf_len = 255;
	struct sip_msg* msg = _params->msg;

	flag_str.s = &flag;
	flag_str.len = 1;

	memset(&from, 0, sizeof(struct to_body));
	memset(&peer_to_body, 0, sizeof(struct to_body));

	from.uri = dlg->from_uri;

	peer_uri.len = buf_len;
	peer_uri.s = (char*)pkg_malloc(buf_len);
	if(peer_uri.s == NULL)
	{
		LM_ERR("No more memory\n");
		goto error;
	}
	/* extract the peer_uri */
	if(dlg_api.fetch_dlg_value(dlg, &peer_dlg_var, &peer_uri, 1) < 0 || peer_uri.len==0)
	{
		LM_ERR("Failed to fetch peer uri dialog variable\n");
		goto error;
	}

	LM_DBG("peer_uri = %.*s\n", peer_uri.len, peer_uri.s);

	parse_to(peer_uri.s, peer_uri.s+peer_uri.len, &peer_to_body);
	if(peer_to_body.error != PARSE_OK)
	{
		LM_ERR("Failed to peer uri [%.*s]\n", peer_uri.len, peer_uri.s);
		goto error;
	}

	/* try to extract the flag */
	dlg_api.fetch_dlg_value(dlg, &flag_dlg_var, &flag_str, 1);
	LM_DBG("flag = %c\n", flag);

	entity_uri.len = buf_len;
	entity_uri.s = (char*)pkg_malloc(buf_len);
	if(entity_uri.s == NULL)
	{
		LM_ERR("No more memory\n");
		goto error;
	}
	/* check if entity is also custom */
	if(dlg_api.fetch_dlg_value(dlg, &entity_dlg_var, &entity_uri, 1) == 0)
	{
		/* overwrite from with this value */
		parse_to(entity_uri.s, entity_uri.s + entity_uri.len, &from);
		if(from.error != PARSE_OK)
		{
			LM_ERR("Wrong format for entity body\n");
			goto error;
		}
		LM_DBG("entity_uri = %.*s\n", entity_uri.len, entity_uri.s);
		LM_DBG("from uri = %.*s\n", from.uri.len, from.uri.s);
	}

	switch (type) {
	case DLGCB_FAILED:
	case DLGCB_TERMINATED:
	case DLGCB_EXPIRED:
		LM_DBG("dialog over, from=%.*s\n", dlg->from_uri.len, dlg->from_uri.s);
		if(flag == DLG_PUB_AB || flag == DLG_PUB_A)
			dialog_publish("terminated", &from, &peer_to_body, &(dlg->callid), 1, 0, 0, 0);
		if(flag == DLG_PUB_AB || flag == DLG_PUB_B)
			dialog_publish("terminated", &peer_to_body, &from, &(dlg->callid), 0, 0, 0, 0);
		break;
	case DLGCB_RESPONSE_WITHIN:
		if (get_cseq(msg)->method_id==METHOD_INVITE) {
			if (msg->flags & nopublish_flag) {
				LM_DBG("nopublish flag was set for this INVITE\n");
				break;
			}
			LM_DBG("nopublish flag not set for this INVITE, will publish\n");
		} else {
			/* no publish for non-INVITEs */
			break;
		}
	case DLGCB_CONFIRMED:
		LM_DBG("dialog confirmed, from=%.*s\n", dlg->from_uri.len, dlg->from_uri.s);
		if(flag == DLG_PUB_AB || flag == DLG_PUB_A)
			dialog_publish("confirmed", &from, &peer_to_body, &(dlg->callid), 1, dlg->lifetime, 0, 0);
		if(flag == DLG_PUB_AB || flag == DLG_PUB_B)
			dialog_publish("confirmed", &peer_to_body, &from, &(dlg->callid), 0, dlg->lifetime, 0, 0);
		break;
	case DLGCB_EARLY:
		LM_DBG("dialog is early, from=%.*s\n", from.uri.len, from.uri.s);
		if (include_tags) {
			/* get to tag*/
			if ( !_params->msg->to && ((parse_headers(_params->msg, HDR_TO_F,0)<0) || !_params->msg->to) ) {
				LM_ERR("bad reply or missing TO hdr :-/\n");
				tag.s = 0;
				tag.len = 0;
			} else {
				tag = get_to(_params->msg)->tag_value;
				if (tag.s==0 || tag.len==0) {
					LM_ERR("missing TAG param in TO hdr :-/\n");
					tag.s = 0;
					tag.len = 0;
				}
			}
			if(flag == DLG_PUB_AB || flag == DLG_PUB_A)
			{
				if (caller_confirmed) {
					dialog_publish("confirmed", &from, &peer_to_body, &(dlg->callid), 1,
						dlg->lifetime, &(dlg->legs[DLG_CALLER_LEG].tag), &tag);
				} else {
					dialog_publish("early", &from, &peer_to_body, &(dlg->callid), 1,
						dlg->lifetime, &(dlg->legs[DLG_CALLER_LEG].tag), &tag);
				}
			}

			if(flag == DLG_PUB_AB || flag == DLG_PUB_B)
			{
				dialog_publish("early", &peer_to_body, &from, &(dlg->callid), 0,
					dlg->lifetime, &tag, &(dlg->legs[DLG_CALLER_LEG].tag));
			}
		} else {
			if(flag == DLG_PUB_AB || flag == DLG_PUB_A)
			{
				if (caller_confirmed) {
					dialog_publish("confirmed", &from, &peer_to_body, &(dlg->callid), 1,
						dlg->lifetime, 0, 0);
				} else {
					dialog_publish("early", &from, &peer_to_body, &(dlg->callid), 1,
						dlg->lifetime, 0, 0);
				}
			}
			if(flag == DLG_PUB_AB || flag == DLG_PUB_B)
			{
				dialog_publish("early", &peer_to_body, &from, &(dlg->callid), 0,
					dlg->lifetime, 0, 0);
			}
		}
		break;
	default:
		LM_ERR("unhandled dialog callback type %d received, from=%.*s\n", type, dlg->from_uri.len, dlg->from_uri.s);
		if(flag == DLG_PUB_AB || flag == DLG_PUB_A)
			dialog_publish("terminated", &from, &peer_to_body, &(dlg->callid), 1, 0, 0, 0);
		if(flag == DLG_PUB_AB || flag == DLG_PUB_B)
			dialog_publish("terminated", &peer_to_body, &from, &(dlg->callid), 0, 0, 0, 0);
	}
error:
	if(peer_uri.s)
		pkg_free(peer_uri.s);
	if(entity_uri.s)
		pkg_free(entity_uri.s);
	if (peer_to_body.param_lst)
		free_to_params(&peer_to_body);
	if (from.param_lst)
		free_to_params(&from);
}