notify_body.c

Go to the documentation of this file.
00001 /*
00002  * $Id: notify_body.c 1337 2006-12-07 18:05:05Z bogdan_iancu $
00003  *
00004  * presence_xml module -  
00005  *
00006  * Copyright (C) 2006 Voice Sistem S.R.L.
00007  *
00008  * This file is part of Kamailio, a free SIP server.
00009  *
00010  * Kamailio is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version
00014  *
00015  * Kamailio is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License 
00021  * along with this program; if not, write to the Free Software 
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023  *
00024  * History:
00025  * --------
00026  *  2007-04-11  initial version (anca)
00027  */
00028 /*! \file
00029  * \brief Kamailio Presence_XML :: Notify BODY handling
00030  * \ingroup presence_xml
00031  */
00032 
00033 
00034 #include <string.h>
00035 #include <stdlib.h>
00036 #include <libxml/parser.h>
00037 
00038 #include "../../mem/mem.h"
00039 #include "../presence/utils_func.h"
00040 #include "../presence/hash.h"
00041 #include "xcap_auth.h"
00042 #include "pidf.h"
00043 #include "notify_body.h"
00044 #include "presence_xml.h"
00045 
00046 str* offline_nbody(str* body);
00047 str* agregate_xmls(str* pres_user, str* pres_domain, str** body_array, int n);
00048 str* get_final_notify_body( subs_t *subs, str* notify_body, xmlNodePtr rule_node);
00049 
00050 void free_xml_body(char* body)
00051 {
00052    if(body== NULL)
00053       return;
00054 
00055    xmlFree(body);
00056    body= NULL;
00057 }
00058 
00059 
00060 str* pres_agg_nbody(str* pres_user, str* pres_domain, str** body_array, int n, int off_index)
00061 {
00062    str* n_body= NULL;
00063    str* body= NULL;
00064 
00065    if(body_array== NULL && !pidf_manipulation)
00066       return NULL;
00067 
00068    if(off_index>= 0)
00069    {
00070       body= body_array[off_index];
00071       body_array[off_index]= offline_nbody(body);
00072 
00073       if(body_array[off_index]== NULL || body_array[off_index]->s== NULL)
00074       {
00075          LM_ERR("while constructing offline body\n");
00076          return NULL;
00077       }
00078    }
00079    LM_DBG("[user]=%.*s  [domain]= %.*s\n",
00080          pres_user->len, pres_user->s, pres_domain->len, pres_domain->s);
00081    n_body= agregate_xmls(pres_user, pres_domain, body_array, n);
00082    if(n_body== NULL && n!= 0)
00083    {
00084       LM_ERR("while aggregating body\n");
00085    }
00086 
00087    if(off_index>= 0)
00088    {
00089       xmlFree(body_array[off_index]->s);
00090       pkg_free(body_array[off_index]);
00091       body_array[off_index]= body;
00092    }
00093 
00094    xmlCleanupParser();
00095     xmlMemoryDump();
00096 
00097    return n_body;
00098 }  
00099 
00100 int pres_apply_auth(str* notify_body, subs_t* subs, str** final_nbody)
00101 {
00102    xmlDocPtr doc= NULL;
00103    xmlNodePtr node= NULL;
00104    str* n_body= NULL;
00105    
00106    *final_nbody= NULL;
00107    if(force_active)
00108       return 0;
00109 
00110    if(subs->auth_rules_doc== NULL)
00111    {
00112       LM_ERR("NULL rules doc\n");
00113       return -1;
00114    }
00115    doc= xmlParseMemory(subs->auth_rules_doc->s, subs->auth_rules_doc->len);
00116    if(doc== NULL)
00117    {
00118       LM_ERR("parsing xml doc\n");
00119       return -1;
00120    }
00121    
00122    node= get_rule_node(subs, doc);
00123    if(node== NULL)
00124    {
00125       LM_DBG("The subscriber didn't match the conditions\n");
00126       xmlFreeDoc(doc);
00127       return 0;
00128    }
00129    
00130    n_body= get_final_notify_body(subs, notify_body, node);
00131    if(n_body== NULL)
00132    {
00133       LM_ERR("in function get_final_notify_body\n");
00134       xmlFreeDoc(doc);
00135       return -1;
00136    }
00137 
00138    xmlFreeDoc(doc);
00139    xmlCleanupParser();
00140     xmlMemoryDump();
00141 
00142    *final_nbody= n_body;
00143    return 1;
00144 
00145 }  
00146 
00147 str* get_final_notify_body( subs_t *subs, str* notify_body, xmlNodePtr rule_node)
00148 {
00149    xmlNodePtr transf_node = NULL, node = NULL, dont_provide = NULL;
00150    xmlNodePtr doc_root = NULL, doc_node = NULL, provide_node = NULL;
00151    xmlNodePtr all_node = NULL;
00152    xmlDocPtr doc= NULL;
00153    char name[15];
00154    char service_uri_scheme[10];
00155    int i= 0, found = 0;
00156    str* new_body = NULL;
00157     char* class_cont = NULL, *occurence_ID= NULL, *service_uri= NULL;
00158    char* deviceID = NULL;
00159    char* content = NULL;
00160    char all_name[20];
00161 
00162    strcpy(all_name, "all-");
00163 
00164    new_body = (str*)pkg_malloc(sizeof(str));
00165    if(new_body == NULL)
00166    {
00167       LM_ERR("while allocating memory\n");
00168       return NULL;
00169    }  
00170 
00171    memset(new_body, 0, sizeof(str));
00172 
00173    doc = xmlParseMemory(notify_body->s, notify_body->len);
00174    if(doc== NULL) 
00175    {
00176       LM_ERR("while parsing the xml body message\n");
00177       goto error;
00178    }
00179    doc_root = xmlDocGetNodeByName(doc,"presence", NULL);
00180    if(doc_root == NULL)
00181    {
00182       LM_ERR("while extracting the presence node\n");
00183       goto error;
00184    }
00185 
00186    transf_node = xmlNodeGetChildByName(rule_node, "transformations");
00187    if(transf_node == NULL)
00188    {
00189       LM_DBG("transformations node not found\n");
00190       goto done;
00191    }
00192    
00193    for(node = transf_node->children; node; node = node->next )
00194    {
00195       if(xmlStrcasecmp(node->name, (unsigned char*)"text")== 0)
00196          continue;
00197 
00198       LM_DBG("transf_node->name:%s\n",node->name);
00199 
00200       strcpy((char*)name ,(char*)(node->name + 8));
00201       strcpy(all_name+4, name);
00202       
00203       if(xmlStrcasecmp((unsigned char*)name,(unsigned char*)"services") == 0)
00204          strcpy(name, "tuple");
00205       if(strncmp((char*)name,"person", 6) == 0)
00206          name[6] = '\0';
00207 
00208       doc_node = xmlNodeGetNodeByName(doc_root, name, NULL);
00209       if(doc_node == NULL)
00210          continue;
00211       LM_DBG("searched doc_node->name:%s\n",name);
00212    
00213       content = (char*)xmlNodeGetContent(node);
00214       if(content)
00215       {
00216          LM_DBG("content = %s\n", content);
00217       
00218          if(xmlStrcasecmp((unsigned char*)content,
00219                (unsigned char*) "FALSE") == 0)
00220          {
00221             LM_DBG("found content false\n");
00222             while( doc_node )
00223             {
00224                xmlUnlinkNode(doc_node);   
00225                xmlFreeNode(doc_node);
00226                doc_node = xmlNodeGetChildByName(doc_root, name);
00227             }
00228             xmlFree(content);
00229             continue;
00230          }
00231       
00232          if(xmlStrcasecmp((unsigned char*)content,
00233                (unsigned char*) "TRUE") == 0)
00234          {
00235             LM_DBG("found content true\n");
00236             xmlFree(content);
00237             continue;
00238          }
00239          xmlFree(content);
00240       }
00241 
00242       while (doc_node )
00243       {
00244          if (xmlStrcasecmp(doc_node->name,(unsigned char*)"text")==0)
00245          {
00246             doc_node = doc_node->next;
00247             continue;
00248          }
00249 
00250          if (xmlStrcasecmp(doc_node->name,(unsigned char*)name)!=0)
00251          {
00252             break;
00253          }
00254          all_node = xmlNodeGetChildByName(node, all_name) ;
00255       
00256          if( all_node )
00257          {
00258             LM_DBG("must provide all\n");
00259             doc_node = doc_node->next;
00260             continue;
00261          }
00262 
00263          found = 0;
00264          class_cont = xmlNodeGetNodeContentByName(doc_node, "class", 
00265                NULL);
00266          if(class_cont == NULL)
00267             LM_DBG("no class tag found\n");
00268          else
00269             LM_DBG("found class = %s\n", class_cont);
00270 
00271          occurence_ID = xmlNodeGetAttrContentByName(doc_node, "id");
00272          if(occurence_ID == NULL)
00273             LM_DBG("no id found\n");
00274          else
00275             LM_DBG("found id = %s\n", occurence_ID);
00276 
00277 
00278          deviceID = xmlNodeGetNodeContentByName(doc_node, "deviceID",
00279                NULL);   
00280          if(deviceID== NULL)
00281             LM_DBG("no deviceID found\n");
00282          else
00283             LM_DBG("found deviceID = %s\n",  deviceID);
00284 
00285 
00286          service_uri = xmlNodeGetNodeContentByName(doc_node, "contact",
00287                NULL);   
00288          if(service_uri == NULL)
00289             LM_DBG("no service_uri found\n");
00290          else
00291             LM_DBG("found service_uri = %s\n", service_uri);
00292          i = 0;
00293          if(service_uri!= NULL)
00294          {
00295             while(service_uri[i]!= ':')
00296             {
00297                service_uri_scheme[i] = service_uri[i];
00298                i++;
00299             }
00300             service_uri_scheme[i] = '\0';
00301             LM_DBG("service_uri_scheme: %s\n", service_uri_scheme);
00302          }
00303 
00304          provide_node = node->children;
00305             
00306          while ( provide_node!= NULL )
00307          {
00308             if(xmlStrcasecmp(provide_node->name,(unsigned char*) "text")==0)
00309             {
00310                provide_node =    provide_node->next;
00311                continue;
00312             }
00313 
00314             if(xmlStrcasecmp(provide_node->name,(unsigned char*)"class")== 0
00315                   && class_cont )
00316             {
00317                content = (char*)xmlNodeGetContent(provide_node);
00318 
00319                if(content&& xmlStrcasecmp((unsigned char*)content,
00320                         (unsigned char*)class_cont) == 0)
00321                {
00322                   found = 1;
00323                   LM_DBG("found class= %s", class_cont);
00324                   xmlFree(content);
00325                   break;
00326                }
00327                if(content)
00328                   xmlFree(content);
00329             }
00330             if(xmlStrcasecmp(provide_node->name,
00331                      (unsigned char*) "deviceID")==0&&deviceID )
00332             {
00333                content = (char*)xmlNodeGetContent(provide_node);
00334 
00335                if(content && xmlStrcasecmp ((unsigned char*)content,
00336                         (unsigned char*)deviceID) == 0)
00337                {
00338                   found = 1;
00339                   LM_DBG("found deviceID= %s", deviceID);
00340                   xmlFree(content);
00341                   break;
00342                }
00343                if(content)
00344                   xmlFree(content);
00345 
00346             }
00347             if(xmlStrcasecmp(provide_node->name,
00348                      (unsigned char*)"occurence-id")== 0&& occurence_ID)
00349             {
00350                content = (char*)xmlNodeGetContent(provide_node);
00351                if(content && xmlStrcasecmp ((unsigned char*)content,
00352                         (unsigned char*)occurence_ID) == 0)
00353                {
00354                   found = 1;
00355                   LM_DBG("found occurenceID= %s\n", occurence_ID);
00356                   xmlFree(content);
00357                   break;
00358                }
00359                if(content)
00360                   xmlFree(content);
00361 
00362             }
00363             if(xmlStrcasecmp(provide_node->name,
00364                      (unsigned char*)"service-uri")== 0 && service_uri)
00365             {
00366                content = (char*)xmlNodeGetContent(provide_node);
00367                if(content&& xmlStrcasecmp ((unsigned char*)content,
00368                         (unsigned char*)service_uri) == 0)
00369                {
00370                   found = 1;
00371                   LM_DBG("found service_uri= %s", service_uri);
00372                   xmlFree(content);
00373                   break;
00374                }
00375                if(content)
00376                   xmlFree(content);
00377 
00378             }
00379          
00380             if(xmlStrcasecmp(provide_node->name,
00381                   (unsigned char*)"service-uri-scheme")==0&& i)
00382             {
00383                content = (char*)xmlNodeGetContent(provide_node);
00384                LM_DBG("service_uri_scheme=%s\n",content);
00385                if(content && xmlStrcasecmp((unsigned char*)content,
00386                         (unsigned char*)service_uri_scheme) == 0)
00387                {
00388                   found = 1;
00389                   LM_DBG("found service_uri_scheme= %s", service_uri_scheme);
00390                   xmlFree(content);
00391                   break;
00392                }  
00393                if(content)
00394                   xmlFree(content);
00395 
00396             }
00397 
00398             provide_node = provide_node->next;
00399          }
00400          
00401          if(found == 0)
00402          {
00403             LM_DBG("delete node: %s\n", doc_node->name);
00404             dont_provide = doc_node;
00405             doc_node = doc_node->next;
00406             xmlUnlinkNode(dont_provide);  
00407             xmlFreeNode(dont_provide);
00408          }  
00409          else
00410             doc_node = doc_node->next;
00411    
00412       }
00413    }
00414 
00415 done:
00416    xmlDocDumpFormatMemory(doc,(xmlChar**)(void*)&new_body->s,
00417          &new_body->len, 1);
00418    LM_DBG("body = \n%.*s\n", new_body->len,
00419          new_body->s);
00420 
00421     xmlFreeDoc(doc);
00422 
00423    xmlFree(class_cont);
00424    xmlFree(occurence_ID);
00425    xmlFree(deviceID);
00426    xmlFree(service_uri);
00427     xmlCleanupParser();
00428     xmlMemoryDump();
00429 
00430     return new_body;
00431 error:
00432     if(doc)
00433       xmlFreeDoc(doc);
00434    if(new_body)
00435    {
00436       if(new_body->s)
00437          xmlFree(new_body->s);
00438       pkg_free(new_body);
00439    }
00440    if(class_cont)
00441       xmlFree(class_cont);
00442    if(occurence_ID)
00443       xmlFree(occurence_ID);
00444    if(deviceID)
00445       xmlFree(deviceID);
00446    if(service_uri)
00447       xmlFree(service_uri);
00448 
00449    return NULL;
00450 }  
00451 
00452 str* agregate_xmls(str* pres_user, str* pres_domain, str** body_array, int n)
00453 {
00454    int i, j= 0, append ;
00455    xmlNodePtr p_root= NULL, new_p_root= NULL ;
00456    xmlDocPtr* xml_array ;
00457    xmlNodePtr node = NULL;
00458    xmlNodePtr add_node = NULL ;
00459    str *body= NULL;
00460    char* id= NULL, *tuple_id = NULL;
00461    xmlDocPtr pidf_manip_doc= NULL;
00462    str* pidf_doc= NULL;
00463 
00464    xml_array = (xmlDocPtr*)pkg_malloc( (n+2)*sizeof(xmlDocPtr));
00465    if(xml_array== NULL)
00466    {
00467    
00468       LM_ERR("while alocating memory");
00469       return NULL;
00470    }
00471    memset(xml_array, 0, (n+2)*sizeof(xmlDocPtr)) ;
00472 
00473    /* if pidf_manipulation usage is configured */
00474    if(pidf_manipulation)
00475    {
00476       if( get_rules_doc(pres_user, pres_domain, PIDF_MANIPULATION, &pidf_doc)< 0)
00477       {
00478          LM_ERR("while getting xcap tree for doc_type PIDF_MANIPULATION\n");
00479          goto error;
00480       }  
00481       if(pidf_doc== NULL)
00482       {
00483          LM_DBG("No PIDF_MANIPULATION doc for [user]= %.*s [domain]= %.*s\n"
00484          ,pres_user->len, pres_user->s, pres_domain->len, pres_domain->s);
00485       }
00486       else
00487       {
00488          pidf_manip_doc= xmlParseMemory(pidf_doc->s, pidf_doc->len);
00489          pkg_free(pidf_doc->s);
00490          pkg_free(pidf_doc);
00491 
00492          if(pidf_manip_doc== NULL)
00493          {
00494             LM_ERR("parsing xml memory\n");
00495             goto error;
00496          }     
00497          else
00498          {  
00499             xml_array[0]= pidf_manip_doc;
00500             j++;
00501          }
00502       }
00503    }
00504    
00505    for(i=0; i<n; i++)
00506    {
00507       if(body_array[i] == NULL )
00508          continue;
00509 
00510       xml_array[j] = NULL;
00511       xml_array[j] = xmlParseMemory( body_array[i]->s, body_array[i]->len );
00512       
00513       if( xml_array[j]== NULL)
00514       {
00515          LM_ERR("while parsing xml body message\n");
00516          goto error;
00517       }
00518       j++;
00519 
00520    } 
00521 
00522    if(j== 0)  /* no body */
00523    {
00524       if(xml_array)
00525          pkg_free(xml_array);
00526       return NULL;
00527    }
00528 
00529    j--;
00530    p_root = xmlDocGetNodeByName( xml_array[j], "presence", NULL);
00531    if(p_root ==NULL)
00532    {
00533       LM_ERR("while geting the xml_tree root\n");
00534       goto error;
00535    }
00536 
00537    for(i= j-1; i>=0; i--)
00538    {
00539       new_p_root= xmlDocGetNodeByName( xml_array[i], "presence", NULL);
00540       if(new_p_root ==NULL)
00541       {
00542          LM_ERR("while geting the xml_tree root\n");
00543          goto error;
00544       }
00545 
00546       append= 1;
00547       node= xmlNodeGetChildByName(new_p_root, "tuple");
00548       if(node != NULL)
00549       {
00550          tuple_id= xmlNodeGetAttrContentByName(node, "id");
00551          if(tuple_id== NULL)
00552          {
00553             LM_ERR("while extracting tuple id\n");
00554             goto error;
00555          }
00556          for (node = p_root->children; node!=NULL; node = node->next)
00557          {     
00558             if( xmlStrcasecmp(node->name,(unsigned char*)"text")==0)
00559                continue;
00560          
00561             if( xmlStrcasecmp(node->name,(unsigned char*)"tuple")==0)
00562             {
00563                id = xmlNodeGetAttrContentByName(node, "id");
00564                if(id== NULL)
00565                {
00566                   LM_ERR("while extracting tuple id\n");
00567                   goto error;
00568                }
00569             
00570                if(xmlStrcasecmp((unsigned char*)tuple_id,
00571                         (unsigned char*)id )== 0)
00572                {
00573                   append = 0;
00574                   xmlFree(id);
00575                   break;
00576                }
00577                xmlFree(id);
00578             }
00579          }
00580          xmlFree(tuple_id);
00581          tuple_id= NULL;
00582       }
00583 
00584       if(append) 
00585       {  
00586          for(node= new_p_root->children; node; node= node->next)
00587          {  
00588             add_node= xmlCopyNode(node, 1);
00589             if(add_node== NULL)
00590             {
00591                LM_ERR("while copying node\n");
00592                goto error;
00593             }
00594             if(xmlAddChild(p_root, add_node)== NULL)
00595             {
00596                LM_ERR("while adding child\n");
00597                goto error;
00598             }
00599                         
00600          }
00601       }
00602    }
00603 
00604    body = (str*)pkg_malloc(sizeof(str));
00605    if(body == NULL)
00606    {
00607       ERR_MEM(PKG_MEM_STR);
00608    }
00609 
00610    xmlDocDumpFormatMemory(xml_array[j],(xmlChar**)(void*)&body->s, 
00611          &body->len, 1);   
00612 
00613    for(i=0; i<=j; i++)
00614    {
00615       if(xml_array[i]!=NULL)
00616          xmlFreeDoc( xml_array[i]);
00617    }
00618    if(xml_array!=NULL)
00619       pkg_free(xml_array);
00620     
00621    xmlCleanupParser();
00622     xmlMemoryDump();
00623 
00624    return body;
00625 
00626 error:
00627    if(xml_array!=NULL)
00628    {
00629       for(i=0; i<=j; i++)
00630       {
00631          if(xml_array[i]!=NULL)
00632             xmlFreeDoc( xml_array[i]);
00633       }
00634       pkg_free(xml_array);
00635    }
00636    if(tuple_id)
00637       xmlFree(tuple_id);
00638    if(body)
00639       pkg_free(body);
00640 
00641    return NULL;
00642 }
00643 
00644 str* offline_nbody(str* body)
00645 {
00646    xmlDocPtr doc= NULL;
00647    xmlDocPtr new_doc= NULL;
00648    xmlNodePtr node, tuple_node= NULL, status_node;
00649    xmlNodePtr root_node, add_node, pres_node;
00650    str* new_body;
00651 
00652    doc= xmlParseMemory(body->s, body->len);
00653    if(doc==  NULL)
00654    {
00655       LM_ERR("while parsing xml memory\n");
00656       return NULL;
00657    }
00658    node= xmlDocGetNodeByName(doc, "basic", NULL);
00659    if(node== NULL)
00660    {
00661       LM_ERR("while extracting basic node\n");
00662       goto error;
00663    }
00664    xmlNodeSetContent(node, (const unsigned char*)"closed");
00665 
00666    tuple_node= xmlDocGetNodeByName(doc, "tuple", NULL);
00667    if(tuple_node== NULL)
00668    {
00669       LM_ERR("while extracting tuple node\n");
00670       goto error;
00671    }
00672    status_node= xmlDocGetNodeByName(doc, "status", NULL);
00673    if(status_node== NULL)
00674    {
00675       LM_ERR("while extracting tuple node\n");
00676       goto error;
00677    }
00678 
00679    pres_node= xmlDocGetNodeByName(doc, "presence", NULL);
00680    if(node== NULL)
00681    {
00682       LM_ERR("while extracting presence node\n");
00683       goto error;
00684    }
00685 
00686     new_doc = xmlNewDoc(BAD_CAST "1.0");
00687     if(new_doc==0)
00688       goto error;
00689    root_node= xmlCopyNode(pres_node, 2);
00690    if(root_node== NULL)
00691    {
00692       LM_ERR("while copying node\n");
00693       goto error;
00694    }
00695     xmlDocSetRootElement(new_doc, root_node);
00696 
00697    tuple_node= xmlCopyNode(tuple_node, 2);
00698    if(tuple_node== NULL)
00699    {
00700       LM_ERR("while copying node\n");
00701       goto error;
00702    }
00703    xmlAddChild(root_node, tuple_node);
00704 
00705    add_node= xmlCopyNode(status_node, 1);
00706    if(add_node== NULL)
00707    {
00708       LM_ERR("while copying node\n");
00709       goto error;
00710    }
00711    xmlAddChild(tuple_node, add_node);
00712 
00713    new_body = (str*)pkg_malloc(sizeof(str));
00714    if(new_body == NULL)
00715    {
00716       ERR_MEM(PKG_MEM_STR);
00717    }
00718    memset(new_body, 0, sizeof(str));
00719 
00720    xmlDocDumpFormatMemory(new_doc,(xmlChar**)(void*)&new_body->s,
00721       &new_body->len, 1);
00722 
00723    xmlFreeDoc(doc);
00724    xmlFreeDoc(new_doc);
00725    xmlCleanupParser();
00726    xmlMemoryDump();
00727 
00728    return new_body;
00729 
00730 error:
00731    if(doc)
00732       xmlFreeDoc(doc);
00733    if(new_doc)
00734       xmlFreeDoc(new_doc);
00735    return NULL;
00736 
00737 }     
00738 

Generated on Wed May 23 20:00:28 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6