send_subscribe.c

Go to the documentation of this file.
00001 /*
00002  * $Id: send_subscribe.c 5643 2009-02-27 19:40:42Z miconda $
00003  *
00004  * pua module - presence user agent 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 
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    /* get dialog information from reply message: callid, to_tag, from_tag */
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       /* delete record from hash_table and call registered functions */
00250 
00251       if(hentity->call_id.s== NULL) /* if a new requets failed-> do nothing*/
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    /*if initial request */
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    /* extract the other necesary information for inserting a new record */    
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    {  /* if an error code and a stored dialog delete it and try to send 
00366          a subscription with type= INSERT_TYPE, else return*/  
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    /*if a 2XX reply handle the two cases- an existing dialog and a new one*/
00413    
00414    /* extract the contact */
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    /* if a new dialog -> insert */
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    /*process record route and add it to a string*/
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    /* write the remote contact filed */
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    /* copy dialog information */
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    /* if flag == INSERT_TYPE insert no matter what the search result is */
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          LM_ERR("request for a subscription"
00864                " with update type and no record found\n");
00865          ret= -1;
00866          goto done;
00867          commented this because of the strange type parameter in usrloc callback functions
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,                    /* Type of the message */
00887       subs->remote_target?subs->remote_target:subs->pres_uri,/* Request-URI*/
00888          subs->pres_uri,              /* To */
00889          subs->watcher_uri,           /* From */
00890          str_hdr,               /* Optional headers including CRLF */
00891          0,                     /* Message body */
00892          subs->outbound_proxy,        /* Outbound_proxy */  
00893          subs_cback_func,           /* Callback function */
00894          (void*)hentity             /* Callback parameter */
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       if(presentity->desired_expires== 0)
00907       {
00908             
00909          if(subs->expires< 0)
00910          {
00911              LM_DBG("Found previous request for unlimited subscribe-"
00912                   " do not send subscribe\n");
00913             
00914             if (subs->event & PWINFO_EVENT)
00915             {  
00916                presentity->watcher_count++;
00917             }
00918             lock_release(&HashT->p_records[hash_code].lock);
00919              goto done;
00920             
00921          }
00922         
00923       
00924          if(subs->event & PWINFO_EVENT)
00925          {  
00926             if(subs->expires== 0)
00927             {
00928                presentity->watcher_count--;
00929                if(   presentity->watcher_count> 0)
00930                {
00931                   lock_release(&HashT->p_records[hash_code].lock);
00932                   goto done;
00933                }
00934             }
00935             else
00936             {
00937                presentity->watcher_count++;
00938                if(presentity->watcher_count> 1)
00939                {
00940                   lock_release(&HashT->p_records[hash_code].lock);
00941                   goto done;
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    // hentity->flag= flag;
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 }

Generated on Thu May 24 12:00:30 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6