Module: kamailio
Branch: 6.0
Commit: 280ca8288c7a64fedfb0e7be321fc74fe7c095da
URL: 
https://github.com/kamailio/kamailio/commit/280ca8288c7a64fedfb0e7be321fc74fe7c095da

Author: Daniel-Constantin Mierla <[email protected]>
Committer: Daniel-Constantin Mierla <[email protected]>
Date: 2026-03-05T15:20:42+01:00

pv: extended string transformation with charat and byteat

(cherry picked from commit df1f5c02c003c77d0a902e6e4ba1115caa096ff3)
(cherry picked from commit 4ed2c55c4cfc8bd8d66b352775d9c5f1f0252ef7)

---

Modified: src/modules/pv/pv_trans.c
Modified: src/modules/pv/pv_trans.h

---

Diff:  
https://github.com/kamailio/kamailio/commit/280ca8288c7a64fedfb0e7be321fc74fe7c095da.diff
Patch: 
https://github.com/kamailio/kamailio/commit/280ca8288c7a64fedfb0e7be321fc74fe7c095da.patch

---

diff --git a/src/modules/pv/pv_trans.c b/src/modules/pv/pv_trans.c
index f3432b13eaa..073c4b75bc2 100644
--- a/src/modules/pv/pv_trans.c
+++ b/src/modules/pv/pv_trans.c
@@ -1574,6 +1574,49 @@ int tr_eval_string(
                        val->rs.s[val->rs.len] = '\0';
                        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());
@@ -3276,6 +3319,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;
        }
 
        LM_ERR("unknown transformation: %.*s/%.*s/%d!\n", in->len, in->s, 
name.len,
diff --git a/src/modules/pv/pv_trans.h b/src/modules/pv/pv_trans.h
index 7db512f0949..b408dbed8e8 100644
--- a/src/modules/pv/pv_trans.h
+++ b/src/modules/pv/pv_trans.h
@@ -105,7 +105,9 @@ enum _tr_s_subtype
        TR_S_RBEFORE,
        TR_S_RAFTER,
        TR_S_FMTLINES,
-       TR_S_FMTLINET
+       TR_S_FMTLINET,
+       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!

Reply via email to