blob: b0605f10429a86e2c426aa183e493017529d988f [file] [log] [blame]
Neels Hofmeyr6a29d322017-01-25 15:04:16 +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#pragma once
25
26#include <stdbool.h>
27#include <stdio.h>
28
Alexander Couzens8b7d7852021-11-05 01:52:05 +010029#include <osmocom/crypt/utran_cipher.h>
Neels Hofmeyr90843962017-09-04 15:04:35 +020030#include <osmocom/msc/gsm_data.h>
Neels Hofmeyr90843962017-09-04 15:04:35 +020031#include <osmocom/msc/vlr.h>
Neels Hofmeyrc4628a32018-12-07 14:47:34 +010032#include <osmocom/msc/msub.h>
33#include <osmocom/msc/msc_a.h>
Neels Hofmeyra99b4272017-11-21 17:13:23 +010034#include <osmocom/msc/mncc.h>
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +020035#include <osmocom/msc/call_leg.h>
36#include <osmocom/msc/rtp_stream.h>
Neels Hofmeyr6a29d322017-01-25 15:04:16 +010037
38extern bool _log_lines;
Neels Hofmeyr35fb6792019-10-21 06:06:27 +020039#define LOG_COLOR "\033[1;33m"
40#define LOG_COLOR_OFF "\033[0;m"
41
Neels Hofmeyr6a29d322017-01-25 15:04:16 +010042#define _log(fmt, args...) do { \
43 if (_log_lines) \
Neels Hofmeyr35fb6792019-10-21 06:06:27 +020044 fprintf(stderr, LOG_COLOR " %4d:%s: " fmt LOG_COLOR_OFF "\n", \
Neels Hofmeyr6a29d322017-01-25 15:04:16 +010045 __LINE__, __FILE__, ## args ); \
46 else \
47 fprintf(stderr, fmt "\n", ## args ); \
48 } while (false)
49
50/* btw means "by the way", the test tells the log what's happening.
51 * BTW() marks a larger section, btw() is the usual logging. */
Neels Hofmeyrc4628a32018-12-07 14:47:34 +010052#define BTW(fmt, args...) _log("\n\n- " fmt, ## args )
Neels Hofmeyr6a29d322017-01-25 15:04:16 +010053#define btw(fmt, args...) _log("- " fmt, ## args )
54#define log(fmt, args...) _log(" " fmt, ## args )
55
Neels Hofmeyrdfdc61d2018-03-02 00:40:58 +010056#define comment_start() fprintf(stderr, "===== %s\n", __func__);
57#define comment_end() fprintf(stderr, "===== %s: SUCCESS\n\n", __func__);
Neels Hofmeyr6a29d322017-01-25 15:04:16 +010058
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +010059extern void *msc_vlr_tests_ctx;
60
Neels Hofmeyrc4628a32018-12-07 14:47:34 +010061extern struct msub *g_msub;
Neels Hofmeyr6a29d322017-01-25 15:04:16 +010062extern struct gsm_network *net;
Neels Hofmeyr6a29d322017-01-25 15:04:16 +010063extern void *msgb_ctx;
64
Neels Hofmeyr7814a832018-12-26 00:40:18 +010065extern enum osmo_rat_type rx_from_ran;
Neels Hofmeyr6a29d322017-01-25 15:04:16 +010066
67extern const char *gsup_tx_expected;
68extern bool gsup_tx_confirmed;
69
70extern struct msgb *dtap_tx_expected;
71extern bool dtap_tx_confirmed;
72
73enum result_sent {
74 RES_NONE = 0,
75 RES_ACCEPT = 1,
76 RES_REJECT = 2,
77};
78extern enum result_sent lu_result_sent;
79extern enum result_sent cm_service_result_sent;
80
81extern bool auth_request_sent;
82extern const char *auth_request_expect_rand;
83extern const char *auth_request_expect_autn;
84
85extern bool cipher_mode_cmd_sent;
86extern bool cipher_mode_cmd_sent_with_imeisv;
Neels Hofmeyrdbabfd32018-03-10 02:06:47 +010087extern const char *cipher_mode_expect_kc;
88
89extern bool security_mode_ctrl_sent;
90extern const char *security_mode_expect_ck;
91extern const char *security_mode_expect_ik;
92
93static inline void expect_cipher_mode_cmd(const char *kc)
94{
95 cipher_mode_cmd_sent = false;
96 cipher_mode_expect_kc = kc;
97 /* make sure we don't mix up the two */
98 security_mode_ctrl_sent = false;
99}
100
101static inline void expect_security_mode_ctrl(const char *ck, const char *ik)
102{
103 security_mode_ctrl_sent = false;
104 security_mode_expect_ck = ck;
105 security_mode_expect_ik = ik;
106 /* make sure we don't mix up the two */
107 cipher_mode_cmd_sent = false;
108}
Neels Hofmeyr6a29d322017-01-25 15:04:16 +0100109
110extern bool paging_sent;
Neels Hofmeyr6a29d322017-01-25 15:04:16 +0100111
Philipp Maierfbf66102017-04-09 12:32:51 +0200112extern bool iu_release_expected;
113extern bool iu_release_sent;
114extern bool bssap_clear_expected;
115extern bool bssap_clear_sent;
116
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100117extern uint32_t cc_to_mncc_tx_expected_msg_type;
118extern const char *cc_to_mncc_tx_expected_imsi;
119extern bool cc_to_mncc_tx_confirmed;
120extern uint32_t cc_to_mncc_tx_got_callref;
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +0100121extern char cc_to_mncc_tx_last_sdp[1024];
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100122
Neels Hofmeyrcbcf89c2018-03-13 17:52:07 +0100123extern struct gsm_mncc *on_call_release_mncc_sends_to_cc_data;
124
Philipp Maierfbf66102017-04-09 12:32:51 +0200125static inline void expect_iu_release()
126{
127 iu_release_expected = true;
128 iu_release_sent = false;
129}
130
131static inline void expect_bssap_clear()
132{
133 bssap_clear_expected = true;
134 bssap_clear_sent = false;
135}
136
Neels Hofmeyr7814a832018-12-26 00:40:18 +0100137static inline void expect_release_clear(enum osmo_rat_type via_ran)
Philipp Maierfbf66102017-04-09 12:32:51 +0200138{
139 switch (via_ran) {
Neels Hofmeyr7814a832018-12-26 00:40:18 +0100140 case OSMO_RAT_GERAN_A:
Philipp Maierfbf66102017-04-09 12:32:51 +0200141 expect_bssap_clear();
142 return;
Neels Hofmeyr7814a832018-12-26 00:40:18 +0100143 case OSMO_RAT_UTRAN_IU:
Philipp Maierfbf66102017-04-09 12:32:51 +0200144 expect_iu_release();
145 return;
146 default:
147 OSMO_ASSERT(false);
148 break;
149 }
150}
151
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200152extern bool bssap_assignment_expected;
153extern bool bssap_assignment_sent;
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +0100154extern struct gsm0808_channel_type bssap_assignment_command_last_channel_type;
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200155extern bool iu_rab_assignment_expected;
156extern bool iu_rab_assignment_sent;
157
158static inline void expect_bssap_assignment()
159{
160 bssap_assignment_expected = true;
161 bssap_assignment_sent = false;
162}
163
164static inline void expect_iu_rab_assignment()
165{
166 iu_rab_assignment_expected = true;
167 iu_rab_assignment_sent = false;
168}
169
Neels Hofmeyr6a29d322017-01-25 15:04:16 +0100170struct msc_vlr_test_cmdline_opts {
171 bool verbose;
172 int run_test_nr;
173};
174
Neels Hofmeyrdfdc61d2018-03-02 00:40:58 +0100175typedef void (* msc_vlr_test_func_t )(void);
Neels Hofmeyr6a29d322017-01-25 15:04:16 +0100176extern msc_vlr_test_func_t msc_vlr_tests[];
177
178struct msgb *msgb_from_hex(const char *label, uint16_t size, const char *hex);
179
180void clear_vlr();
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100181bool conn_exists(const struct msub *msub);
182void conn_conclude_cm_service_req(struct msub *msub, const char *cm_service_use);
Neels Hofmeyr6a29d322017-01-25 15:04:16 +0100183
184void dtap_expect_tx(const char *hex);
185void dtap_expect_tx_ussd(char *ussd_text);
186void paging_expect_imsi(const char *imsi);
187void paging_expect_tmsi(uint32_t tmsi);
188
189void ms_sends_msg(const char *hex);
Neels Hofmeyr3c323dc2022-01-14 03:35:08 +0100190void ms_sends_msgf(const char *fmt, ...);
191void ms_sends_compl_l3(const char *hex, const struct gsm0808_speech_codec_list *codec_list_bss_supported);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100192void ms_sends_classmark_update(const struct osmo_gsm48_classmark *classmark);
193void ms_sends_ciphering_mode_complete(const char *inner_nas_msg);
Alexander Couzens2aaff752021-10-19 17:09:11 +0200194void ms_sends_security_mode_complete(uint8_t utran_encryption);
Neels Hofmeyrcec51b32023-03-01 03:47:45 +0100195void ms_sends_assignment_complete(const char *sdp_codec_name);
Neels Hofmeyr6a29d322017-01-25 15:04:16 +0100196void gsup_rx(const char *rx_hex, const char *expect_tx_hex);
197void send_sms(struct vlr_subscr *receiver,
198 struct vlr_subscr *sender,
199 char *str);
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200200void crcx_ok(enum rtp_direction dir);
Neels Hofmeyr6a29d322017-01-25 15:04:16 +0100201
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100202void ran_sends_clear_complete();
Neels Hofmeyr4068ab22018-04-01 20:55:54 +0200203
Neels Hofmeyr6a29d322017-01-25 15:04:16 +0100204void thwart_rx_non_initial_requests();
205
Neels Hofmeyr6a29d322017-01-25 15:04:16 +0100206#define EXPECT_ACCEPTED(expect_accepted) do { \
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100207 if (g_msub) \
208 OSMO_ASSERT(conn_exists(g_msub)); \
209 bool accepted = msc_a_is_accepted(msub_msc_a(g_msub)); \
210 fprintf(stderr, "msc_a_is_accepted() == %s\n", \
Neels Hofmeyr6a29d322017-01-25 15:04:16 +0100211 accepted ? "true" : "false"); \
212 OSMO_ASSERT(accepted == expect_accepted); \
213 } while (false)
214
Maxbb53a3f2018-12-17 17:09:17 +0100215#define VAL_ASSERT(desc, val, expect_op, fmt) \
Neels Hofmeyr6a29d322017-01-25 15:04:16 +0100216 do { \
Maxbb53a3f2018-12-17 17:09:17 +0100217 log(desc " == " fmt, (val)); \
Neels Hofmeyr6a29d322017-01-25 15:04:16 +0100218 OSMO_ASSERT((val) expect_op); \
Maxbb53a3f2018-12-17 17:09:17 +0100219 } while (0)
220
221#define VERBOSE_ASSERT(val, expect_op, fmt) VAL_ASSERT(#val, val, expect_op, fmt)
Neels Hofmeyr6a29d322017-01-25 15:04:16 +0100222
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100223#define EXPECT_CONN_COUNT(N) VERBOSE_ASSERT(llist_count(&msub_list), == N, "%d")
Neels Hofmeyr6a29d322017-01-25 15:04:16 +0100224
225#define gsup_expect_tx(hex) do \
226{ \
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200227 if (gsup_tx_expected) { \
228 log("Previous expected GSUP tx was not confirmed!"); \
229 OSMO_ASSERT(!gsup_tx_expected); \
230 } \
Neels Hofmeyr6a29d322017-01-25 15:04:16 +0100231 if (!hex) \
232 break; \
233 gsup_tx_expected = hex; \
234 gsup_tx_confirmed = false; \
235} while (0)
236
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100237#define cc_to_mncc_expect_tx(imsi, msg_type) do \
238{ \
239 if (cc_to_mncc_tx_expected_msg_type) { \
240 log("Previous expected MNCC tx was not confirmed!"); \
241 OSMO_ASSERT(!cc_to_mncc_tx_expected_msg_type); \
242 } \
243 cc_to_mncc_tx_expected_imsi = imsi; \
244 cc_to_mncc_tx_expected_msg_type = msg_type; \
245 cc_to_mncc_tx_confirmed = false; \
246} while (0)
247
Neels Hofmeyr6a29d322017-01-25 15:04:16 +0100248void fake_time_start();
249
250/* as macro to get the test file's source line number */
251#define fake_time_passes(secs, usecs) do \
252{ \
253 struct timeval diff; \
254 osmo_gettimeofday_override_add(secs, usecs); \
Stefan Sperlingdefc3c82018-05-15 14:48:04 +0200255 osmo_clock_override_add(CLOCK_MONOTONIC, secs, usecs * 1000); \
Neels Hofmeyr6a29d322017-01-25 15:04:16 +0100256 timersub(&osmo_gettimeofday_override_time, &fake_time_start_time, &diff); \
257 btw("Total time passed: %d.%06d s", \
258 (int)diff.tv_sec, (int)diff.tv_usec); \
259 osmo_timers_prepare(); \
260 osmo_timers_update(); \
261} while (0)
262
263extern const struct timeval fake_time_start_time;
Neels Hofmeyr4068ab22018-04-01 20:55:54 +0200264
265#define ASSERT_RELEASE_CLEAR(via_ran) \
266 switch (via_ran) { \
Neels Hofmeyr7814a832018-12-26 00:40:18 +0100267 case OSMO_RAT_GERAN_A: \
Neels Hofmeyr4068ab22018-04-01 20:55:54 +0200268 VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); \
269 break; \
Neels Hofmeyr7814a832018-12-26 00:40:18 +0100270 case OSMO_RAT_UTRAN_IU: \
Neels Hofmeyr4068ab22018-04-01 20:55:54 +0200271 VERBOSE_ASSERT(iu_release_sent, == true, "%d"); \
272 break; \
273 default: \
274 OSMO_ASSERT(false); \
275 break; \
276 }
277
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100278#define HLR_TO_VLR "0a0101"
279#define VLR_TO_HLR "0a0101"
Neels Hofmeyr63b24642019-12-12 01:31:04 +0100280#define CN_DOMAIN "280102"
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100281#define EUSE_TO_MSC_USSD "0a0103"
282#define MSC_USSD_TO_EUSE "0a0103"
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200283
Neels Hofmeyr3f391dd2019-08-29 03:53:11 +0200284void expect_crcx(enum rtp_direction towards);
Neels Hofmeyr81938fd2022-01-14 03:39:58 +0100285bool crcx_scheduled(enum rtp_direction towards);