diff --git a/src/core/mod_fix.h b/src/core/mod_fix.h index 8c2c766c1ef..043b1e35462 100644 --- a/src/core/mod_fix.h +++ b/src/core/mod_fix.h @@ -62,6 +62,8 @@ int fixup_get_svalue(struct sip_msg* msg, gparam_p gp, str *val); */ #define fixup_get_svalue(msg, fp, sval) get_str_fparam(sval, msg, fp) +#define fixup_get_bufvalue(msg, fp, sval) get_strbuf_fparam(sval, msg, fp) + /** get an int value out of a fparam_t. * * Note: this macro/function is for kamailio compatibility diff --git a/src/core/sr_module.c b/src/core/sr_module.c index d869b8ae631..154ce27740f 100644 --- a/src/core/sr_module.c +++ b/src/core/sr_module.c @@ -1727,6 +1727,92 @@ int get_str_fparam(str* dst, struct sip_msg* msg, fparam_t* param) } +/** Get the function parameter value as string cpoied in the dst->s buffer. + * - dst->len has to provide size of dst->s buffer and it is updated to the + * size of the value + * @return 0 - Success + * -1 - Cannot get value + */ +int get_strbuf_fparam(str* dst, struct sip_msg* msg, fparam_t* param) +{ + int_str val; + int ret; + avp_t* avp; + pv_value_t pv_val; + str sv = STR_NULL; + + if(dst==NULL || dst->s==NULL || dst->len<=0) { + return -1; + } + + switch(param->type) { + case FPARAM_REGEX: + case FPARAM_UNSPEC: + case FPARAM_INT: + return -1; + case FPARAM_STRING: + sv.s = param->v.asciiz; + sv.len = strlen(param->v.asciiz); + break; + case FPARAM_STR: + sv = param->v.str; + break; + case FPARAM_AVP: + avp = search_first_avp(param->v.avp.flags, param->v.avp.name, + &val, 0); + if (unlikely(!avp)) { + LM_DBG("Could not find AVP from function parameter '%s'\n", + param->orig); + return -1; + } + if (likely(avp->flags & AVP_VAL_STR)) { + sv = val.s; + } else { + /* The caller does not know of what type the AVP will be so + * convert int AVPs into string here + */ + sv.s = int2str(val.n, &sv.len); + } + break; + case FPARAM_SELECT: + ret = run_select(&sv, param->v.select, msg); + if (unlikely(ret < 0 || ret > 0)) return -1; + break; + case FPARAM_PVS: + if (likely((pv_get_spec_value(msg, param->v.pvs, &pv_val)==0) && + ((pv_val.flags&(PV_VAL_NULL|PV_VAL_STR))==PV_VAL_STR))){ + sv=pv_val.rs; + }else{ + LM_ERR("Could not convert PV to str\n"); + return -1; + } + break; + case FPARAM_PVE: + if (unlikely(pv_printf(msg, param->v.pve, dst->s, &dst->len)!=0)){ + LM_ERR("Could not convert the PV-formated string to str\n"); + dst->len=0; + return -1; + }; + break; + } + if(param->type != FPARAM_PVE) { + if(sv.len>=dst->len-1) { + LM_ERR("not enough space in output buffer (size: %d need: %d)\n", + dst->len, sv.len); + return -1; + } + if(sv.len > 0) { + memcpy(dst->s, sv.s, sv.len); + dst->len = sv.len; + dst->s[dst->len] = '\0'; + } else { + dst->len = 0; + dst->s[dst->len] = '\0'; + } + } + return 0; +} + /** Get the function parameter value as integer. * @return 0 - Success * -1 - Cannot get value diff --git a/src/core/sr_module.h b/src/core/sr_module.h index 7235c2840a2..ba6f54bd8df 100644 --- a/src/core/sr_module.h +++ b/src/core/sr_module.h @@ -489,6 +489,8 @@ int fixup_str_2(void** param, int param_no); */ int get_str_fparam(str* dst, struct sip_msg* msg, fparam_t* param); +int get_strbuf_fparam(str* dst, struct sip_msg* msg, fparam_t* param); + /** * @brief Get the function parameter value as integer * @param dst string destination