diff --git a/src/modules/rtpengine/doc/rtpengine_admin.xml b/src/modules/rtpengine/doc/rtpengine_admin.xml
index c2d62e1b7ed..4b50f634c22 100644
--- a/src/modules/rtpengine/doc/rtpengine_admin.xml
+++ b/src/modules/rtpengine/doc/rtpengine_admin.xml
@@ -918,6 +918,21 @@ rtpengine_offer();
dialogues within a call are being torn down.
+ to-tag=... - use the specified string as To
+ tag instead of the actual To
tag from the &sip; message, and
+ force inclusion of the tag in the message as per above.
+
+
+ from-tag=... - use the specified string as
+ From
tag instead of the actual From
+ tag from the &sip; message.
+
+
+ call-id=... - use the specified string as
+ Call-ID
instead of the actual Call-ID
+ from the &sip; message.
+
+
rtcp-mux-demux - if rtcp-mux (RFC 5761) was
offered, make the &rtp; proxy accept the offer, but not offer it to the
recipient of this message.
diff --git a/src/modules/rtpengine/rtpengine.c b/src/modules/rtpengine/rtpengine.c
index e3972206fe6..5fd15d0d8c9 100644
--- a/src/modules/rtpengine/rtpengine.c
+++ b/src/modules/rtpengine/rtpengine.c
@@ -116,6 +116,7 @@ enum {
struct ng_flags_parse {
int via, to, packetize, transport;
bencode_item_t *dict, *flags, *direction, *replace, *rtcp_mux;
+ str call_id, from_tag, to_tag;
};
static const char *command_strings[] = {
@@ -1783,16 +1784,25 @@ static int parse_flags(struct ng_flags_parse *ng_flags, struct sip_msg *msg, enu
case 6:
if (str_eq(&key, "to-tag")) {
+ if (val.s)
+ ng_flags->to_tag = val;
ng_flags->to = 1;
goto next;
}
break;
case 7:
- if (str_eq(&key, "RTP/AVP")) {
+ if (str_eq(&key, "RTP/AVP"))
ng_flags->transport = 0x100;
- goto next;
+ else if (str_eq(&key, "call-id")) {
+ err = "missing value";
+ if (!val.s)
+ goto error;
+ ng_flags->call_id = val;
}
+ else
+ goto generic;
+ goto next;
break;
case 8:
@@ -1802,6 +1812,12 @@ static int parse_flags(struct ng_flags_parse *ng_flags, struct sip_msg *msg, enu
ng_flags->transport = 0x102;
else if (str_eq(&key, "RTP/SAVP"))
ng_flags->transport = 0x101;
+ else if (str_eq(&key, "from-tag")) {
+ err = "missing value";
+ if (!val.s)
+ goto error;
+ ng_flags->from_tag = val;
+ }
else
goto generic;
goto next;
@@ -1892,7 +1908,7 @@ static bencode_item_t *rtpp_function_call(bencode_buffer_t *bencbuf, struct sip_
{
struct ng_flags_parse ng_flags;
bencode_item_t *item, *resp;
- str callid = STR_NULL, from_tag = STR_NULL, to_tag = STR_NULL, viabranch = STR_NULL;
+ str viabranch = STR_NULL;
str body = STR_NULL, error = STR_NULL;
int ret, queried_nodes = 0;
struct rtpp_node *node;
@@ -1903,15 +1919,15 @@ static bencode_item_t *rtpp_function_call(bencode_buffer_t *bencbuf, struct sip_
memset(&ng_flags, 0, sizeof(ng_flags));
- if (get_callid(msg, &callid) == -1 || callid.len == 0) {
+ if (get_callid(msg, &ng_flags.call_id) == -1 || ng_flags.call_id.len == 0) {
LM_ERR("can't get Call-Id field\n");
return NULL;
}
- if (get_to_tag(msg, &to_tag) == -1) {
+ if (get_to_tag(msg, &ng_flags.to_tag) == -1) {
LM_ERR("can't get To tag\n");
return NULL;
}
- if (get_from_tag(msg, &from_tag) == -1 || from_tag.len == 0) {
+ if (get_from_tag(msg, &ng_flags.from_tag) == -1 || ng_flags.from_tag.len == 0) {
LM_ERR("can't get From tag\n");
return NULL;
}
@@ -1967,7 +1983,7 @@ static bencode_item_t *rtpp_function_call(bencode_buffer_t *bencbuf, struct sip_
if (ng_flags.rtcp_mux && ng_flags.rtcp_mux->child)
bencode_dictionary_add(ng_flags.dict, "rtcp-mux", ng_flags.rtcp_mux);
- bencode_dictionary_add_str(ng_flags.dict, "call-id", &callid);
+ bencode_dictionary_add_str(ng_flags.dict, "call-id", &ng_flags.call_id);
if (ng_flags.via) {
if (ng_flags.via == 1 || ng_flags.via == 2)
@@ -1992,19 +2008,20 @@ static bencode_item_t *rtpp_function_call(bencode_buffer_t *bencbuf, struct sip_
bencode_list_add_string(item, ip_addr2a(&msg->rcv.src_ip));
if ((msg->first_line.type == SIP_REQUEST && op != OP_ANSWER)
+ || (msg->first_line.type == SIP_REPLY && op == OP_DELETE)
|| (msg->first_line.type == SIP_REPLY && op == OP_ANSWER))
{
- bencode_dictionary_add_str(ng_flags.dict, "from-tag", &from_tag);
- if (ng_flags.to && to_tag.s && to_tag.len)
- bencode_dictionary_add_str(ng_flags.dict, "to-tag", &to_tag);
+ bencode_dictionary_add_str(ng_flags.dict, "from-tag", &ng_flags.from_tag);
+ if (ng_flags.to && ng_flags.to_tag.s && ng_flags.to_tag.len)
+ bencode_dictionary_add_str(ng_flags.dict, "to-tag", &ng_flags.to_tag);
}
else {
- if (!to_tag.s || !to_tag.len) {
+ if (!ng_flags.to_tag.s || !ng_flags.to_tag.len) {
LM_ERR("No to-tag present\n");
goto error;
}
- bencode_dictionary_add_str(ng_flags.dict, "from-tag", &to_tag);
- bencode_dictionary_add_str(ng_flags.dict, "to-tag", &from_tag);
+ bencode_dictionary_add_str(ng_flags.dict, "from-tag", &ng_flags.to_tag);
+ bencode_dictionary_add_str(ng_flags.dict, "to-tag", &ng_flags.from_tag);
}
bencode_dictionary_add_string(ng_flags.dict, "command", command_strings[op]);
@@ -2026,7 +2043,7 @@ static bencode_item_t *rtpp_function_call(bencode_buffer_t *bencbuf, struct sip_
goto error;
}
- node = select_rtpp_node(callid, viabranch, 1, queried_nodes_ptr, queried_nodes, op);
+ node = select_rtpp_node(ng_flags.call_id, viabranch, 1, queried_nodes_ptr, queried_nodes, op);
if (!node) {
LM_ERR("no available proxies\n");
goto error;
@@ -2068,21 +2085,22 @@ static bencode_item_t *rtpp_function_call(bencode_buffer_t *bencbuf, struct sip_
}
/* add hastable entry with the node => */
- if (!rtpengine_hash_table_lookup(callid, viabranch, op)) {
+ if (!rtpengine_hash_table_lookup(ng_flags.call_id, viabranch, op)) {
// build the entry
struct rtpengine_hash_entry *entry = shm_malloc(sizeof(struct rtpengine_hash_entry));
if (!entry) {
LM_ERR("rtpengine hash table fail to create entry for calllen=%d callid=%.*s viabranch=%.*s\n",
- callid.len, callid.len, callid.s, viabranch.len, viabranch.s);
+ ng_flags.call_id.len, ng_flags.call_id.len, ng_flags.call_id.s,
+ viabranch.len, viabranch.s);
goto skip_hash_table_insert;
}
memset(entry, 0, sizeof(struct rtpengine_hash_entry));
// fill the entry
- if (callid.s && callid.len > 0) {
- if (shm_str_dup(&entry->callid, &callid) < 0) {
+ if (ng_flags.call_id.s && ng_flags.call_id.len > 0) {
+ if (shm_str_dup(&entry->callid, &ng_flags.call_id) < 0) {
LM_ERR("rtpengine hash table fail to duplicate calllen=%d callid=%.*s\n",
- callid.len, callid.len, callid.s);
+ ng_flags.call_id.len, ng_flags.call_id.len, ng_flags.call_id.s);
rtpengine_hash_table_free_entry(entry);
goto skip_hash_table_insert;
}
@@ -2090,7 +2108,7 @@ static bencode_item_t *rtpp_function_call(bencode_buffer_t *bencbuf, struct sip_
if (viabranch.s && viabranch.len > 0) {
if (shm_str_dup(&entry->viabranch, &viabranch) < 0) {
LM_ERR("rtpengine hash table fail to duplicate calllen=%d viabranch=%.*s\n",
- callid.len, viabranch.len, viabranch.s);
+ ng_flags.call_id.len, viabranch.len, viabranch.s);
rtpengine_hash_table_free_entry(entry);
goto skip_hash_table_insert;
}
@@ -2100,14 +2118,16 @@ static bencode_item_t *rtpp_function_call(bencode_buffer_t *bencbuf, struct sip_
entry->tout = get_ticks() + hash_table_tout;
// insert the key<->entry from the hashtable
- if (!rtpengine_hash_table_insert(callid, viabranch, entry)) {
+ if (!rtpengine_hash_table_insert(ng_flags.call_id, viabranch, entry)) {
LM_ERR("rtpengine hash table fail to insert node=%.*s for calllen=%d callid=%.*s viabranch=%.*s\n",
- node->rn_url.len, node->rn_url.s, callid.len, callid.len, callid.s, viabranch.len, viabranch.s);
+ node->rn_url.len, node->rn_url.s, ng_flags.call_id.len,
+ ng_flags.call_id.len, ng_flags.call_id.s, viabranch.len, viabranch.s);
rtpengine_hash_table_free_entry(entry);
goto skip_hash_table_insert;
} else {
LM_DBG("rtpengine hash table insert node=%.*s for calllen=%d callid=%.*s viabranch=%.*s\n",
- node->rn_url.len, node->rn_url.s, callid.len, callid.len, callid.s, viabranch.len, viabranch.s);
+ node->rn_url.len, node->rn_url.s, ng_flags.call_id.len,
+ ng_flags.call_id.len, ng_flags.call_id.s, viabranch.len, viabranch.s);
}
}
@@ -2117,12 +2137,14 @@ static bencode_item_t *rtpp_function_call(bencode_buffer_t *bencbuf, struct sip_
if (op == OP_DELETE) {
/* Delete the key<->value from the hashtable */
- if (!rtpengine_hash_table_remove(callid, viabranch, op)) {
+ if (!rtpengine_hash_table_remove(ng_flags.call_id, viabranch, op)) {
LM_ERR("rtpengine hash table failed to remove entry for callen=%d callid=%.*s viabranch=%.*s\n",
- callid.len, callid.len, callid.s, viabranch.len, viabranch.s);
+ ng_flags.call_id.len, ng_flags.call_id.len, ng_flags.call_id.s,
+ viabranch.len, viabranch.s);
} else {
LM_DBG("rtpengine hash table remove entry for callen=%d callid=%.*s viabranch=%.*s\n",
- callid.len, callid.len, callid.s, viabranch.len, viabranch.s);
+ ng_flags.call_id.len, ng_flags.call_id.len, ng_flags.call_id.s,
+ viabranch.len, viabranch.s);
}
}
@@ -3166,4 +3188,4 @@ static sr_kemi_t sr_kemi_rtpengine_exports[] = {
int mod_register(char *path, int *dlflags, void *p1, void *p2) {
sr_kemi_modules_add(sr_kemi_rtpengine_exports);
return 0;
-}
\ No newline at end of file
+}