Exemplo n.º 1
0
int bla_handle_notify(struct sip_msg* msg, char* s1, char* s2)
{
	publ_info_t publ;
	struct to_body *pto= NULL, TO, *pfrom = NULL;
	str body;
	ua_pres_t dialog;
	unsigned int expires= 0;
	struct hdr_field* hdr;
	str subs_state;
	str extra_headers= {0, 0};
	static char buf[255];
	str contact;

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

	if ( parse_headers(msg,HDR_EOH_F, 0)==-1 )
	{
		LM_ERR("parsing headers\n");
		return -1;
	}

	if( msg->to==NULL || msg->to->body.s==NULL)
	{
		LM_ERR("cannot parse TO header\n");
		return -1;
	}
	/* examine the to header */
	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_DBG("'To' header NOT parsed\n");
			return -1;
		}
		pto = &TO;
	}
	publ.pres_uri= &pto->uri;
	dialog.watcher_uri= publ.pres_uri;

	if (pto->tag_value.s==NULL || pto->tag_value.len==0 )
	{
		LM_ERR("NULL to_tag value\n");
		return -1;
	}
	dialog.from_tag= pto->tag_value;

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

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

	if( pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0)
	{
		LM_ERR("no from tag value present\n");
		return -1;
	}
	if ( get_content_length(msg) == 0 )
	{
		LM_DBG("content length= 0\n");
		return 1;
	}
	else
	{
		body.s=get_body(msg);
		if (body.s== NULL)
		{
			LM_ERR("cannot extract body from msg\n");
			return -1;
		}
		body.len = get_content_length( msg );

		if (!bla_body_is_valid( &body ))
		{
			LM_ERR("bad XML body!");
			return -1;
		}
	}
   	
	if(msg->contact== NULL || msg->contact->body.s== NULL)
	{
		LM_ERR("no contact header found");
		return -1;
	}
	if( parse_contact(msg->contact) <0 )
	{
		LM_ERR(" cannot parse contact header\n");
		return -1;
	}

	if(msg->contact->parsed == NULL)
	{
		LM_ERR("cannot parse contact header\n");
		return -1;
	}
	contact = ((contact_body_t* )msg->contact->parsed)->contacts->uri;

	dialog.to_tag= pfrom->tag_value;
	dialog.event= BLA_EVENT;
	dialog.flag= BLA_SUBSCRIBE;
	if(pua_is_dialog(&dialog)< 0)
	{
		LM_ERR("Notify in a non existing dialog\n");
		return -2;
	}

	/* parse Subscription-State and extract expires if existing */
	hdr = get_header_by_static_name( msg, "Subscription-State");
	if( hdr==NULL )
	{
		LM_ERR("No Subscription-State header found\n");
		return -1;
	}
	subs_state= hdr->body;
	if(strncasecmp(subs_state.s, "terminated", 10)== 0)
		expires= 0;
	else
	{
		if(strncasecmp(subs_state.s, "active", 6)== 0 ||
				strncasecmp(subs_state.s, "pending", 7)==0 )
		{
			expires = DEFAULT_EXPIRES;
			char* sep= NULL;
			str exp= {NULL, 0};
			sep= strchr(subs_state.s, ';');
			if(sep)
			{
				if(strncasecmp(sep+1, "expires=", 8)== 0)
				{
					exp.s= sep+ 9;
					sep= exp.s;
					while((*sep)>='0' && (*sep)<='9')
					{
						sep++;
						exp.len++;
					}
					if( str2int(&exp, &expires)< 0)
					{
						LM_ERR("while parsing int\n");
						return -1;
					}
				}
			}
		}
		else
		{
			LM_ERR("unknown Subscription-state token\n");
			return -1;
		}
	}

	/* +2 for ": " between header name and value */
	if ((header_name.len + 2 + contact.len + CRLF_LEN) >= sizeof(buf)) {
		LM_ERR("Sender header too large");
		return -1;
	}

	/* build extra_headers with Sender*/
	extra_headers.s= buf;
	memcpy(extra_headers.s, header_name.s, header_name.len);
	extra_headers.len= header_name.len;
	memcpy(extra_headers.s+extra_headers.len,": ",2);
	extra_headers.len+= 2;
	memcpy(extra_headers.s+ extra_headers.len, contact.s, contact.len);
	extra_headers.len+= contact.len;
	memcpy(extra_headers.s+ extra_headers.len, CRLF, CRLF_LEN);
	extra_headers.len+= CRLF_LEN;

	publ.id= contact;
	publ.body= &body;
	publ.source_flag= BLA_PUBLISH;
	publ.expires= expires;
	publ.event= BLA_EVENT;
	publ.extra_headers= &extra_headers;
	publ.outbound_proxy = presence_server;

	if(pua_send_publish(&publ)< 0)
	{
		LM_ERR("failed to send Publish message\n");
		return -1;
	}

	return 1;
}
Exemplo n.º 2
0
int bla_handle_notify(struct sip_msg* msg, char* s1, char* s2)
{
 	publ_info_t publ;
	struct to_body *pto = NULL, TO = {0}, *pfrom = NULL;
 	str body;
 	ua_pres_t dialog;
 	unsigned int expires= 0;
	struct hdr_field* hdr;
	str subs_state;
	int found= 0;
 	str extra_headers= {0, 0};
 	static char buf[255];
	str contact;

	memset(&publ, 0, sizeof(publ_info_t));
	memset(&dialog, 0, sizeof(ua_pres_t));
 
  	LM_DBG("start\n");
  
  	if ( parse_headers(msg,HDR_EOH_F, 0)==-1 )
  	{
  		LM_ERR("parsing headers\n");
  		return -1;
  	}
  
  	if( msg->to==NULL || msg->to->body.s==NULL)
  	{
  		LM_ERR("cannot parse TO header\n");
  		goto error;
  	}
  	/* examine the to header */
  	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_DBG("'To' header NOT parsed\n");
  			goto error;
  		}
  		pto = &TO;
  	}
  	publ.pres_uri= &pto->uri;
  	dialog.watcher_uri= publ.pres_uri;
  
  	if (pto->tag_value.s==NULL || pto->tag_value.len==0 )
  	{
  		LM_ERR("NULL to_tag value\n");
		goto error;
  	}
  	dialog.from_tag= pto->tag_value;
  
  	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("cannot find 'from' header!\n");
  		goto error;
  	}
  	if (msg->from->parsed == NULL)
  	{
  		LM_DBG(" 'From' header not parsed\n");
  		/* parsing from header */
  		if ( parse_from_header( msg )<0 )
  		{
  			LM_DBG(" ERROR cannot parse From header\n");
  			goto error;
  		}
 	}
 	pfrom = (struct to_body*)msg->from->parsed;
 	dialog.pres_uri= &pfrom->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.event= BLA_EVENT;
 	dialog.flag= BLA_SUBSCRIBE;
 	if(pua_is_dialog(&dialog)< 0)
 	{
 		LM_ERR("Notify in a non existing dialog\n");
 		goto error;
 	}
 	LM_DBG("found a matching dialog\n");
 
 	/* parse Subscription-State and extract expires if existing */
	hdr = msg->headers;
	while (hdr!= NULL)
	{
 		if(cmp_hdrname_strzn(&hdr->name, "Subscription-State",18)==0)
 		{
 			found = 1;
 			break;
 		}
		hdr = hdr->next;
  	}
	if(found==0 )
	{
		LM_ERR("No Subscription-State header found\n");
		goto error;
 	}
 	subs_state= hdr->body;
	if(strncmp(subs_state.s, "terminated", 10)== 0)
 		expires= 0;
 	else
 		if(strncmp(subs_state.s, "active", 6)== 0 ||
				strncmp(subs_state.s, "pending", 7)==0 )
 		{
   			char* sep= NULL;
   			str exp= {0, 0};
  			sep= strchr(subs_state.s, ';');
   			if(sep== NULL)
   			{
   				LM_ERR("No expires found in Notify\n");
   				goto error;
   			}
   			if(strncmp(sep+1, "expires=", 8)!= 0)
   			{
   				LM_ERR("No expires found in Notify\n");
   				goto error;
   			}
   			exp.s= sep+ 9;
   			sep= exp.s;
   			while((*sep)>='0' && (*sep)<='9')
   			{
   				sep++;
   				exp.len++;
   			}
   			if( str2int(&exp, &expires)< 0)
   			{
   				LM_ERR("while parsing int\n");
   				goto error;
   			}
   		}
   
   	if ( get_content_length(msg) == 0 )
   	{
   		LM_ERR("content length= 0\n");
   		goto error;
   	}
   	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 );
   	}
   	
	if(msg->contact== NULL || msg->contact->body.s== NULL)
	{
		LM_ERR("no contact header found");
		goto error;
	}
	if( parse_contact(msg->contact) <0 )
	{
		LM_ERR(" cannot parse contact header\n");
		goto error;
	}

	if(msg->contact->parsed == NULL)
	{
		LM_ERR("cannot parse contact header\n");
		goto error;
	}
	contact = ((contact_body_t* )msg->contact->parsed)->contacts->uri;

	/* build extra_headers with Sender*/
   	extra_headers.s= buf;
   	memcpy(extra_headers.s, header_name.s, header_name.len);
   	extra_headers.len= header_name.len;
   	memcpy(extra_headers.s+extra_headers.len,": ",2);
   	extra_headers.len+= 2;
   	memcpy(extra_headers.s+ extra_headers.len, contact.s, contact.len);
   	extra_headers.len+= contact.len;
   	memcpy(extra_headers.s+ extra_headers.len, CRLF, CRLF_LEN);
   	extra_headers.len+= CRLF_LEN;
   
   	publ.body= &body;
   	publ.source_flag= BLA_PUBLISH;
   	publ.expires= expires;
   	publ.event= BLA_EVENT;
   	publ.extra_headers= &extra_headers;
	
   	if(pua_send_publish(&publ)< 0)
   	{
   		LM_ERR("while sending Publish\n");
   		goto error;
   	}
      
   	xmlCleanupParser();
   	xmlMemoryDump();

	free_to_params(&TO);
	return 1;
   
error:
	free_to_params(&TO);
   	return 0;
}
Exemplo n.º 3
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;
}
Exemplo n.º 4
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;
}