blob: e48f9a363b4bbe8e667cb3f79143e7ce23420da4 [file] [log] [blame]
Harald Welteec8b4502010-02-20 20:34:29 +01001/*
2 * (C) 2008 by Daniel Willmann <daniel@totalueberwachung.de>
Nico Golde28de0532010-07-09 17:19:12 +02003 * (C) 2010 by Nico Golde <nico@ngolde.de>
Harald Welteec8b4502010-02-20 20:34:29 +01004 * All Rights Reserved
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 */
21
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
Pablo Neira Ayuso83419342011-03-22 16:36:13 +010025#include <osmocom/core/msgb.h>
26#include <osmocom/gsm/gsm_utils.h>
27#include <osmocom/core/utils.h>
Holger Hans Peter Freyther31e97ea2010-07-20 02:46:56 +080028
29struct test_case {
30 const uint8_t *input;
31 const uint16_t input_length;
32
33 const uint8_t *expected;
Dennis Wehrle291e6132011-07-24 20:14:13 +020034 const uint16_t expected_octet_length;
35 const uint16_t expected_septet_length;
36 const uint8_t ud_hdr_ind;
Holger Hans Peter Freyther31e97ea2010-07-20 02:46:56 +080037};
38
39static const char simple_text[] = "test text";
Dennis Wehrle291e6132011-07-24 20:14:13 +020040#define simple_septet_length 9
Holger Hans Peter Freyther31e97ea2010-07-20 02:46:56 +080041static const uint8_t simple_enc[] = {
Nico Goldec0ce9aa2010-07-20 15:43:58 +020042 0xf4, 0xf2, 0x9c, 0x0e, 0xa2, 0x97, 0xf1, 0x74
Holger Hans Peter Freyther31e97ea2010-07-20 02:46:56 +080043};
44
Dennis Wehrle291e6132011-07-24 20:14:13 +020045static const char escape_text[] = "!$ a more#^- complicated test@@?_%! case";
46#define escape_septet_length 41 /* note: the ^ counts as two, because it is a extension character */
Holger Hans Peter Freyther31e97ea2010-07-20 02:46:56 +080047static const uint8_t escape_enc[] = {
48 0x21, 0x01, 0x28, 0x0c, 0x6a, 0xbf, 0xe5, 0xe5, 0xd1,
49 0x86, 0xd2, 0x02, 0x8d, 0xdf, 0x6d, 0x38, 0x3b, 0x3d,
50 0x0e, 0xd3, 0xcb, 0x64, 0x10, 0xbd, 0x3c, 0xa7, 0x03,
51 0x00, 0xbf, 0x48, 0x29, 0x04, 0x1a, 0x87, 0xe7, 0x65,
Holger Hans Peter Freyther31e97ea2010-07-20 02:46:56 +080052};
53
Dennis Wehrle291e6132011-07-24 20:14:13 +020054static const char enhanced_text[] = "enhanced ^ {][} test |+~ ^ test";
55#define enhanced_septet_length 39 /* note: the characters { } [ ] ^ | ~ count as two (each of them), because they are extension characters */
56static const uint8_t enhanced_enc[] = {
57 0x65, 0x37, 0x3A, 0xEC, 0x1E, 0x97, 0xC9, 0xA0, 0x0D,
58 0x05, 0xB4, 0x41, 0x6D, 0x7C, 0x1B, 0xDE, 0x26, 0x05,
59 0xA2, 0x97, 0xE7, 0x74, 0xD0, 0x06, 0xB8, 0xDA, 0xF4,
60 0x40, 0x1B, 0x0A, 0x88, 0x5E, 0x9E, 0xD3, 0x01,
61};
62
63static const char enhancedV2_text[] = "enhanced ^ {][} test |+~ ^ tests";
64#define enhancedV2_septet_length 40 /* note: number of octets are equal to the enhanced_text! */
65static const uint8_t enhancedV2_enc[] = {
66 0x65, 0x37, 0x3A, 0xEC, 0x1E, 0x97, 0xC9, 0xA0, 0x0D,
67 0x05, 0xB4, 0x41, 0x6D, 0x7C, 0x1B, 0xDE, 0x26, 0x05,
68 0xA2, 0x97, 0xE7, 0x74, 0xD0, 0x06, 0xB8, 0xDA, 0xF4,
69 0x40, 0x1B, 0x0A, 0x88, 0x5E, 0x9E, 0xD3, 0xE7,
70};
71
72
73
74static const char concatenated_text[] =
75 "this is a testmessage. this is a testmessage. this is a testmessage. this is a testmessage. "
76 "this is a testmessage. this is a testmessage. cut here .....: this is a second testmessage. end here.";
77
78static const char splitted_text_part1[] =
79 "this is a testmessage. this is a testmessage. this is a testmessage. this is a testmessage. "
80 "this is a testmessage. this is a testmessage. cut here .....:";
81#define concatenated_part1_septet_length_with_header 160
82#define concatenated_part1_septet_length 153
83static const uint8_t concatenated_part1_enc[] = {
84 0x05, 0x00, 0x03, 0x6f, 0x02, 0x01,
85 0xe8, 0xe8, 0xf4, 0x1c, 0x94, 0x9e, 0x83, 0xc2,
86 0x20, 0x7a, 0x79, 0x4e, 0x6f, 0x97, 0xe7, 0xf3,
87 0xf0, 0xb9, 0xec, 0x02, 0xd1, 0xd1, 0xe9, 0x39,
88 0x28, 0x3d, 0x07, 0x85, 0x41, 0xf4, 0xf2, 0x9c,
89 0xde, 0x2e, 0xcf, 0xe7, 0xe1, 0x73, 0xd9, 0x05,
90 0xa2, 0xa3, 0xd3, 0x73, 0x50, 0x7a, 0x0e, 0x0a,
91 0x83, 0xe8, 0xe5, 0x39, 0xbd, 0x5d, 0x9e, 0xcf,
92 0xc3, 0xe7, 0xb2, 0x0b, 0x44, 0x47, 0xa7, 0xe7,
93 0xa0, 0xf4, 0x1c, 0x14, 0x06, 0xd1, 0xcb, 0x73,
94 0x7a, 0xbb, 0x3c, 0x9f, 0x87, 0xcf, 0x65, 0x17,
95 0x88, 0x8e, 0x4e, 0xcf, 0x41, 0xe9, 0x39, 0x28,
96 0x0c, 0xa2, 0x97, 0xe7, 0xf4, 0x76, 0x79, 0x3e,
97 0x0f, 0x9f, 0xcb, 0x2e, 0x10, 0x1d, 0x9d, 0x9e,
98 0x83, 0xd2, 0x73, 0x50, 0x18, 0x44, 0x2f, 0xcf,
99 0xe9, 0xed, 0xf2, 0x7c, 0x1e, 0x3e, 0x97, 0x5d,
100 0xa0, 0x71, 0x9d, 0x0e, 0x42, 0x97, 0xe5, 0x65,
101 0x90, 0xcb, 0xe5, 0x72, 0xb9, 0x74,
102};
103
104static const char splitted_text_part2[] = " this is a second testmessage. end here.";
105#define concatenated_part2_septet_length_with_header 47
106#define concatenated_part2_septet_length 40
107static const uint8_t concatenated_part2_enc[] = {
108 0x05, 0x00, 0x03, 0x6f, 0x02, 0x02,
109 0x40, 0x74, 0x74, 0x7a, 0x0e, 0x4a, 0xcf, 0x41,
110 0x61, 0xd0, 0xbc, 0x3c, 0x7e, 0xbb, 0xc9, 0x20,
111 0x7a, 0x79, 0x4e, 0x6f, 0x97, 0xe7, 0xf3, 0xf0,
112 0xb9, 0xec, 0x02, 0x95, 0xdd, 0x64, 0x10, 0xba,
113 0x2c, 0x2f, 0xbb, 0x00,
114};
115
116static const struct test_case test_multiple_encode[] =
117{
118 {
119 .input = concatenated_text,
120 .expected = concatenated_part1_enc,
121 .expected_octet_length = sizeof(concatenated_part1_enc),
122 .expected_septet_length = concatenated_part1_septet_length,
123 .ud_hdr_ind = 1,
124 },
125 {
126 .input = concatenated_text,
127 .expected = concatenated_part2_enc,
128 .expected_octet_length = sizeof(concatenated_part2_enc),
129 .expected_septet_length = concatenated_part2_septet_length,
130 .ud_hdr_ind = 1,
131 },
132};
133
Holger Hans Peter Freyther31e97ea2010-07-20 02:46:56 +0800134static const struct test_case test_encode[] =
135{
136 {
137 .input = simple_text,
138 .expected = simple_enc,
Dennis Wehrle291e6132011-07-24 20:14:13 +0200139 .expected_octet_length = sizeof(simple_enc),
140 .expected_septet_length = simple_septet_length,
141 .ud_hdr_ind = 0,
Holger Hans Peter Freyther31e97ea2010-07-20 02:46:56 +0800142 },
143 {
144 .input = escape_text,
145 .expected = escape_enc,
Dennis Wehrle291e6132011-07-24 20:14:13 +0200146 .expected_octet_length = sizeof(escape_enc),
147 .expected_septet_length = escape_septet_length,
148 .ud_hdr_ind = 0,
149 },
150 {
151 .input = enhanced_text,
152 .expected = enhanced_enc,
153 .expected_octet_length = sizeof(enhanced_enc),
154 .expected_septet_length = enhanced_septet_length,
155 .ud_hdr_ind = 0,
156 },
157 {
158 .input = enhancedV2_text,
159 .expected = enhancedV2_enc,
160 .expected_octet_length = sizeof(enhancedV2_enc),
161 .expected_septet_length = enhancedV2_septet_length,
162 .ud_hdr_ind = 0,
Holger Hans Peter Freyther31e97ea2010-07-20 02:46:56 +0800163 },
164};
165
166static const struct test_case test_decode[] =
167{
168 {
169 .input = simple_enc,
Nico Goldec0ce9aa2010-07-20 15:43:58 +0200170 .input_length = sizeof(simple_enc),
Holger Hans Peter Freyther31e97ea2010-07-20 02:46:56 +0800171 .expected = simple_text,
Dennis Wehrle291e6132011-07-24 20:14:13 +0200172 .expected_septet_length = simple_septet_length,
173 .ud_hdr_ind = 0,
Holger Hans Peter Freyther31e97ea2010-07-20 02:46:56 +0800174 },
175 {
176 .input = escape_enc,
Nico Goldec0ce9aa2010-07-20 15:43:58 +0200177 .input_length = sizeof(escape_enc),
Holger Hans Peter Freyther31e97ea2010-07-20 02:46:56 +0800178 .expected = escape_text,
Dennis Wehrle291e6132011-07-24 20:14:13 +0200179 .expected_septet_length = escape_septet_length,
180 .ud_hdr_ind = 0,
181 },
182 {
183 .input = enhanced_enc,
184 .input_length = sizeof(enhanced_enc),
185 .expected = enhanced_text,
186 .expected_septet_length = enhanced_septet_length,
187 .ud_hdr_ind = 0,
188 },
189 {
190 .input = enhancedV2_enc,
191 .input_length = sizeof(enhancedV2_enc),
192 .expected = enhancedV2_text,
193 .expected_septet_length = enhancedV2_septet_length,
194 .ud_hdr_ind = 0,
195 },
196 {
197 .input = concatenated_part1_enc,
198 .input_length = sizeof(concatenated_part1_enc),
199 .expected = splitted_text_part1,
200 .expected_septet_length = concatenated_part1_septet_length_with_header,
201 .ud_hdr_ind = 1,
202 },
203 {
204 .input = concatenated_part2_enc,
205 .input_length = sizeof(concatenated_part2_enc),
206 .expected = splitted_text_part2,
207 .expected_septet_length = concatenated_part2_septet_length_with_header,
208 .ud_hdr_ind = 1,
Holger Hans Peter Freyther31e97ea2010-07-20 02:46:56 +0800209 },
210};
Harald Welteec8b4502010-02-20 20:34:29 +0100211
Holger Hans Peter Freyther6bfa7442013-08-08 12:38:52 +0200212static void test_octet_return()
213{
214 char out[256];
215 int oct, septets;
216
217 printf("Encoding some tests and printing number of septets/octets\n");
218
219 septets = gsm_7bit_encode_oct((uint8_t *) out, "test1234", &oct);
220 printf("SEPTETS: %d OCTETS: %d\n", septets, oct);
221
222 printf("Done\n");
223}
224
Harald Welteec8b4502010-02-20 20:34:29 +0100225int main(int argc, char** argv)
226{
227 printf("SMS testing\n");
228 struct msgb *msg;
Harald Welteec8b4502010-02-20 20:34:29 +0100229 uint8_t i;
230
Dennis Wehrle291e6132011-07-24 20:14:13 +0200231 uint8_t octet_length;
232 uint8_t septet_length;
233 uint8_t gsm_septet_length;
Harald Welteec8b4502010-02-20 20:34:29 +0100234 uint8_t coded[256];
Dennis Wehrle291e6132011-07-24 20:14:13 +0200235 uint8_t tmp[160];
236 uint8_t septet_data[256];
237 uint8_t ud_header[6];
Harald Welteec8b4502010-02-20 20:34:29 +0100238 char result[256];
239
Holger Hans Peter Freyther31e97ea2010-07-20 02:46:56 +0800240 /* test 7-bit encoding */
Nico Goldec0ce9aa2010-07-20 15:43:58 +0200241 for (i = 0; i < ARRAY_SIZE(test_encode); ++i) {
242 memset(coded, 0x42, sizeof(coded));
Dennis Wehrle291e6132011-07-24 20:14:13 +0200243 septet_length = gsm_7bit_encode(coded, test_encode[i].input);
244 octet_length = gsm_get_octet_len(septet_length);
245 if (octet_length != test_encode[i].expected_octet_length) {
246 fprintf(stderr, "Encode case %d: Octet length failure. Got %d, expected %d\n",
247 i, octet_length, test_encode[i].expected_octet_length);
Holger Hans Peter Freyther31e97ea2010-07-20 02:46:56 +0800248 return -1;
249 }
250
Dennis Wehrle291e6132011-07-24 20:14:13 +0200251 if (septet_length != test_encode[i].expected_septet_length){
252 fprintf(stderr, "Encode case %d: Septet length failure. Got %d, expected %d\n",
253 i, septet_length, test_encode[i].expected_septet_length);
254 return -1;
255 }
256
257 if (memcmp(coded, test_encode[i].expected, octet_length) != 0) {
258 fprintf(stderr, "Encoded content does not match for case %d\n",
Holger Hans Peter Freyther31e97ea2010-07-20 02:46:56 +0800259 i);
260 return -1;
261 }
Harald Welteec8b4502010-02-20 20:34:29 +0100262 }
Nico Golde28de0532010-07-09 17:19:12 +0200263
Dennis Wehrle291e6132011-07-24 20:14:13 +0200264
265 /* Test: encode multiple SMS */
266 int number_of_septets = gsm_septet_encode(septet_data, test_multiple_encode[0].input);
267
268 /* SMS part 1 */
269 memset(tmp, 0x42, sizeof(tmp));
270 memset(coded, 0x42, sizeof(coded));
271 memcpy(tmp, septet_data, concatenated_part1_septet_length);
272
273 /* In our case: test_multiple_decode[0].ud_hdr_ind equals number of padding bits*/
274 octet_length = gsm_septets2octets(coded, tmp, concatenated_part1_septet_length, test_multiple_encode[0].ud_hdr_ind);
275
276 /* copy header */
277 memset(tmp, 0x42, sizeof(tmp));
278 int udh_length = test_multiple_encode[0].expected[0] + 1;
279 memcpy(tmp, test_multiple_encode[0].expected, udh_length);
280 memcpy(tmp + udh_length, coded, octet_length);
281 memset(coded, 0x42, sizeof(coded));
282 memcpy(coded, tmp, octet_length + 6);
283
284 if (memcmp(coded, test_multiple_encode[0].expected, octet_length) != 0) {
285 fprintf(stderr, "Multiple-SMS encoded content does not match for part 1\n");
286 return -1;
287 }
288
289
290 /* SMS part 2 */
291 memset(tmp, 0x42, sizeof(tmp));
292 memset(coded, 0x42, sizeof(coded));
293 memcpy(tmp, septet_data + concatenated_part1_septet_length, concatenated_part2_septet_length);
294
295 /* In our case: test_multiple_decode[1].ud_hdr_ind equals number of padding bits*/
296 octet_length = gsm_septets2octets(coded, tmp, concatenated_part2_septet_length, test_multiple_encode[1].ud_hdr_ind);
297
298 /* copy header */
299 memset(tmp, 0x42, sizeof(tmp));
300 udh_length = test_multiple_encode[1].expected[0] + 1;
301 memcpy(tmp, test_multiple_encode[1].expected, udh_length);
302 memcpy(tmp + udh_length, coded, octet_length);
303 memset(coded, 0x42, sizeof(coded));
304 memcpy(coded, tmp, octet_length + 6);
305
306 if (memcmp(coded, test_multiple_encode[1].expected, octet_length) != 0) {
307 fprintf(stderr, "Multiple-SMS encoded content does not match for part 2\n");
308 return -1;
309 }
310
311
312
Holger Hans Peter Freyther31e97ea2010-07-20 02:46:56 +0800313 /* test 7-bit decoding */
314 for (i = 0; i < ARRAY_SIZE(test_decode); ++i) {
Nico Goldec0ce9aa2010-07-20 15:43:58 +0200315 memset(result, 0x42, sizeof(coded));
Dennis Wehrle291e6132011-07-24 20:14:13 +0200316 septet_length = gsm_7bit_decode_hdr(result, test_decode[i].input,
317 test_decode[i].expected_septet_length, test_decode[i].ud_hdr_ind);
Holger Hans Peter Freyther31e97ea2010-07-20 02:46:56 +0800318
319 if (strcmp(result, test_decode[i].expected) != 0) {
320 fprintf(stderr, "Test case %d failed to decode.\n", i);
321 return -1;
322 }
Dennis Wehrle291e6132011-07-24 20:14:13 +0200323 if (septet_length != test_decode[i].expected_septet_length) {
324 fprintf(stderr, "Decode case %d: Septet length failure. Got %d, expected %d\n",
325 i, septet_length, test_decode[i].expected_septet_length);
326 return -1;
327 }
Nico Golde28de0532010-07-09 17:19:12 +0200328 }
329
Holger Hans Peter Freyther6bfa7442013-08-08 12:38:52 +0200330 test_octet_return();
331
Holger Hans Peter Freyther31e97ea2010-07-20 02:46:56 +0800332 printf("OK\n");
Nico Golde28de0532010-07-09 17:19:12 +0200333 return 0;
Harald Welteec8b4502010-02-20 20:34:29 +0100334}