Przeglądaj źródła

pv: adding xavp_copy with destination index

Julien Chavanton 6 lat temu
rodzic
commit
a6b114162e
2 zmienionych plików z 112 dodań i 16 usunięć
  1. 48 2
      src/modules/pv/doc/pv_admin.xml
  2. 64 14
      src/modules/pv/pv.c

+ 48 - 2
src/modules/pv/doc/pv_admin.xml

@@ -270,7 +270,7 @@ if (not_empty("$var(foo)")) {
 				<function moreinfo="none">xavp_copy(source_name, source_index, destination_name)</function>
 				<function moreinfo="none">xavp_copy(source_name, source_index, destination_name)</function>
 			</title>
 			</title>
 			<para>
 			<para>
-				Copy one XAVP.
+				Copy and append one XAVP.
 			</para>
 			</para>
 			<para>
 			<para>
 				The parameters can be variables or strings.
 				The parameters can be variables or strings.
@@ -285,13 +285,14 @@ if (not_empty("$var(foo)")) {
 				<title><function>xavp_copy</function> usage</title>
 				<title><function>xavp_copy</function> usage</title>
 				<programlisting format="linespecific">
 				<programlisting format="linespecific">
 ...
 ...
-# Using xavp_copy to reorder an existing xavp stack
+# Using xavp_copy to reorder an existing xavp stack in a new one
 $xavp(a=&gt;x) = "a-0-x";
 $xavp(a=&gt;x) = "a-0-x";
 $xavp(a[0]=&gt;y) = "a-0-y";
 $xavp(a[0]=&gt;y) = "a-0-y";
 $xavp(a=&gt;x) = "a-1-x";
 $xavp(a=&gt;x) = "a-1-x";
 $xavp(a[0]=&gt;y) = "a-1-y";
 $xavp(a[0]=&gt;y) = "a-1-y";
 xinfo("$$xavp(a[0]) = [$xavp(a[0]=&gt;x)][$xavp(a[0]=&gt;y)]\n");
 xinfo("$$xavp(a[0]) = [$xavp(a[0]=&gt;x)][$xavp(a[0]=&gt;y)]\n");
 xinfo("$$xavp(a[1]) = [$xavp(a[1]=&gt;x)][$xavp(a[1]=&gt;y)]\n");
 xinfo("$$xavp(a[1]) = [$xavp(a[1]=&gt;x)][$xavp(a[1]=&gt;y)]\n");
+
 # reorder
 # reorder
 $var(source_index) = 1;
 $var(source_index) = 1;
 $var(destination_name) = "b";
 $var(destination_name) = "b";
@@ -299,11 +300,56 @@ xavp_copy("a", "$var(source_index)", "$var(destination_name)");
 xavp_copy("a", "0", "$var(destination_name)");
 xavp_copy("a", "0", "$var(destination_name)");
 xinfo("reordered: $$xavp(b[0]) = [$xavp(b[0]=&gt;x)][$xavp(b[0]=&gt;y)]\n");
 xinfo("reordered: $$xavp(b[0]) = [$xavp(b[0]=&gt;x)][$xavp(b[0]=&gt;y)]\n");
 xinfo("reordered: $$xavp(b[1]) = [$xavp(b[1]=&gt;x)][$xavp(b[1]=&gt;y)]\n");
 xinfo("reordered: $$xavp(b[1]) = [$xavp(b[1]=&gt;x)][$xavp(b[1]=&gt;y)]\n");
+
 # results in:
 # results in:
 # INFO: $xavp(a[0]) = [a-1-x][a-1-y]
 # INFO: $xavp(a[0]) = [a-1-x][a-1-y]
 # INFO: $xavp(a[1]) = [a-0-x][a-0-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[0]) = [a-0-x][a-0-y]
 # INFO: reordered: $xavp(b[1]) = [a-1-x][a-1-y]
 # INFO: reordered: $xavp(b[1]) = [a-1-x][a-1-y]
+...
+				</programlisting>
+			</example>
+		</section>
+		<section id="pv.f.xavp_copy">
+			<title>
+				<function moreinfo="none">xavp_copy(source_name, source_index, destination_name, destination_index)</function>
+			</title>
+			<para>
+				Copy and replace one XAVP.
+			</para>
+			<para>
+				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.
+			</para>
+			<para>
+			Function can be used from ANY ROUTE.
+			</para>
+			<example>
+				<title><function>xavp_copy</function> usage</title>
+				<programlisting format="linespecific">
+...
+# Using xavp_copy to reorder an existing xavp stack inplace
+$xavp(a=>x) = "a-0-x";
+$xavp(a[0]=&gt;y) = "a-0-y";
+$xavp(a=>x) = "a-1-x";
+$xavp(a[0]=&gt;y) = "a-1-y";
+$xavp(a=>x) = "a-2-x";
+$xavp(a[0]=&gt;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]
 ...
 ...
 				</programlisting>
 				</programlisting>
 			</example>
 			</example>

+ 64 - 14
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_typeof(sip_msg_t *msg, char *pv, char *t);
 static int pv_not_empty(sip_msg_t *msg, char *pv, char *s2);
 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(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_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_params_implode(sip_msg_t *msg, char *pxname, char *pvname);
 static int w_xavp_child_seti(sip_msg_t *msg, char *prname, char *pcname,
 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},
 		ANY_ROUTE},
 	{"xavp_copy", (cmd_function)w_xavp_copy, 3, pv_xavp_copy_fixup, 0,
 	{"xavp_copy", (cmd_function)w_xavp_copy, 3, pv_xavp_copy_fixup, 0,
 		ANY_ROUTE},
 		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,
 	{"xavp_params_implode", (cmd_function)w_xavp_params_implode,
 		2, fixup_spve_str, fixup_free_spve_str,
 		2, fixup_spve_str, fixup_free_spve_str,
 		ANY_ROUTE},
 		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)
 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;
 	str src_name;
 	int src_idx;
 	int src_idx;
 	str dst_name;
 	str dst_name;
+	int dst_idx;
+
 	if(get_str_fparam(&src_name, msg, (gparam_p)_src_name) != 0) {
 	if(get_str_fparam(&src_name, msg, (gparam_p)_src_name) != 0) {
 		LM_ERR("xavp_copy: missing source\n");
 		LM_ERR("xavp_copy: missing source\n");
 		return -1;
 		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);
 		LM_ERR("xavp_copy: missing can not find source xavp [%.*s]\n", src_name.len, src_name.s);
 		return -1;
 		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);
 	sr_xavp_t *new_xavp = xavp_clone_level_nodata_with_new_name(src_xavp, &dst_name);
 	if (!new_xavp) {
 	if (!new_xavp) {
 		LM_ERR("error cloning xavp\n");
 		LM_ERR("error cloning xavp\n");
 		return -1;
 		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;
 			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;
 			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;
 	return 1;
 }
 }
 
 
-
 /**
 /**
  *
  *
  */
  */
@@ -1424,7 +1474,7 @@ int pv_xavp_copy_fixup(void **param, int param_no)
 {
 {
 	if(param_no == 1 || param_no == 3)
 	if(param_no == 1 || param_no == 3)
 		return fixup_var_str_12(param, param_no);
 		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);
 		return fixup_var_int_12(param, param_no);
 	LM_ERR("invalid parameter count [%d]\n", param_no);
 	LM_ERR("invalid parameter count [%d]\n", param_no);
 	return -1;
 	return -1;