Пример #1
0
void dialog_publish(char *state, struct to_body* entity, struct to_body *peer, str *callid,
	unsigned int initiator, unsigned int lifetime, str *localtag, str *remotetag)
{
	str* body= NULL;
	publ_info_t publ;
	int ret_code;

	body= build_dialoginfo(state, entity, peer, callid, initiator, localtag, remotetag);
	if(body == NULL || body->s == NULL)
	{
		LM_ERR("failed to construct dialoginfo body\n");
		goto error;
	}

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

	publ.pres_uri= &entity->uri;
	publ.body = body;

	publ.id = *callid;

	publ.content_type.s= "application/dialog-info+xml";
	publ.content_type.len= 27;

	publ.expires= lifetime;

	/* make UPDATE_TYPE, as if this "publish dialog" is not found
	   by pua it will fallback to INSERT_TYPE anyway */
	publ.flag|= UPDATE_TYPE;

	publ.source_flag|= DIALOG_PUBLISH;
	publ.event|= DIALOG_EVENT;
	publ.extra_headers= NULL;
	publ.outbound_proxy = presence_server;

	print_publ(&publ);
	ret_code = pua_send_publish(&publ);
	switch (ret_code) {
	case ERR_PUBLISH_NO_ERROR:
	case ERR_PUBLISH_NO_RECORD:
		break;
	default:
		LM_ERR("sending publish failed for pres_uri [%.*s] to server [%.*s]\n",
			publ.pres_uri->len, publ.pres_uri->s,
			publ.outbound_proxy.len, publ.outbound_proxy.s);
	}

error:

	if(body)
	{
		if(body->s)
			xmlFree(body->s);
		pkg_free(body);
	}

	return;
}
Пример #2
0
int build_publish(xmlNodePtr pres_node, int expires)
{
	str* body= NULL;
	publ_info_t publ;
	char* resource= NULL;
	str pres_uri= {0, 0};
	char* slash;
	char buf[256];
	char* uri;

	uri = XMLNodeGetAttrContentByName(pres_node, "from");
	if(uri == NULL)
	{
		LM_DBG("getting 'from' attribute\n");
		return -1;
	}

	ENC_SIP_URI(pres_uri, buf, uri);
	xmlFree(uri);

	slash= memchr(pres_uri.s, '/', pres_uri.len);
	if(slash)
	{
		pres_uri.len= slash- pres_uri.s;
		resource= (char*)pkg_malloc((strlen(pres_uri.s)-pres_uri.len)*sizeof(char));
		if(resource== NULL)
		{
			LM_ERR("no more memory\n");
			return -1;
		}
		strcpy(resource, slash+1);
		slash= '\0';
	}

	body= build_pidf(pres_node, pres_uri.s, resource);
	if(body== NULL)
	{
		LM_ERR("while constructing PUBLISH body\n");
		goto error;
	}

	/* construct the publ_info_t structure */

	memset(&publ, 0, sizeof(publ_info_t));
	publ.pres_uri= &pres_uri;

	publ.body= body;

	LM_DBG("Publish for [%s]  body:\n %.*s - %d\n", pres_uri.s, publ.body->len,
			publ.body->s, publ.body->len);

	publ.source_flag|= XMPP_PUBLISH;
	publ.expires= expires;
	publ.event= PRESENCE_EVENT;
	publ.extra_headers= NULL;
	publ.outbound_proxy = presence_server;

	if( pua_send_publish(&publ)< 0)
	{
		LM_ERR("while sending publish\n");
		goto error;
	}

	if(resource)
		pkg_free(resource);
	if(body)
	{
		if(body->s)
			xmlFree(body->s);
		pkg_free(body);
	}

	return 0;

error:

	if(resource)
		pkg_free(resource);

	if(body)
	{
		if(body->s)
			xmlFree(body->s);
		pkg_free(body);
	}

	return -1;

}
Пример #3
0
struct mi_root* mi_pua_publish(struct mi_root* cmd, void* param)
{
	int exp;
	struct mi_node* node= NULL;
	str pres_uri, expires;
	str body= {0, 0};
	struct sip_uri uri;
	publ_info_t publ;
	str event;
	str content_type;
	str etag;
	int result;
	int sign= 1;

	LM_DBG("start\n");

	node = cmd->node.kids;
	if(node == NULL)
		return 0;

	/* Get presentity URI */
	pres_uri = node->value;
	if(pres_uri.s == NULL || pres_uri.s== 0)
	{
		LM_ERR("empty uri\n");
		return init_mi_tree(404, "Empty presentity URI", 20);
	}
	if(parse_uri(pres_uri.s, pres_uri.len, &uri)<0 )
	{
		LM_ERR("bad uri\n");
		return init_mi_tree(404, "Bad presentity URI", 18);
	}
	LM_DBG("pres_uri '%.*s'\n", pres_uri.len, pres_uri.s);

	node = node->next;
	if(node == NULL)
		return 0;

	/* Get expires */
	expires= node->value;
	if(expires.s== NULL || expires.len== 0)
	{
		LM_ERR("empty expires parameter\n");
		return init_mi_tree(400, "Empty expires parameter", 23);
	}
	if(expires.s[0]== '-')
	{
		sign= -1;
		expires.s++;
		expires.len--;
	}
	if( str2int(&expires, (unsigned int*) &exp)< 0)
	{
		LM_ERR("invalid expires parameter\n" );
		goto error;
	}
	
	exp= exp* sign;

	LM_DBG("expires '%d'\n", exp);

	node = node->next;
	if(node == NULL)
		return 0;

	/* Get event */
	event= node->value;
	if(event.s== NULL || event.len== 0)
	{
		LM_ERR("empty event parameter\n");
		return init_mi_tree(400, "Empty event parameter", 21);
	}
	LM_DBG("event '%.*s'\n",
	    event.len, event.s);

	node = node->next;
	if(node == NULL)
		return 0;

	/* Get content type */
	content_type= node->value;
	if(content_type.s== NULL || content_type.len== 0)
	{
		LM_ERR("empty content type\n");
		return init_mi_tree(400, "Empty content type parameter", 28);
	}
	LM_DBG("content type '%.*s'\n",
	    content_type.len, content_type.s);

	node = node->next;
	if(node == NULL)
		return 0;

	/* Get etag */
	etag= node->value;
	if(etag.s== NULL || etag.len== 0)
	{
		LM_ERR("empty etag parameter\n");
		return init_mi_tree(400, "Bad expires", 11);
	}
	LM_DBG("etag '%.*s'\n",
	    etag.len, etag.s);

	node = node->next;

	/* Get body */
	if(node == NULL )
	{
		body.s= NULL;
		body.len= 0;
	}
	else
	{
		if(node->next!=NULL)
			return init_mi_tree(400, "Too many parameters", 19);

		body= node->value;
		if(body.s == NULL || body.s== 0)
		{
			LM_ERR("empty body parameter\n");
			return init_mi_tree(400, "Empty body parameter", 20);
		}
	}
	LM_DBG("body '%.*s'\n",
	    body.len, body.s);

	/* Check that body is NULL iff content type is . */
	if(body.s== NULL && (content_type.len!= 1 || content_type.s[0]!= '.'))
	{
		LM_ERR("body is missing, but content type is not .\n");
		return init_mi_tree(400, "Body parameter is missing", 25);
	}

	/* Create the publ_info_t structure */
	memset(&publ, 0, sizeof(publ_info_t));
	
	publ.pres_uri= &pres_uri;
	if(body.s)
	{
		publ.body= &body;
	}
	
	publ.event= get_event_flag(&event);
	if(publ.event< 0)
	{
		LM_ERR("unkown event\n");
		return init_mi_tree(400, "Unknown event", 13);
	}
	if(content_type.len!= 1)
	{
		publ.content_type= content_type;
	}	
	
	if(! (etag.len== 1 && etag.s[0]== '.'))
	{
		publ.etag= &etag;
	}	
	publ.expires= exp;
	
	if (cmd->async_hdl!=NULL)
	{
		publ.source_flag= MI_ASYN_PUBLISH;
		publ.cb_param= (void*)cmd->async_hdl;
	}	
	else
		publ.source_flag|= MI_PUBLISH;

	LM_DBG("send publish\n");

	result= pua_send_publish(&publ);

	if(result< 0)
	{
		LM_ERR("sending publish failed\n");
		return init_mi_tree(500, "MI/PUBLISH failed", 17);
	}	
	if(result== 418)
		return init_mi_tree(418, "Wrong ETag", 10);
	
	if (cmd->async_hdl==NULL)
			return init_mi_tree( 202, "Accepted", 8);
	else
			return MI_ROOT_ASYNC_RPL;

error:

	return 0;
}
Пример #4
0
void dialog_publish(char *state, str* ruri, 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)
{
	str* body= NULL;
	str uri= {NULL, 0};
	publ_info_t* publ= NULL;
	int size= 0;
	str content_type;
    struct sip_uri ruri_uri;


    if (parse_uri(ruri->s, ruri->len, &ruri_uri) < 0) {
		LM_ERR("failed to parse the PUBLISH R-URI\n");
		return;
	}

    if(do_pubruri_localcheck) {

		/* send PUBLISH only if the receiver PUBLISH R-URI is local*/
		if (!check_self(&(ruri_uri.host), 0, 0)) {
			LM_DBG("do not send PUBLISH to external URI %.*s\n",ruri->len, ruri->s);
			return;
		}

    }

	content_type.s= "application/dialog-info+xml";
	content_type.len= 27;

	body= build_dialoginfo(state, entity, peer, callid, initiator, localtag, remotetag, localtarget, remotetarget);
	if(body == NULL || body->s == NULL)
		goto error;
	
	LM_DBG("publish uri= %.*s\n", ruri->len, ruri->s);
	
	size= sizeof(publ_info_t) 
			+ sizeof(str) 			/* *pres_uri */
			+ ( ruri->len 		/* pres_uri->s */
			  + callid->len + 16	/* id.s */
			  + content_type.len	/* content_type.s */
			)*sizeof(char); 
	
	if(body)
		size+= sizeof(str)+ body->len* sizeof(char);

	publ= (publ_info_t*)pkg_malloc(size);
	if(publ== NULL)
	{
		LM_ERR("no more share memory\n");
		goto error;
	}
	memset(publ, 0, size);
	size= sizeof(publ_info_t);

	publ->pres_uri= (str*)((char*)publ + size);
	size+= sizeof(str);
	publ->pres_uri->s= (char*)publ+ size;
	memcpy(publ->pres_uri->s, ruri->s, ruri->len);
	publ->pres_uri->len= ruri->len;
	size+= ruri->len;

	if(body)
	{
		publ->body= (str*)( (char*)publ + size);
		size+= sizeof(str);

		publ->body->s= (char*)publ + size;
		memcpy(publ->body->s, body->s, body->len);
		publ->body->len= body->len;
		size+= body->len;
	}
	publ->id.s= (char*)publ+ size;
	memcpy(publ->id.s, "DIALOG_PUBLISH.", 15);
	memcpy(publ->id.s+15, callid->s, callid->len);
	publ->id.len= 15+ callid->len;
	size+= publ->id.len;

	publ->content_type.s= (char*)publ+ size;
	memcpy(publ->content_type.s, content_type.s, content_type.len);
	publ->content_type.len= content_type.len;
	size+= content_type.len;

	publ->expires= lifetime;
	
	/* make UPDATE_TYPE, as if this "publish dialog" is not found 
	   by pua it will fallback to INSERT_TYPE anyway */
	publ->flag|= UPDATE_TYPE;

	publ->source_flag|= DIALOG_PUBLISH;
	publ->event|= DIALOG_EVENT;
	publ->extra_headers= NULL;
	print_publ(publ);
	if(pua_send_publish(publ)< 0)
	{
		LM_ERR("while sending publish\n");
	}	

error:

	if(publ)
		pkg_free(publ);

	if(body)
	{
		if(body->s)
			xmlFree(body->s);
		pkg_free(body);
	}
	
	if(uri.s)
		pkg_free(uri.s);

	return;
}
Пример #5
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;
}
Пример #6
0
void ul_publish(ucontact_t* c, int type, void* param)
{
	str* body= NULL;
	str uri= {NULL, 0};
	char* at= NULL;
	publ_info_t publ;
	int error;

	if(pua_ul_publish== 0 && !(type & UL_CONTACT_EXPIRE))
	{
		return;
	}

	if(type & UL_CONTACT_DELETE)
		LM_DBG("\nul_publish: DELETE type\n");
	else
		if(type & UL_CONTACT_INSERT)
			LM_DBG("\nul_publish: INSERT type\n");
		else
			if(type & UL_CONTACT_UPDATE)
				LM_DBG("\nul_publish: UPDATE type\n");
			else
				if(type & UL_CONTACT_EXPIRE)
					LM_DBG("\nul_publish: EXPIRE type\n");

	if(type & UL_CONTACT_INSERT)
	{
		body= build_pidf(c);
		if(body == NULL || body->s == NULL)
			goto error;
	}
	else
		body = NULL;

	uri.s = (char*)pkg_malloc(sizeof(char)*(c->aor->len+default_domain.len+6));
	if(uri.s == NULL)
		goto error;

	LM_DBG("aor = %.*s\n", c->aor->len, c->aor->s);

	memcpy(uri.s, "sip:", 4);
	uri.len = 4;
	memcpy(uri.s+ uri.len, c->aor->s, c->aor->len);
	uri.len+= c->aor->len;
	at = memchr(c->aor->s, '@', c->aor->len);
	if(!at)
	{
		uri.s[uri.len++]= '@';
		memcpy(uri.s+ uri.len, default_domain.s, default_domain.len);
		uri.len+= default_domain.len;
	}

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

	memset(&publ, 0, sizeof(publ_info_t));
	publ.pres_uri= &uri;
	publ.body = body;
	publ.id = c->callid;
	publ.content_type.s = "application/pidf+xml";
	publ.content_type.len = 20;

	if(type & UL_CONTACT_EXPIRE || type & UL_CONTACT_DELETE)
		publ.expires= 0;
	else
		publ.expires= c->expires - (int)time(NULL);

	if(type & UL_CONTACT_INSERT)
		publ.flag= INSERT_TYPE;
	else
		publ.flag= UPDATE_TYPE;

	publ.source_flag|= UL_PUBLISH;
	publ.event|= PRESENCE_EVENT;
	publ.extra_headers= NULL;
	publ.outbound_proxy = presence_server;

	if((error = pua_send_publish(&publ))< 0)
	{
		if((type & UL_CONTACT_UPDATE) && (error== ERR_PUBLISH_NO_BODY))
		{
			LM_DBG("Usrloc Publish for update failed - try Insert\n");
			publ.body= build_pidf(c);
			if(publ.body == NULL || publ.body->s == NULL)
			{
				LM_ERR("failed to generate publish body\n");
				goto error;
			}
			publ.flag= INSERT_TYPE;

			if(pua_send_publish(&publ)< 0)
			{
			   LM_ERR("failed to send publish\n");
			}
		}
		else
			LM_ERR("failed to send publish\n");
	}

error:

	if(body)
	{
		if(body->s)
			xmlFree(body->s);
		pkg_free(body);
	}

	if(uri.s)
		pkg_free(uri.s);
	pua_ul_publish= 0;

	return;
}
Пример #7
0
int build_publish(xmlNodePtr pres_node, int expires)
{
	str* body= NULL;
	publ_info_t publ;
	char* uri= NULL, *resource= NULL;
	char* pres_uri= NULL;
	char* slash;
	int uri_len;
	str uri_str;

	LM_DBG("start... \n");
	
	uri= XMLNodeGetAttrContentByName(pres_node, "from");
	if(uri== NULL)
	{
		LM_DBG("getting 'from' attribute\n");
		return -1;
	}
	uri_len= strlen(uri);

	slash= memchr(uri, '/', strlen(uri));
	if(slash)
	{
		uri_len= slash- uri;
		resource= (char*)pkg_malloc((strlen(uri)-uri_len)*sizeof(char));
		if(resource== NULL)
		{
			LM_ERR("no more memory\n");
			return -1;
		}
		strcpy(resource, slash+1);
		slash= '\0';
	}	
	pres_uri= euri_xmpp_sip(uri);
	if(pres_uri== NULL)
	{
		LM_ERR("while encoding xmpp-sip uri\n");
		goto error;	
	}	
	xmlFree(uri);
	uri_str.s= pres_uri;
	uri_str.len= strlen(pres_uri);

	body= build_pidf(pres_node, pres_uri, resource);
	if(body== NULL)
	{
		LM_ERR("while constructing PUBLISH body\n");
		goto error;
	}

	/* construct the publ_info_t structure */

	memset(&publ, 0, sizeof(publ_info_t));
	
	publ.pres_uri= &uri_str;

	LM_DBG("publ->pres_uri: %.*s  -  %d\n", publ.pres_uri->len, 
			publ.pres_uri->s, publ.pres_uri->len );

	publ.body= body;
	
	LM_DBG("publ->notify body: %.*s - %d\n", publ.body->len,
			publ.body->s,  publ.body->len);

	publ.source_flag|= XMPP_PUBLISH;
	publ.expires= expires;
	publ.event= PRESENCE_EVENT;
	publ.extra_headers= NULL;

	if( pua_send_publish(&publ)< 0)
	{
		LM_ERR("while sending publish\n");
		goto error;
	}

	if(resource)
		pkg_free(resource);
	if(body)
	{
		if(body->s)
			xmlFree(body->s);
		pkg_free(body);
	}

	return 0;

error:

	if(resource)
		pkg_free(resource);

	if(body)
	{
		if(body->s)
			xmlFree(body->s);
		pkg_free(body);
	}

	return -1;

}
Пример #8
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;
}
Пример #9
0
void ul_publish(ucontact_t* c, int type, void* param)
{
	str* body= NULL;
	str uri= {NULL, 0};
	char* at= NULL;
	publ_info_t* publ= NULL;
	int size= 0;
	str content_type;

	content_type.s= "application/pidf+xml";
	content_type.len= 20;

	if(pua_ul_publish== 0)
	{
		LM_INFO("should not send ul publish\n");
		return;
	}	

	if(type & UL_CONTACT_DELETE)
		LM_DBG("\nul_publish: DELETE type\n");
	else
		if(type & UL_CONTACT_INSERT)
			LM_DBG("\nul_publish: INSERT type\n");
		else
			if(type & UL_CONTACT_UPDATE)
				LM_DBG("\nul_publish: UPDATE type\n");
			else
				if(type & UL_CONTACT_EXPIRE)
					LM_DBG("\nul_publish: EXPIRE type\n");

	if(type & UL_CONTACT_INSERT)
	{
		body= build_pidf(c);
		if(body == NULL || body->s == NULL)
			goto error;
	}
	else
		body = NULL;
	
	uri.s = (char*)pkg_malloc(sizeof(char)*(c->aor->len+default_domain.len+6));
	if(uri.s == NULL)
		goto error;

	memcpy(uri.s, "sip:", 4);
	uri.len = 4;
	memcpy(uri.s+ uri.len, c->aor->s, c->aor->len);
	uri.len+= c->aor->len;
	at = memchr(c->aor->s, '@', c->aor->len);
	if(!at)
	{
		uri.s[uri.len++]= '@';
		memcpy(uri.s+ uri.len, default_domain.s, default_domain.len);
		uri.len+= default_domain.len;		
	}
	LM_DBG("ul_publish: uri= %.*s\n", uri.len, uri.s);
	
	size= sizeof(publ_info_t)+ sizeof(str)+( uri.len 
			+c->callid.len+ 12 + content_type.len)*sizeof(char); 
	
	if(body)
		size+= sizeof(str)+ body->len* sizeof(char);

	publ= (publ_info_t*)pkg_malloc(size);
	if(publ== NULL)
	{
		LM_ERR("no more share memory\n");
		goto error;
	}
	memset(publ, 0, size);
	size= sizeof(publ_info_t);

	publ->pres_uri= (str*)((char*)publ + size);
	size+= sizeof(str);
	publ->pres_uri->s= (char*)publ+ size;
	memcpy(publ->pres_uri->s, uri.s, uri.len);
	publ->pres_uri->len= uri.len;
	size+= uri.len;

	if(body)
	{
		publ->body= (str*)( (char*)publ + size);
		size+= sizeof(str);

		publ->body->s= (char*)publ + size;
		memcpy(publ->body->s, body->s, body->len);
		publ->body->len= body->len;
		size+= body->len;
	}
	publ->id.s= (char*)publ+ size;
	memcpy(publ->id.s, "UL_PUBLISH.", 11);
	memcpy(publ->id.s+11, c->callid.s, c->callid.len);
	publ->id.len= 11+ c->callid.len;
	size+= publ->id.len;

	publ->content_type.s= (char*)publ+ size;
	memcpy(publ->content_type.s, content_type.s, content_type.len);
	publ->content_type.len= content_type.len;
	size+= content_type.len;

	if(type & UL_CONTACT_EXPIRE || type & UL_CONTACT_DELETE)
		publ->expires= 0;
	else
		publ->expires= c->expires - (int)time(NULL);
	
	if(type & UL_CONTACT_INSERT)
		publ->flag|= INSERT_TYPE;
	else
		publ->flag|= UPDATE_TYPE;

	publ->source_flag|= UL_PUBLISH;
	publ->event|= PRESENCE_EVENT;
	publ->extra_headers= NULL;
	print_publ(publ);
	if(pua_send_publish(publ)< 0)
	{
		LM_ERR("while sending publish\n");
	}	

	pua_ul_publish= 0;

error:

	if(publ)
		pkg_free(publ);

	if(body)
	{
		if(body->s)
			xmlFree(body->s);
		pkg_free(body);
	}
	
	if(uri.s)
		pkg_free(uri.s);
	pua_ul_publish= 0;

	return;

}