blob: eac5a115b6c3e57009b7c5243bc3a1c6fe727930 [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 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 */
23
24#include <stdio.h>
Neels Hofmeyr721aa6d2018-02-20 21:38:00 +010025#include <errno.h>
26#include <strings.h>
Harald Weltede1da352018-10-08 22:27:04 +020027#include <string.h>
Neels Hofmeyr9cd1e742017-10-04 03:15:47 +020028
29#include <osmocom/gsm/gsm23003.h>
Harald Weltede1da352018-10-08 22:27:04 +020030#include <osmocom/gsm/protocol/gsm_23_003.h>
Neels Hofmeyr9cd1e742017-10-04 03:15:47 +020031#include <osmocom/core/utils.h>
32
33#define BOOL_STR(b) ((b)? "true" : "false")
34
35static struct {
36 const char *imsi;
37 bool expect_ok;
38} test_imsis[] = {
39 { "", false },
40 { " ", false },
41 { "1", false },
42 { "123", false },
43 { "12345", false },
44 { "123456", true },
45 { "1234567", true },
46 { "1234567890123", true },
47 { "123456789012345", true },
48 { "000000000000000", true },
49 { "999999999999999", true },
50 { "1234567890123456", false },
51 { "a23456789012345", false },
52 { "1234567b9012345", false },
53 { "12345678901234c", false },
54 { "123456789 01234", false },
55 { "1234567\n123456", false },
56 { "123456\t123456", false },
57 { "123456\r123456", false },
Neels Hofmeyr4b7c7912017-10-07 04:45:01 +020058 { NULL, false },
Neels Hofmeyr9cd1e742017-10-04 03:15:47 +020059};
60
61bool test_valid_imsi()
62{
63 int i;
64 bool pass = true;
65 bool ok = true;
66 printf("----- %s\n", __func__);
67
68 for (i = 0; i < ARRAY_SIZE(test_imsis); i++) {
69 ok = osmo_imsi_str_valid(test_imsis[i].imsi);
70 pass = pass && (ok == test_imsis[i].expect_ok);
71 printf("%2d: expect=%s result=%s imsi='%s'\n",
72 i, BOOL_STR(test_imsis[i].expect_ok), BOOL_STR(ok),
73 test_imsis[i].imsi);
74 }
75 return pass;
76}
77
78static struct {
79 const char *msisdn;
80 bool expect_ok;
81} test_msisdns[] = {
82 { "", false },
83 { " ", false },
84 { "1", true },
85 { "123", true },
86 { "12345", true },
87 { "123456", true },
88 { "1234567", true },
89 { "1234567890123", true },
90 { "123456789012345", true },
91 { "000000000000000", true },
92 { "999999999999999", true },
93 { "1234567890123456", false },
94 { "a23456789012345", false },
95 { "1234567b9012345", false },
96 { "12345678901234c", false },
97 { "123456789 01234", false },
98 { "1234567\n123456", false },
99 { "123456\t123456", false },
100 { "123456\r123456", false },
Neels Hofmeyr4b7c7912017-10-07 04:45:01 +0200101 { NULL, false },
Neels Hofmeyr9cd1e742017-10-04 03:15:47 +0200102};
103
104bool test_valid_msisdn()
105{
106 int i;
107 bool pass = true;
108 bool ok = true;
109 printf("----- %s\n", __func__);
110
111 for (i = 0; i < ARRAY_SIZE(test_msisdns); i++) {
112 ok = osmo_msisdn_str_valid(test_msisdns[i].msisdn);
113 pass = pass && (ok == test_msisdns[i].expect_ok);
114 printf("%2d: expect=%s result=%s msisdn='%s'\n",
115 i, BOOL_STR(test_msisdns[i].expect_ok), BOOL_STR(ok),
116 test_msisdns[i].msisdn);
117 }
118 return pass;
119}
120
Oliver Smith894be2d2019-01-11 13:13:37 +0100121static struct {
122 bool with_15th_digit;
123 const char *imei;
124 bool expect_ok;
125} test_imeis[] = {
126 /* without 15th digit */
127 {false, "12345678901234", true},
128 {false, "1234567890123", false},
129 {false, "123456789012345", false},
130
131 /* with 15th digit: valid */
132 {true, "357613004448485", true},
133 {true, "357805023984447", true},
134 {true, "352936001349777", true},
135 {true, "357663017768551", true},
136
137 /* with 15th digit: invalid */
138 {true, "357613004448480", false},
139 {true, "357613004448405", false},
140 {true, "357613004448085", false},
141
142 { NULL, false, false },
143};
144
145bool test_valid_imei()
146{
147 int i;
148 bool pass = true;
149 bool ok = true;
150 printf("----- %s\n", __func__);
151
152 for (i = 0; i < ARRAY_SIZE(test_imeis); i++) {
153 ok = osmo_imei_str_valid(test_imeis[i].imei, test_imeis[i].with_15th_digit);
154 pass = pass && (ok == test_imeis[i].expect_ok);
155 printf("%2d: expect=%s result=%s imei='%s' with_15th_digit=%s\n",
156 i, BOOL_STR(test_imeis[i].expect_ok), BOOL_STR(ok),
157 test_imeis[i].imei, test_imeis[i].with_15th_digit ? "true" : "false");
158 }
159 return pass;
160}
161
Neels Hofmeyr721aa6d2018-02-20 21:38:00 +0100162struct test_mnc_from_str_result {
163 int rc;
164 uint16_t mnc;
165 bool mnc_3_digits;
166};
167
168struct test_mnc_from_str {
169 const char *mnc_str;
170 struct test_mnc_from_str_result expect;
171};
172
173static struct test_mnc_from_str test_mnc_from_strs[] = {
174 { "0", { 0, 0, false } },
175 { "00", { 0, 0, false } },
176 { "000", { 0, 0, true } },
177 { "1", { 0, 1, false } },
178 { "01", { 0, 1, false } },
179 { "001", { 0, 1, true } },
180 { "", { -EINVAL, 0, false } },
181 { " ", { -EINVAL, 0, false } },
Neels Hofmeyr20f7d0e2018-03-05 04:19:21 +0100182 { "-1", { -EINVAL, 0, false } },
183 { "1000", { -EINVAL, 0, false } },
Neels Hofmeyr721aa6d2018-02-20 21:38:00 +0100184 { "0x", { -EINVAL, 0, false } },
Neels Hofmeyr20f7d0e2018-03-05 04:19:21 +0100185 { " 23", { -EINVAL, 0, false } },
186 { "23 ", { -EINVAL, 0, false } },
187 { " 023", { -EINVAL, 0, false } },
188 { "023 ", { -EINVAL, 0, false } },
189 { "023 ", { -EINVAL, 0, false } },
Neels Hofmeyr721aa6d2018-02-20 21:38:00 +0100190};
191
192static bool test_mnc_from_str()
193{
194 int i;
195 bool pass = true;
196 printf("----- %s\n", __func__);
197
198 for (i = 0; i < ARRAY_SIZE(test_mnc_from_strs); i++) {
199 struct test_mnc_from_str *t = &test_mnc_from_strs[i];
Neels Hofmeyr20f7d0e2018-03-05 04:19:21 +0100200 struct test_mnc_from_str_result result = {};
Neels Hofmeyr721aa6d2018-02-20 21:38:00 +0100201 bool ok;
202
203 result.rc = osmo_mnc_from_str(t->mnc_str, &result.mnc,
204 &result.mnc_3_digits);
Neels Hofmeyr5b8b8c62018-03-01 19:32:11 +0100205 ok = (result.rc == t->expect.rc)
206 && (result.mnc == t->expect.mnc)
207 && (result.mnc_3_digits == t->expect.mnc_3_digits);
Neels Hofmeyr721aa6d2018-02-20 21:38:00 +0100208 printf("%2d: \"%s\" rc=%d mnc=%u mnc_3_digits=%u %s\n",
209 i, osmo_escape_str(t->mnc_str, -1), result.rc, result.mnc, result.mnc_3_digits,
210 ok ? "pass" : "FAIL");
211 pass = pass && ok;
212 }
213 return pass;
214}
215
Harald Weltede1da352018-10-08 22:27:04 +0200216static bool test_gummei_name()
217{
218 static const struct osmo_gummei gummei = {
219 .plmn = { .mcc = 901, .mnc = 70 },
220 .mme = { .group_id = 0xA123, .code = 0xB1 }
221 };
222 const char *out;
223 bool pass = true;
224
225 out = osmo_gummei_name(&gummei);
226 printf("%s\n", out);
227 if (strcmp(out, "901-70-a123-b1"))
228 pass = false;
229
230 return pass;
231}
232
233static bool test_domain_gen()
234{
235 static const struct osmo_gummei gummei = {
236 .plmn = { .mcc = 901, .mnc = 70 },
237 .mme = { .group_id = 0xA123, .code = 0xB1 }
238 };
239 char out[GSM23003_MME_DOMAIN_LEN];
240 bool pass = true;
241 int rc;
242
243 rc = osmo_gen_home_network_domain(out, &gummei.plmn);
244 if (rc < 0)
245 pass = false;
246 printf("%s -> %s\n", osmo_plmn_name(&gummei.plmn), out);
247 if (strcmp(out, "epc.mnc070.mcc901.3gppnetwork.org"))
248 pass = false;
249
250 rc = osmo_gen_mme_domain(out, &gummei);
251 printf("%s -> %s\n", osmo_gummei_name(&gummei), out);
252 if (strcmp(out, "mmecb1.mmegia123.mme.epc.mnc070.mcc901.3gppnetwork.org"))
253 pass = false;
254
255 return pass;
256}
257
258
259static bool test_domain_parse()
260{
261 static const char *mme_dom_valid = "mmec01.mmegiA001.mme.epc.mnc070.mcc901.3gppnetwork.org";
262 static const char *home_dom_valid = "epc.mnc070.mcc901.3gppnetwork.org";
263 struct osmo_gummei gummei;
264 struct osmo_plmn_id plmn;
265 bool pass = true;
266 int rc;
267
268 rc = osmo_parse_home_network_domain(&plmn, home_dom_valid);
269 if (rc < 0)
270 pass = false;
271 printf("%s -> %s\n", home_dom_valid, osmo_plmn_name(&plmn));
272 if (plmn.mcc != 901 || plmn.mnc != 70)
273 pass = false;
274
275 rc = osmo_parse_mme_domain(&gummei, mme_dom_valid);
276 if (rc < 0)
277 pass = false;
278 printf("%s -> %s\n", mme_dom_valid, osmo_gummei_name(&gummei));
279 if (gummei.plmn.mcc != 901 || gummei.plmn.mnc != 70 ||
280 gummei.mme.group_id != 0xA001 || gummei.mme.code != 1)
281 pass = false;
282
283 return pass;
284}
285
Neels Hofmeyr9cd1e742017-10-04 03:15:47 +0200286int main(int argc, char **argv)
287{
288 bool pass = true;
289
290 pass = pass && test_valid_imsi();
291 pass = pass && test_valid_msisdn();
Oliver Smith894be2d2019-01-11 13:13:37 +0100292 pass = pass && test_valid_imei();
Neels Hofmeyr721aa6d2018-02-20 21:38:00 +0100293 pass = pass && test_mnc_from_str();
Harald Weltede1da352018-10-08 22:27:04 +0200294 pass = pass && test_gummei_name();
295 pass = pass && test_domain_gen();
296 pass = pass && test_domain_parse();
Neels Hofmeyr9cd1e742017-10-04 03:15:47 +0200297
298 OSMO_ASSERT(pass);
299
300 return EXIT_SUCCESS;
301}