Esempio n. 1
0
int Notify2Xmpp(struct sip_msg* msg, char* s1, char* s2)
{
	struct to_body *pto, *pfrom= NULL;
	str to_uri;
	str from_uri={0, 0};
	struct hdr_field* hdr= NULL;
	str body;
	xmlDocPtr doc= NULL;
	int is_terminated= 0;
	str id;
	ua_pres_t dialog;
	int event_flag= 0;
	char buf_to[256];

	memset(&dialog, 0, sizeof(ua_pres_t));

	LM_DBG("start...\n\n");

	if( parse_headers(msg,HDR_EOH_F, 0)==-1 )
	{
		LM_ERR("parsing headers\n");
		return -1;
	}
	if((!msg->event ) ||(msg->event->body.len<=0))
	{
		LM_ERR("Missing event header field value\n");
		return -1;
	}

	if( msg->to==NULL || msg->to->body.s==NULL)
	{
		LM_ERR("cannot parse TO header\n");
		return -1;
	}

	pto = get_to(msg);
	if (pto == NULL || pto->error != PARSE_OK) {
		LM_ERR("failed to parse TO header\n");
		return -1;
	}

	dialog.watcher_uri= &pto->uri;

	URI_ADD_NULL_TERM(to_uri, buf_to, dialog.watcher_uri);

	if (pto->tag_value.s==NULL || pto->tag_value.len==0 )
	{
		LM_ERR("to tag value not parsed\n");
		goto error;
	}
	id=  pto->tag_value;
	dialog.from_tag= id;

	if( msg->callid==NULL || msg->callid->body.s==NULL)
	{
		LM_ERR("cannot parse callid header\n");
		goto error;
	}
	dialog.call_id = msg->callid->body;

	if (!msg->from || !msg->from->body.s)
	{
		LM_ERR("ERROR cannot find 'from' header!\n");
		goto error;
	}
	if (msg->from->parsed == NULL)
	{
		/* parsing from header */
		if ( parse_from_header( msg )<0 )
		{
			LM_ERR("ERROR cannot parse From header\n");
			goto error;
		}
	}
	pfrom = (struct to_body*)msg->from->parsed;
	dialog.pres_uri= &pfrom->uri;

	from_uri.s = xmpp_uri_sip2xmpp(dialog.pres_uri);
	if(from_uri.s == 0)
	{
		LM_ERR("Failed to translate uri from sip to xmpp [%.*s]\n",
				dialog.pres_uri->len, dialog.pres_uri->s);
		goto error;
	}
	from_uri.len= strlen(from_uri.s);

	if( pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0)
	{
		LM_ERR("no from tag value present\n");
		goto error;
	}

	dialog.to_tag= pfrom->tag_value;
	dialog.flag|= XMPP_SUBSCRIBE;
	if(msg->event->body.len== 8 &&
			(strncasecmp(msg->event->body.s,"presence",8 )==0))
		event_flag|= PRESENCE_EVENT;
	else
	if(msg->event->body.len== 14 &&
			(strncasecmp(msg->event->body.s,"presence.winfo",14 )==0))
		event_flag|= PWINFO_EVENT;
	else
	{
		LM_ERR("wrong event\n");
		goto error;
	}
	dialog.event= event_flag;

	if(pua_is_dialog(&dialog)< 0) // verify if within a stored dialog
	{
		LM_ERR("Notify in a non existing dialog\n");
		goto error;
	}
	/*constructing the xml body*/
	if(get_content_length(msg) == 0 )
	{
		body.s= NULL;
		body.len= 0;
	}
	else
	{
		if ( get_body(msg,&body)!=0 || body.len==0)
		{
			LM_ERR("cannot extract body from msg\n");
			goto error;
		}
	}

	/* treat the two cases: event= presence & event=presence.winfo */
	if(event_flag & PRESENCE_EVENT)
	{
		LM_DBG("PRESENCE\n");
		hdr = get_header_by_static_name( msg, "Subscription-State" );
		if(hdr && strncasecmp(hdr->body.s,"terminated", 10)== 0)
		{
			/* chack if reason timeout => don't send notification */
			if(strncasecmp(hdr->body.s+11,"reason=timeout", 14)== 0)
			{
				LM_DBG("Received Notification with state"
					"terminated; reason= timeout=> don't send notification\n");
				return 1;
			}
			is_terminated= 1;

		}

		if(build_xmpp_content(&to_uri, &from_uri, &body, &id, is_terminated)< 0)
		{
			LM_ERR("in function build_xmpp_content\n");
			goto error;
		}
		xmlFreeDoc(doc);
	}
	else
	{
		if(event_flag & PWINFO_EVENT)
		{
			LM_DBG("PRESENCE.WINFO\n");
			hdr = get_header_by_static_name( msg, "Subscription-State" );
			if(hdr && strncasecmp(hdr->body.s,"terminated", 10)== 0)
			{
				LM_DBG("Notify for presence.winfo with"
					" Subscription-State terminated- should not translate\n");
				goto error;
			}
			if(winfo2xmpp(&to_uri, &body, &id)< 0)
			{
				LM_ERR("while sending subscription\n");
				goto error;
			}

		}
		else
		{
			LM_ERR("Missing or unsupported event header field value\n");
			goto error;
		}

	}
	return 1;

error:
	if(doc)
		xmlFreeDoc(doc);
	return 0;
}
Esempio n. 2
0
int Notify2Xmpp(struct sip_msg* msg, char* s1, char* s2)
{
	struct to_body *pto, TO = {0}, *pfrom = NULL;
	str to_uri;
	char* uri= NULL;
	str from_uri;
	struct hdr_field* hdr= NULL;
	str body;
	int is_terminated= 0;
	str id;
	ua_pres_t dialog;
	int event_flag= 0;

	memset(&dialog, 0, sizeof(ua_pres_t));

	LM_DBG("start...\n\n");

	if( parse_headers(msg,HDR_EOH_F, 0)==-1 )
	{
		LM_ERR("parsing headers\n");
		return -1;
	}
	if((!msg->event ) ||(msg->event->body.len<=0))
	{
		LM_ERR("Missing event header field value\n");
		return -1;
	}

	if( msg->to==NULL || msg->to->body.s==NULL)
	{
		LM_ERR("cannot parse TO header\n");
		return -1;
	}

	if(msg->to->parsed != NULL)
	{
		pto = (struct to_body*)msg->to->parsed;
		LM_DBG("'To' header ALREADY PARSED:<%.*s>\n",pto->uri.len,pto->uri.s);
	}
	else
	{
		parse_to(msg->to->body.s,msg->to->body.s + msg->to->body.len + 1, &TO);
		if(TO.uri.len <= 0)
		{
			LM_ERR("'To' header NOT parsed\n");
			goto error;
		}
		pto = &TO;
	}

	dialog.watcher_uri= &pto->uri;

	uri=(char*)pkg_malloc(sizeof(char)*( pto->uri.len+1));
	if(uri== NULL)
	{
		LM_ERR("no more memory\n");
		goto error;
	}
	memcpy(uri, pto->uri.s, pto->uri.len);
	uri[pto->uri.len]= '\0';
	to_uri.s= duri_sip_xmpp(uri);
	if(to_uri.s== NULL)
	{
		LM_ERR("while decoding sip uri in xmpp\n");
		pkg_free(uri);
		goto error;
	}
	to_uri.len= strlen(to_uri.s);
	pkg_free(uri);

	if (pto->tag_value.s==NULL || pto->tag_value.len==0 )
	{
		LM_ERR("to tag value not parsed\n");
		goto error;
	}
	id=  pto->tag_value;
	dialog.from_tag= id;

	if( msg->callid==NULL || msg->callid->body.s==NULL)
	{
		LM_ERR("cannot parse callid header\n");
		goto error;
	}
	dialog.call_id = msg->callid->body;

	if (!msg->from || !msg->from->body.s)
	{
		LM_ERR("ERROR cannot find 'from' header!\n");
		goto error;
	}
	if (msg->from->parsed == NULL)
	{
		LM_ERR("'From' header not parsed\n");
		/* parsing from header */
		if ( parse_from_header( msg )<0 )
		{
			LM_ERR("ERROR cannot parse From header\n");
			goto error;
		}
	}
	pfrom = (struct to_body*)msg->from->parsed;
	dialog.pres_uri= &pfrom->uri;

	uri=(char*)pkg_malloc(sizeof(char)*( pfrom->uri.len+1));
	if(uri== NULL)
	{
		LM_ERR("no more memory\n");
		goto error;
	}
	memcpy(uri, pfrom->uri.s, pfrom->uri.len);
	uri[pfrom->uri.len]= '\0';

	from_uri.s= euri_sip_xmpp(uri);
	if(from_uri.s== NULL)
	{
		LM_ERR("while encoding sip uri in xmpp\n");
		pkg_free(uri);
		goto error;
	}
	from_uri.len= strlen(from_uri.s);
	pkg_free(uri);

	if( pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0)
	{
		LM_ERR("no from tag value present\n");
		goto error;
	}

	dialog.to_tag= pfrom->tag_value;
	dialog.flag|= XMPP_SUBSCRIBE;
	if(msg->event->body.len== 8 &&
			(strncmp(msg->event->body.s,"presence",8 )==0))
		event_flag|= PRESENCE_EVENT;
	else
		if(msg->event->body.len== 14 &&
				(strncmp(msg->event->body.s,"presence.winfo",14 )==0))
			event_flag|= PWINFO_EVENT;
		else
		{
			LM_ERR("wrong event\n");
			goto error;
		}
	dialog.event= event_flag;

	if(pua_is_dialog(&dialog)< 0) // verify if within a stored dialog
	{
		LM_ERR("Notify in a non existing dialog\n");
		goto error;
	}
	/*constructing the xml body*/
	if(get_content_length(msg) == 0 )
	{
		body.s= NULL;
		body.len= 0;
	}
	else
	{
		body.s=get_body(msg);
		if (body.s== NULL)
		{
			LM_ERR("cannot extract body from msg\n");
			goto error;
		}
		body.len = get_content_length( msg );
	}

	/* treat the two cases: event= presence & event=presence.winfo */
	if(event_flag & PRESENCE_EVENT)
	{
		LM_DBG("PRESENCE\n");
		hdr = msg->headers;
		while (hdr!= NULL)
		{
			if(cmp_hdrname_strzn(&hdr->name, "Subscription-State", 18)==0)
				break;
			hdr = hdr->next;
		}
		if(hdr && strncmp(hdr->body.s,"terminated", 10)== 0)
		{
			/* chack if reason timeout => don't send notification */
			if(strncmp(hdr->body.s+11,"reason=timeout", 14)== 0)
			{
				LM_DBG("Received Notification with state"
						"terminated; reason= timeout=> don't send notification\n");
				return 1;
			}
			is_terminated= 1;

		}

		if(build_xmpp_content(&to_uri, &from_uri, &body, &id, is_terminated)< 0)
		{
			LM_ERR("in function build_xmpp_content\n");
			goto error;
		}
	}
	else
	{
		if(event_flag & PWINFO_EVENT)
		{
			LM_DBG("PRESENCE.WINFO\n");
			hdr = msg->headers;
			while (hdr!= NULL)
			{
				if(cmp_hdrname_strzn(&hdr->name, "Subscription-State", 18)==0)
					break;
				hdr = hdr->next;
			}
			if(hdr && strncmp(hdr->body.s,"terminated", 10)== 0)
			{
				LM_DBG("Notify for presence.winfo with"
						" Subscription-State terminated- should not translate\n");
				goto error;
			}
			if(winfo2xmpp(&to_uri, &body, &id)< 0)
			{
				LM_ERR("while sending subscription\n");
				goto error;
			}

		}
		else
		{
			LM_ERR("Missing or unsupported event header field value\n");
			goto error;
		}

	}
	free_to_params(&TO);
	return 1;

error:
	free_to_params(&TO);
	return 0;
}