3 * oFono - Open Source Telephony
5 * Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
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.
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.
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
32 #include <glib/gprintf.h>
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";
50 static const char *simple_mwi = "07913366002020F8040B913366600600F100C8318070"
53 static void print_scts(struct sms_scts *scts, const char *prefix)
59 g_print("%s: (YY-MM-DD) %02d-%02d-%02d\n", prefix,
60 (int)scts->year, (int)scts->month, (int)scts->day);
62 g_print("%s: (HH-MM-SS) %02d:%02d:%02d\n", prefix,
63 (int)scts->hour, (int)scts->minute, (int)scts->second);
65 g_print("%s: Timezone %d hours %d minutes\n", prefix,
66 (int)scts->timezone / 4,
67 (int)((abs(scts->timezone) % 4) * 15));
69 ts = sms_scts_to_time(scts, &remote);
71 strftime(buf, 127, "%Y-%m-%dT%H:%M:%S%z", localtime(&ts));
74 g_print("local time: %s\n", buf);
76 strftime(buf, 127, "%Y-%m-%dT%H:%M:%S%z", &remote);
79 g_print("remote time: %s\n", buf);
82 static void print_vpf(enum sms_validity_period_format vpf,
83 struct sms_validity_period *vp)
85 g_print("Validity Period Format: %d\n", (int)vpf);
88 case SMS_VALIDITY_PERIOD_FORMAT_ABSENT:
89 g_print("Validity-Period: Absent\n");
91 case SMS_VALIDITY_PERIOD_FORMAT_RELATIVE:
92 g_print("Validity-Period: %d\n",
95 case SMS_VALIDITY_PERIOD_FORMAT_ABSOLUTE:
96 print_scts(&vp->absolute, "Validity-Period:");
98 case SMS_VALIDITY_PERIOD_FORMAT_ENHANCED:
99 g_print("Validity-Period: Enhanced");
104 static void dump_details(struct sms *sms)
106 if (sms->sc_addr.address[0] == '\0')
107 g_print("SMSC Address absent, default will be used\n");
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);
114 case SMS_TYPE_DELIVER:
115 g_print("Type: Deliver\n");
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);
122 g_print("PID: %d\n", (int)sms->deliver.pid);
123 g_print("DCS: %d\n", (int)sms->deliver.dcs);
125 print_scts(&sms->deliver.scts, "Timestamp");
128 case SMS_TYPE_SUBMIT:
129 g_print("Type: Submit\n");
131 g_print("Message Reference: %u\n", (int)sms->submit.mr);
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);
138 g_print("PID: %d\n", (int)sms->submit.pid);
139 g_print("DCS: %d\n", (int)sms->submit.dcs);
141 print_vpf(sms->submit.vpf, &sms->submit.vp);
144 case SMS_TYPE_STATUS_REPORT:
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:
155 static void test_simple_deliver(void)
158 unsigned char *decoded_pdu;
162 unsigned char *unpacked;
165 decoded_pdu = decode_hex(simple_deliver, -1, &pdu_len, 0);
167 g_assert(decoded_pdu);
168 g_assert(pdu_len == (long)strlen(simple_deliver) / 2);
170 ret = sms_decode(decoded_pdu, pdu_len, FALSE, 30, &sms);
175 g_assert(sms.type == SMS_TYPE_DELIVER);
177 if (g_test_verbose())
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);
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);
190 g_assert(sms.deliver.pid == 0);
191 g_assert(sms.deliver.dcs == 0);
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);
201 g_assert(sms.deliver.udl == 12);
203 data_len = sms_udl_in_bytes(sms.deliver.udl, sms.deliver.dcs);
205 g_assert(data_len == 11);
207 unpacked = unpack_7bit(sms.deliver.ud, data_len, 0, FALSE,
208 sms.deliver.udl, NULL, 0xff);
212 utf8 = convert_gsm_to_utf8(unpacked, -1, NULL, NULL, 0xff);
218 if (g_test_verbose())
219 g_print("Decoded user data is: %s\n", utf8);
221 g_assert(strcmp(utf8, "How are you?") == 0);
226 static void test_alnum_sender(void)
229 unsigned char *decoded_pdu;
233 unsigned char *unpacked;
236 decoded_pdu = decode_hex(alnum_sender, -1, &pdu_len, 0);
238 g_assert(decoded_pdu);
239 g_assert(pdu_len == (long)strlen(alnum_sender) / 2);
241 ret = sms_decode(decoded_pdu, pdu_len, FALSE, 27, &sms);
246 g_assert(sms.type == SMS_TYPE_DELIVER);
248 if (g_test_verbose())
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);
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);
261 g_assert(sms.deliver.pid == 0);
262 g_assert(sms.deliver.dcs == 0);
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);
272 g_assert(sms.deliver.udl == 8);
274 data_len = sms_udl_in_bytes(sms.deliver.udl, sms.deliver.dcs);
276 g_assert(data_len == 7);
278 unpacked = unpack_7bit(sms.deliver.ud, data_len, 0, FALSE,
279 sms.deliver.udl, NULL, 0xff);
283 utf8 = convert_gsm_to_utf8(unpacked, -1, NULL, NULL, 0xff);
289 if (g_test_verbose())
290 g_print("Decoded user data is: %s\n", utf8);
292 g_assert(strcmp(utf8, "Testmail") == 0);
297 static void test_deliver_encode(void)
300 unsigned char *decoded_pdu;
303 unsigned char pdu[176];
305 int encoded_tpdu_len;
308 decoded_pdu = decode_hex(simple_deliver, -1, &pdu_len, 0);
310 g_assert(decoded_pdu);
311 g_assert(pdu_len == (long)strlen(simple_deliver) / 2);
313 ret = sms_decode(decoded_pdu, pdu_len, FALSE, 30, &sms);
318 g_assert(sms.type == SMS_TYPE_DELIVER);
320 ret = sms_encode(&sms, &encoded_pdu_len, &encoded_tpdu_len, pdu);
322 if (g_test_verbose()) {
325 for (i = 0; i < encoded_pdu_len; i++)
326 g_print("%02X", pdu[i]);
331 g_assert(encoded_tpdu_len == 30);
332 g_assert(encoded_pdu_len == pdu_len);
334 encoded_pdu = encode_hex(pdu, encoded_pdu_len, 0);
336 g_assert(strcmp(simple_deliver, encoded_pdu) == 0);
340 decoded_pdu = decode_hex(alnum_sender, -1, &pdu_len, 0);
342 g_assert(decoded_pdu);
343 g_assert(pdu_len == (long)strlen(alnum_sender) / 2);
345 ret = sms_decode(decoded_pdu, pdu_len, FALSE, 27, &sms);
350 g_assert(sms.type == SMS_TYPE_DELIVER);
352 ret = sms_encode(&sms, &encoded_pdu_len, &encoded_tpdu_len, pdu);
354 if (g_test_verbose()) {
357 for (i = 0; i < encoded_pdu_len; i++)
358 g_print("%02X", pdu[i]);
363 g_assert(encoded_tpdu_len == 27);
364 g_assert(encoded_pdu_len == pdu_len);
366 encoded_pdu = encode_hex(pdu, encoded_pdu_len, 0);
368 g_assert(strcmp(alnum_sender, encoded_pdu) == 0);
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);
377 ret = sms_decode(decoded_pdu, pdu_len, FALSE, 149, &sms);
382 g_assert(sms.type == SMS_TYPE_DELIVER);
384 ret = sms_encode(&sms, &encoded_pdu_len, &encoded_tpdu_len, pdu);
386 if (g_test_verbose()) {
389 for (i = 0; i < encoded_pdu_len; i++)
390 g_print("%02X", pdu[i]);
395 g_assert(encoded_tpdu_len == 149);
396 g_assert(encoded_pdu_len == pdu_len);
398 encoded_pdu = encode_hex(pdu, encoded_pdu_len, 0);
400 g_assert(strcmp(unicode_deliver, encoded_pdu) == 0);
405 static void test_simple_submit(void)
408 unsigned char *decoded_pdu;
412 unsigned char *unpacked;
415 decoded_pdu = decode_hex(simple_submit, -1, &pdu_len, 0);
417 g_assert(decoded_pdu);
418 g_assert(pdu_len == (long)strlen(simple_submit) / 2);
420 ret = sms_decode(decoded_pdu, pdu_len, TRUE, 23, &sms);
425 g_assert(sms.type == SMS_TYPE_SUBMIT);
427 if (g_test_verbose())
430 g_assert(strlen(sms.sc_addr.address) == 0);
432 g_assert(sms.submit.mr == 0);
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);
440 g_assert(sms.submit.pid == 0);
441 g_assert(sms.submit.dcs == 0);
443 g_assert(sms.submit.vpf == SMS_VALIDITY_PERIOD_FORMAT_RELATIVE);
444 g_assert(sms.submit.vp.relative == 0xAA);
446 g_assert(sms.submit.udl == 10);
448 data_len = sms_udl_in_bytes(sms.submit.udl, sms.submit.dcs);
450 g_assert(data_len == 9);
452 unpacked = unpack_7bit(sms.submit.ud, data_len, 0, FALSE,
453 sms.submit.udl, NULL, 0xff);
457 utf8 = convert_gsm_to_utf8(unpacked, -1, NULL, NULL, 0xff);
463 if (g_test_verbose())
464 g_print("Decoded user data is: %s\n", utf8);
466 g_assert(strcmp(utf8, "hellohello") == 0);
471 static void test_submit_encode(void)
474 unsigned char *decoded_pdu;
477 unsigned char pdu[176];
479 int encoded_tpdu_len;
482 decoded_pdu = decode_hex(simple_submit, -1, &pdu_len, 0);
484 g_assert(decoded_pdu);
485 g_assert(pdu_len == (long)strlen(simple_submit) / 2);
487 ret = sms_decode(decoded_pdu, pdu_len, TRUE, 23, &sms);
492 g_assert(sms.type == SMS_TYPE_SUBMIT);
494 ret = sms_encode(&sms, &encoded_pdu_len, &encoded_tpdu_len, pdu);
496 if (g_test_verbose()) {
499 for (i = 0; i < encoded_pdu_len; i++)
500 g_print("%02X", pdu[i]);
505 g_assert(encoded_tpdu_len == 23);
506 g_assert(encoded_pdu_len == pdu_len);
508 encoded_pdu = encode_hex(pdu, encoded_pdu_len, 0);
510 g_assert(strcmp(simple_submit, encoded_pdu) == 0);
515 static void test_simple_mwi(void)
518 unsigned char *decoded_pdu;
521 enum sms_mwi_type type;
525 decoded_pdu = decode_hex(simple_mwi, -1, &pdu_len, 0);
527 g_assert(decoded_pdu);
528 g_assert(pdu_len == (long)strlen(simple_mwi) / 2);
530 ret = sms_decode(decoded_pdu, pdu_len, FALSE, 19, &sms);
535 g_assert(sms.type == SMS_TYPE_DELIVER);
537 if (g_test_verbose())
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);
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);
550 g_assert(sms.deliver.pid == 0);
551 g_assert(sms.deliver.dcs == 200);
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);
561 g_assert(sms.deliver.udl == 0);
563 if (sms.deliver.udhi) {
564 struct sms_udh_iter iter;
567 ret = sms_udh_iter_init(&sms, &iter);
570 while ((iei = sms_udh_iter_get_ie_type(&iter)) !=
573 case SMS_IEI_ENHANCED_VOICE_MAIL_INFORMATION:
575 unsigned char evm_iei[140];
576 sms_udh_iter_get_ie_data(&iter, evm_iei);
577 sms_udh_iter_get_ie_length(&iter);
579 if (g_test_verbose())
580 g_print("Enhanced Voicemail IEI\n");
584 case SMS_IEI_SPECIAL_MESSAGE_INDICATION:
586 unsigned char special_iei[4];
588 sms_udh_iter_get_ie_data(&iter, special_iei);
589 sms_udh_iter_get_ie_length(&iter);
591 if (g_test_verbose())
592 g_print("Special Voicemail IEI\n");
601 sms_udh_iter_next(&iter);
605 ret = sms_mwi_dcs_decode(sms.deliver.dcs, &type, NULL, &active,
609 if (g_test_verbose()) {
610 g_print("Type: %d, Active: %d, Discard: %d\n",
611 type, active, discard);
616 struct sms_charset_data {
619 enum gsm_dialect locking_lang;
620 enum gsm_dialect single_lang;
621 char expected_text[];
624 static struct sms_charset_data sms_charset_default = {
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"
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
654 static struct sms_charset_data sms_charset_default_ext = {
656 "0001000B91" "5310101010" "100000151B" "C58602DAA0" "36A9CD6BC3"
657 "DBF436BE0D" "705306",
660 0x0c, 0x5e, 0x20, 0x7b, 0x7d, 0x5c, 0x5b, 0x7e, 0x5d, 0x7c,
661 0xe2, 0x82, 0xac, 0x00
665 static struct sms_charset_data sms_charset_turkey = {
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"
674 .locking_lang = GSM_DIALECT_TURKISH,
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
696 static struct sms_charset_data sms_charset_turkey_ext = {
698 "0001000B91" "5310101010" "1000001A1B" "C586B2416D" "529BD786B7"
699 "E96D7C1BE0" "02C8011318" "870E",
701 .locking_lang = GSM_DIALECT_TURKISH,
702 .single_lang = GSM_DIALECT_TURKISH,
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
710 static struct sms_charset_data sms_charset_portugal = {
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"
719 .locking_lang = GSM_DIALECT_PORTUGUESE,
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
741 static struct sms_charset_data sms_charset_portugal_ext = {
743 "0001000B91" "5310101010" "1000003184" "C446B16038" "1E1BC96662"
744 "D9543696CD" "6583D9643C" "1BD42675D9" "F0C01B9F86" "02CC74B75C"
747 .locking_lang = GSM_DIALECT_PORTUGUESE,
748 .single_lang = GSM_DIALECT_PORTUGUESE,
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
760 static struct sms_charset_data sms_charset_spain = {
762 "0001000B91" "5310101010" "100000269B" "C446B1A16C" "509BD4E6B5"
763 "E16D7A1BDF" "06B8096E92" "9BE7A6BA09" "6FCA9BF4E6" "BDA903",
765 .locking_lang = GSM_DIALECT_SPANISH,
766 .single_lang = GSM_DIALECT_SPANISH,
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,
775 static void test_sms_charset(gconstpointer param)
780 unsigned char *unpacked;
783 enum sms_charset sms_charset;
784 gboolean sms_compressed;
786 struct sms_charset_data *data = (struct sms_charset_data *)param;
788 pdu = decode_hex(data->pdu, -1, &pdu_len, 0);
791 g_assert(pdu_len == (gint64)strlen(data->pdu) / 2);
793 ret = sms_decode(pdu, pdu_len, FALSE, pdu_len, &sms);
799 g_assert(sms.type == SMS_TYPE_DELIVER);
801 ret = sms_dcs_decode(sms.deliver.dcs, NULL, &sms_charset,
802 &sms_compressed, NULL);
805 g_assert(sms_charset == SMS_CHARSET_7BIT);
806 g_assert(sms_compressed == FALSE);
808 data_len = sms_udl_in_bytes(sms.deliver.udl, sms.deliver.dcs);
810 g_assert(data_len == data->data_len);
812 unpacked = unpack_7bit(sms.deliver.ud, data_len, 0, FALSE,
813 sms.deliver.udl, NULL, 0xff);
817 text = convert_gsm_to_utf8_with_lang(unpacked, -1, NULL, NULL, 0xff,
818 data->locking_lang, data->single_lang);
824 g_assert(strcmp(data->expected_text, text) == 0);
829 struct text_format_header {
833 unsigned char format;
837 struct ems_udh_test {
840 const char *expected;
843 unsigned int data_len;
844 struct text_format_header formats[];
847 static struct ems_udh_test ems_udh_test_1 = {
848 .pdu = "0041000B915121551532F40000631A0A031906200A032104100A03270504"
849 "0A032E05080A043807002B8ACD29A85D9ECFC3E7F21C340EBB41E3B79B1"
850 "E4EBB41697A989D1EB340E2379BCC02B1C3F27399059AB7C36C3628EC26"
851 "83C66FF65B5E2683E8653C1D",
853 .expected = "EMS messages can contain italic, bold, large, small and"
896 static struct ems_udh_test ems_udh_test_2 = {
897 .pdu = "079194712272303351030B915121340195F60000FF80230A030F07230A031"
898 "806130A031E0A430A032E0D830A033D14020A035104F60A0355010600159"
899 "D9E83D2735018442FCFE98A243DCC4E97C92C90F8CD26B3407537B92C67A"
900 "7DD65320B1476934173BA3CBD2ED3D1F277FD8C76299CEF3B280C92A7CF6"
901 "83A28CC4E9FDD6532E8FE96935D",
903 .expected = "This is a test\nItalied, bold, underlined, and "
904 "strikethrough.\nNow a right aligned word.",
954 static void test_ems_udh(gconstpointer data)
956 const struct ems_udh_test *test = data;
958 unsigned char *decoded_pdu;
961 unsigned int data_len;
963 struct sms_udh_iter iter;
965 unsigned char *unpacked;
969 decoded_pdu = decode_hex(test->pdu, -1, &pdu_len, 0);
971 g_assert(decoded_pdu);
972 g_assert(pdu_len == (long)strlen(test->pdu) / 2);
974 ret = sms_decode(decoded_pdu, pdu_len, TRUE, test->len, &sms);
979 g_assert(sms.type == SMS_TYPE_SUBMIT);
981 if (g_test_verbose())
983 udhl = sms.submit.ud[0];
985 g_assert(sms.submit.udl == test->udl);
986 g_assert(udhl == test->udhl);
988 ret = sms_udh_iter_init(&sms, &iter);
992 for (i = 0; test->formats[i].len; i++) {
993 if (g_test_verbose()) {
995 unsigned char ie_data[4];
997 sms_udh_iter_get_ie_data(&iter, ie_data);
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]);
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);
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);
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) ==
1022 data_len = sms_udl_in_bytes(sms.submit.udl, sms.submit.dcs);
1024 g_assert(data_len == test->data_len);
1026 max_chars = (data_len - (udhl + 1)) * 8 / 7;
1028 unpacked = unpack_7bit(sms.submit.ud + udhl + 1, data_len - (udhl + 1),
1029 udhl + 1, FALSE, max_chars, NULL, 0xff);
1033 utf8 = convert_gsm_to_utf8(unpacked, -1, NULL, NULL, 0xff);
1039 if (g_test_verbose())
1040 g_print("Decoded user data is: %s\n", utf8);
1042 g_assert(strcmp(utf8, test->expected) == 0);
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;
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;
1069 static const char *assembly_pdu3 = "038121F340048155550119906041001222044A0500"
1070 "031E0303043C043D043004420443002C00200"
1071 "43F043E043704300431044B0432000A043404"
1072 "3004360435002C002004470442043E0020002"
1073 "00431044B043B0020043D04300433002E";
1074 static int assembly_pdu_len3 = 89;
1076 static void test_assembly(void)
1078 unsigned char pdu[176];
1081 struct sms_assembly *assembly = sms_assembly_new(NULL);
1089 decode_hex_own_buf(assembly_pdu1, -1, &pdu_len, 0, pdu);
1090 sms_decode(pdu, pdu_len, FALSE, assembly_pdu_len1, &sms);
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);
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));
1103 g_assert(g_slist_length(assembly->assembly_list) == 1);
1104 g_assert(l == NULL);
1106 sms_assembly_expire(assembly, time(NULL) + 40);
1108 g_assert(g_slist_length(assembly->assembly_list) == 0);
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);
1116 decode_hex_own_buf(assembly_pdu2, -1, &pdu_len, 0, pdu);
1117 sms_decode(pdu, pdu_len, FALSE, assembly_pdu_len2, &sms);
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);
1124 decode_hex_own_buf(assembly_pdu3, -1, &pdu_len, 0, pdu);
1125 sms_decode(pdu, pdu_len, FALSE, assembly_pdu_len3, &sms);
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);
1131 g_assert(l != NULL);
1133 utf8 = sms_decode_text(l);
1135 g_slist_foreach(l, (GFunc)g_free, NULL);
1138 sms_assembly_free(assembly);
1140 if (g_test_verbose())
1141 g_printf("Text:\n%s\n", utf8);
1143 l = sms_text_prepare("555", utf8, ref, TRUE, FALSE);
1145 g_assert(g_slist_length(l) == 3);
1147 reencoded = sms_decode_text(l);
1149 if (g_test_verbose())
1150 g_printf("ReEncoded:\n%s\n", reencoded);
1152 g_assert(strcmp(utf8, reencoded) == 0);
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)
1168 unsigned char pdu[176];
1169 int encoded_pdu_len;
1170 int encoded_tpdu_len;
1173 r = sms_text_prepare("555", test_no_fragmentation_7bit, 0,
1176 g_assert(r != NULL);
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);
1184 if (g_test_verbose())
1185 g_print("sc_addr: %s\n", sms_address_to_string(&sms->sc_addr));
1187 g_assert(!strcmp(sc_addr, sms_address_to_string(&sms->sc_addr)));
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);
1193 if (g_test_verbose())
1194 g_print("da_addr: %s\n",
1195 sms_address_to_string(&sms->submit.daddr));
1197 g_assert(!strcmp(da_addr,
1198 sms_address_to_string(&sms->submit.daddr)));
1200 ret = sms_encode(sms, &encoded_pdu_len, &encoded_tpdu_len, pdu);
1204 if (g_test_verbose()) {
1207 for (i = 0; i < encoded_pdu_len; i++)
1208 g_print("%02X", pdu[i]);
1212 encoded_pdu = encode_hex(pdu, encoded_pdu_len, 0);
1214 g_assert(strcmp(expected_no_fragmentation_7bit, encoded_pdu) == 0);
1216 g_free(encoded_pdu);
1217 g_slist_foreach(r, (GFunc)g_free, NULL);
1221 struct sms_concat_data {
1223 unsigned int segments;
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.",
1234 /* The string in this test should be padded at the end. This confuses some
1235 * decoders which do not use udl properly
1237 static void test_prepare_concat(gconstpointer data)
1239 const struct sms_concat_data *test = data;
1243 GSList *pdus = NULL;
1244 unsigned char pdu[176];
1247 int pdu_len, tpdu_len;
1248 struct sms_assembly *assembly = sms_assembly_new(NULL);
1253 if (g_test_verbose())
1254 g_print("strlen: %zd\n", strlen(test->str));
1256 r = sms_text_prepare("+15554449999", test->str, 0, TRUE, FALSE);
1258 g_assert(g_slist_length(r) == test->segments);
1260 for (l = r; l; l = l->next) {
1265 sms_encode(sms, &pdu_len, &tpdu_len, pdu);
1266 g_assert(pdu_len == (tpdu_len + 1));
1268 strpdu = encode_hex(pdu, pdu_len, 0);
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);
1276 g_slist_foreach(r, (GFunc)g_free, NULL);
1279 for (l = pdus; l; l = l->next) {
1283 decode_hex_own_buf((char *)l->data, -1, &len, 0, pdu);
1285 if (g_test_verbose())
1286 g_print("PDU Len: %ld\n", len);
1288 ok = sms_decode(pdu, len, TRUE, len - 1, &decoded);
1291 if (g_test_verbose())
1292 g_print("Pdu udl: %d\n", (int)decoded.submit.udl);
1294 sms_extract_concatenation(&decoded, &ref, &max, &seq);
1295 r = sms_assembly_add_fragment(assembly, &decoded, time(NULL),
1296 &decoded.submit.daddr,
1302 decoded_str = sms_decode_text(r);
1304 if (g_test_verbose())
1305 g_printf("Decoded String: %s\n", decoded_str);
1307 g_assert(decoded_str);
1308 g_assert(strcmp(decoded_str, test->str) == 0);
1309 g_free(decoded_str);
1310 sms_assembly_free(assembly);
1313 static void test_limit(gunichar uni, int target_size, gboolean use_16bit)
1320 unsigned int stride;
1322 stride = g_unichar_to_utf8(uni, utf8_char);
1324 utf8 = g_new0(char, (target_size + 2) * stride);
1326 for (i = 0; i < target_size * stride; i += stride)
1327 memcpy(utf8 + i, utf8_char, stride);
1331 l = sms_text_prepare("555", utf8, 0, use_16bit, FALSE);
1334 g_assert(g_slist_length(l) == 255);
1336 decoded = sms_decode_text(l);
1337 g_assert(g_utf8_strlen(decoded, -1) == target_size);
1341 memcpy(utf8 + i, utf8_char, stride);
1342 utf8[i+stride] = '\0';
1344 l = sms_text_prepare("555", utf8, 0, use_16bit, FALSE);
1346 g_assert(l == NULL);
1350 static void test_prepare_limits(void)
1352 gunichar ascii = 0x41;
1353 gunichar ucs2 = 0x416;
1354 unsigned int target_size;
1356 /* The limit for 16 bit headers is 255 * 152 for GSM7 */
1357 target_size = 255 * 152;
1358 test_limit(ascii, target_size, TRUE);
1360 /* The limit for 8 bit headers is 255 * 153 for GSM7 */
1361 target_size = 255 * 153;
1362 test_limit(ascii, target_size, FALSE);
1364 /* The limit for 16 bit headers is 255 * 66 for UCS2 */
1365 target_size = 255 * 66;
1366 test_limit(ucs2, target_size, TRUE);
1368 /* The limit for 8 bit headers is 255 * 67 for UCS2 */
1369 target_size = 255 * 67;
1370 test_limit(ucs2, target_size, FALSE);
1373 static const char *cbs1 = "011000320111C2327BFC76BBCBEE46A3D168341A8D46A3D1683"
1374 "41A8D46A3D168341A8D46A3D168341A8D46A3D168341A8D46A3D168341A8D46A3D168"
1375 "341A8D46A3D168341A8D46A3D168341A8D46A3D168341A8D46A3D100";
1377 static const char *cbs2 = "0110003201114679785E96371A8D46A3D168341A8D46A3D1683"
1378 "41A8D46A3D168341A8D46A3D168341A8D46A3D168341A8D46A3D168341A8D46A3D168"
1379 "341A8D46A3D168341A8D46A3D168341A8D46A3D168341A8D46A3D100";
1381 static const char *cbs3 = "001000000111E280604028180E888462C168381E90886442A95"
1382 "82E988C66C3E9783EA09068442A994EA8946AC56AB95EB0986C46ABD96EB89C6EC7EBF"
1383 "97EC0A070482C1A8FC8A472C96C3A9FD0A8744AAD5AAFD8AC76CB05";
1385 static void test_cbs_encode_decode(void)
1387 unsigned char *decoded_pdu;
1391 unsigned char pdu[88];
1395 char iso639_lang[3];
1398 decoded_pdu = decode_hex(cbs1, -1, &pdu_len, 0);
1400 g_assert(decoded_pdu);
1401 g_assert(pdu_len == (long)strlen(cbs1) / 2);
1402 g_assert(pdu_len == 88);
1404 ret = cbs_decode(decoded_pdu, pdu_len, &cbs);
1406 g_free(decoded_pdu);
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);
1418 l = g_slist_append(NULL, &cbs);
1420 utf8 = cbs_decode_text(l, iso639_lang);
1424 if (g_test_verbose()) {
1425 g_printf("%s\n", utf8);
1426 if (iso639_lang[0] == '\0')
1427 g_printf("Lang: Unspecified\n");
1429 g_printf("Lang: %s\n", iso639_lang);
1432 g_assert(strcmp(utf8, "Belconnen") == 0);
1433 g_assert(strcmp(iso639_lang, "en") == 0);
1439 ret = cbs_encode(&cbs, &len, pdu);
1443 encoded_pdu = encode_hex(pdu, len, 0);
1445 g_assert(strcmp(cbs1, encoded_pdu) == 0);
1447 g_free(encoded_pdu);
1450 static void test_cbs_assembly(void)
1452 unsigned char *decoded_pdu;
1456 struct cbs_assembly *assembly;
1457 char iso639_lang[3];
1461 assembly = cbs_assembly_new();
1465 decoded_pdu = decode_hex(cbs1, -1, &pdu_len, 0);
1466 cbs_decode(decoded_pdu, pdu_len, &dec1);
1467 g_free(decoded_pdu);
1469 decoded_pdu = decode_hex(cbs2, -1, &pdu_len, 0);
1470 cbs_decode(decoded_pdu, pdu_len, &dec2);
1471 g_free(decoded_pdu);
1473 /* Add an initial page to the assembly */
1474 l = cbs_assembly_add_page(assembly, &dec1);
1476 g_assert(g_slist_length(assembly->recv_cell) == 1);
1477 g_slist_foreach(l, (GFunc)g_free, NULL);
1480 /* Can we receive new updates ? */
1481 dec1.update_number = 8;
1482 l = cbs_assembly_add_page(assembly, &dec1);
1484 g_assert(g_slist_length(assembly->recv_cell) == 1);
1485 g_slist_foreach(l, (GFunc)g_free, NULL);
1488 /* Do we ignore old pages ? */
1489 l = cbs_assembly_add_page(assembly, &dec1);
1490 g_assert(l == NULL);
1492 /* Do we ignore older pages ? */
1493 dec1.update_number = 5;
1494 l = cbs_assembly_add_page(assembly, &dec1);
1495 g_assert(l == NULL);
1497 cbs_assembly_location_changed(assembly, TRUE, TRUE, TRUE);
1498 g_assert(assembly->recv_cell == NULL);
1500 dec1.update_number = 9;
1504 dec2.update_number = 9;
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);
1514 l = cbs_assembly_add_page(assembly, &dec1);
1517 utf8 = cbs_decode_text(l, iso639_lang);
1521 if (g_test_verbose()) {
1522 g_printf("%s\n", utf8);
1523 if (iso639_lang[0] == '\0')
1524 g_printf("Lang: Unspecified\n");
1526 g_printf("Lang: %s\n", iso639_lang);
1529 g_assert(strcmp(utf8, "BelconnenFraserBelconnen") == 0);
1532 g_slist_foreach(l, (GFunc)g_free, NULL);
1535 cbs_assembly_free(assembly);
1538 static void test_cbs_padding_character(void)
1540 unsigned char *decoded_pdu;
1545 char iso639_lang[3];
1548 decoded_pdu = decode_hex(cbs3, -1, &pdu_len, 0);
1550 g_assert(decoded_pdu);
1551 g_assert(pdu_len == 88);
1553 ret = cbs_decode(decoded_pdu, pdu_len, &cbs);
1555 g_free(decoded_pdu);
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);
1567 l = g_slist_append(NULL, &cbs);
1569 utf8 = cbs_decode_text(l, iso639_lang);
1573 if (g_test_verbose()) {
1574 g_printf("%s\n", utf8);
1575 if (iso639_lang[0] == '\0')
1576 g_printf("Lang: Unspecified\n");
1578 g_printf("Lang: %s\n", iso639_lang);
1581 g_assert(strcmp(utf8, "b£$¥èéùìòÇ\x0AØø\x0DÅåΔ_ΦΓΛΩΠΨΣΘΞÆæßÉ !\"#¤"
1582 "\x25&'()*+,-./0123456789:;<=>?¡ABCDEFGHIJKLM"
1583 "NOPQRSTUVWXYZÄÖ") == 0);
1584 g_assert(strcmp(iso639_lang, "en") == 0);
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",
1593 static const char *inv_ranges[] = { "1-5, 3333", "1-5, afbcd", "1-5, 3-5,,",
1594 "1-5, 3-5, c", NULL };
1596 static void test_range_minimizer(void)
1600 while (inv_ranges[i]) {
1601 GSList *l = cbs_extract_topic_ranges(inv_ranges[i]);
1603 g_assert(l == NULL);
1610 GSList *r = cbs_extract_topic_ranges(ranges[i]);
1613 g_assert(r != NULL);
1616 rangestr = cbs_topic_ranges_to_string(r);
1620 if (g_test_verbose())
1621 g_print("range: %s\n", rangestr);
1624 g_slist_foreach(r, (GFunc)g_free, NULL);
1629 static void test_sr_assembly(void)
1631 const char *sr_pdu1 = "06040D91945152991136F00160124130340A0160124130"
1633 const char *sr_pdu2 = "06050D91945152991136F00160124130640A0160124130"
1635 const char *sr_pdu3 = "0606098121436587F9019012413064A0019012413045A0"
1640 unsigned char pdu[176];
1642 struct status_report_assembly *sra;
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,
1648 unsigned char id[SMS_MSGID_LEN];
1650 /* international address, mr 4 & mr 5 */
1652 decode_hex_own_buf(sr_pdu1, -1, &pdu_len, 0, pdu);
1653 g_assert(sms_decode(pdu, pdu_len, FALSE, 26, &sr1) == TRUE);
1655 decode_hex_own_buf(sr_pdu2, -1, &pdu_len, 0, pdu);
1656 g_assert(sms_decode(pdu, pdu_len, FALSE, 26, &sr2) == TRUE);
1658 /* national address, mr 6 */
1660 decode_hex_own_buf(sr_pdu3, -1, &pdu_len, 0, pdu);
1661 g_assert(sms_decode(pdu, pdu_len, FALSE, 24, &sr3) == TRUE);
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);
1668 g_print("sr2 address: %s, mr: %d\n",
1669 sms_address_to_string(&sr2.status_report.raddr),
1670 sr2.status_report.mr);
1672 g_print("sr3 address: %s, mr: %d\n",
1673 sms_address_to_string(&sr3.status_report.raddr),
1674 sr3.status_report.mr);
1677 sms_address_from_string(&addr, "+4915259911630");
1679 sra = status_report_assembly_new(NULL);
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);
1684 status_report_assembly_expire(sra, time(NULL) + 40);
1685 g_assert(g_hash_table_size(sra->assembly_table) == 0);
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);
1690 g_assert(!status_report_assembly_report(sra, &sr1, id, &delivered));
1691 g_assert(status_report_assembly_report(sra, &sr2, id, &delivered));
1693 g_assert(memcmp(id, sha1, SMS_MSGID_LEN) == 0);
1694 g_assert(delivered == TRUE);
1697 * Send sms-message in the national address-format,
1698 * but receive in the international address-format.
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);
1704 g_assert(!status_report_assembly_report(sra, &sr1, id, &delivered));
1705 g_assert(status_report_assembly_report(sra, &sr2, id, &delivered));
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);
1712 * Send sms-message in the international address-format,
1713 * but receive in the national address-format.
1715 sms_address_from_string(&addr, "+358123456789");
1716 status_report_assembly_add_fragment(sra, sha1, &addr, 6, time(NULL), 1);
1718 g_assert(status_report_assembly_report(sra, &sr3, id, &delivered));
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);
1724 status_report_assembly_free(sra);
1727 struct wap_push_data {
1732 static struct wap_push_data wap_push_1 = {
1733 .pdu = "0791947122725014440185F039F501801140311480720605040B8423F00106"
1734 "246170706C69636174696F6E2F766E642E7761702E6D6D732D6D657373616"
1735 "76500AF84B4868C82984F67514B4B42008D9089088045726F74696B009650"
1736 "696E2D557073008A808E0240008805810303F48083687474703A2F2F65707"
1737 "3332E64652F4F2F5A39495A4F00",
1741 static void test_wap_push(gconstpointer data)
1743 const struct wap_push_data *test = data;
1745 unsigned char *decoded_pdu;
1750 enum sms_charset charset;
1752 unsigned char *wap_push;
1753 int dst_port, src_port;
1756 decoded_pdu = decode_hex(test->pdu, -1, &pdu_len, 0);
1758 g_assert(decoded_pdu);
1760 ret = sms_decode(decoded_pdu, pdu_len, FALSE, test->len, &sms);
1762 g_free(decoded_pdu);
1765 g_assert(sms.type == SMS_TYPE_DELIVER);
1767 if (g_test_verbose())
1770 ret = sms_dcs_decode(sms.deliver.dcs, &cls, &charset, NULL, NULL);
1772 g_assert(ret == TRUE);
1773 g_assert(charset == SMS_CHARSET_8BIT);
1775 g_assert(sms_extract_app_port(&sms, &dst_port, &src_port, &is_8bit));
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);
1782 g_assert(is_8bit == FALSE);
1783 g_assert(dst_port == 2948);
1785 list = g_slist_append(NULL, &sms);
1787 wap_push = sms_decode_datagram(list, &data_len);
1789 if (g_test_verbose()) {
1792 g_print("data_len: %ld\n", data_len);
1794 for (i = 0; i < data_len; i++) {
1795 g_print("%02x", wap_push[i]);
1810 int main(int argc, char **argv)
1812 char long_string[152*33 + 1];
1813 struct sms_concat_data long_string_test;
1815 g_test_init(&argc, &argv, NULL);
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);
1824 g_test_add_data_func("/testsms/Test "
1825 "GSM 7 bit Default Alphabet Decode",
1826 &sms_charset_default, test_sms_charset);
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);
1832 g_test_add_data_func("/testsms/Test "
1833 "Turkish National Language Locking Shift Table Decode",
1834 &sms_charset_turkey, test_sms_charset);
1836 g_test_add_data_func("/testsms/Test "
1837 "Turkish National Language Single Shift Table Decode",
1838 &sms_charset_turkey_ext, test_sms_charset);
1840 g_test_add_data_func("/testsms/Test "
1841 "Portuguese National Language Locking Shift Table Decode",
1842 &sms_charset_portugal, test_sms_charset);
1844 g_test_add_data_func("/testsms/Test "
1845 "Portuguese National Language Single Shift Table Decode",
1846 &sms_charset_portugal_ext, test_sms_charset);
1848 g_test_add_data_func("/testsms/Test "
1849 "Spanish National Language Single Shift Table Decode",
1850 &sms_charset_spain, test_sms_charset);
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);
1857 g_test_add_func("/testsms/Test Assembly", test_assembly);
1858 g_test_add_func("/testsms/Test Prepare 7Bit", test_prepare_7bit);
1860 g_test_add_data_func("/testsms/Test Prepare Concat",
1861 &shakespeare_test, test_prepare_concat);
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';
1869 long_string_test.str = long_string;
1870 long_string_test.segments = 33;
1872 g_test_add_data_func("/testsms/Test Prepare Concat 30+ segments",
1873 &long_string_test, test_prepare_concat);
1875 g_test_add_func("/testsms/Test Prepare Limits", test_prepare_limits);
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);
1881 g_test_add_func("/testsms/Test CBS Padding Character",
1882 test_cbs_padding_character);
1884 g_test_add_func("/testsms/Range minimizer", test_range_minimizer);
1886 g_test_add_func("/testsms/Status Report Assembly", test_sr_assembly);
1888 g_test_add_data_func("/testsms/Test WAP Push 1", &wap_push_1,
1891 return g_test_run();