rls/subscribe.c

Go to the documentation of this file.
00001 /*
00002  * $Id: subscribe.c 2230 2007-06-06 07:13:20Z anca_vamanu $
00003  *
00004  * rls module - resource list server
00005  *
00006  * Copyright (C) 2007 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-09-11  initial version (anca)
00027  */
00028 #include <stdlib.h>
00029 #include <stdio.h>
00030 #include <string.h>
00031 #include <time.h>
00032 
00033 #include "../../ut.h"
00034 #include "../../dprint.h"
00035 #include "../../data_lump_rpl.h"
00036 #include "../../cmpapi.h"
00037 #include "../../parser/msg_parser.h"
00038 #include "../../parser/parse_event.h"
00039 #include "../../parser/parse_expires.h"
00040 #include "../../parser/parse_cseq.h"
00041 #include "../../parser/parse_from.h"
00042 #include "../../parser/contact/parse_contact.h"
00043 #include "../../parser/parse_rr.h"
00044 #include "../presence/subscribe.h"
00045 #include "../presence/utils_func.h"
00046 #include "../presence/hash.h"
00047 #include "subscribe.h"
00048 #include "notify.h"
00049 #include "rls.h"
00050 
00051 int counter= 0;
00052 
00053 static str su_200_rpl     = str_init("OK");
00054 static str pu_421_rpl     = str_init("Extension Required");
00055 static str pu_400_rpl     = str_init("Bad request");
00056 static str stale_cseq_rpl = str_init("Stale Cseq Value");
00057 static str pu_489_rpl     = str_init("Bad Event");
00058 
00059 #define Stale_cseq_code 401
00060 
00061 subs_t* constr_new_subs(struct sip_msg* msg, struct to_body *pto, 
00062       pres_ev_t* event);
00063 int resource_subscriptions(subs_t* subs, xmlNodePtr rl_node);
00064 
00065 int update_rlsubs( subs_t* subs,unsigned int hash_code);
00066 
00067 int get_resource_list(str* pres_uri, char** list)
00068 {
00069    db_key_t query_cols[5];
00070    db_val_t query_vals[5];
00071    db_key_t result_cols[3];
00072    int n_query_cols = 0;
00073    db_res_t *result = 0;
00074    db_row_t *row ;   
00075    db_val_t *row_vals ;
00076    str body ;
00077    struct sip_uri uri;
00078    int n_result_cols= 0;
00079    int etag_col, xcap_col;
00080    char* etag= NULL;
00081    xcap_get_req_t req;
00082 
00083    xcap_doc_sel_t doc_sel;
00084    char* rls_list;
00085 
00086    if(parse_uri(pres_uri->s, pres_uri->len, &uri)< 0)
00087    {
00088       LM_ERR("while parsing uri\n");
00089       return -1;
00090    }
00091    /* first search in database */
00092    query_cols[n_query_cols] = &str_username_col;
00093    query_vals[n_query_cols].type = DB_STR;
00094    query_vals[n_query_cols].nul = 0;
00095    query_vals[n_query_cols].val.str_val = uri.user;
00096    n_query_cols++;
00097    
00098    query_cols[n_query_cols] = &str_domain_col;
00099    query_vals[n_query_cols].type = DB_STR;
00100    query_vals[n_query_cols].nul = 0;
00101    query_vals[n_query_cols].val.str_val = uri.host;
00102    n_query_cols++;
00103    
00104    query_cols[n_query_cols] = &str_doc_type_col;
00105    query_vals[n_query_cols].type = DB_INT;
00106    query_vals[n_query_cols].nul = 0;
00107    query_vals[n_query_cols].val.int_val= RESOURCE_LIST;
00108    n_query_cols++;
00109 
00110    if (rls_dbf.use_table(rls_db, &rls_xcap_table) < 0)
00111    {
00112       LM_ERR("in use_table-[table]= %.*s\n", rls_xcap_table.len, rls_xcap_table.s);
00113       return -1;
00114    }
00115 
00116    result_cols[xcap_col= n_result_cols++] = &str_doc_col;
00117    result_cols[etag_col= n_result_cols++]= &str_etag_col;
00118 
00119    if(rls_dbf.query(rls_db, query_cols, 0 , query_vals, result_cols,
00120             n_query_cols, n_result_cols, 0, &result)<0)
00121    {
00122       LM_ERR("while querying table xcap for [uri]=%.*s\n",
00123             pres_uri->len, pres_uri->s);
00124       if(result)
00125          rls_dbf.free_result(rls_db, result);
00126       return -1;
00127    }
00128 
00129    if(result->n<= 0)
00130    {
00131       LM_DBG("No xcap document for [uri]=%.*s\n",pres_uri->len,pres_uri->s);
00132       
00133       if(rls_integrated_xcap_server)
00134       {
00135          rls_dbf.free_result(rls_db, result);
00136          *list= 0;
00137          return 0;      
00138       }
00139       
00140       /* make an initial request to xcap_client module */
00141       doc_sel.auid.s= "resource-lists";
00142       doc_sel.auid.len= strlen("resource-lists");
00143       doc_sel.doc_type= RESOURCE_LIST;
00144       doc_sel.type= USERS_TYPE;
00145       doc_sel.xid= *pres_uri;
00146       doc_sel.filename.s= "index";
00147       doc_sel.filename.len= 5;
00148 
00149       memset(&req, 0, sizeof(xcap_get_req_t));
00150       req.xcap_root= xcap_root;
00151       req.port= xcap_port;
00152       req.doc_sel= doc_sel;
00153       req.etag= etag;
00154       req.match_type= IF_NONE_MATCH;
00155 
00156       rls_list= xcap_GetNewDoc(req, uri.user, uri.host);
00157       if(rls_list== NULL)
00158       {
00159          LM_ERR("while fetching data from xcap server\n");
00160          goto error; 
00161       }
00162       
00163       *list= rls_list;
00164       return 0;      
00165    }
00166 
00167    row = &result->rows[0];
00168    row_vals = ROW_VALUES(row);
00169 
00170    body.s = (char*)row_vals[xcap_col].val.string_val;
00171    if(body.s== NULL)
00172    {
00173       LM_ERR("Xcap doc NULL\n");
00174       goto error;
00175    }  
00176    body.len = strlen(body.s);
00177    if(body.len== 0)
00178    {
00179       LM_ERR("Xcap doc empty\n");
00180       goto error;
00181    }        
00182    LM_DBG("xcap body:\n%.*s", body.len,body.s);
00183    rls_list= (char*)pkg_malloc((body.len+ 1)* sizeof(char));
00184    if(rls_list== NULL)
00185    {
00186       rls_dbf.free_result(rls_db, result);
00187       ERR_MEM(PKG_MEM_STR);
00188    }
00189    memcpy(rls_list, body.s, body.len);
00190    rls_list[body.len]= '\0';
00191    rls_dbf.free_result(rls_db, result);
00192    *list= rls_list;
00193 
00194    return 0;
00195 
00196 error:
00197    if(result)
00198       rls_dbf.free_result(rls_db, result);
00199    return -1;
00200 
00201 }
00202 
00203 
00204 int reply_421(struct sip_msg* msg)
00205 {
00206    str hdr_append;
00207    char buffer[256];
00208    
00209    hdr_append.s = buffer;
00210    hdr_append.s[0]='\0';
00211    hdr_append.len = sprintf(hdr_append.s, "Require: eventlist\r\n");
00212    if(hdr_append.len < 0)
00213    {
00214       LM_ERR("unsuccessful sprintf\n");
00215       return -1;
00216    }
00217    hdr_append.s[hdr_append.len]= '\0';
00218 
00219    if (add_lump_rpl( msg, hdr_append.s, hdr_append.len, LUMP_RPL_HDR)==0 )
00220    {
00221       LM_ERR("unable to add lump_rl\n");
00222       return -1;
00223    }
00224 
00225    if (slb.send_reply(msg, 421, &pu_421_rpl) == -1)
00226    {
00227       LM_ERR("while sending reply\n");
00228       return -1;
00229    }
00230    return 0;
00231 
00232 }
00233 
00234 int reply_200(struct sip_msg* msg, str* contact, int expires)
00235 {
00236    str hdr_append;
00237    int len;
00238    
00239    hdr_append.s = (char *)pkg_malloc( sizeof(char)*(contact->len+ 70));
00240    if(hdr_append.s == NULL)
00241    {
00242       LM_ERR("no more pkg memory\n");
00243       return -1;
00244    }
00245    hdr_append.len = sprintf(hdr_append.s, "Expires: %d\r\n", expires);  
00246    if(hdr_append.len< 0)
00247    {
00248       LM_ERR("unsuccessful sprintf\n");
00249       goto error;
00250    }
00251    strncpy(hdr_append.s+hdr_append.len ,"Contact: <", 10);
00252    hdr_append.len += 10;
00253    strncpy(hdr_append.s+hdr_append.len, contact->s, contact->len);
00254    hdr_append.len+= contact->len;
00255    strncpy(hdr_append.s+hdr_append.len, ">", 1);
00256    hdr_append.len += 1;
00257    strncpy(hdr_append.s+hdr_append.len, CRLF, CRLF_LEN);
00258    hdr_append.len += CRLF_LEN;
00259 
00260    len = sprintf(hdr_append.s+ hdr_append.len, "Require: eventlist\r\n");
00261    if(len < 0)
00262    {
00263       LM_ERR("unsuccessful sprintf\n");
00264       goto error;
00265    }
00266    hdr_append.len+= len;
00267    hdr_append.s[hdr_append.len]= '\0';
00268    
00269    if (add_lump_rpl( msg, hdr_append.s, hdr_append.len, LUMP_RPL_HDR)==0 )
00270    {
00271       LM_ERR("unable to add lump_rl\n");
00272       goto error;
00273    }
00274 
00275    if(slb.send_reply(msg, 200, &su_200_rpl)== -1)
00276    {
00277       LM_ERR("while sending reply\n");
00278       goto error;
00279    }  
00280    pkg_free(hdr_append.s);
00281    return 0;
00282 
00283 error:
00284    pkg_free(hdr_append.s);
00285    return -1;
00286 }  
00287 
00288 int reply_489(struct sip_msg * msg)
00289 {
00290    str hdr_append;
00291    char buffer[256];
00292    str* ev_list;
00293 
00294    hdr_append.s = buffer;
00295    hdr_append.s[0]='\0';
00296    hdr_append.len = sprintf(hdr_append.s, "Allow-Events: ");
00297    if(hdr_append.len < 0)
00298    {
00299       LM_ERR("unsuccessful sprintf\n");
00300       return -1;
00301    }
00302 
00303    if(pres_get_ev_list(&ev_list)< 0)
00304    {
00305       LM_ERR("while getting ev_list\n");
00306       return -1;
00307    }  
00308    memcpy(hdr_append.s+ hdr_append.len, ev_list->s, ev_list->len);
00309    hdr_append.len+= ev_list->len;
00310    pkg_free(ev_list->s);
00311    pkg_free(ev_list);
00312    memcpy(hdr_append.s+ hdr_append.len, CRLF, CRLF_LEN);
00313    hdr_append.len+=  CRLF_LEN;
00314    hdr_append.s[hdr_append.len]= '\0';
00315       
00316    if (add_lump_rpl( msg, hdr_append.s, hdr_append.len, LUMP_RPL_HDR)==0 )
00317    {
00318       LM_ERR("unable to add lump_rl\n");
00319       return -1;
00320    }
00321    if (slb.send_reply(msg, 489, &pu_489_rpl) == -1)
00322    {
00323       LM_ERR("while sending reply\n");
00324       return -1;
00325    }
00326    return 0;
00327 }
00328    
00329 
00330 int rls_handle_subscribe(struct sip_msg* msg, char* s1, char* s2)
00331 {
00332    struct to_body *pto, *pfrom = NULL, TO;
00333    int found= 0;
00334    struct hdr_field* hdr;
00335    subs_t subs;
00336    str resource_list= {0, 0};
00337    int i, len= 0;
00338    pres_ev_t* event= NULL;
00339    int err_ret= -1;
00340    str* contact= NULL;
00341    xmlDocPtr doc= NULL;
00342    xmlNodePtr rl_node= NULL;
00343    unsigned int hash_code;
00344    int to_tag_gen= 0;
00345    event_t* parsed_event;
00346    param_t* ev_param= NULL;
00347 
00348 /*** filter: 'For me or for presence server?' */   
00349 
00350    memset(&subs, 0, sizeof(subs_t));
00351 
00352    if ( parse_headers(msg,HDR_EOH_F, 0)==-1 )
00353    {
00354       LM_ERR("parsing headers\n");
00355       if (slb.send_reply(msg, 400, &pu_400_rpl) == -1)
00356       {
00357          LM_ERR("while sending 400 reply\n");
00358          return -1;
00359       }
00360       return 0;
00361    }
00362 
00363    /* inspecting the Event header field */
00364    if(msg->event && msg->event->body.len > 0)
00365    {
00366       if (!msg->event->parsed && (parse_event(msg->event) < 0))
00367       {
00368          LM_ERR("cannot parse Event header\n");
00369          goto error;
00370       }
00371       if(! ( ((event_t*)msg->event->parsed)->parsed & rls_events) )
00372       {  
00373          return to_presence_code;
00374       }
00375    }
00376    else
00377       goto bad_event;
00378 
00379    /* search event in the list */
00380    parsed_event= (event_t*)msg->event->parsed;
00381    event= pres_search_event(parsed_event);
00382    if(event== NULL)
00383    {
00384       goto bad_event;
00385    }
00386    subs.event= event;
00387    
00388    /* extract the id if any*/
00389    ev_param= parsed_event->params;
00390    while(ev_param)
00391    {
00392       if(ev_param->name.len== 2 && strncmp(ev_param->name.s, "id", 2)== 0)
00393       {
00394          subs.event_id= ev_param->body;
00395          break;
00396       }
00397       ev_param= ev_param->next;
00398    }     
00399 
00400 
00401    if(msg->to->parsed != NULL)
00402    {
00403       pto = (struct to_body*)msg->to->parsed;
00404       LM_DBG("'To' header ALREADY PARSED: <%.*s>\n",pto->uri.len,pto->uri.s);
00405    }
00406    else
00407    {
00408       memset( &TO , 0, sizeof(TO) );
00409       if( !parse_to(msg->to->body.s,msg->to->body.s+msg->to->body.len+1,&TO));
00410       {
00411          LM_DBG("'To' header NOT parsed\n");
00412          goto error;
00413       }
00414       pto = &TO;
00415    }
00416 
00417    if(pto->tag_value.s== NULL || pto->tag_value.len==0)
00418       /* if an initial Subscribe */
00419    {
00420       /*verify if Request URI represents a list by asking xcap server*/ 
00421       if(uandd_to_uri(msg->parsed_uri.user, msg->parsed_uri.host,
00422                &subs.pres_uri)< 0)
00423       {
00424          LM_ERR("while constructing uri from user and domain\n");
00425          goto error;
00426       }
00427       if( get_resource_list(&subs.pres_uri, &resource_list.s)< 0)
00428       {
00429          LM_ERR("while attepmting to get a resource list\n");
00430          goto error;
00431       }
00432       if( resource_list.s== NULL )    
00433       {
00434          /* if not a resource list subscribe , return  to_presence_code
00435           * so that presence will handle the subscription*/
00436          return to_presence_code; 
00437       }
00438       resource_list.len= strlen(resource_list.s);
00439 
00440    }
00441    else
00442    {
00443       if( msg->callid==NULL || msg->callid->body.s==NULL)
00444       {
00445          LM_ERR("cannot parse callid header\n");
00446          goto error;
00447       }
00448       if (msg->from->parsed == NULL)
00449       {
00450          LM_DBG("'From' header not parsed\n");
00451          /* parsing from header */
00452          if ( parse_from_header( msg )<0 ) 
00453          {
00454             LM_DBG("ERROR cannot parse From header\n");
00455             goto error;
00456          }
00457       }
00458       pfrom = (struct to_body*)msg->from->parsed;
00459       if( pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0)
00460       {
00461          LM_ERR("no from tag value present\n");
00462          goto error;
00463       }
00464 
00465       /* search if a stored dialog */
00466       hash_code= core_hash(&msg->callid->body, &pto->tag_value, hash_size);
00467       lock_get(&rls_table[hash_code].lock);
00468 
00469       if(pres_search_shtable(rls_table,msg->callid->body,
00470                pto->tag_value,   pfrom->tag_value, hash_code)== NULL)
00471       {
00472          lock_release(&rls_table[hash_code].lock);
00473          return to_presence_code;   
00474       }
00475       lock_release(&rls_table[hash_code].lock);
00476    }
00477 
00478 /*** verify if it contains the 'Support: eventlist' header
00479  * and if not - reply with '421 (Extension Required)' */
00480 
00481 /*
00482    hdr = msg->supported;
00483    if(hdr== NULL || hdr->body.s== 0 || hdr->body.len== 0)
00484    {
00485       LM_DBG("msg->supported header NULL\n");
00486       goto found_support;
00487    }
00488 */
00489    hdr= msg->headers;
00490    while(hdr)
00491    {
00492       if(cmp_hdrname_strzn(&hdr->name, "Support", 7)== 0)
00493          break;
00494       hdr= hdr->next;
00495    }
00496    while(hdr!= NULL )
00497    {
00498       len= hdr->body.len- 8;
00499       for(i= 0; i< len; i++)
00500       {  
00501          if(strncmp(hdr->body.s+ i, "eventlist", 9)== 0)
00502          {
00503             found= 1;
00504             goto found_support;
00505          }
00506       }
00507       hdr= hdr->sibling;
00508    }
00509 
00510 found_support: 
00511    if(found== 0)  
00512    {
00513       LM_ERR("No 'Support: eventlist' header found\n");
00514       if(reply_421(msg)< 0)
00515          return -1;
00516       return 0;
00517    }
00518 /*** examine the event header */
00519 
00520    /* extract dialog information from message headers */
00521    if(pres_extract_sdialog_info(&subs, msg, rls_max_expires,
00522             &to_tag_gen, server_address)< 0)
00523    {
00524       LM_ERR("bad Subscribe request\n");
00525       goto error;
00526    }
00527 
00528    hash_code= core_hash(&subs.callid, &subs.to_tag, hash_size);
00529 
00530    if(pto->tag_value.s== NULL || pto->tag_value.len==0) 
00531       /* if an initial subscribe */
00532    {
00533       subs.local_cseq= 0;
00534 
00535       if(subs.expires!= 0)
00536       {
00537          subs.version= 1;
00538          if(pres_insert_shtable(rls_table, hash_code, &subs)< 0)
00539          {
00540             LM_ERR("while adding new subscription\n");
00541             goto error;
00542          }
00543       }
00544    }
00545    else
00546    {
00547       str reason;
00548       int rt;
00549 
00550       rt= update_rlsubs(&subs, hash_code);
00551       if(rt< 0)
00552       {
00553          LM_ERR("while updating resource list subscription\n");
00554          goto error;
00555       }
00556    
00557       if(rt>= 400)
00558       {
00559          reason= (rt==400)?pu_400_rpl:stale_cseq_rpl;
00560       
00561          if (slb.send_reply(msg, 400, &reason) == -1)
00562          {
00563             LM_ERR("while sending reply\n");
00564             goto error;
00565          }
00566          return 0;
00567       }  
00568 
00569       if(get_resource_list(&subs.pres_uri, &resource_list.s)< 0)
00570       {
00571          LM_ERR("when getting resource list\n");
00572          goto error;
00573       }
00574       resource_list.len= strlen(resource_list.s);
00575    }
00576    
00577    doc= xmlParseMemory(resource_list.s, resource_list.len);
00578    if(doc== NULL)
00579    {
00580       LM_ERR("while parsing XML memory\n");
00581       goto error;
00582    }
00583    rl_node= XMLDocGetNodeByName(doc, "resource-lists", NULL);
00584    if(rl_node== NULL)
00585    {
00586       LM_ERR("while extracting resource-lists node\n");
00587       goto error;
00588    }
00589 
00590 /*** send Subscribe requests for all in the list */
00591    
00592    if(resource_subscriptions(&subs, rl_node)< 0)
00593    {
00594       LM_ERR("while sending Subscribe requests to resources in a list\n");
00595       goto error;
00596    }
00597 
00598 /*** if correct reply with 200 OK*/
00599    if(reply_200(msg, &subs.contact, subs.expires)< 0)
00600       goto error;
00601 
00602    /* call sending Notify with full state */
00603    if(send_full_notify(&subs,rl_node,subs.version,&subs.pres_uri,hash_code)< 0)
00604    {
00605       LM_ERR("while sending full state Notify\n");
00606       goto error;
00607    }
00608    if(contact)
00609    {  
00610       if(contact->s)
00611          pkg_free(contact->s);
00612       pkg_free(contact);
00613    }
00614       
00615    pkg_free(resource_list.s);
00616    pkg_free(subs.pres_uri.s);
00617 
00618    if(subs.record_route.s)
00619       pkg_free(subs.record_route.s);
00620    xmlFreeDoc(doc);
00621    return 1;
00622 
00623 bad_event:
00624    if(reply_489(msg)< 0)
00625    {
00626       LM_ERR("while sending 489 reply\n");
00627       err_ret= -1;
00628    }
00629    err_ret= 0;
00630 
00631 error:
00632    LM_ERR("occured in rls_handle_subscribe\n");
00633 
00634    if(contact)
00635    {  
00636       if(contact->s)
00637          pkg_free(contact->s);
00638       pkg_free(contact);
00639    }
00640    if(subs.pres_uri.s)
00641       pkg_free(subs.pres_uri.s);
00642       
00643    if(subs.record_route.s)
00644          pkg_free(subs.record_route.s);   
00645    
00646    if(doc)
00647       xmlFreeDoc(doc);
00648    if(resource_list.s)
00649       pkg_free(resource_list.s);
00650    return err_ret;
00651 }
00652 
00653 int update_rlsubs( subs_t* subs, unsigned int hash_code)
00654 {
00655    subs_t* s, *ps;
00656 
00657    /* search the record in hash table */
00658    lock_get(&rls_table[hash_code].lock);
00659 
00660    s= pres_search_shtable(rls_table, subs->callid,
00661          subs->to_tag, subs->from_tag, hash_code);
00662    if(s== NULL)
00663    {
00664       LM_DBG("record not found in hash table\n");
00665       lock_release(&rls_table[hash_code].lock);
00666       return -1;
00667    }
00668 
00669    s->expires= subs->expires+ (int)time(NULL);
00670    s->remote_cseq= subs->remote_cseq;
00671    
00672    if(s->db_flag & NO_UPDATEDB_FLAG)
00673       s->db_flag= UPDATEDB_FLAG;
00674    
00675    if(   s->remote_cseq>= subs->remote_cseq)
00676    {
00677       lock_release(&rls_table[hash_code].lock);
00678       LM_DBG("stored cseq= %d\n", s->remote_cseq);
00679       return Stale_cseq_code;
00680    }
00681 
00682    subs->pres_uri.s= (char*)pkg_malloc(s->pres_uri.len* sizeof(char));
00683    if(subs->pres_uri.s== NULL)
00684    {
00685       ERR_MEM(PKG_MEM_STR);
00686    }
00687    memcpy(subs->pres_uri.s, s->pres_uri.s, s->pres_uri.len);
00688    subs->pres_uri.len= s->pres_uri.len;
00689 
00690    if(subs->expires== 0)
00691    {
00692       /* delete record from hash table */
00693       ps= rls_table[hash_code].entries;
00694       int found= 0;
00695       while(ps->next)
00696       {
00697          if(ps->next== s)
00698          {
00699             found= 1;
00700             break;
00701          }
00702          ps= ps->next;
00703       }
00704       if(found== 0)
00705       {
00706          LM_ERR("record not found\n");
00707          goto error;
00708       }
00709       ps->next= s->next;
00710       shm_free(s);
00711    }
00712    else
00713    {
00714       s->remote_cseq= subs->remote_cseq;
00715       s->expires= subs->expires+ (int)time(NULL);
00716    }
00717    
00718    subs->local_cseq= s->local_cseq;
00719    subs->version= s->version;
00720 
00721    lock_release(&rls_table[hash_code].lock);
00722 
00723    return 0;
00724 
00725 error:
00726    lock_release(&rls_table[hash_code].lock);
00727    return -1;
00728 }
00729 
00730 int send_resource_subs(char* uri, void* param)
00731 {
00732    str pres_uri;
00733 
00734    pres_uri.s= uri;
00735    pres_uri.len= strlen(uri);
00736 
00737    ((subs_info_t*)param)->pres_uri= &pres_uri;
00738 
00739    return pua_send_subscribe((subs_info_t*)param);
00740 }
00741 
00742 int resource_subscriptions(subs_t* subs, xmlNodePtr rl_node)
00743 {
00744    char* uri= NULL;
00745    subs_info_t s;
00746    str wuri= {0, 0};
00747    static char buf[64];
00748    str extra_headers;
00749    str did_str= {0, 0};
00750       
00751    /* if is initial send an initial Subscribe 
00752     * else search in hash table for a previous subscription */
00753 
00754    CONSTR_RLSUBS_DID(subs, &did_str);
00755    
00756    memset(&s, 0, sizeof(subs_info_t));
00757 
00758    if( uandd_to_uri(subs->from_user, subs->from_domain, &wuri)< 0)
00759    {
00760       LM_ERR("while constructing uri from user and domain\n");
00761       goto error;
00762    }
00763    s.id= did_str;
00764    s.watcher_uri= &wuri;
00765    s.contact= &subs->local_contact;
00766    s.event= get_event_flag(&subs->event->name);
00767    if(s.event< 0)
00768    {
00769       LM_ERR("not recognized event\n");
00770       goto error;
00771    }
00772    s.expires= subs->expires;
00773    s.source_flag= RLS_SUBSCRIBE;
00774    extra_headers.s= buf;
00775    extra_headers.len= sprintf(extra_headers.s,
00776          "Max-Forwards: 70\r\nSupport: eventlist\r\n");
00777    s.extra_headers= &extra_headers;
00778    
00779    if(process_list_and_exec(rl_node, send_resource_subs,(void*)(&s))< 0)
00780    {
00781       LM_ERR("while processing list\n");
00782       goto error;
00783    }
00784 
00785    pkg_free(wuri.s);
00786    pkg_free(did_str.s);
00787 
00788    return 0;
00789 
00790 error:
00791    if(wuri.s)
00792       pkg_free(wuri.s);
00793    if(uri)
00794       xmlFree(uri);
00795    if(did_str.s)
00796       pkg_free(did_str.s);
00797    return -1;
00798 
00799 }
00800 

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