rls/notify.c

Go to the documentation of this file.
00001 /*
00002  * $Id: notify.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 
00029 #include <stdlib.h>
00030 #include <stdio.h>
00031 #include <string.h>
00032 #include <time.h>
00033 
00034 #include "../../ut.h"
00035 #include "../../str.h"
00036 #include "../../dprint.h"
00037 #include "../../data_lump_rpl.h"
00038 #include "../../parser/msg_parser.h"
00039 #include "../../parser/parse_event.h"
00040 #include "../../parser/parse_expires.h"
00041 #include "../../parser/parse_cseq.h"
00042 #include "../../parser/contact/parse_contact.h"
00043 #include "../../parser/parse_rr.h"
00044 #include "../tm/dlg.h"
00045 #include "../presence/utils_func.h"
00046 #include "../presence/hash.h"
00047 #include "rls.h"
00048 #include "notify.h"
00049 
00050 typedef struct res_param
00051 {
00052    xmlNodePtr list_node;
00053    db_res_t* db_result;
00054    char** cid_array;
00055 }res_param_t;
00056 
00057 int resource_uri_col=0, content_type_col, pres_state_col= 0,
00058    auth_state_col= 0, reason_col= 0;
00059 
00060 str* constr_rlmi_doc(db_res_t* result, str* rl_uri, int version,
00061       xmlNodePtr rl_node, char*** cid_array);
00062 str* constr_multipart_body(db_res_t* result,char** cid_array,
00063       char* boundary_string);
00064 
00065 dlg_t* rls_notify_dlg(subs_t* subs);
00066 
00067 void rls_notify_callback( struct cell *t, int type, struct tmcb_params *ps);
00068 
00069 
00070 int send_full_notify(subs_t* subs, xmlNodePtr rl_node, int version, str* rl_uri,
00071       unsigned int hash_code)
00072 {
00073    str* rlmi_body= NULL;
00074    str* multipart_body= NULL;
00075    db_key_t query_cols[2], update_cols[2], result_cols[7];
00076    db_val_t query_vals[2], update_vals[2];
00077    db_res_t *result= NULL;
00078    int n_result_cols= 0, i;
00079    char* boundary_string;
00080    char** cid_array= NULL;
00081    str rlsubs_did= {0, 0};
00082 
00083    LM_DBG("start\n");
00084    /* query in alfabetical order */
00085    
00086    CONSTR_RLSUBS_DID(subs, &rlsubs_did);
00087 
00088    query_cols[0]= &str_rlsubs_did_col;
00089    query_vals[0].type = DB_STR;
00090    query_vals[0].nul = 0;
00091    query_vals[0].val.str_val= rlsubs_did; 
00092 
00093    result_cols[resource_uri_col= n_result_cols++]= &str_resource_uri_col;
00094    result_cols[content_type_col= n_result_cols++]= &str_content_type_col;
00095    result_cols[pres_state_col= n_result_cols++]= &str_presence_state_col;
00096    result_cols[auth_state_col= n_result_cols++]= &str_auth_state_col;
00097    result_cols[reason_col= n_result_cols++]= &str_reason_col;
00098    
00099    if (rls_dbf.use_table(rls_db, &rlpres_table) < 0) 
00100    {
00101       LM_ERR("in use_table\n");
00102       goto error;
00103    }
00104 
00105    if(rls_dbf.query(rls_db, query_cols, 0, query_vals, result_cols,
00106                1, n_result_cols, &str_resource_uri_col, &result )< 0)
00107    {
00108       LM_ERR("in sql query\n");
00109       goto error;
00110    }
00111    if(result== NULL)
00112       goto error;
00113 
00114    rlmi_body= constr_rlmi_doc(result, rl_uri, version, rl_node, &cid_array);
00115    if(rlmi_body== NULL)
00116    {
00117       LM_ERR("while constructing rlmi doc\n");
00118       goto error;
00119    }
00120 
00121    boundary_string= generate_string((int)time(NULL), BOUNDARY_STRING_LEN);
00122    
00123    if(result->n> 0)
00124    {
00125       multipart_body= constr_multipart_body(result, cid_array, 
00126             boundary_string);
00127       if(multipart_body== NULL)
00128       {
00129          LM_ERR("while constructing multipart body\n");
00130          goto error;
00131       }
00132       for(i = 0; i<result->n; i++)
00133       {
00134          if(cid_array[i])
00135             pkg_free(cid_array[i]);
00136       }
00137    }
00138    pkg_free(cid_array);
00139    cid_array= NULL;
00140    rls_dbf.free_result(rls_db, result);
00141    result= NULL;
00142 
00143    if(agg_body_sendn_update(rl_uri, boundary_string, rlmi_body,
00144       multipart_body, subs, hash_code)< 0)
00145    {
00146       LM_ERR("in function agg_body_sendn_update\n");
00147       goto error;
00148    }
00149 
00150    /* update updated col in rlpres_table*/
00151    update_cols[0]= &str_updated_col;
00152    update_vals[0].type = DB_INT;
00153    update_vals[0].nul = 0;
00154    update_vals[0].val.int_val= NO_UPDATE_TYPE; 
00155    
00156    if (rls_dbf.use_table(rls_db, &rlpres_table) < 0) 
00157    {
00158       LM_ERR("in use_table\n");
00159       goto error;
00160    }
00161    if(rls_dbf.update(rls_db, query_cols, 0, query_vals, update_cols,
00162                update_vals, 1, 1)< 0)
00163    {
00164       LM_ERR("in sql update\n");
00165       goto error;
00166    }
00167 
00168    xmlFree(rlmi_body->s);
00169    pkg_free(rlmi_body);
00170 
00171    if(multipart_body)         
00172    {
00173       pkg_free(multipart_body->s);
00174       pkg_free(multipart_body);
00175    }
00176    pkg_free(rlsubs_did.s);
00177 
00178    return 0;
00179 error:
00180 
00181    if(rlmi_body)
00182    {
00183       if(rlmi_body->s)
00184          xmlFree(rlmi_body->s);
00185       pkg_free(rlmi_body);
00186    }
00187    if(multipart_body)
00188    {
00189       if(multipart_body->s)
00190          pkg_free(multipart_body->s);
00191       pkg_free(multipart_body);
00192    }
00193    
00194    if(cid_array)
00195    {
00196       for(i= 0; i< result->n ; i++)
00197          if(cid_array[i])
00198             pkg_free(cid_array[i]);
00199       pkg_free(cid_array);
00200    }
00201    if(result)
00202       rls_dbf.free_result(rls_db, result);
00203    if(rlsubs_did.s)
00204       pkg_free(rlsubs_did.s);
00205    return -1;
00206 }
00207 
00208 int agg_body_sendn_update(str* rl_uri, char* boundary_string, str* rlmi_body,
00209       str* multipart_body, subs_t* subs, unsigned int hash_code)
00210 {
00211    char* cid;
00212    int len;
00213    str body= {0, 0};
00214    int init_len;
00215 
00216    cid= generate_cid(rl_uri->s, rl_uri->len);
00217 
00218    len= 2*strlen(boundary_string)+ 4+ 102+ strlen(cid)+ 2+ rlmi_body->len+50;
00219    if(multipart_body)
00220       len+= multipart_body->len;
00221    
00222    init_len= len;
00223 
00224    body.s= (char*)pkg_malloc(len* sizeof(char));
00225    if(body.s== NULL)
00226    {
00227       ERR_MEM(PKG_MEM_STR);
00228    }
00229    len=  sprintf(body.s, "--%s\r\n", boundary_string);
00230    len+= sprintf(body.s+ len , "Content-Transfer-Encoding: binary\r\n");
00231    len+= sprintf(body.s+ len , "Content-ID: <%s>\r\n", cid);   
00232    len+= sprintf(body.s+ len , 
00233          "Content-Type: application/rlmi+xml;charset=\"UTF-8r\"\r\n");
00234    len+= sprintf(body.s+ len, "\r\n"); /*blank line*/
00235    memcpy(body.s+ len, rlmi_body->s, rlmi_body->len);
00236    len+= rlmi_body->len;
00237    len+= sprintf(body.s+ len, "\r\n"); /*blank line*/
00238 
00239    if(multipart_body)
00240    {
00241       memcpy(body.s+ len, multipart_body->s, multipart_body->len);
00242       len+= multipart_body->len;
00243    }
00244    len+= sprintf(body.s+ len, "--%s--\r\n", boundary_string);
00245 
00246    if(init_len< len)
00247    {
00248       LM_ERR("buffer size overflow init_size= %d\tlen= %d\n",init_len,len);
00249       goto error;
00250    }
00251    body.s[len]= '\0';
00252    body.len= len;
00253 
00254    /* send Notify */
00255    if(rls_send_notify(subs, &body, cid, boundary_string)< 0)
00256    {
00257       LM_ERR("when sending Notify\n");
00258       goto error;
00259    }
00260    /* update local_cseq in cache list watchers table */
00261    pkg_free(body.s);
00262    body.s= NULL;
00263 
00264    if(pres_update_shtable(rls_table, hash_code,subs, LOCAL_TYPE)< 0)
00265    {
00266       LM_ERR("updating in hash table\n");
00267       goto error;
00268    }
00269    return 0;
00270 
00271 error:
00272    if(body.s)
00273       pkg_free(body.s);
00274 
00275    return -1;
00276 }
00277 
00278 
00279 int add_resource_instance(char* uri, xmlNodePtr resource_node,
00280       db_res_t* result, char** cid_array)
00281 {
00282    xmlNodePtr instance_node= NULL;
00283    db_row_t *row; 
00284    db_val_t *row_vals;
00285    int i, cmp_code;
00286    char* auth_state= NULL;
00287    int contor= 0;
00288    str cid;
00289    int auth_state_flag;
00290 
00291    for(i= 0; i< result->n; i++)
00292    {
00293       row = &result->rows[i];
00294       row_vals = ROW_VALUES(row);
00295       
00296       cmp_code= strncmp(row_vals[resource_uri_col].val.string_val, uri,
00297             strlen(uri));
00298       if(cmp_code> 0)
00299          break;
00300 
00301       if(cmp_code== 0)
00302       {
00303          contor++;
00304          instance_node= xmlNewChild(resource_node, NULL, 
00305                BAD_CAST "instance", NULL);
00306          if(instance_node== NULL)
00307          {
00308             LM_ERR("while adding instance child\n");
00309             goto error;
00310          }
00311       
00312          xmlNewProp(instance_node, BAD_CAST "id",
00313                BAD_CAST generate_string(contor, 8));
00314          auth_state_flag= row_vals[auth_state_col].val.int_val;
00315          auth_state= get_auth_string(auth_state_flag );
00316          if(auth_state== NULL)
00317          {
00318             LM_ERR("bad authorization status flag\n");
00319             goto error;
00320          }
00321          xmlNewProp(instance_node, BAD_CAST "state", BAD_CAST auth_state);
00322 
00323          if(auth_state_flag & ACTIVE_STATE)
00324          {
00325             cid.s= generate_cid(uri, strlen(uri));
00326             cid.len= strlen(cid.s);
00327 
00328             cid_array[i]= (char*)pkg_malloc((1+ cid.len)*sizeof(char));
00329             if(cid_array[i]== NULL)
00330             {
00331                ERR_MEM(PKG_MEM_STR);
00332             }  
00333             memcpy(cid_array[i], cid.s, cid.len);
00334             cid_array[i][cid.len]= '\0';
00335 
00336             xmlNewProp(instance_node, BAD_CAST "cid", BAD_CAST cid.s);
00337          }
00338          else
00339          if(auth_state_flag & TERMINATED_STATE)
00340          {
00341             xmlNewProp(instance_node, BAD_CAST "reason", 
00342                   BAD_CAST row_vals[reason_col].val.string_val);  
00343          }
00344       }
00345    }
00346 
00347    /* if record not found should not add a instance node */ 
00348    return 0;
00349 error:
00350    return -1;
00351 }
00352 
00353 int add_resource(char* uri, void* param)
00354 {
00355    char** cid_array= ((res_param_t*)param)->cid_array;
00356    xmlNodePtr list_node= ((res_param_t*)param)->list_node;
00357    xmlNodePtr resource_node= NULL;
00358    db_res_t *result= ((res_param_t*)param)->db_result;
00359 
00360    LM_DBG("uri= %s\n", uri);
00361    resource_node= xmlNewChild(list_node, NULL, BAD_CAST "resource", NULL);
00362    if(resource_node== NULL)
00363    {
00364       LM_ERR("while adding new rsource_node\n");
00365       goto error;
00366    }
00367    xmlNewProp(resource_node, BAD_CAST "uri", BAD_CAST uri);
00368 
00369    if(add_resource_instance(uri, resource_node, result, cid_array)< 0)
00370    {
00371       LM_ERR("while adding resource instance node\n");
00372       goto error;
00373    }
00374 
00375    return 0;
00376 error:
00377    return -1;
00378 }
00379 
00380 str* constr_rlmi_doc(db_res_t *result, str* rl_uri, int version,
00381       xmlNodePtr rl_node, char*** rlmi_cid_array)
00382 {
00383    xmlDocPtr doc= NULL;
00384    xmlNodePtr list_node= NULL;
00385    str* rlmi_cont= NULL;
00386    int len; 
00387    char* uri;
00388    res_param_t param;
00389    char** cid_array= NULL;
00390    int n= result->n;
00391 
00392    LM_DBG("start\n");
00393    cid_array= (char**)pkg_malloc(n* sizeof(char*));
00394    if(cid_array== NULL)
00395    {
00396       ERR_MEM(PKG_MEM_STR);
00397    }
00398    memset(cid_array, 0, n* sizeof(char*));
00399 
00400    doc= xmlNewDoc(BAD_CAST "1.0");
00401    if(doc== NULL)
00402    {
00403       LM_ERR("while constructing new xml doc\n");
00404       goto error;
00405    }
00406    list_node= xmlNewNode(NULL, BAD_CAST "list");
00407    if(list_node== NULL)
00408    {
00409       LM_ERR("while creating new xml node\n");
00410       goto error;
00411    }
00412    uri= (char*)pkg_malloc(rl_uri->len+ 1);
00413    if(uri== NULL)
00414    {
00415       ERR_MEM(PKG_MEM_STR);
00416    }
00417    memcpy(uri, rl_uri->s, rl_uri->len);
00418    uri[rl_uri->len]= '\0';
00419    xmlNewProp(list_node, BAD_CAST "uri", BAD_CAST uri);
00420    pkg_free(uri);
00421 
00422    xmlNewProp(list_node, BAD_CAST "xmlns",
00423          BAD_CAST "urn:ietf:params:xml:ns:rlmi");
00424    xmlNewProp(list_node, BAD_CAST "version", BAD_CAST int2str(version, &len));
00425    xmlNewProp(list_node, BAD_CAST "fullState", BAD_CAST "true");
00426 
00427    xmlDocSetRootElement(doc, list_node);
00428    
00429    /* go through the list -- and add the appropriate 'resource' nodes*/
00430    
00431    param.list_node= list_node;
00432    param.db_result= result;
00433    param.cid_array= cid_array;
00434 
00435    if(   process_list_and_exec(rl_node, add_resource,(void*)(&param))< 0)
00436    {
00437       LM_ERR("in process_list_and_exec function\n");
00438       goto error;
00439    }
00440    rlmi_cont= (str*)pkg_malloc(sizeof(str));
00441    if(rlmi_cont== NULL)
00442    {
00443       ERR_MEM(PKG_MEM_STR);
00444    }
00445    xmlDocDumpFormatMemory(doc,(xmlChar**)(void*)&rlmi_cont->s,
00446          &rlmi_cont->len, 1);
00447 
00448    *rlmi_cid_array= cid_array;
00449    
00450    xmlFreeDoc(doc);
00451 
00452    return rlmi_cont;
00453 
00454 error:
00455    if(doc)
00456       xmlFreeDoc(doc);
00457    return NULL;   
00458 }
00459 
00460 
00461 str* constr_multipart_body(db_res_t* result, char** cid_array, 
00462       char* boundary_string)
00463 {
00464    char* buf= NULL;
00465    int size= BUF_REALLOC_SIZE;
00466    int i, length= 0;
00467    db_row_t *row; 
00468    db_val_t *row_vals;
00469    char* content_id= NULL;
00470    str body= {0, 0};
00471    int antet_len;
00472    str* multi_body= NULL;
00473    
00474    LM_DBG("start\n");
00475    buf= pkg_malloc(size* sizeof(char));
00476    if(buf== NULL)
00477    {
00478       ERR_MEM(PKG_MEM_STR);
00479    }
00480 
00481    antet_len= COMPUTE_ANTET_LEN (boundary_string);
00482 
00483    for(i= 0; i< result->n; i++)
00484    {
00485       row = &result->rows[i];
00486       row_vals = ROW_VALUES(row);
00487    
00488       if(row_vals[auth_state_col].val.int_val!= ACTIVE_STATE)
00489          continue;
00490    
00491       if(length+ antet_len+ body.len+ 4 > size)
00492       {
00493          REALLOC_BUF
00494       }
00495 
00496       length+= sprintf(buf+ length, "--%s\r\n\r\n", boundary_string);
00497       length+= sprintf(buf+ length, "Content-Transfer-Encoding: binary\r\n");
00498       content_id= cid_array[i];
00499       if(content_id== NULL)
00500       {
00501          LM_ERR("No cid found in array for uri= %s\n",
00502                row_vals[resource_uri_col].val.string_val);
00503          goto error;
00504       }
00505 
00506       length+= sprintf(buf+ length, "Content-ID: <%s>\r\n",content_id);
00507       length+= sprintf(buf+ length, "Content-Type: %s\r\n\r\n",
00508             row_vals[content_type_col].val.string_val);
00509       
00510       body.s= (char*)row_vals[pres_state_col].val.string_val;
00511       body.len= strlen(body.s);
00512 
00513       length+= sprintf(buf+length,"%s\r\n\r\n", body.s);
00514    }
00515 
00516    if(length+ strlen( boundary_string)+ 7> size )
00517    {
00518       REALLOC_BUF
00519    }
00520    buf[length]= '\0';
00521    
00522    multi_body= (str*)pkg_malloc(sizeof(str));
00523    if(multi_body== NULL)
00524    {
00525       ERR_MEM(PKG_MEM_STR);
00526    }
00527 
00528    multi_body->s= buf;
00529    multi_body->len= length;
00530 
00531    return multi_body;
00532 
00533 error:
00534 
00535    if(buf)
00536       pkg_free(buf);
00537    return NULL;
00538 }
00539 
00540 str* rls_notify_extra_hdr(subs_t* subs, char* start_cid, char* boundary_string)
00541 {
00542    str* str_hdr= NULL;
00543    int len= 0, expires;
00544 
00545    str_hdr= (str*)pkg_malloc(sizeof(str));
00546    if(str_hdr== NULL)
00547    {
00548       ERR_MEM(PKG_MEM_STR);
00549    }
00550    memset(str_hdr, 0, sizeof(str));
00551 
00552    str_hdr->s= (char*)pkg_malloc(RLS_HDR_LEN* sizeof(char));
00553    if(str_hdr->s== NULL)
00554    {
00555       ERR_MEM(PKG_MEM_STR);
00556    }
00557    memcpy(str_hdr->s ,"Max-Forwards: ", 14);
00558    str_hdr->len = 14;
00559    len= sprintf(str_hdr->s+str_hdr->len, "%d", MAX_FORWARD);
00560    if(len<= 0)
00561    {
00562       LM_ERR("while printing in string\n");
00563       goto error;
00564    }  
00565    str_hdr->len+= len; 
00566    memcpy(str_hdr->s+str_hdr->len, CRLF, CRLF_LEN);
00567    str_hdr->len += CRLF_LEN;
00568 
00569    memcpy(str_hdr->s+str_hdr->len  ,"Event: ", 7);
00570    str_hdr->len+= 7;
00571    memcpy(str_hdr->s+str_hdr->len, subs->event->name.s,
00572          subs->event->name.len);
00573    str_hdr->len+= subs->event->name.len;     
00574    memcpy(str_hdr->s+str_hdr->len, CRLF, CRLF_LEN);
00575    str_hdr->len += CRLF_LEN;
00576 
00577    memcpy(str_hdr->s+str_hdr->len ,"Contact: <", 10);
00578    str_hdr->len += 10;
00579    memcpy(str_hdr->s+str_hdr->len,subs->local_contact.s,
00580          subs->local_contact.len);
00581    str_hdr->len +=  subs->local_contact.len;
00582    memcpy(str_hdr->s+str_hdr->len, ">", 1);
00583    str_hdr->len += 1;
00584    memcpy(str_hdr->s+str_hdr->len, CRLF, CRLF_LEN);
00585    str_hdr->len += CRLF_LEN;
00586 
00587    expires= subs->expires;
00588 
00589    if( expires> 0 )
00590       str_hdr->len+= sprintf(str_hdr->s+str_hdr->len,
00591          "Subscription-State: active;expires=%d\r\n", expires);
00592    else
00593       str_hdr->len+= sprintf(str_hdr->s+str_hdr->len,
00594          "Subscription-State: terminated;reason=timeout");
00595 
00596    str_hdr->len+= sprintf(str_hdr->s+str_hdr->len, "Require: eventlist\r\n");
00597 
00598    if(start_cid && boundary_string)
00599    {
00600       str_hdr->len+= sprintf(str_hdr->s+str_hdr->len,
00601          "Content-Type: \"multipart/related;type=\"application/rlmi+xml\"");
00602       str_hdr->len+= sprintf(str_hdr->s+str_hdr->len,
00603             ";start= <%s>;boundary=%s\r\n", start_cid, boundary_string);
00604    }     
00605    if(str_hdr->len> RLS_HDR_LEN)
00606    {
00607       LM_ERR("buffer size overflow\n");
00608       goto error;
00609    }
00610    str_hdr->s[str_hdr->len] = '\0';
00611 
00612    return str_hdr;
00613 
00614 error:
00615    if(str_hdr)
00616    {
00617       if(str_hdr->s)
00618          pkg_free(str_hdr->s);
00619       pkg_free(str_hdr);
00620    }
00621    return NULL;
00622 
00623 }
00624 void rls_free_td(dlg_t* td)
00625 {
00626       pkg_free(td->loc_uri.s);
00627       pkg_free(td->rem_uri.s);
00628       pkg_free(td);
00629 }
00630 
00631 int rls_send_notify(subs_t* subs, str* body, char* start_cid,
00632       char* boundary_string)
00633 {
00634    dlg_t* td= NULL;
00635    str met= {"NOTIFY", 6};
00636    str* str_hdr= NULL;
00637    dialog_id_t* cb_param= NULL;
00638    int size;
00639    int rt;
00640 
00641    LM_DBG("start\n");
00642    td= rls_notify_dlg(subs);
00643    if(td ==NULL)
00644    {
00645       LM_ERR("while building dlg_t structure\n");
00646       goto error; 
00647    }
00648    
00649    LM_DBG("constructed dlg_t struct\n");
00650    size= sizeof(dialog_id_t)+(subs->to_tag.len+ subs->callid.len+ 
00651          subs->from_tag.len) *sizeof(char);
00652    
00653    cb_param = (dialog_id_t*)shm_malloc(size);
00654    if(cb_param== NULL)
00655    {
00656       ERR_MEM(SHARE_MEM);
00657    }
00658    size= sizeof(dialog_id_t);
00659    
00660    cb_param->callid.s= (char*)cb_param + size;
00661    memcpy(cb_param->callid.s, subs->callid.s, subs->callid.len);
00662    cb_param->callid.len= subs->callid.len;
00663    size+= subs->callid.len;
00664 
00665    cb_param->to_tag.s= (char*)cb_param + size;
00666    memcpy(cb_param->to_tag.s, subs->to_tag.s, subs->to_tag.len);
00667    cb_param->to_tag.len= subs->to_tag.len;
00668    size+= subs->to_tag.len;
00669 
00670    cb_param->from_tag.s= (char*)cb_param + size;
00671    memcpy(cb_param->from_tag.s, subs->from_tag.s, subs->from_tag.len);
00672    cb_param->from_tag.len= subs->from_tag.len;
00673    
00674    LM_DBG("constructed cb_param\n");
00675 
00676    str_hdr= rls_notify_extra_hdr(subs, start_cid, boundary_string);
00677    if(str_hdr== NULL || str_hdr->s== NULL)
00678    {
00679       LM_ERR("while building extra headers\n");
00680       goto error;
00681    }
00682    LM_DBG("str_hdr= %.*s\n", str_hdr->len, str_hdr->s);
00683    rt = tmb.t_request_within
00684       (&met,                               
00685       str_hdr,                               
00686       body,                           
00687       td,                                 
00688       rls_notify_callback,                  
00689       (void*)cb_param);          
00690 
00691    if(rt < 0)
00692    {
00693       LM_ERR("in function tmb.t_request_within\n");
00694       goto error; 
00695    }
00696 
00697    pkg_free(str_hdr->s);
00698    pkg_free(str_hdr);
00699    rls_free_td(td);
00700    return 0;
00701 
00702 error:
00703    if(td)
00704       rls_free_td(td);
00705    if(cb_param)
00706       shm_free(cb_param);
00707    if(str_hdr)
00708    {
00709       if(str_hdr->s)
00710          pkg_free(str_hdr->s);
00711       pkg_free(str_hdr);
00712    }
00713    return -1;
00714 
00715 }
00716 
00717 dlg_t* rls_notify_dlg(subs_t* subs)
00718 {
00719    dlg_t* td=NULL;
00720 
00721    td= (dlg_t*)pkg_malloc(sizeof(dlg_t));
00722    if(td== NULL)
00723    {
00724       ERR_MEM(PKG_MEM_STR);
00725    }
00726 
00727    memset(td, 0, sizeof(dlg_t));
00728    td->loc_seq.value = subs->local_cseq;
00729    td->loc_seq.is_set = 1;
00730 
00731    td->id.call_id = subs->callid;
00732    td->id.rem_tag = subs->from_tag;
00733    td->id.loc_tag =subs->to_tag;
00734    if(uandd_to_uri(subs->to_user, subs->to_domain, &td->loc_uri)< 0)
00735    {
00736       LM_ERR("while constructing uri from user and domain\n");
00737       goto error;
00738    }
00739    
00740    if(uandd_to_uri(subs->from_user, subs->from_domain, &td->rem_uri)< 0)
00741    {
00742       LM_ERR("while constructing uri from user and domain\n");
00743       goto error;
00744    }
00745 
00746    if(subs->contact.len ==0 || subs->contact.s == NULL )
00747    {
00748       LM_DBG("BAD BAD contact NULL\n");
00749       td->rem_target = td->rem_uri;
00750    }
00751    else
00752       td->rem_target = subs->contact;
00753 
00754    if(subs->record_route.s && subs->record_route.len)
00755    {
00756       if(parse_rr_body(subs->record_route.s, subs->record_route.len,
00757          &td->route_set)< 0)
00758       {
00759          LM_ERR("in function parse_rr_body\n");
00760          goto error;
00761       }
00762    }  
00763    td->state= DLG_CONFIRMED ;
00764 
00765    if (subs->sockinfo_str.len) {
00766       int port, proto;
00767         str host;
00768       if (parse_phostport (
00769             subs->sockinfo_str.s,subs->sockinfo_str.len,&host.s,
00770             &host.len,&port, &proto )) {
00771          LM_ERR("bad sockinfo string\n");
00772          goto error;
00773       }
00774       td->send_sock = grep_sock_info (
00775          &host, (unsigned short) port, (unsigned short) proto);
00776    }
00777    
00778    return td;
00779 
00780 error:
00781    if(td)
00782    {
00783       if(td->loc_uri.s)
00784          pkg_free(td->loc_uri.s);
00785    
00786       if(td->rem_uri.s)
00787          pkg_free(td->rem_uri.s);
00788       pkg_free(td);
00789    }  
00790 
00791    return NULL;
00792 
00793 }
00794 void rls_notify_callback( struct cell *t, int type, struct tmcb_params *ps)
00795 {
00796    if(ps->param==NULL || *ps->param==NULL || 
00797          ((dialog_id_t*)(*ps->param)) == NULL)
00798    {
00799       LM_DBG("message id not received\n");
00800       return;
00801    }
00802    
00803    LM_DBG("completed with status %d [to_tag:"
00804          "%.*s]\n",ps->code,
00805          ((dialog_id_t*)(*ps->param))->to_tag.len, 
00806          ((dialog_id_t*)(*ps->param))->to_tag.s);
00807 
00808    if(ps->code >= 300)
00809    {
00810       /* delete from database table */
00811       db_key_t db_keys[2];
00812       db_val_t db_vals[2];
00813       unsigned int hash_code;
00814       subs_t subs;
00815       
00816       memset(&subs, 0, sizeof(subs_t));
00817 
00818       subs.to_tag= ((dialog_id_t*)(*ps->param))->to_tag;
00819       subs.from_tag= ((dialog_id_t*)(*ps->param))->from_tag;
00820       subs.callid= ((dialog_id_t*)(*ps->param))->callid;
00821 
00822       if (rls_dbf.use_table(rls_db, &rlsubs_table) < 0) 
00823       {
00824          LM_ERR("in use_table\n");
00825          goto done;
00826       }
00827       
00828       db_keys[0] =&str_to_tag_col;
00829       db_vals[0].type = DB_STR;
00830       db_vals[0].nul = 0;
00831       db_vals[0].val.str_val = subs.to_tag;
00832 
00833       db_keys[1] =&str_callid_col;
00834       db_vals[1].type = DB_STR;
00835       db_vals[1].nul = 0;
00836       db_vals[1].val.str_val = subs.callid;
00837 
00838 
00839       if (rls_dbf.delete(rls_db, db_keys, 0, db_vals, 2) < 0) 
00840          LM_ERR("cleaning expired messages\n"); 
00841 
00842       /* delete from cache table */
00843       hash_code= core_hash(&subs.callid, &subs.to_tag , hash_size);
00844 
00845       if(pres_delete_shtable(rls_table,hash_code, subs.to_tag)< 0)
00846       {
00847          LM_ERR("record not found in hash table\n");
00848       }
00849    }  
00850 
00851 done: 
00852    if(*ps->param !=NULL  )
00853       shm_free(*ps->param);
00854    return ;
00855 
00856 }
00857 
00858 int process_list_and_exec(xmlNodePtr list_node, list_func_t function,
00859       void* param)
00860 {
00861    xmlNodePtr node;
00862    char* uri;
00863 
00864    LM_DBG("start\n");
00865    for(node= list_node->children; node; node= node->next)
00866    {
00867       if(xmlStrcasecmp(node->name,(unsigned char*)"entry")== 0)
00868       {
00869          uri= XMLNodeGetAttrContentByName(node, "uri");
00870          if(uri== NULL)
00871          {
00872             LM_ERR("when extracting entry uri attribute\n");
00873             return -1;
00874          }
00875          LM_DBG("uri= %s\n", uri);
00876          if(function(uri, param)< 0)
00877          {
00878             LM_ERR(" infunction given as a parameter\n");
00879             xmlFree(uri);
00880             return -1;
00881          }
00882          xmlFree(uri);
00883       }
00884       else
00885       if(xmlStrcasecmp(node->name,(unsigned char*)"list")== 0)
00886          process_list_and_exec(node, function, param);
00887    }
00888    return 0;
00889 
00890 }
00891 
00892 char* generate_string(int seed, int length)
00893 {
00894    static char buf[128];
00895     int r,i;
00896 
00897     if(length>= 128)
00898    {
00899       LM_ERR("requested length exceeds buffer size\n");
00900       return NULL;
00901    }
00902    srand(seed); 
00903       
00904    for(i=0; i<length; i++) 
00905    {
00906       r= rand() % ('z'- 'A') + 'A';
00907        if(r>'Z' && r< 'a')
00908          r= '0'+ (r- 'Z');
00909 
00910         sprintf(buf+i, "%c", r);
00911     }
00912    buf[length]= '\0';
00913 
00914    return buf;
00915 }
00916 
00917 char* generate_cid(char* uri, int uri_len)
00918 {
00919    static char cid[512];
00920    int len;
00921 
00922    len= sprintf(cid, "%d.%.*s.%d", (int)time(NULL), uri_len, uri, rand());
00923    cid[len]= '\0';
00924    
00925    return cid;
00926 }
00927 
00928 char* get_auth_string(int flag)
00929 {
00930    switch(flag)
00931    {
00932       case ACTIVE_STATE:     return "active";
00933       case PENDING_STATE:    return "pending";
00934       case TERMINATED_STATE: return "terminated";
00935    }
00936    return NULL;
00937 }
00938 

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