diff --git a/modules/cgrates/cgrates.c b/modules/cgrates/cgrates.c index b52d8375160..01f0bdafb88 100644 --- a/modules/cgrates/cgrates.c +++ b/modules/cgrates/cgrates.c @@ -40,6 +40,11 @@ #include "cgrates_common.h" #include "cgrates_engine.h" + +#define CGR_PV_NAME_NONE 0 /* used to determine if a name was not set */ +#define CGR_PV_NAME_STR 1 +#define CGR_PV_NAME_VAR 2 + int cgre_compat_mode = 0; int cgre_retry_tout = CGR_DEFAULT_RETRY_TIMEOUT; int cgrc_max_conns = CGR_DEFAULT_MAX_CONNS; @@ -105,8 +110,8 @@ static pv_export_t pvars[] = { pv_parse_cgr, pv_parse_idx_cgr, 0, 0}, { str_init("cgr_opt"), 2004, w_pv_get_cgr_opt, w_pv_set_cgr_opt, w_pv_parse_cgr, pv_parse_idx_cgr, 0, 0}, - { str_init("cgrret"), 2005, pv_get_cgr_reply, - 0, 0, 0, 0, 0}, + { str_init("cgrret"), 2005, pv_get_cgr_reply, 0, + pv_parse_cgr, 0, 0, 0}, { {0, 0}, 0, 0, 0, 0, 0, 0, 0 } }; @@ -359,7 +364,7 @@ static inline str *pv_get_idx_value(struct sip_msg *msg, pv_param_t *param) static pv_value_t idx_val; if (param->pvi.u.dval) { - if (param->pvi.type == PV_NAME_PVAR) { + if (param->pvi.type == CGR_PV_NAME_VAR) { if (pv_get_spec_value(msg, (pv_spec_p)param->pvi.u.dval, &idx_val) != 0) { LM_WARN("cannot get the tag of the cgr variable! " "using default\n"); @@ -394,7 +399,7 @@ static int pv_set_cgr(struct sip_msg *msg, pv_param_t *param, } /* first get the name of the field */ - if (param->pvn.type == PV_NAME_PVAR) { + if (param->pvn.type == CGR_PV_NAME_VAR) { if (pv_get_spec_value(msg, (pv_spec_p)param->pvn.u.dname, &name_val) != 0) { LM_ERR("cannot get the name of the cgr variable\n"); return -1; @@ -500,7 +505,7 @@ static int pv_get_cgr(struct sip_msg *msg, pv_param_t *param, return pv_get_null(msg, param, val); /* first get the name of the field */ - if (param->pvn.type == PV_NAME_PVAR) { + if (param->pvn.type == CGR_PV_NAME_VAR) { if (pv_get_spec_value(msg, (pv_spec_p)param->pvn.u.dname, &name_val) != 0) { LM_ERR("cannot get the name of the cgr variable\n"); return -1; @@ -522,7 +527,7 @@ static int pv_get_cgr(struct sip_msg *msg, pv_param_t *param, return pv_get_null(msg, param, val); if (kv->flags & CGR_KVF_TYPE_INT) { - val->rs.s = int2str(kv->value.n, &val->rs.len); + val->rs.s = sint2str(kv->value.n, &val->rs.len); val->flags = PV_VAL_STR|PV_VAL_INT|PV_TYPE_INT; } else if (kv->flags & CGR_KVF_TYPE_STR) { val->rs = kv->value.s; @@ -549,6 +554,8 @@ static int w_pv_get_cgr_opt(struct sip_msg *msg, pv_param_t *param, static int pv_get_cgr_reply(struct sip_msg *msg, pv_param_t *param, pv_value_t *val) { + str tmp; + struct cgr_kv *kv; struct cgr_local_ctx *ctx; if (!param || !val) { @@ -559,13 +566,41 @@ static int pv_get_cgr_reply(struct sip_msg *msg, pv_param_t *param, if (!(ctx = CGR_GET_LOCAL_CTX()) || !ctx->reply) return pv_get_null(msg, param, val); - if (ctx->reply_flags & CGR_KVF_TYPE_STR) { - val->rs = ctx->reply->s; - val->flags = PV_VAL_STR; + if (param->pvn.type == CGR_PV_NAME_NONE) { + if (ctx->reply_flags & CGR_KVF_TYPE_STR) { + val->rs = ctx->reply->s; + val->flags = PV_VAL_STR; + } else { + val->ri = ctx->reply->n; + val->flags = PV_VAL_INT|PV_TYPE_INT; + } } else { - val->rs.s = int2str(ctx->reply->n, &val->rs.len); - val->ri = ctx->reply->n; - val->flags = PV_VAL_STR|PV_VAL_INT|PV_TYPE_INT; + if (param->pvn.type == CGR_PV_NAME_VAR) { + if (pv_get_spec_value(msg, (pv_spec_p)param->pvn.u.dname, val) != 0) { + LM_ERR("cannot get the name of the $cgrret variable\n"); + return -1; + } + if (val->flags & PV_VAL_NULL || !(val->flags & PV_VAL_STR)) { + LM_ERR("invalid name for the $cgrret variable!\n"); + return -1; + } + tmp = val->rs; + } else + tmp = param->pvn.u.isname.name.s; + kv = cgr_get_local(tmp); + if (!kv) + return pv_get_null(msg, param, val); + if (kv->flags & CGR_KVF_TYPE_STR) { + val->rs = kv->value.s; + val->flags = PV_VAL_STR; + } else { + val->ri = kv->value.n; + val->flags = PV_VAL_INT|PV_TYPE_INT; + } + } + if (val->flags & PV_VAL_INT) { + val->rs.s = sint2str(val->ri, &val->rs.len); + val->flags |= PV_VAL_STR; } return 0; @@ -590,8 +625,8 @@ static int pv_parse_cgr(pv_spec_p sp, str *in) in->len, in->s); return -1; } - sp->pvp.pvn.u.dname = sp; - sp->pvp.pvn.type = PV_NAME_PVAR; + sp->pvp.pvn.u.dname = pv; + sp->pvp.pvn.type = CGR_PV_NAME_VAR; } else { /* we need to add the null terminator */ s = pkg_malloc(in->len + 1); @@ -604,7 +639,7 @@ static int pv_parse_cgr(pv_spec_p sp, str *in) sp->pvp.pvn.u.isname.name.s.s = s; sp->pvp.pvn.u.isname.name.s.len = in->len; - sp->pvp.pvn.type = PV_NAME_INTSTR; + sp->pvp.pvn.type = CGR_PV_NAME_STR; } return 0; } @@ -640,7 +675,7 @@ static int pv_parse_idx_cgr(pv_spec_p sp, str *in) return -1; } sp->pvp.pvi.u.dval = sp; - sp->pvp.pvi.type = PV_NAME_PVAR; + sp->pvp.pvi.type = CGR_PV_NAME_VAR; } else { /* we need to add the null terminator */ s = pkg_malloc(sizeof(str) + in->len); @@ -653,7 +688,7 @@ static int pv_parse_idx_cgr(pv_spec_p sp, str *in) s->len = in->len; sp->pvp.pvi.u.dval = s; - sp->pvp.pvi.type = PV_NAME_INTSTR; + sp->pvp.pvi.type = CGR_PV_NAME_STR; } return 0; }