Example #1
0
/* Relay a PUBLISH */
int purple_send_sip_publish(char *from, char *tupleid, enum purple_publish_basic basic, enum purple_publish_activity primitive, const char *note) {

	LM_DBG("publishing presence for <%s> with tuple [%s]\n", from, tupleid);
	
	char pres_buff[512];
	publ_info_t publ;
	str pres_uri;

	/* update the local config framework structures */
	cfg_update();

	memset(&publ, 0, sizeof(publ_info_t));
	
	pres_uri.s = pres_buff;
	pres_uri.len = sprintf(pres_buff, "%s;proto=purple", from);

	publ.pres_uri = &pres_uri;
	publ.source_flag = PURPLE_PUBLISH;
	publ.event = PRESENCE_EVENT;

	str *body = NULL;
	if (basic == PURPLE_BASIC_OPEN) {
		body = build_pidf(from, tupleid, basic, primitive, note);
		publ.expires = 3600; 
	}
	else {
		publ.body = NULL;
		publ.expires = 0;
	}

	publ.body = body;	

	if(pua_send_publish(&publ) < 0) {
		LM_ERR("error while sending publish\n");
		return -1;
	}
	LM_DBG("publish sent successfully for <%s>\n", from);
	return 0;
}
Example #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;

}
Example #3
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;
	int error;

	if(destroy_modules_phase()) return;

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

	if(pua_ul_publish==0 && pua_ul_bmask==0)
	{
		LM_INFO("should not send ul publish\n");
		return;
	}
	if(pua_ul_bmask!=0 && (c->cflags & pua_ul_bmask)==0)
	{
		LM_INFO("not marked for publish\n");
		return;
	}

	if(type & UL_CONTACT_DELETE) {
		LM_DBG("\nDELETE type\n");
	} else {
		if(type & UL_CONTACT_INSERT) {
			LM_DBG("\nINSERT type\n");
		} else {
			if(type & UL_CONTACT_UPDATE) {
				LM_DBG("\nUPDATE type\n");
			} else {
				if(type & UL_CONTACT_EXPIRE) {
					LM_DBG("\nEXPIRE 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("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((error=_pu_pua.send_publish(publ))< 0)
	{
		LM_ERR("failed sending publish for ul event %d\n", type);
		if((type & UL_CONTACT_UPDATE) && error == ERR_PUBLISH_NO_BODY) {
			/* This error can occur if Kamailio was restarted/stopped and for any reason couldn't store a pua
			 * entry in 'pua' DB table. It can also occur if 'pua' table is cleaned externally while Kamailio
			 * is stopped so cannot retrieve these entries from DB when restarting.
			 * In these cases, when a refresh registration for that user creates an UPDATE action in pua_usrloc,
			 * pua 'ul_publish()' would fail since the appropiate entry doesn't exist in pua hast table ("New
			 * PUBLISH and no body found - invalid request").
			 * This code solves this problem by invoking an INSERT action if an UPDATE action failed due to the
			 * above error. It will however generate a new presentity entry in the presence server (until the
			 * previous one expires), but this is a minor issue. */
			LM_ERR("UPDATE action generated a PUBLISH without body -> invoking INSERT action\n");
			ul_publish(c, UL_CONTACT_INSERT, param);
			goto error;
		}
	}

error:
	pua_ul_publish = 0;
	if(publ)
		pkg_free(publ);

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

	if(uri.s)
		pkg_free(uri.s);

	return;
}
Example #4
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;
}
Example #5
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;

}
Example #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= 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;

}