00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
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
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
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,
00380 &_uac_req.s_ruri,
00381 (_uac_req.s_turi.len<=0)?&_uac_req.s_ruri:&_uac_req.s_turi,
00382 (_uac_req.s_furi.len<=0)?&_uac_req.s_ruri:&_uac_req.s_furi,
00383 (_uac_req.s_hdrs.len<=0)?NULL:&_uac_req.s_hdrs,
00384
00385 (_uac_req.s_body.len<=0)?NULL:&_uac_req.s_body,
00386 (_uac_req.s_ouri.len<=0)?NULL:&_uac_req.s_ouri,
00387 (_uac_req.onreply>0)?uac_send_tm_callback:NULL,
00388 (_uac_req.onreply>0)?(void*)(long)_uac_req.onreply:0
00389
00390 );
00391
00392 if(ret!=0)
00393 return -1;
00394 return 1;
00395 }
00396