blob: 93079381aedbe6d5683ade2a4568b1421f380679 [file] [log] [blame]
Neels Hofmeyra99b4272017-11-21 17:13:23 +01001/* Osmocom MSC+VLR end-to-end tests */
2
3/* (C) 2017 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
4 *
5 * All Rights Reserved
6 *
7 * Author: Neels Hofmeyr <nhofmeyr@sysmocom.de>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Affero General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Affero General Public License for more details.
18 *
19 * You should have received a copy of the GNU Affero General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 *
22 */
23
24#include "msc_vlr_tests.h"
25
26#include <osmocom/msc/gsm_04_08.h>
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +010027#include <osmocom/msc/codec_mapping.h>
Neels Hofmeyra99b4272017-11-21 17:13:23 +010028
Neels Hofmeyr07351d82019-10-21 05:53:58 +020029#define mncc_sends_to_cc(MSG_TYPE, MNCC) do { \
30 (MNCC)->msg_type = MSG_TYPE; \
31 log("MSC <-- MNCC: callref 0x%x: %s\n%s", (MNCC)->callref, \
32 get_mncc_name((MNCC)->msg_type), \
33 (MNCC)->sdp); \
34 mncc_tx_to_cc(net, MNCC); \
35 } while(0)
Neels Hofmeyra99b4272017-11-21 17:13:23 +010036
Neels Hofmeyrc4628a32018-12-07 14:47:34 +010037/*
Neels Hofmeyrcbcf89c2018-03-13 17:52:07 +010038static void on_call_release_mncc_sends_to_cc(uint32_t msg_type, struct gsm_mncc *mncc)
39{
40 mncc->msg_type = msg_type;
41 on_call_release_mncc_sends_to_cc_data = mncc;
42}
Neels Hofmeyrc4628a32018-12-07 14:47:34 +010043*/
Neels Hofmeyrcbcf89c2018-03-13 17:52:07 +010044
Neels Hofmeyra99b4272017-11-21 17:13:23 +010045#define IMSI "901700000010650"
46
Neels Hofmeyr11bf0bc2019-10-21 05:55:49 +020047static void lu_utran_tmsi()
Neels Hofmeyra99b4272017-11-21 17:13:23 +010048{
49 struct vlr_subscr *vsub;
50
51 net->authentication_required = true;
52 net->vlr->cfg.assign_tmsi = true;
Neels Hofmeyr7814a832018-12-26 00:40:18 +010053 rx_from_ran = OSMO_RAT_UTRAN_IU;
Neels Hofmeyra99b4272017-11-21 17:13:23 +010054
55 btw("Location Update request causes a GSUP Send Auth Info request to HLR");
56 lu_result_sent = RES_NONE;
Neels Hofmeyr63b24642019-12-12 01:31:04 +010057 gsup_expect_tx("080108" "09710000000156f0" CN_DOMAIN VLR_TO_HLR);
Neels Hofmeyra99b4272017-11-21 17:13:23 +010058 ms_sends_msg("0508" /* MM LU */
59 "7" /* ciph key seq: no key available */
60 "0" /* LU type: normal */
61 "09f107" "0017" /* LAI, LAC */
62 "57" /* classmark 1: R99, early classmark, no power lvl */
63 "089910070000106005" /* IMSI */
64 "3303575886" /* classmark 2 */
65 );
66 OSMO_ASSERT(gsup_tx_confirmed);
67 VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
68
69 btw("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS");
70 /* based on auc_3g:
71 * K = 'EB215756028D60E3275E613320AEC880',
72 * OPC = 'FB2A3D1B360F599ABAB99DB8669F8308'
73 * SQN = 0
74 */
75 auth_request_sent = false;
76 auth_request_expect_rand = "39fa2f4e3d523d8619a73b4f65c3e14d";
77 auth_request_expect_autn = "8704f5ba55f30000d2ee44b22c8ea919";
78 gsup_rx("0a"
79 /* imsi */
80 "0108" "09710000000156f0"
81 /* 5 auth vectors... */
82 /* TL TL rand */
83 "0362" "2010" "39fa2f4e3d523d8619a73b4f65c3e14d"
84 /* TL sres TL kc */
85 "2104" "9b36efdf" "2208" "059a4f668f6fbe39"
86 /* TL 3G IK */
87 "2310" "27497388b6cb044648f396aa155b95ef"
88 /* TL 3G CK */
89 "2410" "f64735036e5871319c679f4742a75ea1"
90 /* TL AUTN */
91 "2510" "8704f5ba55f30000d2ee44b22c8ea919"
92 /* TL RES */
93 "2708" "e229c19e791f2e41"
94 /* TL TL rand */
95 "0362" "2010" "c187a53a5e6b9d573cac7c74451fd46d"
96 "2104" "85aa3130" "2208" "d3d50a000bf04f6e"
97 "2310" "1159ec926a50e98c034a6b7d7c9f418d"
98 "2410" "df3a03d9ca5335641efc8e36d76cd20b"
99 "2510" "1843a645b98d00005b2d666af46c45d9"
100 "2708" "7db47cf7f81e4dc7"
101 "0362" "2010" "efa9c29a9742148d5c9070348716e1bb"
102 "2104" "69d5f9fb" "2208" "3df176f0c29f1a3d"
103 "2310" "eb50e770ddcc3060101d2f43b6c2b884"
104 "2410" "76542abce5ff9345b0e8947f4c6e019c"
105 "2510" "f9375e6d41e1000096e7fe4ff1c27e39"
106 "2708" "706f996719ba609c"
107 "0362" "2010" "f023d5a3b24726e0631b64b3840f8253"
108 "2104" "d570c03f" "2208" "ec011be8919883d6"
109 "2310" "c4e58af4ba43f3bcd904e16984f086d7"
110 "2410" "0593f65e752e5cb7f473862bda05aa0a"
111 "2510" "541ff1f077270000c5ea00d658bc7e9a"
112 "2708" "3fd26072eaa2a04d"
113 "0362" "2010" "2f8f90c780d6a9c0c53da7ac57b6707e"
114 "2104" "b072446f220823f39f9f425ad6e6"
115 "2310" "65af0527fda95b0dc5ae4aa515cdf32f"
116 "2410" "537c3b35a3b13b08d08eeb28098f45cc"
117 "2510" "4bf4e564f75300009bc796706bc65744"
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100118 "2708" "0edb0eadbea94ac2"
119 HLR_TO_VLR,
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100120 NULL);
121 VERBOSE_ASSERT(auth_request_sent, == true, "%d");
122 VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
123
124 btw("MS sends Authen Response, VLR accepts and sends SecurityModeControl");
Neels Hofmeyrdbabfd32018-03-10 02:06:47 +0100125 expect_security_mode_ctrl(NULL, "27497388b6cb044648f396aa155b95ef");
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100126 ms_sends_msg("0554" "e229c19e" "2104" "791f2e41");
Neels Hofmeyrdbabfd32018-03-10 02:06:47 +0100127 VERBOSE_ASSERT(security_mode_ctrl_sent, == true, "%d");
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100128 VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
129
130 btw("MS sends SecurityModeControl acceptance, VLR accepts and sends GSUP LU Req to HLR");
Neels Hofmeyr63b24642019-12-12 01:31:04 +0100131 gsup_expect_tx("04010809710000000156f0" CN_DOMAIN VLR_TO_HLR);
Alexander Couzens2aaff752021-10-19 17:09:11 +0200132 ms_sends_security_mode_complete(1);
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100133 VERBOSE_ASSERT(gsup_tx_confirmed, == true, "%d");
134 VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
135
136 btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT");
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100137 gsup_rx("10010809710000000156f00804032443f2" HLR_TO_VLR,
138 "12010809710000000156f0" VLR_TO_HLR);
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100139 VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
140
141 btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT");
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100142 gsup_rx("06010809710000000156f0" HLR_TO_VLR, NULL);
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100143
144 VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
145
146 btw("a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl");
147 EXPECT_CONN_COUNT(1);
148 EXPECT_ACCEPTED(false);
149
150 btw("MS sends TMSI Realloc Complete");
151 iu_release_expected = true;
152 iu_release_sent = false;
153 ms_sends_msg("055b");
154 VERBOSE_ASSERT(iu_release_sent, == true, "%d"); \
155
156 btw("LU was successful, and the conn has already been closed");
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100157 ran_sends_clear_complete();
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100158 EXPECT_CONN_COUNT(0);
159
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100160 vsub = vlr_subscr_find_by_imsi(net->vlr, IMSI, __func__);
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100161 VERBOSE_ASSERT(vsub != NULL, == true, "%d");
162 VERBOSE_ASSERT(strcmp(vsub->imsi, IMSI), == 0, "%d");
Max7d41d872018-12-19 11:48:33 +0100163 VAL_ASSERT("LAC", vsub->cgi.lai.lac, == 23, "%u");
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100164 vlr_subscr_put(vsub, __func__);
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100165}
166
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +0100167static void lu_geran_noauth(void)
168{
169 rx_from_ran = OSMO_RAT_GERAN_A;
170 net->authentication_required = false;
171 net->vlr->cfg.assign_tmsi = false;
172
173 btw("Location Update request causes a GSUP LU request to HLR");
174 lu_result_sent = RES_NONE;
175 gsup_expect_tx("04010809710000000156f0280102" VLR_TO_HLR);
176 ms_sends_msg("0508" /* MM LU */
177 "7" /* ciph key seq: no key available */
178 "0" /* LU type: normal */
179 "09f107" "0017" /* LAI, LAC */
180 "57" /* classmark 1: R99, early classmark, no power lvl */
181 "089910070000106005" /* IMSI */
182 "3303575886" /* classmark 2 */
183 );
184 OSMO_ASSERT(gsup_tx_confirmed);
185 VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
186
187 btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT");
188 gsup_rx("10010809710000000156f00804036470f1" HLR_TO_VLR,
189 "12010809710000000156f0" VLR_TO_HLR);
190 VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
191
192 btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT");
193 expect_bssap_clear();
194 gsup_rx("06010809710000000156f0" HLR_TO_VLR, NULL);
195
196 btw("LU was successful, and the conn has already been closed");
197 VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
198 VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
199
200 ran_sends_clear_complete();
201 EXPECT_CONN_COUNT(0);
202}
203
204
Neels Hofmeyrf3d81f62018-03-02 01:05:38 +0100205static void test_call_mo()
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100206{
207 struct gsm_mncc mncc = {
208 .imsi = IMSI,
209 };
Neels Hofmeyr6a1faa92023-03-23 01:56:14 +0100210 struct gsm_mncc_rtp mncc_rtp = {};
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100211
Neels Hofmeyrdfdc61d2018-03-02 00:40:58 +0100212 comment_start();
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100213
214 fake_time_start();
215
Neels Hofmeyr11bf0bc2019-10-21 05:55:49 +0200216 lu_utran_tmsi();
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100217
218 BTW("after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector");
219 auth_request_sent = false;
220 auth_request_expect_rand = "c187a53a5e6b9d573cac7c74451fd46d";
221 auth_request_expect_autn = "1843a645b98d00005b2d666af46c45d9";
222 cm_service_result_sent = RES_NONE;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100223 ms_sends_msg("052471"
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100224 "03575886" /* classmark 2 */
225 "089910070000106005" /* IMSI */);
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100226 VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
227 VERBOSE_ASSERT(auth_request_sent, == true, "%d");
228
229 btw("needs auth, not yet accepted");
230 EXPECT_ACCEPTED(false);
231
232 /* On UTRAN */
233 btw("MS sends Authen Response, VLR accepts and sends SecurityModeControl");
Neels Hofmeyrdbabfd32018-03-10 02:06:47 +0100234 expect_security_mode_ctrl(NULL, "1159ec926a50e98c034a6b7d7c9f418d");
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100235 ms_sends_msg("0554" "7db47cf7" "2104" "f81e4dc7"); /* 2nd vector's res, s.a. */
Neels Hofmeyrdbabfd32018-03-10 02:06:47 +0100236 VERBOSE_ASSERT(security_mode_ctrl_sent, == true, "%d");
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100237 VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
238
239 btw("MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept");
Alexander Couzens2aaff752021-10-19 17:09:11 +0200240 ms_sends_security_mode_complete(1);
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100241 VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
242
243 BTW("a call is initiated");
244
Neels Hofmeyr11c04ae2023-11-28 04:40:52 +0100245 btw("CC SETUP causes CRCX towards CN and RAN");
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100246 expect_crcx(RTP_TO_CN);
247 expect_crcx(RTP_TO_RAN);
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100248 ms_sends_msg("0385" /* CC, seq = 2 -> 0x80 | CC Setup = 0x5 */
249 "0406600402000581" /* Bearer Capability */
250 "5e038121f3" /* Called Number BCD */
251 "15020100" /* CC Capabilities */
252 "4008" /* Supported Codec List */
253 "04026000" /* UMTS: AMR 2 | AMR */
254 "00021f00" /* GSM: HR AMR | FR AMR | GSM EFR | GSM HR | GSM FR */
255 );
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100256 OSMO_ASSERT(crcx_scheduled(RTP_TO_CN));
257 OSMO_ASSERT(crcx_scheduled(RTP_TO_RAN));
258
259 btw("As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered");
260 cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_IND);
261 crcx_ok(RTP_TO_CN);
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100262 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
Neels Hofmeyr6a1faa92023-03-23 01:56:14 +0100263 mncc.callref = mncc_rtp.callref = cc_to_mncc_tx_got_callref;
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100264
Neels Hofmeyr11c04ae2023-11-28 04:40:52 +0100265 btw("MNCC replies with MNCC_RTP_CREATE");
Neels Hofmeyr6a1faa92023-03-23 01:56:14 +0100266 mncc_sends_to_cc(MNCC_RTP_CREATE, &mncc_rtp);
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200267
268 btw("MGW acknowledges the CRCX, triggering Assignment");
269 expect_iu_rab_assignment();
270 crcx_ok(RTP_TO_RAN);
271 OSMO_ASSERT(iu_rab_assignment_sent);
272
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100273 btw("Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC");
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200274 cc_to_mncc_expect_tx("", MNCC_RTP_CREATE);
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100275 ms_sends_assignment_complete("AMR");
276 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200277
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100278 btw("MNCC says that's fine");
279 dtap_expect_tx("8302" /* CC: Call Proceeding */);
280 mncc_sends_to_cc(MNCC_CALL_PROC_REQ, &mncc);
281 OSMO_ASSERT(dtap_tx_confirmed);
282
283 fake_time_passes(1, 23);
284
285 btw("The other call leg got established (not shown here), MNCC tells us so");
286 dtap_expect_tx("8301" /* CC: Call Alerting */);
287 mncc_sends_to_cc(MNCC_ALERT_REQ, &mncc);
288 OSMO_ASSERT(dtap_tx_confirmed);
289
290 dtap_expect_tx("8307" /* CC: Connect */);
291 mncc_sends_to_cc(MNCC_SETUP_RSP, &mncc);
292 OSMO_ASSERT(dtap_tx_confirmed);
293
294 fake_time_passes(1, 23);
295
296 cc_to_mncc_expect_tx("", MNCC_SETUP_COMPL_IND);
297 ms_sends_msg("03cf" /* CC: Connect Acknowledge */);
298 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
299
300 BTW("RTP stream goes ahead, not shown here.");
301 fake_time_passes(123, 45);
302
303 BTW("Call ends");
304 cc_to_mncc_expect_tx("", MNCC_DISC_IND);
305 ms_sends_msg("032502e090" /* CC: Disconnect, cause: Normal Call Clearing */);
306 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
307
308 dtap_expect_tx("832d" /* CC: Release */);
309 mncc_sends_to_cc(MNCC_REL_REQ, &mncc);
310 OSMO_ASSERT(dtap_tx_confirmed);
311
312 cc_to_mncc_expect_tx("", MNCC_REL_CNF);
313 expect_iu_release();
314 ms_sends_msg("036a" /* CC: Release Complete */);
315 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
316 OSMO_ASSERT(iu_release_sent);
317
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100318 ran_sends_clear_complete();
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100319 EXPECT_CONN_COUNT(0);
320 clear_vlr();
Neels Hofmeyrdfdc61d2018-03-02 00:40:58 +0100321 comment_end();
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100322}
323
Neels Hofmeyrf3d81f62018-03-02 01:05:38 +0100324static void test_call_mt()
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100325{
326 struct gsm_mncc mncc = {
327 .imsi = IMSI,
328 .callref = 0x423,
Neels Hofmeyr8dd16462022-01-13 20:06:53 +0100329 .fields = MNCC_F_BEARER_CAP,
330 .bearer_cap = {
331 .speech_ver = {
332 GSM48_BCAP_SV_AMR_F,
333 GSM48_BCAP_SV_EFR,
334 GSM48_BCAP_SV_FR,
335 GSM48_BCAP_SV_AMR_H,
336 GSM48_BCAP_SV_HR,
337 -1 },
338 },
339 /* NOTE: below SDP includes only AMR, above bearer_cap includes more codecs. Ideally, these would match,
340 * but in reality the bearer cap in MNCC was never implemented properly. This test shows that above
341 * bearer_cap is ignored when SDP is present: In the CC Setup below, the Bearer Capability is only
342 * "04 04 60 04 05 8b" with speech versions '04' == GSM48_BCAP_SV_AMR_F and '05' == GSM48_BCAP_SV_AMR_H.
343 */
344 .sdp = "v=0\r\n"
345 "o=OsmoMSC 0 0 IN IP4 10.23.23.1\r\n"
346 "s=GSM Call\r\n"
347 "c=IN IP4 10.23.23.1\r\n"
348 "t=0 0\r\n"
349 "m=audio 23 RTP/AVP 112\r\n"
350 "a=rtpmap:112 AMR/8000\r\n"
351 "a=fmtp:112 octet-align=1\r\n"
352 "a=ptime:20\r\n",
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100353 };
354
Neels Hofmeyr6a1faa92023-03-23 01:56:14 +0100355 struct gsm_mncc_rtp mncc_rtp = {
356 .callref = 0x423,
357 };
358
Neels Hofmeyrdfdc61d2018-03-02 00:40:58 +0100359 comment_start();
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100360
361 fake_time_start();
362
Neels Hofmeyr11bf0bc2019-10-21 05:55:49 +0200363 lu_utran_tmsi();
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100364
365 BTW("after a while, MNCC asks us to setup a call, causing Paging");
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100366
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100367 paging_expect_imsi(IMSI);
368 paging_sent = false;
369 mncc_sends_to_cc(MNCC_SETUP_REQ, &mncc);
Neels Hofmeyr8dd16462022-01-13 20:06:53 +0100370 mncc.sdp[0] = '\0';
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100371
372 VERBOSE_ASSERT(paging_sent, == true, "%d");
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100373
374 btw("MS replies with Paging Response, and VLR sends Auth Request");
375 auth_request_sent = false;
376 auth_request_expect_rand = "c187a53a5e6b9d573cac7c74451fd46d";
377 auth_request_expect_autn = "1843a645b98d00005b2d666af46c45d9";
378 ms_sends_msg("062707"
379 "03575886" /* classmark 2 */
380 "089910070000106005" /* IMSI */);
381 VERBOSE_ASSERT(auth_request_sent, == true, "%d");
382
383 btw("MS sends Authen Response, VLR accepts and sends SecurityModeControl");
Neels Hofmeyrdbabfd32018-03-10 02:06:47 +0100384 expect_security_mode_ctrl(NULL, "1159ec926a50e98c034a6b7d7c9f418d");
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100385 ms_sends_msg("0554" "7db47cf7" "2104" "f81e4dc7"); /* 2nd vector's res, s.a. */
Neels Hofmeyrdbabfd32018-03-10 02:06:47 +0100386 VERBOSE_ASSERT(security_mode_ctrl_sent, == true, "%d");
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100387
388 btw("MS sends SecurityModeControl acceptance, VLR accepts, sends CC Setup");
Neels Hofmeyr8dd16462022-01-13 20:06:53 +0100389 dtap_expect_tx("0305" /* CC: Setup */ "04 04 60 04 05 8b" /* Bearer Cap, speech ver of AMR-FR and AMR-HR */);
Alexander Couzens2aaff752021-10-19 17:09:11 +0200390 ms_sends_security_mode_complete(1);
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100391
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200392 btw("MS confirms call, we create a RAN-side RTP and forward MNCC_CALL_CONF_IND");
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100393 expect_crcx(RTP_TO_CN);
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200394 expect_crcx(RTP_TO_RAN);
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100395 cc_to_mncc_expect_tx(IMSI, MNCC_CALL_CONF_IND);
396 ms_sends_msg("8348" /* CC: Call Confirmed */
397 "0406600402000581" /* Bearer Capability */
398 "15020100" /* Call Control Capabilities */
399 "40080402600400021f00" /* Supported Codec List */);
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100400 OSMO_ASSERT(crcx_scheduled(RTP_TO_CN));
Neels Hofmeyr81938fd2022-01-14 03:39:58 +0100401 OSMO_ASSERT(crcx_scheduled(RTP_TO_RAN));
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200402 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
403
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200404 btw("MGW acknowledges the CRCX to RAN, triggering Assignment");
405 expect_iu_rab_assignment();
406 crcx_ok(RTP_TO_RAN);
407 OSMO_ASSERT(iu_rab_assignment_sent);
408
409 btw("Assignment completes, triggering CRCX to CN");
410 expect_crcx(RTP_TO_CN);
Neels Hofmeyrcec51b32023-03-01 03:47:45 +0100411 ms_sends_assignment_complete("AMR");
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200412
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100413 btw("MNCC sends MNCC_RTP_CREATE, which first waits for the CN side RTP");
Neels Hofmeyr6a1faa92023-03-23 01:56:14 +0100414 mncc_sends_to_cc(MNCC_RTP_CREATE, &mncc_rtp);
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100415
416 btw("When the CN side RTP address is known, ack MNCC_RTP_CREATE with full SDP");
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200417 cc_to_mncc_expect_tx("", MNCC_RTP_CREATE);
418 crcx_ok(RTP_TO_CN);
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100419 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100420
421 fake_time_passes(1, 23);
422
423 cc_to_mncc_expect_tx("", MNCC_ALERT_IND);
424 ms_sends_msg("8381" /* CC: Alerting */);
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100425 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100426
427 fake_time_passes(1, 23);
428
429 cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_CNF);
430 ms_sends_msg("83c7" /* CC: Connect */);
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100431 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100432
433 dtap_expect_tx("030f" /* CC: Connect Acknowledge */);
434 mncc_sends_to_cc(MNCC_SETUP_COMPL_REQ, &mncc);
435
436 BTW("RTP stream goes ahead, not shown here.");
437 fake_time_passes(123, 45);
438
439 BTW("Call ends");
440 cc_to_mncc_expect_tx("", MNCC_DISC_IND);
441 ms_sends_msg("832502e090" /* CC: Disconnect, cause: Normal Call Clearing */);
442 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
443
444 dtap_expect_tx("032d" /* CC: Release */);
445 mncc_sends_to_cc(MNCC_REL_REQ, &mncc);
446 OSMO_ASSERT(dtap_tx_confirmed);
447
448 cc_to_mncc_expect_tx("", MNCC_REL_CNF);
449 expect_iu_release();
450 ms_sends_msg("836a" /* CC: Release Complete */);
451 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
452 OSMO_ASSERT(iu_release_sent);
453
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100454 ran_sends_clear_complete();
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100455 EXPECT_CONN_COUNT(0);
456 clear_vlr();
Neels Hofmeyrdfdc61d2018-03-02 00:40:58 +0100457 comment_end();
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100458}
459
Neels Hofmeyrcbcf89c2018-03-13 17:52:07 +0100460static void test_call_mt2()
461{
462 struct gsm_mncc mncc = {
463 .imsi = IMSI,
464 .callref = 0x423,
Neels Hofmeyr8dd16462022-01-13 20:06:53 +0100465 .fields = MNCC_F_BEARER_CAP,
466 .bearer_cap = {
467 .speech_ver = { GSM48_BCAP_SV_FR, -1, },
468 },
469 /* NOTE: below SDP includes only AMR, above bearer_cap includes only GSM-FR. Ideally, these would match,
470 * but in reality the bearer cap in MNCC was never implemented properly. This test shows that above
471 * bearer_cap is ignored when SDP is present: In the CC Setup below, the Bearer Capability is only
472 * "04 04 60 04 05 8b" with speech versions '04' == GSM48_BCAP_SV_AMR_F and '05' == GSM48_BCAP_SV_AMR_H.
473 */
474 .sdp = "v=0\r\n"
475 "o=OsmoMSC 0 0 IN IP4 10.23.23.1\r\n"
476 "s=GSM Call\r\n"
477 "c=IN IP4 10.23.23.1\r\n"
478 "t=0 0\r\n"
479 "m=audio 23 RTP/AVP 112\r\n"
480 "a=rtpmap:112 AMR/8000\r\n"
481 "a=fmtp:112 octet-align=1\r\n"
482 "a=ptime:20\r\n",
Neels Hofmeyrcbcf89c2018-03-13 17:52:07 +0100483 };
484
Neels Hofmeyr6a1faa92023-03-23 01:56:14 +0100485 struct gsm_mncc_rtp mncc_rtp = {
486 .callref = 0x423,
487 .sdp = "v=0\r\n"
488 "o=OsmoMSC 0 0 IN IP4 10.23.23.1\r\n"
489 "s=GSM Call\r\n"
490 "c=IN IP4 10.23.23.1\r\n"
491 "t=0 0\r\n"
492 "m=audio 23 RTP/AVP 112\r\n"
493 "a=rtpmap:112 AMR/8000\r\n"
494 "a=fmtp:112 octet-align=1\r\n"
495 "a=ptime:20\r\n",
496 };
497
Neels Hofmeyrcbcf89c2018-03-13 17:52:07 +0100498 comment_start();
499
500 fake_time_start();
501
Neels Hofmeyr11bf0bc2019-10-21 05:55:49 +0200502 lu_utran_tmsi();
Neels Hofmeyrcbcf89c2018-03-13 17:52:07 +0100503
504 BTW("after a while, MNCC asks us to setup a call, causing Paging");
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100505
Neels Hofmeyrcbcf89c2018-03-13 17:52:07 +0100506 paging_expect_imsi(IMSI);
507 paging_sent = false;
508 mncc_sends_to_cc(MNCC_SETUP_REQ, &mncc);
509
510 VERBOSE_ASSERT(paging_sent, == true, "%d");
Neels Hofmeyrcbcf89c2018-03-13 17:52:07 +0100511
512 btw("MS replies with Paging Response, and VLR sends Auth Request");
513 auth_request_sent = false;
514 auth_request_expect_rand = "c187a53a5e6b9d573cac7c74451fd46d";
515 auth_request_expect_autn = "1843a645b98d00005b2d666af46c45d9";
516 ms_sends_msg("062707"
517 "03575886" /* classmark 2 */
518 "089910070000106005" /* IMSI */);
519 VERBOSE_ASSERT(auth_request_sent, == true, "%d");
520
521 btw("MS sends Authen Response, VLR accepts and sends SecurityModeControl");
522 expect_security_mode_ctrl(NULL, "1159ec926a50e98c034a6b7d7c9f418d");
523 ms_sends_msg("0554" "7db47cf7" "2104" "f81e4dc7"); /* 2nd vector's res, s.a. */
524 VERBOSE_ASSERT(security_mode_ctrl_sent, == true, "%d");
525
526 btw("MS sends SecurityModeControl acceptance, VLR accepts, sends CC Setup");
Neels Hofmeyr8dd16462022-01-13 20:06:53 +0100527 dtap_expect_tx("0305" /* CC: Setup */ "04 04 60 04 05 8b" /* Bearer Cap, speech ver of AMR-FR and AMR-HR */);
Alexander Couzens2aaff752021-10-19 17:09:11 +0200528 ms_sends_security_mode_complete(1);
Neels Hofmeyrcbcf89c2018-03-13 17:52:07 +0100529
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200530 btw("MS confirms call, we create a RAN-side RTP and forward MNCC_CALL_CONF_IND");
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100531 expect_crcx(RTP_TO_CN);
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200532 expect_crcx(RTP_TO_RAN);
Neels Hofmeyrcbcf89c2018-03-13 17:52:07 +0100533 cc_to_mncc_expect_tx(IMSI, MNCC_CALL_CONF_IND);
534 ms_sends_msg("8348" /* CC: Call Confirmed */
535 "0406600402000581" /* Bearer Capability */
536 "15020100" /* Call Control Capabilities */
537 "40080402600400021f00" /* Supported Codec List */);
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100538 OSMO_ASSERT(crcx_scheduled(RTP_TO_CN));
Neels Hofmeyr81938fd2022-01-14 03:39:58 +0100539 OSMO_ASSERT(crcx_scheduled(RTP_TO_RAN));
Neels Hofmeyrcbcf89c2018-03-13 17:52:07 +0100540 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
541
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100542 btw("MNCC sends MNCC_RTP_CREATE, which first waits for the CN side RTP");
Neels Hofmeyr6a1faa92023-03-23 01:56:14 +0100543 mncc_sends_to_cc(MNCC_RTP_CREATE, &mncc_rtp);
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200544
545 btw("MGW acknowledges the CRCX to RAN, triggering Assignment");
546 expect_iu_rab_assignment();
547 crcx_ok(RTP_TO_RAN);
548 OSMO_ASSERT(iu_rab_assignment_sent);
549
550 btw("Assignment completes, triggering CRCX to CN");
Neels Hofmeyrcec51b32023-03-01 03:47:45 +0100551 ms_sends_assignment_complete("AMR");
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200552
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100553 btw("When the CN side RTP address is known, ack MNCC_RTP_CREATE with full SDP");
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200554 cc_to_mncc_expect_tx("", MNCC_RTP_CREATE);
555 crcx_ok(RTP_TO_CN);
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100556 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
557
Neels Hofmeyrcbcf89c2018-03-13 17:52:07 +0100558 fake_time_passes(1, 23);
559
560 cc_to_mncc_expect_tx("", MNCC_ALERT_IND);
561 ms_sends_msg("8381" /* CC: Alerting */);
562 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
563
564 fake_time_passes(15, 23);
565
566 btw("The call failed, the BSC sends a BSSMAP Clear Request");
Vadim Yanitskiydd466cf2021-02-05 19:17:31 +0100567 cc_to_mncc_expect_tx("", MNCC_REL_IND);
Keith Whyteff17f8f2019-08-01 12:20:25 +0200568 dtap_expect_tx("032d0802e1af"); /* CC: Release */
Neels Hofmeyrcbcf89c2018-03-13 17:52:07 +0100569 expect_iu_release();
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100570 msc_a_release_cn(msub_msc_a(g_msub));
571 OSMO_ASSERT(dtap_tx_confirmed);
Neels Hofmeyrcbcf89c2018-03-13 17:52:07 +0100572 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
573 OSMO_ASSERT(iu_release_sent);
574
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100575 ran_sends_clear_complete();
Neels Hofmeyrcbcf89c2018-03-13 17:52:07 +0100576 EXPECT_CONN_COUNT(0);
577
578 /* Make sure a pending release timer doesn't fire later to access freed data */
579 fake_time_passes(15, 23);
580
581 clear_vlr();
582 comment_end();
583}
584
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100585static void test_call_mo_to_unknown()
586{
587 struct gsm_mncc mncc = {
588 .imsi = IMSI,
589 };
590
Neels Hofmeyr6a1faa92023-03-23 01:56:14 +0100591 struct gsm_mncc_rtp mncc_rtp = {};
592
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100593 comment_start();
594
595 fake_time_start();
596
Neels Hofmeyr11bf0bc2019-10-21 05:55:49 +0200597 lu_utran_tmsi();
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100598
599 BTW("after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector");
600 auth_request_sent = false;
601 auth_request_expect_rand = "c187a53a5e6b9d573cac7c74451fd46d";
602 auth_request_expect_autn = "1843a645b98d00005b2d666af46c45d9";
603 cm_service_result_sent = RES_NONE;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100604 ms_sends_msg("052471"
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100605 "03575886" /* classmark 2 */
606 "089910070000106005" /* IMSI */);
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100607 VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
608 VERBOSE_ASSERT(auth_request_sent, == true, "%d");
609
610 btw("needs auth, not yet accepted");
611 EXPECT_ACCEPTED(false);
612
613 /* On UTRAN */
614 btw("MS sends Authen Response, VLR accepts and sends SecurityModeControl");
615 expect_security_mode_ctrl(NULL, "1159ec926a50e98c034a6b7d7c9f418d");
616 ms_sends_msg("0554" "7db47cf7" "2104" "f81e4dc7"); /* 2nd vector's res, s.a. */
617 VERBOSE_ASSERT(security_mode_ctrl_sent, == true, "%d");
618 VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
619
620 btw("MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept");
Alexander Couzens2aaff752021-10-19 17:09:11 +0200621 ms_sends_security_mode_complete(1);
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100622 VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
623
624 BTW("a call is initiated");
625
Neels Hofmeyr11c04ae2023-11-28 04:40:52 +0100626 btw("CC SETUP causes CRCX towards CN and RAN");
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100627 expect_crcx(RTP_TO_CN);
628 expect_crcx(RTP_TO_RAN);
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100629 ms_sends_msg("0385" /* CC, seq = 2 -> 0x80 | CC Setup = 0x5 */
630 "0406600402000581" /* Bearer Capability */
631 "5e038121f3" /* Called Number BCD */
632 "15020100" /* CC Capabilities */
633 "4008" /* Supported Codec List */
634 "04026000" /* UMTS: AMR 2 | AMR */
635 "00021f00" /* GSM: HR AMR | FR AMR | GSM EFR | GSM HR | GSM FR */
636 );
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100637 OSMO_ASSERT(crcx_scheduled(RTP_TO_CN));
638 OSMO_ASSERT(crcx_scheduled(RTP_TO_RAN));
639
640 btw("As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered");
641 cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_IND);
642 crcx_ok(RTP_TO_CN);
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100643 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
Neels Hofmeyr6a1faa92023-03-23 01:56:14 +0100644 mncc.callref = mncc_rtp.callref = cc_to_mncc_tx_got_callref;
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100645
Neels Hofmeyr11c04ae2023-11-28 04:40:52 +0100646 btw("MNCC replies with MNCC_RTP_CREATE");
Neels Hofmeyr6a1faa92023-03-23 01:56:14 +0100647 mncc_sends_to_cc(MNCC_RTP_CREATE, &mncc_rtp);
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200648
649 btw("MGW acknowledges the CRCX, triggering Assignment");
650 expect_iu_rab_assignment();
651 crcx_ok(RTP_TO_RAN);
652 OSMO_ASSERT(iu_rab_assignment_sent);
653
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100654 btw("Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC");
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200655 cc_to_mncc_expect_tx("", MNCC_RTP_CREATE);
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100656 ms_sends_assignment_complete("AMR");
657 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200658
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100659 btw("MNCC says that's fine");
660 dtap_expect_tx("8302" /* CC: Call Proceeding */);
661 mncc_sends_to_cc(MNCC_CALL_PROC_REQ, &mncc);
662 OSMO_ASSERT(dtap_tx_confirmed);
663
664 btw("But the other side's MSISDN could not be resolved, MNCC tells us to cancel");
665 dtap_expect_tx("832d" /* CC: Release Request */);
666 mncc_sends_to_cc(MNCC_REL_REQ, &mncc);
667
668 dtap_expect_tx("832d" /* CC: Release Request */);
669 fake_time_passes(10, 23);
670
671 expect_iu_release();
672 cc_to_mncc_expect_tx("", MNCC_REL_CNF);
673 ms_sends_msg("036a" /* CC: Release Complete */);
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100674 OSMO_ASSERT(iu_release_sent);
675 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
676
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100677 ran_sends_clear_complete();
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100678 EXPECT_CONN_COUNT(0);
679 clear_vlr();
680 comment_end();
681}
682
683static void test_call_mo_to_unknown_timeout()
684{
685 struct gsm_mncc mncc = {
686 .imsi = IMSI,
687 };
Neels Hofmeyr6a1faa92023-03-23 01:56:14 +0100688 struct gsm_mncc_rtp mncc_rtp = {};
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100689
690 comment_start();
691
692 fake_time_start();
693
Neels Hofmeyr11bf0bc2019-10-21 05:55:49 +0200694 lu_utran_tmsi();
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100695
696 BTW("after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector");
697 auth_request_sent = false;
698 auth_request_expect_rand = "c187a53a5e6b9d573cac7c74451fd46d";
699 auth_request_expect_autn = "1843a645b98d00005b2d666af46c45d9";
700 cm_service_result_sent = RES_NONE;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100701 ms_sends_msg("052471"
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100702 "03575886" /* classmark 2 */
703 "089910070000106005" /* IMSI */);
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100704 VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
705 VERBOSE_ASSERT(auth_request_sent, == true, "%d");
706
707 btw("needs auth, not yet accepted");
708 EXPECT_ACCEPTED(false);
709
710 /* On UTRAN */
711 btw("MS sends Authen Response, VLR accepts and sends SecurityModeControl");
712 expect_security_mode_ctrl(NULL, "1159ec926a50e98c034a6b7d7c9f418d");
713 ms_sends_msg("0554" "7db47cf7" "2104" "f81e4dc7"); /* 2nd vector's res, s.a. */
714 VERBOSE_ASSERT(security_mode_ctrl_sent, == true, "%d");
715 VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
716
717 btw("MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept");
Alexander Couzens2aaff752021-10-19 17:09:11 +0200718 ms_sends_security_mode_complete(1);
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100719 VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
720
721 BTW("a call is initiated");
722
Neels Hofmeyr11c04ae2023-11-28 04:40:52 +0100723 btw("CC SETUP causes CRCX towards CN and RAN");
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100724 expect_crcx(RTP_TO_CN);
725 expect_crcx(RTP_TO_RAN);
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100726 ms_sends_msg("0385" /* CC, seq = 2 -> 0x80 | CC Setup = 0x5 */
727 "0406600402000581" /* Bearer Capability */
728 "5e038121f3" /* Called Number BCD */
729 "15020100" /* CC Capabilities */
730 "4008" /* Supported Codec List */
731 "04026000" /* UMTS: AMR 2 | AMR */
732 "00021f00" /* GSM: HR AMR | FR AMR | GSM EFR | GSM HR | GSM FR */
733 );
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100734 OSMO_ASSERT(crcx_scheduled(RTP_TO_CN));
735 OSMO_ASSERT(crcx_scheduled(RTP_TO_RAN));
736
737 btw("As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered");
738 cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_IND);
739 crcx_ok(RTP_TO_CN);
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100740 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
Neels Hofmeyr6a1faa92023-03-23 01:56:14 +0100741 mncc.callref = mncc_rtp.callref = cc_to_mncc_tx_got_callref;
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100742
Neels Hofmeyr11c04ae2023-11-28 04:40:52 +0100743 btw("MNCC replies with MNCC_RTP_CREATE");
Neels Hofmeyr6a1faa92023-03-23 01:56:14 +0100744 mncc_sends_to_cc(MNCC_RTP_CREATE, &mncc_rtp);
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200745
746 btw("MGW acknowledges the CRCX, triggering Assignment");
747 expect_iu_rab_assignment();
748 crcx_ok(RTP_TO_RAN);
749 OSMO_ASSERT(iu_rab_assignment_sent);
750
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100751 btw("Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC");
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200752 cc_to_mncc_expect_tx("", MNCC_RTP_CREATE);
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100753 ms_sends_assignment_complete("AMR");
754 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200755
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100756 btw("MNCC says that's fine");
757 dtap_expect_tx("8302" /* CC: Call Proceeding */);
758 mncc_sends_to_cc(MNCC_CALL_PROC_REQ, &mncc);
759 OSMO_ASSERT(dtap_tx_confirmed);
760
761 btw("But the other side's MSISDN could not be resolved, MNCC tells us to cancel");
762 dtap_expect_tx("832d" /* CC: Release Request */);
763 mncc_sends_to_cc(MNCC_REL_REQ, &mncc);
764
765 btw("Despite our repeated CC Release Requests, the MS does not respond anymore");
766 dtap_expect_tx("832d" /* CC: Release Request */);
767 fake_time_passes(10, 23);
768
769 btw("The CC Release times out and we still properly clear the conn");
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100770 cc_to_mncc_expect_tx("", MNCC_REL_CNF);
Neels Hofmeyrd6a769b2018-03-12 23:59:07 +0100771 expect_iu_release();
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100772 fake_time_passes(10, 23);
773 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100774 OSMO_ASSERT(iu_release_sent);
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100775
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100776 ran_sends_clear_complete();
Neels Hofmeyrd6a769b2018-03-12 23:59:07 +0100777 EXPECT_CONN_COUNT(0);
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100778 clear_vlr();
779 comment_end();
780}
781
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +0100782#define LIST_END 0xffff
783
784struct codec_test {
785 const char *desc;
786
787 /* What to send during Complete Layer 3 as Codec List (BSS Supported). List ends with a LIST_END entry */
788 enum gsm0808_speech_codec_type mo_rx_compl_l3_codec_list_bss_supported[8];
789
790 /* What to send during CC Setup as MS Bearer Capability. List ends with a LIST_END entry */
791 enum gsm48_bcap_speech_ver mo_rx_ms_bcap[8];
792
793 /* What codecs should osmo-msc send in the MNCC_SETUP_IND message.
794 * Just the SDP subtype names like "GSM", "GSM-EFR", "AMR", ..., list ends with NULL entry */
795 const char *mo_tx_sdp_mncc_setup_ind[8];
796
797 /* What codecs the remote call leg should send as SDP via MNCC during MNCC_RTP_CREATE (if any). */
798 const char *mo_rx_sdp_mncc_rtp_create[8];
799
800 /* What the MSC should send as Channel Type IE in the Assignment Command to the BSS. List ends with a
801 * LIST_END entry */
802 enum gsm0808_permitted_speech mo_tx_assignment_perm_speech[8];
803
804 /* What codec to assign in the Assignment Complete's Codec (Chosen) IE. Just a subtype name. */
805 const char *mo_rx_assigned_codec;
806
807 /* MO acks the MNCC_RTP_CREATE with these codecs (if any). */
808 const char *mo_tx_sdp_mncc_rtp_create[8];
809
810 /* mt_rx_sdp_mncc_setup_req == mo_tx_sdp_mncc_rtp_create */
811#define mt_rx_sdp_mncc_setup_req mo_tx_sdp_mncc_rtp_create
812
813 enum gsm0808_speech_codec_type mt_rx_compl_l3_codec_list_bss_supported[8];
814 bool expect_codec_mismatch_on_paging_response;
815 enum gsm48_bcap_speech_ver mt_tx_cc_setup_bcap[8];
816 enum gsm48_bcap_speech_ver mt_rx_ms_bcap[8];
817 bool expect_codec_mismatch_on_cc_call_conf;
818 const char *mt_tx_sdp_mncc_call_conf_ind[8];
819
820 enum gsm0808_permitted_speech mt_tx_assignment_perm_speech[8];
821 const char *mt_rx_assigned_codec;
822
823 const char *mt_rx_sdp_mncc_rtp_create[8];
824 const char *mt_tx_sdp_mncc_rtp_create[8];
825
826 const char *mt_tx_sdp_mncc_alert_ind[8];
Neels Hofmeyrb51c35e2023-11-28 04:45:09 +0100827
828 bool mo_expect_reassignment;
829 enum gsm0808_permitted_speech mo_tx_reassignment_perm_speech[8];
830 const char *mo_rx_reassigned_codec;
831
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +0100832 const char *mt_tx_sdp_mncc_setup_cnf[8];
833 const char *mt_rx_sdp_mncc_setup_compl_req[8];
834
835 /* mo_rx_sdp_mncc_alert_req == mt_tx_sdp_mncc_alert_ind */
836#define mo_rx_sdp_mncc_alert_req mt_tx_sdp_mncc_alert_ind
837#define mo_rx_sdp_mncc_setup_rsp mt_tx_sdp_mncc_alert_ind
838
839 const char *mo_tx_sdp_mncc_setup_compl_ind[8];
840};
841
842#define CODEC_LIST_ALL_GSM { \
843 GSM0808_SCT_FR1, \
844 GSM0808_SCT_FR2, \
845 GSM0808_SCT_FR3, \
846 GSM0808_SCT_HR1, \
847 GSM0808_SCT_HR3, \
848 LIST_END \
849 }
850
851#define BCAP_ALL_GSM { \
852 GSM48_BCAP_SV_AMR_F, \
853 GSM48_BCAP_SV_AMR_H, \
854 GSM48_BCAP_SV_AMR_OH, \
855 GSM48_BCAP_SV_EFR, \
856 GSM48_BCAP_SV_FR, \
857 GSM48_BCAP_SV_HR, \
858 LIST_END \
859 }
860
861#define PERM_SPEECH_ALL_GSM { \
862 GSM0808_PERM_FR3, \
863 GSM0808_PERM_HR3, \
864 GSM0808_PERM_FR2, \
865 GSM0808_PERM_FR1, \
866 GSM0808_PERM_HR1, \
867 LIST_END \
868 }
869
870#define SDP_CODECS_ALL_GSM { \
871 "AMR", \
872 "GSM-EFR", \
873 "GSM", \
874 "GSM-HR-08", \
875 }
876
877static const struct codec_test codec_tests[] = {
878 {
879 .desc = "AMR picked by both MO and MT",
880 .mo_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
881 .mo_rx_ms_bcap = BCAP_ALL_GSM,
882 .mo_tx_sdp_mncc_setup_ind = SDP_CODECS_ALL_GSM,
883 .mo_rx_sdp_mncc_rtp_create = {},
884 .mo_tx_assignment_perm_speech = PERM_SPEECH_ALL_GSM,
885 .mo_rx_assigned_codec = "AMR",
Neels Hofmeyrb51c35e2023-11-28 04:45:09 +0100886 .mo_tx_sdp_mncc_rtp_create = { "AMR", "GSM-EFR", "GSM", "GSM-HR-08" },
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +0100887 /* mt_rx_sdp_mncc_setup_req == mo_tx_sdp_mncc_rtp_create */
888 .mt_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
889 .mt_tx_cc_setup_bcap = {
890 GSM48_BCAP_SV_AMR_F,
891 GSM48_BCAP_SV_AMR_H,
892 GSM48_BCAP_SV_AMR_OH,
Neels Hofmeyrb51c35e2023-11-28 04:45:09 +0100893 GSM48_BCAP_SV_EFR,
894 GSM48_BCAP_SV_FR,
895 GSM48_BCAP_SV_HR,
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +0100896 LIST_END
897 },
898 .mt_rx_ms_bcap = BCAP_ALL_GSM,
899 .mt_tx_sdp_mncc_call_conf_ind = {},
900 .mt_rx_sdp_mncc_rtp_create = {},
Neels Hofmeyrb51c35e2023-11-28 04:45:09 +0100901 .mt_tx_assignment_perm_speech = {
902 GSM0808_PERM_FR3,
903 GSM0808_PERM_HR3,
904 GSM0808_PERM_FR2,
905 GSM0808_PERM_FR1,
906 GSM0808_PERM_HR1,
907 LIST_END
908 },
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +0100909 .mt_rx_assigned_codec = "AMR",
Neels Hofmeyrb51c35e2023-11-28 04:45:09 +0100910 .mt_tx_sdp_mncc_rtp_create = { "AMR", "GSM-EFR", "GSM", "GSM-HR-08" },
911 .mt_tx_sdp_mncc_alert_ind = { "AMR", "GSM-EFR", "GSM", "GSM-HR-08" },
912 .mt_tx_sdp_mncc_setup_cnf = { "AMR", "GSM-EFR", "GSM", "GSM-HR-08" },
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +0100913 .mo_tx_sdp_mncc_setup_compl_ind = {},
914 },
915
916 {
917 .desc = "FR1 picked by MO from Codec List (BSS Supported), MT hence also picks FR1",
918 .mo_rx_compl_l3_codec_list_bss_supported = { GSM0808_SCT_FR1, LIST_END },
919 .mo_rx_ms_bcap = BCAP_ALL_GSM,
920 .mo_tx_sdp_mncc_setup_ind = { "GSM" },
921 .mo_rx_sdp_mncc_rtp_create = {},
922 .mo_tx_assignment_perm_speech = { GSM0808_PERM_FR1, LIST_END },
923 .mo_rx_assigned_codec = "GSM",
924 .mo_tx_sdp_mncc_rtp_create = { "GSM" },
925 /* .mt_rx_sdp_mncc_setup_req == .mo_tx_sdp_mncc_setup_ind */
926 .mt_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
927 .mt_tx_cc_setup_bcap = { GSM48_BCAP_SV_FR, LIST_END },
928 .mt_rx_ms_bcap = BCAP_ALL_GSM,
929 .mt_tx_sdp_mncc_call_conf_ind = {},
930 .mt_rx_sdp_mncc_rtp_create = {},
931 .mt_tx_assignment_perm_speech = { GSM0808_PERM_FR1, LIST_END },
932 .mt_rx_assigned_codec = "GSM",
933 .mt_tx_sdp_mncc_rtp_create = { "GSM" },
934 .mt_tx_sdp_mncc_alert_ind = { "GSM" },
935 .mt_tx_sdp_mncc_setup_cnf = { "GSM" },
936 .mo_tx_sdp_mncc_setup_compl_ind = {},
937 },
938
939 {
940 .desc = "FR1 picked by MO from Bearer Cap, MT hence also picks FR1",
941 .mo_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
942 .mo_rx_ms_bcap = { GSM48_BCAP_SV_FR, LIST_END },
943 .mo_tx_sdp_mncc_setup_ind = { "GSM" },
944 .mo_rx_sdp_mncc_rtp_create = {},
945 .mo_tx_assignment_perm_speech = { GSM0808_PERM_FR1, LIST_END },
946 .mo_rx_assigned_codec = "GSM",
947 .mo_tx_sdp_mncc_rtp_create = { "GSM" },
948 /* .mt_rx_sdp_mncc_setup_req == .mo_tx_sdp_mncc_setup_ind */
949 .mt_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
950 .mt_tx_cc_setup_bcap = { GSM48_BCAP_SV_FR, LIST_END },
951 .mt_rx_ms_bcap = BCAP_ALL_GSM,
952 .mt_tx_sdp_mncc_call_conf_ind = {},
953 .mt_rx_sdp_mncc_rtp_create = {},
954 .mt_tx_assignment_perm_speech = { GSM0808_PERM_FR1, LIST_END },
955 .mt_rx_assigned_codec = "GSM",
956 .mt_tx_sdp_mncc_rtp_create = { "GSM" },
957 .mt_tx_sdp_mncc_alert_ind = { "GSM" },
958 .mt_tx_sdp_mncc_setup_cnf = { "GSM" },
959 .mo_tx_sdp_mncc_setup_compl_ind = {},
960 },
961
962 {
Neels Hofmeyrb51c35e2023-11-28 04:45:09 +0100963 .desc = "FR1 picked by MT's Codec List (BSS Supported), hence MO re-assigns to FR1",
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +0100964 .mo_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
965 .mo_rx_ms_bcap = BCAP_ALL_GSM,
966 .mo_tx_sdp_mncc_setup_ind = SDP_CODECS_ALL_GSM,
967 .mo_rx_sdp_mncc_rtp_create = {},
968 .mo_tx_assignment_perm_speech = PERM_SPEECH_ALL_GSM,
Neels Hofmeyrb51c35e2023-11-28 04:45:09 +0100969 .mo_rx_assigned_codec = "AMR", /* <- Early Assignment first picks a mismatching codec */
970 .mo_tx_sdp_mncc_rtp_create = { "AMR", "GSM-EFR", "GSM", "GSM-HR-08" },
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +0100971
Neels Hofmeyrb51c35e2023-11-28 04:45:09 +0100972 /* This is the codec limitation this test verifies, Codec List (BSS Supported): */
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +0100973 .mt_rx_compl_l3_codec_list_bss_supported = { GSM0808_SCT_FR1, LIST_END },
Neels Hofmeyrb51c35e2023-11-28 04:45:09 +0100974
975 /* from above codec list, MSC derives the limited bcap sent in CC Setup to MS */
976 .mt_tx_cc_setup_bcap = {
977 GSM48_BCAP_SV_FR,
978 LIST_END
979 },
980 /* MS could do more, but it doesn't affect the choice of FR1 */
981 .mt_rx_ms_bcap = BCAP_ALL_GSM,
982 .mt_tx_sdp_mncc_call_conf_ind = {},
983 .mt_rx_sdp_mncc_rtp_create = {},
984 .mt_tx_assignment_perm_speech = {
985 GSM0808_PERM_FR1,
986 LIST_END
987 },
988 .mt_rx_assigned_codec = "GSM",
989 .mt_tx_sdp_mncc_rtp_create = { "GSM" },
990 .mt_tx_sdp_mncc_alert_ind = { "GSM" },
991
992 .mo_expect_reassignment = true,
993 .mo_tx_reassignment_perm_speech = {
994 GSM0808_PERM_FR1,
995 LIST_END
996 },
997 .mo_rx_reassigned_codec = "GSM",
998
999 .mt_tx_sdp_mncc_setup_cnf = { "GSM" },
1000 .mo_tx_sdp_mncc_setup_compl_ind = {},
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001001 },
1002
1003 {
Neels Hofmeyrb51c35e2023-11-28 04:45:09 +01001004 .desc = "FR1 picked by MT's MS Bearer Capability, hence MO re-assigns to FR1",
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001005 .mo_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
1006 .mo_rx_ms_bcap = BCAP_ALL_GSM,
1007 .mo_tx_sdp_mncc_setup_ind = SDP_CODECS_ALL_GSM,
1008 .mo_rx_sdp_mncc_rtp_create = {},
1009 .mo_tx_assignment_perm_speech = PERM_SPEECH_ALL_GSM,
Neels Hofmeyrb51c35e2023-11-28 04:45:09 +01001010 .mo_rx_assigned_codec = "AMR", /* <- Early Assignment first picks a mismatching codec */
1011 .mo_tx_sdp_mncc_rtp_create = { "AMR", "GSM-EFR", "GSM", "GSM-HR-08" },
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001012
1013 .mt_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
Neels Hofmeyrb51c35e2023-11-28 04:45:09 +01001014 .mt_tx_cc_setup_bcap = BCAP_ALL_GSM,
1015
1016 /* This is the codec limitation this test verifies: */
1017 .mt_rx_ms_bcap = {
1018 GSM48_BCAP_SV_FR,
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001019 LIST_END
1020 },
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001021 .mt_tx_sdp_mncc_call_conf_ind = {},
1022 .mt_rx_sdp_mncc_rtp_create = {},
Neels Hofmeyrb51c35e2023-11-28 04:45:09 +01001023 .mt_tx_assignment_perm_speech = {
1024 GSM0808_PERM_FR1,
1025 LIST_END
1026 },
1027 .mt_rx_assigned_codec = "GSM",
1028 .mt_tx_sdp_mncc_rtp_create = { "GSM" },
1029 .mt_tx_sdp_mncc_alert_ind = { "GSM" },
1030
1031 .mo_expect_reassignment = true,
1032 .mo_tx_reassignment_perm_speech = {
1033 GSM0808_PERM_FR1,
1034 LIST_END
1035 },
1036 .mo_rx_reassigned_codec = "GSM",
1037
1038 .mt_tx_sdp_mncc_setup_cnf = { "GSM" },
1039 .mo_tx_sdp_mncc_setup_compl_ind = {},
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001040 },
1041
Neels Hofmeyr636b4a92023-11-28 05:26:43 +01001042 {
1043 .desc = "AMR picked by both MO and MT, but MT assigns a different payload type number",
1044 .mo_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
1045 .mo_rx_ms_bcap = BCAP_ALL_GSM,
1046 .mo_tx_sdp_mncc_setup_ind = SDP_CODECS_ALL_GSM,
1047 .mo_rx_sdp_mncc_rtp_create = {},
1048 .mo_tx_assignment_perm_speech = PERM_SPEECH_ALL_GSM,
1049 .mo_rx_assigned_codec = "AMR",
1050 .mo_tx_sdp_mncc_rtp_create = { "AMR", "GSM-EFR", "GSM", "GSM-HR-08" },
1051 /* mt_rx_sdp_mncc_setup_req == mo_tx_sdp_mncc_rtp_create */
1052 .mt_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
1053 .mt_tx_cc_setup_bcap = {
1054 GSM48_BCAP_SV_AMR_F,
1055 GSM48_BCAP_SV_AMR_H,
1056 GSM48_BCAP_SV_AMR_OH,
1057 GSM48_BCAP_SV_EFR,
1058 GSM48_BCAP_SV_FR,
1059 GSM48_BCAP_SV_HR,
1060 LIST_END
1061 },
1062 .mt_rx_ms_bcap = BCAP_ALL_GSM,
1063 .mt_tx_sdp_mncc_call_conf_ind = {},
1064 .mt_rx_sdp_mncc_rtp_create = {},
1065 .mt_tx_assignment_perm_speech = {
1066 GSM0808_PERM_FR3,
1067 GSM0808_PERM_HR3,
1068 GSM0808_PERM_FR2,
1069 GSM0808_PERM_FR1,
1070 GSM0808_PERM_HR1,
1071 LIST_END
1072 },
1073 .mt_rx_assigned_codec = "AMR",
Neels Hofmeyrd655cd02023-11-28 05:29:14 +01001074 .mt_tx_sdp_mncc_rtp_create = { "AMR#96", "GSM-EFR", "GSM", "GSM-HR-08" },
1075 .mt_tx_sdp_mncc_alert_ind = { "AMR#96", "GSM-EFR", "GSM", "GSM-HR-08" },
1076 .mt_tx_sdp_mncc_setup_cnf = { "AMR#96", "GSM-EFR", "GSM", "GSM-HR-08" },
Neels Hofmeyr636b4a92023-11-28 05:26:43 +01001077 .mo_tx_sdp_mncc_setup_compl_ind = {},
1078 },
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001079};
1080
1081static char namebuf[4][1024];
1082static int use_namebuf = 0;
1083
1084static const char *codec_list_name(const enum gsm0808_speech_codec_type compl_l3_codec_list_bss_supported[])
1085{
1086 struct osmo_strbuf sb = { .buf = namebuf[use_namebuf], .len = sizeof(namebuf[0]) };
1087 use_namebuf = (use_namebuf + 1) % ARRAY_SIZE(namebuf);
1088
1089 const enum gsm0808_speech_codec_type *pos;
1090 sb.buf[0] = '\0';
1091 for (pos = compl_l3_codec_list_bss_supported; *pos != LIST_END; pos++)
1092 OSMO_STRBUF_PRINTF(sb, " %s", gsm0808_speech_codec_type_name(*pos));
1093 return sb.buf;
1094}
1095
1096static const struct gsm0808_speech_codec_list *codec_list(const enum gsm0808_speech_codec_type compl_l3_codec_list_bss_supported[])
1097{
1098 static struct gsm0808_speech_codec_list scl;
1099 scl = (struct gsm0808_speech_codec_list){};
1100 const enum gsm0808_speech_codec_type *pos;
1101 for (pos = compl_l3_codec_list_bss_supported; *pos != LIST_END; pos++) {
1102 scl.codec[scl.len] = (struct gsm0808_speech_codec){
1103 .fi = true,
1104 .type = *pos,
1105 };
1106 scl.len++;
1107 }
1108 return &scl;
1109}
1110
1111static const char *bcap_name(const enum gsm48_bcap_speech_ver ms_bcap[])
1112{
1113 struct osmo_strbuf sb = { .buf = namebuf[use_namebuf], .len = sizeof(namebuf[0]) };
1114 use_namebuf = (use_namebuf + 1) % ARRAY_SIZE(namebuf);
1115
1116 const enum gsm48_bcap_speech_ver *pos;
1117 sb.buf[0] = '\0';
1118 for (pos = ms_bcap; *pos != LIST_END; pos++) {
1119 const struct codec_mapping *m = codec_mapping_by_speech_ver(*pos);
1120 OSMO_STRBUF_PRINTF(sb, " %s", m ? m->sdp.subtype_name : "NULL");
1121 }
1122 return sb.buf;
1123}
1124
1125static const char *perm_speech_name(const enum gsm0808_permitted_speech perm_speech[])
1126{
1127 struct osmo_strbuf sb = { .buf = namebuf[use_namebuf], .len = sizeof(namebuf[0]) };
1128 use_namebuf = (use_namebuf + 1) % ARRAY_SIZE(namebuf);
1129
1130 const enum gsm0808_permitted_speech *pos;
1131 sb.buf[0] = '\0';
1132 for (pos = perm_speech; *pos != LIST_END; pos++)
1133 OSMO_STRBUF_PRINTF(sb, " %s", gsm0808_permitted_speech_name(*pos));
1134 return sb.buf;
1135}
1136
1137static const char *strlist_name(const char *const*strs)
1138{
1139 struct osmo_strbuf sb = { .buf = namebuf[use_namebuf], .len = sizeof(namebuf[0]) };
1140 use_namebuf = (use_namebuf + 1) % ARRAY_SIZE(namebuf);
1141
1142 const char * const *pos;
1143 sb.buf[0] = '\0';
1144 for (pos = strs; *pos != NULL; pos++)
1145 OSMO_STRBUF_PRINTF(sb, " %s", *pos);
1146 return sb.buf;
1147}
1148
Neels Hofmeyrd655cd02023-11-28 05:29:14 +01001149/* Split an input string of "AMR#96" into "AMR" and 96: copy the subtype name without the "#96" part to
1150 * split_subtype_name_and_pt_nr which must be a char[16]. If pt_nr is non-NULL, write the 96 to *pt_nr.
1151 */
1152static void split_subtype_name_and_pt_nr(char subtype_name_wo_pt[], int *pt_nr, const char *input)
1153{
1154 char *hash;
1155 osmo_strlcpy(subtype_name_wo_pt, input, 16);
1156 hash = strchr(subtype_name_wo_pt, '#');
1157 if (hash) {
1158 *hash = '\0';
1159 if (pt_nr)
1160 *pt_nr = atoi(hash + 1);
1161 }
1162}
1163
1164/* Validate that the codecs in sdp_str appear in the order as expected by the list of subtype names in expected_codecs.
1165 * Ignore any payload type numbers ("#96") in expected_codecs.
1166 */
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001167static bool validate_sdp(const char *func, const char *desc,
1168 const char *sdp_str, const char * const expected_codecs[])
1169{
1170 const char * const *expect_pos;
1171 struct sdp_audio_codec *codec;
1172 struct sdp_msg sdp;
1173 if (sdp_msg_from_sdp_str(&sdp, sdp_str)) {
1174 BTW("%s: %s: ERROR: failed to parse SDP\n%s", func, desc, sdp_str);
1175 return false;
1176 }
1177
1178 expect_pos = expected_codecs;
1179 foreach_sdp_audio_codec(codec, &sdp.audio_codecs) {
Neels Hofmeyrd655cd02023-11-28 05:29:14 +01001180 char subtype_name_wo_pt[16];
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001181 if (!*expect_pos) {
1182 BTW("%s: %s: ERROR: did not expect %s", func, desc, codec->subtype_name);
1183 return false;
1184 }
Neels Hofmeyrd655cd02023-11-28 05:29:14 +01001185 split_subtype_name_and_pt_nr(subtype_name_wo_pt, NULL, *expect_pos);
1186 if (strcmp(subtype_name_wo_pt, codec->subtype_name)) {
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001187 BTW("%s: %s: ERROR: mismatch: in idx %d, expect %s, got %s", func, desc,
1188 (int)(expect_pos - expected_codecs), *expect_pos, codec->subtype_name);
1189 return false;
1190 }
1191 expect_pos++;
Neels Hofmeyrd767c732023-11-17 04:12:29 +01001192
1193 /* only match first codec */
1194 return true;
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001195 }
1196 if (*expect_pos) {
1197 BTW("%s: %s: ERROR: mismatch: expected %s to be listed, but not found", func, desc, *expect_pos);
1198 return false;
1199 }
1200 return true;
1201}
1202
1203#define VALIDATE_SDP(GOT_SDP_STR, EXPECT_SDP_STR) do { \
1204 if (validate_sdp(__func__, t->desc, GOT_SDP_STR, EXPECT_SDP_STR)) { \
1205 btw("VALIDATE_SDP OK: " #GOT_SDP_STR " == " #EXPECT_SDP_STR " ==%s", strlist_name(EXPECT_SDP_STR)); \
1206 } else { \
1207 btw("Failed to validate SDP:\nexpected%s\ngot\n%s", \
1208 strlist_name(EXPECT_SDP_STR), GOT_SDP_STR); \
1209 OSMO_ASSERT(false); \
1210 } \
1211 } while (0)
1212
1213static bool validate_perm_speech(const char *func, const char *desc,
1214 const struct gsm0808_channel_type *ct,
1215 const enum gsm0808_permitted_speech perm_speech[])
1216{
1217 const enum gsm0808_permitted_speech *pos;
1218 const uint8_t *pos2 = ct->perm_spch;
1219 for (pos = perm_speech; *pos != LIST_END; pos++, pos2++) {
1220 if (pos2 - ct->perm_spch >= ct->perm_spch_len) {
1221 BTW("%s: %s: ERROR: mismatch: expected %s to be listed, but not found", func, desc,
1222 gsm0808_permitted_speech_name(*pos));
1223 return false;
1224 }
1225 if (*pos2 != *pos) {
1226 BTW("%s: %s: ERROR: mismatch: in idx %d, expect %s", func, desc,
1227 (int)(pos - perm_speech), gsm0808_permitted_speech_name(*pos));
1228 btw("in idx %d, got %s", (int)(pos - perm_speech), gsm0808_permitted_speech_name(*pos2));
1229 return false;
1230 }
1231 }
1232 if (pos2 - ct->perm_spch < ct->perm_spch_len) {
1233 BTW("%s: %s: ERROR: did not expect %s", func, desc, gsm0808_permitted_speech_name(*pos2));
1234 return false;
1235 }
1236 return true;
1237}
1238
1239#define VALIDATE_PERM_SPEECH(GOT_PERM_SPEECH, EXPECT_PERM_SPEECH) do { \
1240 if (validate_perm_speech(__func__, t->desc, GOT_PERM_SPEECH, EXPECT_PERM_SPEECH)) { \
1241 btw("VALIDATE_PERM_SPEECH OK: " #GOT_PERM_SPEECH " == " #EXPECT_PERM_SPEECH " ==%s", \
1242 perm_speech_name(EXPECT_PERM_SPEECH)); \
1243 } else { \
1244 btw("Failed to validate Permitted Speech:\nexpected%s", \
1245 perm_speech_name(EXPECT_PERM_SPEECH)); \
1246 btw("got:"); \
1247 int i; \
1248 for (i = 0; i < (GOT_PERM_SPEECH)->perm_spch_len; i++) { \
1249 btw("%s", gsm0808_permitted_speech_name((GOT_PERM_SPEECH)->perm_spch[i])); \
1250 } \
1251 OSMO_ASSERT(false); \
1252 } \
1253 } while (0)
1254
Neels Hofmeyrd655cd02023-11-28 05:29:14 +01001255/* Compose a valid SDP string from the list of codec subtype names given. If a subtype name includes a payload type
1256 * number ("AMR#96") then use that PT number in the SDP instead of the default from codec_mapping.c. */
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001257static struct sdp_msg *sdp_from_subtype_names(const char *const *subtype_names)
1258{
1259 static struct sdp_msg sdp;
1260 sdp = (struct sdp_msg){};
1261 const char *const *subtype_name;
1262 osmo_sockaddr_str_from_str(&sdp.rtp, "1.2.3.4", 56);
1263 for (subtype_name = subtype_names; *subtype_name; subtype_name++) {
Neels Hofmeyrd655cd02023-11-28 05:29:14 +01001264 char subtype_name_wo_pt[16];
1265 const struct codec_mapping *m;
1266 struct sdp_audio_codec *ac;
1267 int set_pt = -1;
1268 split_subtype_name_and_pt_nr(subtype_name_wo_pt, &set_pt, *subtype_name);
1269 m = codec_mapping_by_subtype_name(subtype_name_wo_pt);
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001270 if (!m) {
1271 BTW("ERROR: unknown subtype_name: %s", *subtype_name);
1272 abort();
1273 }
Neels Hofmeyrd655cd02023-11-28 05:29:14 +01001274 ac = sdp_audio_codecs_add_copy(&sdp.audio_codecs, &m->sdp);
1275 if (set_pt >= 0)
1276 ac->payload_type = set_pt;
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001277 }
1278 return &sdp;
1279}
1280
1281static int sdp_str_from_subtype_names(char *buf, size_t buflen, const char *const *subtype_names)
1282{
1283 if (!subtype_names[0]) {
1284 buf[0] = '\0';
1285 return 0;
1286 }
1287 return sdp_msg_to_sdp_str_buf(buf, buflen, sdp_from_subtype_names(subtype_names));
1288}
1289
1290static const char *bcap_hexstr(const enum gsm48_bcap_speech_ver ms_bcap[])
1291{
1292 struct gsm_mncc_bearer_cap bcap = {
1293 .transfer = GSM_MNCC_BCAP_SPEECH,
1294 .speech_ver = { -1 },
1295 };
1296 const enum gsm48_bcap_speech_ver *pos;
1297 for (pos = ms_bcap; *pos != LIST_END; pos++)
1298 bearer_cap_add_speech_ver(&bcap, *pos);
1299 bearer_cap_set_radio(&bcap);
1300 struct msgb *msg = msgb_alloc(128, "bcap");
1301 gsm48_encode_bearer_cap(msg, 0, &bcap);
1302 char *ret = osmo_hexdump_nospc(msg->data, msg->len);
1303 msgb_free(msg);
1304 return ret;
1305}
1306
1307static void test_codecs_mo(const struct codec_test *t)
1308{
1309 struct gsm_mncc mncc = {
1310 .imsi = IMSI,
1311 };
1312
Neels Hofmeyr6a1faa92023-03-23 01:56:14 +01001313 struct gsm_mncc_rtp mncc_rtp = {};
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001314
1315 BTW("======================== MO call: %s", t->desc);
1316 btw("CM Service Request with Codec List (BSS Supported) =%s",
1317 codec_list_name(t->mo_rx_compl_l3_codec_list_bss_supported));
1318
1319 cm_service_result_sent = RES_NONE;
1320 ms_sends_compl_l3("052471"
1321 "03575886" /* classmark 2 */
1322 "089910070000106005" /* IMSI */,
1323 codec_list(t->mo_rx_compl_l3_codec_list_bss_supported));
1324 VERBOSE_ASSERT(cm_service_result_sent, == RES_ACCEPT, "%d");
1325 EXPECT_ACCEPTED(true);
1326
1327 btw("MS sends CC SETUP with Bearer Capability = %s",
1328 bcap_name(t->mo_rx_ms_bcap));
1329 expect_crcx(RTP_TO_CN);
1330 expect_crcx(RTP_TO_RAN);
1331 ms_sends_msgf("0385" /* CC, seq = 2 -> 0x80 | CC Setup = 0x5 */
1332 "%s" /* Bearer Capability */
1333 "5e038121f3" /* Called Number BCD */
1334 "15020100" /* CC Capabilities */
1335 "4008" /* Supported Codec List */
1336 "04026000" /* UMTS: AMR 2 | AMR */
1337 "00021f00" /* GSM: HR AMR | FR AMR | GSM EFR | GSM HR | GSM FR */,
1338 bcap_hexstr(t->mo_rx_ms_bcap)
1339 );
1340 OSMO_ASSERT(crcx_scheduled(RTP_TO_CN));
1341 OSMO_ASSERT(crcx_scheduled(RTP_TO_RAN));
1342
1343 btw("As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered");
1344 cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_IND);
1345 crcx_ok(RTP_TO_CN);
1346 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
Neels Hofmeyr6a1faa92023-03-23 01:56:14 +01001347 mncc.callref = mncc_rtp.callref = cc_to_mncc_tx_got_callref;
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001348 VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mo_tx_sdp_mncc_setup_ind);
1349
Neels Hofmeyr11c04ae2023-11-28 04:40:52 +01001350 btw("MNCC replies with MNCC_RTP_CREATE");
Neels Hofmeyr6a1faa92023-03-23 01:56:14 +01001351 sdp_str_from_subtype_names(mncc_rtp.sdp, sizeof(mncc_rtp.sdp), t->mo_rx_sdp_mncc_rtp_create);
1352 mncc_sends_to_cc(MNCC_RTP_CREATE, &mncc_rtp);
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001353
1354 btw("MGW acknowledges the CRCX, triggering Assignment with%s", perm_speech_name(t->mo_tx_assignment_perm_speech));
1355 expect_bssap_assignment();
1356 crcx_ok(RTP_TO_RAN);
1357 OSMO_ASSERT(bssap_assignment_sent);
1358 VALIDATE_PERM_SPEECH(&bssap_assignment_command_last_channel_type, t->mo_tx_assignment_perm_speech);
1359
1360 btw("Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC");
1361 cc_to_mncc_expect_tx("", MNCC_RTP_CREATE);
1362 ms_sends_assignment_complete(t->mo_rx_assigned_codec);
1363 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1364 VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mo_tx_sdp_mncc_rtp_create);
1365
1366 btw("MNCC says that's fine");
1367 dtap_expect_tx("8302" /* CC: Call Proceeding */);
1368 mncc_sends_to_cc(MNCC_CALL_PROC_REQ, &mncc);
1369 OSMO_ASSERT(dtap_tx_confirmed);
1370
1371 fake_time_passes(1, 23);
1372
1373 btw("The other call leg got established (not shown here), MNCC tells us so, with codecs {%s }",
1374 strlist_name(t->mo_rx_sdp_mncc_alert_req));
1375 dtap_expect_tx("8301" /* CC: Call Alerting */);
Neels Hofmeyrb51c35e2023-11-28 04:45:09 +01001376
1377 if (t->mo_expect_reassignment) {
1378 btw("Expecting re-assignment");
1379 expect_bssap_assignment();
1380 }
1381
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001382 sdp_str_from_subtype_names(mncc.sdp, sizeof(mncc.sdp), t->mo_rx_sdp_mncc_alert_req);
1383 mncc_sends_to_cc(MNCC_ALERT_REQ, &mncc);
1384 OSMO_ASSERT(dtap_tx_confirmed);
1385
Neels Hofmeyrb51c35e2023-11-28 04:45:09 +01001386 if (t->mo_expect_reassignment) {
1387 btw("Validating re-assignment");
1388 OSMO_ASSERT(bssap_assignment_sent);
1389 VALIDATE_PERM_SPEECH(&bssap_assignment_command_last_channel_type, t->mo_tx_reassignment_perm_speech);
1390 ms_sends_assignment_complete(t->mo_rx_reassigned_codec);
1391 }
1392
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001393 dtap_expect_tx("8307" /* CC: Connect */);
1394 sdp_str_from_subtype_names(mncc.sdp, sizeof(mncc.sdp), t->mo_rx_sdp_mncc_setup_rsp);
1395 mncc_sends_to_cc(MNCC_SETUP_RSP, &mncc);
1396 OSMO_ASSERT(dtap_tx_confirmed);
1397
1398 fake_time_passes(1, 23);
1399
1400 cc_to_mncc_expect_tx("", MNCC_SETUP_COMPL_IND);
1401 ms_sends_msg("03cf" /* CC: Connect Acknowledge */);
1402 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1403 VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mo_tx_sdp_mncc_setup_compl_ind);
1404
1405 BTW("RTP stream goes ahead, not shown here.");
1406 fake_time_passes(123, 45);
1407
1408 BTW("Call ends");
1409 cc_to_mncc_expect_tx("", MNCC_DISC_IND);
1410 ms_sends_msg("032502e090" /* CC: Disconnect, cause: Normal Call Clearing */);
1411 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1412
1413 dtap_expect_tx("832d" /* CC: Release */);
1414 mncc_sends_to_cc(MNCC_REL_REQ, &mncc);
1415 OSMO_ASSERT(dtap_tx_confirmed);
1416
1417 cc_to_mncc_expect_tx("", MNCC_REL_CNF);
1418 expect_bssap_clear();
1419 ms_sends_msg("036a" /* CC: Release Complete */);
1420 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1421 OSMO_ASSERT(bssap_clear_sent);
1422
1423 ran_sends_clear_complete();
1424 EXPECT_CONN_COUNT(0);
1425 BTW("======================== SUCCESS: MO call: %s", t->desc);
1426}
1427
1428static void test_codecs_mt(const struct codec_test *t)
1429{
1430 struct gsm_mncc mncc = {
1431 .imsi = IMSI,
1432 .callref = 0x423,
1433 .fields = MNCC_F_BEARER_CAP,
1434 .bearer_cap = {
1435 .speech_ver = { GSM48_BCAP_SV_FR, -1, },
1436 },
1437 };
Neels Hofmeyr6a1faa92023-03-23 01:56:14 +01001438 struct gsm_mncc_rtp mncc_rtp = {
1439 .callref = 0x423,
1440 };
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001441
1442 BTW("======================== MT call: %s", t->desc);
1443
1444 BTW("MNCC asks us to setup a call, causing Paging");
1445
1446 paging_expect_imsi(IMSI);
1447 paging_sent = false;
1448 sdp_str_from_subtype_names(mncc.sdp, sizeof(mncc.sdp), t->mt_rx_sdp_mncc_setup_req);
1449 mncc_sends_to_cc(MNCC_SETUP_REQ, &mncc);
1450 mncc.sdp[0] = '\0';
1451
1452 VERBOSE_ASSERT(paging_sent, == true, "%d");
1453
1454 btw("MS replies with Paging Response, with Codec List (BSS Supported) =%s",
1455 codec_list_name(t->mt_rx_compl_l3_codec_list_bss_supported));
1456
1457 if (t->expect_codec_mismatch_on_paging_response) {
1458 btw("VLR accepts, but MSC notices a codec mismatch and aborts");
1459 cc_to_mncc_expect_tx("", MNCC_REL_IND);
1460 expect_bssap_clear();
1461 ms_sends_compl_l3("062707"
1462 "03575886" /* classmark 2 */
1463 "089910070000106005" /* IMSI */,
1464 codec_list(t->mt_rx_compl_l3_codec_list_bss_supported));
1465 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1466 OSMO_ASSERT(bssap_clear_sent);
1467
1468 ran_sends_clear_complete();
1469 EXPECT_CONN_COUNT(0);
1470
1471 BTW("======================== SUCCESS: MT call: %s", t->desc);
1472 return;
1473 }
1474
1475 btw("VLR accepts, MSC sends CC Setup with Bearer Capability = %s",
1476 bcap_name(t->mt_tx_cc_setup_bcap));
1477 char *cc_setup_bcap = talloc_asprintf(msc_vlr_tests_ctx, "0305%s",
1478 bcap_hexstr(t->mt_tx_cc_setup_bcap));
1479 dtap_expect_tx(cc_setup_bcap);
1480 ms_sends_compl_l3("062707"
1481 "03575886" /* classmark 2 */
1482 "089910070000106005" /* IMSI */,
1483 codec_list(t->mt_rx_compl_l3_codec_list_bss_supported));
1484 OSMO_ASSERT(dtap_tx_confirmed);
1485 talloc_free(cc_setup_bcap);
1486
1487 btw("MS confirms call, we create a RAN-side RTP and forward MNCC_CALL_CONF_IND");
1488 expect_crcx(RTP_TO_CN);
1489 expect_crcx(RTP_TO_RAN);
1490 cc_to_mncc_expect_tx(IMSI, MNCC_CALL_CONF_IND);
1491 ms_sends_msgf("8348" /* CC: Call Confirmed */
1492 "%s" /* Bearer Capability */
1493 "15020100" /* Call Control Capabilities */
1494 "40080402600400021f00" /* Supported Codec List */,
1495 bcap_hexstr(t->mt_rx_ms_bcap)
1496 );
1497 OSMO_ASSERT(crcx_scheduled(RTP_TO_CN));
1498 OSMO_ASSERT(crcx_scheduled(RTP_TO_RAN));
1499 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1500 VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mt_tx_sdp_mncc_call_conf_ind);
1501
1502 btw("MGW acknowledges the CRCX to RAN, triggering Assignment with%s", perm_speech_name(t->mt_tx_assignment_perm_speech));
1503
1504 if (t->expect_codec_mismatch_on_cc_call_conf) {
1505 btw("MS Bearer Capability leads to a codec mismatch, Assignment aborts");
1506
1507 dtap_expect_tx("032d0802e1af" /* CC Release */);
1508 cc_to_mncc_expect_tx("", MNCC_REL_IND);
1509 expect_bssap_clear();
1510 crcx_ok(RTP_TO_RAN);
1511
1512 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1513 OSMO_ASSERT(bssap_clear_sent);
1514
1515 ran_sends_clear_complete();
1516 EXPECT_CONN_COUNT(0);
1517 BTW("======================== SUCCESS: MT call: %s", t->desc);
1518 return;
1519 }
1520
1521 expect_bssap_assignment();
1522 crcx_ok(RTP_TO_RAN);
1523 OSMO_ASSERT(bssap_assignment_sent);
1524 VALIDATE_PERM_SPEECH(&bssap_assignment_command_last_channel_type, t->mt_tx_assignment_perm_speech);
1525
1526 btw("Assignment completes, triggering CRCX to CN");
1527 ms_sends_assignment_complete(t->mt_rx_assigned_codec);
1528
1529 btw("MNCC sends MNCC_RTP_CREATE, which first waits for the CN side RTP");
Neels Hofmeyr6a1faa92023-03-23 01:56:14 +01001530 sdp_str_from_subtype_names(mncc_rtp.sdp, sizeof(mncc_rtp.sdp), t->mt_rx_sdp_mncc_rtp_create);
1531 mncc_sends_to_cc(MNCC_RTP_CREATE, &mncc_rtp);
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001532
1533 btw("When the CN side RTP address is known, ack MNCC_RTP_CREATE");
1534 cc_to_mncc_expect_tx("", MNCC_RTP_CREATE);
1535 crcx_ok(RTP_TO_CN);
1536 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1537 VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mt_tx_sdp_mncc_rtp_create);
1538
1539 fake_time_passes(1, 23);
1540
1541 cc_to_mncc_expect_tx("", MNCC_ALERT_IND);
1542 ms_sends_msg("8381" /* CC: Alerting */);
1543 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1544 VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mt_tx_sdp_mncc_alert_ind);
1545
1546 fake_time_passes(1, 23);
1547
1548 cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_CNF);
1549 ms_sends_msg("83c7" /* CC: Connect */);
1550 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1551 VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mt_tx_sdp_mncc_setup_cnf);
1552
1553 dtap_expect_tx("030f" /* CC: Connect Acknowledge */);
1554 sdp_str_from_subtype_names(mncc.sdp, sizeof(mncc.sdp), t->mt_rx_sdp_mncc_setup_compl_req);
1555 mncc_sends_to_cc(MNCC_SETUP_COMPL_REQ, &mncc);
1556
1557 BTW("RTP stream goes ahead, not shown here.");
1558 fake_time_passes(123, 45);
1559
1560 BTW("Call ends");
1561 cc_to_mncc_expect_tx("", MNCC_DISC_IND);
1562 ms_sends_msg("832502e090" /* CC: Disconnect, cause: Normal Call Clearing */);
1563 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1564
1565 dtap_expect_tx("032d" /* CC: Release */);
1566 mncc_sends_to_cc(MNCC_REL_REQ, &mncc);
1567 OSMO_ASSERT(dtap_tx_confirmed);
1568
1569 cc_to_mncc_expect_tx("", MNCC_REL_CNF);
1570 expect_bssap_clear();
1571 ms_sends_msg("836a" /* CC: Release Complete */);
1572 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1573 OSMO_ASSERT(bssap_clear_sent);
1574
1575 ran_sends_clear_complete();
1576 EXPECT_CONN_COUNT(0);
1577 BTW("======================== SUCCESS: MT call: %s", t->desc);
1578}
1579
1580static void test_codecs(void)
1581{
1582 const struct codec_test *t;
1583 clear_vlr();
1584
1585 comment_start();
1586
1587 fake_time_start();
1588
1589 lu_geran_noauth();
1590
1591 for (t = codec_tests; t - codec_tests < ARRAY_SIZE(codec_tests); t++) {
1592 test_codecs_mo(t);
1593 test_codecs_mt(t);
1594 }
1595
1596 EXPECT_CONN_COUNT(0);
1597 clear_vlr();
1598 comment_end();
1599}
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +01001600
Neels Hofmeyra99b4272017-11-21 17:13:23 +01001601msc_vlr_test_func_t msc_vlr_tests[] = {
1602 test_call_mo,
1603 test_call_mt,
Neels Hofmeyrcbcf89c2018-03-13 17:52:07 +01001604 test_call_mt2,
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +01001605 test_call_mo_to_unknown,
1606 test_call_mo_to_unknown_timeout,
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001607 test_codecs,
Neels Hofmeyra99b4272017-11-21 17:13:23 +01001608 NULL
1609};