blob: 516944a82cb953d8a3ff10238f6a7cd918c3b4af [file] [log] [blame]
Harald Welte00a067f2017-09-13 23:27:17 +02001module MGCP_Test {
Harald Weltef07c2862017-11-18 17:16:24 +01002 import from Osmocom_Types all;
Harald Welte00a067f2017-09-13 23:27:17 +02003 import from MGCP_Types all;
Harald Welte4029e8c2017-11-23 22:00:42 +01004 import from MGCP_Templates all;
Harald Welte3c6ebb92017-09-16 00:56:57 +08005 import from SDP_Types all;
6 import from MGCP_CodecPort all;
7 import from MGCP_CodecPort_CtrlFunct all;
Harald Weltef07c2862017-11-18 17:16:24 +01008 import from RTP_CodecPort all;
9 import from RTP_CodecPort_CtrlFunct all;
10 import from RTP_Endpoint all;
Harald Welte3c6ebb92017-09-16 00:56:57 +080011 import from IPL4asp_Types all;
Harald Welte00a067f2017-09-13 23:27:17 +020012
Harald Welte21ba5572017-09-19 17:55:05 +080013 /* any variables declared in the component will be available to
14 * all functions that 'run on' the named component, similar to
15 * class members in C++ */
Harald Welte00a067f2017-09-13 23:27:17 +020016 type component dummy_CT {
Harald Welte3c6ebb92017-09-16 00:56:57 +080017 port MGCP_CODEC_PT MGCP;
Harald Weltef07c2862017-11-18 17:16:24 +010018 port RTP_CODEC_PT RTP;
Harald Welte3c6ebb92017-09-16 00:56:57 +080019 var boolean initialized := false;
Harald Welte55015362017-11-18 16:02:42 +010020 var ConnectionId g_mgcp_conn_id := -1;
Harald Weltee1e18c52017-09-17 16:23:07 +080021 var integer g_trans_id;
Harald Weltef07c2862017-11-18 17:16:24 +010022
23 var RtpEndpoint g_rtp_ep[2];
Harald Welte00a067f2017-09-13 23:27:17 +020024 };
25
Harald Weltee1e18c52017-09-17 16:23:07 +080026 function get_next_trans_id() runs on dummy_CT return MgcpTransId {
27 var MgcpTransId tid := int2str(g_trans_id);
28 g_trans_id := g_trans_id + 1;
29 return tid;
30 }
31
Harald Welte21ba5572017-09-19 17:55:05 +080032 /* all parameters declared here can be modified / overridden by
33 * the config file in the [MODULE_PARAMETERS] section. If no
34 * config file is used or the file doesn't specify them, the
35 * default values assigned below are used */
Harald Welte3c6ebb92017-09-16 00:56:57 +080036 modulepar {
37 PortNumber mp_local_udp_port := 2727;
38 charstring mp_local_ip := "127.0.0.1";
39 PortNumber mp_remote_udp_port := 2427;
40 charstring mp_remote_ip := "127.0.0.1";
Harald Weltef07c2862017-11-18 17:16:24 +010041 PortNumber mp_local_rtp_port_base := 10000;
Harald Welte3c6ebb92017-09-16 00:56:57 +080042 }
43
Harald Welte21ba5572017-09-19 17:55:05 +080044 /* initialization function, called by each test case at the
45 * beginning, but 'initialized' variable ensures its body is
46 * only executed once */
Harald Welteedc45c12017-11-18 19:15:05 +010047 private function f_init(template MgcpEndpoint ep := omit) runs on dummy_CT {
Harald Welte3c6ebb92017-09-16 00:56:57 +080048 var Result res;
Harald Weltef07c2862017-11-18 17:16:24 +010049 var uint32_t ssrc;
Harald Welteedc45c12017-11-18 19:15:05 +010050 if (initialized == false) {
51 initialized := true;
52
53 /* some random number for the initial transaction id */
54 g_trans_id := float2int(rnd()*65535.0);
55 map(self:MGCP, system:MGCP_CODEC_PT);
56 /* connect the MGCP test port using the given
57 * source/destionation ip/port and store the connection id in g_mgcp_conn_id
58 * */
59 res := MGCP_CodecPort_CtrlFunct.f_IPL4_connect(MGCP, mp_remote_ip, mp_remote_udp_port, mp_local_ip, mp_local_udp_port, 0, { udp := {} });
60 g_mgcp_conn_id := res.connId;
61
62 map(self:RTP, system:RTP_CODEC_PT);
63 ssrc := float2int(rnd()*4294967296.0);
64 rtp_endpoint_init(g_rtp_ep[0], mp_local_ip, mp_local_rtp_port_base, ssrc);
65 rtp_endpoint_bind(RTP, g_rtp_ep[0]);
66 rtp_endpoint_init(g_rtp_ep[1], mp_local_ip, mp_local_rtp_port_base+2, ssrc);
67 rtp_endpoint_bind(RTP, g_rtp_ep[1]);
Harald Welte3c6ebb92017-09-16 00:56:57 +080068 }
Harald Welte3c6ebb92017-09-16 00:56:57 +080069
Harald Welteedc45c12017-11-18 19:15:05 +010070 if (isvalue(ep)) {
71 /* do a DLCX on all connections of the EP */
72 f_dlcx_ignore(valueof(ep));
73 }
Harald Welte3c6ebb92017-09-16 00:56:57 +080074 }
75
Harald Welte00a067f2017-09-13 23:27:17 +020076 testcase TC_selftest() runs on dummy_CT {
77 const charstring c_auep := "AUEP 158663169 ds/e1-1/2@172.16.6.66 MGCP 1.0\r\n";
78 const charstring c_mdcx3 := "MDCX 18983215 1@mgw MGCP 1.0\r\n";
79 const charstring c_mdcx3_ret := "200 18983215 OK\r\n" &
80 "I: 1\n" &
81 "\n" &
82 "v=0\r\n" &
83 "o=- 1 23 IN IP4 0.0.0.0\r\n" &
84 "s=-\r\n" &
85 "c=IN IP4 0.0.0.0\r\n" &
86 "t=0 0\r\n" &
87 "m=audio 0 RTP/AVP 126\r\n" &
88 "a=rtpmap:126 AMR/8000\r\n" &
89 "a=ptime:20\r\n";
90 const charstring c_mdcx4 := "MDCX 18983216 1@mgw MGCP 1.0\r\n" &
91 "M: sendrecv\r" &
92 "C: 2\r\n" &
93 "I: 1\r\n" &
94 "L: p:20, a:AMR, nt:IN\r\n" &
95 "\n" &
96 "v=0\r\n" &
97 "o=- 1 23 IN IP4 0.0.0.0\r\n" &
Harald Welte2871d0b2017-09-14 22:42:12 +080098 "s=-\r\n" &
Harald Welte00a067f2017-09-13 23:27:17 +020099 "c=IN IP4 0.0.0.0\r\n" &
100 "t=0 0\r\n" &
101 "m=audio 4441 RTP/AVP 99\r\n" &
102 "a=rtpmap:99 AMR/8000\r\n" &
103 "a=ptime:40\r\n";
Harald Welte3c6ebb92017-09-16 00:56:57 +0800104 const charstring c_crcx510_ret := "510 23 FAIL\r\n"
Harald Welte00a067f2017-09-13 23:27:17 +0200105
106 log(c_auep);
107 log(dec_MgcpCommand(c_auep));
108
109 log(c_mdcx3);
110 log(dec_MgcpCommand(c_mdcx3));
111
112 log(c_mdcx3_ret);
113 log(dec_MgcpResponse(c_mdcx3_ret));
114
115 log(c_mdcx4);
116 log(dec_MgcpCommand(c_mdcx4));
Harald Welte3c6ebb92017-09-16 00:56:57 +0800117
118 log(ts_CRCX("23", "42@mgw", "sendrecv", '1234'H));
119 log(enc_MgcpCommand(valueof(ts_CRCX("23", "42@mgw", "sendrecv", '1234'H))));
120
121 log(c_crcx510_ret);
122 log(dec_MgcpResponse(c_crcx510_ret));
123 log(dec_MgcpMessage(c_crcx510_ret));
124 }
125
Harald Weltee636afd2017-09-17 16:24:09 +0800126 /* CRCX test ideas:
Harald Weltee0b331f2017-11-18 20:34:33 +0100127 * x without mandatory CallId
Harald Weltee636afd2017-09-17 16:24:09 +0800128 * - with forbidden parameters (e.g. Capabilities, PackageList, ...
129 * - CRCX with remote session description and without
130 *
131 * general ideas:
Harald Weltee0b331f2017-11-18 20:34:33 +0100132 * x packetization != 20ms
133 * x invalid mode
Harald Weltee636afd2017-09-17 16:24:09 +0800134 * x unsupported mode (517)
135 * x bidirectional mode before RemoteConnDesc: 527
136 * - invalid codec
Harald Weltee0b331f2017-11-18 20:34:33 +0100137 * x retransmission of same transaction
Harald Weltee636afd2017-09-17 16:24:09 +0800138 * - unsupported LocalConnectionOptions ("b", "a", "e", "gc", "s", "r", "k", ..)
139 */
140
Harald Welte21ba5572017-09-19 17:55:05 +0800141 /* build a receive template for receiving a MGCP message. You
142 * pass the MGCP response template in, and it will generate an
143 * MGCP_RecvFrom template that can match the primitives arriving on the
144 * MGCP_CodecPort */
Harald Weltee636afd2017-09-17 16:24:09 +0800145 function tr_MGCP_RecvFrom_R(template MgcpResponse resp) runs on dummy_CT return template MGCP_RecvFrom {
146 var template MGCP_RecvFrom mrf := {
Harald Welte55015362017-11-18 16:02:42 +0100147 connId := g_mgcp_conn_id,
Harald Weltee636afd2017-09-17 16:24:09 +0800148 remName := mp_remote_ip,
149 remPort := mp_remote_udp_port,
150 locName := mp_local_ip,
151 locPort := mp_local_udp_port,
152 msg := { response := resp }
153 }
154 return mrf;
155 }
156
157 /* Send a MGCP request + receive a (matching!) response */
158 function mgcp_transceive_mgw(template MgcpCommand cmd, template MgcpResponse resp := ?) runs on dummy_CT return MgcpResponse {
159 var MgcpMessage msg := { command := valueof(cmd) };
160 resp.line.trans_id := cmd.line.trans_id;
161 var template MGCP_RecvFrom mrt := tr_MGCP_RecvFrom_R(resp);
Harald Welte3c6ebb92017-09-16 00:56:57 +0800162 var MGCP_RecvFrom mrf;
163 timer T := 5.0;
164
Harald Welte55015362017-11-18 16:02:42 +0100165 MGCP.send(t_MGCP_Send(g_mgcp_conn_id, msg));
Harald Welte3c6ebb92017-09-16 00:56:57 +0800166 T.start;
167 alt {
Harald Weltee636afd2017-09-17 16:24:09 +0800168 [] MGCP.receive(mrt) -> value mrf { }
169 [] MGCP.receive(tr_MGCP_RecvFrom_R(?)) { setverdict(fail); }
Harald Welte3c6ebb92017-09-16 00:56:57 +0800170 [] MGCP.receive { repeat; }
171 [] T.timeout { setverdict(fail); }
172 }
173 T.stop;
Harald Weltee636afd2017-09-17 16:24:09 +0800174
175 if (isbound(mrf) and isbound(mrf.msg) and ischosen(mrf.msg.response)) {
176 return mrf.msg.response;
177 } else {
178 var MgcpResponse r := { line := { code := "999", trans_id := valueof(cmd.line.trans_id) } };
179 return r;
180 }
Harald Welte00a067f2017-09-13 23:27:17 +0200181 }
182
Harald Welteba62c8c2017-11-18 18:26:49 +0100183 function extract_conn_id(MgcpResponse resp) return MgcpConnectionId {
184 var integer i;
185 for (i := 0; i < lengthof(resp.params); i := i + 1) {
186 var MgcpParameter par := resp.params[i];
187 if (par.code == "I") {
188 return str2hex(par.val);
189 }
190 }
191 setverdict(fail);
192 return '00000000'H;
193 }
194
Harald Welte10889c12017-11-18 19:40:31 +0100195 function f_dlcx(MgcpEndpoint ep, template MgcpResponseCode ret_code, template charstring ret_val,
196 template MgcpCallId call_id := omit,
197 template MgcpConnectionId conn_id := omit) runs on dummy_CT {
Harald Welteba62c8c2017-11-18 18:26:49 +0100198 var template MgcpCommand cmd;
199 var MgcpResponse resp;
200 var template MgcpResponse rtmpl := {
201 line := {
Harald Welte10889c12017-11-18 19:40:31 +0100202 code := ret_code,
203 string := ret_val
Harald Welteba62c8c2017-11-18 18:26:49 +0100204 },
205 params := *,
206 sdp := *
207 };
Harald Weltec40e0c32017-11-18 19:08:22 +0100208 cmd := ts_DLCX(get_next_trans_id(), ep, call_id, conn_id);
Harald Welteba62c8c2017-11-18 18:26:49 +0100209 resp := mgcp_transceive_mgw(cmd, rtmpl);
210 }
211
Harald Welte10889c12017-11-18 19:40:31 +0100212 /* Send DLCX and expect OK response */
213 function f_dlcx_ok(MgcpEndpoint ep, template MgcpCallId call_id := omit,
214 template MgcpConnectionId conn_id := omit) runs on dummy_CT {
Harald Weltef91edf32017-12-28 14:16:21 +0100215 f_dlcx(ep, ("200","250"), "OK", call_id, conn_id);
Harald Welte10889c12017-11-18 19:40:31 +0100216 }
217
Harald Welteba62c8c2017-11-18 18:26:49 +0100218 /* Send DLCX and accept any response */
Harald Weltec40e0c32017-11-18 19:08:22 +0100219 function f_dlcx_ignore(MgcpEndpoint ep, template MgcpCallId call_id := omit,
Harald Welteba62c8c2017-11-18 18:26:49 +0100220 template MgcpConnectionId conn_id := omit) runs on dummy_CT {
Harald Welte10889c12017-11-18 19:40:31 +0100221 f_dlcx(ep, ?, *, call_id, conn_id);
Harald Welteba62c8c2017-11-18 18:26:49 +0100222 }
223
Harald Weltee636afd2017-09-17 16:24:09 +0800224 /* test valid CRCX without SDP */
225 testcase TC_crcx() runs on dummy_CT {
226 var template MgcpCommand cmd;
227 var MgcpResponse resp;
Harald Welteba62c8c2017-11-18 18:26:49 +0100228 var MgcpEndpoint ep := "2@mgw";
229 var MgcpCallId call_id := '1234'H;
Harald Weltee636afd2017-09-17 16:24:09 +0800230
Harald Welteedc45c12017-11-18 19:15:05 +0100231 f_init(ep);
Harald Weltee636afd2017-09-17 16:24:09 +0800232
Harald Welteba62c8c2017-11-18 18:26:49 +0100233 /* create the connection on the MGW */
234 cmd := ts_CRCX(get_next_trans_id(), ep, "recvonly", call_id);
Harald Welte9988d282017-11-18 19:22:00 +0100235 resp := mgcp_transceive_mgw(cmd, tr_CRCX_ACK);
Harald Welteba62c8c2017-11-18 18:26:49 +0100236 extract_conn_id(resp);
237
238 /* clean-up */
239 f_dlcx_ok(ep, call_id);
240
Harald Weltee636afd2017-09-17 16:24:09 +0800241 setverdict(pass);
242 }
243
244 /* test CRCX with unsupported mode, expect 517 */
245 testcase TC_crcx_unsupp_mode() runs on dummy_CT {
246 var template MgcpCommand cmd;
247 var MgcpResponse resp;
Harald Welteba62c8c2017-11-18 18:26:49 +0100248 var MgcpEndpoint ep := "2@mgw";
249 var MgcpCallId call_id := '1233'H;
Harald Weltee636afd2017-09-17 16:24:09 +0800250 var template MgcpResponse rtmpl := tr_MgcpResp_Err("517");
251
Harald Welteedc45c12017-11-18 19:15:05 +0100252 f_init(ep);
Harald Weltee636afd2017-09-17 16:24:09 +0800253
Harald Welteba62c8c2017-11-18 18:26:49 +0100254 cmd := ts_CRCX(get_next_trans_id(), ep, "netwtest", call_id);
Harald Weltee636afd2017-09-17 16:24:09 +0800255 resp := mgcp_transceive_mgw(cmd, rtmpl);
256 setverdict(pass);
257 }
258
Harald Welte21ba5572017-09-19 17:55:05 +0800259 /* test CRCX with early bi-directional mode, expect 527 as
260 * bi-diretional media can only be established once both local and
261 * remote side are specified, see MGCP RFC */
Harald Weltee636afd2017-09-17 16:24:09 +0800262 testcase TC_crcx_early_bidir_mode() runs on dummy_CT {
263 var template MgcpCommand cmd;
264 var MgcpResponse resp;
Harald Welteba62c8c2017-11-18 18:26:49 +0100265 var MgcpEndpoint ep := "2@mgw";
266 var MgcpCallId call_id := '1232'H;
Harald Weltee636afd2017-09-17 16:24:09 +0800267 var template MgcpResponse rtmpl := tr_MgcpResp_Err("527");
268
Harald Welteedc45c12017-11-18 19:15:05 +0100269 f_init(ep);
Harald Weltee636afd2017-09-17 16:24:09 +0800270
Harald Welteba62c8c2017-11-18 18:26:49 +0100271 cmd := ts_CRCX(get_next_trans_id(), ep, "sendrecv", call_id);
Harald Weltee636afd2017-09-17 16:24:09 +0800272 resp := mgcp_transceive_mgw(cmd, rtmpl);
273 setverdict(pass);
274 }
275
276 /* test CRCX with unsupported Parameters */
277 testcase TC_crcx_unsupp_param() runs on dummy_CT {
278 var template MgcpCommand cmd;
279 var MgcpResponse resp;
Harald Welteba62c8c2017-11-18 18:26:49 +0100280 var MgcpEndpoint ep := "2@mgw";
281 var MgcpCallId call_id := '1231'H;
Harald Weltee636afd2017-09-17 16:24:09 +0800282 var template MgcpResponse rtmpl := tr_MgcpResp_Err("539");
283
Harald Welteedc45c12017-11-18 19:15:05 +0100284 f_init(ep);
Harald Weltee636afd2017-09-17 16:24:09 +0800285
Harald Welteba62c8c2017-11-18 18:26:49 +0100286 cmd := ts_CRCX(get_next_trans_id(), ep, "recvonly", call_id);
Harald Weltea01e38d2017-11-18 18:40:01 +0100287 /* osmo-bsc_mgcp/mgw doesn't implement notifications */
288 f_mgcp_par_append(cmd.params, MgcpParameter:{ "N", "foobar" });
289
Harald Weltee636afd2017-09-17 16:24:09 +0800290 resp := mgcp_transceive_mgw(cmd, rtmpl);
291 setverdict(pass);
292 }
293
294 /* test CRCX with missing CallId */
295 testcase TC_crcx_missing_callid() runs on dummy_CT {
296 var template MgcpCommand cmd;
297 var MgcpResponse resp;
Harald Welteba62c8c2017-11-18 18:26:49 +0100298 var MgcpEndpoint ep := "2@mgw";
Harald Weltef91edf32017-12-28 14:16:21 +0100299 var template MgcpResponse rtmpl := tr_MgcpResp_Err(("400","516"));
Harald Weltee636afd2017-09-17 16:24:09 +0800300
Harald Welteedc45c12017-11-18 19:15:05 +0100301 f_init(ep);
Harald Weltee636afd2017-09-17 16:24:09 +0800302
Harald Welteba62c8c2017-11-18 18:26:49 +0100303 cmd := ts_CRCX(get_next_trans_id(), ep, "recvonly", '1230'H);
Harald Weltee636afd2017-09-17 16:24:09 +0800304 cmd.params := {
305 t_MgcpParConnMode("recvonly"),
306 t_MgcpParLocConnOpt("p:20")
307 }
308 resp := mgcp_transceive_mgw(cmd, rtmpl);
309 setverdict(pass);
Harald Welteba62c8c2017-11-18 18:26:49 +0100310
Harald Weltee636afd2017-09-17 16:24:09 +0800311 }
312
313 /* test CRCX with missing Mode */
314 testcase TC_crcx_missing_mode() runs on dummy_CT {
315 var template MgcpCommand cmd;
316 var MgcpResponse resp;
Harald Welteba62c8c2017-11-18 18:26:49 +0100317 var MgcpEndpoint ep := "2@mgw";
318 var MgcpCallId call_id := '1229'H;
Harald Weltef91edf32017-12-28 14:16:21 +0100319 var template MgcpResponse rtmpl := tr_MgcpResp_Err(("400","517"));
Harald Weltee636afd2017-09-17 16:24:09 +0800320
Harald Welteedc45c12017-11-18 19:15:05 +0100321 f_init(ep);
Harald Weltee636afd2017-09-17 16:24:09 +0800322
Harald Welteba62c8c2017-11-18 18:26:49 +0100323 cmd := ts_CRCX(get_next_trans_id(), ep, "recvonly", call_id);
Harald Weltee636afd2017-09-17 16:24:09 +0800324 cmd.params := {
Harald Welteba62c8c2017-11-18 18:26:49 +0100325 ts_MgcpParCallId(call_id),
Harald Weltee636afd2017-09-17 16:24:09 +0800326 t_MgcpParLocConnOpt("p:20")
327 }
328 resp := mgcp_transceive_mgw(cmd, rtmpl);
329 setverdict(pass);
330 }
331
332 /* test CRCX with unsupported packetization interval */
333 testcase TC_crcx_unsupp_packet_intv() runs on dummy_CT {
334 var template MgcpCommand cmd;
335 var MgcpResponse resp;
Harald Welteba62c8c2017-11-18 18:26:49 +0100336 var MgcpEndpoint ep := "2@mgw";
337 var MgcpCallId call_id := '1228'H;
Harald Welte0d198612017-11-18 19:58:31 +0100338 var template MgcpResponse rtmpl := tr_MgcpResp_Err("535");
Harald Weltee636afd2017-09-17 16:24:09 +0800339
Harald Welteedc45c12017-11-18 19:15:05 +0100340 f_init(ep);
Harald Weltee636afd2017-09-17 16:24:09 +0800341
Harald Welteba62c8c2017-11-18 18:26:49 +0100342 cmd := ts_CRCX(get_next_trans_id(), ep, "recvonly", call_id);
Harald Weltea01e38d2017-11-18 18:40:01 +0100343 cmd.params[2] := t_MgcpParLocConnOpt("p:111");
Harald Weltee636afd2017-09-17 16:24:09 +0800344 resp := mgcp_transceive_mgw(cmd, rtmpl);
345 setverdict(pass);
346 }
347
348 /* test CRCX with illegal double presence of local connection option */
349 testcase TC_crcx_illegal_double_lco() runs on dummy_CT {
350 var template MgcpCommand cmd;
351 var MgcpResponse resp;
Harald Welteba62c8c2017-11-18 18:26:49 +0100352 var MgcpEndpoint ep := "2@mgw";
353 var MgcpCallId call_id := '1227'H;
Harald Weltee636afd2017-09-17 16:24:09 +0800354 var template MgcpResponse rtmpl := tr_MgcpResp_Err("524");
355
Harald Welteedc45c12017-11-18 19:15:05 +0100356 f_init(ep);
Harald Weltee636afd2017-09-17 16:24:09 +0800357
Harald Welteba62c8c2017-11-18 18:26:49 +0100358 cmd := ts_CRCX(get_next_trans_id(), ep, "recvonly", call_id);
Harald Weltea01e38d2017-11-18 18:40:01 +0100359 /* p:20 is permitted only once and not twice! */
360 cmd.params[2] := t_MgcpParLocConnOpt("p:20, a:AMR, p:20");
Harald Weltee636afd2017-09-17 16:24:09 +0800361 resp := mgcp_transceive_mgw(cmd, rtmpl);
362 setverdict(pass);
363 }
364
365 /* test valid CRCX with valid SDP */
366 testcase TC_crcx_sdp() runs on dummy_CT {
367 var template MgcpCommand cmd;
368 var MgcpResponse resp;
Harald Welteba62c8c2017-11-18 18:26:49 +0100369 var MgcpEndpoint ep := "2@mgw";
370 var MgcpCallId call_id := '1226'H;
Harald Weltee636afd2017-09-17 16:24:09 +0800371
Harald Welteedc45c12017-11-18 19:15:05 +0100372 f_init(ep);
Harald Weltee636afd2017-09-17 16:24:09 +0800373
Harald Welteba62c8c2017-11-18 18:26:49 +0100374 cmd := ts_CRCX(get_next_trans_id(), ep, "sendrecv", call_id);
Harald Weltee636afd2017-09-17 16:24:09 +0800375 cmd.sdp := ts_SDP("127.0.0.1", "127.0.0.2", "23", "42", 2344, { "98" },
376 { valueof(ts_SDP_rtpmap(98, "AMR/8000")),
377 valueof(ts_SDP_ptime(20)) });
Harald Welte9988d282017-11-18 19:22:00 +0100378 resp := mgcp_transceive_mgw(cmd, tr_CRCX_ACK);
Harald Weltee636afd2017-09-17 16:24:09 +0800379 setverdict(pass);
380 }
381
382 /* TODO: various SDP related bits */
383
384
385 /* TODO: CRCX with X-Osmux */
386 /* TODO: double CRCX without force_realloc */
387
388 /* TODO: MDCX (various) */
389
390 /* TODO: MDCX without CRCX first */
391 testcase TC_mdcx_without_crcx() runs on dummy_CT {
392 var template MgcpCommand cmd;
393 var MgcpResponse resp;
Harald Welteba62c8c2017-11-18 18:26:49 +0100394 var MgcpEndpoint ep := "3@mgw";
395 var MgcpCallId call_id := '1225'H;
Harald Weltee636afd2017-09-17 16:24:09 +0800396 var template MgcpResponse rtmpl := {
397 line := {
398 /* TODO: accept/enforce better error? */
399 code := "400",
400 string := ?
401 },
402 params:= { },
403 sdp := omit
404 };
405
Harald Welteedc45c12017-11-18 19:15:05 +0100406 f_init(ep);
Harald Weltee636afd2017-09-17 16:24:09 +0800407
Harald Welte2bcfd3a2017-11-18 22:14:35 +0100408 cmd := ts_MDCX(get_next_trans_id(), ep, "sendrecv", call_id, call_id);
Harald Weltee636afd2017-09-17 16:24:09 +0800409 cmd.sdp := ts_SDP("127.0.0.1", "127.0.0.2", "23", "42", 2344, { "98" },
410 { valueof(ts_SDP_rtpmap(98, "AMR/8000")),
411 valueof(ts_SDP_ptime(20)) });
412 resp := mgcp_transceive_mgw(cmd, rtmpl);
413 setverdict(pass);
414 }
415
416 /* DLCX without CRCX first */
417 testcase TC_dlcx_without_crcx() runs on dummy_CT {
418 var template MgcpCommand cmd;
419 var MgcpResponse resp;
Harald Welteedc45c12017-11-18 19:15:05 +0100420 var MgcpEndpoint ep := "4@mgw";
Harald Weltee636afd2017-09-17 16:24:09 +0800421 var template MgcpResponse rtmpl := {
422 line := {
Harald Weltef91edf32017-12-28 14:16:21 +0100423 code := ("400", "515"),
Harald Weltee636afd2017-09-17 16:24:09 +0800424 string := ?
425 },
426 params:= { },
427 sdp := omit
428 };
429
Harald Welteedc45c12017-11-18 19:15:05 +0100430 f_init(ep);
Harald Weltee636afd2017-09-17 16:24:09 +0800431
Harald Welteedc45c12017-11-18 19:15:05 +0100432 cmd := ts_DLCX(get_next_trans_id(), ep, '41234'H);
Harald Weltee636afd2017-09-17 16:24:09 +0800433 resp := mgcp_transceive_mgw(cmd, rtmpl);
434 setverdict(pass);
435 }
436
Harald Welte79181ff2017-11-18 19:26:11 +0100437 /* Test (valid) CRCX followed by (valid) DLCX containig EP+CallId+ConnId */
438 testcase TC_crcx_and_dlcx_ep_callid_connid() runs on dummy_CT {
439 var template MgcpCommand cmd;
440 var MgcpResponse resp;
441 var MgcpEndpoint ep := "5@mgw";
442 var MgcpCallId call_id := '51234'H;
443
444 f_init(ep);
445
446 cmd := ts_CRCX(get_next_trans_id(), ep, "recvonly", call_id);
447 resp := mgcp_transceive_mgw(cmd, tr_CRCX_ACK);
448
449 f_dlcx_ok(ep, call_id, extract_conn_id(resp));
450
451 setverdict(pass);
452 }
453
Harald Welte646ecdb2017-12-28 03:21:57 +0100454 function f_crcx_and_dlcx_ep_callid_connid(MgcpEndpoint ep, MgcpCallId call_id) runs on dummy_CT {
455 var template MgcpCommand cmd;
456 var MgcpResponse resp;
457
458 cmd := ts_CRCX(get_next_trans_id(), ep, "recvonly", call_id);
459 resp := mgcp_transceive_mgw(cmd, tr_CRCX_ACK);
460
461 f_dlcx_ok(ep, call_id, extract_conn_id(resp));
462
463 setverdict(pass);
464 }
465
466 testcase TC_crcx_dlcx_30ep() runs on dummy_CT {
467 var MgcpEndpoint ep;
468 var MgcpCallId call_id;
469 var integer ep_nr;
470
471 f_init();
472
473 for (ep_nr := 1; ep_nr < 30; ep_nr := ep_nr+1) {
474 ep := hex2str(int2hex(ep_nr, 2)) & "@mgw";
475 call_id := int2hex(ep_nr, 2) & '1234'H;
476 f_crcx_and_dlcx_ep_callid_connid(ep, call_id);
477 }
478 }
479
Harald Welte79181ff2017-11-18 19:26:11 +0100480 /* Test (valid) CRCX followed by (valid) DLCX containing EP+CallId */
481 testcase TC_crcx_and_dlcx_ep_callid() runs on dummy_CT {
Harald Welte5b4c44e2017-09-17 16:35:27 +0800482 var template MgcpCommand cmd;
483 var MgcpResponse resp;
Harald Welteba62c8c2017-11-18 18:26:49 +0100484 var MgcpEndpoint ep := "5@mgw";
Harald Welte6d167f82017-11-18 19:41:35 +0100485 var MgcpCallId call_id := '51233'H;
Harald Welte5b4c44e2017-09-17 16:35:27 +0800486
Harald Welteedc45c12017-11-18 19:15:05 +0100487 f_init(ep);
Harald Welte5b4c44e2017-09-17 16:35:27 +0800488
Harald Welteba62c8c2017-11-18 18:26:49 +0100489 cmd := ts_CRCX(get_next_trans_id(), ep, "recvonly", call_id);
Harald Welte9988d282017-11-18 19:22:00 +0100490 resp := mgcp_transceive_mgw(cmd, tr_CRCX_ACK);
Harald Welte5b4c44e2017-09-17 16:35:27 +0800491
Harald Welteba62c8c2017-11-18 18:26:49 +0100492 f_dlcx_ok(ep, call_id);
Harald Welte5b4c44e2017-09-17 16:35:27 +0800493
494 setverdict(pass);
495 }
496
Harald Welte79181ff2017-11-18 19:26:11 +0100497 /* Test (valid) CRCX followed by (valid) DLCX containing EP */
498 testcase TC_crcx_and_dlcx_ep() runs on dummy_CT {
499 var template MgcpCommand cmd;
500 var MgcpResponse resp;
501 var MgcpEndpoint ep := "5@mgw";
Harald Welte6d167f82017-11-18 19:41:35 +0100502 var MgcpCallId call_id := '51232'H;
Harald Welte79181ff2017-11-18 19:26:11 +0100503
504 f_init(ep);
505
506 cmd := ts_CRCX(get_next_trans_id(), ep, "recvonly", call_id);
507 resp := mgcp_transceive_mgw(cmd, tr_CRCX_ACK);
508
509 f_dlcx_ok(ep);
510
511 setverdict(pass);
512 }
513
514
Harald Welte6d167f82017-11-18 19:41:35 +0100515 /* CRCX + DLCX of valid endpoint but invalid call-id */
516 testcase TC_crcx_and_dlcx_ep_callid_inval() runs on dummy_CT {
517 var template MgcpCommand cmd;
518 var MgcpResponse resp;
519 var MgcpEndpoint ep := "5@mgw";
520 var MgcpCallId call_id := '51231'H;
521
522 f_init(ep);
523
524 cmd := ts_CRCX(get_next_trans_id(), ep, "recvonly", call_id);
525 resp := mgcp_transceive_mgw(cmd, tr_CRCX_ACK);
526
527 f_dlcx(ep, "516", *, 'ffff'H);
528
529 setverdict(pass);
530 }
531
532
533 /* CRCX + DLCX of valid endpoint and call-id but invalid conn-id */
534 testcase TC_crcx_and_dlcx_ep_callid_connid_inval() runs on dummy_CT {
535 var template MgcpCommand cmd;
536 var MgcpResponse resp;
537 var MgcpEndpoint ep := "5@mgw";
538 var MgcpCallId call_id := '51230'H;
539
540 f_init(ep);
541
542 cmd := ts_CRCX(get_next_trans_id(), ep, "recvonly", call_id);
543 resp := mgcp_transceive_mgw(cmd, tr_CRCX_ACK);
544
545 f_dlcx(ep, "515", *, call_id, 'ffff'H);
546
547 setverdict(pass);
548 }
549
550
Harald Weltee636afd2017-09-17 16:24:09 +0800551 /* TODO: Double-DLCX (retransmission) */
Harald Weltef53f1642017-11-18 19:57:11 +0100552 testcase TC_crcx_and_dlcx_retrans() runs on dummy_CT {
553 var template MgcpCommand cmd;
554 var MgcpResponse resp;
555 var MgcpEndpoint ep := "5@mgw";
556 var MgcpCallId call_id := '51229'H;
557 var template MgcpResponse rtmpl := {
558 line := {
559 code := "200",
560 string := "OK"
561 },
562 params:= { },
563 sdp := omit
564 };
565
566 f_init(ep);
567
568 cmd := ts_CRCX(get_next_trans_id(), ep, "recvonly", call_id);
569 resp := mgcp_transceive_mgw(cmd, tr_CRCX_ACK);
570
571 cmd := ts_DLCX(get_next_trans_id(), ep, call_id);
572 resp := mgcp_transceive_mgw(cmd, rtmpl);
573 resp := mgcp_transceive_mgw(cmd, rtmpl);
574
575 setverdict(pass);
576 }
577
578
579
Harald Weltee636afd2017-09-17 16:24:09 +0800580 /* TODO: Double-DLCX (no retransmission) */
581
582
583
584 /* TODO: AUEP (various) */
585 /* TODO: RSIP (various) */
586 /* TODO: RQNT (various) */
587 /* TODO: EPCF (various) */
588 /* TODO: AUCX (various) */
589 /* TODO: invalid verb (various) */
590
Harald Welte00a067f2017-09-13 23:27:17 +0200591 control {
592 execute(TC_selftest());
Harald Welte3c6ebb92017-09-16 00:56:57 +0800593 execute(TC_crcx());
Harald Weltee636afd2017-09-17 16:24:09 +0800594 execute(TC_crcx_unsupp_mode());
595 execute(TC_crcx_early_bidir_mode());
596 execute(TC_crcx_unsupp_param());
597 execute(TC_crcx_missing_callid());
598 execute(TC_crcx_missing_mode());
599 execute(TC_crcx_unsupp_packet_intv());
600 execute(TC_crcx_illegal_double_lco());
601 execute(TC_crcx_sdp());
602 execute(TC_mdcx_without_crcx());
603 execute(TC_dlcx_without_crcx());
Harald Welte79181ff2017-11-18 19:26:11 +0100604 execute(TC_crcx_and_dlcx_ep_callid_connid());
605 execute(TC_crcx_and_dlcx_ep_callid());
606 execute(TC_crcx_and_dlcx_ep());
Harald Welte6d167f82017-11-18 19:41:35 +0100607 execute(TC_crcx_and_dlcx_ep_callid_inval());
608 execute(TC_crcx_and_dlcx_ep_callid_connid_inval());
Harald Weltef53f1642017-11-18 19:57:11 +0100609 execute(TC_crcx_and_dlcx_retrans());
Harald Welte33d82162017-12-28 03:21:57 +0100610
611 execute(TC_crcx_dlcx_30ep());
Harald Welte00a067f2017-09-13 23:27:17 +0200612 }
613}