blob: 1264dfd557f8b5338d3ebad065bf7bf7c50a224b [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];
827 const char *mt_tx_sdp_mncc_setup_cnf[8];
828 const char *mt_rx_sdp_mncc_setup_compl_req[8];
829
830 /* mo_rx_sdp_mncc_alert_req == mt_tx_sdp_mncc_alert_ind */
831#define mo_rx_sdp_mncc_alert_req mt_tx_sdp_mncc_alert_ind
832#define mo_rx_sdp_mncc_setup_rsp mt_tx_sdp_mncc_alert_ind
833
834 const char *mo_tx_sdp_mncc_setup_compl_ind[8];
835};
836
837#define CODEC_LIST_ALL_GSM { \
838 GSM0808_SCT_FR1, \
839 GSM0808_SCT_FR2, \
840 GSM0808_SCT_FR3, \
841 GSM0808_SCT_HR1, \
842 GSM0808_SCT_HR3, \
843 LIST_END \
844 }
845
846#define BCAP_ALL_GSM { \
847 GSM48_BCAP_SV_AMR_F, \
848 GSM48_BCAP_SV_AMR_H, \
849 GSM48_BCAP_SV_AMR_OH, \
850 GSM48_BCAP_SV_EFR, \
851 GSM48_BCAP_SV_FR, \
852 GSM48_BCAP_SV_HR, \
853 LIST_END \
854 }
855
856#define PERM_SPEECH_ALL_GSM { \
857 GSM0808_PERM_FR3, \
858 GSM0808_PERM_HR3, \
859 GSM0808_PERM_FR2, \
860 GSM0808_PERM_FR1, \
861 GSM0808_PERM_HR1, \
862 LIST_END \
863 }
864
865#define SDP_CODECS_ALL_GSM { \
866 "AMR", \
867 "GSM-EFR", \
868 "GSM", \
869 "GSM-HR-08", \
870 }
871
872static const struct codec_test codec_tests[] = {
873 {
874 .desc = "AMR picked by both MO and MT",
875 .mo_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
876 .mo_rx_ms_bcap = BCAP_ALL_GSM,
877 .mo_tx_sdp_mncc_setup_ind = SDP_CODECS_ALL_GSM,
878 .mo_rx_sdp_mncc_rtp_create = {},
879 .mo_tx_assignment_perm_speech = PERM_SPEECH_ALL_GSM,
880 .mo_rx_assigned_codec = "AMR",
881 .mo_tx_sdp_mncc_rtp_create = { "AMR" },
882 /* mt_rx_sdp_mncc_setup_req == mo_tx_sdp_mncc_rtp_create */
883 .mt_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
884 .mt_tx_cc_setup_bcap = {
885 GSM48_BCAP_SV_AMR_F,
886 GSM48_BCAP_SV_AMR_H,
887 GSM48_BCAP_SV_AMR_OH,
888 LIST_END
889 },
890 .mt_rx_ms_bcap = BCAP_ALL_GSM,
891 .mt_tx_sdp_mncc_call_conf_ind = {},
892 .mt_rx_sdp_mncc_rtp_create = {},
893 .mt_tx_assignment_perm_speech = { GSM0808_PERM_FR3, GSM0808_PERM_HR3, LIST_END },
894 .mt_rx_assigned_codec = "AMR",
895 .mt_tx_sdp_mncc_rtp_create = { "AMR" },
896 .mt_tx_sdp_mncc_alert_ind = { "AMR" },
897 .mt_tx_sdp_mncc_setup_cnf = { "AMR" },
898 .mo_tx_sdp_mncc_setup_compl_ind = {},
899 },
900
901 {
902 .desc = "FR1 picked by MO from Codec List (BSS Supported), MT hence also picks FR1",
903 .mo_rx_compl_l3_codec_list_bss_supported = { GSM0808_SCT_FR1, LIST_END },
904 .mo_rx_ms_bcap = BCAP_ALL_GSM,
905 .mo_tx_sdp_mncc_setup_ind = { "GSM" },
906 .mo_rx_sdp_mncc_rtp_create = {},
907 .mo_tx_assignment_perm_speech = { GSM0808_PERM_FR1, LIST_END },
908 .mo_rx_assigned_codec = "GSM",
909 .mo_tx_sdp_mncc_rtp_create = { "GSM" },
910 /* .mt_rx_sdp_mncc_setup_req == .mo_tx_sdp_mncc_setup_ind */
911 .mt_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
912 .mt_tx_cc_setup_bcap = { GSM48_BCAP_SV_FR, LIST_END },
913 .mt_rx_ms_bcap = BCAP_ALL_GSM,
914 .mt_tx_sdp_mncc_call_conf_ind = {},
915 .mt_rx_sdp_mncc_rtp_create = {},
916 .mt_tx_assignment_perm_speech = { GSM0808_PERM_FR1, LIST_END },
917 .mt_rx_assigned_codec = "GSM",
918 .mt_tx_sdp_mncc_rtp_create = { "GSM" },
919 .mt_tx_sdp_mncc_alert_ind = { "GSM" },
920 .mt_tx_sdp_mncc_setup_cnf = { "GSM" },
921 .mo_tx_sdp_mncc_setup_compl_ind = {},
922 },
923
924 {
925 .desc = "FR1 picked by MO from Bearer Cap, MT hence also picks FR1",
926 .mo_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
927 .mo_rx_ms_bcap = { GSM48_BCAP_SV_FR, LIST_END },
928 .mo_tx_sdp_mncc_setup_ind = { "GSM" },
929 .mo_rx_sdp_mncc_rtp_create = {},
930 .mo_tx_assignment_perm_speech = { GSM0808_PERM_FR1, LIST_END },
931 .mo_rx_assigned_codec = "GSM",
932 .mo_tx_sdp_mncc_rtp_create = { "GSM" },
933 /* .mt_rx_sdp_mncc_setup_req == .mo_tx_sdp_mncc_setup_ind */
934 .mt_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
935 .mt_tx_cc_setup_bcap = { GSM48_BCAP_SV_FR, LIST_END },
936 .mt_rx_ms_bcap = BCAP_ALL_GSM,
937 .mt_tx_sdp_mncc_call_conf_ind = {},
938 .mt_rx_sdp_mncc_rtp_create = {},
939 .mt_tx_assignment_perm_speech = { GSM0808_PERM_FR1, LIST_END },
940 .mt_rx_assigned_codec = "GSM",
941 .mt_tx_sdp_mncc_rtp_create = { "GSM" },
942 .mt_tx_sdp_mncc_alert_ind = { "GSM" },
943 .mt_tx_sdp_mncc_setup_cnf = { "GSM" },
944 .mo_tx_sdp_mncc_setup_compl_ind = {},
945 },
946
947 {
948 .desc = "FR1 picked by MT's Codec List (BSS Supported), hence MO also picks FR1 (EXPECTED FAILURE)",
949 /* Currently the MO Assignment happens before MT gets a chance to send its available codecs.
950 * So even though the MO side would be able to assign FR1 and match MT, this is established too late
951 * and MO mismatches MT. This can only be fixed by a) moving MO Assignment to after MT Assignment
952 * or b) doing a Channel Mode Change or re-assignment after MT Assignment -- since re-assigning might
953 * need an lchan type change and means more overhead, a) would be the best option. */
954 .mo_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
955 .mo_rx_ms_bcap = BCAP_ALL_GSM,
956 .mo_tx_sdp_mncc_setup_ind = SDP_CODECS_ALL_GSM,
957 .mo_rx_sdp_mncc_rtp_create = {},
958 .mo_tx_assignment_perm_speech = PERM_SPEECH_ALL_GSM,
959 .mo_rx_assigned_codec = "AMR", /* <- Early Assignment means codec mismatch */
960 .mo_tx_sdp_mncc_rtp_create = { "AMR" },
961
962 .mt_rx_compl_l3_codec_list_bss_supported = { GSM0808_SCT_FR1, LIST_END },
963 .expect_codec_mismatch_on_paging_response = true,
964 /* The mismatching codec AMR vs. GSM means the call fails (in the lack of transcoding) */
965 },
966
967 {
968 .desc = "FR1 picked by MT's MS Bearer Capability, hence MO also picks FR1 (EXPECTED FAILURE)",
969 /* Like above, MO Assignment happens too early to be able to match MT's codec availability. */
970 .mo_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
971 .mo_rx_ms_bcap = BCAP_ALL_GSM,
972 .mo_tx_sdp_mncc_setup_ind = SDP_CODECS_ALL_GSM,
973 .mo_rx_sdp_mncc_rtp_create = {},
974 .mo_tx_assignment_perm_speech = PERM_SPEECH_ALL_GSM,
975 .mo_rx_assigned_codec = "AMR", /* <- Early Assignment means codec mismatch */
976 .mo_tx_sdp_mncc_rtp_create = { "AMR" },
977
978 .mt_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
979 .mt_tx_cc_setup_bcap = {
980 GSM48_BCAP_SV_AMR_F,
981 GSM48_BCAP_SV_AMR_H,
982 GSM48_BCAP_SV_AMR_OH,
983 LIST_END
984 },
985 .mt_rx_ms_bcap = { GSM48_BCAP_SV_FR, LIST_END },
986 .mt_tx_sdp_mncc_call_conf_ind = {},
987 .mt_rx_sdp_mncc_rtp_create = {},
988 .mt_tx_assignment_perm_speech = { GSM0808_PERM_FR3, GSM0808_PERM_HR3, LIST_END },
989 .expect_codec_mismatch_on_cc_call_conf = true,
990 /* The mismatching codec AMR vs. GSM means the call fails (in the lack of transcoding) */
991 },
992
993};
994
995static char namebuf[4][1024];
996static int use_namebuf = 0;
997
998static const char *codec_list_name(const enum gsm0808_speech_codec_type compl_l3_codec_list_bss_supported[])
999{
1000 struct osmo_strbuf sb = { .buf = namebuf[use_namebuf], .len = sizeof(namebuf[0]) };
1001 use_namebuf = (use_namebuf + 1) % ARRAY_SIZE(namebuf);
1002
1003 const enum gsm0808_speech_codec_type *pos;
1004 sb.buf[0] = '\0';
1005 for (pos = compl_l3_codec_list_bss_supported; *pos != LIST_END; pos++)
1006 OSMO_STRBUF_PRINTF(sb, " %s", gsm0808_speech_codec_type_name(*pos));
1007 return sb.buf;
1008}
1009
1010static const struct gsm0808_speech_codec_list *codec_list(const enum gsm0808_speech_codec_type compl_l3_codec_list_bss_supported[])
1011{
1012 static struct gsm0808_speech_codec_list scl;
1013 scl = (struct gsm0808_speech_codec_list){};
1014 const enum gsm0808_speech_codec_type *pos;
1015 for (pos = compl_l3_codec_list_bss_supported; *pos != LIST_END; pos++) {
1016 scl.codec[scl.len] = (struct gsm0808_speech_codec){
1017 .fi = true,
1018 .type = *pos,
1019 };
1020 scl.len++;
1021 }
1022 return &scl;
1023}
1024
1025static const char *bcap_name(const enum gsm48_bcap_speech_ver ms_bcap[])
1026{
1027 struct osmo_strbuf sb = { .buf = namebuf[use_namebuf], .len = sizeof(namebuf[0]) };
1028 use_namebuf = (use_namebuf + 1) % ARRAY_SIZE(namebuf);
1029
1030 const enum gsm48_bcap_speech_ver *pos;
1031 sb.buf[0] = '\0';
1032 for (pos = ms_bcap; *pos != LIST_END; pos++) {
1033 const struct codec_mapping *m = codec_mapping_by_speech_ver(*pos);
1034 OSMO_STRBUF_PRINTF(sb, " %s", m ? m->sdp.subtype_name : "NULL");
1035 }
1036 return sb.buf;
1037}
1038
1039static const char *perm_speech_name(const enum gsm0808_permitted_speech perm_speech[])
1040{
1041 struct osmo_strbuf sb = { .buf = namebuf[use_namebuf], .len = sizeof(namebuf[0]) };
1042 use_namebuf = (use_namebuf + 1) % ARRAY_SIZE(namebuf);
1043
1044 const enum gsm0808_permitted_speech *pos;
1045 sb.buf[0] = '\0';
1046 for (pos = perm_speech; *pos != LIST_END; pos++)
1047 OSMO_STRBUF_PRINTF(sb, " %s", gsm0808_permitted_speech_name(*pos));
1048 return sb.buf;
1049}
1050
1051static const char *strlist_name(const char *const*strs)
1052{
1053 struct osmo_strbuf sb = { .buf = namebuf[use_namebuf], .len = sizeof(namebuf[0]) };
1054 use_namebuf = (use_namebuf + 1) % ARRAY_SIZE(namebuf);
1055
1056 const char * const *pos;
1057 sb.buf[0] = '\0';
1058 for (pos = strs; *pos != NULL; pos++)
1059 OSMO_STRBUF_PRINTF(sb, " %s", *pos);
1060 return sb.buf;
1061}
1062
1063static bool validate_sdp(const char *func, const char *desc,
1064 const char *sdp_str, const char * const expected_codecs[])
1065{
1066 const char * const *expect_pos;
1067 struct sdp_audio_codec *codec;
1068 struct sdp_msg sdp;
1069 if (sdp_msg_from_sdp_str(&sdp, sdp_str)) {
1070 BTW("%s: %s: ERROR: failed to parse SDP\n%s", func, desc, sdp_str);
1071 return false;
1072 }
1073
1074 expect_pos = expected_codecs;
1075 foreach_sdp_audio_codec(codec, &sdp.audio_codecs) {
1076 if (!*expect_pos) {
1077 BTW("%s: %s: ERROR: did not expect %s", func, desc, codec->subtype_name);
1078 return false;
1079 }
1080 if (strcmp(*expect_pos, codec->subtype_name)) {
1081 BTW("%s: %s: ERROR: mismatch: in idx %d, expect %s, got %s", func, desc,
1082 (int)(expect_pos - expected_codecs), *expect_pos, codec->subtype_name);
1083 return false;
1084 }
1085 expect_pos++;
Neels Hofmeyrd767c732023-11-17 04:12:29 +01001086
1087 /* only match first codec */
1088 return true;
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001089 }
1090 if (*expect_pos) {
1091 BTW("%s: %s: ERROR: mismatch: expected %s to be listed, but not found", func, desc, *expect_pos);
1092 return false;
1093 }
1094 return true;
1095}
1096
1097#define VALIDATE_SDP(GOT_SDP_STR, EXPECT_SDP_STR) do { \
1098 if (validate_sdp(__func__, t->desc, GOT_SDP_STR, EXPECT_SDP_STR)) { \
1099 btw("VALIDATE_SDP OK: " #GOT_SDP_STR " == " #EXPECT_SDP_STR " ==%s", strlist_name(EXPECT_SDP_STR)); \
1100 } else { \
1101 btw("Failed to validate SDP:\nexpected%s\ngot\n%s", \
1102 strlist_name(EXPECT_SDP_STR), GOT_SDP_STR); \
1103 OSMO_ASSERT(false); \
1104 } \
1105 } while (0)
1106
1107static bool validate_perm_speech(const char *func, const char *desc,
1108 const struct gsm0808_channel_type *ct,
1109 const enum gsm0808_permitted_speech perm_speech[])
1110{
1111 const enum gsm0808_permitted_speech *pos;
1112 const uint8_t *pos2 = ct->perm_spch;
1113 for (pos = perm_speech; *pos != LIST_END; pos++, pos2++) {
1114 if (pos2 - ct->perm_spch >= ct->perm_spch_len) {
1115 BTW("%s: %s: ERROR: mismatch: expected %s to be listed, but not found", func, desc,
1116 gsm0808_permitted_speech_name(*pos));
1117 return false;
1118 }
1119 if (*pos2 != *pos) {
1120 BTW("%s: %s: ERROR: mismatch: in idx %d, expect %s", func, desc,
1121 (int)(pos - perm_speech), gsm0808_permitted_speech_name(*pos));
1122 btw("in idx %d, got %s", (int)(pos - perm_speech), gsm0808_permitted_speech_name(*pos2));
1123 return false;
1124 }
1125 }
1126 if (pos2 - ct->perm_spch < ct->perm_spch_len) {
1127 BTW("%s: %s: ERROR: did not expect %s", func, desc, gsm0808_permitted_speech_name(*pos2));
1128 return false;
1129 }
1130 return true;
1131}
1132
1133#define VALIDATE_PERM_SPEECH(GOT_PERM_SPEECH, EXPECT_PERM_SPEECH) do { \
1134 if (validate_perm_speech(__func__, t->desc, GOT_PERM_SPEECH, EXPECT_PERM_SPEECH)) { \
1135 btw("VALIDATE_PERM_SPEECH OK: " #GOT_PERM_SPEECH " == " #EXPECT_PERM_SPEECH " ==%s", \
1136 perm_speech_name(EXPECT_PERM_SPEECH)); \
1137 } else { \
1138 btw("Failed to validate Permitted Speech:\nexpected%s", \
1139 perm_speech_name(EXPECT_PERM_SPEECH)); \
1140 btw("got:"); \
1141 int i; \
1142 for (i = 0; i < (GOT_PERM_SPEECH)->perm_spch_len; i++) { \
1143 btw("%s", gsm0808_permitted_speech_name((GOT_PERM_SPEECH)->perm_spch[i])); \
1144 } \
1145 OSMO_ASSERT(false); \
1146 } \
1147 } while (0)
1148
1149static struct sdp_msg *sdp_from_subtype_names(const char *const *subtype_names)
1150{
1151 static struct sdp_msg sdp;
1152 sdp = (struct sdp_msg){};
1153 const char *const *subtype_name;
1154 osmo_sockaddr_str_from_str(&sdp.rtp, "1.2.3.4", 56);
1155 for (subtype_name = subtype_names; *subtype_name; subtype_name++) {
1156 const struct codec_mapping *m = codec_mapping_by_subtype_name(*subtype_name);
1157 if (!m) {
1158 BTW("ERROR: unknown subtype_name: %s", *subtype_name);
1159 abort();
1160 }
1161 sdp_audio_codecs_add_copy(&sdp.audio_codecs, &m->sdp);
1162 }
1163 return &sdp;
1164}
1165
1166static int sdp_str_from_subtype_names(char *buf, size_t buflen, const char *const *subtype_names)
1167{
1168 if (!subtype_names[0]) {
1169 buf[0] = '\0';
1170 return 0;
1171 }
1172 return sdp_msg_to_sdp_str_buf(buf, buflen, sdp_from_subtype_names(subtype_names));
1173}
1174
1175static const char *bcap_hexstr(const enum gsm48_bcap_speech_ver ms_bcap[])
1176{
1177 struct gsm_mncc_bearer_cap bcap = {
1178 .transfer = GSM_MNCC_BCAP_SPEECH,
1179 .speech_ver = { -1 },
1180 };
1181 const enum gsm48_bcap_speech_ver *pos;
1182 for (pos = ms_bcap; *pos != LIST_END; pos++)
1183 bearer_cap_add_speech_ver(&bcap, *pos);
1184 bearer_cap_set_radio(&bcap);
1185 struct msgb *msg = msgb_alloc(128, "bcap");
1186 gsm48_encode_bearer_cap(msg, 0, &bcap);
1187 char *ret = osmo_hexdump_nospc(msg->data, msg->len);
1188 msgb_free(msg);
1189 return ret;
1190}
1191
1192static void test_codecs_mo(const struct codec_test *t)
1193{
1194 struct gsm_mncc mncc = {
1195 .imsi = IMSI,
1196 };
1197
Neels Hofmeyr6a1faa92023-03-23 01:56:14 +01001198 struct gsm_mncc_rtp mncc_rtp = {};
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001199
1200 BTW("======================== MO call: %s", t->desc);
1201 btw("CM Service Request with Codec List (BSS Supported) =%s",
1202 codec_list_name(t->mo_rx_compl_l3_codec_list_bss_supported));
1203
1204 cm_service_result_sent = RES_NONE;
1205 ms_sends_compl_l3("052471"
1206 "03575886" /* classmark 2 */
1207 "089910070000106005" /* IMSI */,
1208 codec_list(t->mo_rx_compl_l3_codec_list_bss_supported));
1209 VERBOSE_ASSERT(cm_service_result_sent, == RES_ACCEPT, "%d");
1210 EXPECT_ACCEPTED(true);
1211
1212 btw("MS sends CC SETUP with Bearer Capability = %s",
1213 bcap_name(t->mo_rx_ms_bcap));
1214 expect_crcx(RTP_TO_CN);
1215 expect_crcx(RTP_TO_RAN);
1216 ms_sends_msgf("0385" /* CC, seq = 2 -> 0x80 | CC Setup = 0x5 */
1217 "%s" /* Bearer Capability */
1218 "5e038121f3" /* Called Number BCD */
1219 "15020100" /* CC Capabilities */
1220 "4008" /* Supported Codec List */
1221 "04026000" /* UMTS: AMR 2 | AMR */
1222 "00021f00" /* GSM: HR AMR | FR AMR | GSM EFR | GSM HR | GSM FR */,
1223 bcap_hexstr(t->mo_rx_ms_bcap)
1224 );
1225 OSMO_ASSERT(crcx_scheduled(RTP_TO_CN));
1226 OSMO_ASSERT(crcx_scheduled(RTP_TO_RAN));
1227
1228 btw("As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered");
1229 cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_IND);
1230 crcx_ok(RTP_TO_CN);
1231 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
Neels Hofmeyr6a1faa92023-03-23 01:56:14 +01001232 mncc.callref = mncc_rtp.callref = cc_to_mncc_tx_got_callref;
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001233 VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mo_tx_sdp_mncc_setup_ind);
1234
Neels Hofmeyr11c04ae2023-11-28 04:40:52 +01001235 btw("MNCC replies with MNCC_RTP_CREATE");
Neels Hofmeyr6a1faa92023-03-23 01:56:14 +01001236 sdp_str_from_subtype_names(mncc_rtp.sdp, sizeof(mncc_rtp.sdp), t->mo_rx_sdp_mncc_rtp_create);
1237 mncc_sends_to_cc(MNCC_RTP_CREATE, &mncc_rtp);
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001238
1239 btw("MGW acknowledges the CRCX, triggering Assignment with%s", perm_speech_name(t->mo_tx_assignment_perm_speech));
1240 expect_bssap_assignment();
1241 crcx_ok(RTP_TO_RAN);
1242 OSMO_ASSERT(bssap_assignment_sent);
1243 VALIDATE_PERM_SPEECH(&bssap_assignment_command_last_channel_type, t->mo_tx_assignment_perm_speech);
1244
1245 btw("Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC");
1246 cc_to_mncc_expect_tx("", MNCC_RTP_CREATE);
1247 ms_sends_assignment_complete(t->mo_rx_assigned_codec);
1248 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1249 VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mo_tx_sdp_mncc_rtp_create);
1250
1251 btw("MNCC says that's fine");
1252 dtap_expect_tx("8302" /* CC: Call Proceeding */);
1253 mncc_sends_to_cc(MNCC_CALL_PROC_REQ, &mncc);
1254 OSMO_ASSERT(dtap_tx_confirmed);
1255
1256 fake_time_passes(1, 23);
1257
1258 btw("The other call leg got established (not shown here), MNCC tells us so, with codecs {%s }",
1259 strlist_name(t->mo_rx_sdp_mncc_alert_req));
1260 dtap_expect_tx("8301" /* CC: Call Alerting */);
1261 sdp_str_from_subtype_names(mncc.sdp, sizeof(mncc.sdp), t->mo_rx_sdp_mncc_alert_req);
1262 mncc_sends_to_cc(MNCC_ALERT_REQ, &mncc);
1263 OSMO_ASSERT(dtap_tx_confirmed);
1264
1265 dtap_expect_tx("8307" /* CC: Connect */);
1266 sdp_str_from_subtype_names(mncc.sdp, sizeof(mncc.sdp), t->mo_rx_sdp_mncc_setup_rsp);
1267 mncc_sends_to_cc(MNCC_SETUP_RSP, &mncc);
1268 OSMO_ASSERT(dtap_tx_confirmed);
1269
1270 fake_time_passes(1, 23);
1271
1272 cc_to_mncc_expect_tx("", MNCC_SETUP_COMPL_IND);
1273 ms_sends_msg("03cf" /* CC: Connect Acknowledge */);
1274 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1275 VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mo_tx_sdp_mncc_setup_compl_ind);
1276
1277 BTW("RTP stream goes ahead, not shown here.");
1278 fake_time_passes(123, 45);
1279
1280 BTW("Call ends");
1281 cc_to_mncc_expect_tx("", MNCC_DISC_IND);
1282 ms_sends_msg("032502e090" /* CC: Disconnect, cause: Normal Call Clearing */);
1283 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1284
1285 dtap_expect_tx("832d" /* CC: Release */);
1286 mncc_sends_to_cc(MNCC_REL_REQ, &mncc);
1287 OSMO_ASSERT(dtap_tx_confirmed);
1288
1289 cc_to_mncc_expect_tx("", MNCC_REL_CNF);
1290 expect_bssap_clear();
1291 ms_sends_msg("036a" /* CC: Release Complete */);
1292 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1293 OSMO_ASSERT(bssap_clear_sent);
1294
1295 ran_sends_clear_complete();
1296 EXPECT_CONN_COUNT(0);
1297 BTW("======================== SUCCESS: MO call: %s", t->desc);
1298}
1299
1300static void test_codecs_mt(const struct codec_test *t)
1301{
1302 struct gsm_mncc mncc = {
1303 .imsi = IMSI,
1304 .callref = 0x423,
1305 .fields = MNCC_F_BEARER_CAP,
1306 .bearer_cap = {
1307 .speech_ver = { GSM48_BCAP_SV_FR, -1, },
1308 },
1309 };
Neels Hofmeyr6a1faa92023-03-23 01:56:14 +01001310 struct gsm_mncc_rtp mncc_rtp = {
1311 .callref = 0x423,
1312 };
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001313
1314 BTW("======================== MT call: %s", t->desc);
1315
1316 BTW("MNCC asks us to setup a call, causing Paging");
1317
1318 paging_expect_imsi(IMSI);
1319 paging_sent = false;
1320 sdp_str_from_subtype_names(mncc.sdp, sizeof(mncc.sdp), t->mt_rx_sdp_mncc_setup_req);
1321 mncc_sends_to_cc(MNCC_SETUP_REQ, &mncc);
1322 mncc.sdp[0] = '\0';
1323
1324 VERBOSE_ASSERT(paging_sent, == true, "%d");
1325
1326 btw("MS replies with Paging Response, with Codec List (BSS Supported) =%s",
1327 codec_list_name(t->mt_rx_compl_l3_codec_list_bss_supported));
1328
1329 if (t->expect_codec_mismatch_on_paging_response) {
1330 btw("VLR accepts, but MSC notices a codec mismatch and aborts");
1331 cc_to_mncc_expect_tx("", MNCC_REL_IND);
1332 expect_bssap_clear();
1333 ms_sends_compl_l3("062707"
1334 "03575886" /* classmark 2 */
1335 "089910070000106005" /* IMSI */,
1336 codec_list(t->mt_rx_compl_l3_codec_list_bss_supported));
1337 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1338 OSMO_ASSERT(bssap_clear_sent);
1339
1340 ran_sends_clear_complete();
1341 EXPECT_CONN_COUNT(0);
1342
1343 BTW("======================== SUCCESS: MT call: %s", t->desc);
1344 return;
1345 }
1346
1347 btw("VLR accepts, MSC sends CC Setup with Bearer Capability = %s",
1348 bcap_name(t->mt_tx_cc_setup_bcap));
1349 char *cc_setup_bcap = talloc_asprintf(msc_vlr_tests_ctx, "0305%s",
1350 bcap_hexstr(t->mt_tx_cc_setup_bcap));
1351 dtap_expect_tx(cc_setup_bcap);
1352 ms_sends_compl_l3("062707"
1353 "03575886" /* classmark 2 */
1354 "089910070000106005" /* IMSI */,
1355 codec_list(t->mt_rx_compl_l3_codec_list_bss_supported));
1356 OSMO_ASSERT(dtap_tx_confirmed);
1357 talloc_free(cc_setup_bcap);
1358
1359 btw("MS confirms call, we create a RAN-side RTP and forward MNCC_CALL_CONF_IND");
1360 expect_crcx(RTP_TO_CN);
1361 expect_crcx(RTP_TO_RAN);
1362 cc_to_mncc_expect_tx(IMSI, MNCC_CALL_CONF_IND);
1363 ms_sends_msgf("8348" /* CC: Call Confirmed */
1364 "%s" /* Bearer Capability */
1365 "15020100" /* Call Control Capabilities */
1366 "40080402600400021f00" /* Supported Codec List */,
1367 bcap_hexstr(t->mt_rx_ms_bcap)
1368 );
1369 OSMO_ASSERT(crcx_scheduled(RTP_TO_CN));
1370 OSMO_ASSERT(crcx_scheduled(RTP_TO_RAN));
1371 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1372 VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mt_tx_sdp_mncc_call_conf_ind);
1373
1374 btw("MGW acknowledges the CRCX to RAN, triggering Assignment with%s", perm_speech_name(t->mt_tx_assignment_perm_speech));
1375
1376 if (t->expect_codec_mismatch_on_cc_call_conf) {
1377 btw("MS Bearer Capability leads to a codec mismatch, Assignment aborts");
1378
1379 dtap_expect_tx("032d0802e1af" /* CC Release */);
1380 cc_to_mncc_expect_tx("", MNCC_REL_IND);
1381 expect_bssap_clear();
1382 crcx_ok(RTP_TO_RAN);
1383
1384 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1385 OSMO_ASSERT(bssap_clear_sent);
1386
1387 ran_sends_clear_complete();
1388 EXPECT_CONN_COUNT(0);
1389 BTW("======================== SUCCESS: MT call: %s", t->desc);
1390 return;
1391 }
1392
1393 expect_bssap_assignment();
1394 crcx_ok(RTP_TO_RAN);
1395 OSMO_ASSERT(bssap_assignment_sent);
1396 VALIDATE_PERM_SPEECH(&bssap_assignment_command_last_channel_type, t->mt_tx_assignment_perm_speech);
1397
1398 btw("Assignment completes, triggering CRCX to CN");
1399 ms_sends_assignment_complete(t->mt_rx_assigned_codec);
1400
1401 btw("MNCC sends MNCC_RTP_CREATE, which first waits for the CN side RTP");
Neels Hofmeyr6a1faa92023-03-23 01:56:14 +01001402 sdp_str_from_subtype_names(mncc_rtp.sdp, sizeof(mncc_rtp.sdp), t->mt_rx_sdp_mncc_rtp_create);
1403 mncc_sends_to_cc(MNCC_RTP_CREATE, &mncc_rtp);
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001404
1405 btw("When the CN side RTP address is known, ack MNCC_RTP_CREATE");
1406 cc_to_mncc_expect_tx("", MNCC_RTP_CREATE);
1407 crcx_ok(RTP_TO_CN);
1408 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1409 VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mt_tx_sdp_mncc_rtp_create);
1410
1411 fake_time_passes(1, 23);
1412
1413 cc_to_mncc_expect_tx("", MNCC_ALERT_IND);
1414 ms_sends_msg("8381" /* CC: Alerting */);
1415 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1416 VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mt_tx_sdp_mncc_alert_ind);
1417
1418 fake_time_passes(1, 23);
1419
1420 cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_CNF);
1421 ms_sends_msg("83c7" /* CC: Connect */);
1422 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1423 VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mt_tx_sdp_mncc_setup_cnf);
1424
1425 dtap_expect_tx("030f" /* CC: Connect Acknowledge */);
1426 sdp_str_from_subtype_names(mncc.sdp, sizeof(mncc.sdp), t->mt_rx_sdp_mncc_setup_compl_req);
1427 mncc_sends_to_cc(MNCC_SETUP_COMPL_REQ, &mncc);
1428
1429 BTW("RTP stream goes ahead, not shown here.");
1430 fake_time_passes(123, 45);
1431
1432 BTW("Call ends");
1433 cc_to_mncc_expect_tx("", MNCC_DISC_IND);
1434 ms_sends_msg("832502e090" /* CC: Disconnect, cause: Normal Call Clearing */);
1435 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1436
1437 dtap_expect_tx("032d" /* CC: Release */);
1438 mncc_sends_to_cc(MNCC_REL_REQ, &mncc);
1439 OSMO_ASSERT(dtap_tx_confirmed);
1440
1441 cc_to_mncc_expect_tx("", MNCC_REL_CNF);
1442 expect_bssap_clear();
1443 ms_sends_msg("836a" /* CC: Release Complete */);
1444 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1445 OSMO_ASSERT(bssap_clear_sent);
1446
1447 ran_sends_clear_complete();
1448 EXPECT_CONN_COUNT(0);
1449 BTW("======================== SUCCESS: MT call: %s", t->desc);
1450}
1451
1452static void test_codecs(void)
1453{
1454 const struct codec_test *t;
1455 clear_vlr();
1456
1457 comment_start();
1458
1459 fake_time_start();
1460
1461 lu_geran_noauth();
1462
1463 for (t = codec_tests; t - codec_tests < ARRAY_SIZE(codec_tests); t++) {
1464 test_codecs_mo(t);
1465 test_codecs_mt(t);
1466 }
1467
1468 EXPECT_CONN_COUNT(0);
1469 clear_vlr();
1470 comment_end();
1471}
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +01001472
Neels Hofmeyra99b4272017-11-21 17:13:23 +01001473msc_vlr_test_func_t msc_vlr_tests[] = {
1474 test_call_mo,
1475 test_call_mt,
Neels Hofmeyrcbcf89c2018-03-13 17:52:07 +01001476 test_call_mt2,
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +01001477 test_call_mo_to_unknown,
1478 test_call_mo_to_unknown_timeout,
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001479 test_codecs,
Neels Hofmeyra99b4272017-11-21 17:13:23 +01001480 NULL
1481};