Module: kamailio Branch: master Commit: df1f5c02c003c77d0a902e6e4ba1115caa096ff3 URL: https://github.com/kamailio/kamailio/commit/df1f5c02c003c77d0a902e6e4ba1115caa096ff3
Author: Daniel-Constantin Mierla <[email protected]> Committer: Daniel-Constantin Mierla <[email protected]> Date: 2026-02-25T08:17:31+01:00 pv: extended string transformation with charat and byteat --- Modified: src/modules/pv/pv_trans.c Modified: src/modules/pv/pv_trans.h --- Diff: https://github.com/kamailio/kamailio/commit/df1f5c02c003c77d0a902e6e4ba1115caa096ff3.diff Patch: https://github.com/kamailio/kamailio/commit/df1f5c02c003c77d0a902e6e4ba1115caa096ff3.patch --- diff --git a/src/modules/pv/pv_trans.c b/src/modules/pv/pv_trans.c index c91737bd675..9e2915598d8 100644 --- a/src/modules/pv/pv_trans.c +++ b/src/modules/pv/pv_trans.c @@ -1707,6 +1707,49 @@ int tr_eval_string( val->flags = PV_TYPE_INT | PV_VAL_INT | PV_VAL_STR; break; + case TR_S_CHARAT: + case TR_S_BYTEAT: + if(tp == NULL) { + LM_ERR("charat/byteat invalid parameters (cfg line: %d)\n", + get_cfg_crt_line()); + return -1; + } + if(!(val->flags & PV_VAL_STR)) + val->rs.s = int2str(val->ri, &val->rs.len); + if(tp->type == TR_PARAM_NUMBER) { + i = tp->v.n; + } else { + if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v) != 0 + || (!(v.flags & PV_VAL_INT))) { + LM_ERR("cannot get p1 (cfg line: %d)\n", + get_cfg_crt_line()); + return -1; + } + i = v.ri; + } + if(subtype == TR_S_CHARAT) { + val->flags = PV_VAL_STR; + } else { + val->flags = PV_TYPE_INT | PV_VAL_INT | PV_VAL_STR; + } + val->ri = 0; + if(i < 0 || i >= val->rs.len) { + _tr_buffer[0] = '\0'; + val->rs.s = _tr_buffer; + val->rs.len = 0; + val->ri = -1; + break; + } + if(subtype == TR_S_CHARAT) { + _tr_buffer[0] = val->rs.s[i]; + _tr_buffer[1] = '\0'; + val->rs.len = 1; + } else { + val->ri = (long)val->rs.s[i]; + val->rs.s = int2str(val->ri, &val->rs.len); + } + break; + default: LM_ERR("unknown subtype %d (cfg line: %d)\n", subtype, get_cfg_crt_line()); @@ -3551,6 +3594,40 @@ char *tr_parse_string(str *in, trans_t *t) goto error; } goto done; + } else if(name.len == 6 && strncasecmp(name.s, "charat", 6) == 0) { + t->subtype = TR_S_CHARAT; + if(*p != TR_PARAM_MARKER) { + LM_ERR("invalid charat transformation: %.*s!\n", in->len, in->s); + goto error; + } + p++; + _tr_parse_nparam(p, p0, tp, spec, n, sign, in, s); + t->params = tp; + tp = 0; + while(*p && (*p == ' ' || *p == '\t' || *p == '\n')) + p++; + if(*p != TR_RBRACKET) { + LM_ERR("invalid charat transformation: %.*s!!\n", in->len, in->s); + goto error; + } + goto done; + } else if(name.len == 6 && strncasecmp(name.s, "byteat", 6) == 0) { + t->subtype = TR_S_BYTEAT; + if(*p != TR_PARAM_MARKER) { + LM_ERR("invalid byteat transformation: %.*s!\n", in->len, in->s); + goto error; + } + p++; + _tr_parse_nparam(p, p0, tp, spec, n, sign, in, s); + t->params = tp; + tp = 0; + while(*p && (*p == ' ' || *p == '\t' || *p == '\n')) + p++; + if(*p != TR_RBRACKET) { + LM_ERR("invalid byteat transformation: %.*s!!\n", in->len, in->s); + goto error; + } + goto done; } else if(name.len == 5 && strncasecmp(name.s, "crc32", 5) == 0) { t->subtype = TR_S_CRC32; goto done; diff --git a/src/modules/pv/pv_trans.h b/src/modules/pv/pv_trans.h index fa33d424ae1..380cf735ebd 100644 --- a/src/modules/pv/pv_trans.h +++ b/src/modules/pv/pv_trans.h @@ -112,7 +112,9 @@ enum _tr_s_subtype TR_S_RAFTER, TR_S_FMTLINES, TR_S_FMTLINET, - TR_S_CRC32 + TR_S_CRC32, + TR_S_CHARAT, + TR_S_BYTEAT }; enum _tr_uri_subtype { _______________________________________________ Kamailio - Development Mailing List -- [email protected] To unsubscribe send an email to [email protected] Important: keep the mailing list in the recipients, do not reply only to the sender!
