From a6b114162ea830863abbd196508d4913060f3f07 Mon Sep 17 00:00:00 2001 From: Julien Chavanton Date: Mon, 30 Sep 2019 11:07:53 -0700 Subject: [PATCH] pv: adding xavp_copy with destination index --- src/modules/pv/doc/pv_admin.xml | 50 ++++++++++++++++++++- src/modules/pv/pv.c | 78 +++++++++++++++++++++++++++------ 2 files changed, 112 insertions(+), 16 deletions(-) diff --git a/src/modules/pv/doc/pv_admin.xml b/src/modules/pv/doc/pv_admin.xml index 6c380ce141b..c66f14df67c 100644 --- a/src/modules/pv/doc/pv_admin.xml +++ b/src/modules/pv/doc/pv_admin.xml @@ -270,7 +270,7 @@ if (not_empty("$var(foo)")) { xavp_copy(source_name, source_index, destination_name) - Copy one XAVP. + Copy and append one XAVP. The parameters can be variables or strings. @@ -285,13 +285,14 @@ if (not_empty("$var(foo)")) { <function>xavp_copy</function> usage ... -# Using xavp_copy to reorder an existing xavp stack +# Using xavp_copy to reorder an existing xavp stack in a new one $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"; @@ -299,11 +300,56 @@ 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] +... + + + +
+ + <function moreinfo="none">xavp_copy(source_name, source_index, destination_name, destination_index)</function> + + + Copy and replace 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 not found xavp_copy will return -1. + Fourth parameter is the destination XAVP index, if not found xavp_copy will return -1. + + + Function can be used from ANY ROUTE. + + + <function>xavp_copy</function> usage + +... +# Using xavp_copy to reorder an existing xavp stack inplace +$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"; +$xavp(a=>x) = "a-2-x"; +$xavp(a[0]=>y) = "a-2-y"; + +# INFO: NEW $xavp(a[0]) = [a-2-x][a-2-y] +# INFO: NEW $xavp(a[1]) = [a-1-x][a-1-y] +# INFO: NEW $xavp(a[2]) = [a-0-x][a-0-y] + +xavp_copy("a", "1", "c"); +xavp_copy("a", "2", "a", "1"); +xavp_copy("c", "0", "a", "2"); + +# INFO: AFTER $xavp(a[0]) = [a-2-x][a-2-y] +# INFO: AFTER $xavp(a[1]) = [a-0-x][a-0-y] +# INFO: AFTER $xavp(a[2]) = [a-1-x][a-1-y] ... diff --git a/src/modules/pv/pv.c b/src/modules/pv/pv.c index 8f47a5934c9..67727fabba7 100644 --- a/src/modules/pv/pv.c +++ b/src/modules/pv/pv.c @@ -536,6 +536,7 @@ 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_copy_dst(sip_msg_t *msg, char *src_name, char *src_idx, char *dst_name, char *dst_idx); 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, @@ -584,6 +585,8 @@ static cmd_export_t cmds[]={ ANY_ROUTE}, {"xavp_copy", (cmd_function)w_xavp_copy, 3, pv_xavp_copy_fixup, 0, ANY_ROUTE}, + {"xavp_copy", (cmd_function)w_xavp_copy_dst, 4, 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}, @@ -819,10 +822,20 @@ static int ki_xavp_print(sip_msg_t* msg) * */ static int w_xavp_copy(sip_msg_t *msg, char *_src_name, char *_src_idx, char *_dst_name) +{ + return w_xavp_copy_dst(msg, _src_name, _src_idx, _dst_name, NULL); +} + +/** + * + */ +static int w_xavp_copy_dst(sip_msg_t *msg, char *_src_name, char *_src_idx, char *_dst_name, char *_dst_idx) { str src_name; int src_idx; str dst_name; + int dst_idx; + if(get_str_fparam(&src_name, msg, (gparam_p)_src_name) != 0) { LM_ERR("xavp_copy: missing source\n"); return -1; @@ -840,32 +853,69 @@ static int w_xavp_copy(sip_msg_t *msg, char *_src_name, char *_src_idx, char *_d 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 *dst_xavp = NULL; + LM_DBG("xavp_copy: dst_name xavp [%.*s]\n", dst_name.len, dst_name.s); 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); + + if (_dst_idx) { + if(get_int_fparam(&dst_idx, msg, (gparam_t*)_dst_idx)<0) { + LM_ERR("failed to get the dst_idx value\n"); 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); + dst_xavp = xavp_get_by_index(&dst_name, dst_idx, NULL); + if(!dst_xavp) { + LM_ERR("xavp_copy: missing can not find destination xavp [%.*s]\n", dst_name.len, dst_name.s); + xavp_destroy_list(&new_xavp); + return -1; + } + + LM_DBG("xavp_copy(replace): $xavp(%.*s[%d]) >> $xavp(%.*s[%d])\n", src_name.len, src_name.s, src_idx, dst_name.len, dst_name.s, dst_idx); + if(dst_idx == 0) { + if(xavp_add(new_xavp, NULL)<0) { + LM_ERR("error adding new xavp\n"); + xavp_destroy_list(&new_xavp); + return -1; + } + } else { + sr_xavp_t *prev_xavp = xavp_get_by_index(&dst_name, dst_idx-1, NULL); + if(!prev_xavp) { + LM_ERR("error inserting xavp, parent not found $xavp(%.*s[%d])\n", dst_name.len, dst_name.s, dst_idx); + xavp_destroy_list(&new_xavp); + return -1; + } + xavp_add_after(new_xavp, prev_xavp); + } + if(xavp_rm(dst_xavp, NULL)<0) { + LM_ERR("can not remove the exiting index $xavp(%.*s[%d])\n", dst_name.len, dst_name.s, dst_idx); return -1; } + } else { + // Check if destination exist, if it does we will append, similar to XAVP assigment + dst_xavp = xavp_get(&dst_name, NULL); + 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; } - /** * */ @@ -1424,7 +1474,7 @@ 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) + if (param_no == 2 || param_no == 4) return fixup_var_int_12(param, param_no); LM_ERR("invalid parameter count [%d]\n", param_no); return -1;