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