blob: 2c67c1ef6cfc3814dd4131542d7cf0329efa1b0c [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 };
210
Neels Hofmeyrdfdc61d2018-03-02 00:40:58 +0100211 comment_start();
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100212
213 fake_time_start();
214
Neels Hofmeyr11bf0bc2019-10-21 05:55:49 +0200215 lu_utran_tmsi();
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100216
217 BTW("after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector");
218 auth_request_sent = false;
219 auth_request_expect_rand = "c187a53a5e6b9d573cac7c74451fd46d";
220 auth_request_expect_autn = "1843a645b98d00005b2d666af46c45d9";
221 cm_service_result_sent = RES_NONE;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100222 ms_sends_msg("052471"
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100223 "03575886" /* classmark 2 */
224 "089910070000106005" /* IMSI */);
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100225 VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
226 VERBOSE_ASSERT(auth_request_sent, == true, "%d");
227
228 btw("needs auth, not yet accepted");
229 EXPECT_ACCEPTED(false);
230
231 /* On UTRAN */
232 btw("MS sends Authen Response, VLR accepts and sends SecurityModeControl");
Neels Hofmeyrdbabfd32018-03-10 02:06:47 +0100233 expect_security_mode_ctrl(NULL, "1159ec926a50e98c034a6b7d7c9f418d");
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100234 ms_sends_msg("0554" "7db47cf7" "2104" "f81e4dc7"); /* 2nd vector's res, s.a. */
Neels Hofmeyrdbabfd32018-03-10 02:06:47 +0100235 VERBOSE_ASSERT(security_mode_ctrl_sent, == true, "%d");
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100236 VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
237
238 btw("MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept");
Alexander Couzens2aaff752021-10-19 17:09:11 +0200239 ms_sends_security_mode_complete(1);
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100240 VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
241
242 BTW("a call is initiated");
243
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100244 btw("CC SETUP causes CRCX towards CN");
245 expect_crcx(RTP_TO_CN);
246 expect_crcx(RTP_TO_RAN);
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100247 ms_sends_msg("0385" /* CC, seq = 2 -> 0x80 | CC Setup = 0x5 */
248 "0406600402000581" /* Bearer Capability */
249 "5e038121f3" /* Called Number BCD */
250 "15020100" /* CC Capabilities */
251 "4008" /* Supported Codec List */
252 "04026000" /* UMTS: AMR 2 | AMR */
253 "00021f00" /* GSM: HR AMR | FR AMR | GSM EFR | GSM HR | GSM FR */
254 );
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100255 OSMO_ASSERT(crcx_scheduled(RTP_TO_CN));
256 OSMO_ASSERT(crcx_scheduled(RTP_TO_RAN));
257
258 btw("As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered");
259 cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_IND);
260 crcx_ok(RTP_TO_CN);
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100261 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
262 mncc.callref = cc_to_mncc_tx_got_callref;
263
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200264 btw("MNCC replies with MNCC_RTP_CREATE, causing MGW endpoint CRCX to RAN");
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200265 mncc_sends_to_cc(MNCC_RTP_CREATE, &mncc);
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200266
267 btw("MGW acknowledges the CRCX, triggering Assignment");
268 expect_iu_rab_assignment();
269 crcx_ok(RTP_TO_RAN);
270 OSMO_ASSERT(iu_rab_assignment_sent);
271
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100272 btw("Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC");
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200273 cc_to_mncc_expect_tx("", MNCC_RTP_CREATE);
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100274 ms_sends_assignment_complete("AMR");
275 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200276
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100277 btw("MNCC says that's fine");
278 dtap_expect_tx("8302" /* CC: Call Proceeding */);
279 mncc_sends_to_cc(MNCC_CALL_PROC_REQ, &mncc);
280 OSMO_ASSERT(dtap_tx_confirmed);
281
282 fake_time_passes(1, 23);
283
284 btw("The other call leg got established (not shown here), MNCC tells us so");
285 dtap_expect_tx("8301" /* CC: Call Alerting */);
286 mncc_sends_to_cc(MNCC_ALERT_REQ, &mncc);
287 OSMO_ASSERT(dtap_tx_confirmed);
288
289 dtap_expect_tx("8307" /* CC: Connect */);
290 mncc_sends_to_cc(MNCC_SETUP_RSP, &mncc);
291 OSMO_ASSERT(dtap_tx_confirmed);
292
293 fake_time_passes(1, 23);
294
295 cc_to_mncc_expect_tx("", MNCC_SETUP_COMPL_IND);
296 ms_sends_msg("03cf" /* CC: Connect Acknowledge */);
297 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
298
299 BTW("RTP stream goes ahead, not shown here.");
300 fake_time_passes(123, 45);
301
302 BTW("Call ends");
303 cc_to_mncc_expect_tx("", MNCC_DISC_IND);
304 ms_sends_msg("032502e090" /* CC: Disconnect, cause: Normal Call Clearing */);
305 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
306
307 dtap_expect_tx("832d" /* CC: Release */);
308 mncc_sends_to_cc(MNCC_REL_REQ, &mncc);
309 OSMO_ASSERT(dtap_tx_confirmed);
310
311 cc_to_mncc_expect_tx("", MNCC_REL_CNF);
312 expect_iu_release();
313 ms_sends_msg("036a" /* CC: Release Complete */);
314 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
315 OSMO_ASSERT(iu_release_sent);
316
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100317 ran_sends_clear_complete();
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100318 EXPECT_CONN_COUNT(0);
319 clear_vlr();
Neels Hofmeyrdfdc61d2018-03-02 00:40:58 +0100320 comment_end();
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100321}
322
Neels Hofmeyrf3d81f62018-03-02 01:05:38 +0100323static void test_call_mt()
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100324{
325 struct gsm_mncc mncc = {
326 .imsi = IMSI,
327 .callref = 0x423,
Neels Hofmeyr8dd16462022-01-13 20:06:53 +0100328 .fields = MNCC_F_BEARER_CAP,
329 .bearer_cap = {
330 .speech_ver = {
331 GSM48_BCAP_SV_AMR_F,
332 GSM48_BCAP_SV_EFR,
333 GSM48_BCAP_SV_FR,
334 GSM48_BCAP_SV_AMR_H,
335 GSM48_BCAP_SV_HR,
336 -1 },
337 },
338 /* NOTE: below SDP includes only AMR, above bearer_cap includes more codecs. Ideally, these would match,
339 * but in reality the bearer cap in MNCC was never implemented properly. This test shows that above
340 * bearer_cap is ignored when SDP is present: In the CC Setup below, the Bearer Capability is only
341 * "04 04 60 04 05 8b" with speech versions '04' == GSM48_BCAP_SV_AMR_F and '05' == GSM48_BCAP_SV_AMR_H.
342 */
343 .sdp = "v=0\r\n"
344 "o=OsmoMSC 0 0 IN IP4 10.23.23.1\r\n"
345 "s=GSM Call\r\n"
346 "c=IN IP4 10.23.23.1\r\n"
347 "t=0 0\r\n"
348 "m=audio 23 RTP/AVP 112\r\n"
349 "a=rtpmap:112 AMR/8000\r\n"
350 "a=fmtp:112 octet-align=1\r\n"
351 "a=ptime:20\r\n",
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100352 };
353
Neels Hofmeyrdfdc61d2018-03-02 00:40:58 +0100354 comment_start();
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100355
356 fake_time_start();
357
Neels Hofmeyr11bf0bc2019-10-21 05:55:49 +0200358 lu_utran_tmsi();
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100359
360 BTW("after a while, MNCC asks us to setup a call, causing Paging");
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100361
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100362 paging_expect_imsi(IMSI);
363 paging_sent = false;
364 mncc_sends_to_cc(MNCC_SETUP_REQ, &mncc);
Neels Hofmeyr8dd16462022-01-13 20:06:53 +0100365 mncc.sdp[0] = '\0';
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100366
367 VERBOSE_ASSERT(paging_sent, == true, "%d");
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100368
369 btw("MS replies with Paging Response, and VLR sends Auth Request");
370 auth_request_sent = false;
371 auth_request_expect_rand = "c187a53a5e6b9d573cac7c74451fd46d";
372 auth_request_expect_autn = "1843a645b98d00005b2d666af46c45d9";
373 ms_sends_msg("062707"
374 "03575886" /* classmark 2 */
375 "089910070000106005" /* IMSI */);
376 VERBOSE_ASSERT(auth_request_sent, == true, "%d");
377
378 btw("MS sends Authen Response, VLR accepts and sends SecurityModeControl");
Neels Hofmeyrdbabfd32018-03-10 02:06:47 +0100379 expect_security_mode_ctrl(NULL, "1159ec926a50e98c034a6b7d7c9f418d");
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100380 ms_sends_msg("0554" "7db47cf7" "2104" "f81e4dc7"); /* 2nd vector's res, s.a. */
Neels Hofmeyrdbabfd32018-03-10 02:06:47 +0100381 VERBOSE_ASSERT(security_mode_ctrl_sent, == true, "%d");
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100382
383 btw("MS sends SecurityModeControl acceptance, VLR accepts, sends CC Setup");
Neels Hofmeyr8dd16462022-01-13 20:06:53 +0100384 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 +0200385 ms_sends_security_mode_complete(1);
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100386
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200387 btw("MS confirms call, we create a RAN-side RTP and forward MNCC_CALL_CONF_IND");
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100388 expect_crcx(RTP_TO_CN);
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200389 expect_crcx(RTP_TO_RAN);
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100390 cc_to_mncc_expect_tx(IMSI, MNCC_CALL_CONF_IND);
391 ms_sends_msg("8348" /* CC: Call Confirmed */
392 "0406600402000581" /* Bearer Capability */
393 "15020100" /* Call Control Capabilities */
394 "40080402600400021f00" /* Supported Codec List */);
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100395 OSMO_ASSERT(crcx_scheduled(RTP_TO_CN));
Neels Hofmeyr81938fd2022-01-14 03:39:58 +0100396 OSMO_ASSERT(crcx_scheduled(RTP_TO_RAN));
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200397 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
398
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200399 btw("MGW acknowledges the CRCX to RAN, triggering Assignment");
400 expect_iu_rab_assignment();
401 crcx_ok(RTP_TO_RAN);
402 OSMO_ASSERT(iu_rab_assignment_sent);
403
404 btw("Assignment completes, triggering CRCX to CN");
405 expect_crcx(RTP_TO_CN);
Neels Hofmeyrcec51b32023-03-01 03:47:45 +0100406 ms_sends_assignment_complete("AMR");
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200407
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100408 btw("MNCC sends MNCC_RTP_CREATE, which first waits for the CN side RTP");
409 mncc_sends_to_cc(MNCC_RTP_CREATE, &mncc);
410
411 btw("When the CN side RTP address is known, ack MNCC_RTP_CREATE with full SDP");
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200412 cc_to_mncc_expect_tx("", MNCC_RTP_CREATE);
413 crcx_ok(RTP_TO_CN);
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100414 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100415
416 fake_time_passes(1, 23);
417
418 cc_to_mncc_expect_tx("", MNCC_ALERT_IND);
419 ms_sends_msg("8381" /* CC: Alerting */);
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100420 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100421
422 fake_time_passes(1, 23);
423
424 cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_CNF);
425 ms_sends_msg("83c7" /* CC: Connect */);
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100426 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100427
428 dtap_expect_tx("030f" /* CC: Connect Acknowledge */);
429 mncc_sends_to_cc(MNCC_SETUP_COMPL_REQ, &mncc);
430
431 BTW("RTP stream goes ahead, not shown here.");
432 fake_time_passes(123, 45);
433
434 BTW("Call ends");
435 cc_to_mncc_expect_tx("", MNCC_DISC_IND);
436 ms_sends_msg("832502e090" /* CC: Disconnect, cause: Normal Call Clearing */);
437 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
438
439 dtap_expect_tx("032d" /* CC: Release */);
440 mncc_sends_to_cc(MNCC_REL_REQ, &mncc);
441 OSMO_ASSERT(dtap_tx_confirmed);
442
443 cc_to_mncc_expect_tx("", MNCC_REL_CNF);
444 expect_iu_release();
445 ms_sends_msg("836a" /* CC: Release Complete */);
446 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
447 OSMO_ASSERT(iu_release_sent);
448
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100449 ran_sends_clear_complete();
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100450 EXPECT_CONN_COUNT(0);
451 clear_vlr();
Neels Hofmeyrdfdc61d2018-03-02 00:40:58 +0100452 comment_end();
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100453}
454
Neels Hofmeyrcbcf89c2018-03-13 17:52:07 +0100455static void test_call_mt2()
456{
457 struct gsm_mncc mncc = {
458 .imsi = IMSI,
459 .callref = 0x423,
Neels Hofmeyr8dd16462022-01-13 20:06:53 +0100460 .fields = MNCC_F_BEARER_CAP,
461 .bearer_cap = {
462 .speech_ver = { GSM48_BCAP_SV_FR, -1, },
463 },
464 /* NOTE: below SDP includes only AMR, above bearer_cap includes only GSM-FR. Ideally, these would match,
465 * but in reality the bearer cap in MNCC was never implemented properly. This test shows that above
466 * bearer_cap is ignored when SDP is present: In the CC Setup below, the Bearer Capability is only
467 * "04 04 60 04 05 8b" with speech versions '04' == GSM48_BCAP_SV_AMR_F and '05' == GSM48_BCAP_SV_AMR_H.
468 */
469 .sdp = "v=0\r\n"
470 "o=OsmoMSC 0 0 IN IP4 10.23.23.1\r\n"
471 "s=GSM Call\r\n"
472 "c=IN IP4 10.23.23.1\r\n"
473 "t=0 0\r\n"
474 "m=audio 23 RTP/AVP 112\r\n"
475 "a=rtpmap:112 AMR/8000\r\n"
476 "a=fmtp:112 octet-align=1\r\n"
477 "a=ptime:20\r\n",
Neels Hofmeyrcbcf89c2018-03-13 17:52:07 +0100478 };
479
480 comment_start();
481
482 fake_time_start();
483
Neels Hofmeyr11bf0bc2019-10-21 05:55:49 +0200484 lu_utran_tmsi();
Neels Hofmeyrcbcf89c2018-03-13 17:52:07 +0100485
486 BTW("after a while, MNCC asks us to setup a call, causing Paging");
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100487
Neels Hofmeyrcbcf89c2018-03-13 17:52:07 +0100488 paging_expect_imsi(IMSI);
489 paging_sent = false;
490 mncc_sends_to_cc(MNCC_SETUP_REQ, &mncc);
491
492 VERBOSE_ASSERT(paging_sent, == true, "%d");
Neels Hofmeyrcbcf89c2018-03-13 17:52:07 +0100493
494 btw("MS replies with Paging Response, and VLR sends Auth Request");
495 auth_request_sent = false;
496 auth_request_expect_rand = "c187a53a5e6b9d573cac7c74451fd46d";
497 auth_request_expect_autn = "1843a645b98d00005b2d666af46c45d9";
498 ms_sends_msg("062707"
499 "03575886" /* classmark 2 */
500 "089910070000106005" /* IMSI */);
501 VERBOSE_ASSERT(auth_request_sent, == true, "%d");
502
503 btw("MS sends Authen Response, VLR accepts and sends SecurityModeControl");
504 expect_security_mode_ctrl(NULL, "1159ec926a50e98c034a6b7d7c9f418d");
505 ms_sends_msg("0554" "7db47cf7" "2104" "f81e4dc7"); /* 2nd vector's res, s.a. */
506 VERBOSE_ASSERT(security_mode_ctrl_sent, == true, "%d");
507
508 btw("MS sends SecurityModeControl acceptance, VLR accepts, sends CC Setup");
Neels Hofmeyr8dd16462022-01-13 20:06:53 +0100509 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 +0200510 ms_sends_security_mode_complete(1);
Neels Hofmeyrcbcf89c2018-03-13 17:52:07 +0100511
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200512 btw("MS confirms call, we create a RAN-side RTP and forward MNCC_CALL_CONF_IND");
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100513 expect_crcx(RTP_TO_CN);
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200514 expect_crcx(RTP_TO_RAN);
Neels Hofmeyrcbcf89c2018-03-13 17:52:07 +0100515 cc_to_mncc_expect_tx(IMSI, MNCC_CALL_CONF_IND);
516 ms_sends_msg("8348" /* CC: Call Confirmed */
517 "0406600402000581" /* Bearer Capability */
518 "15020100" /* Call Control Capabilities */
519 "40080402600400021f00" /* Supported Codec List */);
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100520 OSMO_ASSERT(crcx_scheduled(RTP_TO_CN));
Neels Hofmeyr81938fd2022-01-14 03:39:58 +0100521 OSMO_ASSERT(crcx_scheduled(RTP_TO_RAN));
Neels Hofmeyrcbcf89c2018-03-13 17:52:07 +0100522 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
523
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100524 btw("MNCC sends MNCC_RTP_CREATE, which first waits for the CN side RTP");
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200525 mncc_sends_to_cc(MNCC_RTP_CREATE, &mncc);
526
527 btw("MGW acknowledges the CRCX to RAN, triggering Assignment");
528 expect_iu_rab_assignment();
529 crcx_ok(RTP_TO_RAN);
530 OSMO_ASSERT(iu_rab_assignment_sent);
531
532 btw("Assignment completes, triggering CRCX to CN");
Neels Hofmeyrcec51b32023-03-01 03:47:45 +0100533 ms_sends_assignment_complete("AMR");
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200534
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100535 btw("When the CN side RTP address is known, ack MNCC_RTP_CREATE with full SDP");
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200536 cc_to_mncc_expect_tx("", MNCC_RTP_CREATE);
537 crcx_ok(RTP_TO_CN);
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100538 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
539
Neels Hofmeyrcbcf89c2018-03-13 17:52:07 +0100540 fake_time_passes(1, 23);
541
542 cc_to_mncc_expect_tx("", MNCC_ALERT_IND);
543 ms_sends_msg("8381" /* CC: Alerting */);
544 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
545
546 fake_time_passes(15, 23);
547
548 btw("The call failed, the BSC sends a BSSMAP Clear Request");
Vadim Yanitskiydd466cf2021-02-05 19:17:31 +0100549 cc_to_mncc_expect_tx("", MNCC_REL_IND);
Keith Whyteff17f8f2019-08-01 12:20:25 +0200550 dtap_expect_tx("032d0802e1af"); /* CC: Release */
Neels Hofmeyrcbcf89c2018-03-13 17:52:07 +0100551 expect_iu_release();
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100552 msc_a_release_cn(msub_msc_a(g_msub));
553 OSMO_ASSERT(dtap_tx_confirmed);
Neels Hofmeyrcbcf89c2018-03-13 17:52:07 +0100554 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
555 OSMO_ASSERT(iu_release_sent);
556
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100557 ran_sends_clear_complete();
Neels Hofmeyrcbcf89c2018-03-13 17:52:07 +0100558 EXPECT_CONN_COUNT(0);
559
560 /* Make sure a pending release timer doesn't fire later to access freed data */
561 fake_time_passes(15, 23);
562
563 clear_vlr();
564 comment_end();
565}
566
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100567static void test_call_mo_to_unknown()
568{
569 struct gsm_mncc mncc = {
570 .imsi = IMSI,
571 };
572
573 comment_start();
574
575 fake_time_start();
576
Neels Hofmeyr11bf0bc2019-10-21 05:55:49 +0200577 lu_utran_tmsi();
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100578
579 BTW("after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector");
580 auth_request_sent = false;
581 auth_request_expect_rand = "c187a53a5e6b9d573cac7c74451fd46d";
582 auth_request_expect_autn = "1843a645b98d00005b2d666af46c45d9";
583 cm_service_result_sent = RES_NONE;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100584 ms_sends_msg("052471"
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100585 "03575886" /* classmark 2 */
586 "089910070000106005" /* IMSI */);
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100587 VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
588 VERBOSE_ASSERT(auth_request_sent, == true, "%d");
589
590 btw("needs auth, not yet accepted");
591 EXPECT_ACCEPTED(false);
592
593 /* On UTRAN */
594 btw("MS sends Authen Response, VLR accepts and sends SecurityModeControl");
595 expect_security_mode_ctrl(NULL, "1159ec926a50e98c034a6b7d7c9f418d");
596 ms_sends_msg("0554" "7db47cf7" "2104" "f81e4dc7"); /* 2nd vector's res, s.a. */
597 VERBOSE_ASSERT(security_mode_ctrl_sent, == true, "%d");
598 VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
599
600 btw("MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept");
Alexander Couzens2aaff752021-10-19 17:09:11 +0200601 ms_sends_security_mode_complete(1);
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100602 VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
603
604 BTW("a call is initiated");
605
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100606 btw("CC SETUP causes CRCX towards CN");
607 expect_crcx(RTP_TO_CN);
608 expect_crcx(RTP_TO_RAN);
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100609 ms_sends_msg("0385" /* CC, seq = 2 -> 0x80 | CC Setup = 0x5 */
610 "0406600402000581" /* Bearer Capability */
611 "5e038121f3" /* Called Number BCD */
612 "15020100" /* CC Capabilities */
613 "4008" /* Supported Codec List */
614 "04026000" /* UMTS: AMR 2 | AMR */
615 "00021f00" /* GSM: HR AMR | FR AMR | GSM EFR | GSM HR | GSM FR */
616 );
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100617 OSMO_ASSERT(crcx_scheduled(RTP_TO_CN));
618 OSMO_ASSERT(crcx_scheduled(RTP_TO_RAN));
619
620 btw("As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered");
621 cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_IND);
622 crcx_ok(RTP_TO_CN);
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100623 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
624 mncc.callref = cc_to_mncc_tx_got_callref;
625
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200626 btw("MNCC replies with MNCC_RTP_CREATE, causing MGW endpoint CRCX to RAN");
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200627 mncc_sends_to_cc(MNCC_RTP_CREATE, &mncc);
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200628
629 btw("MGW acknowledges the CRCX, triggering Assignment");
630 expect_iu_rab_assignment();
631 crcx_ok(RTP_TO_RAN);
632 OSMO_ASSERT(iu_rab_assignment_sent);
633
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100634 btw("Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC");
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200635 cc_to_mncc_expect_tx("", MNCC_RTP_CREATE);
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100636 ms_sends_assignment_complete("AMR");
637 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200638
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100639 btw("MNCC says that's fine");
640 dtap_expect_tx("8302" /* CC: Call Proceeding */);
641 mncc_sends_to_cc(MNCC_CALL_PROC_REQ, &mncc);
642 OSMO_ASSERT(dtap_tx_confirmed);
643
644 btw("But the other side's MSISDN could not be resolved, MNCC tells us to cancel");
645 dtap_expect_tx("832d" /* CC: Release Request */);
646 mncc_sends_to_cc(MNCC_REL_REQ, &mncc);
647
648 dtap_expect_tx("832d" /* CC: Release Request */);
649 fake_time_passes(10, 23);
650
651 expect_iu_release();
652 cc_to_mncc_expect_tx("", MNCC_REL_CNF);
653 ms_sends_msg("036a" /* CC: Release Complete */);
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100654 OSMO_ASSERT(iu_release_sent);
655 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
656
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100657 ran_sends_clear_complete();
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100658 EXPECT_CONN_COUNT(0);
659 clear_vlr();
660 comment_end();
661}
662
663static void test_call_mo_to_unknown_timeout()
664{
665 struct gsm_mncc mncc = {
666 .imsi = IMSI,
667 };
668
669 comment_start();
670
671 fake_time_start();
672
Neels Hofmeyr11bf0bc2019-10-21 05:55:49 +0200673 lu_utran_tmsi();
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100674
675 BTW("after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector");
676 auth_request_sent = false;
677 auth_request_expect_rand = "c187a53a5e6b9d573cac7c74451fd46d";
678 auth_request_expect_autn = "1843a645b98d00005b2d666af46c45d9";
679 cm_service_result_sent = RES_NONE;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100680 ms_sends_msg("052471"
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100681 "03575886" /* classmark 2 */
682 "089910070000106005" /* IMSI */);
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100683 VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
684 VERBOSE_ASSERT(auth_request_sent, == true, "%d");
685
686 btw("needs auth, not yet accepted");
687 EXPECT_ACCEPTED(false);
688
689 /* On UTRAN */
690 btw("MS sends Authen Response, VLR accepts and sends SecurityModeControl");
691 expect_security_mode_ctrl(NULL, "1159ec926a50e98c034a6b7d7c9f418d");
692 ms_sends_msg("0554" "7db47cf7" "2104" "f81e4dc7"); /* 2nd vector's res, s.a. */
693 VERBOSE_ASSERT(security_mode_ctrl_sent, == true, "%d");
694 VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
695
696 btw("MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept");
Alexander Couzens2aaff752021-10-19 17:09:11 +0200697 ms_sends_security_mode_complete(1);
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100698 VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
699
700 BTW("a call is initiated");
701
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100702 btw("CC SETUP causes CRCX towards CN");
703 expect_crcx(RTP_TO_CN);
704 expect_crcx(RTP_TO_RAN);
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100705 ms_sends_msg("0385" /* CC, seq = 2 -> 0x80 | CC Setup = 0x5 */
706 "0406600402000581" /* Bearer Capability */
707 "5e038121f3" /* Called Number BCD */
708 "15020100" /* CC Capabilities */
709 "4008" /* Supported Codec List */
710 "04026000" /* UMTS: AMR 2 | AMR */
711 "00021f00" /* GSM: HR AMR | FR AMR | GSM EFR | GSM HR | GSM FR */
712 );
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100713 OSMO_ASSERT(crcx_scheduled(RTP_TO_CN));
714 OSMO_ASSERT(crcx_scheduled(RTP_TO_RAN));
715
716 btw("As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered");
717 cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_IND);
718 crcx_ok(RTP_TO_CN);
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100719 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
720 mncc.callref = cc_to_mncc_tx_got_callref;
721
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200722 btw("MNCC replies with MNCC_RTP_CREATE, causing MGW endpoint CRCX to RAN");
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200723 mncc_sends_to_cc(MNCC_RTP_CREATE, &mncc);
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200724
725 btw("MGW acknowledges the CRCX, triggering Assignment");
726 expect_iu_rab_assignment();
727 crcx_ok(RTP_TO_RAN);
728 OSMO_ASSERT(iu_rab_assignment_sent);
729
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100730 btw("Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC");
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200731 cc_to_mncc_expect_tx("", MNCC_RTP_CREATE);
Neels Hofmeyrbd5f8e92022-01-13 23:18:02 +0100732 ms_sends_assignment_complete("AMR");
733 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200734
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100735 btw("MNCC says that's fine");
736 dtap_expect_tx("8302" /* CC: Call Proceeding */);
737 mncc_sends_to_cc(MNCC_CALL_PROC_REQ, &mncc);
738 OSMO_ASSERT(dtap_tx_confirmed);
739
740 btw("But the other side's MSISDN could not be resolved, MNCC tells us to cancel");
741 dtap_expect_tx("832d" /* CC: Release Request */);
742 mncc_sends_to_cc(MNCC_REL_REQ, &mncc);
743
744 btw("Despite our repeated CC Release Requests, the MS does not respond anymore");
745 dtap_expect_tx("832d" /* CC: Release Request */);
746 fake_time_passes(10, 23);
747
748 btw("The CC Release times out and we still properly clear the conn");
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100749 cc_to_mncc_expect_tx("", MNCC_REL_CNF);
Neels Hofmeyrd6a769b2018-03-12 23:59:07 +0100750 expect_iu_release();
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100751 fake_time_passes(10, 23);
752 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100753 OSMO_ASSERT(iu_release_sent);
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100754
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100755 ran_sends_clear_complete();
Neels Hofmeyrd6a769b2018-03-12 23:59:07 +0100756 EXPECT_CONN_COUNT(0);
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +0100757 clear_vlr();
758 comment_end();
759}
760
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +0100761#define LIST_END 0xffff
762
763struct codec_test {
764 const char *desc;
765
766 /* What to send during Complete Layer 3 as Codec List (BSS Supported). List ends with a LIST_END entry */
767 enum gsm0808_speech_codec_type mo_rx_compl_l3_codec_list_bss_supported[8];
768
769 /* What to send during CC Setup as MS Bearer Capability. List ends with a LIST_END entry */
770 enum gsm48_bcap_speech_ver mo_rx_ms_bcap[8];
771
772 /* What codecs should osmo-msc send in the MNCC_SETUP_IND message.
773 * Just the SDP subtype names like "GSM", "GSM-EFR", "AMR", ..., list ends with NULL entry */
774 const char *mo_tx_sdp_mncc_setup_ind[8];
775
776 /* What codecs the remote call leg should send as SDP via MNCC during MNCC_RTP_CREATE (if any). */
777 const char *mo_rx_sdp_mncc_rtp_create[8];
778
779 /* What the MSC should send as Channel Type IE in the Assignment Command to the BSS. List ends with a
780 * LIST_END entry */
781 enum gsm0808_permitted_speech mo_tx_assignment_perm_speech[8];
782
783 /* What codec to assign in the Assignment Complete's Codec (Chosen) IE. Just a subtype name. */
784 const char *mo_rx_assigned_codec;
785
786 /* MO acks the MNCC_RTP_CREATE with these codecs (if any). */
787 const char *mo_tx_sdp_mncc_rtp_create[8];
788
789 /* mt_rx_sdp_mncc_setup_req == mo_tx_sdp_mncc_rtp_create */
790#define mt_rx_sdp_mncc_setup_req mo_tx_sdp_mncc_rtp_create
791
792 enum gsm0808_speech_codec_type mt_rx_compl_l3_codec_list_bss_supported[8];
793 bool expect_codec_mismatch_on_paging_response;
794 enum gsm48_bcap_speech_ver mt_tx_cc_setup_bcap[8];
795 enum gsm48_bcap_speech_ver mt_rx_ms_bcap[8];
796 bool expect_codec_mismatch_on_cc_call_conf;
797 const char *mt_tx_sdp_mncc_call_conf_ind[8];
798
799 enum gsm0808_permitted_speech mt_tx_assignment_perm_speech[8];
800 const char *mt_rx_assigned_codec;
801
802 const char *mt_rx_sdp_mncc_rtp_create[8];
803 const char *mt_tx_sdp_mncc_rtp_create[8];
804
805 const char *mt_tx_sdp_mncc_alert_ind[8];
806 const char *mt_tx_sdp_mncc_setup_cnf[8];
807 const char *mt_rx_sdp_mncc_setup_compl_req[8];
808
809 /* mo_rx_sdp_mncc_alert_req == mt_tx_sdp_mncc_alert_ind */
810#define mo_rx_sdp_mncc_alert_req mt_tx_sdp_mncc_alert_ind
811#define mo_rx_sdp_mncc_setup_rsp mt_tx_sdp_mncc_alert_ind
812
813 const char *mo_tx_sdp_mncc_setup_compl_ind[8];
814};
815
816#define CODEC_LIST_ALL_GSM { \
817 GSM0808_SCT_FR1, \
818 GSM0808_SCT_FR2, \
819 GSM0808_SCT_FR3, \
820 GSM0808_SCT_HR1, \
821 GSM0808_SCT_HR3, \
822 LIST_END \
823 }
824
825#define BCAP_ALL_GSM { \
826 GSM48_BCAP_SV_AMR_F, \
827 GSM48_BCAP_SV_AMR_H, \
828 GSM48_BCAP_SV_AMR_OH, \
829 GSM48_BCAP_SV_EFR, \
830 GSM48_BCAP_SV_FR, \
831 GSM48_BCAP_SV_HR, \
832 LIST_END \
833 }
834
835#define PERM_SPEECH_ALL_GSM { \
836 GSM0808_PERM_FR3, \
837 GSM0808_PERM_HR3, \
838 GSM0808_PERM_FR2, \
839 GSM0808_PERM_FR1, \
840 GSM0808_PERM_HR1, \
841 LIST_END \
842 }
843
844#define SDP_CODECS_ALL_GSM { \
845 "AMR", \
846 "GSM-EFR", \
847 "GSM", \
848 "GSM-HR-08", \
849 }
850
851static const struct codec_test codec_tests[] = {
852 {
853 .desc = "AMR picked by both MO and MT",
854 .mo_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
855 .mo_rx_ms_bcap = BCAP_ALL_GSM,
856 .mo_tx_sdp_mncc_setup_ind = SDP_CODECS_ALL_GSM,
857 .mo_rx_sdp_mncc_rtp_create = {},
858 .mo_tx_assignment_perm_speech = PERM_SPEECH_ALL_GSM,
859 .mo_rx_assigned_codec = "AMR",
860 .mo_tx_sdp_mncc_rtp_create = { "AMR" },
861 /* mt_rx_sdp_mncc_setup_req == mo_tx_sdp_mncc_rtp_create */
862 .mt_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
863 .mt_tx_cc_setup_bcap = {
864 GSM48_BCAP_SV_AMR_F,
865 GSM48_BCAP_SV_AMR_H,
866 GSM48_BCAP_SV_AMR_OH,
867 LIST_END
868 },
869 .mt_rx_ms_bcap = BCAP_ALL_GSM,
870 .mt_tx_sdp_mncc_call_conf_ind = {},
871 .mt_rx_sdp_mncc_rtp_create = {},
872 .mt_tx_assignment_perm_speech = { GSM0808_PERM_FR3, GSM0808_PERM_HR3, LIST_END },
873 .mt_rx_assigned_codec = "AMR",
874 .mt_tx_sdp_mncc_rtp_create = { "AMR" },
875 .mt_tx_sdp_mncc_alert_ind = { "AMR" },
876 .mt_tx_sdp_mncc_setup_cnf = { "AMR" },
877 .mo_tx_sdp_mncc_setup_compl_ind = {},
878 },
879
880 {
881 .desc = "FR1 picked by MO from Codec List (BSS Supported), MT hence also picks FR1",
882 .mo_rx_compl_l3_codec_list_bss_supported = { GSM0808_SCT_FR1, LIST_END },
883 .mo_rx_ms_bcap = BCAP_ALL_GSM,
884 .mo_tx_sdp_mncc_setup_ind = { "GSM" },
885 .mo_rx_sdp_mncc_rtp_create = {},
886 .mo_tx_assignment_perm_speech = { GSM0808_PERM_FR1, LIST_END },
887 .mo_rx_assigned_codec = "GSM",
888 .mo_tx_sdp_mncc_rtp_create = { "GSM" },
889 /* .mt_rx_sdp_mncc_setup_req == .mo_tx_sdp_mncc_setup_ind */
890 .mt_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
891 .mt_tx_cc_setup_bcap = { GSM48_BCAP_SV_FR, LIST_END },
892 .mt_rx_ms_bcap = BCAP_ALL_GSM,
893 .mt_tx_sdp_mncc_call_conf_ind = {},
894 .mt_rx_sdp_mncc_rtp_create = {},
895 .mt_tx_assignment_perm_speech = { GSM0808_PERM_FR1, LIST_END },
896 .mt_rx_assigned_codec = "GSM",
897 .mt_tx_sdp_mncc_rtp_create = { "GSM" },
898 .mt_tx_sdp_mncc_alert_ind = { "GSM" },
899 .mt_tx_sdp_mncc_setup_cnf = { "GSM" },
900 .mo_tx_sdp_mncc_setup_compl_ind = {},
901 },
902
903 {
904 .desc = "FR1 picked by MO from Bearer Cap, MT hence also picks FR1",
905 .mo_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
906 .mo_rx_ms_bcap = { GSM48_BCAP_SV_FR, LIST_END },
907 .mo_tx_sdp_mncc_setup_ind = { "GSM" },
908 .mo_rx_sdp_mncc_rtp_create = {},
909 .mo_tx_assignment_perm_speech = { GSM0808_PERM_FR1, LIST_END },
910 .mo_rx_assigned_codec = "GSM",
911 .mo_tx_sdp_mncc_rtp_create = { "GSM" },
912 /* .mt_rx_sdp_mncc_setup_req == .mo_tx_sdp_mncc_setup_ind */
913 .mt_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
914 .mt_tx_cc_setup_bcap = { GSM48_BCAP_SV_FR, LIST_END },
915 .mt_rx_ms_bcap = BCAP_ALL_GSM,
916 .mt_tx_sdp_mncc_call_conf_ind = {},
917 .mt_rx_sdp_mncc_rtp_create = {},
918 .mt_tx_assignment_perm_speech = { GSM0808_PERM_FR1, LIST_END },
919 .mt_rx_assigned_codec = "GSM",
920 .mt_tx_sdp_mncc_rtp_create = { "GSM" },
921 .mt_tx_sdp_mncc_alert_ind = { "GSM" },
922 .mt_tx_sdp_mncc_setup_cnf = { "GSM" },
923 .mo_tx_sdp_mncc_setup_compl_ind = {},
924 },
925
926 {
927 .desc = "FR1 picked by MT's Codec List (BSS Supported), hence MO also picks FR1 (EXPECTED FAILURE)",
928 /* Currently the MO Assignment happens before MT gets a chance to send its available codecs.
929 * So even though the MO side would be able to assign FR1 and match MT, this is established too late
930 * and MO mismatches MT. This can only be fixed by a) moving MO Assignment to after MT Assignment
931 * or b) doing a Channel Mode Change or re-assignment after MT Assignment -- since re-assigning might
932 * need an lchan type change and means more overhead, a) would be the best option. */
933 .mo_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
934 .mo_rx_ms_bcap = BCAP_ALL_GSM,
935 .mo_tx_sdp_mncc_setup_ind = SDP_CODECS_ALL_GSM,
936 .mo_rx_sdp_mncc_rtp_create = {},
937 .mo_tx_assignment_perm_speech = PERM_SPEECH_ALL_GSM,
938 .mo_rx_assigned_codec = "AMR", /* <- Early Assignment means codec mismatch */
939 .mo_tx_sdp_mncc_rtp_create = { "AMR" },
940
941 .mt_rx_compl_l3_codec_list_bss_supported = { GSM0808_SCT_FR1, LIST_END },
942 .expect_codec_mismatch_on_paging_response = true,
943 /* The mismatching codec AMR vs. GSM means the call fails (in the lack of transcoding) */
944 },
945
946 {
947 .desc = "FR1 picked by MT's MS Bearer Capability, hence MO also picks FR1 (EXPECTED FAILURE)",
948 /* Like above, MO Assignment happens too early to be able to match MT's codec availability. */
949 .mo_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
950 .mo_rx_ms_bcap = BCAP_ALL_GSM,
951 .mo_tx_sdp_mncc_setup_ind = SDP_CODECS_ALL_GSM,
952 .mo_rx_sdp_mncc_rtp_create = {},
953 .mo_tx_assignment_perm_speech = PERM_SPEECH_ALL_GSM,
954 .mo_rx_assigned_codec = "AMR", /* <- Early Assignment means codec mismatch */
955 .mo_tx_sdp_mncc_rtp_create = { "AMR" },
956
957 .mt_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
958 .mt_tx_cc_setup_bcap = {
959 GSM48_BCAP_SV_AMR_F,
960 GSM48_BCAP_SV_AMR_H,
961 GSM48_BCAP_SV_AMR_OH,
962 LIST_END
963 },
964 .mt_rx_ms_bcap = { GSM48_BCAP_SV_FR, LIST_END },
965 .mt_tx_sdp_mncc_call_conf_ind = {},
966 .mt_rx_sdp_mncc_rtp_create = {},
967 .mt_tx_assignment_perm_speech = { GSM0808_PERM_FR3, GSM0808_PERM_HR3, LIST_END },
968 .expect_codec_mismatch_on_cc_call_conf = true,
969 /* The mismatching codec AMR vs. GSM means the call fails (in the lack of transcoding) */
970 },
971
972};
973
974static char namebuf[4][1024];
975static int use_namebuf = 0;
976
977static const char *codec_list_name(const enum gsm0808_speech_codec_type compl_l3_codec_list_bss_supported[])
978{
979 struct osmo_strbuf sb = { .buf = namebuf[use_namebuf], .len = sizeof(namebuf[0]) };
980 use_namebuf = (use_namebuf + 1) % ARRAY_SIZE(namebuf);
981
982 const enum gsm0808_speech_codec_type *pos;
983 sb.buf[0] = '\0';
984 for (pos = compl_l3_codec_list_bss_supported; *pos != LIST_END; pos++)
985 OSMO_STRBUF_PRINTF(sb, " %s", gsm0808_speech_codec_type_name(*pos));
986 return sb.buf;
987}
988
989static const struct gsm0808_speech_codec_list *codec_list(const enum gsm0808_speech_codec_type compl_l3_codec_list_bss_supported[])
990{
991 static struct gsm0808_speech_codec_list scl;
992 scl = (struct gsm0808_speech_codec_list){};
993 const enum gsm0808_speech_codec_type *pos;
994 for (pos = compl_l3_codec_list_bss_supported; *pos != LIST_END; pos++) {
995 scl.codec[scl.len] = (struct gsm0808_speech_codec){
996 .fi = true,
997 .type = *pos,
998 };
999 scl.len++;
1000 }
1001 return &scl;
1002}
1003
1004static const char *bcap_name(const enum gsm48_bcap_speech_ver ms_bcap[])
1005{
1006 struct osmo_strbuf sb = { .buf = namebuf[use_namebuf], .len = sizeof(namebuf[0]) };
1007 use_namebuf = (use_namebuf + 1) % ARRAY_SIZE(namebuf);
1008
1009 const enum gsm48_bcap_speech_ver *pos;
1010 sb.buf[0] = '\0';
1011 for (pos = ms_bcap; *pos != LIST_END; pos++) {
1012 const struct codec_mapping *m = codec_mapping_by_speech_ver(*pos);
1013 OSMO_STRBUF_PRINTF(sb, " %s", m ? m->sdp.subtype_name : "NULL");
1014 }
1015 return sb.buf;
1016}
1017
1018static const char *perm_speech_name(const enum gsm0808_permitted_speech perm_speech[])
1019{
1020 struct osmo_strbuf sb = { .buf = namebuf[use_namebuf], .len = sizeof(namebuf[0]) };
1021 use_namebuf = (use_namebuf + 1) % ARRAY_SIZE(namebuf);
1022
1023 const enum gsm0808_permitted_speech *pos;
1024 sb.buf[0] = '\0';
1025 for (pos = perm_speech; *pos != LIST_END; pos++)
1026 OSMO_STRBUF_PRINTF(sb, " %s", gsm0808_permitted_speech_name(*pos));
1027 return sb.buf;
1028}
1029
1030static const char *strlist_name(const char *const*strs)
1031{
1032 struct osmo_strbuf sb = { .buf = namebuf[use_namebuf], .len = sizeof(namebuf[0]) };
1033 use_namebuf = (use_namebuf + 1) % ARRAY_SIZE(namebuf);
1034
1035 const char * const *pos;
1036 sb.buf[0] = '\0';
1037 for (pos = strs; *pos != NULL; pos++)
1038 OSMO_STRBUF_PRINTF(sb, " %s", *pos);
1039 return sb.buf;
1040}
1041
1042static bool validate_sdp(const char *func, const char *desc,
1043 const char *sdp_str, const char * const expected_codecs[])
1044{
1045 const char * const *expect_pos;
1046 struct sdp_audio_codec *codec;
1047 struct sdp_msg sdp;
1048 if (sdp_msg_from_sdp_str(&sdp, sdp_str)) {
1049 BTW("%s: %s: ERROR: failed to parse SDP\n%s", func, desc, sdp_str);
1050 return false;
1051 }
1052
1053 expect_pos = expected_codecs;
1054 foreach_sdp_audio_codec(codec, &sdp.audio_codecs) {
1055 if (!*expect_pos) {
1056 BTW("%s: %s: ERROR: did not expect %s", func, desc, codec->subtype_name);
1057 return false;
1058 }
1059 if (strcmp(*expect_pos, codec->subtype_name)) {
1060 BTW("%s: %s: ERROR: mismatch: in idx %d, expect %s, got %s", func, desc,
1061 (int)(expect_pos - expected_codecs), *expect_pos, codec->subtype_name);
1062 return false;
1063 }
1064 expect_pos++;
1065 }
1066 if (*expect_pos) {
1067 BTW("%s: %s: ERROR: mismatch: expected %s to be listed, but not found", func, desc, *expect_pos);
1068 return false;
1069 }
1070 return true;
1071}
1072
1073#define VALIDATE_SDP(GOT_SDP_STR, EXPECT_SDP_STR) do { \
1074 if (validate_sdp(__func__, t->desc, GOT_SDP_STR, EXPECT_SDP_STR)) { \
1075 btw("VALIDATE_SDP OK: " #GOT_SDP_STR " == " #EXPECT_SDP_STR " ==%s", strlist_name(EXPECT_SDP_STR)); \
1076 } else { \
1077 btw("Failed to validate SDP:\nexpected%s\ngot\n%s", \
1078 strlist_name(EXPECT_SDP_STR), GOT_SDP_STR); \
1079 OSMO_ASSERT(false); \
1080 } \
1081 } while (0)
1082
1083static bool validate_perm_speech(const char *func, const char *desc,
1084 const struct gsm0808_channel_type *ct,
1085 const enum gsm0808_permitted_speech perm_speech[])
1086{
1087 const enum gsm0808_permitted_speech *pos;
1088 const uint8_t *pos2 = ct->perm_spch;
1089 for (pos = perm_speech; *pos != LIST_END; pos++, pos2++) {
1090 if (pos2 - ct->perm_spch >= ct->perm_spch_len) {
1091 BTW("%s: %s: ERROR: mismatch: expected %s to be listed, but not found", func, desc,
1092 gsm0808_permitted_speech_name(*pos));
1093 return false;
1094 }
1095 if (*pos2 != *pos) {
1096 BTW("%s: %s: ERROR: mismatch: in idx %d, expect %s", func, desc,
1097 (int)(pos - perm_speech), gsm0808_permitted_speech_name(*pos));
1098 btw("in idx %d, got %s", (int)(pos - perm_speech), gsm0808_permitted_speech_name(*pos2));
1099 return false;
1100 }
1101 }
1102 if (pos2 - ct->perm_spch < ct->perm_spch_len) {
1103 BTW("%s: %s: ERROR: did not expect %s", func, desc, gsm0808_permitted_speech_name(*pos2));
1104 return false;
1105 }
1106 return true;
1107}
1108
1109#define VALIDATE_PERM_SPEECH(GOT_PERM_SPEECH, EXPECT_PERM_SPEECH) do { \
1110 if (validate_perm_speech(__func__, t->desc, GOT_PERM_SPEECH, EXPECT_PERM_SPEECH)) { \
1111 btw("VALIDATE_PERM_SPEECH OK: " #GOT_PERM_SPEECH " == " #EXPECT_PERM_SPEECH " ==%s", \
1112 perm_speech_name(EXPECT_PERM_SPEECH)); \
1113 } else { \
1114 btw("Failed to validate Permitted Speech:\nexpected%s", \
1115 perm_speech_name(EXPECT_PERM_SPEECH)); \
1116 btw("got:"); \
1117 int i; \
1118 for (i = 0; i < (GOT_PERM_SPEECH)->perm_spch_len; i++) { \
1119 btw("%s", gsm0808_permitted_speech_name((GOT_PERM_SPEECH)->perm_spch[i])); \
1120 } \
1121 OSMO_ASSERT(false); \
1122 } \
1123 } while (0)
1124
1125static struct sdp_msg *sdp_from_subtype_names(const char *const *subtype_names)
1126{
1127 static struct sdp_msg sdp;
1128 sdp = (struct sdp_msg){};
1129 const char *const *subtype_name;
1130 osmo_sockaddr_str_from_str(&sdp.rtp, "1.2.3.4", 56);
1131 for (subtype_name = subtype_names; *subtype_name; subtype_name++) {
1132 const struct codec_mapping *m = codec_mapping_by_subtype_name(*subtype_name);
1133 if (!m) {
1134 BTW("ERROR: unknown subtype_name: %s", *subtype_name);
1135 abort();
1136 }
1137 sdp_audio_codecs_add_copy(&sdp.audio_codecs, &m->sdp);
1138 }
1139 return &sdp;
1140}
1141
1142static int sdp_str_from_subtype_names(char *buf, size_t buflen, const char *const *subtype_names)
1143{
1144 if (!subtype_names[0]) {
1145 buf[0] = '\0';
1146 return 0;
1147 }
1148 return sdp_msg_to_sdp_str_buf(buf, buflen, sdp_from_subtype_names(subtype_names));
1149}
1150
1151static const char *bcap_hexstr(const enum gsm48_bcap_speech_ver ms_bcap[])
1152{
1153 struct gsm_mncc_bearer_cap bcap = {
1154 .transfer = GSM_MNCC_BCAP_SPEECH,
1155 .speech_ver = { -1 },
1156 };
1157 const enum gsm48_bcap_speech_ver *pos;
1158 for (pos = ms_bcap; *pos != LIST_END; pos++)
1159 bearer_cap_add_speech_ver(&bcap, *pos);
1160 bearer_cap_set_radio(&bcap);
1161 struct msgb *msg = msgb_alloc(128, "bcap");
1162 gsm48_encode_bearer_cap(msg, 0, &bcap);
1163 char *ret = osmo_hexdump_nospc(msg->data, msg->len);
1164 msgb_free(msg);
1165 return ret;
1166}
1167
1168static void test_codecs_mo(const struct codec_test *t)
1169{
1170 struct gsm_mncc mncc = {
1171 .imsi = IMSI,
1172 };
1173
1174 struct gsm_mncc_rtp *mncc_rtp = (void *)&mncc;
1175
1176 BTW("======================== MO call: %s", t->desc);
1177 btw("CM Service Request with Codec List (BSS Supported) =%s",
1178 codec_list_name(t->mo_rx_compl_l3_codec_list_bss_supported));
1179
1180 cm_service_result_sent = RES_NONE;
1181 ms_sends_compl_l3("052471"
1182 "03575886" /* classmark 2 */
1183 "089910070000106005" /* IMSI */,
1184 codec_list(t->mo_rx_compl_l3_codec_list_bss_supported));
1185 VERBOSE_ASSERT(cm_service_result_sent, == RES_ACCEPT, "%d");
1186 EXPECT_ACCEPTED(true);
1187
1188 btw("MS sends CC SETUP with Bearer Capability = %s",
1189 bcap_name(t->mo_rx_ms_bcap));
1190 expect_crcx(RTP_TO_CN);
1191 expect_crcx(RTP_TO_RAN);
1192 ms_sends_msgf("0385" /* CC, seq = 2 -> 0x80 | CC Setup = 0x5 */
1193 "%s" /* Bearer Capability */
1194 "5e038121f3" /* Called Number BCD */
1195 "15020100" /* CC Capabilities */
1196 "4008" /* Supported Codec List */
1197 "04026000" /* UMTS: AMR 2 | AMR */
1198 "00021f00" /* GSM: HR AMR | FR AMR | GSM EFR | GSM HR | GSM FR */,
1199 bcap_hexstr(t->mo_rx_ms_bcap)
1200 );
1201 OSMO_ASSERT(crcx_scheduled(RTP_TO_CN));
1202 OSMO_ASSERT(crcx_scheduled(RTP_TO_RAN));
1203
1204 btw("As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered");
1205 cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_IND);
1206 crcx_ok(RTP_TO_CN);
1207 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1208 mncc.callref = cc_to_mncc_tx_got_callref;
1209 VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mo_tx_sdp_mncc_setup_ind);
1210
1211 btw("MNCC replies with MNCC_RTP_CREATE, causing MGW endpoint CRCX to RAN");
1212 sdp_str_from_subtype_names(mncc_rtp->sdp, sizeof(mncc_rtp->sdp), t->mo_rx_sdp_mncc_rtp_create);
1213 mncc_sends_to_cc(MNCC_RTP_CREATE, &mncc);
1214
1215 btw("MGW acknowledges the CRCX, triggering Assignment with%s", perm_speech_name(t->mo_tx_assignment_perm_speech));
1216 expect_bssap_assignment();
1217 crcx_ok(RTP_TO_RAN);
1218 OSMO_ASSERT(bssap_assignment_sent);
1219 VALIDATE_PERM_SPEECH(&bssap_assignment_command_last_channel_type, t->mo_tx_assignment_perm_speech);
1220
1221 btw("Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC");
1222 cc_to_mncc_expect_tx("", MNCC_RTP_CREATE);
1223 ms_sends_assignment_complete(t->mo_rx_assigned_codec);
1224 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1225 VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mo_tx_sdp_mncc_rtp_create);
1226
1227 btw("MNCC says that's fine");
1228 dtap_expect_tx("8302" /* CC: Call Proceeding */);
1229 mncc_sends_to_cc(MNCC_CALL_PROC_REQ, &mncc);
1230 OSMO_ASSERT(dtap_tx_confirmed);
1231
1232 fake_time_passes(1, 23);
1233
1234 btw("The other call leg got established (not shown here), MNCC tells us so, with codecs {%s }",
1235 strlist_name(t->mo_rx_sdp_mncc_alert_req));
1236 dtap_expect_tx("8301" /* CC: Call Alerting */);
1237 sdp_str_from_subtype_names(mncc.sdp, sizeof(mncc.sdp), t->mo_rx_sdp_mncc_alert_req);
1238 mncc_sends_to_cc(MNCC_ALERT_REQ, &mncc);
1239 OSMO_ASSERT(dtap_tx_confirmed);
1240
1241 dtap_expect_tx("8307" /* CC: Connect */);
1242 sdp_str_from_subtype_names(mncc.sdp, sizeof(mncc.sdp), t->mo_rx_sdp_mncc_setup_rsp);
1243 mncc_sends_to_cc(MNCC_SETUP_RSP, &mncc);
1244 OSMO_ASSERT(dtap_tx_confirmed);
1245
1246 fake_time_passes(1, 23);
1247
1248 cc_to_mncc_expect_tx("", MNCC_SETUP_COMPL_IND);
1249 ms_sends_msg("03cf" /* CC: Connect Acknowledge */);
1250 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1251 VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mo_tx_sdp_mncc_setup_compl_ind);
1252
1253 BTW("RTP stream goes ahead, not shown here.");
1254 fake_time_passes(123, 45);
1255
1256 BTW("Call ends");
1257 cc_to_mncc_expect_tx("", MNCC_DISC_IND);
1258 ms_sends_msg("032502e090" /* CC: Disconnect, cause: Normal Call Clearing */);
1259 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1260
1261 dtap_expect_tx("832d" /* CC: Release */);
1262 mncc_sends_to_cc(MNCC_REL_REQ, &mncc);
1263 OSMO_ASSERT(dtap_tx_confirmed);
1264
1265 cc_to_mncc_expect_tx("", MNCC_REL_CNF);
1266 expect_bssap_clear();
1267 ms_sends_msg("036a" /* CC: Release Complete */);
1268 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1269 OSMO_ASSERT(bssap_clear_sent);
1270
1271 ran_sends_clear_complete();
1272 EXPECT_CONN_COUNT(0);
1273 BTW("======================== SUCCESS: MO call: %s", t->desc);
1274}
1275
1276static void test_codecs_mt(const struct codec_test *t)
1277{
1278 struct gsm_mncc mncc = {
1279 .imsi = IMSI,
1280 .callref = 0x423,
1281 .fields = MNCC_F_BEARER_CAP,
1282 .bearer_cap = {
1283 .speech_ver = { GSM48_BCAP_SV_FR, -1, },
1284 },
1285 };
1286 struct gsm_mncc_rtp *mncc_rtp = (void *)&mncc;
1287
1288 BTW("======================== MT call: %s", t->desc);
1289
1290 BTW("MNCC asks us to setup a call, causing Paging");
1291
1292 paging_expect_imsi(IMSI);
1293 paging_sent = false;
1294 sdp_str_from_subtype_names(mncc.sdp, sizeof(mncc.sdp), t->mt_rx_sdp_mncc_setup_req);
1295 mncc_sends_to_cc(MNCC_SETUP_REQ, &mncc);
1296 mncc.sdp[0] = '\0';
1297
1298 VERBOSE_ASSERT(paging_sent, == true, "%d");
1299
1300 btw("MS replies with Paging Response, with Codec List (BSS Supported) =%s",
1301 codec_list_name(t->mt_rx_compl_l3_codec_list_bss_supported));
1302
1303 if (t->expect_codec_mismatch_on_paging_response) {
1304 btw("VLR accepts, but MSC notices a codec mismatch and aborts");
1305 cc_to_mncc_expect_tx("", MNCC_REL_IND);
1306 expect_bssap_clear();
1307 ms_sends_compl_l3("062707"
1308 "03575886" /* classmark 2 */
1309 "089910070000106005" /* IMSI */,
1310 codec_list(t->mt_rx_compl_l3_codec_list_bss_supported));
1311 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1312 OSMO_ASSERT(bssap_clear_sent);
1313
1314 ran_sends_clear_complete();
1315 EXPECT_CONN_COUNT(0);
1316
1317 BTW("======================== SUCCESS: MT call: %s", t->desc);
1318 return;
1319 }
1320
1321 btw("VLR accepts, MSC sends CC Setup with Bearer Capability = %s",
1322 bcap_name(t->mt_tx_cc_setup_bcap));
1323 char *cc_setup_bcap = talloc_asprintf(msc_vlr_tests_ctx, "0305%s",
1324 bcap_hexstr(t->mt_tx_cc_setup_bcap));
1325 dtap_expect_tx(cc_setup_bcap);
1326 ms_sends_compl_l3("062707"
1327 "03575886" /* classmark 2 */
1328 "089910070000106005" /* IMSI */,
1329 codec_list(t->mt_rx_compl_l3_codec_list_bss_supported));
1330 OSMO_ASSERT(dtap_tx_confirmed);
1331 talloc_free(cc_setup_bcap);
1332
1333 btw("MS confirms call, we create a RAN-side RTP and forward MNCC_CALL_CONF_IND");
1334 expect_crcx(RTP_TO_CN);
1335 expect_crcx(RTP_TO_RAN);
1336 cc_to_mncc_expect_tx(IMSI, MNCC_CALL_CONF_IND);
1337 ms_sends_msgf("8348" /* CC: Call Confirmed */
1338 "%s" /* Bearer Capability */
1339 "15020100" /* Call Control Capabilities */
1340 "40080402600400021f00" /* Supported Codec List */,
1341 bcap_hexstr(t->mt_rx_ms_bcap)
1342 );
1343 OSMO_ASSERT(crcx_scheduled(RTP_TO_CN));
1344 OSMO_ASSERT(crcx_scheduled(RTP_TO_RAN));
1345 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1346 VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mt_tx_sdp_mncc_call_conf_ind);
1347
1348 btw("MGW acknowledges the CRCX to RAN, triggering Assignment with%s", perm_speech_name(t->mt_tx_assignment_perm_speech));
1349
1350 if (t->expect_codec_mismatch_on_cc_call_conf) {
1351 btw("MS Bearer Capability leads to a codec mismatch, Assignment aborts");
1352
1353 dtap_expect_tx("032d0802e1af" /* CC Release */);
1354 cc_to_mncc_expect_tx("", MNCC_REL_IND);
1355 expect_bssap_clear();
1356 crcx_ok(RTP_TO_RAN);
1357
1358 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1359 OSMO_ASSERT(bssap_clear_sent);
1360
1361 ran_sends_clear_complete();
1362 EXPECT_CONN_COUNT(0);
1363 BTW("======================== SUCCESS: MT call: %s", t->desc);
1364 return;
1365 }
1366
1367 expect_bssap_assignment();
1368 crcx_ok(RTP_TO_RAN);
1369 OSMO_ASSERT(bssap_assignment_sent);
1370 VALIDATE_PERM_SPEECH(&bssap_assignment_command_last_channel_type, t->mt_tx_assignment_perm_speech);
1371
1372 btw("Assignment completes, triggering CRCX to CN");
1373 ms_sends_assignment_complete(t->mt_rx_assigned_codec);
1374
1375 btw("MNCC sends MNCC_RTP_CREATE, which first waits for the CN side RTP");
1376 sdp_str_from_subtype_names(mncc_rtp->sdp, sizeof(mncc_rtp->sdp), t->mt_rx_sdp_mncc_rtp_create);
1377 mncc_sends_to_cc(MNCC_RTP_CREATE, &mncc);
1378
1379 btw("When the CN side RTP address is known, ack MNCC_RTP_CREATE");
1380 cc_to_mncc_expect_tx("", MNCC_RTP_CREATE);
1381 crcx_ok(RTP_TO_CN);
1382 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1383 VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mt_tx_sdp_mncc_rtp_create);
1384
1385 fake_time_passes(1, 23);
1386
1387 cc_to_mncc_expect_tx("", MNCC_ALERT_IND);
1388 ms_sends_msg("8381" /* CC: Alerting */);
1389 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1390 VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mt_tx_sdp_mncc_alert_ind);
1391
1392 fake_time_passes(1, 23);
1393
1394 cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_CNF);
1395 ms_sends_msg("83c7" /* CC: Connect */);
1396 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1397 VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mt_tx_sdp_mncc_setup_cnf);
1398
1399 dtap_expect_tx("030f" /* CC: Connect Acknowledge */);
1400 sdp_str_from_subtype_names(mncc.sdp, sizeof(mncc.sdp), t->mt_rx_sdp_mncc_setup_compl_req);
1401 mncc_sends_to_cc(MNCC_SETUP_COMPL_REQ, &mncc);
1402
1403 BTW("RTP stream goes ahead, not shown here.");
1404 fake_time_passes(123, 45);
1405
1406 BTW("Call ends");
1407 cc_to_mncc_expect_tx("", MNCC_DISC_IND);
1408 ms_sends_msg("832502e090" /* CC: Disconnect, cause: Normal Call Clearing */);
1409 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1410
1411 dtap_expect_tx("032d" /* CC: Release */);
1412 mncc_sends_to_cc(MNCC_REL_REQ, &mncc);
1413 OSMO_ASSERT(dtap_tx_confirmed);
1414
1415 cc_to_mncc_expect_tx("", MNCC_REL_CNF);
1416 expect_bssap_clear();
1417 ms_sends_msg("836a" /* CC: Release Complete */);
1418 OSMO_ASSERT(cc_to_mncc_tx_confirmed);
1419 OSMO_ASSERT(bssap_clear_sent);
1420
1421 ran_sends_clear_complete();
1422 EXPECT_CONN_COUNT(0);
1423 BTW("======================== SUCCESS: MT call: %s", t->desc);
1424}
1425
1426static void test_codecs(void)
1427{
1428 const struct codec_test *t;
1429 clear_vlr();
1430
1431 comment_start();
1432
1433 fake_time_start();
1434
1435 lu_geran_noauth();
1436
1437 for (t = codec_tests; t - codec_tests < ARRAY_SIZE(codec_tests); t++) {
1438 test_codecs_mo(t);
1439 test_codecs_mt(t);
1440 }
1441
1442 EXPECT_CONN_COUNT(0);
1443 clear_vlr();
1444 comment_end();
1445}
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +01001446
Neels Hofmeyra99b4272017-11-21 17:13:23 +01001447msc_vlr_test_func_t msc_vlr_tests[] = {
1448 test_call_mo,
1449 test_call_mt,
Neels Hofmeyrcbcf89c2018-03-13 17:52:07 +01001450 test_call_mt2,
Neels Hofmeyreb1cfdb2018-03-15 13:42:10 +01001451 test_call_mo_to_unknown,
1452 test_call_mo_to_unknown_timeout,
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +01001453 test_codecs,
Neels Hofmeyra99b4272017-11-21 17:13:23 +01001454 NULL
1455};