blob: e67ac7d5aaca38b060554b776bae341e06beaf54 [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",
1074 .mt_tx_sdp_mncc_rtp_create = { "AMR", "GSM-EFR", "GSM", "GSM-HR-08" },
1075 .mt_tx_sdp_mncc_alert_ind = { "AMR", "GSM-EFR", "GSM", "GSM-HR-08" },
1076 .mt_tx_sdp_mncc_setup_cnf = { "AMR", "GSM-EFR", "GSM", "GSM-HR-08" },
1077 .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
1149static bool validate_sdp(const char *func, const char *desc,
1150 const char *sdp_str, const char * const expected_codecs[])
1151{
1152 const char * const *expect_pos;
1153 struct sdp_audio_codec *codec;
1154 struct sdp_msg sdp;
1155 if (sdp_msg_from_sdp_str(&sdp, sdp_str)) {
1156 BTW("%s: %s: ERROR: failed to parse SDP\n%s", func, desc, sdp_str);
1157 return false;
1158 }
1159
1160 expect_pos = expected_codecs;
1161 foreach_sdp_audio_codec(codec, &sdp.audio_codecs) {
1162 if (!*expect_pos) {
1163 BTW("%s: %s: ERROR: did not expect %s", func, desc, codec->subtype_name);
1164 return false;
1165 }
1166 if (strcmp(*expect_pos, codec->subtype_name)) {
1167 BTW("%s: %s: ERROR: mismatch: in idx %d, expect %s, got %s", func, desc,
1168 (int)(expect_pos - expected_codecs), *expect_pos, codec->subtype_name);
1169 return false;
1170 }
1171 expect_pos++;
Neels Hofmeyrd767c732023-11-17 04:12:29 +01001172
1173 /* only match first codec */
1174 return true;
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001175 }
1176 if (*expect_pos) {
1177 BTW("%s: %s: ERROR: mismatch: expected %s to be listed, but not found", func, desc, *expect_pos);
1178 return false;
1179 }
1180 return true;
1181}
1182
1183#define VALIDATE_SDP(GOT_SDP_STR, EXPECT_SDP_STR) do { \
1184 if (validate_sdp(__func__, t->desc, GOT_SDP_STR, EXPECT_SDP_STR)) { \
1185 btw("VALIDATE_SDP OK: " #GOT_SDP_STR " == " #EXPECT_SDP_STR " ==%s", strlist_name(EXPECT_SDP_STR)); \
1186 } else { \
1187 btw("Failed to validate SDP:\nexpected%s\ngot\n%s", \
1188 strlist_name(EXPECT_SDP_STR), GOT_SDP_STR); \
1189 OSMO_ASSERT(false); \
1190 } \
1191 } while (0)
1192
1193static bool validate_perm_speech(const char *func, const char *desc,
1194 const struct gsm0808_channel_type *ct,
1195 const enum gsm0808_permitted_speech perm_speech[])
1196{
1197 const enum gsm0808_permitted_speech *pos;
1198 const uint8_t *pos2 = ct->perm_spch;
1199 for (pos = perm_speech; *pos != LIST_END; pos++, pos2++) {
1200 if (pos2 - ct->perm_spch >= ct->perm_spch_len) {
1201 BTW("%s: %s: ERROR: mismatch: expected %s to be listed, but not found", func, desc,
1202 gsm0808_permitted_speech_name(*pos));
1203 return false;
1204 }
1205 if (*pos2 != *pos) {
1206 BTW("%s: %s: ERROR: mismatch: in idx %d, expect %s", func, desc,
1207 (int)(pos - perm_speech), gsm0808_permitted_speech_name(*pos));
1208 btw("in idx %d, got %s", (int)(pos - perm_speech), gsm0808_permitted_speech_name(*pos2));
1209 return false;
1210 }
1211 }
1212 if (pos2 - ct->perm_spch < ct->perm_spch_len) {
1213 BTW("%s: %s: ERROR: did not expect %s", func, desc, gsm0808_permitted_speech_name(*pos2));
1214 return false;
1215 }
1216 return true;
1217}
1218
1219#define VALIDATE_PERM_SPEECH(GOT_PERM_SPEECH, EXPECT_PERM_SPEECH) do { \
1220 if (validate_perm_speech(__func__, t->desc, GOT_PERM_SPEECH, EXPECT_PERM_SPEECH)) { \
1221 btw("VALIDATE_PERM_SPEECH OK: " #GOT_PERM_SPEECH " == " #EXPECT_PERM_SPEECH " ==%s", \
1222 perm_speech_name(EXPECT_PERM_SPEECH)); \
1223 } else { \
1224 btw("Failed to validate Permitted Speech:\nexpected%s", \
1225 perm_speech_name(EXPECT_PERM_SPEECH)); \
1226 btw("got:"); \
1227 int i; \
1228 for (i = 0; i < (GOT_PERM_SPEECH)->perm_spch_len; i++) { \
1229 btw("%s", gsm0808_permitted_speech_name((GOT_PERM_SPEECH)->perm_spch[i])); \
1230 } \
1231 OSMO_ASSERT(false); \
1232 } \
1233 } while (0)
1234
1235static struct sdp_msg *sdp_from_subtype_names(const char *const *subtype_names)
1236{
1237 static struct sdp_msg sdp;
1238 sdp = (struct sdp_msg){};
1239 const char *const *subtype_name;
1240 osmo_sockaddr_str_from_str(&sdp.rtp, "1.2.3.4", 56);
1241 for (subtype_name = subtype_names; *subtype_name; subtype_name++) {
1242 const struct codec_mapping *m = codec_mapping_by_subtype_name(*subtype_name);
1243 if (!m) {
1244 BTW("ERROR: unknown subtype_name: %s", *subtype_name);
1245 abort();
1246 }
1247 sdp_audio_codecs_add_copy(&sdp.audio_codecs, &m->sdp);
1248 }
1249 return &sdp;
1250}
1251
1252static int sdp_str_from_subtype_names(char *buf, size_t buflen, const char *const *subtype_names)
1253{
1254 if (!subtype_names[0]) {
1255 buf[0] = '\0';
1256 return 0;
1257 }
1258 return sdp_msg_to_sdp_str_buf(buf, buflen, sdp_from_subtype_names(subtype_names));
1259}
1260
1261static const char *bcap_hexstr(const enum gsm48_bcap_speech_ver ms_bcap[])
1262{
1263 struct gsm_mncc_bearer_cap bcap = {
1264 .transfer = GSM_MNCC_BCAP_SPEECH,
1265 .speech_ver = { -1 },
1266 };
1267 const enum gsm48_bcap_speech_ver *pos;
1268 for (pos = ms_bcap; *pos != LIST_END; pos++)
1269 bearer_cap_add_speech_ver(&bcap, *pos);
1270 bearer_cap_set_radio(&bcap);
1271 struct msgb *msg = msgb_alloc(128, "bcap");
1272 gsm48_encode_bearer_cap(msg, 0, &bcap);
1273 char *ret = osmo_hexdump_nospc(msg->data, msg->len);
1274 msgb_free(msg);
1275 return ret;
1276}
1277
1278static void test_codecs_mo(const struct codec_test *t)
1279{
1280 struct gsm_mncc mncc = {
1281 .imsi = IMSI,
1282 };
1283
Neels Hofmeyr6a1faa92023-03-23 01:56:14 +01001284 struct gsm_mncc_rtp mncc_rtp = {};
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001285
1286 BTW("======================== MO call: %s", t->desc);
1287 btw("CM Service Request with Codec List (BSS Supported) =%s",
1288 codec_list_name(t->mo_rx_compl_l3_codec_list_bss_supported));
1289
1290 cm_service_result_sent = RES_NONE;
1291 ms_sends_compl_l3("052471"
1292 "03575886" /* classmark 2 */
1293 "089910070000106005" /* IMSI */,
1294 codec_list(t->mo_rx_compl_l3_codec_list_bss_supported));
1295 VERBOSE_ASSERT(cm_service_result_sent, == RES_ACCEPT, "%d");
1296 EXPECT_ACCEPTED(true);
1297
1298 btw("MS sends CC SETUP with Bearer Capability = %s",
1299 bcap_name(t->mo_rx_ms_bcap));
1300 expect_crcx(RTP_TO_CN);
1301 expect_crcx(RTP_TO_RAN);
1302 ms_sends_msgf("0385" /* CC, seq = 2 -> 0x80 | CC Setup = 0x5 */
1303 "%s" /* Bearer Capability */
1304 "5e038121f3" /* Called Number BCD */
1305 "15020100" /* CC Capabilities */
1306 "4008" /* Supported Codec List */
1307 "04026000" /* UMTS: AMR 2 | AMR */
1308 "00021f00" /* GSM: HR AMR | FR AMR | GSM EFR | GSM HR | GSM FR */,
1309 bcap_hexstr(t->mo_rx_ms_bcap)
1310 );
1311 OSMO_ASSERT(crcx_scheduled(RTP_TO_CN));
1312 OSMO_ASSERT(crcx_scheduled(RTP_TO_RAN));
1313
1314 btw("As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered");
1315 cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_IND);
1316 crcx_ok(RTP_TO_CN);
1317 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
Neels Hofmeyr6a1faa92023-03-23 01:56:14 +01001318 mncc.callref = mncc_rtp.callref = cc_to_mncc_tx_got_callref;
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001319 VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mo_tx_sdp_mncc_setup_ind);
1320
Neels Hofmeyr11c04ae2023-11-28 04:40:52 +01001321 btw("MNCC replies with MNCC_RTP_CREATE");
Neels Hofmeyr6a1faa92023-03-23 01:56:14 +01001322 sdp_str_from_subtype_names(mncc_rtp.sdp, sizeof(mncc_rtp.sdp), t->mo_rx_sdp_mncc_rtp_create);
1323 mncc_sends_to_cc(MNCC_RTP_CREATE, &mncc_rtp);
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001324
1325 btw("MGW acknowledges the CRCX, triggering Assignment with%s", perm_speech_name(t->mo_tx_assignment_perm_speech));
1326 expect_bssap_assignment();
1327 crcx_ok(RTP_TO_RAN);
1328 OSMO_ASSERT(bssap_assignment_sent);
1329 VALIDATE_PERM_SPEECH(&bssap_assignment_command_last_channel_type, t->mo_tx_assignment_perm_speech);
1330
1331 btw("Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC");
1332 cc_to_mncc_expect_tx("", MNCC_RTP_CREATE);
1333 ms_sends_assignment_complete(t->mo_rx_assigned_codec);
1334 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1335 VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mo_tx_sdp_mncc_rtp_create);
1336
1337 btw("MNCC says that's fine");
1338 dtap_expect_tx("8302" /* CC: Call Proceeding */);
1339 mncc_sends_to_cc(MNCC_CALL_PROC_REQ, &mncc);
1340 OSMO_ASSERT(dtap_tx_confirmed);
1341
1342 fake_time_passes(1, 23);
1343
1344 btw("The other call leg got established (not shown here), MNCC tells us so, with codecs {%s }",
1345 strlist_name(t->mo_rx_sdp_mncc_alert_req));
1346 dtap_expect_tx("8301" /* CC: Call Alerting */);
Neels Hofmeyrb51c35e2023-11-28 04:45:09 +01001347
1348 if (t->mo_expect_reassignment) {
1349 btw("Expecting re-assignment");
1350 expect_bssap_assignment();
1351 }
1352
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001353 sdp_str_from_subtype_names(mncc.sdp, sizeof(mncc.sdp), t->mo_rx_sdp_mncc_alert_req);
1354 mncc_sends_to_cc(MNCC_ALERT_REQ, &mncc);
1355 OSMO_ASSERT(dtap_tx_confirmed);
1356
Neels Hofmeyrb51c35e2023-11-28 04:45:09 +01001357 if (t->mo_expect_reassignment) {
1358 btw("Validating re-assignment");
1359 OSMO_ASSERT(bssap_assignment_sent);
1360 VALIDATE_PERM_SPEECH(&bssap_assignment_command_last_channel_type, t->mo_tx_reassignment_perm_speech);
1361 ms_sends_assignment_complete(t->mo_rx_reassigned_codec);
1362 }
1363
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001364 dtap_expect_tx("8307" /* CC: Connect */);
1365 sdp_str_from_subtype_names(mncc.sdp, sizeof(mncc.sdp), t->mo_rx_sdp_mncc_setup_rsp);
1366 mncc_sends_to_cc(MNCC_SETUP_RSP, &mncc);
1367 OSMO_ASSERT(dtap_tx_confirmed);
1368
1369 fake_time_passes(1, 23);
1370
1371 cc_to_mncc_expect_tx("", MNCC_SETUP_COMPL_IND);
1372 ms_sends_msg("03cf" /* CC: Connect Acknowledge */);
1373 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1374 VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mo_tx_sdp_mncc_setup_compl_ind);
1375
1376 BTW("RTP stream goes ahead, not shown here.");
1377 fake_time_passes(123, 45);
1378
1379 BTW("Call ends");
1380 cc_to_mncc_expect_tx("", MNCC_DISC_IND);
1381 ms_sends_msg("032502e090" /* CC: Disconnect, cause: Normal Call Clearing */);
1382 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1383
1384 dtap_expect_tx("832d" /* CC: Release */);
1385 mncc_sends_to_cc(MNCC_REL_REQ, &mncc);
1386 OSMO_ASSERT(dtap_tx_confirmed);
1387
1388 cc_to_mncc_expect_tx("", MNCC_REL_CNF);
1389 expect_bssap_clear();
1390 ms_sends_msg("036a" /* CC: Release Complete */);
1391 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1392 OSMO_ASSERT(bssap_clear_sent);
1393
1394 ran_sends_clear_complete();
1395 EXPECT_CONN_COUNT(0);
1396 BTW("======================== SUCCESS: MO call: %s", t->desc);
1397}
1398
1399static void test_codecs_mt(const struct codec_test *t)
1400{
1401 struct gsm_mncc mncc = {
1402 .imsi = IMSI,
1403 .callref = 0x423,
1404 .fields = MNCC_F_BEARER_CAP,
1405 .bearer_cap = {
1406 .speech_ver = { GSM48_BCAP_SV_FR, -1, },
1407 },
1408 };
Neels Hofmeyr6a1faa92023-03-23 01:56:14 +01001409 struct gsm_mncc_rtp mncc_rtp = {
1410 .callref = 0x423,
1411 };
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001412
1413 BTW("======================== MT call: %s", t->desc);
1414
1415 BTW("MNCC asks us to setup a call, causing Paging");
1416
1417 paging_expect_imsi(IMSI);
1418 paging_sent = false;
1419 sdp_str_from_subtype_names(mncc.sdp, sizeof(mncc.sdp), t->mt_rx_sdp_mncc_setup_req);
1420 mncc_sends_to_cc(MNCC_SETUP_REQ, &mncc);
1421 mncc.sdp[0] = '\0';
1422
1423 VERBOSE_ASSERT(paging_sent, == true, "%d");
1424
1425 btw("MS replies with Paging Response, with Codec List (BSS Supported) =%s",
1426 codec_list_name(t->mt_rx_compl_l3_codec_list_bss_supported));
1427
1428 if (t->expect_codec_mismatch_on_paging_response) {
1429 btw("VLR accepts, but MSC notices a codec mismatch and aborts");
1430 cc_to_mncc_expect_tx("", MNCC_REL_IND);
1431 expect_bssap_clear();
1432 ms_sends_compl_l3("062707"
1433 "03575886" /* classmark 2 */
1434 "089910070000106005" /* IMSI */,
1435 codec_list(t->mt_rx_compl_l3_codec_list_bss_supported));
1436 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1437 OSMO_ASSERT(bssap_clear_sent);
1438
1439 ran_sends_clear_complete();
1440 EXPECT_CONN_COUNT(0);
1441
1442 BTW("======================== SUCCESS: MT call: %s", t->desc);
1443 return;
1444 }
1445
1446 btw("VLR accepts, MSC sends CC Setup with Bearer Capability = %s",
1447 bcap_name(t->mt_tx_cc_setup_bcap));
1448 char *cc_setup_bcap = talloc_asprintf(msc_vlr_tests_ctx, "0305%s",
1449 bcap_hexstr(t->mt_tx_cc_setup_bcap));
1450 dtap_expect_tx(cc_setup_bcap);
1451 ms_sends_compl_l3("062707"
1452 "03575886" /* classmark 2 */
1453 "089910070000106005" /* IMSI */,
1454 codec_list(t->mt_rx_compl_l3_codec_list_bss_supported));
1455 OSMO_ASSERT(dtap_tx_confirmed);
1456 talloc_free(cc_setup_bcap);
1457
1458 btw("MS confirms call, we create a RAN-side RTP and forward MNCC_CALL_CONF_IND");
1459 expect_crcx(RTP_TO_CN);
1460 expect_crcx(RTP_TO_RAN);
1461 cc_to_mncc_expect_tx(IMSI, MNCC_CALL_CONF_IND);
1462 ms_sends_msgf("8348" /* CC: Call Confirmed */
1463 "%s" /* Bearer Capability */
1464 "15020100" /* Call Control Capabilities */
1465 "40080402600400021f00" /* Supported Codec List */,
1466 bcap_hexstr(t->mt_rx_ms_bcap)
1467 );
1468 OSMO_ASSERT(crcx_scheduled(RTP_TO_CN));
1469 OSMO_ASSERT(crcx_scheduled(RTP_TO_RAN));
1470 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1471 VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mt_tx_sdp_mncc_call_conf_ind);
1472
1473 btw("MGW acknowledges the CRCX to RAN, triggering Assignment with%s", perm_speech_name(t->mt_tx_assignment_perm_speech));
1474
1475 if (t->expect_codec_mismatch_on_cc_call_conf) {
1476 btw("MS Bearer Capability leads to a codec mismatch, Assignment aborts");
1477
1478 dtap_expect_tx("032d0802e1af" /* CC Release */);
1479 cc_to_mncc_expect_tx("", MNCC_REL_IND);
1480 expect_bssap_clear();
1481 crcx_ok(RTP_TO_RAN);
1482
1483 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1484 OSMO_ASSERT(bssap_clear_sent);
1485
1486 ran_sends_clear_complete();
1487 EXPECT_CONN_COUNT(0);
1488 BTW("======================== SUCCESS: MT call: %s", t->desc);
1489 return;
1490 }
1491
1492 expect_bssap_assignment();
1493 crcx_ok(RTP_TO_RAN);
1494 OSMO_ASSERT(bssap_assignment_sent);
1495 VALIDATE_PERM_SPEECH(&bssap_assignment_command_last_channel_type, t->mt_tx_assignment_perm_speech);
1496
1497 btw("Assignment completes, triggering CRCX to CN");
1498 ms_sends_assignment_complete(t->mt_rx_assigned_codec);
1499
1500 btw("MNCC sends MNCC_RTP_CREATE, which first waits for the CN side RTP");
Neels Hofmeyr6a1faa92023-03-23 01:56:14 +01001501 sdp_str_from_subtype_names(mncc_rtp.sdp, sizeof(mncc_rtp.sdp), t->mt_rx_sdp_mncc_rtp_create);
1502 mncc_sends_to_cc(MNCC_RTP_CREATE, &mncc_rtp);
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001503
1504 btw("When the CN side RTP address is known, ack MNCC_RTP_CREATE");
1505 cc_to_mncc_expect_tx("", MNCC_RTP_CREATE);
1506 crcx_ok(RTP_TO_CN);
1507 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1508 VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mt_tx_sdp_mncc_rtp_create);
1509
1510 fake_time_passes(1, 23);
1511
1512 cc_to_mncc_expect_tx("", MNCC_ALERT_IND);
1513 ms_sends_msg("8381" /* CC: Alerting */);
1514 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1515 VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mt_tx_sdp_mncc_alert_ind);
1516
1517 fake_time_passes(1, 23);
1518
1519 cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_CNF);
1520 ms_sends_msg("83c7" /* CC: Connect */);
1521 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1522 VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mt_tx_sdp_mncc_setup_cnf);
1523
1524 dtap_expect_tx("030f" /* CC: Connect Acknowledge */);
1525 sdp_str_from_subtype_names(mncc.sdp, sizeof(mncc.sdp), t->mt_rx_sdp_mncc_setup_compl_req);
1526 mncc_sends_to_cc(MNCC_SETUP_COMPL_REQ, &mncc);
1527
1528 BTW("RTP stream goes ahead, not shown here.");
1529 fake_time_passes(123, 45);
1530
1531 BTW("Call ends");
1532 cc_to_mncc_expect_tx("", MNCC_DISC_IND);
1533 ms_sends_msg("832502e090" /* CC: Disconnect, cause: Normal Call Clearing */);
1534 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1535
1536 dtap_expect_tx("032d" /* CC: Release */);
1537 mncc_sends_to_cc(MNCC_REL_REQ, &mncc);
1538 OSMO_ASSERT(dtap_tx_confirmed);
1539
1540 cc_to_mncc_expect_tx("", MNCC_REL_CNF);
1541 expect_bssap_clear();
1542 ms_sends_msg("836a" /* CC: Release Complete */);
1543 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1544 OSMO_ASSERT(bssap_clear_sent);
1545
1546 ran_sends_clear_complete();
1547 EXPECT_CONN_COUNT(0);
1548 BTW("======================== SUCCESS: MT call: %s", t->desc);
1549}
1550
1551static void test_codecs(void)
1552{
1553 const struct codec_test *t;
1554 clear_vlr();
1555
1556 comment_start();
1557
1558 fake_time_start();
1559
1560 lu_geran_noauth();
1561
1562 for (t = codec_tests; t - codec_tests < ARRAY_SIZE(codec_tests); t++) {
1563 test_codecs_mo(t);
1564 test_codecs_mt(t);
1565 }
1566
1567 EXPECT_CONN_COUNT(0);
1568 clear_vlr();
1569 comment_end();
1570}
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +01001571
Neels Hofmeyra99b4272017-11-21 17:13:23 +01001572msc_vlr_test_func_t msc_vlr_tests[] = {
1573 test_call_mo,
1574 test_call_mt,
Neels Hofmeyrcbcf89c2018-03-13 17:52:07 +01001575 test_call_mt2,
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +01001576 test_call_mo_to_unknown,
1577 test_call_mo_to_unknown_timeout,
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001578 test_codecs,
Neels Hofmeyra99b4272017-11-21 17:13:23 +01001579 NULL
1580};