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 #include <stdio.h>
00026 #include <stdlib.h>
00027 #include <string.h>
00028 #include <libxml/parser.h>
00029 #include <time.h>
00030
00031 #include "../../parser/parse_expires.h"
00032 #include "../../parser/msg_parser.h"
00033 #include "../../str.h"
00034 #include "../../str_list.h"
00035 #include "../../name_alias.h"
00036 #include "../../socket_info.h"
00037 #include "../usrloc/usrloc.h"
00038 #include "../usrloc/ul_callback.h"
00039 #include "../../modules/tm/tm_load.h"
00040 #include "../pua/pua.h"
00041 #include "pua_dialoginfo.h"
00042
00043
00044 extern int include_callid;
00045 extern int include_localremote;
00046 extern int include_tags;
00047
00048
00049
00050 void print_publ(publ_info_t* p)
00051 {
00052 LM_DBG("publ:\n");
00053 LM_DBG("uri= %.*s\n", p->pres_uri->len, p->pres_uri->s);
00054 LM_DBG("id= %.*s\n", p->id.len, p->id.s);
00055 LM_DBG("expires= %d\n", p->expires);
00056 }
00057
00058 str* build_dialoginfo(char *state, str *entity, str *peer, str *callid,
00059 unsigned int initiator, str *localtag, str *remotetag,
00060 str *localtarget, str *remotetarget)
00061 {
00062 xmlDocPtr doc = NULL;
00063 xmlNodePtr root_node = NULL;
00064 xmlNodePtr dialog_node = NULL;
00065 xmlNodePtr state_node = NULL;
00066 xmlNodePtr remote_node = NULL;
00067 xmlNodePtr local_node = NULL;
00068 xmlNodePtr tag_node = NULL;
00069 str *body= NULL;
00070 char buf[MAX_URI_SIZE+1];
00071
00072 if (entity->len > MAX_URI_SIZE) {
00073 LM_ERR("entity URI '%.*s' too long, maximum=%d\n",entity->len, entity->s, MAX_URI_SIZE);
00074 return NULL;
00075 }
00076 memcpy(buf, entity->s, entity->len);
00077 buf[entity->len]= '\0';
00078
00079
00080 doc = xmlNewDoc(BAD_CAST "1.0");
00081 if(doc==0)
00082 return NULL;
00083
00084 root_node = xmlNewNode(NULL, BAD_CAST "dialog-info");
00085 if(root_node==0)
00086 goto error;
00087
00088 xmlDocSetRootElement(doc, root_node);
00089
00090 xmlNewProp(root_node, BAD_CAST "xmlns",
00091 BAD_CAST "urn:ietf:params:xml:ns:dialog-info");
00092
00093
00094 xmlNewProp(root_node, BAD_CAST "version",
00095 BAD_CAST "0");
00096 xmlNewProp(root_node, BAD_CAST "state",
00097 BAD_CAST "full" );
00098 xmlNewProp(root_node, BAD_CAST "entity",
00099 BAD_CAST buf);
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 dialog_node =xmlNewChild(root_node, NULL, BAD_CAST "dialog", NULL) ;
00112 if( dialog_node ==NULL)
00113 {
00114 LM_ERR("while adding child\n");
00115 goto error;
00116 }
00117
00118 if (callid->len > MAX_URI_SIZE) {
00119 LM_ERR("call-id '%.*s' too long, maximum=%d\n", callid->len, callid->s, MAX_URI_SIZE);
00120 return NULL;
00121 }
00122 memcpy(buf, callid->s, callid->len);
00123 buf[callid->len]= '\0';
00124
00125 xmlNewProp(dialog_node, BAD_CAST "id", BAD_CAST buf);
00126 if (include_callid) {
00127 xmlNewProp(dialog_node, BAD_CAST "call-id", BAD_CAST buf);
00128 }
00129 if (include_tags) {
00130 if (localtag && localtag->s) {
00131 if (localtag->len > MAX_URI_SIZE) {
00132 LM_ERR("localtag '%.*s' too long, maximum=%d\n", localtag->len, localtag->s, MAX_URI_SIZE);
00133 return NULL;
00134 }
00135 memcpy(buf, localtag->s, localtag->len);
00136 buf[localtag->len]= '\0';
00137 xmlNewProp(dialog_node, BAD_CAST "local-tag", BAD_CAST buf);
00138 }
00139 if (remotetag && remotetag->s) {
00140 if (remotetag->len > MAX_URI_SIZE) {
00141 LM_ERR("remotetag '%.*s' too long, maximum=%d\n", remotetag->len, remotetag->s, MAX_URI_SIZE);
00142 return NULL;
00143 }
00144 memcpy(buf, remotetag->s, remotetag->len);
00145 buf[remotetag->len]= '\0';
00146 xmlNewProp(dialog_node, BAD_CAST "remote-tag", BAD_CAST buf);
00147 }
00148 }
00149
00150 if (initiator) {
00151 xmlNewProp(dialog_node, BAD_CAST "direction", BAD_CAST "initiator");
00152 }else {
00153 xmlNewProp(dialog_node, BAD_CAST "direction", BAD_CAST "recipient");
00154 }
00155
00156
00157 state_node = xmlNewChild(dialog_node, NULL, BAD_CAST "state", BAD_CAST state) ;
00158 if( state_node ==NULL)
00159 {
00160 LM_ERR("while adding child\n");
00161 goto error;
00162 }
00163
00164 if (include_localremote) {
00165
00166 remote_node = xmlNewChild(dialog_node, NULL, BAD_CAST "remote", NULL) ;
00167 if( remote_node ==NULL)
00168 {
00169 LM_ERR("while adding child\n");
00170 goto error;
00171 }
00172
00173 if (peer->len > MAX_URI_SIZE) {
00174 LM_ERR("peer '%.*s' too long, maximum=%d\n", peer->len, peer->s, MAX_URI_SIZE);
00175 return NULL;
00176 }
00177 memcpy(buf, peer->s, peer->len);
00178 buf[peer->len]= '\0';
00179
00180 tag_node = xmlNewChild(remote_node, NULL, BAD_CAST "identity", BAD_CAST buf) ;
00181 if( tag_node ==NULL)
00182 {
00183 LM_ERR("while adding child\n");
00184 goto error;
00185 }
00186 tag_node = xmlNewChild(remote_node, NULL, BAD_CAST "target", NULL) ;
00187 if( tag_node ==NULL)
00188 {
00189 LM_ERR("while adding child\n");
00190 goto error;
00191 }
00192 if (remotetarget && remotetarget->s) {
00193 memcpy(buf, remotetarget->s, remotetarget->len);
00194 buf[remotetarget->len]= '\0';
00195 }
00196 xmlNewProp(tag_node, BAD_CAST "uri", BAD_CAST buf);
00197
00198
00199 local_node = xmlNewChild(dialog_node, NULL, BAD_CAST "local", NULL) ;
00200 if( local_node ==NULL)
00201 {
00202 LM_ERR("while adding child\n");
00203 goto error;
00204 }
00205
00206 if (entity->len > MAX_URI_SIZE) {
00207 LM_ERR("entity '%.*s' too long, maximum=%d\n", entity->len, entity->s, MAX_URI_SIZE);
00208 return NULL;
00209 }
00210 memcpy(buf, entity->s, entity->len);
00211 buf[entity->len]= '\0';
00212
00213 tag_node = xmlNewChild(local_node, NULL, BAD_CAST "identity", BAD_CAST buf) ;
00214 if( tag_node ==NULL)
00215 {
00216 LM_ERR("while adding child\n");
00217 goto error;
00218 }
00219 tag_node = xmlNewChild(local_node, NULL, BAD_CAST "target", NULL) ;
00220 if( tag_node ==NULL)
00221 {
00222 LM_ERR("while adding child\n");
00223 goto error;
00224 }
00225 if (localtarget && localtarget->s) {
00226 memcpy(buf, localtarget->s, localtarget->len);
00227 buf[localtarget->len]= '\0';
00228 }
00229 xmlNewProp(tag_node, BAD_CAST "uri", BAD_CAST buf);
00230 }
00231
00232
00233 body = (str*)pkg_malloc(sizeof(str));
00234 if(body == NULL)
00235 {
00236 LM_ERR("while allocating memory\n");
00237 return NULL;
00238 }
00239 memset(body, 0, sizeof(str));
00240
00241 xmlDocDumpFormatMemory(doc,(unsigned char**)(void*)&body->s,&body->len,1);
00242
00243 LM_DBG("new_body:\n%.*s\n",body->len, body->s);
00244
00245
00246 xmlFreeDoc(doc);
00247 xmlCleanupParser();
00248
00249 return body;
00250
00251 error:
00252 if(body)
00253 {
00254 if(body->s)
00255 xmlFree(body->s);
00256 pkg_free(body);
00257 }
00258 if(doc)
00259 xmlFreeDoc(doc);
00260 return NULL;
00261 }
00262
00263 void dialog_publish(char *state, str* ruri, str *entity, str *peer, str *callid,
00264 unsigned int initiator, unsigned int lifetime, str *localtag, str *remotetag,
00265 str *localtarget, str *remotetarget, unsigned short do_pubruri_localcheck)
00266 {
00267 str* body= NULL;
00268 str uri= {NULL, 0};
00269 publ_info_t* publ= NULL;
00270 int size= 0;
00271 str content_type;
00272 struct sip_uri ruri_uri;
00273
00274
00275 if (parse_uri(ruri->s, ruri->len, &ruri_uri) < 0) {
00276 LM_ERR("failed to parse the PUBLISH R-URI\n");
00277 return;
00278 }
00279
00280 if(do_pubruri_localcheck) {
00281
00282
00283 if (!check_self(&(ruri_uri.host), 0, 0)) {
00284 LM_DBG("do not send PUBLISH to external URI %.*s\n",ruri->len, ruri->s);
00285 return;
00286 }
00287
00288 }
00289
00290 content_type.s= "application/dialog-info+xml";
00291 content_type.len= 27;
00292
00293 body= build_dialoginfo(state, entity, peer, callid, initiator, localtag, remotetag, localtarget, remotetarget);
00294 if(body == NULL || body->s == NULL)
00295 goto error;
00296
00297 LM_DBG("publish uri= %.*s\n", ruri->len, ruri->s);
00298
00299 size= sizeof(publ_info_t)
00300 + sizeof(str)
00301 + ( ruri->len
00302 + callid->len + 16
00303 + content_type.len
00304 )*sizeof(char);
00305
00306 if(body)
00307 size+= sizeof(str)+ body->len* sizeof(char);
00308
00309 publ= (publ_info_t*)pkg_malloc(size);
00310 if(publ== NULL)
00311 {
00312 LM_ERR("no more share memory\n");
00313 goto error;
00314 }
00315 memset(publ, 0, size);
00316 size= sizeof(publ_info_t);
00317
00318 publ->pres_uri= (str*)((char*)publ + size);
00319 size+= sizeof(str);
00320 publ->pres_uri->s= (char*)publ+ size;
00321 memcpy(publ->pres_uri->s, ruri->s, ruri->len);
00322 publ->pres_uri->len= ruri->len;
00323 size+= ruri->len;
00324
00325 if(body)
00326 {
00327 publ->body= (str*)( (char*)publ + size);
00328 size+= sizeof(str);
00329
00330 publ->body->s= (char*)publ + size;
00331 memcpy(publ->body->s, body->s, body->len);
00332 publ->body->len= body->len;
00333 size+= body->len;
00334 }
00335 publ->id.s= (char*)publ+ size;
00336 memcpy(publ->id.s, "DIALOG_PUBLISH.", 15);
00337 memcpy(publ->id.s+15, callid->s, callid->len);
00338 publ->id.len= 15+ callid->len;
00339 size+= publ->id.len;
00340
00341 publ->content_type.s= (char*)publ+ size;
00342 memcpy(publ->content_type.s, content_type.s, content_type.len);
00343 publ->content_type.len= content_type.len;
00344 size+= content_type.len;
00345
00346 publ->expires= lifetime;
00347
00348
00349
00350 publ->flag|= UPDATE_TYPE;
00351
00352 publ->source_flag|= DIALOG_PUBLISH;
00353 publ->event|= DIALOG_EVENT;
00354 publ->extra_headers= NULL;
00355 print_publ(publ);
00356 if(pua_send_publish(publ)< 0)
00357 {
00358 LM_ERR("while sending publish\n");
00359 }
00360
00361 error:
00362
00363 if(publ)
00364 pkg_free(publ);
00365
00366 if(body)
00367 {
00368 if(body->s)
00369 xmlFree(body->s);
00370 pkg_free(body);
00371 }
00372
00373 if(uri.s)
00374 pkg_free(uri.s);
00375
00376 return;
00377 }
00378
00379
00380
00381 void dialog_publish_multi(char *state, struct str_list* ruris, str *entity, str *peer, str *callid,
00382 unsigned int initiator, unsigned int lifetime, str *localtag, str *remotetag,
00383 str *localtarget, str *remotetarget, unsigned short do_pubruri_localcheck) {
00384
00385 while(ruris) {
00386 LM_INFO("CALLING dialog_publish for URI %.*s\n",ruris->s.len, ruris->s.s);
00387 dialog_publish(state,&(ruris->s),entity,peer,callid,initiator,lifetime,localtag,remotetag,localtarget,remotetarget,do_pubruri_localcheck);
00388 ruris=ruris->next;
00389 }
00390
00391 }