Module: kamailio Branch: master Commit: 3ee78cbdf6c01aaf1c3b1dd32f12396d77519a3b URL: https://github.com/kamailio/kamailio/commit/3ee78cbdf6c01aaf1c3b1dd32f12396d...
Author: Daniel-Constantin Mierla miconda@gmail.com Committer: Daniel-Constantin Mierla miconda@gmail.com Date: 2025-07-10T10:51:05+02:00
tm: added rpc command tm.t_uac_attrs
- combine the variants of tm.t_uac_* by providing first parameter with attributes in the format 'name=value;...'
---
Modified: src/modules/tm/rpc_uac.c Modified: src/modules/tm/rpc_uac.h Modified: src/modules/tm/tm.c
---
Diff: https://github.com/kamailio/kamailio/commit/3ee78cbdf6c01aaf1c3b1dd32f12396d... Patch: https://github.com/kamailio/kamailio/commit/3ee78cbdf6c01aaf1c3b1dd32f12396d...
---
diff --git a/src/modules/tm/rpc_uac.c b/src/modules/tm/rpc_uac.c index dfd038a3f2c..19b9b528a5c 100644 --- a/src/modules/tm/rpc_uac.c +++ b/src/modules/tm/rpc_uac.c @@ -1004,6 +1004,68 @@ void rpc_t_uac_wait_block_noack_hex(rpc_t *rpc, void *c) rpc_t_uac(rpc, c, 2, TMCB_DONT_ACK, 1); }
+/** t_uac with attributes. + * @see rpc_t_uac. + */ +void rpc_t_uac_attrs(rpc_t *rpc, void *c) +{ + tm_rpc_uac_attrs_t tattrs; + str sattrs = STR_NULL; + param_t *params_list = NULL; + param_hooks_t phooks; + param_t *pit = NULL; + int ival = 0; + int ret; + + memset(&tattrs, 0, sizeof(tm_rpc_uac_attrs_t)); + + ret = rpc->scan(c, "SSSSSS*S", &sattrs, &tattrs.method, &tattrs.ruri, + &tattrs.nexthop, &tattrs.send_socket, &tattrs.headers, + &tattrs.body); + if(ret < 6 && !(-ret == 6)) { + rpc->fault(c, 400, "too few parameters (%d/5)", ret ? ret : -ret); + return; + } + if(sattrs.len > 0) { + if(sattrs.s[sattrs.len - 1] == ';') { + sattrs.len--; + } + if(parse_params(&sattrs, CLASS_ANY, &phooks, ¶ms_list) < 0) { + return; + } + for(pit = params_list; pit; pit = pit->next) { + if(pit->name.len == 5 + && strncasecmp(pit->name.s, "reply", 5) == 0) { + if(pit->body.len == 4 + && strncasecmp(pit->name.s, "wait", 4) == 0) { + tattrs.reply_wait = 1; + } else if(pit->body.len == 5 + && strncasecmp(pit->name.s, "block", 5) == 0) { + tattrs.reply_wait = 2; + } else { + LM_ERR("unknown reply attribute value\n"); + } + } else if(pit->name.len == 7 + && strncasecmp(pit->name.s, "cbflags", 7) == 0) { + if(pit->body.len == 5 + && strncasecmp(pit->name.s, "noack", 5) == 0) { + tattrs.cbflags |= TMCB_DONT_ACK; + } else { + LM_ERR("unknown cbflags attribute value\n"); + } + } else if(pit->name.len == 7 + && strncasecmp(pit->name.s, "rpflags", 7) == 0) { + str2sint(&pit->body, &ival); + tattrs.rpflags |= ival; + } else { + LM_ERR("unknown attribute provided\n"); + } + } + } + + rpc_t_uac_attrs_helper(rpc, c, &tattrs); +} + static int t_uac_check_msg(struct sip_msg *msg, str *method, str *body, str *fromtag, int *cseq_is, int *cseq, str *callid) { diff --git a/src/modules/tm/rpc_uac.h b/src/modules/tm/rpc_uac.h index 7826c9ef544..95d01649178 100644 --- a/src/modules/tm/rpc_uac.h +++ b/src/modules/tm/rpc_uac.h @@ -38,6 +38,8 @@ void rpc_t_uac_wait_noack_hex(rpc_t *rpc, void *c); void rpc_t_uac_wait_block_noack(rpc_t *rpc, void *c); void rpc_t_uac_wait_block_noack_hex(rpc_t *rpc, void *c);
+void rpc_t_uac_attrs(rpc_t *rpc, void *c); + int t_uac_send(str *method, str *ruri, str *nexthop, str *send_socket, str *headers, str *body);
diff --git a/src/modules/tm/tm.c b/src/modules/tm/tm.c index 54d06950199..8997abe983b 100644 --- a/src/modules/tm/tm.c +++ b/src/modules/tm/tm.c @@ -2975,6 +2975,12 @@ static const char *rpc_t_uac_wait_block_noack_hex_doc[2] = { 0 };
+static const char *rpc_t_uac_attrs_doc[2] = { + "starts a tm uac using a list of string parameters: attributes, method," + " ruri, dst_uri, send_sock, headers (CRLF separated) and body (optional)", + 0 +}; + static const char *tm_rpc_list_doc[2] = { "List transactions.", 0 @@ -3020,6 +3026,8 @@ static rpc_export_t tm_rpc[] = { rpc_t_uac_wait_block_noack_doc, 0}, {"tm.t_uac_wait_block_noack_hex", rpc_t_uac_wait_block_noack_hex, rpc_t_uac_wait_block_noack_hex_doc, 0}, + {"tm.t_uac_attrs", rpc_t_uac_attrs, + rpc_t_uac_attrs_doc, RET_ARRAY}, {"tm.list", tm_rpc_list, tm_rpc_list_doc, RET_ARRAY}, {"tm.clean", tm_rpc_clean, tm_rpc_clean_doc, 0}, {0, 0, 0, 0}