diff --git a/src/modules/pv/pv.c b/src/modules/pv/pv.c index a233a684cfe..fd123a42a31 100644 --- a/src/modules/pv/pv.c +++ b/src/modules/pv/pv.c @@ -93,6 +93,9 @@ static pv_export_t mod_pvs[] = { { {"xavp", sizeof("xavp")-1}, /* xavp */ PVT_XAVP, pv_get_xavp, pv_set_xavp, pv_parse_xavp_name, 0, 0, 0 }, + { {"xavu", sizeof("xavu")-1}, /* xavu */ + PVT_XAVU, pv_get_xavu, pv_set_xavu, + pv_parse_xavp_name, 0, 0, 0 }, {{"avp", (sizeof("avp")-1)}, PVT_AVP, pv_get_avp, pv_set_avp, pv_parse_avp_name, pv_parse_index, 0, 0}, {{"hdr", (sizeof("hdr")-1)}, PVT_HDR, pv_get_hdr, 0, pv_parse_hdr_name, diff --git a/src/modules/pv/pv_xavp.c b/src/modules/pv/pv_xavp.c index 9dca116a42c..5b14b1a3a7b 100644 --- a/src/modules/pv/pv_xavp.c +++ b/src/modules/pv/pv_xavp.c @@ -19,6 +19,7 @@ #include "../../core/dprint.h" #include "../../core/xavp.h" #include "../../core/pvapi.h" +#include "../../core/trim.h" #include "../../core/parser/parse_param.h" #include "pv_xavp.h" @@ -759,3 +760,159 @@ int pv_xavp_to_var(str *xname) { } while(xavp); return 1; } + +void pv_xavu_name_destroy(pv_xavu_name_t *xname) +{ + return; +} + +int pv_parse_xavu_name(pv_spec_t *sp, str *in) +{ + pv_xavu_name_t *xname=NULL; + str s; + int i; + + if(in->s==NULL || in->len<=0) + return -1; + + xname = (pv_xavu_name_t*)pkg_malloc(sizeof(pv_xavu_name_t)); + if(xname==NULL) { + LM_ERR("not enough pkg mem\n"); + return -1; + } + + memset(xname, 0, sizeof(pv_xavu_name_t)); + + s = *in; + trim(&s); + xname->name.s = s.s; + xname->name.len = s.len; + for(i=0; i') { + goto error; + } + i++; + + LM_DBG("xavp sublist [%.*s] - key [%.*s]\n", xname->name.len, + xname->name.s, s.len - i, s.s + i); + + xname->next = (pv_xavu_name_t*)pkg_malloc(sizeof(pv_xavu_name_t)); + if(xname->next==NULL) { + LM_ERR("not enough pkg mem\n"); + goto error; + } + memset(xname->next, 0, sizeof(pv_xavu_name_t)); + + xname->next->name.s = s.s + i; + xname->next->name.len = s.len - i; + +done: + sp->pvp.pvn.u.dname = (void*)xname; + sp->pvp.pvn.type = PV_NAME_PVAR; + return 0; + +error: + if(xname!=NULL) { + pv_xavu_name_destroy(xname); + pkg_free(xname); + } + return -1; +} + +int pv_get_xavu(struct sip_msg *msg, pv_param_t *param, + pv_value_t *res) +{ + pv_xavu_name_t *xname=NULL; + sr_xavp_t *avu=NULL; + + if(param==NULL) { + LM_ERR("bad parameters\n"); + return -1; + } + xname = (pv_xavu_name_t*)param->pvn.u.dname; + + avu = xavu_lookup(&xname->name, NULL); + if(avu==NULL) { + return pv_get_null(msg, param, res); + } + if(xname->next==NULL) { + return pv_xavp_get_value(msg, param, res, avu); + } + if(avu->val.type != SR_XTYPE_XAVP) { + return pv_get_null(msg, param, res); + } + + avu = xavu_lookup(&xname->next->name, &avu->val.v.xavp); + if(avu==NULL) { + return pv_get_null(msg, param, res); + } + return pv_xavp_get_value(msg, param, res, avu); +} + +/** + * $xavu(name1=>name2) + */ +int pv_set_xavu(struct sip_msg* msg, pv_param_t *param, + int op, pv_value_t *val) +{ + pv_xavu_name_t *xname=NULL; + sr_xavp_t *avu=NULL; + sr_xval_t xval; + + if(param==NULL) { + LM_ERR("bad parameters\n"); + return -1; + } + xname = (pv_xavu_name_t*)param->pvn.u.dname; + + if((val==NULL) || (val->flags&PV_VAL_NULL)) { + if(xname->next==NULL) { + xavu_rm_by_name(&xname->name, NULL); + return 0; + } + + avu = xavu_lookup(&xname->name, NULL); + if(avu!=NULL && avu->val.type==SR_XTYPE_XAVP) { + xavu_rm_by_name(&xname->next->name, &avu->val.v.xavp); + } + return 0; + } /* NULL assignment */ + + /* build xavp value */ + memset(&xval, 0, sizeof(sr_xval_t)); + + if(val->flags&PV_TYPE_INT) { + xval.type = SR_XTYPE_INT; + xval.v.i = val->ri; + } else { + xval.type = SR_XTYPE_STR; + xval.v.s = val->rs; + } + + if(xname->next==NULL) { + /* set root xavu value */ + if(xavu_set_xval(&xname->name, &xval, NULL)==NULL) { + return -1; + } + return 0; + } + + /* set child xavu value */ + if(xavu_set_child_xval(&xname->name, &xname->next->name, &xval)==NULL) { + return -1; + } + return 0; +} diff --git a/src/modules/pv/pv_xavp.h b/src/modules/pv/pv_xavp.h index 35c410931e6..6f2e9f474b2 100644 --- a/src/modules/pv/pv_xavp.h +++ b/src/modules/pv/pv_xavp.h @@ -26,6 +26,12 @@ int pv_set_xavp(struct sip_msg* msg, pv_param_t *param, int op, pv_value_t *val); int pv_parse_xavp_name(pv_spec_p sp, str *in); +int pv_get_xavu(struct sip_msg *msg, pv_param_t *param, + pv_value_t *res); +int pv_set_xavu(struct sip_msg* msg, pv_param_t *param, + int op, pv_value_t *val); +int pv_parse_xavu_name(pv_spec_p sp, str *in); + int pv_xavp_print(struct sip_msg* msg, char* s1, char *s2); int xavp_params_explode(str *params, str *xname);