uac_send.c

Go to the documentation of this file.
00001 /**
00002  * $Id$
00003  *
00004  * Copyright (C) 2009 Daniel-Constantin Mierla (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 "../../dprint.h"
00024 
00025 #include "../tm/tm_load.h"
00026 
00027 #include "uac_send.h"
00028 
00029 #define MAX_UACH_SIZE 2048
00030 #define MAX_UACB_SIZE 4086
00031 
00032 /** TM bind */
00033 struct tm_binds tmb;
00034 
00035 struct _uac_send_info {
00036    unsigned int flags;
00037    char  b_method[32];
00038    str   s_method;
00039    char  b_ruri[MAX_URI_SIZE];
00040    str   s_ruri;
00041    char  b_turi[MAX_URI_SIZE];
00042    str   s_turi;
00043    char  b_furi[MAX_URI_SIZE];
00044    str   s_furi;
00045    char  b_hdrs[MAX_UACH_SIZE];
00046    str   s_hdrs;
00047    char  b_body[MAX_UACB_SIZE];
00048    str   s_body;
00049    char  b_ouri[MAX_URI_SIZE];
00050    str   s_ouri;
00051    unsigned int onreply;
00052 };
00053 
00054 static struct _uac_send_info _uac_req;
00055 
00056 int pv_get_uac_req(struct sip_msg *msg, pv_param_t *param,
00057       pv_value_t *res)
00058 {
00059    if(param==NULL || tmb.t_request==NULL)
00060       return -1;
00061 
00062    switch(param->pvn.u.isname.name.n)
00063    {
00064       case 0:
00065          return pv_get_uintval(msg, param, res, _uac_req.flags);
00066       case 1:
00067          if(_uac_req.s_ruri.len<=0)
00068             return pv_get_null(msg, param, res);
00069          return pv_get_strval(msg, param, res, &_uac_req.s_ruri);
00070       case 2:
00071          if(_uac_req.s_turi.len<=0)
00072             return pv_get_null(msg, param, res);
00073          return pv_get_strval(msg, param, res, &_uac_req.s_turi);
00074       case 3:
00075          if(_uac_req.s_furi.len<=0)
00076             return pv_get_null(msg, param, res);
00077          return pv_get_strval(msg, param, res, &_uac_req.s_furi);
00078       case 4:
00079          if(_uac_req.s_hdrs.len<=0)
00080             return pv_get_null(msg, param, res);
00081          return pv_get_strval(msg, param, res, &_uac_req.s_hdrs);
00082       case 5:
00083          if(_uac_req.s_body.len<=0)
00084             return pv_get_null(msg, param, res);
00085          return pv_get_strval(msg, param, res, &_uac_req.s_body);
00086       case 6:
00087          if(_uac_req.s_ouri.len<=0)
00088             return pv_get_null(msg, param, res);
00089          return pv_get_strval(msg, param, res, &_uac_req.s_ouri);
00090       case 7:
00091          if(_uac_req.s_method.len<=0)
00092             return pv_get_null(msg, param, res);
00093          return pv_get_strval(msg, param, res, &_uac_req.s_method);
00094       default:
00095          return pv_get_uintval(msg, param, res, _uac_req.flags);
00096    }
00097    return 0;
00098 }
00099 
00100 int pv_set_uac_req(struct sip_msg* msg, pv_param_t *param,
00101       int op, pv_value_t *val)
00102 {
00103    if(param==NULL || tmb.t_request==NULL)
00104       return -1;
00105 
00106    switch(param->pvn.u.isname.name.n)
00107    {
00108       case 0:
00109          if(val==NULL)
00110          {
00111             _uac_req.flags = 0;
00112             _uac_req.s_ruri.len = 0;
00113             _uac_req.s_furi.len = 0;
00114             _uac_req.s_turi.len = 0;
00115             _uac_req.s_ouri.len = 0;
00116             _uac_req.s_hdrs.len = 0;
00117             _uac_req.s_body.len = 0;
00118             _uac_req.s_method.len = 0;
00119             _uac_req.onreply = 0;
00120          }
00121          break;
00122       case 1:
00123          if(val==NULL)
00124          {
00125             _uac_req.s_ruri.len = 0;
00126             return 0;
00127          }
00128          if(!(val->flags&PV_VAL_STR))
00129          {
00130             LM_ERR("Invalid value type\n");
00131             return -1;
00132          }
00133          if(val->rs.len>=MAX_URI_SIZE)
00134          {
00135             LM_ERR("Value size too big\n");
00136             return -1;
00137          }
00138          memcpy(_uac_req.s_ruri.s, val->rs.s, val->rs.len);
00139          _uac_req.s_ruri.s[val->rs.len] = '\0';
00140          _uac_req.s_ruri.len = val->rs.len;
00141          break;
00142       case 2:
00143          if(val==NULL)
00144          {
00145             _uac_req.s_turi.len = 0;
00146             return 0;
00147          }
00148          if(!(val->flags&PV_VAL_STR))
00149          {
00150             LM_ERR("Invalid value type\n");
00151             return -1;
00152          }
00153          if(val->rs.len>=MAX_URI_SIZE)
00154          {
00155             LM_ERR("Value size too big\n");
00156             return -1;
00157          }
00158          memcpy(_uac_req.s_turi.s, val->rs.s, val->rs.len);
00159          _uac_req.s_turi.s[val->rs.len] = '\0';
00160          _uac_req.s_turi.len = val->rs.len;
00161          break;
00162       case 3:
00163          if(val==NULL)
00164          {
00165             _uac_req.s_furi.len = 0;
00166             return 0;
00167          }
00168          if(!(val->flags&PV_VAL_STR))
00169          {
00170             LM_ERR("Invalid value type\n");
00171             return -1;
00172          }
00173          if(val->rs.len>=MAX_URI_SIZE)
00174          {
00175             LM_ERR("Value size too big\n");
00176             return -1;
00177          }
00178          memcpy(_uac_req.s_furi.s, val->rs.s, val->rs.len);
00179          _uac_req.s_furi.s[val->rs.len] = '\0';
00180          _uac_req.s_furi.len = val->rs.len;
00181          break;
00182       case 4:
00183          if(val==NULL)
00184          {
00185             _uac_req.s_hdrs.len = 0;
00186             return 0;
00187          }
00188                   if(!(val->flags&PV_VAL_STR))
00189          {
00190             LM_ERR("Invalid value type\n");
00191             return -1;
00192          }
00193          if(val->rs.len>=MAX_UACH_SIZE)
00194          {
00195             LM_ERR("Value size too big\n");
00196             return -1;
00197          }
00198          memcpy(_uac_req.s_hdrs.s, val->rs.s, val->rs.len);
00199          _uac_req.s_hdrs.s[val->rs.len] = '\0';
00200          _uac_req.s_hdrs.len = val->rs.len;
00201          break;
00202       case 5:
00203          if(val==NULL)
00204          {
00205             _uac_req.s_body.len = 0;
00206             return 0;
00207          }
00208          if(!(val->flags&PV_VAL_STR))
00209          {
00210             LM_ERR("Invalid value type\n");
00211             return -1;
00212          }
00213          if(val->rs.len>=MAX_UACB_SIZE)
00214          {
00215             LM_ERR("Value size too big\n");
00216             return -1;
00217          }
00218          memcpy(_uac_req.s_body.s, val->rs.s, val->rs.len);
00219          _uac_req.s_body.s[val->rs.len] = '\0';
00220          _uac_req.s_body.len = val->rs.len;
00221          break;
00222       case 6:
00223          if(val==NULL)
00224          {
00225             _uac_req.s_ouri.len = 0;
00226             return 0;
00227          }
00228          if(!(val->flags&PV_VAL_STR))
00229          {
00230             LM_ERR("Invalid value type\n");
00231             return -1;
00232          }
00233          if(val->rs.len>=MAX_URI_SIZE)
00234          {
00235             LM_ERR("Value size too big\n");
00236             return -1;
00237          }
00238          memcpy(_uac_req.s_ouri.s, val->rs.s, val->rs.len);
00239          _uac_req.s_ouri.s[val->rs.len] = '\0';
00240          _uac_req.s_ouri.len = val->rs.len;
00241          break;
00242       case 7:
00243          if(val==NULL)
00244          {
00245             _uac_req.s_method.len = 0;
00246             return 0;
00247          }
00248          if(!(val->flags&PV_VAL_STR))
00249          {
00250             LM_ERR("Invalid value type\n");
00251             return -1;
00252          }
00253          if(val->rs.len>=32)
00254          {
00255             LM_ERR("Value size too big\n");
00256             return -1;
00257          }
00258          memcpy(_uac_req.s_method.s, val->rs.s, val->rs.len);
00259          _uac_req.s_method.s[val->rs.len] = '\0';
00260          _uac_req.s_method.len = val->rs.len;
00261          break;
00262       case 8:
00263          if(val==NULL)
00264          {
00265             _uac_req.onreply = 0;
00266             return 0;
00267          }
00268          if(!(val->flags&PV_VAL_INT))
00269          {
00270             LM_ERR("Invalid value type\n");
00271             return -1;
00272          }
00273          if(val->ri>=ONREPLY_RT_NO)
00274          {
00275             LM_ERR("Value too big\n");
00276             return -1;
00277          }
00278          _uac_req.onreply = val->ri;
00279          break;
00280    }
00281    return 0;
00282 }
00283 
00284 int pv_parse_uac_req_name(pv_spec_p sp, str *in)
00285 {
00286    if(sp==NULL || in==NULL || in->len<=0)
00287       return -1;
00288 
00289    switch(in->len)
00290    {
00291       case 3: 
00292          if(strncmp(in->s, "all", 3)==0)
00293             sp->pvp.pvn.u.isname.name.n = 0;
00294          else goto error;
00295       break;
00296       case 4: 
00297          if(strncmp(in->s, "ruri", 4)==0)
00298             sp->pvp.pvn.u.isname.name.n = 1;
00299          else if(strncmp(in->s, "turi", 4)==0)
00300             sp->pvp.pvn.u.isname.name.n = 2;
00301          else if(strncmp(in->s, "furi", 4)==0)
00302             sp->pvp.pvn.u.isname.name.n = 3;
00303          else if(strncmp(in->s, "hdrs", 4)==0)
00304             sp->pvp.pvn.u.isname.name.n = 4;
00305          else if(strncmp(in->s, "body", 4)==0)
00306             sp->pvp.pvn.u.isname.name.n = 5;
00307          else if(strncmp(in->s, "ouri", 4)==0)
00308             sp->pvp.pvn.u.isname.name.n = 6;
00309          else goto error;
00310       break;
00311       case 6: 
00312          if(strncmp(in->s, "method", 6)==0)
00313             sp->pvp.pvn.u.isname.name.n = 7;
00314          else goto error;
00315       break;
00316       case 7: 
00317          if(strncmp(in->s, "onreply", 7)==0)
00318             sp->pvp.pvn.u.isname.name.n = 8;
00319          else goto error;
00320       break;
00321       default:
00322          goto error;
00323    }
00324    sp->pvp.pvn.type = PV_NAME_INTSTR;
00325    sp->pvp.pvn.u.isname.type = 0;
00326 
00327    return 0;
00328 
00329 error:
00330    LM_ERR("unknown uac_req name %.*s\n", in->len, in->s);
00331    return -1;
00332 }
00333 
00334 void uac_req_init(void)
00335 {
00336    /* load the TM API */
00337    if (load_tm_api(&tmb)!=0) {
00338       LM_DBG("can't load TM API - disable it\n");
00339       memset(&tmb, 0, sizeof(struct tm_binds));
00340       return;
00341    }
00342    memset(&_uac_req, 0, sizeof(struct _uac_send_info));
00343    _uac_req.s_ruri.s = _uac_req.b_ruri;
00344    _uac_req.s_furi.s = _uac_req.b_furi;
00345    _uac_req.s_turi.s = _uac_req.b_turi;
00346    _uac_req.s_ouri.s = _uac_req.b_ouri;
00347    _uac_req.s_hdrs.s = _uac_req.b_hdrs;
00348    _uac_req.s_body.s = _uac_req.b_body;
00349    _uac_req.s_method.s = _uac_req.b_method;
00350    return;
00351 }
00352 
00353 /** 
00354  * TM callback function
00355  */
00356 void uac_send_tm_callback( struct cell *t, int type, struct tmcb_params *ps)
00357 {
00358    unsigned int onreply;
00359    if(ps->param==NULL || *ps->param==0)
00360    {
00361       LM_DBG("message id not received\n");
00362       goto done;
00363    }
00364    onreply = *((unsigned int*)ps->param);
00365    LM_DBG("completed with status %d [onreply: %u]\n",
00366       ps->code, onreply);
00367 
00368 done:
00369    return;
00370 }
00371 
00372 
00373 int uac_req_send(struct sip_msg *msg, char *s1, char *s2)
00374 {
00375    int ret;
00376    if(_uac_req.s_ruri.len<=0 || _uac_req.s_method.len == 0
00377          || tmb.t_request==NULL)
00378       return -1;
00379    ret = tmb.t_request(&_uac_req.s_method,  /* Type of the message */
00380       &_uac_req.s_ruri,     /* Request-URI (To) */
00381       (_uac_req.s_turi.len<=0)?&_uac_req.s_ruri:&_uac_req.s_turi,  /* To */
00382       (_uac_req.s_furi.len<=0)?&_uac_req.s_ruri:&_uac_req.s_furi,  /* From */
00383       (_uac_req.s_hdrs.len<=0)?NULL:&_uac_req.s_hdrs, /* Optional headers
00384                                              including CRLF */
00385       (_uac_req.s_body.len<=0)?NULL:&_uac_req.s_body, /* Message body */
00386       (_uac_req.s_ouri.len<=0)?NULL:&_uac_req.s_ouri, /* outbound uri */
00387       (_uac_req.onreply>0)?uac_send_tm_callback:NULL, /* Callback function */
00388       (_uac_req.onreply>0)?(void*)(long)_uac_req.onreply:0
00389                                           /* Callback parameter */
00390       );
00391 
00392    if(ret!=0)
00393       return -1;
00394    return 1;
00395 }
00396 

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