/* 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; }
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; }
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; }
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; }
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; }
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; }