/** * return the XML node for rls-services matching uri */ xmlNodePtr rls_get_by_service_uri(xmlDocPtr doc, str* uri) { xmlNodePtr root, node; char* val; root = XMLDocGetNodeByName(doc, "rls-services", NULL); if(root==NULL) { LM_ERR("no rls-services node in XML document\n"); return NULL; } for(node=root->children; node; node=node->next) { if(xmlStrcasecmp(node->name, (unsigned char*)"service")==0) { val = XMLNodeGetAttrContentByName(node, "uri"); if(val!=NULL) { if((uri->len==strlen(val)) && (strncmp(val, uri->s, uri->len)==0)) { xmlFree(val); return node; } xmlFree(val); } } } return NULL; }
xmlNodePtr search_service_uri(xmlDocPtr doc, str* service_uri) { xmlNodePtr rl_node, node; struct sip_uri sip_uri; str uri, uri_str; str *normalized_uri; rl_node= XMLDocGetNodeByName(doc, "rls-services", NULL); if(rl_node== NULL) { LM_ERR("while extracting rls-services node\n"); return NULL; } for(node= rl_node->children; node; node= node->next) { if(xmlStrcasecmp(node->name,(unsigned char*)"service")== 0) { uri.s = XMLNodeGetAttrContentByName(node, "uri"); if (uri.s == NULL) { LM_DBG("failed to fetch 'uri' in service [invalid XML from XCAP]\n"); continue; } uri.len = strlen(uri.s); normalized_uri = normalizeSipUri(&uri); if (normalized_uri->s == NULL || normalized_uri->len == 0) { LM_ERR("failed to normalize service URI\n"); xmlFree(uri.s); return NULL; } xmlFree(uri.s); if(parse_uri(normalized_uri->s, normalized_uri->len, &sip_uri)< 0) { LM_ERR("failed to parse uri\n"); return NULL; } if(uandd_to_uri(sip_uri.user, sip_uri.host, &uri_str)< 0) { LM_ERR("failed to construct uri from user and domain\n"); return NULL; } if(uri_str.len== service_uri->len && strncmp(uri_str.s, service_uri->s, uri_str.len) == 0) { pkg_free(uri_str.s); return node; } LM_DBG("match not found, service-uri = [%.*s]\n", uri_str.len, uri_str.s); pkg_free(uri_str.s); } } return NULL; }
void pres_Xmpp2Sip(char *msg, int type, void *param) { xmlDocPtr doc= NULL; xmlNodePtr pres_node= NULL; char* pres_type= NULL; doc= xmlParseMemory(msg, strlen(msg)); if(doc == NULL) { LM_ERR("while parsing xml memory\n"); return; } pres_node= XMLDocGetNodeByName(doc, "presence", NULL); if(pres_node == NULL) { LM_ERR("while getting node\n"); goto error; } pres_type= XMLNodeGetAttrContentByName(pres_node, "type" ); if(pres_type== NULL ) { LM_DBG("type attribut not present\n"); build_publish(pres_node, -1); if(presence_subscribe(pres_node, 3600, XMPP_SUBSCRIBE)< 0) { LM_ERR("when sending subscribe for presence"); xmlFree(pres_type); goto error; } /* send subscribe after publish because in xmpp subscribe message * comes only when a new contact is inserted in buddy list */ } else if(strcmp(pres_type, "unavailable")== 0) { build_publish(pres_node, 0); if(presence_subscribe(pres_node, 3600, XMPP_SUBSCRIBE)< 0) /* else subscribe for one hour*/ { LM_ERR("when unsubscribing for presence"); xmlFree(pres_type); goto error; } } else if((strcmp(pres_type, "subscribe")==0)|| ( strcmp(pres_type, "unsubscribe")== 0)|| (strcmp(pres_type, "probe")== 0)) { if(strcmp(pres_type, "subscribe")==0 || strcmp(pres_type, "probe")== 0) { LM_DBG("send Subscribe message (no time limit)\n"); if(presence_subscribe(pres_node, -1, XMPP_INITIAL_SUBS)< 0) { LM_ERR("when sending subscribe for presence"); xmlFree(pres_type); goto error; } } if(strcmp(pres_type, "unsubscribe")== 0) { if(presence_subscribe(pres_node, 0, XMPP_INITIAL_SUBS)< 0) { LM_ERR("when unsubscribing for presence"); xmlFree(pres_type); goto error; } } } xmlFree(pres_type); // else // send_reply_message(pres_node); xmlFreeDoc(doc); xmlCleanupParser(); xmlMemoryDump(); return ; error: if(doc) xmlFreeDoc(doc); xmlCleanupParser(); xmlMemoryDump(); return ; }
int presence_subscribe(xmlNodePtr pres_node, int expires,int flag) { subs_info_t subs; char* type= NULL, *uri= NULL; str to_uri= {0, 0}; str from_uri= {0, 0}; char buf_from[256]; uri= XMLNodeGetAttrContentByName(pres_node, "to"); if(uri== NULL) { LM_ERR("failed to get to attribute from xml doc\n"); return -1; } to_uri.s = xmpp_uri_xmpp2sip(uri, &to_uri.len); if(to_uri.s == 0) { LM_ERR("failed to get from attribute from xml doc\n"); goto error; } xmlFree(uri); uri= XMLNodeGetAttrContentByName(pres_node, "from"); if(uri == NULL) { LM_ERR("failed to get from attribute from xml doc\n"); goto error; } ENC_SIP_URI(from_uri, buf_from, uri); xmlFree(uri); memset(&subs, 0, sizeof(subs_info_t)); subs.pres_uri= &to_uri; subs.watcher_uri= &from_uri; subs.contact= &server_address; if(presence_server.s) subs.outbound_proxy = &presence_server; /* type= XMLNodeGetAttrContentByName(pres_node, "type" ); if(strcmp(type, "subscribe")==0 ||strcmp(type, "probe")== 0) subs->flag|= INSERT_TYPE; else if(strcmp(type, "unsubscribe")== 0) subs->flag|= UPDATE_TYPE; xmlFree(type); type= NULL; */ subs.source_flag|= flag; subs.event= PRESENCE_EVENT; subs.expires= expires; if(presence_server.s && presence_server.len) subs.outbound_proxy = &presence_server; LM_DBG("XMPP subscription to [%.*s] , from [%.*s], expires= [%d]\n", subs.pres_uri->len, subs.pres_uri->s, subs.watcher_uri->len, subs.watcher_uri->s, expires); if(subs.outbound_proxy) LM_DBG("outbound_proxy= %.*s\n", subs.outbound_proxy->len, subs.outbound_proxy->s); if(pua_send_subscribe(&subs)< 0) { LM_ERR("while sending SUBSCRIBE\n"); goto error; } return 0; error: if(type) xmlFree(type); return -1; }
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; }
str* build_pidf(xmlNodePtr pres_node, char* uri, char* resource) { str* body= NULL; xmlDocPtr doc= NULL; xmlNodePtr root_node= NULL, status_node= NULL; xmlNodePtr node= NULL, person_node= NULL; xmlNodePtr tuple_node= NULL, basic_node= NULL; char* show_cont= NULL, *status_cont= NULL; char* entity= NULL; char* type= NULL; char* status= NULL; entity=(char*)pkg_malloc(7+ strlen(uri)*sizeof(char)); if(entity== NULL) { LM_ERR("no more memory\n"); goto error; } strcpy(entity, "pres:"); memcpy(entity+5, uri+4, strlen(uri)-4); entity[1+ strlen(uri)]= '\0'; doc= xmlNewDoc(BAD_CAST "1.0"); if(doc== NULL) { LM_ERR("allocating new xml doc\n"); goto error; } root_node = xmlNewNode(NULL, BAD_CAST "presence"); if(root_node== 0) { LM_ERR("extracting presence node\n"); goto error; } xmlDocSetRootElement(doc, root_node); xmlNewProp(root_node, BAD_CAST "xmlns", BAD_CAST "urn:ietf:params:xml:ns:pidf"); xmlNewProp(root_node, BAD_CAST "xmlns:dm", BAD_CAST "urn:ietf:params:xml:ns:pidf:data-model"); xmlNewProp(root_node, BAD_CAST "xmlns:rpid", BAD_CAST "urn:ietf:params:xml:ns:pidf:rpid" ); xmlNewProp(root_node, BAD_CAST "xmlns:c", BAD_CAST "urn:ietf:params:xml:ns:pidf:cipid"); xmlNewProp(root_node, BAD_CAST "entity", BAD_CAST entity); tuple_node =xmlNewChild(root_node, NULL, BAD_CAST "tuple", NULL) ; if( tuple_node ==NULL) { LM_ERR("while adding child\n"); goto error; } status_node = xmlNewChild(tuple_node, NULL, BAD_CAST "status", NULL) ; if( status_node ==NULL) { LM_ERR("while adding child\n"); goto error; } type= XMLNodeGetAttrContentByName(pres_node, "type"); if(type== NULL) { basic_node = xmlNewChild(status_node, NULL, BAD_CAST "basic", BAD_CAST "open") ; if( basic_node ==NULL) { LM_ERR("while adding child\n"); goto error; } } else { basic_node = xmlNewChild(status_node, NULL, BAD_CAST "basic", BAD_CAST "closed") ; if( basic_node ==NULL) { LM_ERR("while adding child\n"); goto error; } goto done; } /*if no type present search for suplimentary information */ status_cont= XMLNodeGetNodeContentByName(pres_node, "status", NULL); show_cont= XMLNodeGetNodeContentByName(pres_node, "show", NULL); if(show_cont) { if(strcmp(show_cont, "xa")== 0) status= "not available"; else if(strcmp(show_cont, "chat")== 0) status= "free for chat"; else if(strcmp(show_cont, "dnd")== 0) status= "do not disturb"; else status= show_cont; } if(status_cont) { /* person_node= xmlNewChild(root_node, NULL, BAD_CAST "person", 0); if(person_node== NULL) { LM_ERR("while adding node\n"); goto error; } */ node = xmlNewChild(root_node, NULL, BAD_CAST "note", BAD_CAST status_cont); if(node== NULL) { LM_ERR("while adding node\n"); goto error; } }else if(show_cont) { node = xmlNewChild(root_node, NULL, BAD_CAST "note", BAD_CAST status); if(node== NULL) { LM_ERR("while adding node\n"); goto error; } } if(show_cont) { LM_DBG("show_cont= %s\n", show_cont); if(person_node== NULL) { person_node= xmlNewChild(root_node, NULL, BAD_CAST "person",0 ); if(person_node== NULL) { LM_ERR("while adding node\n"); goto error; } } node= xmlNewChild(person_node, NULL, BAD_CAST "activities", BAD_CAST 0); if(node== NULL) { LM_ERR("while adding node\n"); goto error; } if( xmlNewChild(person_node, NULL, BAD_CAST "note", BAD_CAST status )== NULL) { LM_ERR("while adding node\n"); goto error; } } done: body= (str* )pkg_malloc(sizeof(str)); if(body== NULL) { LM_ERR("no more memory\n"); goto error; } xmlDocDumpMemory(doc,(xmlChar**)(void*)&body->s, &body->len); if(entity) pkg_free(entity); if(status_cont) xmlFree(status_cont); if(show_cont) xmlFree(show_cont); if(type) xmlFree(type); xmlFreeDoc(doc); return body; error: if(entity) pkg_free(entity); if(body) { if(body->s) xmlFree(body->s); pkg_free(body); } if(status_cont) xmlFree(status_cont); if(show_cont) xmlFree(show_cont); if(type) xmlFree(type); if(doc) xmlFreeDoc(doc); return NULL; }
int presence_subscribe(xmlNodePtr pres_node, int expires,int flag) { subs_info_t subs; char* to_uri= NULL, *from_uri= NULL; char* uri= NULL; char* type= NULL; str to_uri_str; str from_uri_str; uri= XMLNodeGetAttrContentByName(pres_node, "to"); if(uri== NULL) { LM_ERR("while getting attribute from xml doc\n"); return -1; } to_uri= duri_xmpp_sip(uri); if(to_uri== NULL) { LM_ERR("while decoding xmpp--sip uri\n"); goto error; } xmlFree(uri); to_uri_str.s= to_uri; to_uri_str.len= strlen(to_uri); uri= XMLNodeGetAttrContentByName(pres_node, "from"); if(uri== NULL) { LM_ERR("while getting attribute from xml doc\n"); goto error; } from_uri= euri_xmpp_sip(uri); if(from_uri== NULL) { LM_ERR("while encoding xmpp-sip uri\n"); goto error; } xmlFree(uri); from_uri_str.s= from_uri; from_uri_str.len= strlen(from_uri); memset(&subs, 0, sizeof(subs_info_t)); subs.pres_uri= &to_uri_str; subs.watcher_uri= &from_uri_str; subs.contact= subs.watcher_uri; /* type= XMLNodeGetAttrContentByName(pres_node, "type" ); if(strcmp(type, "subscribe")==0 ||strcmp(type, "probe")== 0) subs->flag|= INSERT_TYPE; else if(strcmp(type, "unsubscribe")== 0) subs->flag|= UPDATE_TYPE; xmlFree(type); type= NULL; */ subs.source_flag|= flag; subs.event= PRESENCE_EVENT; subs.expires= expires; LM_DBG("subs:\n"); LM_DBG("\tpres_uri= %.*s\n", subs.pres_uri->len, subs.pres_uri->s); LM_DBG("\twatcher_uri= %.*s\n", subs.watcher_uri->len, subs.watcher_uri->s); LM_DBG("\texpires= %d\n", subs.expires); if(pua_send_subscribe(&subs)< 0) { LM_ERR("while sending SUBSCRIBE\n"); goto error; } return 0; error: if(type) xmlFree(type); return -1; }
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; }
int build_xmpp_content(str* to_uri, str* from_uri, str* body, str* id, int is_terminated) { xmlDocPtr sip_doc= NULL; xmlDocPtr doc= NULL; xmlNodePtr xmpp_root= NULL; xmlNodePtr sip_root= NULL; xmlNodePtr new_node= NULL; xmlNodePtr node = NULL; xmlBufferPtr buffer= NULL; xmlAttrPtr attr= NULL; char* basic= NULL, *priority= NULL, *note= NULL; str xmpp_msg; LM_DBG("start...\n"); /* creating the xml doc for the xmpp message*/ doc= xmlNewDoc(0); if(doc== NULL) { LM_ERR("when creating new xml doc\n"); goto error; } xmpp_root = xmlNewNode(NULL, BAD_CAST "presence"); if(xmpp_root==0) { LM_ERR("when adding new node- presence\n"); goto error; } xmlDocSetRootElement(doc, xmpp_root); attr= xmlNewProp(xmpp_root, BAD_CAST "to", BAD_CAST to_uri->s); if(attr== NULL) { LM_ERR("while adding new attribute\n"); goto error; } attr= xmlNewProp(xmpp_root, BAD_CAST "from", BAD_CAST from_uri->s); if(attr== NULL) { LM_ERR("while adding new attribute\n"); goto error; } if(is_terminated) { attr= xmlNewProp(xmpp_root, BAD_CAST "type", BAD_CAST "unsubscribed"); if(attr== NULL) { LM_ERR("while adding new attribute\n"); goto error; } goto done; } if(body->s== NULL) { attr= xmlNewProp(xmpp_root, BAD_CAST "type", BAD_CAST "unavailable"); if(attr== NULL) { LM_ERR("while adding new attribute\n"); goto error; } goto done; } /*extractiong the information from the sip message body*/ sip_doc= xmlParseMemory(body->s, body->len); if(sip_doc== NULL) { LM_ERR("while parsing xml memory\n"); return -1; } sip_root= XMLDocGetNodeByName(sip_doc, "presence", NULL); if(sip_root== NULL) { LM_ERR("while extracting 'presence' node\n"); goto error; } node = XMLNodeGetNodeByName(sip_root, "basic", NULL); if(node== NULL) { LM_ERR("while extracting status basic node\n"); goto error; } basic= (char*)xmlNodeGetContent(node); if(basic== NULL) { LM_ERR("while extracting status basic node content\n"); goto error; } if(xmlStrcasecmp( (unsigned char*)basic,(unsigned char*) "closed")==0 ) { attr= xmlNewProp(xmpp_root, BAD_CAST "type", BAD_CAST "unavailable"); if(attr== NULL) { LM_ERR("while adding node attr\n"); xmlFree(basic); goto error; } xmlFree(basic); goto done; }/* else the status is open so no type attr should be added */ xmlFree(basic); /* addind show node */ node= XMLNodeGetNodeByName(sip_root, "note", NULL); if(node== NULL) { LM_DBG("No note node found\n"); node= XMLNodeGetNodeByName(sip_root, "person", NULL); if(node== NULL) { LM_DBG("No person node found\n"); goto done; } node= XMLNodeGetNodeByName(node, "note", NULL); if(node== NULL) { LM_DBG("Person node has no note node\n"); goto done; } } note= (char*)xmlNodeGetContent(node); if(note== NULL) { LM_ERR("while extracting note node content\n"); goto error; } if(xmlStrcasecmp((unsigned char*)note, (unsigned char*)"away")== 0) { new_node = xmlNewChild(xmpp_root, NULL, BAD_CAST "show", BAD_CAST "away"); if(new_node== NULL) { LM_ERR("while adding node show: away\n"); goto error; } } else if(xmlStrcasecmp((unsigned char*)note, (unsigned char*)"busy")== 0) { new_node = xmlNewChild(xmpp_root, NULL, BAD_CAST "show" , BAD_CAST "xa"); if(new_node== NULL) { LM_ERR("while adding node show: away\n"); goto error; } } /* if(xmlStrcasecmp((unsigned char*)note, (unsigned char*)"on the phone")== 0) { new_node = xmlNewChild(xmpp_root, NULL, BAD_CAST "show", BAD_CAST "chat"); if(new_node== NULL) { LM_ERR("while adding node show: chat\n"); goto error; } } else if(xmlStrcasecmp((unsigned char*)note, (unsigned char*)"idle")== 0) { new_node = xmlNewChild(xmpp_root, NULL, BAD_CAST "show", BAD_CAST "idle"); if(new_node== NULL) { LM_ERR("while adding node: idle\n"); goto error; } } else */ if((xmlStrcasecmp((unsigned char*)note, (unsigned char*)"dnd")== 0)|| (xmlStrcasecmp((unsigned char*)note, (unsigned char*)"do not disturb")== 0)) { new_node = xmlNewChild(xmpp_root, NULL, BAD_CAST "show", BAD_CAST "dnd"); if(new_node== NULL) { LM_ERR("while adding node show: dnd\n"); goto error; } } /* adding status node */ new_node = xmlNewChild(xmpp_root, NULL, BAD_CAST "status", BAD_CAST note); if(new_node== NULL) { LM_ERR("while adding node status\n"); goto error; } xmlFree(note); note= NULL; /* adding priotity node*/ node= XMLNodeGetNodeByName(sip_root, "contact", NULL); if(node== NULL) { LM_DBG("No contact node found\n"); } else { priority= XMLNodeGetAttrContentByName(node, "priority"); if(priority== NULL) LM_DBG("No priority attribute found\n"); else { new_node= xmlNewChild(xmpp_root, NULL, BAD_CAST "priority", BAD_CAST priority); if(sip_root== NULL) { LM_ERR("while adding node\n"); xmlFree(priority); goto error; } xmlFree(priority); } } done: buffer= xmlBufferCreate(); if(buffer== NULL) { LM_ERR("while adding creating new buffer\n"); goto error; } xmpp_msg.len= xmlNodeDump(buffer, doc, xmpp_root, 1,1); if(xmpp_msg.len== -1) { LM_ERR("while dumping node\n"); goto error; } xmpp_msg.s= (char*)xmlBufferContent( buffer); if(xmpp_msg.s== NULL) { LM_ERR("while extracting buffer content\n"); goto error; } LM_DBG("xmpp_msg: %.*s\n",xmpp_msg.len, xmpp_msg.s); if( xmpp_notify(from_uri, to_uri, &xmpp_msg, id)< 0) { LM_ERR("while sending xmpp_notify\n"); goto error; } xmlBufferFree(buffer); xmlCleanupParser(); xmlMemoryDump(); if(sip_doc) xmlFreeDoc(sip_doc); if(doc) xmlFreeDoc(doc); return 0; error: if(sip_doc) xmlFreeDoc(sip_doc); if(note) xmlFree(note); if(buffer) xmlBufferFree(buffer); xmlCleanupParser(); xmlMemoryDump(); return -1; }