pespin has submitted this change. (
https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/36547?usp=email )
Change subject: asterisk: Introduce test TC_internal_call_momt
......................................................................
asterisk: Introduce test TC_internal_call_momt
Lots of infrastructure added to allow call establishment and hang up
between 2 users connected to Asterisk.
SIP_Tests is updated to accomodate for necessary changes in
SIP_Templates used by Asterisk_Templates.
Change-Id: Ic5827a3e94b06fbc57f6405bf0f0aa6598c5d1fe
Related: SYS#6782
---
M asterisk/Asterisk_Tests.ttcn
M asterisk/expected-results.xml
M library/SIP_Templates.ttcn
M sip/SIP_Tests.ttcn
4 files changed, 727 insertions(+), 110 deletions(-)
Approvals:
osmith: Looks good to me, but someone else must approve
Jenkins Builder: Verified
pespin: Looks good to me, approved
diff --git a/asterisk/Asterisk_Tests.ttcn b/asterisk/Asterisk_Tests.ttcn
index ebf1914..6ca05c1 100644
--- a/asterisk/Asterisk_Tests.ttcn
+++ b/asterisk/Asterisk_Tests.ttcn
@@ -31,46 +31,65 @@
integer mp_remote_sip_port := 5060;
}
+type port Coord_PT message
+{
+ inout charstring;
+} with { extension "internal" };
+private const charstring COORD_CMD_REGISTERED := "COORD_CMD_REGISTERED";
+private const charstring COORD_CMD_START := "COORD_CMD_START";
+private const charstring COORD_CMD_CALL_ESTABLISHED :=
"COORD_CMD_CALL_ESTABLISHED";
+private const charstring COORD_CMD_HANGUP := "COORD_CMD_HANGUP";
+
type component test_CT {
var SIP_Emulation_CT vc_SIP;
+ port Coord_PT COORD;
}
type component ConnHdlr extends SIP_ConnHdlr {
+ var charstring g_name;
var ConnHdlrPars g_pars;
timer g_Tguard;
var PDU_SIP_Request g_rx_sip_req;
var PDU_SIP_Response g_rx_sip_resp;
+
+ port Coord_PT COORD;
}
type record ConnHdlrPars {
float t_guard,
charstring user,
+ charstring display_name,
charstring password,
- SipUrl registrar_sip_url,
+ SipUrl registrar_sip_req_uri,
SipAddr registrar_sip_record,
CallidString registrar_sip_call_id,
- Via registrar_via,
integer registrar_sip_seq_nr,
- SipAddr sip_url_ext,
+ Via local_via,
+ SipUrl local_sip_url_ext,
+ SipAddr local_sip_record,
Contact local_contact,
CallPars cp optional
}
template (value) ConnHdlrPars t_Pars(charstring user,
- charstring displayname := "\"Anonymous\"",
- charstring password := "secret") := {
+ charstring display_name := "Anonymous",
+ charstring password := "secret",
+ template (value) CallPars cp := t_CallPars()) := {
t_guard := 30.0,
user := user,
+ display_name := f_sip_str_quote(display_name),
password := password,
- registrar_sip_url := valueof(ts_SipUrlHost(mp_remote_sip_host)),
+ registrar_sip_req_uri := valueof(ts_SipUrlHost(mp_remote_sip_host)),
registrar_sip_record := ts_SipAddr(ts_HostPort(mp_remote_sip_host),
ts_UserInfo(user),
- displayName := displayname),
+ f_sip_str_quote(display_name)),
registrar_sip_call_id := hex2str(f_rnd_hexstring(15)) & "@" &
mp_local_sip_host,
- registrar_via := ts_Via_from(ts_HostPort(mp_local_sip_host, mp_local_sip_port)),
registrar_sip_seq_nr := f_sip_rand_seq_nr(),
- sip_url_ext := ts_SipAddr(ts_HostPort(mp_local_sip_host, mp_local_sip_port),
- ts_UserInfo(user)),
+ local_via := ts_Via_from(ts_HostPort(mp_local_sip_host, mp_local_sip_port)),
+ local_sip_url_ext := ts_SipUrl(ts_HostPort(mp_local_sip_host, mp_local_sip_port),
+ ts_UserInfo(user)),
+ local_sip_record := ts_SipAddr(ts_HostPort(mp_local_sip_host),
+ ts_UserInfo(user)),
local_contact := valueof(ts_Contact({
ts_ContactAddress(
ts_Addr_Union_SipUrl(ts_SipUrl(ts_HostPort(
@@ -79,46 +98,46 @@
ts_UserInfo(user))),
omit)
})),
- cp := omit
+ cp := cp
}
function f_init_ConnHdlrPars(integer idx := 1) runs on test_CT return ConnHdlrPars {
- var ConnHdlrPars pars := valueof(t_Pars("0" & int2str(500 + idx)));
- return pars;
+ var template (value) CallPars cp := t_CallPars(idx := idx);
+ var template (value) ConnHdlrPars pars := t_Pars("0" & int2str(500 +
idx),
+ cp := cp);
+ return valueof(pars);
}
type record CallPars {
- boolean is_mo,
- charstring calling,
- charstring called,
+ SipAddr calling optional,
+ SipAddr called optional,
- CallParsComputed comp optional,
+ SipAddr from_addr optional,
+ SipAddr to_addr optional,
- charstring sip_rtp_addr,
- uint16_t sip_rtp_port,
- charstring cn_rtp_addr,
- uint16_t cn_rtp_port
-}
-
-type record CallParsComputed {
CallidString sip_call_id,
- charstring sip_body,
- integer sip_seq_nr
+ integer sip_seq_nr,
+ charstring sip_body optional,
+
+ charstring local_rtp_addr,
+ uint16_t local_rtp_port,
+
+ SDP_Message peer_sdp optional
}
-private template (value) CallPars t_CallPars(boolean is_mo) := {
- is_mo := is_mo,
- calling := "12345",
- called := "98766",
- comp := {
- sip_call_id := hex2str(f_rnd_hexstring(15)),
- sip_body := "",
- sip_seq_nr := f_sip_rand_seq_nr()
- },
- sip_rtp_addr := "1.2.3.4",
- sip_rtp_port := 1234,
- cn_rtp_addr := "5.6.7.8",
- cn_rtp_port := 5678
+private template (value) CallPars t_CallPars(integer idx := 1,
+ template (omit) SipAddr calling := omit,
+ template (omit) SipAddr called := omit) := {
+ calling := calling,
+ called := called,
+ from_addr := omit,
+ to_addr := omit,
+ sip_call_id := hex2str(f_rnd_hexstring(15)),
+ sip_seq_nr := f_sip_rand_seq_nr(),
+ sip_body := omit,
+ local_rtp_addr := mp_local_sip_host,
+ local_rtp_port := 1234 + 2*idx,
+ peer_sdp := omit
}
function f_init() runs on test_CT {
@@ -131,13 +150,15 @@
function f_start_handler(void_fn fn, ConnHdlrPars pars)
runs on test_CT return ConnHdlr {
var ConnHdlr vc_conn;
- var charstring id := testcasename();
+ var charstring id := testcasename() & "-ConnHdlr-" & pars.user;
vc_conn := ConnHdlr.create(id) alive;
connect(vc_conn:SIP, vc_SIP:CLIENT);
connect(vc_conn:SIP_PROC, vc_SIP:CLIENT_PROC);
+ connect(vc_conn:COORD, self:COORD);
+
vc_conn.start(f_handler_init(fn, id, pars));
return vc_conn;
}
@@ -151,6 +172,7 @@
private function f_handler_init(void_fn fn, charstring id, ConnHdlrPars pars)
runs on ConnHdlr {
+ g_name := id;
g_pars := pars;
g_Tguard.start(pars.t_guard);
activate(as_Tguard());
@@ -163,21 +185,45 @@
fn.apply(id);
}
-altstep as_SIP_expect_req(template PDU_SIP_Request sip_expect) runs on ConnHdlr
+private altstep as_SIP_fail_req(charstring exp_msg_str := "") runs on ConnHdlr
{
- [] SIP.receive(sip_expect) -> value g_rx_sip_req;
- [] SIP.receive {
- log("FAIL: expected SIP message ", sip_expect);
- Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received unexpected SIP
message");
+ var PDU_SIP_Request sip_req;
+ [] SIP.receive(PDU_SIP_Request:?) -> value sip_req {
+ Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
+ log2str(g_name & ": Received unexpected SIP Req message := ", sip_req,
"\nvs exp := ", exp_msg_str));
}
}
-altstep as_SIP_expect_resp(template PDU_SIP_Response sip_expect) runs on ConnHdlr
+private altstep as_SIP_fail_resp(charstring exp_msg_str := "") runs on
ConnHdlr
{
+ var PDU_SIP_Response sip_resp;
+ [] SIP.receive(PDU_SIP_Response:?) -> value sip_resp {
+ Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
+ log2str(g_name & ": Received unexpected SIP Resp message := ",
sip_resp, "\nvs exp := ", exp_msg_str));
+ }
+}
+
+altstep as_SIP_expect_req(template (present) PDU_SIP_Request sip_expect, boolean
fail_others := true) runs on ConnHdlr
+{
+ var charstring sip_expect_str := log2str(sip_expect);
+ [] SIP.receive(sip_expect) -> value g_rx_sip_req;
+ [fail_others] as_SIP_fail_req(sip_expect_str);
+ [fail_others] as_SIP_fail_resp(sip_expect_str);
+}
+
+altstep as_SIP_expect_resp(template (present) PDU_SIP_Response sip_expect, boolean
fail_others := true) runs on ConnHdlr
+{
+ var charstring sip_expect_str := log2str(sip_expect);
[] SIP.receive(sip_expect) -> value g_rx_sip_resp;
- [] SIP.receive {
- log("FAIL: expected SIP message ", sip_expect);
- Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received unexpected SIP
message");
+ [fail_others] as_SIP_fail_resp(sip_expect_str);
+ [fail_others] as_SIP_fail_req(sip_expect_str);
+}
+
+altstep as_SIP_ignore_resp(template PDU_SIP_Response sip_expect := ?) runs on ConnHdlr
+{
+ [] SIP.receive(sip_expect) -> value g_rx_sip_resp {
+ log("Ignoring ", g_rx_sip_resp);
+ repeat;
}
}
@@ -192,15 +238,45 @@
via_resp_params);
}
-private function f_tr_To_response(SipAddr to_req) return template (present) SipAddr {
+private function f_tr_To_response(template (value) SipAddr to_req) return template
(present) SipAddr {
return tr_SipAddr_from_val(to_req);
}
-function f_SIP_register() runs on ConnHdlr return PDU_SIP_Response
+private function f_tr_From(template (value) SipAddr from_req) return template (present)
SipAddr {
+ return tr_SipAddr_from_val(from_req);
+}
+
+private function f_gen_sdp() runs on ConnHdlr return charstring {
+ var charstring sdp :=
+ "v=0\r\n" &
+ "o=0502 2390 1824 IN IP4 " & g_pars.cp.local_rtp_addr &
"\r\n" &
+ "s=Talk\r\n" &
+ "c=IN IP4 " & g_pars.cp.local_rtp_addr & "\r\n" &
+ "t=0 0\r\n" &
+ "a=rtcp-xr:rcvr-rtt=all:10000 stat-summary=loss,dup,jitt,TTL
voip-metrics\r\n" &
+ "a=record:off\r\n" &
+ "m=audio " & int2str(g_pars.cp.local_rtp_port) & " RTP/AVP 96 97
98 0 8 18 99 100 101\r\n" &
+ "a=rtpmap:96 opus/48000/2\r\n" &
+ "a=fmtp:96 useinbandfec=1\r\n" &
+ "a=rtpmap:97 speex/16000\r\n" &
+ "a=fmtp:97 vbr=on\r\n" &
+ "a=rtpmap:98 speex/8000\r\n" &
+ "a=fmtp:98 vbr=on\r\n" &
+ "a=fmtp:18 annexb=yes\r\n" &
+ "a=rtpmap:99 telephone-event/48000\r\n" &
+ "a=rtpmap:100 telephone-event/16000\r\n" &
+ "a=rtpmap:101 telephone-event/8000\r\n" &
+ "a=rtcp:" & int2str(g_pars.cp.local_rtp_port + 1) & "\r\n"
&
+ "a=rtcp-fb:* trr-int 1000\r\n" &
+ "a=rtcp-fb:* ccm tmmbr\r\n";
+ return sdp;
+}
+
+private function f_SIP_register() runs on ConnHdlr return PDU_SIP_Response
{
var template (present) PDU_SIP_Response exp;
var Authorization authorization;
- var Via via := g_pars.registrar_via;
+ var Via via := g_pars.local_via;
var SipAddr from_sipaddr := g_pars.registrar_sip_record;
var charstring branch_value;
@@ -211,7 +287,7 @@
via.viaBody[0].viaParams := f_sip_param_set(via.viaBody[0].viaParams,
"branch", branch_value);
from_sipaddr.params := f_sip_param_set(from_sipaddr.params, "tag",
f_sip_rand_tag());
- SIP.send(ts_SIP_REGISTER(g_pars.registrar_sip_url,
+ SIP.send(ts_SIP_REGISTER(g_pars.registrar_sip_req_uri,
g_pars.registrar_sip_call_id,
from_sipaddr,
g_pars.registrar_sip_record,
@@ -220,7 +296,7 @@
g_pars.local_contact,
ts_Expires("7200")));
- exp := tr_SIP_Response_REGISTER_Unauthorized(
+ exp := tr_SIP_Response_Unauthorized(
g_pars.registrar_sip_call_id,
from_sipaddr,
f_tr_To_response(g_pars.registrar_sip_record),
@@ -233,7 +309,8 @@
/* Digest Auth: RFC 2617 */
authorization :=
f_sip_digest_gen_Authorization(g_rx_sip_resp.msgHeader.wwwAuthenticate,
g_pars.user, g_pars.password,
- "REGISTER", "sip:" & mp_remote_sip_host)
+ "REGISTER",
+ f_sip_SipUrl_to_str(g_pars.registrar_sip_req_uri))
/* New transaction: */
g_pars.registrar_sip_seq_nr := g_pars.registrar_sip_seq_nr + 1;
@@ -243,7 +320,7 @@
g_pars.registrar_sip_seq_nr);
via.viaBody[0].viaParams := f_sip_param_set(via.viaBody[0].viaParams,
"branch", branch_value);
- SIP.send(ts_SIP_REGISTER(g_pars.registrar_sip_url,
+ SIP.send(ts_SIP_REGISTER(g_pars.registrar_sip_req_uri,
g_pars.registrar_sip_call_id,
from_sipaddr,
g_pars.registrar_sip_record,
@@ -269,6 +346,303 @@
return g_rx_sip_resp;
}
+private function f_SIP_mo_call_setup() runs on ConnHdlr
+{
+ var template (value) PDU_SIP_Request req;
+ var template (present) PDU_SIP_Response exp;
+ var Via via;
+ var charstring tx_sdp := f_gen_sdp();
+ var default d_trying, d_ringing;
+ var charstring branch_value;
+
+ /* RFC 3261 8.1.1.3 From */
+ g_pars.cp.from_addr := g_pars.cp.calling;
+ g_pars.cp.from_addr.params := f_sip_param_set(g_pars.cp.from_addr.params,
"tag", f_sip_rand_tag());
+ g_pars.cp.to_addr := g_pars.cp.called;
+ branch_value := f_sip_gen_branch(f_sip_SipAddr_to_str(g_pars.cp.from_addr),
+ f_sip_SipAddr_to_str(valueof(g_pars.cp.to_addr)),
+ g_pars.cp.sip_call_id,
+ g_pars.cp.sip_seq_nr);
+ via := g_pars.local_via;
+ via.viaBody[0].viaParams := f_sip_param_set(via.viaBody[0].viaParams,
"branch", branch_value);
+
+ req := ts_SIP_INVITE(g_pars.cp.sip_call_id,
+ g_pars.cp.from_addr,
+ g_pars.cp.to_addr,
+ via,
+ g_pars.local_contact,
+ g_pars.cp.sip_seq_nr,
+ body := tx_sdp);
+
+ SIP.send(req);
+
+ /* RFC 3261 22.2: */
+ exp := tr_SIP_Response_Unauthorized(
+ g_pars.cp.sip_call_id,
+ f_tr_From(g_pars.cp.from_addr),
+ f_tr_To_response(g_pars.cp.to_addr),
+ f_tr_Via_response(via),
+ *,
+ tr_WwwAuthenticate({tr_Challenge_digestCln(?)}),
+ g_pars.cp.sip_seq_nr, "INVITE");
+ as_SIP_expect_resp(exp);
+
+ /* Digest Auth: RFC 2617 */
+ req.msgHeader.authorization := f_sip_digest_gen_Authorization(
+ g_rx_sip_resp.msgHeader.wwwAuthenticate,
+ g_pars.user, g_pars.password,
+ "INVITE",
+ f_sip_SipUrl_to_str(g_pars.registrar_sip_req_uri))
+ g_pars.cp.sip_seq_nr := g_pars.cp.sip_seq_nr + 1;
+ f_sip_Request_inc_seq_nr(req);
+ SIP.send(req);
+
+ /* Conditionally match and accept 100 Trying. */
+ exp := tr_SIP_Response_Trying(g_pars.cp.sip_call_id,
+ g_pars.cp.from_addr,
+ f_tr_To_response(g_pars.cp.to_addr),
+ f_tr_Via_response(via),
+ g_pars.cp.sip_seq_nr, "INVITE");
+ d_trying := activate(as_SIP_ignore_resp(exp));
+
+ /* Conditionally match and accept 180 Ringing */
+ exp := tr_SIP_Response_Ringing(g_pars.cp.sip_call_id,
+ g_pars.cp.from_addr,
+ f_tr_To_response(g_pars.cp.to_addr),
+ f_tr_Via_response(via),
+ g_pars.cp.sip_seq_nr, "INVITE");
+ d_ringing := activate(as_SIP_ignore_resp(exp));
+
+ /* Wait for OK answer */
+ exp := tr_SIP_Response(
+ g_pars.cp.sip_call_id,
+ g_pars.cp.from_addr,
+ f_tr_To_response(g_pars.cp.to_addr),
+ f_tr_Via_response(via),
+ *,
+ "INVITE", 200,
+ g_pars.cp.sip_seq_nr, "OK",
+ body := ?);
+ as_SIP_expect_resp(exp, fail_others := false);
+
+ deactivate(d_trying);
+ deactivate(d_ringing);
+
+ /* Update To with the tags received from peer: */
+ g_pars.cp.to_addr :=
valueof(ts_SipAddr_from_Addr_Union(g_rx_sip_resp.msgHeader.toField.addressField,
+ g_rx_sip_resp.msgHeader.toField.toParams));
+
+ /* Transmit ACK */
+ g_pars.cp.sip_seq_nr := g_pars.cp.sip_seq_nr + 1;
+ req := ts_SIP_ACK(g_pars.cp.sip_call_id,
+ g_pars.cp.from_addr,
+ g_pars.cp.to_addr,
+ via,
+ g_pars.cp.sip_seq_nr,
+ omit);
+ SIP.send(req);
+ g_pars.cp.sip_seq_nr := g_pars.cp.sip_seq_nr + 1;
+}
+
+/* Peer is calling us, accept it: */
+private altstep as_SIP_mt_call_accept(boolean exp_update_to_direct_rtp := true, boolean
fail_others := true) runs on ConnHdlr
+{
+ var template (present) PDU_SIP_Request exp_req :=
+ tr_SIP_INVITE(f_tr_SipUrl_opt_defport(g_pars.local_sip_url_ext),
+ ?,
+ f_tr_From(g_pars.cp.calling),
+ g_pars.cp.called,
+ tr_Via_from(f_tr_HostPort(mp_remote_sip_host, mp_remote_sip_port)),
+ ?, ?);
+ var charstring sip_expect_str := log2str(exp_req);
+
+ [] SIP.receive(exp_req) -> value g_rx_sip_req {
+ var template (value) PDU_SIP_Response tx_resp;
+ var Via via;
+ var charstring tx_sdp;
+
+ f_SDP_decodeMessage(g_rx_sip_req.messageBody, g_pars.cp.peer_sdp);
+ log("Rx Initial MT INVITE decoded SDP: ", g_pars.cp.peer_sdp);
+
+ /* Obtain params: */
+ g_pars.cp.sip_call_id := g_rx_sip_req.msgHeader.callId.callid;
+ g_pars.cp.from_addr :=
valueof(ts_SipAddr_from_Addr_Union(g_rx_sip_req.msgHeader.fromField.addressField,
+ g_rx_sip_req.msgHeader.fromField.fromParams));
+ g_pars.cp.to_addr :=
valueof(ts_SipAddr_from_Addr_Union(g_rx_sip_req.msgHeader.toField.addressField,
+ g_rx_sip_req.msgHeader.toField.toParams));
+ g_pars.cp.to_addr.params := f_sip_param_set(g_pars.cp.to_addr.params, "tag",
f_sip_rand_tag());
+ g_pars.cp.sip_seq_nr := g_rx_sip_req.msgHeader.cSeq.seqNumber;
+ via := g_rx_sip_req.msgHeader.via;
+
+
+ /* Tx 180 Ringing */
+ tx_resp := ts_SIP_Response_Ringing(g_pars.cp.sip_call_id,
+ g_pars.cp.from_addr,
+ g_pars.cp.to_addr,
+ via,
+ g_pars.cp.sip_seq_nr);
+ SIP.send(tx_resp);
+
+ /* Tx 200 OK */
+ tx_sdp := f_gen_sdp();
+ tx_resp := ts_SIP_Response(g_pars.cp.sip_call_id,
+ g_pars.cp.from_addr,
+ g_pars.cp.to_addr,
+ "INVITE", 200,
+ g_pars.cp.sip_seq_nr,
+ "OK",
+ via,
+ body := tx_sdp);
+ SIP.send(tx_resp);
+
+ /* Wait for ACK */
+ exp_req := tr_SIP_ACK(f_tr_SipUrl_opt_defport(g_pars.local_sip_url_ext),
+ g_pars.cp.sip_call_id,
+ g_pars.cp.from_addr,
+ g_pars.cp.to_addr,
+ f_tr_Via_response(via),
+ g_pars.cp.sip_seq_nr, *);
+ as_SIP_expect_req(exp_req);
+
+ if (exp_update_to_direct_rtp) {
+ /* Asterisk will now update the session to connect us to MO directly: */
+ /* Via is not kept since anyway "branch" will change upon following INVITE.
*/
+ as_SIP_exp_call_update(g_pars.cp.sip_seq_nr + 1);
+ }
+ }
+ [fail_others] as_SIP_fail_resp(sip_expect_str);
+ [fail_others] as_SIP_fail_req(sip_expect_str);
+
+}
+
+/* New INVITE arrives after MT call is established. Accept it: */
+private altstep as_SIP_exp_call_update(template (present) integer exp_seq_nr := ?,
boolean fail_others := true) runs on ConnHdlr
+{
+ var template (present) PDU_SIP_Request exp_req :=
+ tr_SIP_INVITE(f_tr_SipUrl_opt_defport(g_pars.local_sip_url_ext),
+ g_pars.cp.sip_call_id,
+ g_pars.cp.from_addr,
+ g_pars.cp.to_addr,
+ tr_Via_from(f_tr_HostPort(mp_remote_sip_host, mp_remote_sip_port)),
+ exp_seq_nr,
+ ?);
+ var charstring sip_expect_str := log2str(exp_req);
+
+ [] SIP.receive(exp_req) -> value g_rx_sip_req {
+ var template (value) PDU_SIP_Response tx_resp;
+ var charstring tx_sdp;
+ var Via via;
+
+ f_SDP_decodeMessage(g_rx_sip_req.messageBody, g_pars.cp.peer_sdp);
+ log("Rx Update MT INVITE decoded SDP: ", g_pars.cp.peer_sdp);
+
+ /* Update parameters: */
+ g_pars.cp.sip_seq_nr := g_rx_sip_req.msgHeader.cSeq.seqNumber;
+ /* "branch" has changed: */
+ via := g_rx_sip_req.msgHeader.via;
+
+ /* Tx 200 OK */
+ tx_sdp := f_gen_sdp();
+ tx_resp := ts_SIP_Response(g_pars.cp.sip_call_id,
+ g_pars.cp.from_addr,
+ g_pars.cp.to_addr,
+ "INVITE", 200,
+ g_pars.cp.sip_seq_nr,
+ "OK",
+ via,
+ body := tx_sdp);
+ SIP.send(tx_resp);
+
+ /* Wait for ACK */
+ exp_req := tr_SIP_ACK(f_tr_SipUrl_opt_defport(g_pars.local_sip_url_ext),
+ g_pars.cp.sip_call_id,
+ g_pars.cp.from_addr,
+ g_pars.cp.to_addr,
+ f_tr_Via_response(via),
+ g_pars.cp.sip_seq_nr, *);
+ as_SIP_expect_req(exp_req);
+ }
+ [fail_others] as_SIP_fail_resp(sip_expect_str);
+ [fail_others] as_SIP_fail_req(sip_expect_str);
+}
+
+/* Tx BYE: */
+private function f_SIP_do_call_hangup() runs on ConnHdlr
+{
+ var template (value) PDU_SIP_Request req;
+ var template (present) PDU_SIP_Response exp_resp;
+ var Via via;
+ var charstring branch_value;
+
+ branch_value := f_sip_gen_branch(f_sip_SipAddr_to_str(g_pars.cp.from_addr),
+ f_sip_SipAddr_to_str(valueof(g_pars.cp.to_addr)),
+ g_pars.cp.sip_call_id,
+ g_pars.cp.sip_seq_nr);
+
+ via := g_pars.local_via;
+ via.viaBody[0].viaParams := f_sip_param_set(via.viaBody[0].viaParams,
"branch", branch_value);
+
+ /* Transmit ACK */
+ req := ts_SIP_BYE(g_pars.cp.sip_call_id,
+ g_pars.cp.from_addr,
+ g_pars.cp.to_addr,
+ via,
+ g_pars.cp.sip_seq_nr,
+ omit);
+ SIP.send(req);
+
+ /* Wait for OK answer */
+ exp_resp := tr_SIP_Response(
+ g_pars.cp.sip_call_id,
+ g_pars.cp.from_addr,
+ f_tr_To_response(g_pars.cp.to_addr),
+ f_tr_Via_response(via),
+ *,
+ "BYE", 200,
+ g_pars.cp.sip_seq_nr, "OK");
+ as_SIP_expect_resp(exp_resp);
+
+ g_pars.cp.sip_seq_nr := g_pars.cp.sip_seq_nr + 1;
+}
+
+/* Call is terminated by peer: */
+private altstep as_SIP_exp_call_hangup(template (present) integer exp_seq_nr := ?,
boolean fail_others := true) runs on ConnHdlr
+{
+ var template (present) PDU_SIP_Request exp_req :=
+ tr_SIP_BYE(f_tr_SipUrl_opt_defport(g_pars.local_sip_url_ext),
+ g_pars.cp.sip_call_id,
+ g_pars.cp.from_addr,
+ g_pars.cp.to_addr,
+ tr_Via_from(f_tr_HostPort(mp_remote_sip_host, mp_remote_sip_port)),
+ exp_seq_nr);
+ var charstring sip_expect_str := log2str(exp_req);
+
+ [] SIP.receive(exp_req) -> value g_rx_sip_req {
+ var template (value) PDU_SIP_Response tx_resp;
+ var charstring tx_sdp;
+ var Via via;
+
+ /* Update parameters: */
+ g_pars.cp.sip_seq_nr := g_rx_sip_req.msgHeader.cSeq.seqNumber;
+ /* "branch" has changed: */
+ via := g_rx_sip_req.msgHeader.via;
+
+ /* Tx 200 OK */
+ tx_sdp := f_gen_sdp();
+ tx_resp := ts_SIP_Response(g_pars.cp.sip_call_id,
+ g_pars.cp.from_addr,
+ g_pars.cp.to_addr,
+ "BYE", 200,
+ g_pars.cp.sip_seq_nr,
+ "OK",
+ via,
+ body := tx_sdp);
+ SIP.send(tx_resp);
+ }
+ [fail_others] as_SIP_fail_resp(sip_expect_str);
+ [fail_others] as_SIP_fail_req(sip_expect_str);
+}
+
/* Test SIP registration of local clients */
private function f_TC_internal_registration(charstring id) runs on ConnHdlr {
@@ -276,7 +650,6 @@
// f_SIP_deregister();
setverdict(pass);
}
-
testcase TC_internal_registration() runs on test_CT {
var ConnHdlrPars pars;
var ConnHdlr vc_conn;
@@ -286,6 +659,74 @@
vc_conn.done;
}
+/* Successful SIP MO-MT Call between local clients: */
+private function f_TC_internal_call_mo(charstring id) runs on ConnHdlr {
+
+ f_SIP_register();
+ COORD.send(COORD_CMD_REGISTERED);
+
+ COORD.receive(COORD_CMD_START);
+ f_SIP_mo_call_setup();
+ COORD.send(COORD_CMD_CALL_ESTABLISHED);
+
+ COORD.receive(COORD_CMD_HANGUP);
+ f_SIP_do_call_hangup();
+
+ setverdict(pass);
+}
+private function f_TC_internal_call_mt(charstring id) runs on ConnHdlr {
+
+ f_create_sip_expect(valueof(ts_SipUrl_from_Addr_Union(g_pars.cp.called.addr)));
+
+ f_SIP_register();
+ COORD.send(COORD_CMD_REGISTERED);
+
+ as_SIP_mt_call_accept();
+ COORD.send(COORD_CMD_CALL_ESTABLISHED);
+
+ /* Once MO hangs up, Asterisk updates us to point RTP to it: */
+ as_SIP_exp_call_update(g_pars.cp.sip_seq_nr + 1);
+ as_SIP_exp_call_hangup(g_pars.cp.sip_seq_nr + 1);
+
+ setverdict(pass);
+}
+testcase TC_internal_call_momt() runs on test_CT {
+ var ConnHdlrPars pars[2];
+ var ConnHdlr vc_conn[2];
+
+ f_init();
+
+ pars[0] := f_init_ConnHdlrPars(idx := 1);
+ pars[1] := f_init_ConnHdlrPars(idx := 2);
+
+ pars[0].cp.calling := pars[0].registrar_sip_record;
+ pars[0].cp.called := pars[1].registrar_sip_record;
+
+ pars[1].cp.calling := pars[0].registrar_sip_record;
+ pars[1].cp.called := pars[1].local_sip_record;
+
+ vc_conn[0] := f_start_handler(refers(f_TC_internal_call_mo), pars[0]);
+ vc_conn[1] := f_start_handler(refers(f_TC_internal_call_mt), pars[1]);
+
+ interleave {
+ [] COORD.receive(COORD_CMD_REGISTERED) from vc_conn[0];
+ [] COORD.receive(COORD_CMD_REGISTERED) from vc_conn[1];
+ }
+
+ COORD.send(COORD_CMD_START) to vc_conn[0];
+
+ interleave {
+ [] COORD.receive(COORD_CMD_CALL_ESTABLISHED) from vc_conn[0];
+ [] COORD.receive(COORD_CMD_CALL_ESTABLISHED) from vc_conn[1];
+ }
+
+ COORD.send(COORD_CMD_HANGUP) to vc_conn[0];
+
+
+ vc_conn[0].done;
+ vc_conn[1].done;
+}
+
testcase TC_selftest() runs on test_CT {
f_sip_digest_selftest();
setverdict(pass);
@@ -293,6 +734,7 @@
control {
execute( TC_internal_registration() );
+ execute( TC_internal_call_momt() );
}
}
diff --git a/asterisk/expected-results.xml b/asterisk/expected-results.xml
index c1d9e2e..3eb9c8f 100644
--- a/asterisk/expected-results.xml
+++ b/asterisk/expected-results.xml
@@ -1,4 +1,5 @@
<?xml version="1.0"?>
<testsuite name='Titan' tests='9' failures='0'
errors='0' skipped='0' inconc='0' time='MASKED'>
<testcase classname='Asterisk_Tests' name='TC_internal_registration'
time='MASKED'/>
+ <testcase classname='Asterisk_Tests' name='TC_internal_call_momt'
time='MASKED'/>
</testsuite>
diff --git a/library/SIP_Templates.ttcn b/library/SIP_Templates.ttcn
index 7de2d27..9a9b44c 100644
--- a/library/SIP_Templates.ttcn
+++ b/library/SIP_Templates.ttcn
@@ -52,8 +52,18 @@
headers := *
}
-template (value) SipUrl ts_SipUrlHost(template (value) charstring host)
- := ts_SipUrl(ts_HostPort(host));
+template (value) SipUrl ts_SipUrlHost(template (value) charstring host,
+ template (omit) integer portField := omit)
+ := ts_SipUrl(ts_HostPort(host, portField));
+
+function ts_SipUrl_from_Addr_Union(template (value) Addr_Union au)
+return template (value) SipUrl {
+ if (ischosen(au.nameAddr)) {
+ return au.nameAddr.addrSpec;
+ } else { /* au.addrSpecUnion */
+ return au.addrSpecUnion;
+ }
+}
template (value) Credentials ts_Credentials_DigestResponse(template (value)
CommaParam_List digestResponse) := {
digestResponse := digestResponse
@@ -212,27 +222,74 @@
}
/* build a receive template from a value: substitute '*' for omit */
-function tr_SipAddr_from_val(SipAddr tin) return template (present) SipAddr {
+function tr_SipUrl_from_val(template (value) SipUrl tin) return template (present) SipUrl
{
+ var template (present) SipUrl ret := tin;
+
+ /* if the port number is 5060, it may be omitted */
+ if (ispresent(tin.hostPort.portField) and
+ valueof(tin.hostPort.portField) == 5060) {
+ ret.hostPort.portField := 5060 ifpresent;
+ }
+ if (not ispresent(tin.userInfo.password)) {
+ ret.userInfo.password := *;
+ }
+
+ return ret;
+}
+function tr_SipAddr_from_val(template (value) SipAddr tin) return template (present)
SipAddr {
var template (present) SipAddr ret := tin;
- if (tin.addr.nameAddr.displayName == omit) {
+
+ if (not ispresent(tin.addr.nameAddr.displayName)) {
ret.addr.nameAddr.displayName := *;
+ } else if (f_str_tolower(f_sip_str_unquote(tin.addr.nameAddr.displayName)) ==
"anonymous") {
+ /* if the user is Anonymous, it may be omitted */
+ ret.addr.nameAddr.displayName := tin.addr.nameAddr.displayName ifpresent;
}
- if (tin.addr.nameAddr.addrSpec.userInfo.password == omit) {
- ret.addr.nameAddr.addrSpec.userInfo.password := *;
- }
- if (tin.params == omit) {
+
+ ret.addr.nameAddr.addrSpec := tr_SipUrl_from_val(tin.addr.nameAddr.addrSpec);
+
+ if (not ispresent(tin.params)) {
ret.params := *;
}
return ret;
}
+function ts_SipAddr_from_Addr_Union(template (value) Addr_Union au,
+ template (omit) SemicolonParam_List params := omit)
+return template (value) SipAddr {
+ var template (value) SipUrl addrSpec := ts_SipUrl_from_Addr_Union(au);
+ var template (omit) charstring displayName;
+
+ if (ischosen(au.nameAddr)) {
+ displayName := au.nameAddr.displayName;
+ } else { /* au.addrSpecUnion */
+ displayName := omit
+ }
+
+ return ts_SipAddr(addrSpec.hostPort,
+ addrSpec.userInfo,
+ displayName,
+ params);
+}
+
template (value) HostPort ts_HostPort(template (omit) charstring host := omit,
template (omit) integer portField := omit) := {
host := host,
portField := portField
}
-function tr_HostPort(template HostPort hp) return template HostPort {
- var template HostPort hpout := hp;
+
+template (present) HostPort tr_HostPort(template charstring host := *,
+ template integer portField := *) := {
+ host := host,
+ portField := portField
+}
+function f_tr_HostPort(template charstring host := *,
+ template integer portField := *)
+return template (present) HostPort {
+ return f_tr_HostPort_opt_defport(tr_HostPort(host, portField));
+}
+function f_tr_HostPort_opt_defport(template (present) HostPort hp) return template
(present) HostPort {
+ var template (present) HostPort hpout := hp;
/* if the port number is 5060, it may be omitted */
if (isvalue(hp.portField) and valueof(hp.portField) == 5060) {
hpout.portField := 5060 ifpresent;
@@ -240,6 +297,11 @@
return hpout;
}
+function f_tr_SipUrl_opt_defport(template (present) SipUrl url) return template (present)
SipUrl {
+ var template (present) SipUrl urlout := url;
+ urlout.hostPort := f_tr_HostPort_opt_defport(url.hostPort);
+ return urlout;
+}
template (value) UserInfo ts_UserInfo(template (value) charstring
userOrTelephoneSubscriber,
template (omit) charstring password := omit) := {
@@ -515,7 +577,7 @@
template charstring body := *) := {
requestLine := tr_SIP_ReqLine(REGISTER_E, sip_url_host_port),
msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, contact,
- tr_Via_from(tr_HostPort(from_addr.addr.nameAddr.addrSpec.hostPort)),
+
tr_Via_from(f_tr_HostPort_opt_defport(from_addr.addr.nameAddr.addrSpec.hostPort)),
"REGISTER", *, seq_nr,
expires := expires),
messageBody := body,
@@ -523,96 +585,102 @@
}
template (value) PDU_SIP_Request
-ts_SIP_INVITE(CallidString call_id,
- SipAddr from_addr,
- SipAddr to_addr,
+ts_SIP_INVITE(template (value) CallidString call_id,
+ template (value) SipAddr from_addr,
+ template (value) SipAddr to_addr,
+ template (value) Via via,
+ template (value) Contact contact,
integer seq_nr,
template (omit) charstring body := omit) := {
requestLine := ts_SIP_ReqLine(INVITE_E, to_addr.addr.nameAddr.addrSpec),
- msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr,
- ts_Contact_SipAddr(from_addr),
+ msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, contact,
"INVITE", seq_nr,
- ts_Via_from(from_addr.addr.nameAddr.addrSpec.hostPort),
+ via,
f_ContentTypeOrOmit(ts_CT_SDP, body)),
messageBody := body,
payload := omit
}
template (present) PDU_SIP_Request
-tr_SIP_INVITE(template CallidString call_id,
+tr_SIP_INVITE(template (present) SipUrl uri,
+ template CallidString call_id,
template SipAddr from_addr,
template SipAddr to_addr,
+ template Via via := tr_Via_from(f_tr_HostPort_opt_defport(?)),
template integer seq_nr,
template charstring body) := {
- requestLine := tr_SIP_ReqLine(INVITE_E, to_addr.addr.nameAddr.addrSpec),
+ requestLine := tr_SIP_ReqLine(INVITE_E, uri),
msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, ?,
- tr_Via_from(tr_HostPort(from_addr.addr.nameAddr.addrSpec.hostPort)),
- "INVITE", *, seq_nr),
+ via, "INVITE", *, seq_nr),
messageBody := body,
payload := omit
}
template (value) PDU_SIP_Request
ts_SIP_BYE(CallidString call_id,
- SipAddr from_addr,
- SipAddr to_addr,
+ template (value) SipAddr from_addr,
+ template (value) SipAddr to_addr,
+ template (value) Via via,
integer seq_nr,
template (omit) charstring body) := {
requestLine := ts_SIP_ReqLine(BYE_E, to_addr.addr.nameAddr.addrSpec),
msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, omit, "BYE",
seq_nr,
- ts_Via_from(from_addr.addr.nameAddr.addrSpec.hostPort),
- f_ContentTypeOrOmit(ts_CT_SDP, body)),
+ via, f_ContentTypeOrOmit(ts_CT_SDP, body)),
messageBody := body,
payload := omit
}
template (present) PDU_SIP_Request
-tr_SIP_BYE(template CallidString call_id,
+tr_SIP_BYE(template (present) SipUrl uri,
+ template CallidString call_id,
template SipAddr from_addr,
template SipAddr to_addr,
+ template Via via,
template integer seq_nr,
- template charstring body) := {
- requestLine := tr_SIP_ReqLine(BYE_E, to_addr.addr.nameAddr.addrSpec),
+ template charstring body := *) := {
+ requestLine := tr_SIP_ReqLine(BYE_E, uri),
msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, omit,
- tr_Via_from(tr_HostPort(from_addr.addr.nameAddr.addrSpec.hostPort)),
- "BYE", *, seq_nr),
+ via, "BYE", *, seq_nr),
messageBody := body,
payload := omit
}
template (value) PDU_SIP_Request
-ts_SIP_ACK(CallidString call_id,
- SipAddr from_addr,
- SipAddr to_addr,
+ts_SIP_ACK(template (value) CallidString call_id,
+ template (value) SipAddr from_addr,
+ template (value) SipAddr to_addr,
+ template (value) Via via,
integer seq_nr,
template (omit) charstring body) := {
requestLine := ts_SIP_ReqLine(ACK_E, to_addr.addr.nameAddr.addrSpec),
msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr,
ts_Contact_SipAddr(from_addr),
"ACK", seq_nr,
- ts_Via_from(from_addr.addr.nameAddr.addrSpec.hostPort),
+ via,
f_ContentTypeOrOmit(ts_CT_SDP, body)),
messageBody := body,
payload := omit
}
template (present) PDU_SIP_Request
-tr_SIP_ACK(template CallidString call_id,
+tr_SIP_ACK(template (present) SipUrl uri,
+ template CallidString call_id,
template SipAddr from_addr,
template SipAddr to_addr,
+ template Via via,
template integer seq_nr,
template charstring body) := {
- requestLine := tr_SIP_ReqLine(ACK_E, to_addr.addr.nameAddr.addrSpec),
+ requestLine := tr_SIP_ReqLine(ACK_E, uri),
msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, *,
- tr_Via_from(tr_HostPort(from_addr.addr.nameAddr.addrSpec.hostPort)),
+ via,
"ACK", *, seq_nr),
messageBody := body,
payload := omit
}
template (value) PDU_SIP_Response
-ts_SIP_Response(CallidString call_id,
- SipAddr from_addr,
- SipAddr to_addr,
+ts_SIP_Response(template (value) CallidString call_id,
+ template (value) SipAddr from_addr,
+ template (value) SipAddr to_addr,
charstring method,
integer status_code,
integer seq_nr,
@@ -626,6 +694,23 @@
payload := omit
}
+/* 180 Ringing */
+template (value) PDU_SIP_Response
+ts_SIP_Response_Ringing(
+ template (value) CallidString call_id,
+ template (value) SipAddr from_addr,
+ template (value) SipAddr to_addr,
+ Via via,
+ integer seq_nr,
+ charstring method := "INVITE",
+ template (omit) charstring body := omit) := {
+ statusLine := ts_SIP_StatusLine(180, "Ringing"),
+ msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, omit, method, seq_nr,
+ via, f_ContentTypeOrOmit(ts_CT_SDP, body)),
+ messageBody := body,
+ payload := omit
+}
+
template (present) PDU_SIP_Response
tr_SIP_Response(template CallidString call_id,
template SipAddr from_addr,
@@ -645,9 +730,9 @@
payload := omit
}
-/* Expect during first REGISTER when authorization is required: */
+/* Expect during first REGISTER/INVITE/... when authorization is required: */
template (present) PDU_SIP_Response
-tr_SIP_Response_REGISTER_Unauthorized(
+tr_SIP_Response_Unauthorized(
template CallidString call_id,
template SipAddr from_addr,
template SipAddr to_addr,
@@ -668,6 +753,50 @@
payload := omit
}
+/* 100 Trying */
+template (present) PDU_SIP_Response
+tr_SIP_Response_Trying(
+ template CallidString call_id,
+ template SipAddr from_addr,
+ template SipAddr to_addr,
+ template (present) Via via := tr_Via_from(?),
+ template integer seq_nr := ?,
+ template charstring method := "INVITE",
+ template integer status_code := 100,
+ template charstring reason := "Trying",
+ template charstring body := *) := {
+ statusLine := tr_SIP_StatusLine(status_code, reason),
+ msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, omit,
+ via,
+ method, *, seq_nr),
+ messageBody := body,
+ payload := omit
+}
+
+/* 180 Ringing */
+template (present) PDU_SIP_Response
+tr_SIP_Response_Ringing(
+ template CallidString call_id,
+ template SipAddr from_addr,
+ template SipAddr to_addr,
+ template (present) Via via := tr_Via_from(?),
+ template integer seq_nr := ?,
+ template charstring method := "INVITE",
+ template integer status_code := 180,
+ template charstring reason := "Ringing",
+ template charstring body := *) := {
+ statusLine := tr_SIP_StatusLine(status_code, reason),
+ msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, *,
+ via,
+ method, *, seq_nr),
+ messageBody := body,
+ payload := omit
+}
+
+/****************
+ * FUNCTIONS:
+ ****************/
+
function f_sip_param_find(GenericParam_List li,
template (present) charstring id := ?)
return template (omit) GenericParam {
@@ -998,6 +1127,14 @@
return f_rnd_int(2147483648)
}
+function f_sip_next_seq_nr(integer seq_nr) return integer {
+ return (seq_nr + 1) mod 2147483648;
+}
+
+function f_sip_Request_inc_seq_nr(inout template (value) PDU_SIP_Request req) {
+ req.msgHeader.cSeq.seqNumber :=
f_sip_next_seq_nr(valueof(req.msgHeader.cSeq.seqNumber));
+}
+
/* Tags shall have at least 32 bit of randomness */
function f_sip_rand_tag() return charstring {
var integer rnd_int := f_rnd_int(4294967296);
diff --git a/sip/SIP_Tests.ttcn b/sip/SIP_Tests.ttcn
index 2164ef0..95f09e8 100644
--- a/sip/SIP_Tests.ttcn
+++ b/sip/SIP_Tests.ttcn
@@ -267,7 +267,9 @@
/* OSC <- SIP: A party sends SIP invite for a MT-call into OSC */
SIP.send(ts_SIP_INVITE(cp.comp.sip_call_id, cp.comp.sip_url_ext, cp.comp.sip_url_gsm,
- cp.comp.sip_seq_nr, cp.comp.sip_body));
+ ts_Via_from(cp.comp.sip_url_ext.addr.nameAddr.addrSpec.hostPort),
+ ts_Contact_SipAddr(cp.comp.sip_url_ext),
+ cp.comp.sip_seq_nr, cp.comp.sip_body));
if (cp.mncc_with_sdp) {
/* We just sent SDP via SIP, now expect the same SDP in MNCC to the MSC */
expect_sdp_to_msc := cp.comp.sip_body;
@@ -275,7 +277,7 @@
/* OSC -> SIP */
as_SIP_expect_resp(tr_SIP_Response(cp.comp.sip_call_id, sip_addr_ext, sip_addr_gsm,
- tr_Via_from(tr_HostPort(sip_addr_ext.addr.nameAddr.addrSpec.hostPort)),
+
tr_Via_from(f_tr_HostPort_opt_defport(sip_addr_ext.addr.nameAddr.addrSpec.hostPort)),
*,
"INVITE", 100, ?, "Trying", *));
@@ -288,7 +290,9 @@
}
[] SIP.receive {
setverdict(fail, "Received unexpected SIP response");
- SIP.send(ts_SIP_ACK(cp.comp.sip_call_id, cp.comp.sip_url_ext, cp.comp.sip_url_gsm,
+ SIP.send(ts_SIP_ACK(cp.comp.sip_call_id,
+ cp.comp.sip_url_ext, cp.comp.sip_url_gsm,
+ ts_Via_from(cp.comp.sip_url_ext.addr.nameAddr.addrSpec.hostPort),
cp.comp.sip_seq_nr, omit));
mtc.stop;
}
@@ -331,7 +335,7 @@
/* 180 Ringing should not contain any SDP. */
as_SIP_expect_resp(tr_SIP_Response(cp.comp.sip_call_id, sip_addr_ext, sip_addr_gsm,
- tr_Via_from(tr_HostPort(sip_addr_ext.addr.nameAddr.addrSpec.hostPort)),
+
tr_Via_from(f_tr_HostPort_opt_defport(sip_addr_ext.addr.nameAddr.addrSpec.hostPort)),
*,
"INVITE", 180, ?, "Ringing", omit));
@@ -347,14 +351,16 @@
/* OSC -> SIP: OSC confirms call establishment to SIP side */
as_SIP_expect_resp(tr_SIP_Response(cp.comp.sip_call_id, sip_addr_ext, sip_addr_gsm,
- tr_Via_from(tr_HostPort(sip_addr_ext.addr.nameAddr.addrSpec.hostPort)),
+
tr_Via_from(f_tr_HostPort_opt_defport(sip_addr_ext.addr.nameAddr.addrSpec.hostPort)),
contact := ?,
method := "INVITE", status_code := 200,
seq_nr := ?, reason := "OK",
body := expect_sdp_to_sip));
/* OSC <- SIP: SIP world acknowledges "200 OK" */
- SIP.send(ts_SIP_ACK(cp.comp.sip_call_id, cp.comp.sip_url_ext, cp.comp.sip_url_gsm,
+ SIP.send(ts_SIP_ACK(cp.comp.sip_call_id,
+ cp.comp.sip_url_ext, cp.comp.sip_url_gsm,
+ ts_Via_from(cp.comp.sip_url_ext.addr.nameAddr.addrSpec.hostPort),
cp.comp.sip_seq_nr, omit));
/* MSC <- OSC: OSC sends SETUP COMPL to MNCC (which triggers CC CONNECT ACK */
MNCC.receive(tr_MNCC_SETUP_COMPL_req(cp.mncc_call_id)) -> value mncc {
@@ -430,7 +436,10 @@
* "a=sendrecv;" */
expect_sdp_to_sip := pattern cn_sdp & "*";
}
- sip_req := f_SIP_expect_req(tr_SIP_INVITE(?, sip_addr_gsm, sip_addr_ext, ?,
expect_sdp_to_sip));
+ sip_req := f_SIP_expect_req(tr_SIP_INVITE(sip_addr_ext.addr.nameAddr.addrSpec, ?,
+ sip_addr_gsm, sip_addr_ext,
+
tr_Via_from(f_tr_HostPort_opt_defport(sip_addr_gsm.addr.nameAddr.addrSpec.hostPort)),
+ ?, expect_sdp_to_sip));
cp.comp.sip_url_gsm.params := sip_req.msgHeader.fromField.fromParams;
cp.comp.sip_call_id := sip_req.msgHeader.callId.callid;
seq_nr := sip_req.msgHeader.cSeq.seqNumber;
@@ -474,7 +483,12 @@
/* MSC -> OSC: CC CONNECT ACK was received from MS */
MNCC.send(ts_MNCC_SETUP_COMPL_ind(cp.mncc_call_id));
/* OSC -> SIP: Acknowledge the call */
- SIP.receive(tr_SIP_ACK(cp.comp.sip_call_id, sip_addr_gsm, sip_addr_ext, ?, omit));
+ SIP.receive(tr_SIP_ACK(sip_addr_ext.addr.nameAddr.addrSpec,
+ cp.comp.sip_call_id,
+ sip_addr_gsm,
+ sip_addr_ext,
+
tr_Via_from(f_tr_HostPort_opt_defport(sip_addr_gsm.addr.nameAddr.addrSpec.hostPort)),
+ ?, omit));
}
/* Release call from the mobile side */
@@ -487,7 +501,10 @@
MNCC.send(ts_MNCC_DISC_ind(cp.mncc_call_id, ts_MNCC_cause(0)));
/* OSC -> SIP: Expect BYE from OSC to SIP side */
- sip_req := f_SIP_expect_req(tr_SIP_BYE(cp.comp.sip_call_id, sip_addr_gsm, sip_addr_ext,
?, *));
+ sip_req := f_SIP_expect_req(tr_SIP_BYE(sip_addr_ext.addr.nameAddr.addrSpec,
+ cp.comp.sip_call_id, sip_addr_gsm, sip_addr_ext,
+
tr_Via_from(f_tr_HostPort_opt_defport(sip_addr_gsm.addr.nameAddr.addrSpec.hostPort)),
+ ?, *));
cp.comp.sip_url_gsm.params := sip_req.msgHeader.fromField.fromParams;
/* OSC <- SIP: Acknowledge the BYE */
@@ -506,6 +523,7 @@
var template SipAddr sip_addr_ext := tr_SipAddr_from_val(cp.comp.sip_url_ext);
/* OSC <- SIP: SIP-side sends a BYE to OSC */
SIP.send(ts_SIP_BYE(cp.comp.sip_call_id, cp.comp.sip_url_ext, cp.comp.sip_url_gsm,
+ ts_Via_from(cp.comp.sip_url_ext.addr.nameAddr.addrSpec.hostPort),
cp.comp.sip_seq_nr, omit));
/* MSC <- OSC: Expect OSC to cause MNCC Disconnect Request */
MNCC.receive(tr_MNCC_DISC_req(cp.mncc_call_id));
@@ -513,7 +531,7 @@
MNCC.send(ts_MNCC_REL_ind(cp.mncc_call_id, ts_MNCC_cause(0)));
/* OSC -> SIP: Confirmation to SIP side */
as_SIP_expect_resp(tr_SIP_Response(cp.comp.sip_call_id, sip_addr_ext, sip_addr_gsm,
- tr_Via_from(tr_HostPort(sip_addr_ext.addr.nameAddr.addrSpec.hostPort)),
+
tr_Via_from(f_tr_HostPort_opt_defport(sip_addr_ext.addr.nameAddr.addrSpec.hostPort)),
*,
"BYE", 200, cp.comp.sip_seq_nr, "OK", omit));
}
@@ -682,7 +700,10 @@
timer T := 10.0;
T.start;
alt {
- [] SIP.receive(tr_SIP_INVITE(?, sip_addr_gsm, sip_addr_ext, ?, ?)) {
+ [] SIP.receive(tr_SIP_INVITE(sip_addr_ext.addr.nameAddr.addrSpec, ?,
+ sip_addr_gsm, sip_addr_ext,
+
tr_Via_from(f_tr_HostPort_opt_defport(sip_addr_gsm.addr.nameAddr.addrSpec.hostPort)),
+ ?, ?)) {
setverdict(fail, "Received unexpected INVITE");
}
[] T.timeout {
--
To view, visit
https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/36547?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-ttcn3-hacks
Gerrit-Branch: master
Gerrit-Change-Id: Ic5827a3e94b06fbc57f6405bf0f0aa6598c5d1fe
Gerrit-Change-Number: 36547
Gerrit-PatchSet: 4
Gerrit-Owner: pespin <pespin(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-Reviewer: jolly <andreas(a)eversberg.eu>
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: osmith <osmith(a)sysmocom.de>
Gerrit-Reviewer: pespin <pespin(a)sysmocom.de>
Gerrit-MessageType: merged