From 3cffe8789fd14baef4ff548bb2afc5b2ca9ed66e Mon Sep 17 00:00:00 2001 From: Julien Chavanton Date: Fri, 20 Sep 2019 21:57:46 -0700 Subject: [PATCH 1/2] core: adding xavp_clone_level_nodata_with_new_name --- src/core/xavp.c | 11 ++++++++--- src/core/xavp.h | 1 + 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/core/xavp.c b/src/core/xavp.c index e5e33f6e9df..f279def1ede 100644 --- a/src/core/xavp.c +++ b/src/core/xavp.c @@ -693,11 +693,16 @@ struct str_list *xavp_get_list_key_names(sr_xavp_t *xavp) return result; } +sr_xavp_t *xavp_clone_level_nodata(sr_xavp_t *xold) +{ + return xavp_clone_level_nodata_with_new_name(xold, &xold->name); +} + /** * clone the xavp without values that are custom data * - only one list level is cloned, other sublists are ignored */ -sr_xavp_t *xavp_clone_level_nodata(sr_xavp_t *xold) +sr_xavp_t *xavp_clone_level_nodata_with_new_name(sr_xavp_t *xold, str *dst_name) { sr_xavp_t *xnew = NULL; sr_xavp_t *navp = NULL; @@ -713,13 +718,13 @@ sr_xavp_t *xavp_clone_level_nodata(sr_xavp_t *xold) LM_INFO("xavp value type is 'data' - ignoring in clone\n"); return NULL; } - xnew = xavp_new_value(&xold->name, &xold->val); + xnew = xavp_new_value(dst_name, &xold->val); if(xnew==NULL) { LM_ERR("cannot create cloned root xavp\n"); return NULL; } - LM_DBG("cloned root xavp [%.*s]\n", xold->name.len, xold->name.s); + LM_DBG("cloned root xavp [%.*s] >> [%.*s]\n", xold->name.len, xold->name.s, dst_name->len, dst_name->s); if(xold->val.type!=SR_XTYPE_XAVP) { diff --git a/src/core/xavp.h b/src/core/xavp.h index 071a421a4a3..85c4bb3a3d1 100644 --- a/src/core/xavp.h +++ b/src/core/xavp.h @@ -102,6 +102,7 @@ sr_xavp_t *xavp_extract(str *name, sr_xavp_t **list); void xavp_print_list(sr_xavp_t **head); sr_xavp_t *xavp_clone_level_nodata(sr_xavp_t *xold); +sr_xavp_t *xavp_clone_level_nodata_with_new_name(sr_xavp_t *xold, str *dst_name); sr_xavp_t* xavp_get_child(str *rname, str *cname); sr_xavp_t* xavp_get_child_with_ival(str *rname, str *cname); From e38165575c5e05e871fd3eb89973b385c2146539 Mon Sep 17 00:00:00 2001 From: Julien Chavanton Date: Fri, 20 Sep 2019 18:33:37 -0700 Subject: [PATCH 2/2] pv: adding xavp_copy --- src/modules/pv/doc/pv_admin.xml | 43 ++++++++++++++++++++++ src/modules/pv/pv.c | 65 +++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) diff --git a/src/modules/pv/doc/pv_admin.xml b/src/modules/pv/doc/pv_admin.xml index c563f90d6fd..6c380ce141b 100644 --- a/src/modules/pv/doc/pv_admin.xml +++ b/src/modules/pv/doc/pv_admin.xml @@ -261,6 +261,49 @@ if (typeof("$var(foo)", "str")) { if (not_empty("$var(foo)")) { append_hf("X-Foo: $var(foo)\r\n"); } +... + + + +
+ + <function moreinfo="none">xavp_copy(source_name, source_index, destination_name)</function> + + + Copy one XAVP. + + + The parameters can be variables or strings. + First parameter is the source XAVP name. + Second parameter is the source XAVP stack index, use 0 to copy the last assigned XAVP. + Third parameter is the destination XAVP name, if found the XAVP will be appended else it will be created. + + + Function can be used from ANY ROUTE. + + + <function>xavp_copy</function> usage + +... +# Using xavp_copy to reorder an existing xavp stack +$xavp(a=>x) = "a-0-x"; +$xavp(a[0]=>y) = "a-0-y"; +$xavp(a=>x) = "a-1-x"; +$xavp(a[0]=>y) = "a-1-y"; +xinfo("$$xavp(a[0]) = [$xavp(a[0]=>x)][$xavp(a[0]=>y)]\n"); +xinfo("$$xavp(a[1]) = [$xavp(a[1]=>x)][$xavp(a[1]=>y)]\n"); +# reorder +$var(source_index) = 1; +$var(destination_name) = "b"; +xavp_copy("a", "$var(source_index)", "$var(destination_name)"); +xavp_copy("a", "0", "$var(destination_name)"); +xinfo("reordered: $$xavp(b[0]) = [$xavp(b[0]=>x)][$xavp(b[0]=>y)]\n"); +xinfo("reordered: $$xavp(b[1]) = [$xavp(b[1]=>x)][$xavp(b[1]=>y)]\n"); +# results in: +# INFO: $xavp(a[0]) = [a-1-x][a-1-y] +# INFO: $xavp(a[1]) = [a-0-x][a-0-y] +# INFO: reordered: $xavp(b[0]) = [a-0-x][a-0-y] +# INFO: reordered: $xavp(b[1]) = [a-1-x][a-1-y] ... diff --git a/src/modules/pv/pv.c b/src/modules/pv/pv.c index 310acf53d03..8f47a5934c9 100644 --- a/src/modules/pv/pv.c +++ b/src/modules/pv/pv.c @@ -535,6 +535,7 @@ static int pv_unset(struct sip_msg* msg, char* pvid, char *foo); static int is_int(struct sip_msg* msg, char* pvar, char* s2); static int pv_typeof(sip_msg_t *msg, char *pv, char *t); static int pv_not_empty(sip_msg_t *msg, char *pv, char *s2); +static int w_xavp_copy(sip_msg_t *msg, char *src_name, char *src_idx, char *dst_name); static int w_xavp_params_explode(sip_msg_t *msg, char *pparams, char *pxname); static int w_xavp_params_implode(sip_msg_t *msg, char *pxname, char *pvname); static int w_xavp_child_seti(sip_msg_t *msg, char *prname, char *pcname, @@ -549,6 +550,7 @@ static int w_sbranch_reset(sip_msg_t *msg, char p1, char *p2); static int w_var_to_xavp(sip_msg_t *msg, char *p1, char *p2); static int w_xavp_to_var(sip_msg_t *msg, char *p1); +int pv_xavp_copy_fixup(void** param, int param_no); int pv_evalx_fixup(void** param, int param_no); int w_pv_evalx(struct sip_msg *msg, char *dst, str *fmt); @@ -580,6 +582,8 @@ static cmd_export_t cmds[]={ {"xavp_params_explode", (cmd_function)w_xavp_params_explode, 2, fixup_spve_spve, fixup_free_spve_spve, ANY_ROUTE}, + {"xavp_copy", (cmd_function)w_xavp_copy, 3, pv_xavp_copy_fixup, 0, + ANY_ROUTE}, {"xavp_params_implode", (cmd_function)w_xavp_params_implode, 2, fixup_spve_str, fixup_free_spve_str, ANY_ROUTE}, @@ -811,6 +815,57 @@ static int ki_xavp_print(sip_msg_t* msg) return 1; } +/** + * + */ +static int w_xavp_copy(sip_msg_t *msg, char *_src_name, char *_src_idx, char *_dst_name) +{ + str src_name; + int src_idx; + str dst_name; + if(get_str_fparam(&src_name, msg, (gparam_p)_src_name) != 0) { + LM_ERR("xavp_copy: missing source\n"); + return -1; + } + if(get_str_fparam(&dst_name, msg, (gparam_p)_dst_name) != 0) { + LM_ERR("xavp_copy: missing destination\n"); + return -1; + } + if(get_int_fparam(&src_idx, msg, (gparam_t*)_src_idx)<0) { + LM_ERR("failed to get the src_idx value\n"); + return -1; + } + sr_xavp_t *src_xavp = xavp_get_by_index(&src_name, src_idx, NULL); + if(!src_xavp) { + LM_ERR("xavp_copy: missing can not find source xavp [%.*s]\n", src_name.len, src_name.s); + return -1; + } + // Check if destination exist, if it does we will append, similar to XAVP assigment + sr_xavp_t *dst_xavp = xavp_get(&dst_name, NULL); + sr_xavp_t *new_xavp = xavp_clone_level_nodata_with_new_name(src_xavp, &dst_name); + if (!new_xavp) { + LM_ERR("error cloning xavp\n"); + return -1; + } + if (!dst_xavp) { + LM_DBG("xavp_copy(new): $xavp(%.*s[%d]) >> $xavp(%.*s)\n", src_name.len, src_name.s, src_idx, dst_name.len, dst_name.s); + if(xavp_add(new_xavp, NULL)<0) { + LM_ERR("error adding new xavp\n"); + xavp_destroy_list(&dst_xavp); + return -1; + } + } else { + LM_DBG("xavp_copy(append): $xavp(%.*s[%d]) >> $xavp(%.*s)\n", src_name.len, src_name.s, src_idx, dst_name.len, dst_name.s); + if(xavp_add_last(new_xavp, &dst_xavp)<0) { + LM_ERR("error appending new xavp\n"); + xavp_destroy_list(&dst_xavp); + return -1; + } + } + return 1; +} + + /** * */ @@ -1365,6 +1420,16 @@ static int ki_sbranch_reset(sip_msg_t *msg) return 1; } +int pv_xavp_copy_fixup(void **param, int param_no) +{ + if(param_no == 1 || param_no == 3) + return fixup_var_str_12(param, param_no); + if (param_no == 2) + return fixup_var_int_12(param, param_no); + LM_ERR("invalid parameter count [%d]\n", param_no); + return -1; +} + int pv_evalx_fixup(void** param, int param_no) { pv_spec_t *spec=NULL;