00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <stdio.h>
00034 #include <string.h>
00035 #include <stdlib.h>
00036 #include <libxml/parser.h>
00037
00038 #include "../../parser/msg_parser.h"
00039 #include "../../parser/parse_from.h"
00040 #include "../../parser/parse_to.h"
00041 #include "../../parser/parse_content.h"
00042 #include "../../mem/mem.h"
00043 #include "../../ut.h"
00044 #include "../pua/pua.h"
00045 #include "pua_xmpp.h"
00046
00047 int build_publish(xmlNodePtr pres_node, int expire);
00048 int presence_subscribe(xmlNodePtr pres_node, int expires, int flag);
00049
00050
00051
00052
00053
00054 void pres_Xmpp2Sip(char *msg, int type, void *param)
00055 {
00056 xmlDocPtr doc= NULL;
00057 xmlNodePtr pres_node= NULL;
00058 char* pres_type= NULL;
00059
00060 doc= xmlParseMemory(msg, strlen(msg));
00061 if(doc == NULL)
00062 {
00063 LM_ERR("while parsing xml memory\n");
00064 return;
00065 }
00066
00067 pres_node= XMLDocGetNodeByName(doc, "presence", NULL);
00068 if(pres_node == NULL)
00069 {
00070 LM_ERR("while getting node\n");
00071 goto error;
00072 }
00073 pres_type= XMLNodeGetAttrContentByName(pres_node, "type" );
00074
00075 if(pres_type== NULL )
00076 {
00077 LM_DBG("type attribut not present\n");
00078 build_publish(pres_node, -1);
00079 if(presence_subscribe(pres_node, 3600, XMPP_SUBSCRIBE)< 0)
00080 {
00081 LM_ERR("when sending subscribe for presence");
00082 xmlFree(pres_type);
00083 goto error;
00084 }
00085
00086
00087
00088
00089 }
00090 else
00091 if(strcmp(pres_type, "unavailable")== 0)
00092 {
00093 build_publish(pres_node, 0);
00094 if(presence_subscribe(pres_node, 3600, XMPP_SUBSCRIBE)< 0)
00095
00096 {
00097 LM_ERR("when unsubscribing for presence");
00098 xmlFree(pres_type);
00099 goto error;
00100 }
00101
00102 }
00103 else
00104 if((strcmp(pres_type, "subscribe")==0)||
00105 ( strcmp(pres_type, "unsubscribe")== 0)||
00106 (strcmp(pres_type, "probe")== 0))
00107 {
00108 if(strcmp(pres_type, "subscribe")==0 ||
00109 strcmp(pres_type, "probe")== 0)
00110 {
00111 LM_DBG("send Subscribe message (no time limit)\n");
00112 if(presence_subscribe(pres_node, -1,
00113 XMPP_INITIAL_SUBS)< 0)
00114 {
00115 LM_ERR("when sending subscribe for presence");
00116 xmlFree(pres_type);
00117 goto error;
00118 }
00119 }
00120 if(strcmp(pres_type, "unsubscribe")== 0)
00121 {
00122 if(presence_subscribe(pres_node, 0,
00123 XMPP_INITIAL_SUBS)< 0)
00124 {
00125 LM_ERR("when unsubscribing for presence");
00126 xmlFree(pres_type);
00127 goto error;
00128 }
00129 }
00130 }
00131 xmlFree(pres_type);
00132
00133
00134
00135
00136 xmlFreeDoc(doc);
00137 xmlCleanupParser();
00138 xmlMemoryDump();
00139 return ;
00140
00141 error:
00142
00143 if(doc)
00144 xmlFreeDoc(doc);
00145 xmlCleanupParser();
00146 xmlMemoryDump();
00147
00148 return ;
00149
00150 }
00151
00152 str* build_pidf(xmlNodePtr pres_node, char* uri, char* resource)
00153 {
00154 str* body= NULL;
00155 xmlDocPtr doc= NULL;
00156 xmlNodePtr root_node= NULL, status_node= NULL;
00157 xmlNodePtr node= NULL, person_node= NULL;
00158 xmlNodePtr tuple_node= NULL, basic_node= NULL;
00159 char* show_cont= NULL, *status_cont= NULL;
00160 char* entity= NULL;
00161 char* type= NULL;
00162 char* status= NULL;
00163
00164 LM_DBG("start\n");
00165
00166 entity=(char*)pkg_malloc(7+ strlen(uri)*sizeof(char));
00167 if(entity== NULL)
00168 {
00169 LM_ERR("no more memory\n");
00170 goto error;
00171 }
00172 strcpy(entity, "pres:");
00173 memcpy(entity+5, uri+4, strlen(uri)-4);
00174 entity[1+ strlen(uri)]= '\0';
00175 LM_DBG("entity: %s\n", entity);
00176
00177 doc= xmlNewDoc(BAD_CAST "1.0");
00178 if(doc== NULL)
00179 {
00180 LM_ERR("allocating new xml doc\n");
00181 goto error;
00182 }
00183
00184 root_node = xmlNewNode(NULL, BAD_CAST "presence");
00185 if(root_node== 0)
00186 {
00187 LM_ERR("extracting presence node\n");
00188 goto error;
00189 }
00190 xmlDocSetRootElement(doc, root_node);
00191
00192 xmlNewProp(root_node, BAD_CAST "xmlns",
00193 BAD_CAST "urn:ietf:params:xml:ns:pidf");
00194 xmlNewProp(root_node, BAD_CAST "xmlns:dm",
00195 BAD_CAST "urn:ietf:params:xml:ns:pidf:data-model");
00196 xmlNewProp(root_node, BAD_CAST "xmlns:rpid",
00197 BAD_CAST "urn:ietf:params:xml:ns:pidf:rpid" );
00198 xmlNewProp(root_node, BAD_CAST "xmlns:c",
00199 BAD_CAST "urn:ietf:params:xml:ns:pidf:cipid");
00200 xmlNewProp(root_node, BAD_CAST "entity", BAD_CAST entity);
00201
00202 tuple_node =xmlNewChild(root_node, NULL, BAD_CAST "tuple", NULL) ;
00203 if( tuple_node ==NULL)
00204 {
00205 LM_ERR("while adding child\n");
00206 goto error;
00207 }
00208
00209 status_node = xmlNewChild(tuple_node, NULL, BAD_CAST "status", NULL) ;
00210 if( status_node ==NULL)
00211 {
00212 LM_ERR("while adding child\n");
00213 goto error;
00214 }
00215
00216 type= XMLNodeGetAttrContentByName(pres_node, "type");
00217 if(type== NULL)
00218 {
00219 basic_node = xmlNewChild(status_node, NULL, BAD_CAST "basic",
00220 BAD_CAST "open") ;
00221 if( basic_node ==NULL)
00222 {
00223 LM_ERR("while adding child\n");
00224 goto error;
00225 }
00226
00227 }
00228 else
00229 {
00230 basic_node = xmlNewChild(status_node, NULL, BAD_CAST "basic",
00231 BAD_CAST "closed") ;
00232 if( basic_node ==NULL)
00233 {
00234 LM_ERR("while adding child\n");
00235 goto error;
00236 }
00237 goto done;
00238 }
00239
00240 status_cont= XMLNodeGetNodeContentByName(pres_node, "status", NULL);
00241 show_cont= XMLNodeGetNodeContentByName(pres_node, "show", NULL);
00242
00243 if(show_cont)
00244 {
00245 if(strcmp(show_cont, "xa")== 0)
00246 status= "not available";
00247 else
00248 if(strcmp(show_cont, "chat")== 0)
00249 status= "free for chat";
00250 else
00251 if(strcmp(show_cont, "dnd")== 0)
00252 status= "do not disturb";
00253 else
00254 status= show_cont;
00255 }
00256
00257 if(status_cont)
00258 {
00259
00260
00261
00262
00263
00264
00265
00266
00267 node = xmlNewChild(root_node, NULL, BAD_CAST "note",
00268 BAD_CAST status_cont);
00269 if(node== NULL)
00270 {
00271 LM_ERR("while adding node\n");
00272 goto error;
00273 }
00274 }else
00275 if(show_cont)
00276 {
00277 node = xmlNewChild(root_node, NULL, BAD_CAST "note",
00278 BAD_CAST status);
00279 if(node== NULL)
00280 {
00281 LM_ERR("while adding node\n");
00282 goto error;
00283 }
00284 }
00285
00286 if(show_cont)
00287 {
00288 LM_DBG("show_cont= %s\n", show_cont);
00289 if(person_node== NULL)
00290 {
00291 person_node= xmlNewChild(root_node, NULL, BAD_CAST "person",0 );
00292 if(person_node== NULL)
00293 {
00294 LM_ERR("while adding node\n");
00295 goto error;
00296 }
00297 }
00298 node= xmlNewChild(person_node, NULL, BAD_CAST "activities",
00299 BAD_CAST 0);
00300 if(node== NULL)
00301 {
00302 LM_ERR("while adding node\n");
00303 goto error;
00304 }
00305
00306
00307 if( xmlNewChild(person_node, NULL, BAD_CAST "note",
00308 BAD_CAST status )== NULL)
00309 {
00310 LM_ERR("while adding node\n");
00311 goto error;
00312 }
00313
00314
00315 }
00316
00317
00318 done:
00319 body= (str* )pkg_malloc(sizeof(str));
00320 if(body== NULL)
00321 {
00322 LM_ERR("no more memory\n");
00323 goto error;
00324 }
00325 xmlDocDumpFormatMemory(doc,(xmlChar**)(void*)&body->s, &body->len, 1);
00326
00327 if(entity)
00328 pkg_free(entity);
00329 if(status_cont)
00330 xmlFree(status_cont);
00331 if(show_cont)
00332 xmlFree(show_cont);
00333 if(type)
00334 xmlFree(type);
00335 xmlFreeDoc(doc);
00336
00337 return body;
00338
00339 error:
00340 if(entity)
00341 pkg_free(entity);
00342 if(body)
00343 {
00344 if(body->s)
00345 xmlFree(body->s);
00346 pkg_free(body);
00347 }
00348 if(status_cont)
00349 xmlFree(status_cont);
00350 if(show_cont)
00351 xmlFree(show_cont);
00352 if(type)
00353 xmlFree(type);
00354 if(doc)
00355 xmlFreeDoc(doc);
00356
00357 return NULL;
00358 }
00359
00360
00361 int build_publish(xmlNodePtr pres_node, int expires)
00362 {
00363 str* body= NULL;
00364 publ_info_t publ;
00365 char* uri= NULL, *resource= NULL;
00366 char* pres_uri= NULL;
00367 char* slash;
00368 int uri_len;
00369 str uri_str;
00370
00371 LM_DBG("start... \n");
00372
00373 uri= XMLNodeGetAttrContentByName(pres_node, "from");
00374 if(uri== NULL)
00375 {
00376 LM_DBG("getting 'from' attribute\n");
00377 return -1;
00378 }
00379 uri_len= strlen(uri);
00380
00381 slash= memchr(uri, '/', strlen(uri));
00382 if(slash)
00383 {
00384 uri_len= slash- uri;
00385 resource= (char*)pkg_malloc((strlen(uri)-uri_len)*sizeof(char));
00386 if(resource== NULL)
00387 {
00388 LM_ERR("no more memory\n");
00389 return -1;
00390 }
00391 strcpy(resource, slash+1);
00392 slash= '\0';
00393 }
00394 pres_uri= euri_xmpp_sip(uri);
00395 if(pres_uri== NULL)
00396 {
00397 LM_ERR("while encoding xmpp-sip uri\n");
00398 goto error;
00399 }
00400 xmlFree(uri);
00401 uri_str.s= pres_uri;
00402 uri_str.len= strlen(pres_uri);
00403
00404 body= build_pidf(pres_node, pres_uri, resource);
00405 if(body== NULL)
00406 {
00407 LM_ERR("while constructing PUBLISH body\n");
00408 goto error;
00409 }
00410
00411
00412
00413 memset(&publ, 0, sizeof(publ_info_t));
00414
00415 publ.pres_uri= &uri_str;
00416
00417 LM_DBG("publ->pres_uri: %.*s - %d\n", publ.pres_uri->len,
00418 publ.pres_uri->s, publ.pres_uri->len );
00419
00420 publ.body= body;
00421
00422 LM_DBG("publ->notify body: %.*s - %d\n", publ.body->len,
00423 publ.body->s, publ.body->len);
00424
00425 publ.source_flag|= XMPP_PUBLISH;
00426 publ.expires= expires;
00427 publ.event= PRESENCE_EVENT;
00428 publ.extra_headers= NULL;
00429
00430 if( pua_send_publish(&publ)< 0)
00431 {
00432 LM_ERR("while sending publish\n");
00433 goto error;
00434 }
00435
00436 if(resource)
00437 pkg_free(resource);
00438 if(body)
00439 {
00440 if(body->s)
00441 xmlFree(body->s);
00442 pkg_free(body);
00443 }
00444
00445 return 0;
00446
00447 error:
00448
00449 if(resource)
00450 pkg_free(resource);
00451
00452 if(body)
00453 {
00454 if(body->s)
00455 xmlFree(body->s);
00456 pkg_free(body);
00457 }
00458
00459 return -1;
00460
00461 }
00462
00463 int presence_subscribe(xmlNodePtr pres_node, int expires,int flag)
00464 {
00465 subs_info_t subs;
00466 char* to_uri= NULL, *from_uri= NULL;
00467 char* uri= NULL;
00468 char* type= NULL;
00469 str to_uri_str;
00470 str from_uri_str;
00471
00472 uri= XMLNodeGetAttrContentByName(pres_node, "to");
00473 if(uri== NULL)
00474 {
00475 LM_ERR("while getting attribute from xml doc\n");
00476 return -1;
00477 }
00478 to_uri= duri_xmpp_sip(uri);
00479 if(to_uri== NULL)
00480 {
00481 LM_ERR("while decoding xmpp--sip uri\n");
00482 goto error;
00483 }
00484 xmlFree(uri);
00485 to_uri_str.s= to_uri;
00486 to_uri_str.len= strlen(to_uri);
00487
00488 uri= XMLNodeGetAttrContentByName(pres_node, "from");
00489 if(uri== NULL)
00490 {
00491 LM_ERR("while getting attribute from xml doc\n");
00492 goto error;
00493 }
00494 from_uri= euri_xmpp_sip(uri);
00495 if(from_uri== NULL)
00496 {
00497 LM_ERR("while encoding xmpp-sip uri\n");
00498 goto error;
00499 }
00500 xmlFree(uri);
00501 from_uri_str.s= from_uri;
00502 from_uri_str.len= strlen(from_uri);
00503
00504 memset(&subs, 0, sizeof(subs_info_t));
00505
00506 subs.pres_uri= &to_uri_str;
00507 subs.watcher_uri= &from_uri_str;
00508 subs.contact= subs.watcher_uri;
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520 subs.source_flag|= flag;
00521 subs.event= PRESENCE_EVENT;
00522 subs.expires= expires;
00523
00524 LM_DBG("subs:\n");
00525 LM_DBG("\tpres_uri= %.*s\n", subs.pres_uri->len, subs.pres_uri->s);
00526 LM_DBG("\twatcher_uri= %.*s\n", subs.watcher_uri->len, subs.watcher_uri->s);
00527 LM_DBG("\texpires= %d\n", subs.expires);
00528
00529 if(pua_send_subscribe(&subs)< 0)
00530 {
00531 LM_ERR("while sending SUBSCRIBE\n");
00532 goto error;
00533 }
00534 return 0;
00535
00536 error:
00537 if(type)
00538 xmlFree(type);
00539
00540 return -1;
00541 }
00542