t_var.c

Go to the documentation of this file.
00001 /**
00002  * $Id$
00003  *
00004  * Copyright (C) 2008 Elena-Ramona Modroiu (asipto.com)
00005  *
00006  * This file is part of kamailio, a free SIP server.
00007  *
00008  * openser is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version
00012  *
00013  * openser is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, write to the Free Software
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  */
00022 
00023 #include "../../mem/mem.h"
00024 
00025 #include "t_lookup.h"
00026 #include "t_var.h"
00027 
00028 static struct cell *_pv_T_req = NULL;
00029 static struct cell *_pv_T_rpl = NULL;
00030 static struct sip_msg _pv_treq;
00031 static struct sip_msg _pv_trpl;
00032 static struct sip_msg *_pv_treq_p = NULL;
00033 static struct sip_msg *_pv_trpl_p = NULL;
00034 static unsigned int _pv_treq_id = 0;
00035 static unsigned int _pv_trpl_id = 0;
00036 static char *_pv_treq_buf = NULL;
00037 static char *_pv_trpl_buf = NULL;
00038 static unsigned int _pv_treq_size = 0;
00039 static unsigned int _pv_trpl_size = 0;
00040 
00041 int pv_t_copy_msg(struct sip_msg *src, struct sip_msg *dst)
00042 {
00043    dst->id = src->id;
00044    dst->rcv = src->rcv;
00045    dst->set_global_address=src->set_global_address;
00046    dst->set_global_port=src->set_global_port;
00047    dst->flags = src->flags;
00048    dst->force_send_socket = src->force_send_socket;
00049 
00050    if (parse_msg(dst->buf, dst->len, dst)!=0)
00051    {
00052       LM_ERR("parse msg failed\n");
00053       return -1;
00054    }
00055    return 0;
00056 }
00057 
00058 int pv_t_update_req(struct sip_msg *msg)
00059 {
00060    struct cell * t;
00061    int branch;
00062 
00063    if(msg==NULL)
00064       return 1;
00065 
00066    if(msg!=FAKED_REPLY && msg->first_line.type!=SIP_REPLY)
00067       return 1;
00068 
00069    t = get_t();
00070 
00071    if(t==NULL || t==T_UNDEFINED)
00072    {
00073       if(msg==FAKED_REPLY)
00074          return 1;
00075       branch=-1;
00076       if (t_check(msg, &branch ) == -1)
00077          return 1;
00078       t = get_t();
00079       if ((t == 0) || (t == T_UNDEFINED))
00080          return 1;
00081 
00082    }
00083 
00084    if(t->uas.request==NULL)
00085       return 1;
00086 
00087    if(_pv_T_req==t && t->uas.request==_pv_treq_p
00088          && t->uas.request->id==_pv_treq_id)
00089       return 0;
00090 
00091    /* make a copy */
00092    if(_pv_treq_buf==NULL || _pv_treq_size<t->uas.request->len+1)
00093    {
00094       if(_pv_treq_buf!=NULL)
00095          pkg_free(_pv_treq_buf);
00096       if(_pv_treq_p)
00097          free_sip_msg(&_pv_treq);
00098       _pv_treq_p = NULL;
00099       _pv_treq_id = 0;
00100       _pv_T_req = NULL;
00101       _pv_treq_size = t->uas.request->len+1;
00102       _pv_treq_buf = (char*)pkg_malloc(_pv_treq_size*sizeof(char));
00103       if(_pv_treq_buf==NULL)
00104       {
00105          LM_ERR("no more pkg\n");
00106          _pv_treq_size = 0;
00107          return -1;
00108       }
00109    }
00110    if(_pv_treq_p)
00111       free_sip_msg(&_pv_treq);
00112    memset(&_pv_treq, 0, sizeof(struct sip_msg));
00113    memcpy(_pv_treq_buf, t->uas.request->buf, t->uas.request->len);
00114    _pv_treq_buf[t->uas.request->len] = '\0';
00115    _pv_treq.len = t->uas.request->len;
00116    _pv_treq.buf = _pv_treq_buf;
00117    _pv_treq_p = t->uas.request;
00118    _pv_treq_id = t->uas.request->id;
00119    _pv_T_req = t;
00120 
00121 
00122    if(pv_t_copy_msg(t->uas.request, &_pv_treq)!=0)
00123    {
00124       pkg_free(_pv_treq_buf);
00125       _pv_treq_size = 0;
00126       _pv_treq_buf = NULL;
00127       _pv_T_req = NULL;
00128       return -1;
00129    }
00130 
00131    return 0;
00132 }
00133 
00134 int pv_t_update_rpl(struct sip_msg *msg)
00135 {
00136    struct cell * t;
00137    int branch;
00138 
00139    if(msg==NULL)
00140       return 1;
00141 
00142    if(msg==FAKED_REPLY || msg->first_line.type!=SIP_REQUEST)
00143       return 1;
00144 
00145    t = get_t();
00146 
00147    if(t==NULL || t==T_UNDEFINED)
00148    {
00149       if(t_lookup_request(msg, 0)<=0)
00150          return 1;
00151       t = get_t();
00152 
00153       if(t==NULL || t==T_UNDEFINED)
00154          return 1;
00155    }
00156    if ( (branch=t_get_picked_branch())<0 )
00157       return 1;
00158    if(t->uac[branch].reply==NULL || t->uac[branch].reply==FAKED_REPLY)
00159       return 1;
00160 
00161    if(_pv_T_rpl==t && t->uac[branch].reply==_pv_trpl_p
00162          && t->uac[branch].reply->id==_pv_trpl_id)
00163       return 0;
00164 
00165    /* make a copy */
00166    if(_pv_trpl_buf==NULL || _pv_trpl_size<t->uac[branch].reply->len+1)
00167    {
00168       if(_pv_trpl_buf!=NULL)
00169          pkg_free(_pv_trpl_buf);
00170       if(_pv_trpl_p)
00171          free_sip_msg(&_pv_trpl);
00172       _pv_trpl_p = NULL;
00173       _pv_trpl_id = 0;
00174       _pv_T_rpl = NULL;
00175       _pv_trpl_size = t->uac[branch].reply->len+1;
00176       _pv_trpl_buf = (char*)pkg_malloc(_pv_trpl_size*sizeof(char));
00177       if(_pv_trpl_buf==NULL)
00178       {
00179          LM_ERR("no more pkg\n");
00180          _pv_trpl_size = 0;
00181          return -1;
00182       }
00183    }
00184    if(_pv_trpl_p)
00185       free_sip_msg(&_pv_trpl);
00186    memset(&_pv_trpl, 0, sizeof(struct sip_msg));
00187    memcpy(_pv_trpl_buf, t->uac[branch].reply->buf, t->uac[branch].reply->len);
00188    _pv_trpl_buf[t->uac[branch].reply->len] = '\0';
00189    _pv_trpl.len = t->uac[branch].reply->len;
00190    _pv_trpl.buf = _pv_trpl_buf;
00191    _pv_trpl_p = t->uac[branch].reply;
00192    _pv_trpl_id = t->uac[branch].reply->id;
00193    _pv_T_rpl = t;
00194 
00195    if(pv_t_copy_msg(t->uac[branch].reply, &_pv_trpl)!=0)
00196    {
00197       pkg_free(_pv_trpl_buf);
00198       _pv_trpl_buf = NULL;
00199       _pv_trpl_size = 0;
00200       _pv_T_rpl = 0;
00201       return -1;
00202    }
00203 
00204    return 0;
00205 }
00206 
00207 int pv_get_t_var_req(struct sip_msg *msg,  pv_param_t *param,
00208       pv_value_t *res)
00209 {
00210    pv_spec_t *pv=NULL;
00211 
00212    if(pv_t_update_req(msg))
00213       return pv_get_null(msg, param, res);
00214 
00215    pv = (pv_spec_t*)param->pvn.u.dname;
00216    if(pv==NULL || pv_alter_context(pv))
00217       return pv_get_null(msg, param, res);
00218 
00219    return pv_get_spec_value(&_pv_treq, pv, res);
00220 }
00221 
00222 int pv_get_t_var_rpl(struct sip_msg *msg,  pv_param_t *param,
00223       pv_value_t *res)
00224 {
00225    pv_spec_t *pv=NULL;
00226 
00227    if(pv_t_update_rpl(msg))
00228       return pv_get_null(msg, param, res);
00229 
00230    pv = (pv_spec_t*)param->pvn.u.dname;
00231    if(pv==NULL || pv_alter_context(pv))
00232       return pv_get_null(msg, param, res);
00233 
00234    return pv_get_spec_value(&_pv_trpl, pv, res);
00235 }
00236 
00237 int pv_parse_t_var_name(pv_spec_p sp, str *in)
00238 {
00239    pv_spec_t *pv=NULL;
00240 
00241    if(in->s==NULL || in->len<=0)
00242       return -1;
00243 
00244    pv = (pv_spec_t*)pkg_malloc(sizeof(pv_spec_t));
00245    if(pv==NULL)
00246       return -1;
00247 
00248    memset(pv, 0, sizeof(pv_spec_t));
00249 
00250    if(pv_parse_spec(in, pv)==NULL)
00251       goto error;
00252 
00253    sp->pvp.pvn.u.dname = (void*)pv;
00254    sp->pvp.pvn.type = PV_NAME_PVAR;
00255    return 0;
00256 
00257 error:
00258    LM_ERR("invalid pv name [%.*s]\n", in->len, in->s);
00259    if(pv!=NULL)
00260       pkg_free(pv);
00261    return -1;
00262 }
00263 

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