pespin has uploaded this change for review. ( 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 library/SIP_Emulation.ttcn M library/SIP_Templates.ttcn M sip/SIP_Tests.ttcn 4 files changed, 728 insertions(+), 114 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-ttcn3-hacks refs/changes/47/36547/1 diff --git a/asterisk/Asterisk_Tests.ttcn b/asterisk/Asterisk_Tests.ttcn index dab9400..910fc79 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); + 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)); } } -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,72 @@ 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 +732,7 @@ control { execute( TC_internal_registration() ); + execute( TC_internal_call_momt() ); } } diff --git a/library/SIP_Emulation.ttcn b/library/SIP_Emulation.ttcn index 4aef536..559b575 100644 --- a/library/SIP_Emulation.ttcn +++ b/library/SIP_Emulation.ttcn @@ -237,7 +237,7 @@ create_cb := refers(SIP_Emulation.ExpectedCreateCallback) }; - ct := SIP_Emulation_CT.create(id); + ct := SIP_Emulation_CT.create(id) alive; map(ct:SIP, system:SIP); ct.start(SIP_Emulation.main(ops, id)); } 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 4c6be1c..95f09e8 100644 --- a/sip/SIP_Tests.ttcn +++ b/sip/SIP_Tests.ttcn @@ -122,7 +122,7 @@ unitdata_cb := refers(MNCC_Emulation.DummyUnitdataCallback) }; - vc_MNCC := MNCC_Emulation_CT.create(id); + vc_MNCC := MNCC_Emulation_CT.create(id) alive; map(vc_MNCC:MNCC, system:MNCC_CODEC_PT); vc_MNCC.start(MNCC_Emulation.main(ops, id, mp_mncc, true)); } @@ -147,7 +147,7 @@ var ConnHdlr vc_conn; var charstring id := testcasename(); - vc_conn := ConnHdlr.create(id); + vc_conn := ConnHdlr.create(id) alive; connect(vc_conn:SIP, vc_SIP:CLIENT); connect(vc_conn:SIP_PROC, vc_SIP:CLIENT_PROC); @@ -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: 1 Gerrit-Owner: pespin <pes...@sysmocom.de> Gerrit-MessageType: newchange