blob: 77d3173e2c3c9fe0fb92d0237a578778f86e3721 [file] [log] [blame]
Neels Hofmeyr9cd1e742017-10-04 03:15:47 +02001/*
2 * (C) 2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
Harald Weltee08da972017-11-13 01:00:26 +09003 * Author: Neels Hofmeyr <nhofmeyr@sysmocom.de>
Neels Hofmeyr9cd1e742017-10-04 03:15:47 +02004 * All Rights Reserved
5 *
Harald Weltee08da972017-11-13 01:00:26 +09006 * SPDX-License-Identifier: GPL-2.0+
Neels Hofmeyr9cd1e742017-10-04 03:15:47 +02007 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
Neels Hofmeyr9cd1e742017-10-04 03:15:47 +020018 */
19
20#include <stdio.h>
Neels Hofmeyr721aa6d2018-02-20 21:38:00 +010021#include <errno.h>
22#include <strings.h>
Harald Weltede1da352018-10-08 22:27:04 +020023#include <string.h>
Neels Hofmeyr9cd1e742017-10-04 03:15:47 +020024
25#include <osmocom/gsm/gsm23003.h>
Harald Weltede1da352018-10-08 22:27:04 +020026#include <osmocom/gsm/protocol/gsm_23_003.h>
Neels Hofmeyr9cd1e742017-10-04 03:15:47 +020027#include <osmocom/core/utils.h>
28
29#define BOOL_STR(b) ((b)? "true" : "false")
30
31static struct {
32 const char *imsi;
33 bool expect_ok;
34} test_imsis[] = {
35 { "", false },
36 { " ", false },
37 { "1", false },
38 { "123", false },
39 { "12345", false },
40 { "123456", true },
41 { "1234567", true },
42 { "1234567890123", true },
43 { "123456789012345", true },
44 { "000000000000000", true },
45 { "999999999999999", true },
46 { "1234567890123456", false },
47 { "a23456789012345", false },
48 { "1234567b9012345", false },
49 { "12345678901234c", false },
50 { "123456789 01234", false },
51 { "1234567\n123456", false },
52 { "123456\t123456", false },
53 { "123456\r123456", false },
Neels Hofmeyr4b7c7912017-10-07 04:45:01 +020054 { NULL, false },
Neels Hofmeyr9cd1e742017-10-04 03:15:47 +020055};
56
Harald Weltee61d4592022-11-03 11:05:58 +010057bool test_valid_imsi(void)
Neels Hofmeyr9cd1e742017-10-04 03:15:47 +020058{
59 int i;
60 bool pass = true;
61 bool ok = true;
62 printf("----- %s\n", __func__);
63
64 for (i = 0; i < ARRAY_SIZE(test_imsis); i++) {
65 ok = osmo_imsi_str_valid(test_imsis[i].imsi);
66 pass = pass && (ok == test_imsis[i].expect_ok);
67 printf("%2d: expect=%s result=%s imsi='%s'\n",
68 i, BOOL_STR(test_imsis[i].expect_ok), BOOL_STR(ok),
69 test_imsis[i].imsi);
70 }
71 return pass;
72}
73
74static struct {
75 const char *msisdn;
76 bool expect_ok;
77} test_msisdns[] = {
78 { "", false },
79 { " ", false },
80 { "1", true },
81 { "123", true },
82 { "12345", true },
83 { "123456", true },
84 { "1234567", true },
85 { "1234567890123", true },
86 { "123456789012345", true },
87 { "000000000000000", true },
88 { "999999999999999", true },
89 { "1234567890123456", false },
90 { "a23456789012345", false },
91 { "1234567b9012345", false },
92 { "12345678901234c", false },
93 { "123456789 01234", false },
94 { "1234567\n123456", false },
95 { "123456\t123456", false },
96 { "123456\r123456", false },
Neels Hofmeyr4b7c7912017-10-07 04:45:01 +020097 { NULL, false },
Neels Hofmeyr9cd1e742017-10-04 03:15:47 +020098};
99
Harald Weltee61d4592022-11-03 11:05:58 +0100100bool test_valid_msisdn(void)
Neels Hofmeyr9cd1e742017-10-04 03:15:47 +0200101{
102 int i;
103 bool pass = true;
104 bool ok = true;
105 printf("----- %s\n", __func__);
106
107 for (i = 0; i < ARRAY_SIZE(test_msisdns); i++) {
108 ok = osmo_msisdn_str_valid(test_msisdns[i].msisdn);
109 pass = pass && (ok == test_msisdns[i].expect_ok);
110 printf("%2d: expect=%s result=%s msisdn='%s'\n",
111 i, BOOL_STR(test_msisdns[i].expect_ok), BOOL_STR(ok),
112 test_msisdns[i].msisdn);
113 }
114 return pass;
115}
116
Oliver Smith894be2d2019-01-11 13:13:37 +0100117static struct {
118 bool with_15th_digit;
119 const char *imei;
120 bool expect_ok;
121} test_imeis[] = {
122 /* without 15th digit */
123 {false, "12345678901234", true},
124 {false, "1234567890123", false},
125 {false, "123456789012345", false},
126
127 /* with 15th digit: valid */
128 {true, "357613004448485", true},
129 {true, "357805023984447", true},
130 {true, "352936001349777", true},
131 {true, "357663017768551", true},
132
133 /* with 15th digit: invalid */
134 {true, "357613004448480", false},
135 {true, "357613004448405", false},
136 {true, "357613004448085", false},
137
138 { NULL, false, false },
139};
140
Harald Weltee61d4592022-11-03 11:05:58 +0100141bool test_valid_imei(void)
Oliver Smith894be2d2019-01-11 13:13:37 +0100142{
143 int i;
144 bool pass = true;
145 bool ok = true;
146 printf("----- %s\n", __func__);
147
148 for (i = 0; i < ARRAY_SIZE(test_imeis); i++) {
149 ok = osmo_imei_str_valid(test_imeis[i].imei, test_imeis[i].with_15th_digit);
150 pass = pass && (ok == test_imeis[i].expect_ok);
151 printf("%2d: expect=%s result=%s imei='%s' with_15th_digit=%s\n",
152 i, BOOL_STR(test_imeis[i].expect_ok), BOOL_STR(ok),
153 test_imeis[i].imei, test_imeis[i].with_15th_digit ? "true" : "false");
154 }
155 return pass;
156}
157
Neels Hofmeyr721aa6d2018-02-20 21:38:00 +0100158struct test_mnc_from_str_result {
159 int rc;
160 uint16_t mnc;
161 bool mnc_3_digits;
162};
163
164struct test_mnc_from_str {
165 const char *mnc_str;
166 struct test_mnc_from_str_result expect;
167};
168
169static struct test_mnc_from_str test_mnc_from_strs[] = {
170 { "0", { 0, 0, false } },
171 { "00", { 0, 0, false } },
172 { "000", { 0, 0, true } },
173 { "1", { 0, 1, false } },
174 { "01", { 0, 1, false } },
175 { "001", { 0, 1, true } },
176 { "", { -EINVAL, 0, false } },
177 { " ", { -EINVAL, 0, false } },
Neels Hofmeyr20f7d0e2018-03-05 04:19:21 +0100178 { "-1", { -EINVAL, 0, false } },
179 { "1000", { -EINVAL, 0, false } },
Neels Hofmeyr721aa6d2018-02-20 21:38:00 +0100180 { "0x", { -EINVAL, 0, false } },
Neels Hofmeyr20f7d0e2018-03-05 04:19:21 +0100181 { " 23", { -EINVAL, 0, false } },
182 { "23 ", { -EINVAL, 0, false } },
183 { " 023", { -EINVAL, 0, false } },
184 { "023 ", { -EINVAL, 0, false } },
185 { "023 ", { -EINVAL, 0, false } },
Neels Hofmeyr721aa6d2018-02-20 21:38:00 +0100186};
187
Harald Weltee61d4592022-11-03 11:05:58 +0100188static bool test_mnc_from_str(void)
Neels Hofmeyr721aa6d2018-02-20 21:38:00 +0100189{
190 int i;
191 bool pass = true;
192 printf("----- %s\n", __func__);
193
194 for (i = 0; i < ARRAY_SIZE(test_mnc_from_strs); i++) {
195 struct test_mnc_from_str *t = &test_mnc_from_strs[i];
Neels Hofmeyr20f7d0e2018-03-05 04:19:21 +0100196 struct test_mnc_from_str_result result = {};
Neels Hofmeyr721aa6d2018-02-20 21:38:00 +0100197 bool ok;
198
199 result.rc = osmo_mnc_from_str(t->mnc_str, &result.mnc,
200 &result.mnc_3_digits);
Neels Hofmeyr5b8b8c62018-03-01 19:32:11 +0100201 ok = (result.rc == t->expect.rc)
202 && (result.mnc == t->expect.mnc)
203 && (result.mnc_3_digits == t->expect.mnc_3_digits);
Neels Hofmeyr721aa6d2018-02-20 21:38:00 +0100204 printf("%2d: \"%s\" rc=%d mnc=%u mnc_3_digits=%u %s\n",
205 i, osmo_escape_str(t->mnc_str, -1), result.rc, result.mnc, result.mnc_3_digits,
206 ok ? "pass" : "FAIL");
207 pass = pass && ok;
208 }
209 return pass;
210}
211
Harald Weltee61d4592022-11-03 11:05:58 +0100212static bool test_gummei_name(void)
Harald Weltede1da352018-10-08 22:27:04 +0200213{
214 static const struct osmo_gummei gummei = {
215 .plmn = { .mcc = 901, .mnc = 70 },
216 .mme = { .group_id = 0xA123, .code = 0xB1 }
217 };
218 const char *out;
219 bool pass = true;
220
221 out = osmo_gummei_name(&gummei);
222 printf("%s\n", out);
223 if (strcmp(out, "901-70-a123-b1"))
224 pass = false;
225
226 return pass;
227}
228
Harald Weltee61d4592022-11-03 11:05:58 +0100229static bool test_domain_gen(void)
Harald Weltede1da352018-10-08 22:27:04 +0200230{
231 static const struct osmo_gummei gummei = {
232 .plmn = { .mcc = 901, .mnc = 70 },
233 .mme = { .group_id = 0xA123, .code = 0xB1 }
234 };
235 char out[GSM23003_MME_DOMAIN_LEN];
236 bool pass = true;
237 int rc;
238
239 rc = osmo_gen_home_network_domain(out, &gummei.plmn);
240 if (rc < 0)
241 pass = false;
242 printf("%s -> %s\n", osmo_plmn_name(&gummei.plmn), out);
243 if (strcmp(out, "epc.mnc070.mcc901.3gppnetwork.org"))
244 pass = false;
245
246 rc = osmo_gen_mme_domain(out, &gummei);
247 printf("%s -> %s\n", osmo_gummei_name(&gummei), out);
248 if (strcmp(out, "mmecb1.mmegia123.mme.epc.mnc070.mcc901.3gppnetwork.org"))
249 pass = false;
250
251 return pass;
252}
253
254
Harald Weltee61d4592022-11-03 11:05:58 +0100255static bool test_domain_parse(void)
Harald Weltede1da352018-10-08 22:27:04 +0200256{
257 static const char *mme_dom_valid = "mmec01.mmegiA001.mme.epc.mnc070.mcc901.3gppnetwork.org";
258 static const char *home_dom_valid = "epc.mnc070.mcc901.3gppnetwork.org";
259 struct osmo_gummei gummei;
260 struct osmo_plmn_id plmn;
261 bool pass = true;
262 int rc;
263
264 rc = osmo_parse_home_network_domain(&plmn, home_dom_valid);
265 if (rc < 0)
266 pass = false;
267 printf("%s -> %s\n", home_dom_valid, osmo_plmn_name(&plmn));
268 if (plmn.mcc != 901 || plmn.mnc != 70)
269 pass = false;
270
271 rc = osmo_parse_mme_domain(&gummei, mme_dom_valid);
272 if (rc < 0)
273 pass = false;
274 printf("%s -> %s\n", mme_dom_valid, osmo_gummei_name(&gummei));
275 if (gummei.plmn.mcc != 901 || gummei.plmn.mnc != 70 ||
276 gummei.mme.group_id != 0xA001 || gummei.mme.code != 1)
277 pass = false;
278
279 return pass;
280}
281
Neels Hofmeyr9cd1e742017-10-04 03:15:47 +0200282int main(int argc, char **argv)
283{
284 bool pass = true;
285
286 pass = pass && test_valid_imsi();
287 pass = pass && test_valid_msisdn();
Oliver Smith894be2d2019-01-11 13:13:37 +0100288 pass = pass && test_valid_imei();
Neels Hofmeyr721aa6d2018-02-20 21:38:00 +0100289 pass = pass && test_mnc_from_str();
Harald Weltede1da352018-10-08 22:27:04 +0200290 pass = pass && test_gummei_name();
291 pass = pass && test_domain_gen();
292 pass = pass && test_domain_parse();
Neels Hofmeyr9cd1e742017-10-04 03:15:47 +0200293
294 OSMO_ASSERT(pass);
295
296 return EXIT_SUCCESS;
297}