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 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include <string.h>
00029 #include <time.h>
00030 #include <libxml/parser.h>
00031
00032 #include "../../mem/mem.h"
00033 #include "../../dprint.h"
00034 #include "../../ut.h"
00035 #include "../tm/tm_load.h"
00036 #include "../tm/dlg.h"
00037 #include "../../parser/msg_parser.h"
00038 #include "../../parser/contact/parse_contact.h"
00039 #include "../../parser/parse_from.h"
00040 #include "../../parser/parse_expires.h"
00041 #include "../presence/hash.h"
00042 #include "hash.h"
00043 #include "pua.h"
00044 #include "send_subscribe.h"
00045 #include "pua_callback.h"
00046 #include "event_list.h"
00047
00048
00049 void print_subs(subs_info_t* subs)
00050 {
00051 LM_DBG("pres_uri= %.*s - len: %d\n",
00052 subs->pres_uri->len, subs->pres_uri->s, subs->pres_uri->len );
00053 LM_DBG("watcher_uri= %.*s - len: %d\n",
00054 subs->watcher_uri->len, subs->watcher_uri->s,
00055 subs->watcher_uri->len);
00056
00057 }
00058
00059 str* subs_build_hdr(str* contact, int expires, int event, str* extra_headers)
00060 {
00061 str* str_hdr= NULL;
00062 static char buf[3000];
00063 char* subs_expires= NULL;
00064 int len= 1;
00065 pua_event_t* ev;
00066
00067 str_hdr= (str*)pkg_malloc(sizeof(str));
00068 if(str_hdr== NULL)
00069 {
00070 LM_ERR("no more memory\n");
00071 return NULL;
00072 }
00073 memset(str_hdr, 0, sizeof(str));
00074 str_hdr->s= buf;
00075
00076 ev= get_event(event);
00077 if(ev== NULL)
00078 {
00079 LM_ERR("getting event from list\n");
00080 goto error;
00081 }
00082
00083 memcpy(str_hdr->s ,"Max-Forwards: ", 14);
00084 str_hdr->len = 14;
00085 str_hdr->len+= sprintf(str_hdr->s+ str_hdr->len,"%d", MAX_FORWARD);
00086 memcpy(str_hdr->s+str_hdr->len, CRLF, CRLF_LEN);
00087 str_hdr->len += CRLF_LEN;
00088
00089 memcpy(str_hdr->s+ str_hdr->len ,"Event: ", 7);
00090 str_hdr->len+= 7;
00091 memcpy(str_hdr->s+ str_hdr->len, ev->name.s, ev->name.len);
00092 str_hdr->len+= ev->name.len;
00093 memcpy(str_hdr->s+str_hdr->len, CRLF, CRLF_LEN);
00094 str_hdr->len += CRLF_LEN;
00095
00096 memcpy(str_hdr->s+ str_hdr->len ,"Contact: <", 10);
00097 str_hdr->len += 10;
00098 memcpy(str_hdr->s +str_hdr->len, contact->s,
00099 contact->len);
00100 str_hdr->len+= contact->len;
00101 memcpy(str_hdr->s+ str_hdr->len, ">", 1);
00102 str_hdr->len+= 1;
00103 memcpy(str_hdr->s+str_hdr->len, CRLF, CRLF_LEN);
00104 str_hdr->len += CRLF_LEN;
00105
00106 memcpy(str_hdr->s+ str_hdr->len ,"Expires: ", 9);
00107 str_hdr->len += 9;
00108
00109 if( expires<= min_expires)
00110 subs_expires= int2str(min_expires, &len);
00111 else
00112 subs_expires= int2str(expires+ 10, &len);
00113
00114 if(subs_expires == NULL || len == 0)
00115 {
00116 LM_ERR("while converting int to str\n");
00117 pkg_free(str_hdr);
00118 return NULL;
00119 }
00120 memcpy(str_hdr->s+str_hdr->len, subs_expires, len);
00121 str_hdr->len += len;
00122 memcpy(str_hdr->s+str_hdr->len, CRLF, CRLF_LEN);
00123 str_hdr->len += CRLF_LEN;
00124
00125 if(extra_headers && extra_headers->len)
00126 {
00127 memcpy(str_hdr->s+str_hdr->len, extra_headers->s, extra_headers->len);
00128 str_hdr->len += extra_headers->len;
00129 }
00130
00131 str_hdr->s[str_hdr->len]= '\0';
00132
00133 return str_hdr;
00134
00135 error:
00136 if(str_hdr)
00137 pkg_free(str_hdr);
00138 return NULL;
00139 }
00140
00141 dlg_t* pua_build_dlg_t(ua_pres_t* presentity)
00142 {
00143 dlg_t* td =NULL;
00144 int size;
00145
00146 size= sizeof(dlg_t)+ presentity->call_id.len+ presentity->to_tag.len+
00147 presentity->from_tag.len+ presentity->watcher_uri->len+
00148 presentity->pres_uri->len+ presentity->remote_contact.len;
00149
00150 td = (dlg_t*)pkg_malloc(size);
00151 if(td == NULL)
00152 {
00153 LM_ERR("No memory left\n");
00154 return NULL;
00155 }
00156 memset(td, 0, size);
00157 size= sizeof(dlg_t);
00158
00159 td->id.call_id.s = (char*)td+ size;
00160 memcpy(td->id.call_id.s, presentity->call_id.s, presentity->call_id.len);
00161 td->id.call_id.len= presentity->call_id.len;
00162 size+= presentity->call_id.len;
00163
00164 td->id.rem_tag.s = (char*)td+ size;
00165 memcpy(td->id.rem_tag.s, presentity->to_tag.s, presentity->to_tag.len);
00166 td->id.rem_tag.len = presentity->to_tag.len;
00167 size+= presentity->to_tag.len;
00168
00169 td->id.loc_tag.s = (char*)td+ size;
00170 memcpy(td->id.loc_tag.s, presentity->from_tag.s, presentity->from_tag.len);
00171 td->id.loc_tag.len =presentity->from_tag.len;
00172 size+= presentity->from_tag.len;
00173
00174 td->loc_uri.s = (char*)td+ size;
00175 memcpy(td->loc_uri.s, presentity->watcher_uri->s,
00176 presentity->watcher_uri->len) ;
00177 td->loc_uri.len = presentity->watcher_uri->len;
00178 size+= td->loc_uri.len;
00179
00180 td->rem_uri.s = (char*)td+ size;
00181 memcpy(td->rem_uri.s, presentity->pres_uri->s, presentity->pres_uri->len) ;
00182 td->rem_uri.len = presentity->pres_uri->len;
00183 size+= td->rem_uri.len;
00184
00185 td->rem_target.s = (char*)td+ size;
00186 memcpy(td->rem_target.s, presentity->remote_contact.s,
00187 presentity->remote_contact.len) ;
00188 td->rem_target.len = presentity->remote_contact.len;
00189 size+= td->rem_target.len;
00190
00191 if(presentity->record_route.s && presentity->record_route.len)
00192 {
00193 if(parse_rr_body(presentity->record_route.s, presentity->record_route.len,
00194 &td->route_set)< 0)
00195 {
00196 LM_ERR("ERROR in function parse_rr_body\n");
00197 pkg_free(td);
00198 return NULL;
00199 }
00200 }
00201
00202 td->loc_seq.value = presentity->cseq;
00203 td->loc_seq.is_set = 1;
00204 td->state= DLG_CONFIRMED ;
00205
00206 LM_DBG("size = %d\n", size);
00207
00208 return td;
00209 }
00210
00211 void subs_cback_func(struct cell *t, int cb_type, struct tmcb_params *ps)
00212 {
00213 struct sip_msg* msg= NULL;
00214 int lexpire= 0;
00215 unsigned int cseq;
00216 ua_pres_t* presentity= NULL, *hentity= NULL;
00217 struct to_body *pto= NULL, *pfrom = NULL, TO;
00218 int size= 0;
00219 unsigned int hash_code;
00220 int flag ;
00221 str record_route= {0, 0};
00222 int rt;
00223 str contact;
00224 int initial_request = 0;
00225
00226 if( ps->param== NULL || *ps->param== NULL )
00227 {
00228 LM_ERR("null callback parameter\n");
00229 return;
00230 }
00231 LM_DBG("completed with status %d\n",ps->code) ;
00232 hentity= (ua_pres_t*)(*ps->param);
00233 hash_code= core_hash(hentity->pres_uri,hentity->watcher_uri,
00234 HASH_SIZE);
00235 flag= hentity->flag;
00236 if(hentity->flag & XMPP_INITIAL_SUBS)
00237 hentity->flag= XMPP_SUBSCRIBE;
00238
00239
00240 msg= ps->rpl;
00241 if(msg == NULL)
00242 {
00243 LM_ERR("no reply message found\n ");
00244 goto error;
00245 }
00246
00247 if(msg== FAKED_REPLY)
00248 {
00249
00250
00251 if(hentity->call_id.s== NULL)
00252 {
00253 LM_DBG("initial Subscribe request failed\n");
00254 goto done;
00255 }
00256
00257 lock_get(&HashT->p_records[hash_code].lock);
00258
00259 presentity= get_dialog(hentity, hash_code);
00260 if(presentity== NULL)
00261 {
00262 LM_ERR("no record found in hash table\n");
00263 lock_release(&HashT->p_records[hash_code].lock);
00264 goto done;
00265 }
00266
00267 delete_htable(presentity, hash_code);
00268 lock_release(&HashT->p_records[hash_code].lock);
00269 goto done;
00270 }
00271
00272 if ( parse_headers(msg,HDR_EOH_F, 0)==-1 )
00273 {
00274 LM_ERR("when parsing headers\n");
00275 goto done;
00276 }
00277
00278
00279
00280 if(hentity->call_id.s== NULL)
00281 {
00282 initial_request = 1;
00283 if(ps->code>= 300)
00284 {
00285 LM_DBG("initial Subscribe request failed\n");
00286 goto done;
00287 }
00288
00289 if( msg->callid==NULL || msg->callid->body.s==NULL)
00290 {
00291 LM_ERR("cannot parse callid header\n");
00292 goto done;
00293 }
00294
00295 if (!msg->from || !msg->from->body.s)
00296 {
00297 LM_ERR("cannot find 'from' header!\n");
00298 goto done;
00299 }
00300 if (msg->from->parsed == NULL)
00301 {
00302 if ( parse_from_header( msg )<0 )
00303 {
00304 LM_ERR("cannot parse From header\n");
00305 goto done;
00306 }
00307 }
00308 pfrom = (struct to_body*)msg->from->parsed;
00309
00310 if( pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0)
00311 {
00312 LM_ERR("no from tag value present\n");
00313 goto done;
00314 }
00315 if( msg->to==NULL || msg->to->body.s==NULL)
00316 {
00317 LM_ERR("cannot parse TO header\n");
00318 goto done;
00319 }
00320 if(msg->to->parsed != NULL)
00321 {
00322 pto = (struct to_body*)msg->to->parsed;
00323 LM_DBG("'To' header ALREADY PARSED: <%.*s>\n",pto->uri.len,pto->uri.s);
00324 }
00325 else
00326 {
00327 memset( &TO , 0, sizeof(TO) );
00328 parse_to(msg->to->body.s,msg->to->body.s +
00329 msg->to->body.len + 1, &TO);
00330 if(TO.uri.len <= 0)
00331 {
00332 LM_DBG("'To' header NOT parsed\n");
00333 goto done;
00334 }
00335 pto = &TO;
00336 }
00337 if( pto->tag_value.s ==NULL || pto->tag_value.len == 0)
00338 {
00339 LM_ERR("no to tag value present\n");
00340 goto done;
00341 }
00342 hentity->call_id= msg->callid->body;
00343 hentity->to_tag= pto->tag_value;
00344 hentity->from_tag= pfrom->tag_value;
00345
00346 }
00347
00348
00349 if(ps->rpl->expires && msg->expires->body.len > 0)
00350 {
00351 if (!msg->expires->parsed && (parse_expires(msg->expires) < 0))
00352 {
00353 LM_ERR("cannot parse Expires header\n");
00354 goto done;
00355 }
00356 lexpire = ((exp_body_t*)msg->expires->parsed)->val;
00357 LM_DBG("lexpire= %d\n", lexpire);
00358 }
00359
00360 lock_get(&HashT->p_records[hash_code].lock);
00361
00362 presentity= get_dialog(hentity, hash_code);
00363
00364 if(ps->code >= 300 )
00365 {
00366
00367
00368 if(presentity)
00369 {
00370 subs_info_t subs;
00371 hentity->event= presentity->event;
00372 delete_htable(presentity, hash_code);
00373 lock_release(&HashT->p_records[hash_code].lock);
00374
00375 memset(&subs, 0, sizeof(subs_info_t));
00376 subs.pres_uri= hentity->pres_uri;
00377 subs.watcher_uri= hentity->watcher_uri;
00378 subs.contact= &hentity->contact;
00379
00380 if(hentity->remote_contact.s)
00381 subs.remote_target= &hentity->remote_contact;
00382
00383 if(hentity->desired_expires== 0)
00384 subs.expires= -1;
00385 else
00386 if(hentity->desired_expires< (int)time(NULL))
00387 subs.expires= 0;
00388 else
00389 subs.expires= hentity->desired_expires- (int)time(NULL)+ 3;
00390
00391 subs.flag= INSERT_TYPE;
00392 subs.source_flag= flag;
00393 subs.event= hentity->event;
00394 subs.id= hentity->id;
00395 subs.outbound_proxy= hentity->outbound_proxy;
00396 subs.extra_headers= hentity->extra_headers;
00397 subs.cb_param= hentity->cb_param;
00398
00399 if(send_subscribe(&subs)< 0)
00400 {
00401 LM_ERR("when trying to send SUBSCRIBE\n");
00402 goto done;
00403 }
00404 }
00405 else
00406 {
00407 LM_DBG("No dialog found\n");
00408 lock_release(&HashT->p_records[hash_code].lock);
00409 }
00410 goto done;
00411 }
00412
00413
00414
00415 if(msg->contact== NULL || msg->contact->body.s== NULL)
00416 {
00417 LM_ERR("no contact header found");
00418 lock_release(&HashT->p_records[hash_code].lock);
00419 goto error;
00420 }
00421 if( parse_contact(msg->contact) <0 )
00422 {
00423 LM_ERR(" cannot parse contact header\n");
00424 lock_release(&HashT->p_records[hash_code].lock);
00425 goto error;
00426 }
00427
00428 if(msg->contact->parsed == NULL)
00429 {
00430 LM_ERR("cannot parse contact header\n");
00431 lock_release(&HashT->p_records[hash_code].lock);
00432 goto error;
00433 }
00434 contact = ((contact_body_t* )msg->contact->parsed)->contacts->uri;
00435
00436 if(presentity)
00437 {
00438 if(lexpire== 0 )
00439 {
00440 LM_DBG("lexpire= 0 Delete from hash table");
00441 delete_htable(presentity, hash_code);
00442 lock_release(&HashT->p_records[hash_code].lock);
00443 goto done;
00444 }
00445 LM_DBG("*** Update expires\n");
00446 update_htable(presentity, hentity->desired_expires, lexpire, NULL,
00447 hash_code, &contact);
00448 lock_release(&HashT->p_records[hash_code].lock);
00449 goto done;
00450 }
00451 if(initial_request == 0)
00452 {
00453 LM_ERR("Not initial request and no record found\n");
00454 lock_release(&HashT->p_records[hash_code].lock);
00455 goto error;
00456 }
00457
00458
00459 lock_release(&HashT->p_records[hash_code].lock);
00460
00461
00462 if(lexpire== 0)
00463 {
00464 LM_DBG("expires= 0: no not insert\n");
00465 goto done;
00466 }
00467
00468 if( msg->cseq==NULL || msg->cseq->body.s==NULL)
00469 {
00470 LM_ERR("cannot parse cseq header\n");
00471 goto done;
00472 }
00473
00474 if( str2int( &(get_cseq(msg)->number), &cseq)< 0)
00475 {
00476 LM_ERR("while converting str to int\n");
00477 goto done;
00478 }
00479
00480
00481 if (msg->record_route!=NULL)
00482 {
00483 rt = print_rr_body(msg->record_route, &record_route, 1, 0);
00484 if(rt != 0)
00485 {
00486 LM_ERR("parsing record route [%d]\n", rt);
00487 record_route.s=NULL;
00488 record_route.len=0;
00489 }
00490 }
00491
00492 size= sizeof(ua_pres_t)+ 2*sizeof(str)+( pto->uri.len+
00493 pfrom->uri.len+ pto->tag_value.len+ pfrom->tag_value.len
00494 +msg->callid->body.len+ record_route.len+ hentity->contact.len+
00495 hentity->id.len )*sizeof(char);
00496
00497 if(hentity->extra_headers)
00498 size+= sizeof(str)+ hentity->extra_headers->len*sizeof(char);
00499
00500 presentity= (ua_pres_t*)shm_malloc(size);
00501 if(presentity== NULL)
00502 {
00503 LM_ERR("no more share memory\n");
00504 if(record_route.s)
00505 pkg_free(record_route.s);
00506 goto done;
00507 }
00508 memset(presentity, 0, size);
00509 size= sizeof(ua_pres_t);
00510
00511 presentity->pres_uri= (str*)( (char*)presentity+ size);
00512 size+= sizeof(str);
00513 presentity->pres_uri->s= (char*)presentity+ size;
00514 memcpy(presentity->pres_uri->s, pto->uri.s, pto->uri.len);
00515 presentity->pres_uri->len= pto->uri.len;
00516 size+= pto->uri.len;
00517
00518 presentity->watcher_uri= (str*)( (char*)presentity+ size);
00519 size+= sizeof(str);
00520 presentity->watcher_uri->s= (char*)presentity+ size;
00521 memcpy(presentity->watcher_uri->s, pfrom->uri.s, pfrom->uri.len);
00522 presentity->watcher_uri->len= pfrom->uri.len;
00523 size+= pfrom->uri.len;
00524
00525 presentity->call_id.s= (char*)presentity + size;
00526 memcpy(presentity->call_id.s,msg->callid->body.s,
00527 msg->callid->body.len);
00528 presentity->call_id.len= msg->callid->body.len;
00529 size+= presentity->call_id.len;
00530
00531 presentity->to_tag.s= (char*)presentity + size;
00532 memcpy(presentity->to_tag.s,pto->tag_value.s,
00533 pto->tag_value.len);
00534 presentity->to_tag.len= pto->tag_value.len;
00535 size+= pto->tag_value.len;
00536
00537 presentity->from_tag.s= (char*)presentity + size;
00538 memcpy(presentity->from_tag.s,pfrom->tag_value.s,
00539 pfrom->tag_value.len);
00540 presentity->from_tag.len= pfrom->tag_value.len;
00541 size+= pfrom->tag_value.len;
00542
00543 if(record_route.len && record_route.s)
00544 {
00545 presentity->record_route.s= (char*)presentity + size;
00546 memcpy(presentity->record_route.s, record_route.s, record_route.len);
00547 presentity->record_route.len= record_route.len;
00548 size+= record_route.len;
00549 pkg_free(record_route.s);
00550 }
00551
00552
00553 presentity->contact.s= (char*)presentity + size;
00554 memcpy(presentity->contact.s, hentity->contact.s, hentity->contact.len);
00555 presentity->contact.len= hentity->contact.len;
00556 size+= hentity->contact.len;
00557
00558 if(hentity->id.s)
00559 {
00560 presentity->id.s=(char*)presentity+ size;
00561 memcpy(presentity->id.s, hentity->id.s,
00562 hentity->id.len);
00563 presentity->id.len= hentity->id.len;
00564 size+= presentity->id.len;
00565 }
00566
00567 if(hentity->extra_headers)
00568 {
00569 presentity->extra_headers= (str*)((char*)presentity+ size);
00570 size+= sizeof(str);
00571 presentity->extra_headers->s=(char*)presentity+ size;
00572 memcpy(presentity->extra_headers->s, hentity->extra_headers->s,
00573 hentity->extra_headers->len);
00574 presentity->extra_headers->len= hentity->extra_headers->len;
00575 size+= hentity->extra_headers->len;
00576 }
00577
00578
00579 presentity->remote_contact.s= (char*)shm_malloc(contact.len* sizeof(char));
00580 if(presentity->remote_contact.s== NULL)
00581 {
00582 ERR_MEM(SHARE_MEM);
00583 }
00584 memcpy(presentity->remote_contact.s, contact.s, contact.len);
00585 presentity->remote_contact.len= contact.len;
00586
00587 presentity->event|= hentity->event;
00588 presentity->flag= hentity->flag;
00589 presentity->etag.s= NULL;
00590 presentity->cseq= cseq;
00591 presentity->desired_expires= hentity->desired_expires;
00592 presentity->expires= lexpire+ (int)time(NULL);
00593 if(BLA_SUBSCRIBE & presentity->flag)
00594 {
00595 LM_DBG("BLA_SUBSCRIBE FLAG inserted\n");
00596 }
00597 LM_DBG("record for subscribe from %.*s to %.*s inserted in datatbase\n",
00598 presentity->watcher_uri->len, presentity->watcher_uri->s,
00599 presentity->pres_uri->len, presentity->pres_uri->s);
00600 insert_htable(presentity);
00601
00602 done:
00603 if(hentity->ua_flag == REQ_OTHER)
00604 {
00605 hentity->flag= flag;
00606 run_pua_callbacks( hentity, msg);
00607 }
00608 error:
00609 if(hentity)
00610 {
00611 shm_free(hentity);
00612 hentity= NULL;
00613 }
00614 return;
00615
00616 }
00617
00618 ua_pres_t* subscribe_cbparam(subs_info_t* subs, int ua_flag)
00619 {
00620 ua_pres_t* hentity= NULL;
00621 int size;
00622
00623 size= sizeof(ua_pres_t)+ 2*sizeof(str)+(subs->pres_uri->len+
00624 subs->watcher_uri->len+ subs->contact->len+ subs->id.len+ 1)*
00625 sizeof(char);
00626
00627 if(subs->outbound_proxy && subs->outbound_proxy->len && subs->outbound_proxy->s )
00628 size+= sizeof(str)+ subs->outbound_proxy->len* sizeof(char);
00629
00630 if(subs->extra_headers && subs->extra_headers->s)
00631 size+= sizeof(str)+ subs->extra_headers->len* sizeof(char);
00632
00633 hentity= (ua_pres_t*)shm_malloc(size);
00634 if(hentity== NULL)
00635 {
00636 LM_ERR("No more share memory\n");
00637 return NULL;
00638 }
00639 memset(hentity, 0, size);
00640
00641 size= sizeof(ua_pres_t);
00642
00643 hentity->pres_uri = (str*)((char*)hentity + size);
00644 size+= sizeof(str);
00645
00646 hentity->pres_uri->s = (char*)hentity+ size;
00647 memcpy(hentity->pres_uri->s, subs->pres_uri->s ,
00648 subs->pres_uri->len ) ;
00649 hentity->pres_uri->len= subs->pres_uri->len;
00650 size+= subs->pres_uri->len;
00651
00652 hentity->watcher_uri = (str*)((char*)hentity + size);
00653 size+= sizeof(str);
00654
00655 hentity->watcher_uri->s = (char*)hentity+ size;
00656 memcpy(hentity->watcher_uri->s, subs->watcher_uri->s ,
00657 subs->watcher_uri->len ) ;
00658 hentity->watcher_uri->len= subs->watcher_uri->len;
00659 size+= subs->watcher_uri->len;
00660
00661 hentity->contact.s = (char*)hentity+ size;
00662 memcpy(hentity->contact.s, subs->contact->s ,
00663 subs->contact->len );
00664 hentity->contact.len= subs->contact->len;
00665 size+= subs->contact->len;
00666
00667 if(subs->outbound_proxy)
00668 {
00669 hentity->outbound_proxy= (str*)((char*)hentity+ size);
00670 size+= sizeof(str);
00671 hentity->outbound_proxy->s= (char*)hentity+ size;
00672 memcpy(hentity->outbound_proxy->s, subs->outbound_proxy->s, subs->outbound_proxy->len);
00673 hentity->outbound_proxy->len= subs->outbound_proxy->len;
00674 size+= subs->outbound_proxy->len;
00675 }
00676 if(subs->expires< 0)
00677 hentity->desired_expires= 0;
00678 else
00679 hentity->desired_expires=subs->expires+ (int)time(NULL);
00680
00681 if(subs->id.s)
00682 {
00683 CONT_COPY(hentity, hentity->id, subs->id)
00684 }
00685 if(subs->extra_headers)
00686 {
00687 hentity->extra_headers= (str*)((char*)hentity+ size);
00688 size+= sizeof(str);
00689 hentity->extra_headers->s= (char*)hentity+ size;
00690 memcpy(hentity->extra_headers->s, subs->extra_headers->s,
00691 subs->extra_headers->len);
00692 hentity->extra_headers->len= subs->extra_headers->len;
00693 size+= subs->extra_headers->len;
00694 }
00695 hentity->flag= subs->source_flag;
00696 hentity->event= subs->event;
00697 hentity->ua_flag= hentity->ua_flag;
00698 hentity->cb_param= subs->cb_param;
00699 return hentity;
00700
00701 }
00702
00703 ua_pres_t* subs_cbparam_indlg(ua_pres_t* subs, int expires, int ua_flag)
00704 {
00705 ua_pres_t* hentity= NULL;
00706 int size;
00707
00708 size= sizeof(ua_pres_t)+ 2*sizeof(str)+subs->pres_uri->len+
00709 subs->watcher_uri->len+ subs->contact.len+ subs->id.len+
00710 subs->to_tag.len+ subs->call_id.len+ subs->from_tag.len+ 1;
00711
00712 if(subs->outbound_proxy && subs->outbound_proxy->len && subs->outbound_proxy->s )
00713 size+= sizeof(str)+ subs->outbound_proxy->len;
00714
00715 if(subs->extra_headers && subs->extra_headers->s)
00716 size+= sizeof(str)+ subs->extra_headers->len;
00717
00718 if(subs->remote_contact.s)
00719 size+= subs->remote_contact.len;
00720
00721 hentity= (ua_pres_t*)shm_malloc(size);
00722 if(hentity== NULL)
00723 {
00724 LM_ERR("No more share memory\n");
00725 return NULL;
00726 }
00727 memset(hentity, 0, size);
00728
00729 size= sizeof(ua_pres_t);
00730
00731 hentity->pres_uri = (str*)((char*)hentity + size);
00732 size+= sizeof(str);
00733
00734 hentity->pres_uri->s = (char*)hentity+ size;
00735 memcpy(hentity->pres_uri->s, subs->pres_uri->s ,
00736 subs->pres_uri->len ) ;
00737 hentity->pres_uri->len= subs->pres_uri->len;
00738 size+= subs->pres_uri->len;
00739
00740 hentity->watcher_uri = (str*)((char*)hentity + size);
00741 size+= sizeof(str);
00742
00743 hentity->watcher_uri->s = (char*)hentity+ size;
00744 memcpy(hentity->watcher_uri->s, subs->watcher_uri->s ,
00745 subs->watcher_uri->len ) ;
00746 hentity->watcher_uri->len= subs->watcher_uri->len;
00747 size+= subs->watcher_uri->len;
00748
00749 CONT_COPY(hentity, hentity->contact, subs->contact)
00750
00751 if(subs->outbound_proxy)
00752 {
00753 hentity->outbound_proxy= (str*)((char*)hentity+ size);
00754 size+= sizeof(str);
00755 hentity->outbound_proxy->s= (char*)hentity+ size;
00756 memcpy(hentity->outbound_proxy->s, subs->outbound_proxy->s, subs->outbound_proxy->len);
00757 hentity->outbound_proxy->len= subs->outbound_proxy->len;
00758 size+= subs->outbound_proxy->len;
00759 }
00760
00761 if(subs->id.s)
00762 {
00763 CONT_COPY(hentity, hentity->id, subs->id)
00764 }
00765
00766 if(subs->remote_contact.s)
00767 {
00768 CONT_COPY(hentity, hentity->remote_contact, subs->remote_contact)
00769 }
00770
00771 if(subs->extra_headers)
00772 {
00773 hentity->extra_headers= (str*)((char*)hentity+ size);
00774 size+= sizeof(str);
00775 hentity->extra_headers->s= (char*)hentity+ size;
00776 memcpy(hentity->extra_headers->s, subs->extra_headers->s,
00777 subs->extra_headers->len);
00778 hentity->extra_headers->len= subs->extra_headers->len;
00779 size+= subs->extra_headers->len;
00780 }
00781
00782
00783 CONT_COPY(hentity, hentity->to_tag, subs->to_tag)
00784 CONT_COPY(hentity, hentity->from_tag, subs->from_tag)
00785 CONT_COPY(hentity, hentity->call_id, subs->call_id)
00786
00787 if(expires< 0)
00788 hentity->desired_expires= 0;
00789 else
00790 hentity->desired_expires=expires+ (int)time(NULL);
00791
00792 hentity->flag= subs->flag;
00793 hentity->event= subs->event;
00794 hentity->ua_flag= hentity->ua_flag;
00795 hentity->cb_param= subs->cb_param;
00796
00797 LM_DBG("size= %d\n", size);
00798
00799 return hentity;
00800
00801 }
00802
00803 int send_subscribe(subs_info_t* subs)
00804 {
00805 ua_pres_t* presentity= NULL;
00806 str met= {"SUBSCRIBE", 9};
00807 str* str_hdr= NULL;
00808 int ret= 0;
00809 unsigned int hash_code;
00810 ua_pres_t* hentity= NULL, pres;
00811 int expires;
00812 int flag;
00813 int result;
00814
00815 print_subs(subs);
00816
00817 flag= subs->source_flag;
00818 if(subs->source_flag & XMPP_INITIAL_SUBS)
00819 subs->source_flag= XMPP_SUBSCRIBE;
00820
00821 if(subs->expires< 0)
00822 expires= 3600;
00823 else
00824 expires= subs->expires;
00825
00826 str_hdr= subs_build_hdr(subs->contact, expires, subs->event,
00827 subs->extra_headers);
00828 if(str_hdr== NULL || str_hdr->s== NULL)
00829 {
00830 LM_ERR("while building extra headers\n");
00831 return -1;
00832 }
00833
00834 hash_code=core_hash(subs->pres_uri, subs->watcher_uri, HASH_SIZE);
00835
00836 lock_get(&HashT->p_records[hash_code].lock);
00837
00838 memset(&pres, 0, sizeof(ua_pres_t));
00839 pres.pres_uri= subs->pres_uri;
00840 pres.watcher_uri= subs->watcher_uri;
00841 pres.flag= subs->source_flag;
00842 pres.id= subs->id;
00843 pres.event= subs->event;
00844 if(subs->remote_target)
00845 pres.remote_contact= *subs->remote_target;
00846
00847 presentity= search_htable(&pres, hash_code);
00848
00849
00850 if(subs->flag & INSERT_TYPE)
00851 {
00852 LM_DBG("A subscription request with insert type\n");
00853 goto insert;
00854 }
00855
00856 if(presentity== NULL )
00857 {
00858 insert:
00859 lock_release(&HashT->p_records[hash_code].lock);
00860 if(subs->flag & UPDATE_TYPE)
00861 {
00862
00863
00864
00865
00866
00867
00868
00869
00870 LM_DBG("request for a subscription with update type"
00871 " and no record found\n");
00872 subs->flag= INSERT_TYPE;
00873
00874 }
00875 hentity= subscribe_cbparam(subs, REQ_OTHER);
00876 if(hentity== NULL)
00877 {
00878 LM_ERR("while building callback"
00879 " param\n");
00880 ret= -1;
00881 goto done;
00882 }
00883 hentity->flag= flag;
00884
00885 result= tmb.t_request
00886 (&met,
00887 subs->remote_target?subs->remote_target:subs->pres_uri,
00888 subs->pres_uri,
00889 subs->watcher_uri,
00890 str_hdr,
00891 0,
00892 subs->outbound_proxy,
00893 subs_cback_func,
00894 (void*)hentity
00895 );
00896 if(result< 0)
00897 {
00898 LM_ERR("while sending request with t_request\n");
00899 shm_free(hentity);
00900 goto done;
00901 }
00902 }
00903 else
00904 {
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949 dlg_t* td= NULL;
00950 td= pua_build_dlg_t(presentity);
00951 if(td== NULL)
00952 {
00953 LM_ERR("while building tm dlg_t structure");
00954 ret= -1;
00955 lock_release(&HashT->p_records[hash_code].lock);
00956 goto done;
00957 }
00958
00959 hentity= subs_cbparam_indlg(presentity, expires, REQ_OTHER);
00960 if(hentity== NULL)
00961 {
00962 LM_ERR("while building callback param\n");
00963 lock_release(&HashT->p_records[hash_code].lock);
00964 ret= -1;
00965 pkg_free(td);
00966 goto done;
00967 }
00968 lock_release(&HashT->p_records[hash_code].lock);
00969
00970
00971 LM_DBG("event parameter: %d\n", hentity->event);
00972 result= tmb.t_request_within
00973 (&met,
00974 str_hdr,
00975 0,
00976 td,
00977 subs_cback_func,
00978 (void*)hentity
00979 );
00980 if(result< 0)
00981 {
00982 shm_free(hentity);
00983 hentity= NULL;
00984 LM_ERR("while sending request with t_request\n");
00985 goto done;
00986 }
00987
00988 if(td->route_set)
00989 free_rr(&td->route_set);
00990 pkg_free(td);
00991 td= NULL;
00992 }
00993
00994 done:
00995 pkg_free(str_hdr);
00996 return ret;
00997 }