blob: b4f7cd3df3472725f322f7f194507808e73ba5d0 [file] [log] [blame]
Holger Hans Peter Freytherb79a1482014-01-02 13:55:00 +01001/* tests for utilities of libmsomcore */
2/*
3 * (C) 2014 Holger Hans Peter Freyther
4 *
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 */
22
Holger Hans Peter Freytherf558ed42015-06-02 15:52:06 +020023#include <osmocom/gsm/ipa.h>
24
25#include <osmocom/core/logging.h>
Holger Hans Peter Freytherb79a1482014-01-02 13:55:00 +010026#include <osmocom/core/utils.h>
27
28#include <stdio.h>
Harald Welte504caac2017-10-27 17:19:59 +020029#include <ctype.h>
Holger Hans Peter Freytherb79a1482014-01-02 13:55:00 +010030
31static void hexdump_test(void)
32{
33 uint8_t data[4098];
34 int i;
35
36 for (i = 0; i < ARRAY_SIZE(data); ++i)
37 data[i] = i & 0xff;
38
39 printf("Plain dump\n");
40 printf("%s\n", osmo_hexdump(data, 4));
41
42 printf("Corner case\n");
43 printf("%s\n", osmo_hexdump(data, ARRAY_SIZE(data)));
44 printf("%s\n", osmo_hexdump_nospc(data, ARRAY_SIZE(data)));
45}
46
Neels Hofmeyr7adb5672017-02-14 15:48:19 +010047static void hexparse_test(void)
48{
49 int i;
50 int rc;
51 uint8_t data[256];
52
53 printf("\nHexparse 0..255 in lower case\n");
54 memset(data, 0, sizeof(data));
55 rc = osmo_hexparse(
56 "000102030405060708090a0b0c0d0e0f"
57 "101112131415161718191a1b1c1d1e1f"
58 "202122232425262728292a2b2c2d2e2f"
59 "303132333435363738393a3b3c3d3e3f"
60 "404142434445464748494a4b4c4d4e4f"
61 "505152535455565758595a5b5c5d5e5f"
62 "606162636465666768696a6b6c6d6e6f"
63 "707172737475767778797a7b7c7d7e7f"
64 "808182838485868788898a8b8c8d8e8f"
65 "909192939495969798999a9b9c9d9e9f"
66 "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
67 "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
68 "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
69 "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
70 "e0e1e2e3e4e5e6e7e8e9eaebecedeeef"
71 "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"
72 , data, sizeof(data));
73 printf("rc = %d\n", rc);
74 printf("--> %s\n\n", osmo_hexdump(data, sizeof(data)));
75 for (i = 0; i < sizeof(data); i++)
76 OSMO_ASSERT(data[i] == i);
77
78 printf("Hexparse 0..255 in upper case\n");
79 memset(data, 0, sizeof(data));
80 rc = osmo_hexparse(
81 "000102030405060708090A0B0C0D0E0F"
82 "101112131415161718191A1B1C1D1E1F"
83 "202122232425262728292A2B2C2D2E2F"
84 "303132333435363738393A3B3C3D3E3F"
85 "404142434445464748494A4B4C4D4E4F"
86 "505152535455565758595A5B5C5D5E5F"
87 "606162636465666768696A6B6C6D6E6F"
88 "707172737475767778797A7B7C7D7E7F"
89 "808182838485868788898A8B8C8D8E8F"
90 "909192939495969798999A9B9C9D9E9F"
91 "A0A1A2A3A4A5A6A7A8A9AAABACADAEAF"
92 "B0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF"
93 "C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF"
94 "D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF"
95 "E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF"
96 "F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF"
97 , data, sizeof(data));
98 printf("rc = %d\n", rc);
99 printf("--> %s\n\n", osmo_hexdump(data, sizeof(data)));
100 for (i = 0; i < sizeof(data); i++)
101 OSMO_ASSERT(data[i] == i);
102
103 printf("Hexparse 0..255 in mixed case\n");
104 memset(data, 0, sizeof(data));
105 rc = osmo_hexparse(
106 "000102030405060708090A0B0C0D0E0F"
107 "101112131415161718191A1B1C1D1E1F"
108 "202122232425262728292A2B2C2D2E2F"
109 "303132333435363738393a3b3c3d3e3f"
110 "404142434445464748494A4B4C4D4E4F"
111 "505152535455565758595a5b5c5d5e5f"
112 "606162636465666768696A6B6C6D6E6F"
113 "707172737475767778797A7B7C7D7E7F"
114 "808182838485868788898A8B8C8D8E8F"
115 "909192939495969798999A9B9C9D9E9F"
116 "A0A1A2A3a4a5a6a7a8a9AAABACADAEAF"
117 "B0B1B2B3b4b5b6b7b8b9BABBBCBDBEBF"
118 "C0C1C2C3c4c5c6c7c8c9CACBCCCDCECF"
119 "D0D1D2D3d4d5d6d7d8d9DADBDCDDDEDF"
120 "E0E1E2E3e4e5e6e7e8e9EAEBECEDEEEF"
121 "F0F1F2F3f4f5f6f7f8f9FAFBFCFDFEFF"
122 , data, sizeof(data));
123 printf("rc = %d\n", rc);
124 printf("--> %s\n\n", osmo_hexdump(data, sizeof(data)));
125 for (i = 0; i < sizeof(data); i++)
126 OSMO_ASSERT(data[i] == i);
127
Neels Hofmeyr437ed4a2017-02-14 15:54:31 +0100128 printf("Hexparse 0..255 with whitespace\n");
129 memset(data, 0, sizeof(data));
130 rc = osmo_hexparse(
131 "00 01\t02\r030405060708090A0B0C0D0 E 0 F\n"
132 "10 11\t12\r131415161718191A1B1C1D1 E 1 F\n"
133 "20 21\t22\r232425262728292A2B2C2D2 E 2 F\n"
134 "30 31\t32\r333435363738393a3b3c3d3 e 3 f\n"
135 "40 41\t42\r434445464748494A4B4C4D4 E 4 F\n"
136 "50 51\t52\r535455565758595a5b5c5d5 e 5 f\n"
137 "60 61\t62\r636465666768696A6B6C6D6 E 6 F\n"
138 "70 71\t72\r737475767778797A7B7C7D7 E 7 F\n"
139 "80 81\t82\r838485868788898A8B8C8D8 E 8 F\n"
140 "90 91\t92\r939495969798999A9B9C9D9 E 9 F\n"
141 "A0 A1\tA2\rA3a4a5a6a7a8a9AAABACADA E A F\n"
142 "B0 B1\tB2\rB3b4b5b6b7b8b9BABBBCBDB E B F\n"
143 "C0 C1\tC2\rC3c4c5c6c7c8c9CACBCCCDC E C F \n"
144 "D0 D1\tD2\rD3d4d5d6d7d8d9DADBDCDDD E D F\t\n"
145 "E0 E1\tE2\rE3e4e5e6e7e8e9EAEBECEDE E E F \t\n"
146 "F0 F1\tF2\rF3f4f5f6f7f8f9FAFBFCFDF E F F \t\r\n"
147 , data, sizeof(data));
148 printf("rc = %d\n", rc);
149 printf("--> %s\n\n", osmo_hexdump(data, sizeof(data)));
150 for (i = 0; i < sizeof(data); i++)
151 OSMO_ASSERT(data[i] == i);
152
Neels Hofmeyr7adb5672017-02-14 15:48:19 +0100153 printf("Hexparse with buffer too short\n");
154 memset(data, 0, sizeof(data));
155 rc = osmo_hexparse("000102030405060708090a0b0c0d0e0f", data, 15);
156 printf("rc = %d\n", rc);
157
158 printf("Hexparse with uneven amount of digits\n");
159 memset(data, 0, sizeof(data));
160 rc = osmo_hexparse("000102030405060708090a0b0c0d0e0", data, 16);
161 printf("rc = %d\n", rc);
162
163 printf("Hexparse with invalid char\n");
164 memset(data, 0, sizeof(data));
165 rc = osmo_hexparse("0001020304050X0708090a0b0c0d0e0f", data, 16);
166 printf("rc = %d\n", rc);
167}
168
Holger Hans Peter Freytherf558ed42015-06-02 15:52:06 +0200169static void test_idtag_parsing(void)
170{
171 struct tlv_parsed tvp;
172 int rc;
173
174 static uint8_t data[] = {
175 0x01, 0x08,
176 0x01, 0x07,
177 0x01, 0x02,
178 0x01, 0x03,
179 0x01, 0x04,
180 0x01, 0x05,
181 0x01, 0x01,
182 0x01, 0x00,
183 0x11, 0x23, 0x4e, 0x6a, 0x28, 0xd2, 0xa2, 0x53, 0x3a, 0x2a, 0x82, 0xa7, 0x7a, 0xef, 0x29, 0xd4, 0x44, 0x30,
184 0x11, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
185 };
186
187 rc = ipa_ccm_idtag_parse_off(&tvp, data, sizeof(data), 1);
188 OSMO_ASSERT(rc == 0);
189
190 OSMO_ASSERT(TLVP_PRESENT(&tvp, 8));
191 OSMO_ASSERT(TLVP_LEN(&tvp, 8) == 0);
192
193 OSMO_ASSERT(TLVP_PRESENT(&tvp, 7));
194 OSMO_ASSERT(TLVP_LEN(&tvp, 7) == 0);
195
196 OSMO_ASSERT(TLVP_PRESENT(&tvp, 2));
197 OSMO_ASSERT(TLVP_LEN(&tvp, 2) == 0);
198
199 OSMO_ASSERT(TLVP_PRESENT(&tvp, 3));
200 OSMO_ASSERT(TLVP_LEN(&tvp, 3) == 0);
201
202 OSMO_ASSERT(TLVP_PRESENT(&tvp, 4));
203 OSMO_ASSERT(TLVP_LEN(&tvp, 4) == 0);
204
205 OSMO_ASSERT(TLVP_PRESENT(&tvp, 5));
206 OSMO_ASSERT(TLVP_LEN(&tvp, 5) == 0);
207
208 OSMO_ASSERT(TLVP_PRESENT(&tvp, 1));
209 OSMO_ASSERT(TLVP_LEN(&tvp, 1) == 0);
210
211 OSMO_ASSERT(TLVP_PRESENT(&tvp, 0));
212 OSMO_ASSERT(TLVP_LEN(&tvp, 0) == 0);
213
214 OSMO_ASSERT(TLVP_PRESENT(&tvp, 0x23));
215 OSMO_ASSERT(TLVP_LEN(&tvp, 0x23) == 16);
216
217 OSMO_ASSERT(TLVP_PRESENT(&tvp, 0x24));
218 OSMO_ASSERT(TLVP_LEN(&tvp, 0x24) == 16);
219
220 OSMO_ASSERT(!TLVP_PRESENT(&tvp, 0x25));
221}
222
Neels Hofmeyr4335bad2017-10-07 04:39:14 +0200223static struct {
224 const char *str;
225 int min_digits;
226 int max_digits;
227 bool require_even;
228 bool expect_ok;
229} test_hexstrs[] = {
230 { NULL, 0, 10, false, true },
231 { NULL, 1, 10, false, false },
232 { "", 0, 10, false, true },
233 { "", 1, 10, false, false },
234 { " ", 0, 10, false, false },
235 { "1", 0, 10, false, true },
236 { "1", 1, 10, false, true },
237 { "1", 1, 10, true, false },
238 { "1", 2, 10, false, false },
239 { "123", 1, 10, false, true },
240 { "123", 1, 10, true, false },
241 { "123", 4, 10, false, false },
242 { "1234", 4, 10, true, true },
243 { "12345", 4, 10, true, false },
244 { "123456", 4, 10, true, true },
245 { "1234567", 4, 10, true, false },
246 { "12345678", 4, 10, true, true },
247 { "123456789", 4, 10, true, false },
248 { "123456789a", 4, 10, true, true },
249 { "123456789ab", 4, 10, true, false },
250 { "123456789abc", 4, 10, true, false },
251 { "123456789ab", 4, 10, false, false },
252 { "123456789abc", 4, 10, false, false },
253 { "0123456789abcdefABCDEF", 0, 100, false, true },
254 { "0123456789 abcdef ABCDEF", 0, 100, false, false },
255 { "foobar", 0, 100, false, false },
256 { "BeadedBeeAced1EbbedDefacedFacade", 32, 32, true, true },
257 { "C01ffedC1cadaeAc1d1f1edAcac1aB0a", 32, 32, false, true },
258 { "DeafBeddedBabeAcceededFadedDecaff", 32, 32, false, false },
259};
260
261bool test_is_hexstr()
262{
263 int i;
264 bool pass = true;
265 bool ok = true;
266 printf("\n----- %s\n", __func__);
267
268 for (i = 0; i < ARRAY_SIZE(test_hexstrs); i++) {
269 ok = osmo_is_hexstr(test_hexstrs[i].str,
270 test_hexstrs[i].min_digits,
271 test_hexstrs[i].max_digits,
272 test_hexstrs[i].require_even);
273 pass = pass && (ok == test_hexstrs[i].expect_ok);
274 printf("%2d: %s str='%s' min=%d max=%d even=%d expect=%s\n",
275 i, test_hexstrs[i].expect_ok == ok ? "pass" : "FAIL",
276 test_hexstrs[i].str,
277 test_hexstrs[i].min_digits,
278 test_hexstrs[i].max_digits,
279 test_hexstrs[i].require_even,
280 test_hexstrs[i].expect_ok ? "valid" : "invalid");
281 }
282 return pass;
283}
284
Harald Welte504caac2017-10-27 17:19:59 +0200285struct bcdcheck {
286 uint8_t bcd;
287 char ch;
288};
289
290static const struct bcdcheck bcdchecks[] = {
291 { 0, '0' },
292 { 1, '1' },
293 { 2, '2' },
294 { 3, '3' },
295 { 4, '4' },
296 { 5, '5' },
297 { 6, '6' },
298 { 7, '7' },
299 { 8, '8' },
300 { 9, '9' },
301 { 0xA, 'A' },
302 { 0xB, 'B' },
303 { 0xC, 'C' },
304 { 0xD, 'D' },
305 { 0xE, 'E' },
306 { 0xF, 'F' },
307};
308
309static void bcd_test(void)
310{
311 int i;
312
313 printf("\nTesting BCD conversion\n");
314 for (i = 0; i < ARRAY_SIZE(bcdchecks); i++) {
315 const struct bcdcheck *check = &bcdchecks[i];
316 char ch = osmo_bcd2char(check->bcd);
317 printf("\tval=0x%x, expected=%c, found=%c\n", check->bcd, check->ch, ch);
318 OSMO_ASSERT(osmo_bcd2char(check->bcd) == check->ch);
319 /* test char -> bcd back-coversion */
320 OSMO_ASSERT(osmo_char2bcd(ch) == check->bcd);
321 /* test for lowercase hex char */
322 OSMO_ASSERT(osmo_char2bcd(tolower(ch)) == check->bcd);
323 }
324}
325
Neels Hofmeyr9910bbc2017-12-16 00:54:52 +0100326static void str_escape_test(void)
327{
328 int i;
329 int j;
330 uint8_t in_buf[32];
331 char out_buf[11];
332 const char *printable = "printable";
333 const char *res;
334
335 printf("\nTesting string escaping\n");
336 printf("- all chars from 0 to 255 in batches of 16:\n");
337 for (j = 0; j < 16; j++) {
338 for (i = 0; i < 16; i++)
339 in_buf[i] = (j << 4) | i;
340 printf("\"%s\"\n", osmo_escape_str((const char*)in_buf, 16));
341 }
342
343 printf("- nul terminated:\n");
344 printf("\"%s\"\n", osmo_escape_str("termi\nated", -1));
345
346 printf("- passthru:\n");
347 res = osmo_escape_str(printable, -1);
348 if (res != printable)
349 printf("NOT passed through! \"%s\"\n", res);
350 else
351 printf("passed through unchanged \"%s\"\n", res);
352
353 printf("- zero length:\n");
354 printf("\"%s\"\n", osmo_escape_str("omitted", 0));
355
356 printf("- truncation when too long:\n");
357 memset(in_buf, 'x', sizeof(in_buf));
358 in_buf[0] = '\a';
359 in_buf[7] = 'E';
360 memset(out_buf, 0x7f, sizeof(out_buf));
361 printf("\"%s\"\n", osmo_escape_str_buf((const char *)in_buf, sizeof(in_buf), out_buf, 10));
362 OSMO_ASSERT(out_buf[10] == 0x7f);
363
364 printf("- passthrough without truncation when no escaping needed:\n");
365 memset(in_buf, 'x', sizeof(in_buf));
366 in_buf[19] = 'E';
367 in_buf[20] = '\0';
368 memset(out_buf, 0x7f, sizeof(out_buf));
369 printf("\"%s\"\n", osmo_escape_str_buf((const char *)in_buf, -1, out_buf, 10));
370 OSMO_ASSERT(out_buf[0] == 0x7f);
371}
372
Holger Hans Peter Freytherb79a1482014-01-02 13:55:00 +0100373int main(int argc, char **argv)
374{
Holger Hans Peter Freytherf558ed42015-06-02 15:52:06 +0200375 static const struct log_info log_info = {};
376 log_init(&log_info, NULL);
377
Holger Hans Peter Freytherb79a1482014-01-02 13:55:00 +0100378 hexdump_test();
Neels Hofmeyr7adb5672017-02-14 15:48:19 +0100379 hexparse_test();
Holger Hans Peter Freytherf558ed42015-06-02 15:52:06 +0200380 test_idtag_parsing();
Neels Hofmeyr4335bad2017-10-07 04:39:14 +0200381 test_is_hexstr();
Harald Welte504caac2017-10-27 17:19:59 +0200382 bcd_test();
Neels Hofmeyr9910bbc2017-12-16 00:54:52 +0100383 str_escape_test();
Holger Hans Peter Freytherb79a1482014-01-02 13:55:00 +0100384 return 0;
385}