blob: ebf19146ada742a5479a781842ec945d0914aec4 [file] [log] [blame]
Pau Espin Pedrol37ee0ed2024-03-28 21:17:12 +01001module Asterisk_Tests {
2
3/* Asterisk test suite in TTCN-3
4 * (C) 2024 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
5 * All rights reserved.
6 * Author: Pau Espin Pedrol <pespin@sysmocom.de>
7 *
8 * Released under the terms of GNU General Public License, Version 2 or
9 * (at your option) any later version.
10 *
11 * SPDX-License-Identifier: GPL-2.0-or-later
12 */
13
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +020014import from TCCOpenSecurity_Functions all;
Pau Espin Pedrol37ee0ed2024-03-28 21:17:12 +010015import from General_Types all;
16import from Osmocom_Types all;
17import from Native_Functions all;
18import from Misc_Helpers all;
19
20import from SDP_Types all;
21import from SDP_Templates all;
22
23import from SIP_Emulation all;
24import from SIPmsg_Types all;
25import from SIP_Templates all;
26
27modulepar {
28 charstring mp_local_sip_host := "127.0.0.2";
29 integer mp_local_sip_port := 5060;
30 charstring mp_remote_sip_host := "127.0.0.1";
31 integer mp_remote_sip_port := 5060;
32}
33
34type component test_CT {
35 var SIP_Emulation_CT vc_SIP;
36}
37
38type component ConnHdlr extends SIP_ConnHdlr {
39 var ConnHdlrPars g_pars;
40 timer g_Tguard;
41 var PDU_SIP_Request g_rx_sip_req;
42 var PDU_SIP_Response g_rx_sip_resp;
43}
44
45type record ConnHdlrPars {
46 float t_guard,
47 charstring user,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +020048 charstring password,
Pau Espin Pedrol37ee0ed2024-03-28 21:17:12 +010049 SipUrl registrar_sip_url,
50 SipAddr registrar_sip_record,
51 CallidString registrar_sip_call_id,
52 Via registrar_via,
53 integer registrar_sip_seq_nr,
54 SipAddr sip_url_ext,
55 Contact local_contact,
56 CallPars cp optional
57}
58
59template (value) ConnHdlrPars t_Pars(charstring user,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +020060 charstring displayname := "\"Anonymous\"",
61 charstring password := "secret") := {
Pau Espin Pedrol37ee0ed2024-03-28 21:17:12 +010062 t_guard := 30.0,
63 user := user,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +020064 password := password,
Pau Espin Pedrol37ee0ed2024-03-28 21:17:12 +010065 registrar_sip_url := valueof(ts_SipUrlHost(mp_remote_sip_host)),
66 registrar_sip_record := ts_SipAddr(ts_HostPort(mp_remote_sip_host),
67 ts_UserInfo(user),
68 displayName := displayname),
69 registrar_sip_call_id := hex2str(f_rnd_hexstring(15)) & "@" & mp_local_sip_host,
70 registrar_via := ts_Via_from(ts_HostPort(mp_local_sip_host, mp_local_sip_port)),
71 registrar_sip_seq_nr := f_sip_rand_seq_nr(),
72 sip_url_ext := ts_SipAddr(ts_HostPort(mp_local_sip_host, mp_local_sip_port),
73 ts_UserInfo(user)),
74 local_contact := valueof(ts_Contact({
75 ts_ContactAddress(
76 ts_Addr_Union_SipUrl(ts_SipUrl(ts_HostPort(
77 mp_local_sip_host,
78 mp_local_sip_port),
79 ts_UserInfo(user))),
80 omit)
81 })),
82 cp := omit
83}
84
85function f_init_ConnHdlrPars(integer idx := 1) runs on test_CT return ConnHdlrPars {
Pau Espin Pedrol95058fd2024-04-02 11:56:48 +020086 var ConnHdlrPars pars := valueof(t_Pars("0" & int2str(500 + idx)));
Pau Espin Pedrol37ee0ed2024-03-28 21:17:12 +010087 return pars;
88}
89
90type record CallPars {
91 boolean is_mo,
92 charstring calling,
93 charstring called,
94
95 CallParsComputed comp optional,
96
97 charstring sip_rtp_addr,
98 uint16_t sip_rtp_port,
99 charstring cn_rtp_addr,
100 uint16_t cn_rtp_port
101}
102
103type record CallParsComputed {
104 CallidString sip_call_id,
105 charstring sip_body,
106 integer sip_seq_nr
107}
108
109private template (value) CallPars t_CallPars(boolean is_mo) := {
110 is_mo := is_mo,
111 calling := "12345",
112 called := "98766",
113 comp := {
114 sip_call_id := hex2str(f_rnd_hexstring(15)),
115 sip_body := "",
116 sip_seq_nr := f_sip_rand_seq_nr()
117 },
118 sip_rtp_addr := "1.2.3.4",
119 sip_rtp_port := 1234,
120 cn_rtp_addr := "5.6.7.8",
121 cn_rtp_port := 5678
122}
123
124function f_init() runs on test_CT {
125 f_init_sip(vc_SIP, "Asterisk_Test");
126 log("end of f_init");
127}
128
129type function void_fn(charstring id) runs on ConnHdlr;
130
131function f_start_handler(void_fn fn, ConnHdlrPars pars)
132runs on test_CT return ConnHdlr {
133 var ConnHdlr vc_conn;
134 var charstring id := testcasename();
135
Pau Espin Pedrole94a6482024-04-10 13:37:55 +0200136 vc_conn := ConnHdlr.create(id) alive;
Pau Espin Pedrol37ee0ed2024-03-28 21:17:12 +0100137
138 connect(vc_conn:SIP, vc_SIP:CLIENT);
139 connect(vc_conn:SIP_PROC, vc_SIP:CLIENT_PROC);
140
141 vc_conn.start(f_handler_init(fn, id, pars));
142 return vc_conn;
143}
144
145private altstep as_Tguard() runs on ConnHdlr {
146 [] g_Tguard.timeout {
147 setverdict(fail, "Tguard timeout");
148 mtc.stop;
149 }
150}
151
152private function f_handler_init(void_fn fn, charstring id, ConnHdlrPars pars)
153runs on ConnHdlr {
154 g_pars := pars;
155 g_Tguard.start(pars.t_guard);
156 activate(as_Tguard());
157
158 // Make sure the UA is deregistered before starting the test:
159 // sends REGISTER with Contact = "*" and Expires = 0
160 //f_SIP_deregister();
161
162 /* call the user-supied test case function */
163 fn.apply(id);
164}
165
166altstep as_SIP_expect_req(template PDU_SIP_Request sip_expect) runs on ConnHdlr
167{
168 [] SIP.receive(sip_expect) -> value g_rx_sip_req;
169 [] SIP.receive {
170 log("FAIL: expected SIP message ", sip_expect);
171 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received unexpected SIP message");
172 }
173}
174
175altstep as_SIP_expect_resp(template PDU_SIP_Response sip_expect) runs on ConnHdlr
176{
177 [] SIP.receive(sip_expect) -> value g_rx_sip_resp;
178 [] SIP.receive {
179 log("FAIL: expected SIP message ", sip_expect);
180 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received unexpected SIP message");
181 }
182}
183
184private function f_tr_Via_response(Via via_req) return template (present) Via {
185 template (present) SemicolonParam_List via_resp_params := ?;
186
187 /*via_resp_params := {
188 { id := "rport", paramValue := int2str(mp_remote_sip_port) },
189 { id := "received", paramValue := mp_remote_sip_host }
190 }; */
191 return tr_Via_from(via_req.viaBody[0].sentBy,
192 via_resp_params);
193}
194
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +0200195private function f_tr_To_response(SipAddr to_req) return template (present) SipAddr {
196 return tr_SipAddr_from_val(to_req);
197}
198
Pau Espin Pedrol37ee0ed2024-03-28 21:17:12 +0100199function f_SIP_register() runs on ConnHdlr return PDU_SIP_Response
200{
201 var template (present) PDU_SIP_Response exp;
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +0200202 var Authorization authorization;
203 var Via via := g_pars.registrar_via;
204 var SipAddr from_sipaddr := g_pars.registrar_sip_record;
205 var charstring branch_value;
Pau Espin Pedrol37ee0ed2024-03-28 21:17:12 +0100206
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +0200207 branch_value := f_sip_gen_branch(f_sip_SipAddr_to_str(g_pars.registrar_sip_record),
208 f_sip_SipAddr_to_str(g_pars.registrar_sip_record),
209 g_pars.registrar_sip_call_id,
210 g_pars.registrar_sip_seq_nr);
211
212 via.viaBody[0].viaParams := f_sip_param_set(via.viaBody[0].viaParams, "branch", branch_value);
213 from_sipaddr.params := f_sip_param_set(from_sipaddr.params, "tag", f_sip_rand_tag());
Pau Espin Pedrol37ee0ed2024-03-28 21:17:12 +0100214 SIP.send(ts_SIP_REGISTER(g_pars.registrar_sip_url,
215 g_pars.registrar_sip_call_id,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +0200216 from_sipaddr,
Pau Espin Pedrol37ee0ed2024-03-28 21:17:12 +0100217 g_pars.registrar_sip_record,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +0200218 via,
Pau Espin Pedrol37ee0ed2024-03-28 21:17:12 +0100219 g_pars.registrar_sip_seq_nr,
220 g_pars.local_contact,
221 ts_Expires("7200")));
222
223 exp := tr_SIP_Response_REGISTER_Unauthorized(
224 g_pars.registrar_sip_call_id,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +0200225 from_sipaddr,
226 f_tr_To_response(g_pars.registrar_sip_record),
227 f_tr_Via_response(via),
Pau Espin Pedrol37ee0ed2024-03-28 21:17:12 +0100228 *,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +0200229 tr_WwwAuthenticate({tr_Challenge_digestCln(?)}),
Pau Espin Pedrol37ee0ed2024-03-28 21:17:12 +0100230 g_pars.registrar_sip_seq_nr);
231 as_SIP_expect_resp(exp);
232
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +0200233 /* Digest Auth: RFC 2617 */
234 authorization := f_sip_digest_gen_Authorization(g_rx_sip_resp.msgHeader.wwwAuthenticate,
235 g_pars.user, g_pars.password,
236 "REGISTER", "sip:" & mp_remote_sip_host)
237
238 /* New transaction: */
239 g_pars.registrar_sip_seq_nr := g_pars.registrar_sip_seq_nr + 1;
240 branch_value := f_sip_gen_branch(f_sip_SipAddr_to_str(g_pars.registrar_sip_record),
241 f_sip_SipAddr_to_str(g_pars.registrar_sip_record),
242 g_pars.registrar_sip_call_id,
243 g_pars.registrar_sip_seq_nr);
244 via.viaBody[0].viaParams := f_sip_param_set(via.viaBody[0].viaParams, "branch", branch_value);
245
246 SIP.send(ts_SIP_REGISTER(g_pars.registrar_sip_url,
247 g_pars.registrar_sip_call_id,
248 from_sipaddr,
249 g_pars.registrar_sip_record,
250 via,
251 g_pars.registrar_sip_seq_nr,
252 g_pars.local_contact,
253 ts_Expires("7200"),
254 authorization := authorization));
255
256 /* Wait for OK answer */
257 exp := tr_SIP_Response(
258 g_pars.registrar_sip_call_id,
259 from_sipaddr,
260 f_tr_To_response(g_pars.registrar_sip_record),
261 f_tr_Via_response(via),
262 *,
263 "REGISTER", 200,
264 g_pars.registrar_sip_seq_nr, "OK");
265 as_SIP_expect_resp(exp);
266
267 /* Prepare for next use: */
268 g_pars.registrar_sip_seq_nr := g_pars.registrar_sip_seq_nr + 1;
Pau Espin Pedrol37ee0ed2024-03-28 21:17:12 +0100269 return g_rx_sip_resp;
270}
271
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +0200272/* Test SIP registration of local clients */
Pau Espin Pedrol37ee0ed2024-03-28 21:17:12 +0100273private function f_TC_internal_registration(charstring id) runs on ConnHdlr {
274
275 f_SIP_register();
Pau Espin Pedrol37ee0ed2024-03-28 21:17:12 +0100276 // f_SIP_deregister();
277 setverdict(pass);
278}
279
280testcase TC_internal_registration() runs on test_CT {
281 var ConnHdlrPars pars;
282 var ConnHdlr vc_conn;
283 f_init();
284 pars := f_init_ConnHdlrPars();
285 vc_conn := f_start_handler(refers(f_TC_internal_registration), pars);
286 vc_conn.done;
287}
288
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +0200289testcase TC_selftest() runs on test_CT {
290 f_sip_digest_selftest();
291 setverdict(pass);
292}
293
Pau Espin Pedrol37ee0ed2024-03-28 21:17:12 +0100294control {
295 execute( TC_internal_registration() );
296}
297
298}