packaging: Bump to 1.17
[platform/upstream/ofono.git] / unit / test-util.c
1 /*
2  *
3  *  oFono - Open Source Telephony
4  *
5  *  Copyright (C) 2008-2011  Intel Corporation. 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 version 2 as
9  *  published by the Free Software Foundation.
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
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <string.h>
27 #include <stdio.h>
28 #include <assert.h>
29 #include <glib.h>
30
31 #include "util.h"
32
33 const unsigned char invalid_gsm_extended[] = {
34         0x1b, 0x15
35 };
36
37 const unsigned char invalid_gsm_extended_len[] = {
38         0x1b, 0x28, 0x1b
39 };
40
41 const unsigned char invalid_ucs2[] = {
42         0x03, 0x93, 0x00, 0x00
43 };
44
45 unsigned short gsm_to_unicode_map[] =
46 {
47 0x00,   0x0040,
48 0x01,   0x00A3,
49 0x02,   0x0024,
50 0x03,   0x00A5,
51 0x04,   0x00E8,
52 0x05,   0x00E9,
53 0x06,   0x00F9,
54 0x07,   0x00EC,
55 0x08,   0x00F2,
56 0x09,   0x00C7,
57 0x0A,   0x000A,
58 0x0B,   0x00D8,
59 0x0C,   0x00F8,
60 0x0D,   0x000D,
61 0x0E,   0x00C5,
62 0x0F,   0x00E5,
63 0x10,   0x0394,
64 0x11,   0x005F,
65 0x12,   0x03A6,
66 0x13,   0x0393,
67 0x14,   0x039B,
68 0x15,   0x03A9,
69 0x16,   0x03A0,
70 0x17,   0x03A8,
71 0x18,   0x03A3,
72 0x19,   0x0398,
73 0x1A,   0x039E,
74 /*0x1B, 0x00A0,*/
75 0x1B0A, 0x000C,
76 0x1B14, 0x005E,
77 0x1B28, 0x007B,
78 0x1B29, 0x007D,
79 0x1B2F, 0x005C,
80 0x1B3C, 0x005B,
81 0x1B3D, 0x007E,
82 0x1B3E, 0x005D,
83 0x1B40, 0x007C,
84 0x1B65, 0x20AC,
85 0x1C,   0x00C6,
86 0x1D,   0x00E6,
87 0x1E,   0x00DF,
88 0x1F,   0x00C9,
89 0x20,   0x0020,
90 0x21,   0x0021,
91 0x22,   0x0022,
92 0x23,   0x0023,
93 0x24,   0x00A4,
94 0x25,   0x0025,
95 0x26,   0x0026,
96 0x27,   0x0027,
97 0x28,   0x0028,
98 0x29,   0x0029,
99 0x2A,   0x002A,
100 0x2B,   0x002B,
101 0x2C,   0x002C,
102 0x2D,   0x002D,
103 0x2E,   0x002E,
104 0x2F,   0x002F,
105 0x30,   0x0030,
106 0x31,   0x0031,
107 0x32,   0x0032,
108 0x33,   0x0033,
109 0x34,   0x0034,
110 0x35,   0x0035,
111 0x36,   0x0036,
112 0x37,   0x0037,
113 0x38,   0x0038,
114 0x39,   0x0039,
115 0x3A,   0x003A,
116 0x3B,   0x003B,
117 0x3C,   0x003C,
118 0x3D,   0x003D,
119 0x3E,   0x003E,
120 0x3F,   0x003F,
121 0x40,   0x00A1,
122 0x41,   0x0041,
123 0x42,   0x0042,
124 0x43,   0x0043,
125 0x44,   0x0044,
126 0x45,   0x0045,
127 0x46,   0x0046,
128 0x47,   0x0047,
129 0x48,   0x0048,
130 0x49,   0x0049,
131 0x4A,   0x004A,
132 0x4B,   0x004B,
133 0x4C,   0x004C,
134 0x4D,   0x004D,
135 0x4E,   0x004E,
136 0x4F,   0x004F,
137 0x50,   0x0050,
138 0x51,   0x0051,
139 0x52,   0x0052,
140 0x53,   0x0053,
141 0x54,   0x0054,
142 0x55,   0x0055,
143 0x56,   0x0056,
144 0x57,   0x0057,
145 0x58,   0x0058,
146 0x59,   0x0059,
147 0x5A,   0x005A,
148 0x5B,   0x00C4,
149 0x5C,   0x00D6,
150 0x5D,   0x00D1,
151 0x5E,   0x00DC,
152 0x5F,   0x00A7,
153 0x60,   0x00BF,
154 0x61,   0x0061,
155 0x62,   0x0062,
156 0x63,   0x0063,
157 0x64,   0x0064,
158 0x65,   0x0065,
159 0x66,   0x0066,
160 0x67,   0x0067,
161 0x68,   0x0068,
162 0x69,   0x0069,
163 0x6A,   0x006A,
164 0x6B,   0x006B,
165 0x6C,   0x006C,
166 0x6D,   0x006D,
167 0x6E,   0x006E,
168 0x6F,   0x006F,
169 0x70,   0x0070,
170 0x71,   0x0071,
171 0x72,   0x0072,
172 0x73,   0x0073,
173 0x74,   0x0074,
174 0x75,   0x0075,
175 0x76,   0x0076,
176 0x77,   0x0077,
177 0x78,   0x0078,
178 0x79,   0x0079,
179 0x7A,   0x007A,
180 0x7B,   0x00E4,
181 0x7C,   0x00F6,
182 0x7D,   0x00F1,
183 0x7E,   0x00FC,
184 0x7F,   0x00E0,
185 };
186
187 unsigned short gsm_turkish_to_unicode_map[] =
188 {
189 0x00, 0x0040,
190 0x01, 0x00A3,
191 0x02, 0x0024,
192 0x03, 0x00A5,
193 0x04, 0x20AC,
194 0x05, 0x00E9,
195 0x06, 0x00F9,
196 0x07, 0x0131,
197 0x08, 0x00F2,
198 0x09, 0x00C7,
199 0x0A, 0x000A,
200 0x0B, 0x011E,
201 0x0C, 0x011F,
202 0x0D, 0x000D,
203 0x0E, 0x00C5,
204 0x0F, 0x00E5,
205 0x10, 0x0394,
206 0x11, 0x005F,
207 0x12, 0x03A6,
208 0x13, 0x0393,
209 0x14, 0x039B,
210 0x15, 0x03A9,
211 0x16, 0x03A0,
212 0x17, 0x03A8,
213 0x18, 0x03A3,
214 0x19, 0x0398,
215 0x1A, 0x039E,
216 /* We're not including some of the single shift codes to this map,
217 * because the turkish variant isn't symmetric, i.e., the same
218 * character is present in both the locking shift table as well as the
219 * single shift table */
220 0x1B0A, 0x000C,
221 0x1B14, 0x005E,
222 0x1B28, 0x007B,
223 0x1B29, 0x007D,
224 0x1B2F, 0x005C,
225 0x1B3C, 0x005B,
226 0x1B3D, 0x007E,
227 0x1B3E, 0x005D,
228 0x1B40, 0x007C,
229 /*0x1B47, 0x011E,*/
230 /*0x1B49, 0x0130,*/
231 /*0x1B53, 0x015E,*/
232 /*0x1B63, 0x00E7,*/
233 /*0x1B65, 0x20AC,*/
234 /*0x1B67, 0x011F,*/
235 /*0x1B69, 0x0131,*/
236 /*0x1B73, 0x015F,*/
237 0x1C, 0x015E,
238 0x1D, 0x015F,
239 0x1E, 0x00DF,
240 0x1F, 0x00C9,
241 0x20, 0x0020,
242 0x21, 0x0021,
243 0x22, 0x0022,
244 0x23, 0x0023,
245 0x24, 0x00A4,
246 0x25, 0x0025,
247 0x26, 0x0026,
248 0x27, 0x0027,
249 0x28, 0x0028,
250 0x29, 0x0029,
251 0x2A, 0x002A,
252 0x2B, 0x002B,
253 0x2C, 0x002C,
254 0x2D, 0x002D,
255 0x2E, 0x002E,
256 0x2F, 0x002F,
257 0x30, 0x0030,
258 0x31, 0x0031,
259 0x32, 0x0032,
260 0x33, 0x0033,
261 0x34, 0x0034,
262 0x35, 0x0035,
263 0x36, 0x0036,
264 0x37, 0x0037,
265 0x38, 0x0038,
266 0x39, 0x0039,
267 0x40, 0x0130,
268 0x3A, 0x003A,
269 0x3B, 0x003B,
270 0x3C, 0x003C,
271 0x3D, 0x003D,
272 0x3E, 0x003E,
273 0x3F, 0x003F,
274 0x40, 0x0130,
275 0x41, 0x0041,
276 0x42, 0x0042,
277 0x43, 0x0043,
278 0x44, 0x0044,
279 0x45, 0x0045,
280 0x46, 0x0046,
281 0x47, 0x0047,
282 0x48, 0x0048,
283 0x49, 0x0049,
284 0x4A, 0x004A,
285 0x4B, 0x004B,
286 0x4C, 0x004C,
287 0x4D, 0x004D,
288 0x4E, 0x004E,
289 0x4F, 0x004F,
290 0x50, 0x0050,
291 0x51, 0x0051,
292 0x52, 0x0052,
293 0x53, 0x0053,
294 0x54, 0x0054,
295 0x55, 0x0055,
296 0x56, 0x0056,
297 0x57, 0x0057,
298 0x58, 0x0058,
299 0x59, 0x0059,
300 0x5A, 0x005A,
301 0x5B, 0x00C4,
302 0x5C, 0x00D6,
303 0x5D, 0x00D1,
304 0x5E, 0x00DC,
305 0x5F, 0x00A7,
306 0x60, 0x00E7,
307 0x61, 0x0061,
308 0x62, 0x0062,
309 0x63, 0x0063,
310 0x64, 0x0064,
311 0x65, 0x0065,
312 0x66, 0x0066,
313 0x67, 0x0067,
314 0x68, 0x0068,
315 0x69, 0x0069,
316 0x6A, 0x006A,
317 0x6B, 0x006B,
318 0x6C, 0x006C,
319 0x6D, 0x006D,
320 0x6E, 0x006E,
321 0x6F, 0x006F,
322 0x70, 0x0070,
323 0x71, 0x0071,
324 0x72, 0x0072,
325 0x73, 0x0073,
326 0x74, 0x0074,
327 0x75, 0x0075,
328 0x76, 0x0076,
329 0x77, 0x0077,
330 0x78, 0x0078,
331 0x79, 0x0079,
332 0x7A, 0x007A,
333 0x7B, 0x00E4,
334 0x7C, 0x00F6,
335 0x7D, 0x00F1,
336 0x7E, 0x00FC,
337 0x7F, 0x00E0
338 };
339
340 #define UTF8_LENGTH(c) \
341         ((c) < 0x80 ? 1 : \
342          ((c) < 0x800 ? 2 : 3))
343
344 static void test_invalid(void)
345 {
346         long nwritten;
347         long nread;
348         short unsigned int exp_code;
349         long exp_res_length;
350         char *res, *exp_res = NULL;
351         unsigned char *gsm;
352
353         res = convert_gsm_to_utf8(invalid_gsm_extended, 0, &nread, &nwritten,
354                                         0);
355         g_assert(res);
356         g_assert(nread == 0);
357         g_assert(nwritten == 0);
358         g_assert(res[0] == '\0');
359         g_free(res);
360
361         /*
362          * In case of invalid GSM extended code, we should display
363          * the character of the main default alphabet table.
364          */
365         res = convert_gsm_to_utf8(invalid_gsm_extended,
366                                         sizeof(invalid_gsm_extended),
367                                         &nread, &nwritten, 0);
368
369         exp_code = gsm_to_unicode_map[invalid_gsm_extended[1]*2 + 1];
370
371         exp_res_length = UTF8_LENGTH(exp_code);
372         exp_res = g_new0(char, exp_res_length + 1);
373         g_unichar_to_utf8(exp_code, exp_res);
374
375         g_assert(g_strcmp0(res, exp_res) == 0);
376         g_assert(nread == exp_res_length);
377         g_free(exp_res);
378         g_free(res);
379
380         res = convert_gsm_to_utf8(invalid_gsm_extended_len,
381                                         sizeof(invalid_gsm_extended_len),
382                                         &nread, &nwritten, 0);
383         g_assert(res == NULL);
384         g_assert(nread == 3);
385
386         gsm = convert_ucs2_to_gsm(invalid_ucs2,
387                                         sizeof(invalid_ucs2),
388                                         &nread, &nwritten, 0);
389         g_assert(gsm == NULL);
390         g_assert(nread == 2);
391
392         nread = 0;
393         gsm = convert_ucs2_to_gsm(invalid_ucs2,
394                                         sizeof(invalid_ucs2) - 1,
395                                         &nread, &nwritten, 0);
396         g_assert(gsm == NULL);
397         g_assert(nread == 0);
398 }
399
400 static void test_valid(void)
401 {
402         long nwritten;
403         long nread;
404         char *res;
405         int i;
406         long size;
407         gunichar *verify;
408         unsigned char *back;
409
410         unsigned char buf[2];
411
412         static int map_size =
413                 sizeof(gsm_to_unicode_map) / sizeof(unsigned short) / 2;
414
415         for (i = 0; i < map_size; i++) {
416                 unsigned short c = gsm_to_unicode_map[i*2];
417
418                 if (c & 0x1b00) {
419                         buf[0] = 0x1b;
420                         buf[1] = c & 0x7f;
421                         size = 2;
422                 } else {
423                         size = 1;
424                         buf[0] = c & 0x7f;
425                 }
426
427                 res = convert_gsm_to_utf8(buf, size, &nread, &nwritten, 0);
428                 g_assert(res);
429
430                 if (g_test_verbose())
431                         g_print("size: %ld, nread:%ld, nwritten:%ld, %s\n",
432                                 size, nread, nwritten, res);
433
434                 g_assert(nread == size);
435
436                 verify = g_utf8_to_ucs4(res, -1, NULL, NULL, NULL);
437
438                 g_assert(verify[0] == gsm_to_unicode_map[i*2+1]);
439                 g_assert(verify[1] == 0);
440
441                 g_assert(nwritten == UTF8_LENGTH(verify[0]));
442
443                 back = convert_utf8_to_gsm(res, -1, &nread, &nwritten, 0);
444
445                 g_assert(back);
446
447                 g_assert(nwritten == size);
448
449                 if (c & 0x1b00) {
450                         g_assert(back[0] == 0x1b);
451                         g_assert(back[1] == (c & 0x7f));
452                 } else {
453                         g_assert(back[0] == (c & 0x7f));
454                 }
455
456                 g_free(back);
457                 g_free(verify);
458                 g_free(res);
459         }
460 }
461
462 static void test_valid_turkish(void)
463 {
464         long nwritten;
465         long nread;
466         char *res;
467         int i;
468         long size;
469         gunichar *verify;
470         unsigned char *back;
471
472         unsigned char buf[2];
473
474         static int map_size =
475                 sizeof(gsm_turkish_to_unicode_map) / sizeof(unsigned short) / 2;
476
477         for (i = 0; i < map_size; i++) {
478                 unsigned short c = gsm_turkish_to_unicode_map[i*2];
479
480                 if (c & 0x1b00) {
481                         buf[0] = 0x1b;
482                         buf[1] = c & 0x7f;
483                         size = 2;
484                 } else {
485                         size = 1;
486                         buf[0] = c & 0x7f;
487                 }
488
489                 res = convert_gsm_to_utf8_with_lang(buf, size, &nread,
490                                                         &nwritten, 0, 1, 1);
491                 g_assert(res);
492
493                 if (g_test_verbose())
494                         g_print("size: %ld, nread:%ld, nwritten:%ld, %s\n",
495                                 size, nread, nwritten, res);
496
497                 g_assert(nread == size);
498
499                 verify = g_utf8_to_ucs4(res, -1, NULL, NULL, NULL);
500
501                 g_assert(verify[0] == gsm_turkish_to_unicode_map[i*2+1]);
502                 g_assert(verify[1] == 0);
503
504                 g_assert(nwritten == UTF8_LENGTH(verify[0]));
505
506                 back = convert_utf8_to_gsm_with_lang(res, -1, &nread,
507                                                         &nwritten, 0, 1, 1);
508
509                 g_assert(back);
510
511                 g_assert(nwritten == size);
512
513                 if (c & 0x1b00) {
514                         g_assert(back[0] == 0x1b);
515                         g_assert(back[1] == (c & 0x7f));
516                 } else {
517                         g_assert(back[0] == (c & 0x7f));
518                 }
519
520                 g_free(back);
521                 g_free(verify);
522                 g_free(res);
523         }
524 }
525
526 static const char hex_packed_sms[] = "493A283D0795C3F33C88FE06C9CB6132885EC6D34"
527                                         "1EDF27C1E3E97E7207B3A0C0A5241E377BB1D"
528                                         "7693E72E";
529 static const char expected[] = "It is easy to read text messages via AT "
530                                 "commands.";
531 static int reported_text_size = 49;
532
533 static void test_decode_encode(void)
534 {
535         const char *sms = hex_packed_sms;
536         unsigned char *decoded, *packed;
537         char *utf8, *hex_packed;
538         unsigned char *gsm, *gsm_encoded;
539         long hex_decoded_size;
540         long unpacked_size, packed_size;
541         long gsm_encoded_size;
542         long i;
543
544         if (g_test_verbose())
545                 g_print("Size of the orig string: %u\n",
546                         (unsigned int)strlen(sms));
547
548         decoded = decode_hex(sms, -1, &hex_decoded_size, 0);
549
550         g_assert(decoded != NULL);
551
552         if (g_test_verbose())
553                 g_print("Decode to %ld bytes\n", hex_decoded_size);
554
555         if (g_test_verbose()) {
556                 g_print("%s\n", sms);
557
558                 for (i = 0; i < hex_decoded_size; i++)
559                         g_print("%02X", decoded[i]);
560                 g_print("\n");
561         }
562
563         gsm = unpack_7bit(decoded, hex_decoded_size, 0, FALSE,
564                                 reported_text_size, &unpacked_size, 0xff);
565
566         g_assert(gsm != NULL);
567
568         if (g_test_verbose())
569                 g_print("String unpacked to %ld bytes\n", unpacked_size);
570
571         utf8 = convert_gsm_to_utf8(gsm, -1, NULL, NULL, 0xff);
572
573         g_assert(utf8 != NULL);
574
575         if (g_test_verbose())
576                 g_print("String is: -->%s<--\n", utf8);
577
578         g_assert(strcmp(utf8, expected) == 0);
579
580         gsm_encoded = convert_utf8_to_gsm(utf8, -1, NULL,
581                                                 &gsm_encoded_size, 0xff);
582
583         g_assert(gsm_encoded != NULL);
584
585         if (g_test_verbose())
586                 g_print("Converted back to GSM string of %ld bytes\n",
587                                 gsm_encoded_size);
588
589         g_assert(gsm_encoded[gsm_encoded_size] == 0xff);
590         g_assert(gsm_encoded_size == unpacked_size);
591         g_assert(memcmp(gsm_encoded, gsm, gsm_encoded_size) == 0);
592
593         g_free(utf8);
594         g_free(gsm);
595
596         packed = pack_7bit(gsm_encoded, -1, 0, FALSE, &packed_size, 0xff);
597
598         g_free(gsm_encoded);
599
600         g_assert(packed != NULL);
601
602         if (g_test_verbose())
603                 g_print("Packed GSM to size of %ld bytes\n", packed_size);
604
605         if (g_test_verbose()) {
606                 for (i = 0; i < packed_size; i++)
607                         g_print("%02X", packed[i]);
608                 g_print("\n");
609         }
610
611         g_assert(packed_size == hex_decoded_size);
612         g_assert(memcmp(packed, decoded, packed_size) == 0);
613
614         g_free(decoded);
615
616         hex_packed = encode_hex(packed, packed_size, 0);
617
618         g_assert(hex_packed != NULL);
619
620         g_free(packed);
621
622         if (g_test_verbose())
623                 g_print("Hex encoded packed to size %ld bytes\n",
624                                 (long)strlen(hex_packed));
625
626         g_assert(strlen(hex_packed) == strlen(sms));
627         g_assert(strcmp(hex_packed, sms) == 0);
628
629         g_free(hex_packed);
630 }
631
632 static void test_pack_size(void)
633 {
634         unsigned char c1[] = { 'a' };
635         unsigned char c2[] = { 'a', 'b' };
636         unsigned char c3[] = { 'a', 'b', 'c' };
637         unsigned char c4[] = { 'a', 'b', 'c', 'd' };
638         unsigned char c5[] = { 'a', 'b', 'c', 'd', 'e' };
639         unsigned char c6[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
640         unsigned char c7[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g' };
641         unsigned char c8[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' };
642
643         unsigned char *packed;
644         long size;
645
646         packed = pack_7bit(c1, 1, 0, FALSE, &size, 0);
647         g_assert(packed != NULL);
648         g_assert(size == 1);
649         g_free(packed);
650
651         packed = pack_7bit(c2, 2, 0, FALSE, &size, 0);
652         g_assert(packed != NULL);
653         g_assert(size == 2);
654         g_free(packed);
655
656         packed = pack_7bit(c3, 3, 0, FALSE, &size, 0);
657         g_assert(packed != NULL);
658         g_assert(size == 3);
659         g_free(packed);
660
661         packed = pack_7bit(c4, 4, 0, FALSE, &size, 0);
662         g_assert(packed != NULL);
663         g_assert(size == 4);
664         g_free(packed);
665
666         packed = pack_7bit(c5, 5, 0, FALSE, &size, 0);
667         g_assert(packed != NULL);
668         g_assert(size == 5);
669         g_free(packed);
670
671         packed = pack_7bit(c6, 6, 0, FALSE, &size, 0);
672         g_assert(packed != NULL);
673         g_assert(size == 6);
674         g_free(packed);
675
676         packed = pack_7bit(c7, 7, 0, FALSE, &size, 0);
677         g_assert(packed != NULL);
678         g_assert(size == 7);
679         g_assert((packed[6] & 0xfe) == 0);
680         g_free(packed);
681
682         packed = pack_7bit(c7, 7, 0, TRUE, &size, 0);
683         g_assert(packed != NULL);
684         g_assert(size == 7);
685         g_assert(((packed[6] & 0xfe) >> 1) == '\r');
686         g_free(packed);
687
688         packed = pack_7bit(c8, 8, 0, FALSE, &size, 0);
689         g_assert(packed != NULL);
690         g_assert(size == 7);
691         g_free(packed);
692 }
693
694 static void test_cr_handling(void)
695 {
696         unsigned char c7[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g' };
697         unsigned char c7_expected[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g',
698                                         '\r' };
699         unsigned char c8[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', '\r' };
700         unsigned char c8_expected[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g',
701                                         '\r', '\r' };
702
703         unsigned char *packed;
704         unsigned char *unpacked;
705         long packed_size;
706         long unpacked_size;
707
708         packed = pack_7bit(c8, 8, 0, TRUE, &packed_size, 0);
709         g_assert(packed != NULL);
710         g_assert(packed_size == 8);
711         g_assert(((packed[6] & 0xfe) >> 1) == '\r');
712         g_assert((packed[7] & 0x7f) == '\r');
713
714         unpacked = unpack_7bit(packed, 8, 0, TRUE, -1, &unpacked_size, 0);
715         if (g_test_verbose())
716                 g_print("Unpacked to size: %ld\n", unpacked_size);
717
718         g_assert(unpacked != NULL);
719         g_assert(unpacked_size == 9);
720         g_assert(memcmp(c8_expected, unpacked, 9) == 0);
721
722         g_free(unpacked);
723         g_free(packed);
724
725         packed = pack_7bit(c7, 7, 0, TRUE, &packed_size, 0);
726         g_assert(packed != NULL);
727         g_assert(packed_size == 7);
728         g_assert(((packed[6] & 0xfe) >> 1) == '\r');
729
730         unpacked = unpack_7bit(packed, 7, 0, TRUE, -1, &unpacked_size, 0);
731         if (g_test_verbose())
732                 g_print("Unpacked to size: %ld\n", unpacked_size);
733
734         g_assert(unpacked != NULL);
735         g_assert(unpacked_size == 7);
736         g_assert(memcmp(c7, unpacked, 7) == 0);
737
738         g_free(unpacked);
739         g_free(packed);
740
741         /* As above, but now unpack using SMS style, we should now have cr at
742          * the end of the stream
743          */
744         packed = pack_7bit(c7, 7, 0, TRUE, &packed_size, 0);
745         unpacked = unpack_7bit(packed, 7, 0, FALSE, 8, &unpacked_size, 0);
746         if (g_test_verbose())
747                 g_print("Unpacked to size: %ld\n", unpacked_size);
748
749         g_assert(unpacked != NULL);
750         g_assert(unpacked_size == 8);
751         g_assert(memcmp(c7_expected, unpacked, 8) == 0);
752
753         g_free(unpacked);
754         g_free(packed);
755 }
756
757 static void test_sms_handling(void)
758 {
759         unsigned char c7[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g' };
760
761         unsigned char *packed;
762         unsigned char *unpacked;
763         long packed_size;
764         long unpacked_size;
765
766         packed = pack_7bit(c7, 7, 0, FALSE, &packed_size, 0);
767         g_assert(packed != NULL);
768         g_assert(packed_size == 7);
769
770         unpacked = unpack_7bit(packed, 7, 0, FALSE, 8, &unpacked_size, 0xff);
771         if (g_test_verbose())
772                 g_print("Unpacked to size: %ld\n", unpacked_size);
773
774         g_assert(unpacked != NULL);
775         g_assert(unpacked_size == 8);
776         g_assert(unpacked[7] == 0);
777         g_assert(unpacked[8] == 0xff);
778
779         g_free(unpacked);
780         g_free(packed);
781
782         packed = pack_7bit(c7, 7, 0, FALSE, &packed_size, 0);
783         g_assert(packed != NULL);
784         g_assert(packed_size == 7);
785
786         unpacked = unpack_7bit(packed, 7, 0, FALSE, 7, &unpacked_size, 0xff);
787         if (g_test_verbose())
788                 g_print("Unpacked to size: %ld\n", unpacked_size);
789
790         g_assert(unpacked != NULL);
791         g_assert(unpacked_size == 7);
792         g_assert(unpacked[7] == 0xff);
793
794         g_free(unpacked);
795         g_free(packed);
796 }
797
798 static void test_offset_handling(void)
799 {
800         unsigned char c7[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g' };
801         unsigned char c8[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' };
802         unsigned char c9[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i' };
803         unsigned char *packed;
804         unsigned char *unpacked;
805         long packed_size;
806         long unpacked_size;
807
808         /* Pack at offset = 2 bytes, e.g. starting with 21st bit */
809         packed = pack_7bit(c7, 6, 2, FALSE, &packed_size, 0);
810
811         if (g_test_verbose())
812                 g_print("Packed to size: %ld\n", packed_size);
813
814         g_assert(packed != NULL);
815         g_assert(packed_size == 6);
816
817         unpacked = unpack_7bit(packed, 6, 2, FALSE, 6, &unpacked_size, 0xff);
818         if (g_test_verbose())
819                 g_print("Unpacked to size: %ld\n", unpacked_size);
820
821         g_assert(unpacked != NULL);
822         g_assert(unpacked_size == 6);
823         g_assert(unpacked[6] == 0xff);
824         g_assert(unpacked[0] == 'a');
825         g_assert(unpacked[5] == 'f');
826
827         g_free(unpacked);
828         g_free(packed);
829
830         /* Pack at offset = 6 bytes, we should be able to fit one character
831          * into the first byte, and the other 7 characters into the following
832          * 7 bytes.  The 7 MSB bits of the last byte should be 0 since
833          * we're not using CBS packing
834          */
835         packed = pack_7bit(c8, 8, 6, FALSE, &packed_size, 0);
836
837         if (g_test_verbose())
838                 g_print("Packed to size: %ld\n", packed_size);
839
840         g_assert(packed != NULL);
841         g_assert(packed_size == 8);
842
843         unpacked = unpack_7bit(packed, 8, 6, FALSE, 8, &unpacked_size, 0xff);
844         if (g_test_verbose())
845                 g_print("Unpacked to size: %ld\n", unpacked_size);
846
847         g_assert(unpacked != NULL);
848         g_assert(unpacked_size == 8);
849         g_assert(unpacked[8] == 0xff);
850         g_assert(unpacked[0] == 'a');
851         g_assert(unpacked[7] == 'h');
852
853         g_free(unpacked);
854         g_free(packed);
855
856         /* Same as above, but instead pack in 9 characters */
857         packed = pack_7bit(c9, 9, 6, FALSE, &packed_size, 0);
858
859         if (g_test_verbose())
860                 g_print("Packed to size: %ld\n", packed_size);
861
862         g_assert(packed != NULL);
863         g_assert(packed_size == 8);
864
865         unpacked = unpack_7bit(packed, 8, 6, FALSE, 9, &unpacked_size, 0xff);
866         if (g_test_verbose())
867                 g_print("Unpacked to size: %ld\n", unpacked_size);
868
869         g_assert(unpacked != NULL);
870         g_assert(unpacked_size == 9);
871         g_assert(unpacked[9] == 0xff);
872         g_assert(unpacked[0] == 'a');
873         g_assert(unpacked[8] == 'i');
874
875         g_free(unpacked);
876         g_free(packed);
877 }
878
879 static unsigned char sim_7bit[] = { 0x6F, 0x46, 0x6F, 0x6E, 0x6F, 0xFF, 0xFF };
880 static unsigned char sim_80_1[] = { 0x80, 0x00, 0x6F, 0x00, 0x6E, 0x00,
881                                         0x6F };
882 static unsigned char sim_80_2[] = { 0x80, 0x00, 0x6F, 0x00, 0x6E, 0x00,
883                                         0x6F, 0xFF, 0xFF, 0xFF};
884 static unsigned char sim_80_3[] = { 0x80, 0x00, 0x6F, 0x00, 0x6E, 0x00,
885                                         0x6F, 0xFF, 0xFF};
886 static unsigned char sim_81_0[] = { 0x81, 0x05, 0x13, 0x53, 0x95, 0xA6,
887                                         0xA6, 0xFF, 0xFF };
888 static unsigned char sim_81_1[] = { 0x81, 0x03, 0x00, 0x6F, 0x6E, 0x6F, 0xFF };
889 static unsigned char sim_81_2[] = { 0x81, 0x05, 0x08, 0xB3, 0xB4, 0xB5, 0x53,
890                                         0x54, 0xFF, 0xFF, 0xFF };
891 static unsigned char sim_82_0[] = { 0x82, 0x05, 0x05, 0x30, 0x2D, 0x82,
892                                         0xD3, 0x2D, 0x31 };
893 static unsigned char sim_82_1[] = { 0x82, 0x05, 0x04, 0x00, 0x2D, 0xB3, 0xB4,
894                                         0x2D, 0x31 };
895 static unsigned char sim_82_2[] = { 0x82, 0x05, 0xD8, 0x00, 0x2D, 0xB3, 0xB4,
896                                         0x2D, 0x31 };
897 static unsigned char sim_7bit_empty[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
898
899 static void test_sim(void)
900 {
901         char *utf8;
902
903         utf8 = sim_string_to_utf8(sim_7bit, sizeof(sim_7bit));
904
905         g_assert(utf8);
906         g_assert(strcmp(utf8, "oFono") == 0);
907         g_free(utf8);
908
909         utf8 = sim_string_to_utf8(sim_80_1, sizeof(sim_80_1));
910         g_assert(utf8);
911         g_assert(strcmp(utf8, "ono") == 0);
912         g_free(utf8);
913
914         utf8 = sim_string_to_utf8(sim_80_2, sizeof(sim_80_2));
915         g_assert(utf8);
916         g_assert(strcmp(utf8, "ono") == 0);
917         g_free(utf8);
918
919         utf8 = sim_string_to_utf8(sim_80_3, sizeof(sim_80_3));
920         g_assert(utf8);
921         g_assert(strcmp(utf8, "ono") == 0);
922         g_free(utf8);
923
924         utf8 = sim_string_to_utf8(sim_81_0, sizeof(sim_81_0));
925         g_assert(utf8);
926         g_free(utf8);
927
928         utf8 = sim_string_to_utf8(sim_81_2, sizeof(sim_81_2));
929         g_assert(utf8);
930         g_free(utf8);
931
932         utf8 = sim_string_to_utf8(sim_81_1, sizeof(sim_81_1));
933         g_assert(utf8);
934         g_assert(strcmp(utf8, "ono") == 0);
935         g_free(utf8);
936
937         utf8 = sim_string_to_utf8(sim_82_0, sizeof(sim_82_0));
938         g_assert(utf8);
939         g_free(utf8);
940
941         utf8 = sim_string_to_utf8(sim_82_1, sizeof(sim_82_1));
942         g_assert(utf8);
943         g_free(utf8);
944
945         utf8 = sim_string_to_utf8(sim_82_2, sizeof(sim_82_2));
946         g_assert(utf8 == NULL);
947
948         utf8 = sim_string_to_utf8(sim_7bit_empty, sizeof(sim_7bit_empty));
949         g_assert(utf8);
950         g_assert(strcmp(utf8, "") == 0);
951         g_free(utf8);
952 }
953
954 static void test_unicode_to_gsm(void)
955 {
956         long nwritten;
957         long nread;
958         int i;
959         unsigned char *res;
960         char *utf8;
961         unsigned char buf[2];
962         unsigned char *back;
963         gunichar2 verify;
964
965         static int map_size =
966                 sizeof(gsm_to_unicode_map) / sizeof(unsigned short) / 2;
967
968         for (i = 0; i < map_size; i++) {
969                 unsigned short c = gsm_to_unicode_map[i*2+1];
970
971                 buf[0] = c >> 8;
972                 buf[1] = c & 0xff;
973
974                 res = convert_ucs2_to_gsm(buf, 2, &nread, &nwritten, 0);
975                 g_assert(res);
976
977                 if (g_test_verbose())
978                         g_print("nread:%ld, nwritten:%ld, %s\n",
979                                 nread, nwritten, res);
980
981                 if (res[0] == 0x1B)
982                         g_assert(nwritten == 2);
983                 else
984                         g_assert(nwritten == 1);
985
986                 utf8 = g_convert((const gchar *) buf, 2,
987                                 "UTF-8", "UCS-2BE",
988                                 NULL, NULL, NULL);
989                 g_assert(utf8);
990
991                 back = convert_utf8_to_gsm(utf8, strlen(utf8), &nread,
992                                                 &nwritten, 0);
993                 g_assert(back);
994
995                 if (back[0] == 0x1B) {
996                         g_assert(nwritten == 2);
997                         verify = back[0] << 8 | back[1];
998                 } else {
999                         g_assert(nwritten == 1);
1000                         verify = back[0];
1001                 }
1002
1003                 if (g_test_verbose())
1004                         g_print("nwritten:%ld, verify: 0x%x\n",
1005                                 nwritten, verify);
1006
1007                 g_assert(verify == gsm_to_unicode_map[i*2]);
1008
1009                 g_free(res);
1010                 g_free(back);
1011                 g_free(utf8);
1012         }
1013 }
1014
1015 int main(int argc, char **argv)
1016 {
1017         g_test_init(&argc, &argv, NULL);
1018
1019         g_test_add_func("/testutil/Invalid Conversions", test_invalid);
1020         g_test_add_func("/testutil/Valid Conversions", test_valid);
1021         g_test_add_func("/testutil/Valid Turkish National Variant Conversions",
1022                         test_valid_turkish);
1023         g_test_add_func("/testutil/Decode Encode", test_decode_encode);
1024         g_test_add_func("/testutil/Pack Size", test_pack_size);
1025         g_test_add_func("/testutil/CBS CR Handling", test_cr_handling);
1026         g_test_add_func("/testutil/SMS Handling", test_sms_handling);
1027         g_test_add_func("/testutil/Offset Handling", test_offset_handling);
1028         g_test_add_func("/testutil/SIM conversions", test_sim);
1029         g_test_add_func("/testutil/Valid Unicode to GSM Conversion",
1030                         test_unicode_to_gsm);
1031
1032         return g_test_run();
1033 }