blob: f7ff94002148be056c1bd269325f921b81b5b649 [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
Neels Hofmeyr90843962017-09-04 15:04:35 +020029#include <osmocom/msc/gsm_data.h>
Neels Hofmeyr90843962017-09-04 15:04:35 +020030#include <osmocom/msc/vlr.h>
Neels Hofmeyra99b4272017-11-21 17:13:23 +010031#include <osmocom/msc/mncc.h>
Neels Hofmeyr6a29d322017-01-25 15:04:16 +010032
33extern bool _log_lines;
34#define _log(fmt, args...) do { \
35 if (_log_lines) \
36 fprintf(stderr, " %4d:%s: " fmt "\n", \
37 __LINE__, __FILE__, ## args ); \
38 else \
39 fprintf(stderr, fmt "\n", ## args ); \
40 } while (false)
41
42/* btw means "by the way", the test tells the log what's happening.
43 * BTW() marks a larger section, btw() is the usual logging. */
44#define BTW(fmt, args...) _log("---\n- " fmt, ## args )
45#define btw(fmt, args...) _log("- " fmt, ## args )
46#define log(fmt, args...) _log(" " fmt, ## args )
47
Neels Hofmeyrdfdc61d2018-03-02 00:40:58 +010048#define comment_start() fprintf(stderr, "===== %s\n", __func__);
49#define comment_end() fprintf(stderr, "===== %s: SUCCESS\n\n", __func__);
Neels Hofmeyr6a29d322017-01-25 15:04:16 +010050
Neels Hofmeyrc036b792018-11-29 22:37:51 +010051extern struct ran_conn *g_conn;
Neels Hofmeyr6a29d322017-01-25 15:04:16 +010052extern struct gsm_network *net;
53extern struct gsm_bts *the_bts;
54extern void *msgb_ctx;
55
56extern enum ran_type rx_from_ran;
57
58extern const char *gsup_tx_expected;
59extern bool gsup_tx_confirmed;
60
61extern struct msgb *dtap_tx_expected;
62extern bool dtap_tx_confirmed;
63
64enum result_sent {
65 RES_NONE = 0,
66 RES_ACCEPT = 1,
67 RES_REJECT = 2,
68};
69extern enum result_sent lu_result_sent;
70extern enum result_sent cm_service_result_sent;
71
72extern bool auth_request_sent;
73extern const char *auth_request_expect_rand;
74extern const char *auth_request_expect_autn;
75
76extern bool cipher_mode_cmd_sent;
77extern bool cipher_mode_cmd_sent_with_imeisv;
Neels Hofmeyrdbabfd32018-03-10 02:06:47 +010078extern const char *cipher_mode_expect_kc;
79
80extern bool security_mode_ctrl_sent;
81extern const char *security_mode_expect_ck;
82extern const char *security_mode_expect_ik;
83
84static inline void expect_cipher_mode_cmd(const char *kc)
85{
86 cipher_mode_cmd_sent = false;
87 cipher_mode_expect_kc = kc;
88 /* make sure we don't mix up the two */
89 security_mode_ctrl_sent = false;
90}
91
92static inline void expect_security_mode_ctrl(const char *ck, const char *ik)
93{
94 security_mode_ctrl_sent = false;
95 security_mode_expect_ck = ck;
96 security_mode_expect_ik = ik;
97 /* make sure we don't mix up the two */
98 cipher_mode_cmd_sent = false;
99}
Neels Hofmeyr6a29d322017-01-25 15:04:16 +0100100
101extern bool paging_sent;
102extern bool paging_stopped;
103
Philipp Maierfbf66102017-04-09 12:32:51 +0200104extern bool iu_release_expected;
105extern bool iu_release_sent;
106extern bool bssap_clear_expected;
107extern bool bssap_clear_sent;
108
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100109extern uint32_t cc_to_mncc_tx_expected_msg_type;
110extern const char *cc_to_mncc_tx_expected_imsi;
111extern bool cc_to_mncc_tx_confirmed;
112extern uint32_t cc_to_mncc_tx_got_callref;
113
Neels Hofmeyrcbcf89c2018-03-13 17:52:07 +0100114extern struct gsm_mncc *on_call_release_mncc_sends_to_cc_data;
115
Philipp Maierfbf66102017-04-09 12:32:51 +0200116static inline void expect_iu_release()
117{
118 iu_release_expected = true;
119 iu_release_sent = false;
120}
121
122static inline void expect_bssap_clear()
123{
124 bssap_clear_expected = true;
125 bssap_clear_sent = false;
126}
127
128static inline void expect_release_clear(enum ran_type via_ran)
129{
130 switch (via_ran) {
131 case RAN_GERAN_A:
132 expect_bssap_clear();
133 return;
134 case RAN_UTRAN_IU:
135 expect_iu_release();
136 return;
137 default:
138 OSMO_ASSERT(false);
139 break;
140 }
141}
142
Neels Hofmeyr6a29d322017-01-25 15:04:16 +0100143struct msc_vlr_test_cmdline_opts {
144 bool verbose;
145 int run_test_nr;
146};
147
Neels Hofmeyrdfdc61d2018-03-02 00:40:58 +0100148typedef void (* msc_vlr_test_func_t )(void);
Neels Hofmeyr6a29d322017-01-25 15:04:16 +0100149extern msc_vlr_test_func_t msc_vlr_tests[];
150
151struct msgb *msgb_from_hex(const char *label, uint16_t size, const char *hex);
152
153void clear_vlr();
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100154bool conn_exists(const struct ran_conn *conn);
155void conn_conclude_cm_service_req(struct ran_conn *conn,
Vadim Yanitskiy27605852018-06-15 23:57:30 +0700156 enum ran_type via_ran);
Neels Hofmeyr6a29d322017-01-25 15:04:16 +0100157
158void dtap_expect_tx(const char *hex);
159void dtap_expect_tx_ussd(char *ussd_text);
160void paging_expect_imsi(const char *imsi);
161void paging_expect_tmsi(uint32_t tmsi);
162
Neels Hofmeyr3117b702018-09-13 03:23:07 +0200163void bss_sends_bssap_mgmt(const char *hex);
Neels Hofmeyr6a29d322017-01-25 15:04:16 +0100164void ms_sends_msg(const char *hex);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200165void ms_sends_security_mode_complete();
Neels Hofmeyr6a29d322017-01-25 15:04:16 +0100166void gsup_rx(const char *rx_hex, const char *expect_tx_hex);
167void send_sms(struct vlr_subscr *receiver,
168 struct vlr_subscr *sender,
169 char *str);
170
Neels Hofmeyr4068ab22018-04-01 20:55:54 +0200171void bss_sends_clear_complete();
172void rnc_sends_release_complete();
173
Neels Hofmeyr6a29d322017-01-25 15:04:16 +0100174void thwart_rx_non_initial_requests();
175
Neels Hofmeyr6a29d322017-01-25 15:04:16 +0100176#define EXPECT_ACCEPTED(expect_accepted) do { \
177 if (g_conn) \
178 OSMO_ASSERT(conn_exists(g_conn)); \
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100179 bool accepted = ran_conn_is_accepted(g_conn); \
180 fprintf(stderr, "ran_conn_is_accepted() == %s\n", \
Neels Hofmeyr6a29d322017-01-25 15:04:16 +0100181 accepted ? "true" : "false"); \
182 OSMO_ASSERT(accepted == expect_accepted); \
183 } while (false)
184
185#define VERBOSE_ASSERT(val, expect_op, fmt) \
186 do { \
187 log(#val " == " fmt, (val)); \
188 OSMO_ASSERT((val) expect_op); \
189 } while (0);
190
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100191#define EXPECT_CONN_COUNT(N) VERBOSE_ASSERT(llist_count(&net->ran_conns), == N, "%d")
Neels Hofmeyr6a29d322017-01-25 15:04:16 +0100192
193#define gsup_expect_tx(hex) do \
194{ \
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200195 if (gsup_tx_expected) { \
196 log("Previous expected GSUP tx was not confirmed!"); \
197 OSMO_ASSERT(!gsup_tx_expected); \
198 } \
Neels Hofmeyr6a29d322017-01-25 15:04:16 +0100199 if (!hex) \
200 break; \
201 gsup_tx_expected = hex; \
202 gsup_tx_confirmed = false; \
203} while (0)
204
Neels Hofmeyra99b4272017-11-21 17:13:23 +0100205#define cc_to_mncc_expect_tx(imsi, msg_type) do \
206{ \
207 if (cc_to_mncc_tx_expected_msg_type) { \
208 log("Previous expected MNCC tx was not confirmed!"); \
209 OSMO_ASSERT(!cc_to_mncc_tx_expected_msg_type); \
210 } \
211 cc_to_mncc_tx_expected_imsi = imsi; \
212 cc_to_mncc_tx_expected_msg_type = msg_type; \
213 cc_to_mncc_tx_confirmed = false; \
214} while (0)
215
Neels Hofmeyr6a29d322017-01-25 15:04:16 +0100216void fake_time_start();
217
218/* as macro to get the test file's source line number */
219#define fake_time_passes(secs, usecs) do \
220{ \
221 struct timeval diff; \
222 osmo_gettimeofday_override_add(secs, usecs); \
Stefan Sperlingdefc3c82018-05-15 14:48:04 +0200223 osmo_clock_override_add(CLOCK_MONOTONIC, secs, usecs * 1000); \
Neels Hofmeyr6a29d322017-01-25 15:04:16 +0100224 timersub(&osmo_gettimeofday_override_time, &fake_time_start_time, &diff); \
225 btw("Total time passed: %d.%06d s", \
226 (int)diff.tv_sec, (int)diff.tv_usec); \
227 osmo_timers_prepare(); \
228 osmo_timers_update(); \
229} while (0)
230
231extern const struct timeval fake_time_start_time;
Neels Hofmeyr4068ab22018-04-01 20:55:54 +0200232
233#define ASSERT_RELEASE_CLEAR(via_ran) \
234 switch (via_ran) { \
235 case RAN_GERAN_A: \
236 VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); \
237 break; \
238 case RAN_UTRAN_IU: \
239 VERBOSE_ASSERT(iu_release_sent, == true, "%d"); \
240 break; \
241 default: \
242 OSMO_ASSERT(false); \
243 break; \
244 }
245
246static inline void bss_rnc_sends_release_clear_complete(enum ran_type via_ran)
247{
248 switch (via_ran) {
249 case RAN_GERAN_A:
250 bss_sends_clear_complete();
251 return;
252 case RAN_UTRAN_IU:
253 rnc_sends_release_complete();
254 return;
255 default:
256 OSMO_ASSERT(false);
257 break;
258 }
259}