packaging: Bump to 1.17
[platform/upstream/ofono.git] / unit / test-sms.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 <stdio.h>
27 #include <unistd.h>
28 #include <stdlib.h>
29 #include <string.h>
30
31 #include <glib.h>
32 #include <glib/gprintf.h>
33
34 #include "util.h"
35 #include "smsutil.h"
36
37 static const char *simple_deliver = "07911326040000F0"
38                 "040B911346610089F60000208062917314480CC8F71D14969741F977FD07";
39 static const char *alnum_sender = "0791447758100650"
40                 "040DD0F334FC1CA6970100008080312170224008D4F29CDE0EA7D9";
41 static const char *unicode_deliver = "04819999990414D0FBFD7EBFDFEFF77BFE1E001"
42                 "9512090801361807E00DC00FC00C400E400D600F600C500E500D800F800C"
43                 "600E600C700E700C900E900CA00EA00DF003100320033003400350036003"
44                 "7003800390030002000540068006900730020006D0065007300730061006"
45                 "7006500200069007300200036003300200075006E00690063006F0064006"
46                 "5002000630068006100720073002E";
47 static const char *simple_submit = "0011000B916407281553F80000AA"
48                 "0AE8329BFD4697D9EC37";
49
50 static const char *simple_mwi = "07913366002020F8040B913366600600F100C8318070"
51                                 "6174148000";
52
53 static void print_scts(struct sms_scts *scts, const char *prefix)
54 {
55         time_t ts;
56         struct tm remote;
57         char buf[128];
58
59         g_print("%s: (YY-MM-DD) %02d-%02d-%02d\n", prefix,
60                 (int)scts->year, (int)scts->month, (int)scts->day);
61
62         g_print("%s: (HH-MM-SS) %02d:%02d:%02d\n", prefix,
63                 (int)scts->hour, (int)scts->minute, (int)scts->second);
64
65         g_print("%s: Timezone %d hours %d minutes\n", prefix,
66                 (int)scts->timezone / 4,
67                 (int)((abs(scts->timezone) % 4) * 15));
68
69         ts = sms_scts_to_time(scts, &remote);
70
71         strftime(buf, 127, "%Y-%m-%dT%H:%M:%S%z", localtime(&ts));
72         buf[127] = '\0';
73
74         g_print("local time: %s\n", buf);
75
76         strftime(buf, 127, "%Y-%m-%dT%H:%M:%S%z", &remote);
77         buf[127] = '\0';
78
79         g_print("remote time: %s\n", buf);
80 }
81
82 static void print_vpf(enum sms_validity_period_format vpf,
83                         struct sms_validity_period *vp)
84 {
85         g_print("Validity Period Format: %d\n", (int)vpf);
86
87         switch (vpf) {
88         case SMS_VALIDITY_PERIOD_FORMAT_ABSENT:
89                 g_print("Validity-Period: Absent\n");
90                 break;
91         case SMS_VALIDITY_PERIOD_FORMAT_RELATIVE:
92                 g_print("Validity-Period: %d\n",
93                         (int)vp->relative);
94                 break;
95         case SMS_VALIDITY_PERIOD_FORMAT_ABSOLUTE:
96                 print_scts(&vp->absolute, "Validity-Period:");
97                 break;
98         case SMS_VALIDITY_PERIOD_FORMAT_ENHANCED:
99                 g_print("Validity-Period: Enhanced");
100                 break;
101         }
102 }
103
104 static void dump_details(struct sms *sms)
105 {
106         if (sms->sc_addr.address[0] == '\0')
107                 g_print("SMSC Address absent, default will be used\n");
108         else
109                 g_print("SMSC Address number_type: %d, number_plan: %d, %s\n",
110                         (int)sms->sc_addr.number_type,
111                         (int)sms->sc_addr.numbering_plan, sms->sc_addr.address);
112
113         switch (sms->type) {
114         case SMS_TYPE_DELIVER:
115                 g_print("Type: Deliver\n");
116
117                 g_print("Originator-Address: %d, %d, %s\n",
118                         (int)sms->deliver.oaddr.number_type,
119                         (int)sms->deliver.oaddr.numbering_plan,
120                         sms->deliver.oaddr.address);
121
122                 g_print("PID: %d\n", (int)sms->deliver.pid);
123                 g_print("DCS: %d\n", (int)sms->deliver.dcs);
124
125                 print_scts(&sms->deliver.scts, "Timestamp");
126
127                 break;
128         case SMS_TYPE_SUBMIT:
129                 g_print("Type: Submit\n");
130
131                 g_print("Message Reference: %u\n", (int)sms->submit.mr);
132
133                 g_print("Destination-Address: %d, %d, %s\n",
134                         (int)sms->submit.daddr.number_type,
135                         (int)sms->submit.daddr.numbering_plan,
136                         sms->submit.daddr.address);
137
138                 g_print("PID: %d\n", (int)sms->submit.pid);
139                 g_print("DCS: %d\n", (int)sms->submit.dcs);
140
141                 print_vpf(sms->submit.vpf, &sms->submit.vp);
142
143                 break;
144         case SMS_TYPE_STATUS_REPORT:
145                 break;
146         case SMS_TYPE_COMMAND:
147         case SMS_TYPE_DELIVER_REPORT_ACK:
148         case SMS_TYPE_DELIVER_REPORT_ERROR:
149         case SMS_TYPE_SUBMIT_REPORT_ACK:
150         case SMS_TYPE_SUBMIT_REPORT_ERROR:
151                 break;
152         }
153 }
154
155 static void test_simple_deliver(void)
156 {
157         struct sms sms;
158         unsigned char *decoded_pdu;
159         long pdu_len;
160         gboolean ret;
161         int data_len;
162         unsigned char *unpacked;
163         char *utf8;
164
165         decoded_pdu = decode_hex(simple_deliver, -1, &pdu_len, 0);
166
167         g_assert(decoded_pdu);
168         g_assert(pdu_len == (long)strlen(simple_deliver) / 2);
169
170         ret = sms_decode(decoded_pdu, pdu_len, FALSE, 30, &sms);
171
172         g_free(decoded_pdu);
173
174         g_assert(ret);
175         g_assert(sms.type == SMS_TYPE_DELIVER);
176
177         if (g_test_verbose())
178                 dump_details(&sms);
179
180         g_assert(sms.sc_addr.number_type == SMS_NUMBER_TYPE_INTERNATIONAL);
181         g_assert(sms.sc_addr.numbering_plan == SMS_NUMBERING_PLAN_ISDN);
182         g_assert(strcmp(sms.sc_addr.address, "31624000000") == 0);
183
184         g_assert(sms.deliver.oaddr.number_type ==
185                         SMS_NUMBER_TYPE_INTERNATIONAL);
186         g_assert(sms.deliver.oaddr.numbering_plan ==
187                         SMS_NUMBERING_PLAN_ISDN);
188         g_assert(strcmp(sms.deliver.oaddr.address, "31641600986") == 0);
189
190         g_assert(sms.deliver.pid == 0);
191         g_assert(sms.deliver.dcs == 0);
192
193         g_assert(sms.deliver.scts.year == 2);
194         g_assert(sms.deliver.scts.month == 8);
195         g_assert(sms.deliver.scts.day == 26);
196         g_assert(sms.deliver.scts.hour == 19);
197         g_assert(sms.deliver.scts.minute == 37);
198         g_assert(sms.deliver.scts.second == 41);
199         g_assert(sms.deliver.scts.timezone == -4);
200
201         g_assert(sms.deliver.udl == 12);
202
203         data_len = sms_udl_in_bytes(sms.deliver.udl, sms.deliver.dcs);
204
205         g_assert(data_len == 11);
206
207         unpacked = unpack_7bit(sms.deliver.ud, data_len, 0, FALSE,
208                                 sms.deliver.udl, NULL, 0xff);
209
210         g_assert(unpacked);
211
212         utf8 = convert_gsm_to_utf8(unpacked, -1, NULL, NULL, 0xff);
213
214         g_free(unpacked);
215
216         g_assert(utf8);
217
218         if (g_test_verbose())
219                 g_print("Decoded user data is: %s\n", utf8);
220
221         g_assert(strcmp(utf8, "How are you?") == 0);
222
223         g_free(utf8);
224 }
225
226 static void test_alnum_sender(void)
227 {
228         struct sms sms;
229         unsigned char *decoded_pdu;
230         long pdu_len;
231         gboolean ret;
232         int data_len;
233         unsigned char *unpacked;
234         char *utf8;
235
236         decoded_pdu = decode_hex(alnum_sender, -1, &pdu_len, 0);
237
238         g_assert(decoded_pdu);
239         g_assert(pdu_len == (long)strlen(alnum_sender) / 2);
240
241         ret = sms_decode(decoded_pdu, pdu_len, FALSE, 27, &sms);
242
243         g_free(decoded_pdu);
244
245         g_assert(ret);
246         g_assert(sms.type == SMS_TYPE_DELIVER);
247
248         if (g_test_verbose())
249                 dump_details(&sms);
250
251         g_assert(sms.sc_addr.number_type == SMS_NUMBER_TYPE_INTERNATIONAL);
252         g_assert(sms.sc_addr.numbering_plan == SMS_NUMBERING_PLAN_ISDN);
253         g_assert(strcmp(sms.sc_addr.address, "447785016005") == 0);
254
255         g_assert(sms.deliver.oaddr.number_type ==
256                         SMS_NUMBER_TYPE_ALPHANUMERIC);
257         g_assert(sms.deliver.oaddr.numbering_plan ==
258                         SMS_NUMBERING_PLAN_UNKNOWN);
259         g_assert(strcmp(sms.deliver.oaddr.address, "sipgate") == 0);
260
261         g_assert(sms.deliver.pid == 0);
262         g_assert(sms.deliver.dcs == 0);
263
264         g_assert(sms.deliver.scts.year == 8);
265         g_assert(sms.deliver.scts.month == 8);
266         g_assert(sms.deliver.scts.day == 13);
267         g_assert(sms.deliver.scts.hour == 12);
268         g_assert(sms.deliver.scts.minute == 07);
269         g_assert(sms.deliver.scts.second == 22);
270         g_assert(sms.deliver.scts.timezone == 4);
271
272         g_assert(sms.deliver.udl == 8);
273
274         data_len = sms_udl_in_bytes(sms.deliver.udl, sms.deliver.dcs);
275
276         g_assert(data_len == 7);
277
278         unpacked = unpack_7bit(sms.deliver.ud, data_len, 0, FALSE,
279                                 sms.deliver.udl, NULL, 0xff);
280
281         g_assert(unpacked);
282
283         utf8 = convert_gsm_to_utf8(unpacked, -1, NULL, NULL, 0xff);
284
285         g_free(unpacked);
286
287         g_assert(utf8);
288
289         if (g_test_verbose())
290                 g_print("Decoded user data is: %s\n", utf8);
291
292         g_assert(strcmp(utf8, "Testmail") == 0);
293
294         g_free(utf8);
295 }
296
297 static void test_deliver_encode(void)
298 {
299         struct sms sms;
300         unsigned char *decoded_pdu;
301         long pdu_len;
302         gboolean ret;
303         unsigned char pdu[176];
304         int encoded_pdu_len;
305         int encoded_tpdu_len;
306         char *encoded_pdu;
307
308         decoded_pdu = decode_hex(simple_deliver, -1, &pdu_len, 0);
309
310         g_assert(decoded_pdu);
311         g_assert(pdu_len == (long)strlen(simple_deliver) / 2);
312
313         ret = sms_decode(decoded_pdu, pdu_len, FALSE, 30, &sms);
314
315         g_free(decoded_pdu);
316
317         g_assert(ret);
318         g_assert(sms.type == SMS_TYPE_DELIVER);
319
320         ret = sms_encode(&sms, &encoded_pdu_len, &encoded_tpdu_len, pdu);
321
322         if (g_test_verbose()) {
323                 int i;
324
325                 for (i = 0; i < encoded_pdu_len; i++)
326                         g_print("%02X", pdu[i]);
327                 g_print("\n");
328         }
329
330         g_assert(ret);
331         g_assert(encoded_tpdu_len == 30);
332         g_assert(encoded_pdu_len == pdu_len);
333
334         encoded_pdu = encode_hex(pdu, encoded_pdu_len, 0);
335
336         g_assert(strcmp(simple_deliver, encoded_pdu) == 0);
337
338         g_free(encoded_pdu);
339
340         decoded_pdu = decode_hex(alnum_sender, -1, &pdu_len, 0);
341
342         g_assert(decoded_pdu);
343         g_assert(pdu_len == (long)strlen(alnum_sender) / 2);
344
345         ret = sms_decode(decoded_pdu, pdu_len, FALSE, 27, &sms);
346
347         g_free(decoded_pdu);
348
349         g_assert(ret);
350         g_assert(sms.type == SMS_TYPE_DELIVER);
351
352         ret = sms_encode(&sms, &encoded_pdu_len, &encoded_tpdu_len, pdu);
353
354         if (g_test_verbose()) {
355                 int i;
356
357                 for (i = 0; i < encoded_pdu_len; i++)
358                         g_print("%02X", pdu[i]);
359                 g_print("\n");
360         }
361
362         g_assert(ret);
363         g_assert(encoded_tpdu_len == 27);
364         g_assert(encoded_pdu_len == pdu_len);
365
366         encoded_pdu = encode_hex(pdu, encoded_pdu_len, 0);
367
368         g_assert(strcmp(alnum_sender, encoded_pdu) == 0);
369
370         g_free(encoded_pdu);
371
372         /* test unicode_deliver*/
373         decoded_pdu = decode_hex(unicode_deliver, -1, &pdu_len, 0);
374         g_assert(decoded_pdu);
375         g_assert(pdu_len == (long)strlen(unicode_deliver) / 2);
376
377         ret = sms_decode(decoded_pdu, pdu_len, FALSE, 149, &sms);
378
379         g_free(decoded_pdu);
380
381         g_assert(ret);
382         g_assert(sms.type == SMS_TYPE_DELIVER);
383
384         ret = sms_encode(&sms, &encoded_pdu_len, &encoded_tpdu_len, pdu);
385
386         if (g_test_verbose()) {
387                 int i;
388
389                 for (i = 0; i < encoded_pdu_len; i++)
390                         g_print("%02X", pdu[i]);
391                 g_print("\n");
392         }
393
394         g_assert(ret);
395         g_assert(encoded_tpdu_len == 149);
396         g_assert(encoded_pdu_len == pdu_len);
397
398         encoded_pdu = encode_hex(pdu, encoded_pdu_len, 0);
399
400         g_assert(strcmp(unicode_deliver, encoded_pdu) == 0);
401
402         g_free(encoded_pdu);
403 }
404
405 static void test_simple_submit(void)
406 {
407         struct sms sms;
408         unsigned char *decoded_pdu;
409         long pdu_len;
410         gboolean ret;
411         int data_len;
412         unsigned char *unpacked;
413         char *utf8;
414
415         decoded_pdu = decode_hex(simple_submit, -1, &pdu_len, 0);
416
417         g_assert(decoded_pdu);
418         g_assert(pdu_len == (long)strlen(simple_submit) / 2);
419
420         ret = sms_decode(decoded_pdu, pdu_len, TRUE, 23, &sms);
421
422         g_free(decoded_pdu);
423
424         g_assert(ret);
425         g_assert(sms.type == SMS_TYPE_SUBMIT);
426
427         if (g_test_verbose())
428                 dump_details(&sms);
429
430         g_assert(strlen(sms.sc_addr.address) == 0);
431
432         g_assert(sms.submit.mr == 0);
433
434         g_assert(sms.submit.daddr.number_type ==
435                         SMS_NUMBER_TYPE_INTERNATIONAL);
436         g_assert(sms.submit.daddr.numbering_plan ==
437                         SMS_NUMBERING_PLAN_ISDN);
438         g_assert(strcmp(sms.submit.daddr.address, "46708251358") == 0);
439
440         g_assert(sms.submit.pid == 0);
441         g_assert(sms.submit.dcs == 0);
442
443         g_assert(sms.submit.vpf == SMS_VALIDITY_PERIOD_FORMAT_RELATIVE);
444         g_assert(sms.submit.vp.relative == 0xAA);
445
446         g_assert(sms.submit.udl == 10);
447
448         data_len = sms_udl_in_bytes(sms.submit.udl, sms.submit.dcs);
449
450         g_assert(data_len == 9);
451
452         unpacked = unpack_7bit(sms.submit.ud, data_len, 0, FALSE,
453                                 sms.submit.udl, NULL, 0xff);
454
455         g_assert(unpacked);
456
457         utf8 = convert_gsm_to_utf8(unpacked, -1, NULL, NULL, 0xff);
458
459         g_free(unpacked);
460
461         g_assert(utf8);
462
463         if (g_test_verbose())
464                 g_print("Decoded user data is: %s\n", utf8);
465
466         g_assert(strcmp(utf8, "hellohello") == 0);
467
468         g_free(utf8);
469 }
470
471 static void test_submit_encode(void)
472 {
473         struct sms sms;
474         unsigned char *decoded_pdu;
475         long pdu_len;
476         gboolean ret;
477         unsigned char pdu[176];
478         int encoded_pdu_len;
479         int encoded_tpdu_len;
480         char *encoded_pdu;
481
482         decoded_pdu = decode_hex(simple_submit, -1, &pdu_len, 0);
483
484         g_assert(decoded_pdu);
485         g_assert(pdu_len == (long)strlen(simple_submit) / 2);
486
487         ret = sms_decode(decoded_pdu, pdu_len, TRUE, 23, &sms);
488
489         g_free(decoded_pdu);
490
491         g_assert(ret);
492         g_assert(sms.type == SMS_TYPE_SUBMIT);
493
494         ret = sms_encode(&sms, &encoded_pdu_len, &encoded_tpdu_len, pdu);
495
496         if (g_test_verbose()) {
497                 int i;
498
499                 for (i = 0; i < encoded_pdu_len; i++)
500                         g_print("%02X", pdu[i]);
501                 g_print("\n");
502         }
503
504         g_assert(ret);
505         g_assert(encoded_tpdu_len == 23);
506         g_assert(encoded_pdu_len == pdu_len);
507
508         encoded_pdu = encode_hex(pdu, encoded_pdu_len, 0);
509
510         g_assert(strcmp(simple_submit, encoded_pdu) == 0);
511
512         g_free(encoded_pdu);
513 }
514
515 static void test_simple_mwi(void)
516 {
517         struct sms sms;
518         unsigned char *decoded_pdu;
519         long pdu_len;
520         gboolean ret;
521         enum sms_mwi_type type;
522         gboolean active;
523         gboolean discard;
524
525         decoded_pdu = decode_hex(simple_mwi, -1, &pdu_len, 0);
526
527         g_assert(decoded_pdu);
528         g_assert(pdu_len == (long)strlen(simple_mwi) / 2);
529
530         ret = sms_decode(decoded_pdu, pdu_len, FALSE, 19, &sms);
531
532         g_free(decoded_pdu);
533
534         g_assert(ret);
535         g_assert(sms.type == SMS_TYPE_DELIVER);
536
537         if (g_test_verbose())
538                 dump_details(&sms);
539
540         g_assert(sms.sc_addr.number_type == SMS_NUMBER_TYPE_INTERNATIONAL);
541         g_assert(sms.sc_addr.numbering_plan == SMS_NUMBERING_PLAN_ISDN);
542         g_assert(strcmp(sms.sc_addr.address, "33660002028") == 0);
543
544         g_assert(sms.deliver.oaddr.number_type ==
545                         SMS_NUMBER_TYPE_INTERNATIONAL);
546         g_assert(sms.deliver.oaddr.numbering_plan ==
547                         SMS_NUMBERING_PLAN_ISDN);
548         g_assert(strcmp(sms.deliver.oaddr.address, "33660660001") == 0);
549
550         g_assert(sms.deliver.pid == 0);
551         g_assert(sms.deliver.dcs == 200);
552
553         g_assert(sms.deliver.scts.year == 13);
554         g_assert(sms.deliver.scts.month == 8);
555         g_assert(sms.deliver.scts.day == 7);
556         g_assert(sms.deliver.scts.hour == 16);
557         g_assert(sms.deliver.scts.minute == 47);
558         g_assert(sms.deliver.scts.second == 41);
559         g_assert(sms.deliver.scts.timezone == 8);
560
561         g_assert(sms.deliver.udl == 0);
562
563         if (sms.deliver.udhi) {
564                 struct sms_udh_iter iter;
565                 enum sms_iei iei;
566
567                 ret = sms_udh_iter_init(&sms, &iter);
568                 g_assert(ret);
569
570                 while ((iei = sms_udh_iter_get_ie_type(&iter)) !=
571                                 SMS_IEI_INVALID) {
572                         switch (iei) {
573                         case SMS_IEI_ENHANCED_VOICE_MAIL_INFORMATION:
574                         {
575                                 unsigned char evm_iei[140];
576                                 sms_udh_iter_get_ie_data(&iter, evm_iei);
577                                 sms_udh_iter_get_ie_length(&iter);
578
579                                 if (g_test_verbose())
580                                         g_print("Enhanced Voicemail IEI\n");
581                                 break;
582                         }
583
584                         case SMS_IEI_SPECIAL_MESSAGE_INDICATION:
585                         {
586                                 unsigned char special_iei[4];
587
588                                 sms_udh_iter_get_ie_data(&iter, special_iei);
589                                 sms_udh_iter_get_ie_length(&iter);
590
591                                 if (g_test_verbose())
592                                         g_print("Special Voicemail IEI\n");
593
594                                 break;
595                         }
596
597                         default:
598                                 break;
599                         }
600
601                         sms_udh_iter_next(&iter);
602                 }
603         }
604
605         ret = sms_mwi_dcs_decode(sms.deliver.dcs, &type, NULL, &active,
606                                         &discard);
607         g_assert(ret);
608
609         if (g_test_verbose()) {
610                 g_print("Type: %d, Active: %d, Discard: %d\n",
611                                 type, active, discard);
612
613         }
614 }
615
616 struct sms_charset_data {
617         char *pdu;
618         int data_len;
619         enum gsm_dialect locking_lang;
620         enum gsm_dialect single_lang;
621         char expected_text[];
622 };
623
624 static struct sms_charset_data sms_charset_default = {
625         .pdu =
626                 "0001000B91" "5310101010" "1000008080" "8060402818" "0E888462C1"
627                 "68381E9088" "6442A9582E" "988C06C4E9" "783EA09068" "442A994EA8"
628                 "946AC56AB9" "5EB0986C46" "ABD96EB89C" "6EC7EBF97E" "C0A070482C"
629                 "1A8FC8A472" "C96C3A9FD0" "A8744AAD5A" "AFD8AC76CB" "ED7ABFE0B0"
630                 "784C2E9BCF" "E8B47ACD6E" "BBDFF0B87C" "4EAFDBEFF8" "BC7ECFEFFB"
631                 "FF",
632         .data_len = 112,
633         .expected_text = {
634                 0x40, 0xc2, 0xa3, 0x24, 0xc2, 0xa5, 0xc3, 0xa8, 0xc3, 0xa9,
635                 0xc3, 0xb9, 0xc3, 0xac, 0xc3, 0xb2, 0xc3, 0x87, 0x0a, 0xc3,
636                 0x98, 0xc3, 0xb8, 0x0d, 0xc3, 0x85, 0xc3, 0xa5, 0xce, 0x94,
637                 0x5f, 0xce, 0xa6, 0xce, 0x93, 0xce, 0x9b, 0xce, 0xa9, 0xce,
638                 0xa0, 0xce, 0xa8, 0xce, 0xa3, 0xce, 0x98, 0xce, 0x9e, 0x20,
639                 0xc3, 0x86, 0xc3, 0xa6, 0xc3, 0x9f, 0xc3, 0x89, 0x20, 0x21,
640                 0x22, 0x23, 0xc2, 0xa4, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,
641                 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34,
642                 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
643                 0x3f, 0xc2, 0xa1, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
644                 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51,
645                 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0xc3,
646                 0x84, 0xc3, 0x96, 0xc3, 0x91, 0xc3, 0x9c, 0xc2, 0xa7, 0xc2,
647                 0xbf, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
648                 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73,
649                 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0xc3, 0xa4, 0xc3,
650                 0xb6, 0xc3, 0xb1, 0xc3, 0xbc, 0xc3, 0xa0, 0x00
651         }
652 };
653
654 static struct sms_charset_data sms_charset_default_ext = {
655         .pdu =
656                 "0001000B91" "5310101010" "100000151B" "C58602DAA0" "36A9CD6BC3"
657                 "DBF436BE0D" "705306",
658         .data_len = 19,
659         .expected_text = {
660                 0x0c, 0x5e, 0x20, 0x7b, 0x7d, 0x5c, 0x5b, 0x7e, 0x5d, 0x7c,
661                 0xe2, 0x82, 0xac, 0x00
662         }
663 };
664
665 static struct sms_charset_data sms_charset_turkey = {
666         .pdu =
667                 "0001000B91" "5310101010" "1000008080" "8060402818" "0E888462C1"
668                 "68381E9088" "6442A9582E" "988C06C4E9" "783EA09068" "442A994EA8"
669                 "946AC56AB9" "5EB0986C46" "ABD96EB89C" "6EC7EBF97E" "C0A070482C"
670                 "1A8FC8A472" "C96C3A9FD0" "A8744AAD5A" "AFD8AC76CB" "ED7ABFE0B0"
671                 "784C2E9BCF" "E8B47ACD6E" "BBDFF0B87C" "4EAFDBEFF8" "BC7ECFEFFB"
672                 "FF",
673         .data_len = 112,
674         .locking_lang = GSM_DIALECT_TURKISH,
675         .expected_text = {
676                 0x40, 0xc2, 0xa3, 0x24, 0xc2, 0xa5, 0xe2, 0x82, 0xac, 0xc3,
677                 0xa9, 0xc3, 0xb9, 0xc4, 0xb1, 0xc3, 0xb2, 0xc3, 0x87, 0x0a,
678                 0xc4, 0x9e, 0xc4, 0x9f, 0x0d, 0xc3, 0x85, 0xc3, 0xa5, 0xce,
679                 0x94, 0x5f, 0xce, 0xa6, 0xce, 0x93, 0xce, 0x9b, 0xce, 0xa9,
680                 0xce, 0xa0, 0xce, 0xa8, 0xce, 0xa3, 0xce, 0x98, 0xce, 0x9e,
681                 0x20, 0xc5, 0x9e, 0xc5, 0x9f, 0xc3, 0x9f, 0xc3, 0x89, 0x20,
682                 0x21, 0x22, 0x23, 0xc2, 0xa4, 0x25, 0x26, 0x27, 0x28, 0x29,
683                 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33,
684                 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d,
685                 0x3e, 0x3f, 0xc4, 0xb0, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
686                 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
687                 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a,
688                 0xc3, 0x84, 0xc3, 0x96, 0xc3, 0x91, 0xc3, 0x9c, 0xc2, 0xa7,
689                 0xc3, 0xa7, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
690                 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72,
691                 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0xc3, 0xa4,
692                 0xc3, 0xb6, 0xc3, 0xb1, 0xc3, 0xbc, 0xc3, 0xa0, 0x00
693         }
694 };
695
696 static struct sms_charset_data sms_charset_turkey_ext = {
697         .pdu =
698                 "0001000B91" "5310101010" "1000001A1B" "C586B2416D" "529BD786B7"
699                 "E96D7C1BE0" "02C8011318" "870E",
700         .data_len = 23,
701         .locking_lang = GSM_DIALECT_TURKISH,
702         .single_lang = GSM_DIALECT_TURKISH,
703         .expected_text = {
704                 0x0c, 0x5e, 0x7b, 0x7d, 0x5c, 0x5b, 0x7e, 0x5d, 0x7c, 0xc4,
705                 0x9e, 0xc4, 0xb0, 0xc5, 0x9e, 0xc3, 0xa7, 0xe2, 0x82, 0xac,
706                 0xc4, 0x9f, 0xc4, 0xb1, 0xc5, 0x9f, 0x00
707         }
708 };
709
710 static struct sms_charset_data sms_charset_portugal = {
711         .pdu =
712                 "0001000B91" "5310101010" "1000008080" "8060402818" "0E888462C1"
713                 "68381E9088" "6442A9582E" "988C06C4E9" "783EA09068" "442A994EA8"
714                 "946AC56AB9" "5EB0986C46" "ABD96EB89C" "6EC7EBF97E" "C0A070482C"
715                 "1A8FC8A472" "C96C3A9FD0" "A8744AAD5A" "AFD8AC76CB" "ED7ABFE0B0"
716                 "784C2E9BCF" "E8B47ACD6E" "BBDFF0B87C" "4EAFDBEFF8" "BC7ECFEFFB"
717                 "FF",
718         .data_len = 112,
719         .locking_lang = GSM_DIALECT_PORTUGUESE,
720         .expected_text = {
721                 0x40, 0xc2, 0xa3, 0x24, 0xc2, 0xa5, 0xc3, 0xaa, 0xc3, 0xa9,
722                 0xc3, 0xba, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xa7, 0x0a, 0xc3,
723                 0x94, 0xc3, 0xb4, 0x0d, 0xc3, 0x81, 0xc3, 0xa1, 0xce, 0x94,
724                 0x5f, 0xc2, 0xaa, 0xc3, 0x87, 0xc3, 0x80, 0xe2, 0x88, 0x9e,
725                 0x5e, 0x5c, 0xe2, 0x82, 0xac, 0xc3, 0x93, 0x7c, 0x20, 0xc3,
726                 0x82, 0xc3, 0xa2, 0xc3, 0x8a, 0xc3, 0x89, 0x20, 0x21, 0x22,
727                 0x23, 0xc2, 0xba, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
728                 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
729                 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
730                 0xc3, 0x8d, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
731                 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52,
732                 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0xc3, 0x83,
733                 0xc3, 0x95, 0xc3, 0x9a, 0xc3, 0x9c, 0xc2, 0xa7, 0x7e, 0x61,
734                 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
735                 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75,
736                 0x76, 0x77, 0x78, 0x79, 0x7a, 0xc3, 0xa3, 0xc3, 0xb5, 0x60,
737                 0xc3, 0xbc, 0xc3, 0xa0, 0x00
738         }
739 };
740
741 static struct sms_charset_data sms_charset_portugal_ext = {
742         .pdu =
743                 "0001000B91" "5310101010" "1000003184" "C446B16038" "1E1BC96662"
744                 "D9543696CD" "6583D9643C" "1BD42675D9" "F0C01B9F86" "02CC74B75C"
745                 "0EE68030EC" "F91D",
746         .data_len = 43,
747         .locking_lang = GSM_DIALECT_PORTUGUESE,
748         .single_lang = GSM_DIALECT_PORTUGUESE,
749         .expected_text = {
750                 0xc3, 0xaa, 0xc3, 0xa7, 0x0c, 0xc3, 0x94, 0xc3, 0xb4, 0xc3,
751                 0x81, 0xc3, 0xa1, 0xce, 0xa6, 0xce, 0x93, 0x5e, 0xce, 0xa9,
752                 0xce, 0xa0, 0xce, 0xa8, 0xce, 0xa3, 0xce, 0x98, 0xc3, 0x8a,
753                 0x7b, 0x7d, 0x5c, 0x5b, 0x7e, 0x5d, 0x7c, 0xc3, 0x80, 0xc3,
754                 0x8d, 0xc3, 0x93, 0xc3, 0x9a, 0xc3, 0x83, 0xc3, 0x95, 0xc3,
755                 0x82, 0xe2, 0x82, 0xac, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba,
756                 0xc3, 0xa3, 0xc3, 0xb5, 0xc3, 0xa2, 0x00
757         }
758 };
759
760 static struct sms_charset_data sms_charset_spain = {
761         .pdu =
762                 "0001000B91" "5310101010" "100000269B" "C446B1A16C" "509BD4E6B5"
763                 "E16D7A1BDF" "06B8096E92" "9BE7A6BA09" "6FCA9BF4E6" "BDA903",
764         .data_len = 34,
765         .locking_lang = GSM_DIALECT_SPANISH,
766         .single_lang = GSM_DIALECT_SPANISH,
767         .expected_text = {
768                 0xc3, 0xa7, 0x0c, 0x5e, 0x7b, 0x7d, 0x5c, 0x5b, 0x7e, 0x5d,
769                 0x7c, 0xc3, 0x81, 0xc3, 0x8d, 0xc3, 0x93, 0xc3, 0x9a, 0xc3,
770                 0xa1, 0xe2, 0x82, 0xac, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba,
771                 0x00
772         }
773 };
774
775 static void test_sms_charset(gconstpointer param)
776 {
777         gboolean ret;
778         struct sms sms;
779         unsigned char *pdu;
780         unsigned char *unpacked;
781         long pdu_len;
782         int data_len;
783         enum sms_charset sms_charset;
784         gboolean sms_compressed;
785         char *text;
786         struct sms_charset_data *data = (struct sms_charset_data *)param;
787
788         pdu = decode_hex(data->pdu, -1, &pdu_len, 0);
789
790         g_assert(pdu);
791         g_assert(pdu_len == (gint64)strlen(data->pdu) / 2);
792
793         ret = sms_decode(pdu, pdu_len, FALSE, pdu_len, &sms);
794
795         g_assert(ret);
796
797         g_free(pdu);
798
799         g_assert(sms.type == SMS_TYPE_DELIVER);
800
801         ret = sms_dcs_decode(sms.deliver.dcs, NULL, &sms_charset,
802                                 &sms_compressed, NULL);
803
804         g_assert(ret);
805         g_assert(sms_charset == SMS_CHARSET_7BIT);
806         g_assert(sms_compressed == FALSE);
807
808         data_len = sms_udl_in_bytes(sms.deliver.udl, sms.deliver.dcs);
809
810         g_assert(data_len == data->data_len);
811
812         unpacked = unpack_7bit(sms.deliver.ud, data_len, 0, FALSE,
813                                 sms.deliver.udl, NULL, 0xff);
814
815         g_assert(unpacked);
816
817         text = convert_gsm_to_utf8_with_lang(unpacked, -1, NULL, NULL, 0xff,
818                 data->locking_lang, data->single_lang);
819
820         g_assert(text);
821
822         g_free(unpacked);
823
824         g_assert(strcmp(data->expected_text, text) == 0);
825
826         g_free(text);
827 }
828
829 struct text_format_header {
830         unsigned char len;
831         unsigned char start;
832         unsigned char span;
833         unsigned char format;
834         unsigned char color;
835 };
836
837 struct ems_udh_test {
838         const char *pdu;
839         unsigned int len;
840         const char *expected;
841         unsigned int udl;
842         unsigned int udhl;
843         unsigned int data_len;
844         struct text_format_header formats[];
845 };
846
847 static struct ems_udh_test ems_udh_test_1 = {
848         .pdu = "0041000B915121551532F40000631A0A031906200A032104100A03270504"
849                 "0A032E05080A043807002B8ACD29A85D9ECFC3E7F21C340EBB41E3B79B1"
850                 "E4EBB41697A989D1EB340E2379BCC02B1C3F27399059AB7C36C3628EC26"
851                 "83C66FF65B5E2683E8653C1D",
852         .len = 100,
853         .expected = "EMS messages can contain italic, bold, large, small and"
854                 " colored text",
855         .formats = {
856                 {
857                         .len = 3,
858                         .start = 0x19,
859                         .span = 0x06,
860                         .format = 0x20,
861                 },
862                 {
863                         .len = 3,
864                         .start = 0x21,
865                         .span = 0x04,
866                         .format = 0x10,
867                 },
868                 {
869                         .len = 3,
870                         .start = 0x27,
871                         .span = 0x05,
872                         .format = 0x04,
873                 },
874                 {
875                         .len = 3,
876                         .start = 0x2E,
877                         .span = 0x05,
878                         .format = 0x08,
879                 },
880                 {
881                         .len = 4,
882                         .start = 0x38,
883                         .span = 0x07,
884                         .format = 0x00,
885                         .color = 0x2B,
886                 },
887                 {
888                         .len = 0,
889                 }
890         },
891         .udl = 99,
892         .udhl = 26,
893         .data_len = 87,
894 };
895
896 static struct ems_udh_test ems_udh_test_2 = {
897         .pdu = "079194712272303351030B915121340195F60000FF80230A030F07230A031"
898                 "806130A031E0A430A032E0D830A033D14020A035104F60A0355010600159"
899                 "D9E83D2735018442FCFE98A243DCC4E97C92C90F8CD26B3407537B92C67A"
900                 "7DD65320B1476934173BA3CBD2ED3D1F277FD8C76299CEF3B280C92A7CF6"
901                 "83A28CC4E9FDD6532E8FE96935D",
902         .len = 126,
903         .expected = "This is a test\nItalied, bold, underlined, and "
904                 "strikethrough.\nNow a right aligned word.",
905         .formats = {
906                 {
907                         .len = 3,
908                         .start = 0x0f,
909                         .span = 0x07,
910                         .format = 0x23,
911                 },
912                 {
913                         .len = 3,
914                         .start = 0x18,
915                         .span = 0x06,
916                         .format = 0x13,
917                 },
918                 {
919                         .len = 3,
920                         .start = 0x1e,
921                         .span = 0x0a,
922                         .format = 0x43,
923                 },
924                 {
925                         .len = 3,
926                         .start = 0x2e,
927                         .span = 0x0d,
928                         .format = 0x83,
929                 },
930                 {
931                         .len = 3,
932                         .start = 0x3d,
933                         .span = 0x14,
934                         .format = 0x02,
935                 },
936                 {
937                         .len = 3,
938                         .start = 0x51,
939                         .span = 0x04,
940                         .format = 0xf6,
941                 },
942                 {
943                         .len = 3,
944                         .start = 0x55,
945                         .span = 0x01,
946                         .format = 0x06,
947                 },
948         },
949         .udl = 128,
950         .udhl = 35,
951         .data_len = 112,
952 };
953
954 static void test_ems_udh(gconstpointer data)
955 {
956         const struct ems_udh_test *test = data;
957         struct sms sms;
958         unsigned char *decoded_pdu;
959         long pdu_len;
960         gboolean ret;
961         unsigned int data_len;
962         unsigned int udhl;
963         struct sms_udh_iter iter;
964         int max_chars;
965         unsigned char *unpacked;
966         char *utf8;
967         int i;
968
969         decoded_pdu = decode_hex(test->pdu, -1, &pdu_len, 0);
970
971         g_assert(decoded_pdu);
972         g_assert(pdu_len == (long)strlen(test->pdu) / 2);
973
974         ret = sms_decode(decoded_pdu, pdu_len, TRUE, test->len, &sms);
975
976         g_free(decoded_pdu);
977
978         g_assert(ret);
979         g_assert(sms.type == SMS_TYPE_SUBMIT);
980
981         if (g_test_verbose())
982                 dump_details(&sms);
983         udhl = sms.submit.ud[0];
984
985         g_assert(sms.submit.udl == test->udl);
986         g_assert(udhl == test->udhl);
987
988         ret = sms_udh_iter_init(&sms, &iter);
989
990         g_assert(ret);
991
992         for (i = 0; test->formats[i].len; i++) {
993                 if (g_test_verbose()) {
994                         int j;
995                         unsigned char ie_data[4];
996
997                         sms_udh_iter_get_ie_data(&iter, ie_data);
998
999                         g_print("Header:\n");
1000                         for (j = 0; j < sms_udh_iter_get_ie_length(&iter); j++)
1001                                 g_print("0x%02x ", ie_data[j]);
1002
1003                         g_print("\n");
1004                 }
1005
1006                 g_assert(sms_udh_iter_get_ie_type(&iter) ==
1007                                 SMS_IEI_TEXT_FORMAT);
1008                 g_assert(sms_udh_iter_get_ie_length(&iter) ==
1009                                 test->formats[i].len);
1010
1011                 if (test->formats[i+1].len) {
1012                         g_assert(sms_udh_iter_has_next(&iter) == TRUE);
1013                         g_assert(sms_udh_iter_next(&iter) == TRUE);
1014                 } else {
1015                         g_assert(sms_udh_iter_has_next(&iter) == FALSE);
1016                         g_assert(sms_udh_iter_next(&iter) == FALSE);
1017                         g_assert(sms_udh_iter_get_ie_type(&iter) ==
1018                                         SMS_IEI_INVALID);
1019                 }
1020         }
1021
1022         data_len = sms_udl_in_bytes(sms.submit.udl, sms.submit.dcs);
1023
1024         g_assert(data_len == test->data_len);
1025
1026         max_chars = (data_len - (udhl + 1)) * 8 / 7;
1027
1028         unpacked = unpack_7bit(sms.submit.ud + udhl + 1, data_len - (udhl + 1),
1029                                 udhl + 1, FALSE, max_chars, NULL, 0xff);
1030
1031         g_assert(unpacked);
1032
1033         utf8 = convert_gsm_to_utf8(unpacked, -1, NULL, NULL, 0xff);
1034
1035         g_free(unpacked);
1036
1037         g_assert(utf8);
1038
1039         if (g_test_verbose())
1040                 g_print("Decoded user data is: %s\n", utf8);
1041
1042         g_assert(strcmp(utf8, test->expected) == 0);
1043
1044         g_free(utf8);
1045 }
1046
1047 static const char *assembly_pdu1 = "038121F340048155550119906041001222048C0500"
1048                                         "031E0301041804420430043A002C002004100"
1049                                         "43B0435043A04410430043D04340440002000"
1050                                         "200441043B044304480430043B00200437043"
1051                                         "000200434043204350440044C044E00200020"
1052                                         "04380020002004320441043500200431043E0"
1053                                         "43B044C044804350020043F04400435043804"
1054                                         "41043F043E043B043D044F043B0441044F002"
1055                                         "000200433043D0435";
1056 static int assembly_pdu_len1 = 155;
1057
1058 static const char *assembly_pdu2 = "038121F340048155550119906041001222048C0500"
1059                                         "031E03020432043E043C002E000A041D04300"
1060                                         "43A043E043D04350446002C0020043D043500"
1061                                         "200432002004410438043B043004450020043"
1062                                         "40430043B043504350020044204350440043F"
1063                                         "04350442044C002C0020043E043D002004410"
1064                                         "44204400435043C043804420435043B044C04"
1065                                         "3D043E002004320431043504360430043B002"
1066                                         "004320020043A043E";
1067 static int assembly_pdu_len2 = 155;
1068
1069 static const char *assembly_pdu3 = "038121F340048155550119906041001222044A0500"
1070                                         "031E0303043C043D043004420443002C00200"
1071                                         "43F043E043704300431044B0432000A043404"
1072                                         "3004360435002C002004470442043E0020002"
1073                                         "00431044B043B0020043D04300433002E";
1074 static int assembly_pdu_len3 = 89;
1075
1076 static void test_assembly(void)
1077 {
1078         unsigned char pdu[176];
1079         long pdu_len;
1080         struct sms sms;
1081         struct sms_assembly *assembly = sms_assembly_new(NULL);
1082         guint16 ref;
1083         guint8 max;
1084         guint8 seq;
1085         GSList *l;
1086         char *utf8;
1087         char *reencoded;
1088
1089         decode_hex_own_buf(assembly_pdu1, -1, &pdu_len, 0, pdu);
1090         sms_decode(pdu, pdu_len, FALSE, assembly_pdu_len1, &sms);
1091
1092         sms_extract_concatenation(&sms, &ref, &max, &seq);
1093         l = sms_assembly_add_fragment(assembly, &sms, time(NULL),
1094                                         &sms.deliver.oaddr, ref, max, seq);
1095
1096         if (g_test_verbose()) {
1097                 g_print("Ref: %u\n", ref);
1098                 g_print("Max: %u\n", max);
1099                 g_print("From: %s\n",
1100                                 sms_address_to_string(&sms.deliver.oaddr));
1101         }
1102
1103         g_assert(g_slist_length(assembly->assembly_list) == 1);
1104         g_assert(l == NULL);
1105
1106         sms_assembly_expire(assembly, time(NULL) + 40);
1107
1108         g_assert(g_slist_length(assembly->assembly_list) == 0);
1109
1110         sms_extract_concatenation(&sms, &ref, &max, &seq);
1111         l = sms_assembly_add_fragment(assembly, &sms, time(NULL),
1112                                         &sms.deliver.oaddr, ref, max, seq);
1113         g_assert(g_slist_length(assembly->assembly_list) == 1);
1114         g_assert(l == NULL);
1115
1116         decode_hex_own_buf(assembly_pdu2, -1, &pdu_len, 0, pdu);
1117         sms_decode(pdu, pdu_len, FALSE, assembly_pdu_len2, &sms);
1118
1119         sms_extract_concatenation(&sms, &ref, &max, &seq);
1120         l = sms_assembly_add_fragment(assembly, &sms, time(NULL),
1121                                         &sms.deliver.oaddr, ref, max, seq);
1122         g_assert(l == NULL);
1123
1124         decode_hex_own_buf(assembly_pdu3, -1, &pdu_len, 0, pdu);
1125         sms_decode(pdu, pdu_len, FALSE, assembly_pdu_len3, &sms);
1126
1127         sms_extract_concatenation(&sms, &ref, &max, &seq);
1128         l = sms_assembly_add_fragment(assembly, &sms, time(NULL),
1129                                         &sms.deliver.oaddr, ref, max, seq);
1130
1131         g_assert(l != NULL);
1132
1133         utf8 = sms_decode_text(l);
1134
1135         g_slist_foreach(l, (GFunc)g_free, NULL);
1136         g_slist_free(l);
1137
1138         sms_assembly_free(assembly);
1139
1140         if (g_test_verbose())
1141                 g_printf("Text:\n%s\n", utf8);
1142
1143         l = sms_text_prepare("555", utf8, ref, TRUE, FALSE);
1144         g_assert(l);
1145         g_assert(g_slist_length(l) == 3);
1146
1147         reencoded = sms_decode_text(l);
1148
1149         if (g_test_verbose())
1150                 g_printf("ReEncoded:\n%s\n", reencoded);
1151
1152         g_assert(strcmp(utf8, reencoded) == 0);
1153
1154         g_free(utf8);
1155         g_free(reencoded);
1156 }
1157
1158 static const char *test_no_fragmentation_7bit = "This is testing !";
1159 static const char *expected_no_fragmentation_7bit = "079153485002020911000C915"
1160                         "348870420140000A71154747A0E4ACF41F4F29C9E769F4121";
1161 static const char *sc_addr = "+358405202090";
1162 static const char *da_addr = "+358478400241";
1163 static void test_prepare_7bit(void)
1164 {
1165         GSList *r;
1166         struct sms *sms;
1167         gboolean ret;
1168         unsigned char pdu[176];
1169         int encoded_pdu_len;
1170         int encoded_tpdu_len;
1171         char *encoded_pdu;
1172
1173         r = sms_text_prepare("555", test_no_fragmentation_7bit, 0,
1174                                 FALSE, FALSE);
1175
1176         g_assert(r != NULL);
1177
1178         sms = r->data;
1179
1180         sms->sc_addr.number_type = SMS_NUMBER_TYPE_INTERNATIONAL;
1181         sms->sc_addr.numbering_plan = SMS_NUMBERING_PLAN_ISDN;
1182         strcpy(sms->sc_addr.address, sc_addr+1);
1183
1184         if (g_test_verbose())
1185                 g_print("sc_addr: %s\n", sms_address_to_string(&sms->sc_addr));
1186
1187         g_assert(!strcmp(sc_addr, sms_address_to_string(&sms->sc_addr)));
1188
1189         sms->submit.daddr.number_type = SMS_NUMBER_TYPE_INTERNATIONAL;
1190         sms->submit.daddr.numbering_plan = SMS_NUMBERING_PLAN_ISDN;
1191         strcpy(sms->submit.daddr.address, da_addr+1);
1192
1193         if (g_test_verbose())
1194                 g_print("da_addr: %s\n",
1195                         sms_address_to_string(&sms->submit.daddr));
1196
1197         g_assert(!strcmp(da_addr,
1198                                 sms_address_to_string(&sms->submit.daddr)));
1199
1200         ret = sms_encode(sms, &encoded_pdu_len, &encoded_tpdu_len, pdu);
1201
1202         g_assert(ret);
1203
1204         if (g_test_verbose()) {
1205                 int i;
1206
1207                 for (i = 0; i < encoded_pdu_len; i++)
1208                         g_print("%02X", pdu[i]);
1209                 g_print("\n");
1210         }
1211
1212         encoded_pdu = encode_hex(pdu, encoded_pdu_len, 0);
1213
1214         g_assert(strcmp(expected_no_fragmentation_7bit, encoded_pdu) == 0);
1215
1216         g_free(encoded_pdu);
1217         g_slist_foreach(r, (GFunc)g_free, NULL);
1218         g_slist_free(r);
1219 }
1220
1221 struct sms_concat_data {
1222         const char *str;
1223         unsigned int segments;
1224 };
1225
1226 static struct sms_concat_data shakespeare_test = {
1227         .str = "Shakespeare divided his time between London and Str"
1228         "atford during his career. In 1596, the year before he bought New Plac"
1229         "e as his family home in Stratford, Shakespeare was living in the pari"
1230         "sh of St. Helen's, Bishopsgate, north of the River Thames.",
1231         .segments = 2,
1232 };
1233
1234 /* The string in this test should be padded at the end.  This confuses some
1235  * decoders which do not use udl properly
1236  */
1237 static void test_prepare_concat(gconstpointer data)
1238 {
1239         const struct sms_concat_data *test = data;
1240         GSList *r;
1241         GSList *l;
1242         char *decoded_str;
1243         GSList *pdus = NULL;
1244         unsigned char pdu[176];
1245         struct sms *sms;
1246         struct sms decoded;
1247         int pdu_len, tpdu_len;
1248         struct sms_assembly *assembly = sms_assembly_new(NULL);
1249         guint16 ref;
1250         guint8 max;
1251         guint8 seq;
1252
1253         if (g_test_verbose())
1254                 g_print("strlen: %zd\n", strlen(test->str));
1255
1256         r = sms_text_prepare("+15554449999", test->str, 0, TRUE, FALSE);
1257         g_assert(r);
1258         g_assert(g_slist_length(r) == test->segments);
1259
1260         for (l = r; l; l = l->next) {
1261                 char *strpdu;
1262
1263                 sms = l->data;
1264
1265                 sms_encode(sms, &pdu_len, &tpdu_len, pdu);
1266                 g_assert(pdu_len == (tpdu_len + 1));
1267
1268                 strpdu = encode_hex(pdu, pdu_len, 0);
1269
1270                 if (g_test_verbose())
1271                         g_printf("PDU: %s, len: %d, tlen: %d\n",
1272                                 strpdu, pdu_len, tpdu_len);
1273                 pdus = g_slist_append(pdus, strpdu);
1274         }
1275
1276         g_slist_foreach(r, (GFunc)g_free, NULL);
1277         g_slist_free(r);
1278
1279         for (l = pdus; l; l = l->next) {
1280                 long len;
1281                 gboolean ok;
1282
1283                 decode_hex_own_buf((char *)l->data, -1, &len, 0, pdu);
1284
1285                 if (g_test_verbose())
1286                         g_print("PDU Len: %ld\n", len);
1287
1288                 ok = sms_decode(pdu, len, TRUE, len - 1, &decoded);
1289                 g_assert(ok);
1290
1291                 if (g_test_verbose())
1292                         g_print("Pdu udl: %d\n", (int)decoded.submit.udl);
1293
1294                 sms_extract_concatenation(&decoded, &ref, &max, &seq);
1295                 r = sms_assembly_add_fragment(assembly, &decoded, time(NULL),
1296                                                 &decoded.submit.daddr,
1297                                                 ref, max, seq);
1298         }
1299
1300         g_assert(r);
1301
1302         decoded_str = sms_decode_text(r);
1303
1304         if (g_test_verbose())
1305                 g_printf("Decoded String: %s\n", decoded_str);
1306
1307         g_assert(decoded_str);
1308         g_assert(strcmp(decoded_str, test->str) == 0);
1309         g_free(decoded_str);
1310         sms_assembly_free(assembly);
1311 }
1312
1313 static void test_limit(gunichar uni, int target_size, gboolean use_16bit)
1314 {
1315         char *utf8;
1316         char *decoded;
1317         GSList *l;
1318         unsigned int i;
1319         char utf8_char[6];
1320         unsigned int stride;
1321
1322         stride = g_unichar_to_utf8(uni, utf8_char);
1323
1324         utf8 = g_new0(char, (target_size + 2) * stride);
1325
1326         for (i = 0; i < target_size * stride; i += stride)
1327                 memcpy(utf8 + i, utf8_char, stride);
1328
1329         utf8[i] = '\0';
1330
1331         l = sms_text_prepare("555", utf8, 0, use_16bit, FALSE);
1332
1333         g_assert(l);
1334         g_assert(g_slist_length(l) == 255);
1335
1336         decoded = sms_decode_text(l);
1337         g_assert(g_utf8_strlen(decoded, -1) == target_size);
1338
1339         g_free(decoded);
1340
1341         memcpy(utf8 + i, utf8_char, stride);
1342         utf8[i+stride] = '\0';
1343
1344         l = sms_text_prepare("555", utf8, 0, use_16bit, FALSE);
1345
1346         g_assert(l == NULL);
1347         g_free(utf8);
1348 }
1349
1350 static void test_prepare_limits(void)
1351 {
1352         gunichar ascii = 0x41;
1353         gunichar ucs2 = 0x416;
1354         unsigned int target_size;
1355
1356         /* The limit for 16 bit headers is 255 * 152 for GSM7 */
1357         target_size = 255 * 152;
1358         test_limit(ascii, target_size, TRUE);
1359
1360         /* The limit for 8 bit headers is 255 * 153 for GSM7 */
1361         target_size = 255 * 153;
1362         test_limit(ascii, target_size, FALSE);
1363
1364         /* The limit for 16 bit headers is 255 * 66 for UCS2 */
1365         target_size = 255 * 66;
1366         test_limit(ucs2, target_size, TRUE);
1367
1368         /* The limit for 8 bit headers is 255 * 67 for UCS2 */
1369         target_size = 255 * 67;
1370         test_limit(ucs2, target_size, FALSE);
1371 }
1372
1373 static const char *cbs1 = "011000320111C2327BFC76BBCBEE46A3D168341A8D46A3D1683"
1374         "41A8D46A3D168341A8D46A3D168341A8D46A3D168341A8D46A3D168341A8D46A3D168"
1375         "341A8D46A3D168341A8D46A3D168341A8D46A3D168341A8D46A3D100";
1376
1377 static const char *cbs2 = "0110003201114679785E96371A8D46A3D168341A8D46A3D1683"
1378         "41A8D46A3D168341A8D46A3D168341A8D46A3D168341A8D46A3D168341A8D46A3D168"
1379         "341A8D46A3D168341A8D46A3D168341A8D46A3D168341A8D46A3D100";
1380
1381 static const char *cbs3 = "001000000111E280604028180E888462C168381E90886442A95"
1382         "82E988C66C3E9783EA09068442A994EA8946AC56AB95EB0986C46ABD96EB89C6EC7EBF"
1383         "97EC0A070482C1A8FC8A472C96C3A9FD0A8744AAD5AAFD8AC76CB05";
1384
1385 static void test_cbs_encode_decode(void)
1386 {
1387         unsigned char *decoded_pdu;
1388         long pdu_len;
1389         gboolean ret;
1390         struct cbs cbs;
1391         unsigned char pdu[88];
1392         int len;
1393         char *encoded_pdu;
1394         GSList *l;
1395         char iso639_lang[3];
1396         char *utf8;
1397
1398         decoded_pdu = decode_hex(cbs1, -1, &pdu_len, 0);
1399
1400         g_assert(decoded_pdu);
1401         g_assert(pdu_len == (long)strlen(cbs1) / 2);
1402         g_assert(pdu_len == 88);
1403
1404         ret = cbs_decode(decoded_pdu, pdu_len, &cbs);
1405
1406         g_free(decoded_pdu);
1407
1408         g_assert(ret);
1409
1410         g_assert(cbs.gs == CBS_GEO_SCOPE_CELL_IMMEDIATE);
1411         g_assert(cbs.message_code == 17);
1412         g_assert(cbs.update_number == 0);
1413         g_assert(cbs.message_identifier == 50);
1414         g_assert(cbs.dcs == 1);
1415         g_assert(cbs.max_pages == 1);
1416         g_assert(cbs.page == 1);
1417
1418         l = g_slist_append(NULL, &cbs);
1419
1420         utf8 = cbs_decode_text(l, iso639_lang);
1421
1422         g_assert(utf8);
1423
1424         if (g_test_verbose()) {
1425                 g_printf("%s\n", utf8);
1426                 if (iso639_lang[0] == '\0')
1427                         g_printf("Lang: Unspecified\n");
1428                 else
1429                         g_printf("Lang: %s\n", iso639_lang);
1430         }
1431
1432         g_assert(strcmp(utf8, "Belconnen") == 0);
1433         g_assert(strcmp(iso639_lang, "en") == 0);
1434
1435         g_free(utf8);
1436
1437         g_slist_free(l);
1438
1439         ret = cbs_encode(&cbs, &len, pdu);
1440
1441         g_assert(ret);
1442
1443         encoded_pdu = encode_hex(pdu, len, 0);
1444
1445         g_assert(strcmp(cbs1, encoded_pdu) == 0);
1446
1447         g_free(encoded_pdu);
1448 }
1449
1450 static void test_cbs_assembly(void)
1451 {
1452         unsigned char *decoded_pdu;
1453         long pdu_len;
1454         struct cbs dec1;
1455         struct cbs dec2;
1456         struct cbs_assembly *assembly;
1457         char iso639_lang[3];
1458         GSList *l;
1459         char *utf8;
1460
1461         assembly = cbs_assembly_new();
1462
1463         g_assert(assembly);
1464
1465         decoded_pdu = decode_hex(cbs1, -1, &pdu_len, 0);
1466         cbs_decode(decoded_pdu, pdu_len, &dec1);
1467         g_free(decoded_pdu);
1468
1469         decoded_pdu = decode_hex(cbs2, -1, &pdu_len, 0);
1470         cbs_decode(decoded_pdu, pdu_len, &dec2);
1471         g_free(decoded_pdu);
1472
1473         /* Add an initial page to the assembly */
1474         l = cbs_assembly_add_page(assembly, &dec1);
1475         g_assert(l);
1476         g_assert(g_slist_length(assembly->recv_cell) == 1);
1477         g_slist_foreach(l, (GFunc)g_free, NULL);
1478         g_slist_free(l);
1479
1480         /* Can we receive new updates ? */
1481         dec1.update_number = 8;
1482         l = cbs_assembly_add_page(assembly, &dec1);
1483         g_assert(l);
1484         g_assert(g_slist_length(assembly->recv_cell) == 1);
1485         g_slist_foreach(l, (GFunc)g_free, NULL);
1486         g_slist_free(l);
1487
1488         /* Do we ignore old pages ? */
1489         l = cbs_assembly_add_page(assembly, &dec1);
1490         g_assert(l == NULL);
1491
1492         /* Do we ignore older pages ? */
1493         dec1.update_number = 5;
1494         l = cbs_assembly_add_page(assembly, &dec1);
1495         g_assert(l == NULL);
1496
1497         cbs_assembly_location_changed(assembly, TRUE, TRUE, TRUE);
1498         g_assert(assembly->recv_cell == NULL);
1499
1500         dec1.update_number = 9;
1501         dec1.page = 3;
1502         dec1.max_pages = 3;
1503
1504         dec2.update_number = 9;
1505         dec2.page = 2;
1506         dec2.max_pages = 3;
1507
1508         l = cbs_assembly_add_page(assembly, &dec2);
1509         g_assert(l == NULL);
1510         l = cbs_assembly_add_page(assembly, &dec1);
1511         g_assert(l == NULL);
1512
1513         dec1.page = 1;
1514         l = cbs_assembly_add_page(assembly, &dec1);
1515         g_assert(l);
1516
1517         utf8 = cbs_decode_text(l, iso639_lang);
1518
1519         g_assert(utf8);
1520
1521         if (g_test_verbose()) {
1522                 g_printf("%s\n", utf8);
1523                 if (iso639_lang[0] == '\0')
1524                         g_printf("Lang: Unspecified\n");
1525                 else
1526                         g_printf("Lang: %s\n", iso639_lang);
1527         }
1528
1529         g_assert(strcmp(utf8, "BelconnenFraserBelconnen") == 0);
1530
1531         g_free(utf8);
1532         g_slist_foreach(l, (GFunc)g_free, NULL);
1533         g_slist_free(l);
1534
1535         cbs_assembly_free(assembly);
1536 }
1537
1538 static void test_cbs_padding_character(void)
1539 {
1540         unsigned char *decoded_pdu;
1541         long pdu_len;
1542         gboolean ret;
1543         struct cbs cbs;
1544         GSList *l;
1545         char iso639_lang[3];
1546         char *utf8;
1547
1548         decoded_pdu = decode_hex(cbs3, -1, &pdu_len, 0);
1549
1550         g_assert(decoded_pdu);
1551         g_assert(pdu_len == 88);
1552
1553         ret = cbs_decode(decoded_pdu, pdu_len, &cbs);
1554
1555         g_free(decoded_pdu);
1556
1557         g_assert(ret);
1558
1559         g_assert(cbs.gs == CBS_GEO_SCOPE_CELL_IMMEDIATE);
1560         g_assert(cbs.message_code == 1);
1561         g_assert(cbs.update_number == 0);
1562         g_assert(cbs.message_identifier == 0);
1563         g_assert(cbs.dcs == 1);
1564         g_assert(cbs.max_pages == 1);
1565         g_assert(cbs.page == 1);
1566
1567         l = g_slist_append(NULL, &cbs);
1568
1569         utf8 = cbs_decode_text(l, iso639_lang);
1570
1571         g_assert(utf8);
1572
1573         if (g_test_verbose()) {
1574                 g_printf("%s\n", utf8);
1575                 if (iso639_lang[0] == '\0')
1576                         g_printf("Lang: Unspecified\n");
1577                 else
1578                         g_printf("Lang: %s\n", iso639_lang);
1579         }
1580
1581         g_assert(strcmp(utf8, "b£$¥èéùìòÇ\x0AØø\x0DÅåΔ_ΦΓΛΩΠΨΣΘΞÆæßÉ !\"#¤"
1582                                 "\x25&'()*+,-./0123456789:;<=>?¡ABCDEFGHIJKLM"
1583                                 "NOPQRSTUVWXYZÄÖ") == 0);
1584         g_assert(strcmp(iso639_lang, "en") == 0);
1585
1586         g_free(utf8);
1587         g_slist_free(l);
1588 }
1589
1590 static const char *ranges[] = { "1-5, 2, 3, 600, 569-900, 999",
1591                                 "0-20, 33, 44, 50-60, 20-50, 1-5, 5, 3, 5",
1592                                 NULL };
1593 static const char *inv_ranges[] = { "1-5, 3333", "1-5, afbcd", "1-5, 3-5,,",
1594                                         "1-5, 3-5, c", NULL };
1595
1596 static void test_range_minimizer(void)
1597 {
1598         int i = 0;
1599
1600         while (inv_ranges[i]) {
1601                 GSList *l = cbs_extract_topic_ranges(inv_ranges[i]);
1602
1603                 g_assert(l == NULL);
1604                 i++;
1605         }
1606
1607         i = 0;
1608
1609         while (ranges[i]) {
1610                 GSList *r = cbs_extract_topic_ranges(ranges[i]);
1611                 char *rangestr;
1612
1613                 g_assert(r != NULL);
1614                 i++;
1615
1616                 rangestr = cbs_topic_ranges_to_string(r);
1617
1618                 g_assert(rangestr);
1619
1620                 if (g_test_verbose())
1621                         g_print("range: %s\n", rangestr);
1622
1623                 g_free(rangestr);
1624                 g_slist_foreach(r, (GFunc)g_free, NULL);
1625                 g_slist_free(r);
1626         }
1627 }
1628
1629 static void test_sr_assembly(void)
1630 {
1631         const char *sr_pdu1 = "06040D91945152991136F00160124130340A0160124130"
1632                                 "940A00";
1633         const char *sr_pdu2 = "06050D91945152991136F00160124130640A0160124130"
1634                                 "450A00";
1635         const char *sr_pdu3 = "0606098121436587F9019012413064A0019012413045A0"
1636                                 "00";
1637         struct sms sr1;
1638         struct sms sr2;
1639         struct sms sr3;
1640         unsigned char pdu[176];
1641         long pdu_len;
1642         struct status_report_assembly *sra;
1643         gboolean delivered;
1644         struct sms_address addr;
1645         unsigned char sha1[SMS_MSGID_LEN] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
1646                                                 10, 11, 12, 13, 14, 15,
1647                                                 16, 17, 18, 19 };
1648         unsigned char id[SMS_MSGID_LEN];
1649
1650         /* international address, mr 4 & mr 5 */
1651
1652         decode_hex_own_buf(sr_pdu1, -1, &pdu_len, 0, pdu);
1653         g_assert(sms_decode(pdu, pdu_len, FALSE, 26, &sr1) == TRUE);
1654
1655         decode_hex_own_buf(sr_pdu2, -1, &pdu_len, 0, pdu);
1656         g_assert(sms_decode(pdu, pdu_len, FALSE, 26, &sr2) == TRUE);
1657
1658         /* national address, mr 6 */
1659
1660         decode_hex_own_buf(sr_pdu3, -1, &pdu_len, 0, pdu);
1661         g_assert(sms_decode(pdu, pdu_len, FALSE, 24, &sr3) == TRUE);
1662
1663         if (g_test_verbose()) {
1664                 g_print("sr1 address: %s, mr: %d\n",
1665                         sms_address_to_string(&sr1.status_report.raddr),
1666                         sr1.status_report.mr);
1667
1668                 g_print("sr2 address: %s, mr: %d\n",
1669                         sms_address_to_string(&sr2.status_report.raddr),
1670                         sr2.status_report.mr);
1671
1672                 g_print("sr3 address: %s, mr: %d\n",
1673                         sms_address_to_string(&sr3.status_report.raddr),
1674                         sr3.status_report.mr);
1675         }
1676
1677         sms_address_from_string(&addr, "+4915259911630");
1678
1679         sra = status_report_assembly_new(NULL);
1680
1681         status_report_assembly_add_fragment(sra, sha1, &addr, 4, time(NULL), 2);
1682         status_report_assembly_add_fragment(sra, sha1, &addr, 5, time(NULL), 2);
1683
1684         status_report_assembly_expire(sra, time(NULL) + 40);
1685         g_assert(g_hash_table_size(sra->assembly_table) == 0);
1686
1687         status_report_assembly_add_fragment(sra, sha1, &addr, 4, time(NULL), 2);
1688         status_report_assembly_add_fragment(sra, sha1, &addr, 5, time(NULL), 2);
1689
1690         g_assert(!status_report_assembly_report(sra, &sr1, id, &delivered));
1691         g_assert(status_report_assembly_report(sra, &sr2, id, &delivered));
1692
1693         g_assert(memcmp(id, sha1, SMS_MSGID_LEN) == 0);
1694         g_assert(delivered == TRUE);
1695
1696         /*
1697          * Send sms-message in the national address-format,
1698          * but receive in the international address-format.
1699          */
1700         sms_address_from_string(&addr, "9911630");
1701         status_report_assembly_add_fragment(sra, sha1, &addr, 4, time(NULL), 2);
1702         status_report_assembly_add_fragment(sra, sha1, &addr, 5, time(NULL), 2);
1703
1704         g_assert(!status_report_assembly_report(sra, &sr1, id, &delivered));
1705         g_assert(status_report_assembly_report(sra, &sr2, id, &delivered));
1706
1707         g_assert(memcmp(id, sha1, SMS_MSGID_LEN) == 0);
1708         g_assert(delivered == TRUE);
1709         g_assert(g_hash_table_size(sra->assembly_table) == 0);
1710
1711         /*
1712          * Send sms-message in the international address-format,
1713          * but receive in the national address-format.
1714          */
1715         sms_address_from_string(&addr, "+358123456789");
1716         status_report_assembly_add_fragment(sra, sha1, &addr, 6, time(NULL), 1);
1717
1718         g_assert(status_report_assembly_report(sra, &sr3, id, &delivered));
1719
1720         g_assert(memcmp(id, sha1, SMS_MSGID_LEN) == 0);
1721         g_assert(delivered == TRUE);
1722         g_assert(g_hash_table_size(sra->assembly_table) == 0);
1723
1724         status_report_assembly_free(sra);
1725 }
1726
1727 struct wap_push_data {
1728         const char *pdu;
1729         int len;
1730 };
1731
1732 static struct wap_push_data wap_push_1 = {
1733         .pdu = "0791947122725014440185F039F501801140311480720605040B8423F00106"
1734                 "246170706C69636174696F6E2F766E642E7761702E6D6D732D6D657373616"
1735                 "76500AF84B4868C82984F67514B4B42008D9089088045726F74696B009650"
1736                 "696E2D557073008A808E0240008805810303F48083687474703A2F2F65707"
1737                 "3332E64652F4F2F5A39495A4F00",
1738         .len = 128,
1739 };
1740
1741 static void test_wap_push(gconstpointer data)
1742 {
1743         const struct wap_push_data *test = data;
1744         struct sms sms;
1745         unsigned char *decoded_pdu;
1746         gboolean ret;
1747         long pdu_len;
1748         long data_len;
1749         enum sms_class cls;
1750         enum sms_charset charset;
1751         GSList *list;
1752         unsigned char *wap_push;
1753         int dst_port, src_port;
1754         gboolean is_8bit;
1755
1756         decoded_pdu = decode_hex(test->pdu, -1, &pdu_len, 0);
1757
1758         g_assert(decoded_pdu);
1759
1760         ret = sms_decode(decoded_pdu, pdu_len, FALSE, test->len, &sms);
1761
1762         g_free(decoded_pdu);
1763
1764         g_assert(ret);
1765         g_assert(sms.type == SMS_TYPE_DELIVER);
1766
1767         if (g_test_verbose())
1768                 dump_details(&sms);
1769
1770         ret = sms_dcs_decode(sms.deliver.dcs, &cls, &charset, NULL, NULL);
1771
1772         g_assert(ret == TRUE);
1773         g_assert(charset == SMS_CHARSET_8BIT);
1774
1775         g_assert(sms_extract_app_port(&sms, &dst_port, &src_port, &is_8bit));
1776
1777         if (g_test_verbose()) {
1778                 g_print("8bit: %d\n", is_8bit);
1779                 g_print("src: %d, dst: %d\n", src_port, dst_port);
1780         }
1781
1782         g_assert(is_8bit == FALSE);
1783         g_assert(dst_port == 2948);
1784
1785         list = g_slist_append(NULL, &sms);
1786
1787         wap_push = sms_decode_datagram(list, &data_len);
1788
1789         if (g_test_verbose()) {
1790                 int i;
1791
1792                 g_print("data_len: %ld\n", data_len);
1793
1794                 for (i = 0; i < data_len; i++) {
1795                         g_print("%02x", wap_push[i]);
1796
1797                         if ((i % 16) == 15)
1798                                 g_print("\n");
1799                 }
1800
1801                 g_print("\n");
1802         }
1803
1804         g_assert(wap_push);
1805
1806         g_free(wap_push);
1807         g_slist_free(list);
1808 }
1809
1810 int main(int argc, char **argv)
1811 {
1812         char long_string[152*33 + 1];
1813         struct sms_concat_data long_string_test;
1814
1815         g_test_init(&argc, &argv, NULL);
1816
1817         g_test_add_func("/testsms/Test Simple Deliver", test_simple_deliver);
1818         g_test_add_func("/testsms/Test Alnum Deliver", test_alnum_sender);
1819         g_test_add_func("/testsms/Test Deliver Encode", test_deliver_encode);
1820         g_test_add_func("/testsms/Test Simple Submit", test_simple_submit);
1821         g_test_add_func("/testsms/Test Submit Encode", test_submit_encode);
1822         g_test_add_func("/testsms/Test Simple MWI", test_simple_mwi);
1823
1824         g_test_add_data_func("/testsms/Test "
1825                 "GSM 7 bit Default Alphabet Decode",
1826                 &sms_charset_default, test_sms_charset);
1827
1828         g_test_add_data_func("/testsms/Test "
1829                 "GSM 7 bit Default Alphabet Extension Table Decode",
1830                 &sms_charset_default_ext, test_sms_charset);
1831
1832         g_test_add_data_func("/testsms/Test "
1833                 "Turkish National Language Locking Shift Table Decode",
1834                 &sms_charset_turkey, test_sms_charset);
1835
1836         g_test_add_data_func("/testsms/Test "
1837                 "Turkish National Language Single Shift Table Decode",
1838                 &sms_charset_turkey_ext, test_sms_charset);
1839
1840         g_test_add_data_func("/testsms/Test "
1841                 "Portuguese National Language Locking Shift Table Decode",
1842                 &sms_charset_portugal, test_sms_charset);
1843
1844         g_test_add_data_func("/testsms/Test "
1845                 "Portuguese National Language Single Shift Table Decode",
1846                 &sms_charset_portugal_ext, test_sms_charset);
1847
1848         g_test_add_data_func("/testsms/Test "
1849                 "Spanish National Language Single Shift Table Decode",
1850                 &sms_charset_spain, test_sms_charset);
1851
1852         g_test_add_data_func("/testsms/Test EMS UDH 1",
1853                         &ems_udh_test_1, test_ems_udh);
1854         g_test_add_data_func("/testsms/Test EMS UDH 2",
1855                         &ems_udh_test_2, test_ems_udh);
1856
1857         g_test_add_func("/testsms/Test Assembly", test_assembly);
1858         g_test_add_func("/testsms/Test Prepare 7Bit", test_prepare_7bit);
1859
1860         g_test_add_data_func("/testsms/Test Prepare Concat",
1861                         &shakespeare_test, test_prepare_concat);
1862
1863         memset(long_string, 'a', 152*30);
1864         memset(long_string + 152*30, 'b', 152);
1865         memset(long_string + 152*31, 'c', 152);
1866         memset(long_string + 152*32, 'd', 152);
1867         long_string[152*33] = '\0';
1868
1869         long_string_test.str = long_string;
1870         long_string_test.segments = 33;
1871
1872         g_test_add_data_func("/testsms/Test Prepare Concat 30+ segments",
1873                         &long_string_test, test_prepare_concat);
1874
1875         g_test_add_func("/testsms/Test Prepare Limits", test_prepare_limits);
1876
1877         g_test_add_func("/testsms/Test CBS Encode / Decode",
1878                         test_cbs_encode_decode);
1879         g_test_add_func("/testsms/Test CBS Assembly", test_cbs_assembly);
1880
1881         g_test_add_func("/testsms/Test CBS Padding Character",
1882                         test_cbs_padding_character);
1883
1884         g_test_add_func("/testsms/Range minimizer", test_range_minimizer);
1885
1886         g_test_add_func("/testsms/Status Report Assembly", test_sr_assembly);
1887
1888         g_test_add_data_func("/testsms/Test WAP Push 1", &wap_push_1,
1889                                 test_wap_push);
1890
1891         return g_test_run();
1892 }