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
00034 #define MAX_INT_LEN 11
00035
00036 #include <string.h>
00037 #include <stdlib.h>
00038 #include <libxml/parser.h>
00039
00040 #include "../../mem/mem.h"
00041 #include "../presence/utils_func.h"
00042 #include "../presence/hash.h"
00043 #include "../presence/event_list.h"
00044 #include "../presence/presence.h"
00045 #include "../presence/presentity.h"
00046 #include "notify_body.h"
00047 #include "pidf.h"
00048
00049 str* agregate_xmls(str* pres_user, str* pres_domain, str** body_array, int n);
00050 extern int force_single_dialog;
00051
00052 void free_xml_body(char* body)
00053 {
00054 if(body== NULL)
00055 return;
00056
00057 xmlFree(body);
00058 body= NULL;
00059 }
00060
00061
00062 str* dlginfo_agg_nbody(str* pres_user, str* pres_domain, str** body_array, int n, int off_index)
00063 {
00064 str* n_body= NULL;
00065
00066 LM_DBG("[pres_user]=%.*s [pres_domain]= %.*s, [n]=%d\n",
00067 pres_user->len, pres_user->s, pres_domain->len, pres_domain->s, n);
00068
00069 if(body_array== NULL)
00070 return NULL;
00071
00072 n_body= agregate_xmls(pres_user, pres_domain, body_array, n);
00073 LM_DBG("[n_body]=%p\n", n_body);
00074 if(n_body) {
00075 LM_DBG("[*n_body]=%.*s\n",
00076 n_body->len, n_body->s);
00077 }
00078 if(n_body== NULL && n!= 0)
00079 {
00080 LM_ERR("while aggregating body\n");
00081 }
00082
00083 xmlCleanupParser();
00084 xmlMemoryDump();
00085
00086 return n_body;
00087 }
00088
00089 str* agregate_xmls(str* pres_user, str* pres_domain, str** body_array, int n)
00090 {
00091 int i, j= 0;
00092
00093 xmlDocPtr doc = NULL;
00094 xmlNodePtr root_node = NULL;
00095 xmlNsPtr namespace = NULL;
00096
00097 xmlNodePtr p_root= NULL;
00098 xmlDocPtr* xml_array ;
00099 xmlNodePtr node = NULL;
00100 char *state;
00101 int winner_priority = -1, priority ;
00102 xmlNodePtr winner_dialog_node = NULL ;
00103 str *body= NULL;
00104 char buf[MAX_URI_SIZE+1];
00105
00106 LM_DBG("[pres_user]=%.*s [pres_domain]= %.*s, [n]=%d\n",
00107 pres_user->len, pres_user->s, pres_domain->len, pres_domain->s, n);
00108
00109 xml_array = (xmlDocPtr*)pkg_malloc( n*sizeof(xmlDocPtr));
00110 if(xml_array== NULL)
00111 {
00112 LM_ERR("while allocating memory");
00113 return NULL;
00114 }
00115 memset(xml_array, 0, n*sizeof(xmlDocPtr)) ;
00116
00117
00118 for(i=0; i<n; i++)
00119 {
00120 if(body_array[i] == NULL )
00121 continue;
00122
00123 xml_array[j] = NULL;
00124 xml_array[j] = xmlParseMemory( body_array[i]->s, body_array[i]->len );
00125
00126
00127
00128 if( xml_array[j]== NULL)
00129 {
00130 LM_ERR("while parsing xml body message\n");
00131 goto error;
00132 }
00133 j++;
00134
00135 }
00136
00137 if(j== 0)
00138 {
00139 if(xml_array)
00140 pkg_free(xml_array);
00141 return NULL;
00142 }
00143
00144
00145
00146
00147
00148
00149
00150 if ( (pres_user->len + pres_domain->len + 1) > MAX_URI_SIZE) {
00151 LM_ERR("entity URI too long, maximum=%d\n", MAX_URI_SIZE);
00152 return NULL;
00153 }
00154 memcpy(buf, pres_user->s, pres_user->len);
00155 buf[pres_user->len] = '@';
00156 memcpy(buf + pres_user->len + 1, pres_domain->s, pres_domain->len);
00157 buf[pres_user->len + 1 + pres_domain->len]= '\0';
00158
00159 doc = xmlNewDoc(BAD_CAST "1.0");
00160 if(doc==0)
00161 return NULL;
00162
00163 root_node = xmlNewNode(NULL, BAD_CAST "dialog-info");
00164 if(root_node==0)
00165 goto error;
00166
00167 xmlDocSetRootElement(doc, root_node);
00168 namespace = xmlNewNs(root_node, BAD_CAST "urn:ietf:params:xml:ns:dialog-info", NULL);
00169 if (!namespace) {
00170 LM_ERR("creating namespace failed\n");
00171 }
00172 xmlSetNs(root_node, namespace);
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 xmlNewProp(root_node, BAD_CAST "version", BAD_CAST "00000000000");
00184 xmlNewProp(root_node, BAD_CAST "state", BAD_CAST "full" );
00185 xmlNewProp(root_node, BAD_CAST "entity", BAD_CAST buf);
00186
00187
00188 for(i=0; i<j; i++)
00189 {
00190
00191 p_root= xmlDocGetRootElement(xml_array[i]);
00192 if(p_root ==NULL) {
00193 LM_ERR("while geting the xml_tree root element\n");
00194 goto error;
00195 }
00196 if (p_root->children) {
00197 for (node = p_root->children; node; node = node->next) {
00198 if (node->type == XML_ELEMENT_NODE) {
00199 LM_DBG("node type: Element, name: %s\n", node->name);
00200
00201
00202
00203
00204
00205
00206 if (!force_single_dialog || (j==1)) {
00207 xmlUnlinkNode(node);
00208 if(xmlAddChild(root_node, node)== NULL) {
00209 LM_ERR("while adding child\n");
00210 goto error;
00211 }
00212 } else {
00213
00214
00215
00216 state = xmlNodeGetNodeContentByName(node, "state", NULL);
00217 if (state) {
00218 LM_DBG("state element content = %s\n", state);
00219 priority = get_dialog_state_priority(state);
00220 if (priority > winner_priority) {
00221 winner_priority = priority;
00222 LM_DBG("new winner priority = %s (%d)\n", state, winner_priority);
00223 winner_dialog_node = node;
00224 }
00225 xmlFree(state);
00226 }
00227 }
00228 }
00229 }
00230 }
00231 }
00232
00233 if (force_single_dialog && (j!=1)) {
00234 xmlUnlinkNode(winner_dialog_node);
00235 if(xmlAddChild(root_node, winner_dialog_node)== NULL) {
00236 LM_ERR("while adding winner-child\n");
00237 goto error;
00238 }
00239 }
00240
00241 body = (str*)pkg_malloc(sizeof(str));
00242 if(body == NULL) {
00243 ERR_MEM(PKG_MEM_STR);
00244 }
00245
00246 xmlDocDumpFormatMemory(doc,(xmlChar**)(void*)&body->s,
00247 &body->len, 1);
00248
00249 for(i=0; i<j; i++)
00250 {
00251 if(xml_array[i]!=NULL)
00252 xmlFreeDoc( xml_array[i]);
00253 }
00254 if (doc)
00255 xmlFreeDoc(doc);
00256 if(xml_array!=NULL)
00257 pkg_free(xml_array);
00258
00259 xmlCleanupParser();
00260 xmlMemoryDump();
00261
00262 return body;
00263
00264 error:
00265 if(xml_array!=NULL)
00266 {
00267 for(i=0; i<j; i++)
00268 {
00269 if(xml_array[i]!=NULL)
00270 xmlFreeDoc( xml_array[i]);
00271 }
00272 pkg_free(xml_array);
00273 }
00274 if(body)
00275 pkg_free(body);
00276
00277 return NULL;
00278 }
00279
00280
00281 int get_dialog_state_priority(char *state) {
00282 if (strcasecmp(state,"terminated") == 0)
00283 return 0;
00284 if (strcasecmp(state,"trying") == 0)
00285 return 1;
00286 if (strcasecmp(state,"proceeding") == 0)
00287 return 2;
00288 if (strcasecmp(state,"confirmed") == 0)
00289 return 3;
00290 if (strcasecmp(state,"early") == 0)
00291 return 4;
00292
00293 return 0;
00294 }
00295
00296
00297 str *dlginfo_body_setversion(subs_t *subs, str *body) {
00298 char *version_start=0;
00299 char version[MAX_INT_LEN + 2];
00300 int version_len;
00301
00302 if (!body) {
00303 return NULL;
00304 }
00305
00306
00307
00308 if (body->len < 41) {
00309 LM_ERR("body string too short!\n");
00310 return NULL;
00311 }
00312 version_start = strstr(body->s + 34, "version=");
00313 if (!version_start) {
00314 LM_ERR("version string not found!\n");
00315 return NULL;
00316 }
00317 version_start += 9;
00318
00319
00320
00321 if(strncmp(version_start, "00000000000\"", 12)!=0)
00322 return NULL;
00323
00324 version_len = snprintf(version, MAX_INT_LEN + 2,"%d\"", subs->version);
00325 if (version_len >= MAX_INT_LEN + 2) {
00326 LM_ERR("failed to convert 'version' to string\n");
00327 memcpy(version_start, "00000000000\"", 12);
00328 return NULL;
00329 }
00330
00331
00332
00333 LM_DBG("replace version with \"%s\n",version);
00334 memcpy(version_start, version, version_len);
00335 memset(version_start + version_len, ' ', 12 - version_len);
00336
00337 return NULL;
00338 }