Skip to content

Commit

Permalink
pv: $xavu(...) config variables implementation
Browse files Browse the repository at this point in the history
- 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(...)
  • Loading branch information
miconda committed Apr 1, 2020
1 parent 77ae0e2 commit af0d730
Show file tree
Hide file tree
Showing 3 changed files with 166 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/modules/pv/pv.c
Expand Up @@ -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,
Expand Down
157 changes: 157 additions & 0 deletions src/modules/pv/pv_xavp.c
Expand Up @@ -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"
Expand Down Expand Up @@ -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 changes: 6 additions & 0 deletions src/modules/pv/pv_xavp.h
Expand Up @@ -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);
Expand Down

0 comments on commit af0d730

Please sign in to comment.