Bläddra i källkod

pv: $xavu(...) config variables implementation

- single (unique) value variables similar to $xavp(...)
- support for root list values: $xavu(x)
- support for child list values: $xavu(x=>y)
- values can be int or string
- assign to $null deletes the $xavu(...)
Daniel-Constantin Mierla 5 år sedan
förälder
incheckning
af0d730fd8
3 ändrade filer med 166 tillägg och 0 borttagningar
  1. 3 0
      src/modules/pv/pv.c
  2. 157 0
      src/modules/pv/pv_xavp.c
  3. 6 0
      src/modules/pv/pv_xavp.h

+ 3 - 0
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,

+ 157 - 0
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<s.len; i++) {
+		if(s.s[i] == '=') {
+			break;
+		}
+	}
+	if(i==s.len) {
+		goto done;
+	}
+	if(i>=s.len-2) {
+		goto error;
+	}
+	xname->name.len = i;
+
+	i++;
+	if(s.s[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;
+}

+ 6 - 0
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);