Skip to content

Commit 6338168

Browse files
committed
Working implementation
1 parent d0c4fc4 commit 6338168

File tree

2 files changed

+88
-0
lines changed

2 files changed

+88
-0
lines changed

modules/tm/README

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ tm Module
7272

7373
1.4.21. t_flush_flags()
7474
1.4.22. t_anycast_replicate()
75+
1.4.23 t_reply_by_callid()
7576

7677
1.5. Exported Pseudo-Variables
7778

@@ -173,6 +174,7 @@ tm Module
173174
1.42. t_write_req/unix usage
174175
1.43. t_flush_flags usage
175176
1.44. t_anycast_replicate usage
177+
1.45. t_reply_by_callid usage
176178

177179
Chapter 1. Admin Guide
178180

@@ -1372,6 +1374,58 @@ if (is_method("ACK|CANCEL") && !t_check_trans()) {
13721374
}
13731375
...
13741376

1377+
1.4.23. t_reply_by_callid(code, reason_phrase, [callid], [cseq])
1378+
1379+
This function is used to send a reply to
1380+
an existing INVITE transaction.
1381+
The usual use case is when opensips is used as an UAS
1382+
and when an INVITE is receveid, it is "parked" locally on
1383+
opensips by replying to it with
1384+
t_reply(180, "Ringing" or t_reply(183, "Session Progress")
1385+
and later we need to handle CANCEL or BYE for it and send
1386+
'487 Request Terminated' to the original INVITE transaction.
1387+
1388+
The callid and cseq used to identify the transaction
1389+
will be obtained from the current messsage being processed.
1390+
But they can be passed explicitly so that for example we can
1391+
handle a BYE where the cseq must be the cseq
1392+
of the INVITE minus one.
1393+
1394+
This function can be used from REQUEST_ROUTE.
1395+
1396+
Example 1.45. t_reply_by_callid usage
1397+
...
1398+
1399+
route{
1400+
if($rU == "LOCAL_PARK") {
1401+
if(is_method("INVITE")) {
1402+
$T_fr_timeout = 10;
1403+
$T_fr_inv_timeout = 10;
1404+
append_to_reply("Contact: sip:LOCAL_PARK@$socket_in(ip):$socket_in(port)\r\n");
1405+
t_reply(180, "Ringing");
1406+
t_wait_for_new_branches();
1407+
} else if(is_method("CANCEL")) {
1408+
if(!t_reply_by_callid(487, "Request Terminated")) {
1409+
sl_send_reply(481, "Call Leg/Transaction Does Not Exist");
1410+
} else {
1411+
sl_send_reply(200, "OK");
1412+
}
1413+
} else if(is_method("BYE")) {
1414+
$var(prev_cseq) = ($(cs{s.int}) - 1);
1415+
if(!t_reply_by_callid(487, "Request Terminated", , $var(prev_cseq))) {
1416+
sl_send_reply(481, "Call Leg/Transaction Does Not Exist");
1417+
} else {
1418+
sl_send_reply(200, "OK");
1419+
}
1420+
} else if(is_method("ACK")) {
1421+
t_relay();
1422+
}
1423+
exit;
1424+
}
1425+
}
1426+
1427+
...
1428+
13751429
1.5. Exported Pseudo-Variables
13761430

13771431
Exported variables are listed in the next sections.

modules/tm/tm.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ static int w_t_new_request(struct sip_msg* msg, str *method,
128128
static int t_wait_for_new_branches(struct sip_msg* msg,
129129
unsigned int* br_to_wait);
130130
static int w_t_wait_no_more_branches(struct sip_msg* msg);
131+
static int t_reply_by_callid(struct sip_msg* msg, unsigned int* code, str* text, str* callid, str* cseq);
131132

132133
struct sip_msg* tm_pv_context_request(struct sip_msg* msg);
133134
struct sip_msg* tm_pv_context_reply(struct sip_msg* msg);
@@ -272,6 +273,12 @@ static cmd_export_t cmds[]={
272273
REQUEST_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|FAILURE_ROUTE},
273274
{"t_anycast_replicate", (cmd_function)tm_anycast_replicate, {{0,0,0}},
274275
REQUEST_ROUTE},
276+
{"t_reply_by_callid", (cmd_function)t_reply_by_callid, {
277+
{CMD_PARAM_INT, fixup_reply_code, 0},
278+
{CMD_PARAM_STR, 0, 0},
279+
{CMD_PARAM_STR | CMD_PARAM_OPT, 0, 0},
280+
{CMD_PARAM_STR | CMD_PARAM_OPT, 0, 0}, {0,0,0}},
281+
REQUEST_ROUTE},
275282
{"load_tm", (cmd_function)load_tm, {{0,0,0}}, 0},
276283
{0,0,{{0,0,0}},0}
277284
};
@@ -1609,6 +1616,33 @@ static int w_t_wait_no_more_branches(struct sip_msg* msg)
16091616
return 1;
16101617
}
16111618

1619+
1620+
static int t_reply_by_callid(struct sip_msg* msg, unsigned int* code, str* text, str* callid, str* cseq_number)
1621+
{
1622+
struct cell *trans;
1623+
int n;
1624+
1625+
if (!callid && msg->callid==NULL && ((parse_headers(msg, HDR_CALLID_F, 0) ==-1) || (msg->callid==NULL)) ) {
1626+
/* could not get callid */
1627+
return -2;
1628+
}
1629+
1630+
if (!cseq_number && !msg->cseq && ((parse_headers(msg, HDR_CSEQ_F, 0) == -1) || !msg->cseq)) {
1631+
/* could not get cseq */
1632+
return -3;
1633+
}
1634+
1635+
if(t_lookup_callid( &trans, callid ? *callid : msg->callid->body, cseq_number ? *cseq_number : get_cseq(msg)->number) < 0) {
1636+
/* transaction not found */
1637+
return -4;
1638+
}
1639+
1640+
n = t_reply_with_body( trans, *code, text, 0, 0, 0);
1641+
1642+
return n;
1643+
}
1644+
1645+
16121646
/******************** pseudo-variable functions *************************/
16131647

16141648
static int pv_get_tm_branch_idx(struct sip_msg *msg, pv_param_t *param,

0 commit comments

Comments
 (0)