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 *simple_submit = "0011000B916407281553F80000AA"
42 "0AE8329BFD4697D9EC37";
44 static void print_scts(struct sms_scts *scts, const char *prefix)
50 g_print("%s: (YY-MM-DD) %02d-%02d-%02d\n", prefix,
51 (int)scts->year, (int)scts->month, (int)scts->day);
53 g_print("%s: (HH-MM-SS) %02d:%02d:%02d\n", prefix,
54 (int)scts->hour, (int)scts->minute, (int)scts->second);
56 g_print("%s: Timezone %d hours %d minutes\n", prefix,
57 (int)scts->timezone / 4,
58 (int)((abs(scts->timezone) % 4) * 15));
60 ts = sms_scts_to_time(scts, &remote);
62 strftime(buf, 127, "%Y-%m-%dT%H:%M:%S%z", localtime(&ts));
65 g_print("local time: %s\n", buf);
67 strftime(buf, 127, "%Y-%m-%dT%H:%M:%S%z", &remote);
70 g_print("remote time: %s\n", buf);
73 static void print_vpf(enum sms_validity_period_format vpf,
74 struct sms_validity_period *vp)
76 g_print("Validity Period Format: %d\n", (int)vpf);
79 case SMS_VALIDITY_PERIOD_FORMAT_ABSENT:
80 g_print("Validity-Period: Absent\n");
82 case SMS_VALIDITY_PERIOD_FORMAT_RELATIVE:
83 g_print("Validity-Period: %d\n",
86 case SMS_VALIDITY_PERIOD_FORMAT_ABSOLUTE:
87 print_scts(&vp->absolute, "Validity-Period:");
89 case SMS_VALIDITY_PERIOD_FORMAT_ENHANCED:
90 g_print("Validity-Period: Enhanced");
95 static void dump_details(struct sms *sms)
97 if (sms->sc_addr.address[0] == '\0')
98 g_print("SMSC Address absent, default will be used\n");
100 g_print("SMSC Address number_type: %d, number_plan: %d, %s\n",
101 (int)sms->sc_addr.number_type,
102 (int)sms->sc_addr.numbering_plan, sms->sc_addr.address);
105 case SMS_TYPE_DELIVER:
106 g_print("Type: Deliver\n");
108 g_print("Originator-Address: %d, %d, %s\n",
109 (int)sms->deliver.oaddr.number_type,
110 (int)sms->deliver.oaddr.numbering_plan,
111 sms->deliver.oaddr.address);
113 g_print("PID: %d\n", (int)sms->deliver.pid);
114 g_print("DCS: %d\n", (int)sms->deliver.dcs);
116 print_scts(&sms->deliver.scts, "Timestamp");
119 case SMS_TYPE_SUBMIT:
120 g_print("Type: Submit\n");
122 g_print("Message Reference: %u\n", (int)sms->submit.mr);
124 g_print("Destination-Address: %d, %d, %s\n",
125 (int)sms->submit.daddr.number_type,
126 (int)sms->submit.daddr.numbering_plan,
127 sms->submit.daddr.address);
129 g_print("PID: %d\n", (int)sms->submit.pid);
130 g_print("DCS: %d\n", (int)sms->submit.dcs);
132 print_vpf(sms->submit.vpf, &sms->submit.vp);
135 case SMS_TYPE_STATUS_REPORT:
137 case SMS_TYPE_COMMAND:
138 case SMS_TYPE_DELIVER_REPORT_ACK:
139 case SMS_TYPE_DELIVER_REPORT_ERROR:
140 case SMS_TYPE_SUBMIT_REPORT_ACK:
141 case SMS_TYPE_SUBMIT_REPORT_ERROR:
146 static void test_simple_deliver(void)
149 unsigned char *decoded_pdu;
153 unsigned char *unpacked;
156 decoded_pdu = decode_hex(simple_deliver, -1, &pdu_len, 0);
158 g_assert(decoded_pdu);
159 g_assert(pdu_len == (long)strlen(simple_deliver) / 2);
161 ret = sms_decode(decoded_pdu, pdu_len, FALSE, 30, &sms);
166 g_assert(sms.type == SMS_TYPE_DELIVER);
168 if (g_test_verbose())
171 g_assert(sms.sc_addr.number_type == SMS_NUMBER_TYPE_INTERNATIONAL);
172 g_assert(sms.sc_addr.numbering_plan == SMS_NUMBERING_PLAN_ISDN);
173 g_assert(strcmp(sms.sc_addr.address, "31624000000") == 0);
175 g_assert(sms.deliver.oaddr.number_type ==
176 SMS_NUMBER_TYPE_INTERNATIONAL);
177 g_assert(sms.deliver.oaddr.numbering_plan ==
178 SMS_NUMBERING_PLAN_ISDN);
179 g_assert(strcmp(sms.deliver.oaddr.address, "31641600986") == 0);
181 g_assert(sms.deliver.pid == 0);
182 g_assert(sms.deliver.dcs == 0);
184 g_assert(sms.deliver.scts.year == 2);
185 g_assert(sms.deliver.scts.month == 8);
186 g_assert(sms.deliver.scts.day == 26);
187 g_assert(sms.deliver.scts.hour == 19);
188 g_assert(sms.deliver.scts.minute == 37);
189 g_assert(sms.deliver.scts.second == 41);
190 g_assert(sms.deliver.scts.timezone == -4);
192 g_assert(sms.deliver.udl == 12);
194 data_len = sms_udl_in_bytes(sms.deliver.udl, sms.deliver.dcs);
196 g_assert(data_len == 11);
198 unpacked = unpack_7bit(sms.deliver.ud, data_len, 0, FALSE,
199 sms.deliver.udl, NULL, 0xff);
203 utf8 = convert_gsm_to_utf8(unpacked, -1, NULL, NULL, 0xff);
209 if (g_test_verbose())
210 g_print("Decoded user data is: %s\n", utf8);
212 g_assert(strcmp(utf8, "How are you?") == 0);
217 static void test_alnum_sender(void)
220 unsigned char *decoded_pdu;
224 unsigned char *unpacked;
227 decoded_pdu = decode_hex(alnum_sender, -1, &pdu_len, 0);
229 g_assert(decoded_pdu);
230 g_assert(pdu_len == (long)strlen(alnum_sender) / 2);
232 ret = sms_decode(decoded_pdu, pdu_len, FALSE, 27, &sms);
237 g_assert(sms.type == SMS_TYPE_DELIVER);
239 if (g_test_verbose())
242 g_assert(sms.sc_addr.number_type == SMS_NUMBER_TYPE_INTERNATIONAL);
243 g_assert(sms.sc_addr.numbering_plan == SMS_NUMBERING_PLAN_ISDN);
244 g_assert(strcmp(sms.sc_addr.address, "447785016005") == 0);
246 g_assert(sms.deliver.oaddr.number_type ==
247 SMS_NUMBER_TYPE_ALPHANUMERIC);
248 g_assert(sms.deliver.oaddr.numbering_plan ==
249 SMS_NUMBERING_PLAN_UNKNOWN);
250 g_assert(strcmp(sms.deliver.oaddr.address, "sipgate") == 0);
252 g_assert(sms.deliver.pid == 0);
253 g_assert(sms.deliver.dcs == 0);
255 g_assert(sms.deliver.scts.year == 8);
256 g_assert(sms.deliver.scts.month == 8);
257 g_assert(sms.deliver.scts.day == 13);
258 g_assert(sms.deliver.scts.hour == 12);
259 g_assert(sms.deliver.scts.minute == 07);
260 g_assert(sms.deliver.scts.second == 22);
261 g_assert(sms.deliver.scts.timezone == 4);
263 g_assert(sms.deliver.udl == 8);
265 data_len = sms_udl_in_bytes(sms.deliver.udl, sms.deliver.dcs);
267 g_assert(data_len == 7);
269 unpacked = unpack_7bit(sms.deliver.ud, data_len, 0, FALSE,
270 sms.deliver.udl, NULL, 0xff);
274 utf8 = convert_gsm_to_utf8(unpacked, -1, NULL, NULL, 0xff);
280 if (g_test_verbose())
281 g_print("Decoded user data is: %s\n", utf8);
283 g_assert(strcmp(utf8, "Testmail") == 0);
288 static void test_deliver_encode(void)
291 unsigned char *decoded_pdu;
294 unsigned char pdu[176];
296 int encoded_tpdu_len;
299 decoded_pdu = decode_hex(simple_deliver, -1, &pdu_len, 0);
301 g_assert(decoded_pdu);
302 g_assert(pdu_len == (long)strlen(simple_deliver) / 2);
304 ret = sms_decode(decoded_pdu, pdu_len, FALSE, 30, &sms);
309 g_assert(sms.type == SMS_TYPE_DELIVER);
311 ret = sms_encode(&sms, &encoded_pdu_len, &encoded_tpdu_len, pdu);
313 if (g_test_verbose()) {
316 for (i = 0; i < encoded_pdu_len; i++)
317 g_print("%02X", pdu[i]);
322 g_assert(encoded_tpdu_len == 30);
323 g_assert(encoded_pdu_len == pdu_len);
325 encoded_pdu = encode_hex(pdu, encoded_pdu_len, 0);
327 g_assert(strcmp(simple_deliver, encoded_pdu) == 0);
331 decoded_pdu = decode_hex(alnum_sender, -1, &pdu_len, 0);
333 g_assert(decoded_pdu);
334 g_assert(pdu_len == (long)strlen(alnum_sender) / 2);
336 ret = sms_decode(decoded_pdu, pdu_len, FALSE, 27, &sms);
341 g_assert(sms.type == SMS_TYPE_DELIVER);
343 ret = sms_encode(&sms, &encoded_pdu_len, &encoded_tpdu_len, pdu);
345 if (g_test_verbose()) {
348 for (i = 0; i < encoded_pdu_len; i++)
349 g_print("%02X", pdu[i]);
354 g_assert(encoded_tpdu_len == 27);
355 g_assert(encoded_pdu_len == pdu_len);
357 encoded_pdu = encode_hex(pdu, encoded_pdu_len, 0);
359 g_assert(strcmp(alnum_sender, encoded_pdu) == 0);
364 static void test_simple_submit(void)
367 unsigned char *decoded_pdu;
371 unsigned char *unpacked;
374 decoded_pdu = decode_hex(simple_submit, -1, &pdu_len, 0);
376 g_assert(decoded_pdu);
377 g_assert(pdu_len == (long)strlen(simple_submit) / 2);
379 ret = sms_decode(decoded_pdu, pdu_len, TRUE, 23, &sms);
384 g_assert(sms.type == SMS_TYPE_SUBMIT);
386 if (g_test_verbose())
389 g_assert(strlen(sms.sc_addr.address) == 0);
391 g_assert(sms.submit.mr == 0);
393 g_assert(sms.submit.daddr.number_type ==
394 SMS_NUMBER_TYPE_INTERNATIONAL);
395 g_assert(sms.submit.daddr.numbering_plan ==
396 SMS_NUMBERING_PLAN_ISDN);
397 g_assert(strcmp(sms.submit.daddr.address, "46708251358") == 0);
399 g_assert(sms.submit.pid == 0);
400 g_assert(sms.submit.dcs == 0);
402 g_assert(sms.submit.vpf == SMS_VALIDITY_PERIOD_FORMAT_RELATIVE);
403 g_assert(sms.submit.vp.relative == 0xAA);
405 g_assert(sms.submit.udl == 10);
407 data_len = sms_udl_in_bytes(sms.submit.udl, sms.submit.dcs);
409 g_assert(data_len == 9);
411 unpacked = unpack_7bit(sms.submit.ud, data_len, 0, FALSE,
412 sms.submit.udl, NULL, 0xff);
416 utf8 = convert_gsm_to_utf8(unpacked, -1, NULL, NULL, 0xff);
422 if (g_test_verbose())
423 g_print("Decoded user data is: %s\n", utf8);
425 g_assert(strcmp(utf8, "hellohello") == 0);
430 static void test_submit_encode(void)
433 unsigned char *decoded_pdu;
436 unsigned char pdu[176];
438 int encoded_tpdu_len;
441 decoded_pdu = decode_hex(simple_submit, -1, &pdu_len, 0);
443 g_assert(decoded_pdu);
444 g_assert(pdu_len == (long)strlen(simple_submit) / 2);
446 ret = sms_decode(decoded_pdu, pdu_len, TRUE, 23, &sms);
451 g_assert(sms.type == SMS_TYPE_SUBMIT);
453 ret = sms_encode(&sms, &encoded_pdu_len, &encoded_tpdu_len, pdu);
455 if (g_test_verbose()) {
458 for (i = 0; i < encoded_pdu_len; i++)
459 g_print("%02X", pdu[i]);
464 g_assert(encoded_tpdu_len == 23);
465 g_assert(encoded_pdu_len == pdu_len);
467 encoded_pdu = encode_hex(pdu, encoded_pdu_len, 0);
469 g_assert(strcmp(simple_submit, encoded_pdu) == 0);
474 struct sms_charset_data {
477 enum gsm_dialect locking_lang;
478 enum gsm_dialect single_lang;
479 char expected_text[];
482 static struct sms_charset_data sms_charset_default = {
484 "0001000B91" "5310101010" "1000008080" "8060402818" "0E888462C1"
485 "68381E9088" "6442A9582E" "988C06C4E9" "783EA09068" "442A994EA8"
486 "946AC56AB9" "5EB0986C46" "ABD96EB89C" "6EC7EBF97E" "C0A070482C"
487 "1A8FC8A472" "C96C3A9FD0" "A8744AAD5A" "AFD8AC76CB" "ED7ABFE0B0"
488 "784C2E9BCF" "E8B47ACD6E" "BBDFF0B87C" "4EAFDBEFF8" "BC7ECFEFFB"
492 0x40, 0xc2, 0xa3, 0x24, 0xc2, 0xa5, 0xc3, 0xa8, 0xc3, 0xa9,
493 0xc3, 0xb9, 0xc3, 0xac, 0xc3, 0xb2, 0xc3, 0x87, 0x0a, 0xc3,
494 0x98, 0xc3, 0xb8, 0x0d, 0xc3, 0x85, 0xc3, 0xa5, 0xce, 0x94,
495 0x5f, 0xce, 0xa6, 0xce, 0x93, 0xce, 0x9b, 0xce, 0xa9, 0xce,
496 0xa0, 0xce, 0xa8, 0xce, 0xa3, 0xce, 0x98, 0xce, 0x9e, 0x20,
497 0xc3, 0x86, 0xc3, 0xa6, 0xc3, 0x9f, 0xc3, 0x89, 0x20, 0x21,
498 0x22, 0x23, 0xc2, 0xa4, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,
499 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34,
500 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
501 0x3f, 0xc2, 0xa1, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
502 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51,
503 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0xc3,
504 0x84, 0xc3, 0x96, 0xc3, 0x91, 0xc3, 0x9c, 0xc2, 0xa7, 0xc2,
505 0xbf, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
506 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73,
507 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0xc3, 0xa4, 0xc3,
508 0xb6, 0xc3, 0xb1, 0xc3, 0xbc, 0xc3, 0xa0, 0x00
512 static struct sms_charset_data sms_charset_default_ext = {
514 "0001000B91" "5310101010" "100000151B" "C58602DAA0" "36A9CD6BC3"
515 "DBF436BE0D" "705306",
518 0x0c, 0x5e, 0x20, 0x7b, 0x7d, 0x5c, 0x5b, 0x7e, 0x5d, 0x7c,
519 0xe2, 0x82, 0xac, 0x00
523 static struct sms_charset_data sms_charset_turkey = {
525 "0001000B91" "5310101010" "1000008080" "8060402818" "0E888462C1"
526 "68381E9088" "6442A9582E" "988C06C4E9" "783EA09068" "442A994EA8"
527 "946AC56AB9" "5EB0986C46" "ABD96EB89C" "6EC7EBF97E" "C0A070482C"
528 "1A8FC8A472" "C96C3A9FD0" "A8744AAD5A" "AFD8AC76CB" "ED7ABFE0B0"
529 "784C2E9BCF" "E8B47ACD6E" "BBDFF0B87C" "4EAFDBEFF8" "BC7ECFEFFB"
532 .locking_lang = GSM_DIALECT_TURKISH,
534 0x40, 0xc2, 0xa3, 0x24, 0xc2, 0xa5, 0xe2, 0x82, 0xac, 0xc3,
535 0xa9, 0xc3, 0xb9, 0xc4, 0xb1, 0xc3, 0xb2, 0xc3, 0x87, 0x0a,
536 0xc4, 0x9e, 0xc4, 0x9f, 0x0d, 0xc3, 0x85, 0xc3, 0xa5, 0xce,
537 0x94, 0x5f, 0xce, 0xa6, 0xce, 0x93, 0xce, 0x9b, 0xce, 0xa9,
538 0xce, 0xa0, 0xce, 0xa8, 0xce, 0xa3, 0xce, 0x98, 0xce, 0x9e,
539 0x20, 0xc5, 0x9e, 0xc5, 0x9f, 0xc3, 0x9f, 0xc3, 0x89, 0x20,
540 0x21, 0x22, 0x23, 0xc2, 0xa4, 0x25, 0x26, 0x27, 0x28, 0x29,
541 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33,
542 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d,
543 0x3e, 0x3f, 0xc4, 0xb0, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
544 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
545 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a,
546 0xc3, 0x84, 0xc3, 0x96, 0xc3, 0x91, 0xc3, 0x9c, 0xc2, 0xa7,
547 0xc3, 0xa7, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
548 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72,
549 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0xc3, 0xa4,
550 0xc3, 0xb6, 0xc3, 0xb1, 0xc3, 0xbc, 0xc3, 0xa0, 0x00
554 static struct sms_charset_data sms_charset_turkey_ext = {
556 "0001000B91" "5310101010" "1000001A1B" "C586B2416D" "529BD786B7"
557 "E96D7C1BE0" "02C8011318" "870E",
559 .locking_lang = GSM_DIALECT_TURKISH,
560 .single_lang = GSM_DIALECT_TURKISH,
562 0x0c, 0x5e, 0x7b, 0x7d, 0x5c, 0x5b, 0x7e, 0x5d, 0x7c, 0xc4,
563 0x9e, 0xc4, 0xb0, 0xc5, 0x9e, 0xc3, 0xa7, 0xe2, 0x82, 0xac,
564 0xc4, 0x9f, 0xc4, 0xb1, 0xc5, 0x9f, 0x00
568 static struct sms_charset_data sms_charset_portugal = {
570 "0001000B91" "5310101010" "1000008080" "8060402818" "0E888462C1"
571 "68381E9088" "6442A9582E" "988C06C4E9" "783EA09068" "442A994EA8"
572 "946AC56AB9" "5EB0986C46" "ABD96EB89C" "6EC7EBF97E" "C0A070482C"
573 "1A8FC8A472" "C96C3A9FD0" "A8744AAD5A" "AFD8AC76CB" "ED7ABFE0B0"
574 "784C2E9BCF" "E8B47ACD6E" "BBDFF0B87C" "4EAFDBEFF8" "BC7ECFEFFB"
577 .locking_lang = GSM_DIALECT_PORTUGUESE,
579 0x40, 0xc2, 0xa3, 0x24, 0xc2, 0xa5, 0xc3, 0xaa, 0xc3, 0xa9,
580 0xc3, 0xba, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xa7, 0x0a, 0xc3,
581 0x94, 0xc3, 0xb4, 0x0d, 0xc3, 0x81, 0xc3, 0xa1, 0xce, 0x94,
582 0x5f, 0xc2, 0xaa, 0xc3, 0x87, 0xc3, 0x80, 0xe2, 0x88, 0x9e,
583 0x5e, 0x5c, 0xe2, 0x82, 0xac, 0xc3, 0x93, 0x7c, 0x20, 0xc3,
584 0x82, 0xc3, 0xa2, 0xc3, 0x8a, 0xc3, 0x89, 0x20, 0x21, 0x22,
585 0x23, 0xc2, 0xba, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
586 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
587 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
588 0xc3, 0x8d, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
589 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52,
590 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0xc3, 0x83,
591 0xc3, 0x95, 0xc3, 0x9a, 0xc3, 0x9c, 0xc2, 0xa7, 0x7e, 0x61,
592 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
593 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75,
594 0x76, 0x77, 0x78, 0x79, 0x7a, 0xc3, 0xa3, 0xc3, 0xb5, 0x60,
595 0xc3, 0xbc, 0xc3, 0xa0, 0x00
599 static struct sms_charset_data sms_charset_portugal_ext = {
601 "0001000B91" "5310101010" "1000003184" "C446B16038" "1E1BC96662"
602 "D9543696CD" "6583D9643C" "1BD42675D9" "F0C01B9F86" "02CC74B75C"
605 .locking_lang = GSM_DIALECT_PORTUGUESE,
606 .single_lang = GSM_DIALECT_PORTUGUESE,
608 0xc3, 0xaa, 0xc3, 0xa7, 0x0c, 0xc3, 0x94, 0xc3, 0xb4, 0xc3,
609 0x81, 0xc3, 0xa1, 0xce, 0xa6, 0xce, 0x93, 0x5e, 0xce, 0xa9,
610 0xce, 0xa0, 0xce, 0xa8, 0xce, 0xa3, 0xce, 0x98, 0xc3, 0x8a,
611 0x7b, 0x7d, 0x5c, 0x5b, 0x7e, 0x5d, 0x7c, 0xc3, 0x80, 0xc3,
612 0x8d, 0xc3, 0x93, 0xc3, 0x9a, 0xc3, 0x83, 0xc3, 0x95, 0xc3,
613 0x82, 0xe2, 0x82, 0xac, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba,
614 0xc3, 0xa3, 0xc3, 0xb5, 0xc3, 0xa2, 0x00
618 static struct sms_charset_data sms_charset_spain = {
620 "0001000B91" "5310101010" "100000269B" "C446B1A16C" "509BD4E6B5"
621 "E16D7A1BDF" "06B8096E92" "9BE7A6BA09" "6FCA9BF4E6" "BDA903",
623 .locking_lang = GSM_DIALECT_SPANISH,
624 .single_lang = GSM_DIALECT_SPANISH,
626 0xc3, 0xa7, 0x0c, 0x5e, 0x7b, 0x7d, 0x5c, 0x5b, 0x7e, 0x5d,
627 0x7c, 0xc3, 0x81, 0xc3, 0x8d, 0xc3, 0x93, 0xc3, 0x9a, 0xc3,
628 0xa1, 0xe2, 0x82, 0xac, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba,
633 static void test_sms_charset(gconstpointer param)
638 unsigned char *unpacked;
641 enum sms_charset sms_charset;
642 gboolean sms_compressed;
644 struct sms_charset_data *data = (struct sms_charset_data *)param;
646 pdu = decode_hex(data->pdu, -1, &pdu_len, 0);
649 g_assert(pdu_len == (gint64)strlen(data->pdu) / 2);
651 ret = sms_decode(pdu, pdu_len, FALSE, pdu_len, &sms);
657 g_assert(sms.type == SMS_TYPE_DELIVER);
659 ret = sms_dcs_decode(sms.deliver.dcs, NULL, &sms_charset,
660 &sms_compressed, NULL);
663 g_assert(sms_charset == SMS_CHARSET_7BIT);
664 g_assert(sms_compressed == FALSE);
666 data_len = sms_udl_in_bytes(sms.deliver.udl, sms.deliver.dcs);
668 g_assert(data_len == data->data_len);
670 unpacked = unpack_7bit(sms.deliver.ud, data_len, 0, FALSE,
671 sms.deliver.udl, NULL, 0xff);
675 text = convert_gsm_to_utf8_with_lang(unpacked, -1, NULL, NULL, 0xff,
676 data->locking_lang, data->single_lang);
682 g_assert(strcmp(data->expected_text, text) == 0);
687 struct text_format_header {
691 unsigned char format;
695 struct ems_udh_test {
698 const char *expected;
701 unsigned int data_len;
702 struct text_format_header formats[];
705 static struct ems_udh_test ems_udh_test_1 = {
706 .pdu = "0041000B915121551532F40000631A0A031906200A032104100A03270504"
707 "0A032E05080A043807002B8ACD29A85D9ECFC3E7F21C340EBB41E3B79B1"
708 "E4EBB41697A989D1EB340E2379BCC02B1C3F27399059AB7C36C3628EC26"
709 "83C66FF65B5E2683E8653C1D",
711 .expected = "EMS messages can contain italic, bold, large, small and"
754 static struct ems_udh_test ems_udh_test_2 = {
755 .pdu = "079194712272303351030B915121340195F60000FF80230A030F07230A031"
756 "806130A031E0A430A032E0D830A033D14020A035104F60A0355010600159"
757 "D9E83D2735018442FCFE98A243DCC4E97C92C90F8CD26B3407537B92C67A"
758 "7DD65320B1476934173BA3CBD2ED3D1F277FD8C76299CEF3B280C92A7CF6"
759 "83A28CC4E9FDD6532E8FE96935D",
761 .expected = "This is a test\nItalied, bold, underlined, and "
762 "strikethrough.\nNow a right aligned word.",
812 static void test_ems_udh(gconstpointer data)
814 const struct ems_udh_test *test = data;
816 unsigned char *decoded_pdu;
819 unsigned int data_len;
821 struct sms_udh_iter iter;
823 unsigned char *unpacked;
827 decoded_pdu = decode_hex(test->pdu, -1, &pdu_len, 0);
829 g_assert(decoded_pdu);
830 g_assert(pdu_len == (long)strlen(test->pdu) / 2);
832 ret = sms_decode(decoded_pdu, pdu_len, TRUE, test->len, &sms);
837 g_assert(sms.type == SMS_TYPE_SUBMIT);
839 if (g_test_verbose())
841 udhl = sms.submit.ud[0];
843 g_assert(sms.submit.udl == test->udl);
844 g_assert(udhl == test->udhl);
846 ret = sms_udh_iter_init(&sms, &iter);
850 for (i = 0; test->formats[i].len; i++) {
851 if (g_test_verbose()) {
853 unsigned char data[4];
855 sms_udh_iter_get_ie_data(&iter, data);
857 g_print("Header:\n");
858 for (j = 0; j < sms_udh_iter_get_ie_length(&iter); j++)
859 g_print("0x%02x ", data[j]);
864 g_assert(sms_udh_iter_get_ie_type(&iter) ==
865 SMS_IEI_TEXT_FORMAT);
866 g_assert(sms_udh_iter_get_ie_length(&iter) ==
867 test->formats[i].len);
869 if (test->formats[i+1].len) {
870 g_assert(sms_udh_iter_has_next(&iter) == TRUE);
871 g_assert(sms_udh_iter_next(&iter) == TRUE);
873 g_assert(sms_udh_iter_has_next(&iter) == FALSE);
874 g_assert(sms_udh_iter_next(&iter) == FALSE);
875 g_assert(sms_udh_iter_get_ie_type(&iter) ==
880 data_len = sms_udl_in_bytes(sms.submit.udl, sms.submit.dcs);
882 g_assert(data_len == test->data_len);
884 max_chars = (data_len - (udhl + 1)) * 8 / 7;
886 unpacked = unpack_7bit(sms.submit.ud + udhl + 1, data_len - (udhl + 1),
887 udhl + 1, FALSE, max_chars, NULL, 0xff);
891 utf8 = convert_gsm_to_utf8(unpacked, -1, NULL, NULL, 0xff);
897 if (g_test_verbose())
898 g_print("Decoded user data is: %s\n", utf8);
900 g_assert(strcmp(utf8, test->expected) == 0);
905 static const char *assembly_pdu1 = "038121F340048155550119906041001222048C0500"
906 "031E0301041804420430043A002C002004100"
907 "43B0435043A04410430043D04340440002000"
908 "200441043B044304480430043B00200437043"
909 "000200434043204350440044C044E00200020"
910 "04380020002004320441043500200431043E0"
911 "43B044C044804350020043F04400435043804"
912 "41043F043E043B043D044F043B0441044F002"
914 static int assembly_pdu_len1 = 155;
916 static const char *assembly_pdu2 = "038121F340048155550119906041001222048C0500"
917 "031E03020432043E043C002E000A041D04300"
918 "43A043E043D04350446002C0020043D043500"
919 "200432002004410438043B043004450020043"
920 "40430043B043504350020044204350440043F"
921 "04350442044C002C0020043E043D002004410"
922 "44204400435043C043804420435043B044C04"
923 "3D043E002004320431043504360430043B002"
925 static int assembly_pdu_len2 = 155;
927 static const char *assembly_pdu3 = "038121F340048155550119906041001222044A0500"
928 "031E0303043C043D043004420443002C00200"
929 "43F043E043704300431044B0432000A043404"
930 "3004360435002C002004470442043E0020002"
931 "00431044B043B0020043D04300433002E";
932 static int assembly_pdu_len3 = 89;
934 static void test_assembly(void)
936 unsigned char pdu[176];
939 struct sms_assembly *assembly = sms_assembly_new(NULL);
947 decode_hex_own_buf(assembly_pdu1, -1, &pdu_len, 0, pdu);
948 sms_decode(pdu, pdu_len, FALSE, assembly_pdu_len1, &sms);
950 sms_extract_concatenation(&sms, &ref, &max, &seq);
951 l = sms_assembly_add_fragment(assembly, &sms, time(NULL),
952 &sms.deliver.oaddr, ref, max, seq);
954 if (g_test_verbose()) {
955 g_print("Ref: %u\n", ref);
956 g_print("Max: %u\n", max);
957 g_print("From: %s\n",
958 sms_address_to_string(&sms.deliver.oaddr));
961 g_assert(g_slist_length(assembly->assembly_list) == 1);
964 sms_assembly_expire(assembly, time(NULL) + 40);
966 g_assert(g_slist_length(assembly->assembly_list) == 0);
968 sms_extract_concatenation(&sms, &ref, &max, &seq);
969 l = sms_assembly_add_fragment(assembly, &sms, time(NULL),
970 &sms.deliver.oaddr, ref, max, seq);
971 g_assert(g_slist_length(assembly->assembly_list) == 1);
974 decode_hex_own_buf(assembly_pdu2, -1, &pdu_len, 0, pdu);
975 sms_decode(pdu, pdu_len, FALSE, assembly_pdu_len2, &sms);
977 sms_extract_concatenation(&sms, &ref, &max, &seq);
978 l = sms_assembly_add_fragment(assembly, &sms, time(NULL),
979 &sms.deliver.oaddr, ref, max, seq);
982 decode_hex_own_buf(assembly_pdu3, -1, &pdu_len, 0, pdu);
983 sms_decode(pdu, pdu_len, FALSE, assembly_pdu_len3, &sms);
985 sms_extract_concatenation(&sms, &ref, &max, &seq);
986 l = sms_assembly_add_fragment(assembly, &sms, time(NULL),
987 &sms.deliver.oaddr, ref, max, seq);
991 utf8 = sms_decode_text(l);
993 g_slist_foreach(l, (GFunc)g_free, NULL);
996 sms_assembly_free(assembly);
998 if (g_test_verbose())
999 g_printf("Text:\n%s\n", utf8);
1001 l = sms_text_prepare("555", utf8, ref, TRUE, FALSE);
1003 g_assert(g_slist_length(l) == 3);
1005 reencoded = sms_decode_text(l);
1007 if (g_test_verbose())
1008 g_printf("ReEncoded:\n%s\n", reencoded);
1010 g_assert(strcmp(utf8, reencoded) == 0);
1016 static const char *test_no_fragmentation_7bit = "This is testing !";
1017 static const char *expected_no_fragmentation_7bit = "079153485002020911000C915"
1018 "348870420140000A71154747A0E4ACF41F4F29C9E769F4121";
1019 static const char *sc_addr = "+358405202090";
1020 static const char *da_addr = "+358478400241";
1021 static void test_prepare_7bit(void)
1026 unsigned char pdu[176];
1027 int encoded_pdu_len;
1028 int encoded_tpdu_len;
1031 r = sms_text_prepare("555", test_no_fragmentation_7bit, 0,
1034 g_assert(r != NULL);
1038 sms->sc_addr.number_type = SMS_NUMBER_TYPE_INTERNATIONAL;
1039 sms->sc_addr.numbering_plan = SMS_NUMBERING_PLAN_ISDN;
1040 strcpy(sms->sc_addr.address, sc_addr+1);
1042 if (g_test_verbose())
1043 g_print("sc_addr: %s\n", sms_address_to_string(&sms->sc_addr));
1045 g_assert(!strcmp(sc_addr, sms_address_to_string(&sms->sc_addr)));
1047 sms->submit.daddr.number_type = SMS_NUMBER_TYPE_INTERNATIONAL;
1048 sms->submit.daddr.numbering_plan = SMS_NUMBERING_PLAN_ISDN;
1049 strcpy(sms->submit.daddr.address, da_addr+1);
1051 if (g_test_verbose())
1052 g_print("da_addr: %s\n",
1053 sms_address_to_string(&sms->submit.daddr));
1055 g_assert(!strcmp(da_addr,
1056 sms_address_to_string(&sms->submit.daddr)));
1058 ret = sms_encode(sms, &encoded_pdu_len, &encoded_tpdu_len, pdu);
1062 if (g_test_verbose()) {
1065 for (i = 0; i < encoded_pdu_len; i++)
1066 g_print("%02X", pdu[i]);
1070 encoded_pdu = encode_hex(pdu, encoded_pdu_len, 0);
1072 g_assert(strcmp(expected_no_fragmentation_7bit, encoded_pdu) == 0);
1074 g_free(encoded_pdu);
1075 g_slist_foreach(r, (GFunc)g_free, NULL);
1079 struct sms_concat_data {
1081 unsigned int segments;
1084 static struct sms_concat_data shakespeare_test = {
1085 .str = "Shakespeare divided his time between London and Str"
1086 "atford during his career. In 1596, the year before he bought New Plac"
1087 "e as his family home in Stratford, Shakespeare was living in the pari"
1088 "sh of St. Helen's, Bishopsgate, north of the River Thames.",
1092 /* The string in this test should be padded at the end. This confuses some
1093 * decoders which do not use udl properly
1095 static void test_prepare_concat(gconstpointer data)
1097 const struct sms_concat_data *test = data;
1101 GSList *pdus = NULL;
1102 unsigned char pdu[176];
1105 int pdu_len, tpdu_len;
1106 struct sms_assembly *assembly = sms_assembly_new(NULL);
1111 if (g_test_verbose())
1112 g_print("strlen: %zd\n", strlen(test->str));
1114 r = sms_text_prepare("+15554449999", test->str, 0, TRUE, FALSE);
1116 g_assert(g_slist_length(r) == test->segments);
1118 for (l = r; l; l = l->next) {
1123 sms_encode(sms, &pdu_len, &tpdu_len, pdu);
1124 g_assert(pdu_len == (tpdu_len + 1));
1126 strpdu = encode_hex(pdu, pdu_len, 0);
1128 if (g_test_verbose())
1129 g_printf("PDU: %s, len: %d, tlen: %d\n",
1130 strpdu, pdu_len, tpdu_len);
1131 pdus = g_slist_append(pdus, strpdu);
1134 g_slist_foreach(r, (GFunc)g_free, NULL);
1137 for (l = pdus; l; l = l->next) {
1141 decode_hex_own_buf((char *)l->data, -1, &len, 0, pdu);
1143 if (g_test_verbose())
1144 g_print("PDU Len: %ld\n", len);
1146 ok = sms_decode(pdu, len, TRUE, len - 1, &decoded);
1149 if (g_test_verbose())
1150 g_print("Pdu udl: %d\n", (int)decoded.submit.udl);
1152 sms_extract_concatenation(&decoded, &ref, &max, &seq);
1153 r = sms_assembly_add_fragment(assembly, &decoded, time(NULL),
1154 &decoded.submit.daddr,
1160 decoded_str = sms_decode_text(r);
1162 if (g_test_verbose())
1163 g_printf("Decoded String: %s\n", decoded_str);
1165 g_assert(decoded_str);
1166 g_assert(strcmp(decoded_str, test->str) == 0);
1167 g_free(decoded_str);
1168 sms_assembly_free(assembly);
1171 static void test_limit(gunichar uni, int target_size, gboolean use_16bit)
1178 unsigned int stride;
1180 stride = g_unichar_to_utf8(uni, utf8_char);
1182 utf8 = g_new0(char, (target_size + 2) * stride);
1184 for (i = 0; i < target_size * stride; i += stride)
1185 memcpy(utf8 + i, utf8_char, stride);
1189 l = sms_text_prepare("555", utf8, 0, use_16bit, FALSE);
1192 g_assert(g_slist_length(l) == 255);
1194 decoded = sms_decode_text(l);
1195 g_assert(g_utf8_strlen(decoded, -1) == target_size);
1199 memcpy(utf8 + i, utf8_char, stride);
1200 utf8[i+stride] = '\0';
1202 l = sms_text_prepare("555", utf8, 0, use_16bit, FALSE);
1204 g_assert(l == NULL);
1208 static void test_prepare_limits(void)
1210 gunichar ascii = 0x41;
1211 gunichar ucs2 = 0x416;
1212 unsigned int target_size;
1214 /* The limit for 16 bit headers is 255 * 152 for GSM7 */
1215 target_size = 255 * 152;
1216 test_limit(ascii, target_size, TRUE);
1218 /* The limit for 8 bit headers is 255 * 153 for GSM7 */
1219 target_size = 255 * 153;
1220 test_limit(ascii, target_size, FALSE);
1222 /* The limit for 16 bit headers is 255 * 66 for UCS2 */
1223 target_size = 255 * 66;
1224 test_limit(ucs2, target_size, TRUE);
1226 /* The limit for 8 bit headers is 255 * 67 for UCS2 */
1227 target_size = 255 * 67;
1228 test_limit(ucs2, target_size, FALSE);
1231 static const char *cbs1 = "011000320111C2327BFC76BBCBEE46A3D168341A8D46A3D1683"
1232 "41A8D46A3D168341A8D46A3D168341A8D46A3D168341A8D46A3D168341A8D46A3D168"
1233 "341A8D46A3D168341A8D46A3D168341A8D46A3D168341A8D46A3D100";
1235 static const char *cbs2 = "0110003201114679785E96371A8D46A3D168341A8D46A3D1683"
1236 "41A8D46A3D168341A8D46A3D168341A8D46A3D168341A8D46A3D168341A8D46A3D168"
1237 "341A8D46A3D168341A8D46A3D168341A8D46A3D168341A8D46A3D100";
1239 static void test_cbs_encode_decode(void)
1241 unsigned char *decoded_pdu;
1245 unsigned char pdu[88];
1249 char iso639_lang[3];
1252 decoded_pdu = decode_hex(cbs1, -1, &pdu_len, 0);
1254 g_assert(decoded_pdu);
1255 g_assert(pdu_len == (long)strlen(cbs1) / 2);
1256 g_assert(pdu_len == 88);
1258 ret = cbs_decode(decoded_pdu, pdu_len, &cbs);
1260 g_free(decoded_pdu);
1264 g_assert(cbs.gs == CBS_GEO_SCOPE_CELL_IMMEDIATE);
1265 g_assert(cbs.message_code == 17);
1266 g_assert(cbs.update_number == 0);
1267 g_assert(cbs.message_identifier == 50);
1268 g_assert(cbs.dcs == 1);
1269 g_assert(cbs.max_pages == 1);
1270 g_assert(cbs.page == 1);
1272 l = g_slist_append(NULL, &cbs);
1274 utf8 = cbs_decode_text(l, iso639_lang);
1278 if (g_test_verbose()) {
1279 g_printf("%s\n", utf8);
1280 if (iso639_lang[0] == '\0')
1281 g_printf("Lang: Unspecified\n");
1283 g_printf("Lang: %s\n", iso639_lang);
1286 g_assert(strcmp(utf8, "Belconnen") == 0);
1287 g_assert(strcmp(iso639_lang, "en") == 0);
1293 ret = cbs_encode(&cbs, &len, pdu);
1297 encoded_pdu = encode_hex(pdu, len, 0);
1299 g_assert(strcmp(cbs1, encoded_pdu) == 0);
1301 g_free(encoded_pdu);
1304 static void test_cbs_assembly(void)
1306 unsigned char *decoded_pdu;
1310 struct cbs_assembly *assembly;
1311 char iso639_lang[3];
1315 assembly = cbs_assembly_new();
1319 decoded_pdu = decode_hex(cbs1, -1, &pdu_len, 0);
1320 cbs_decode(decoded_pdu, pdu_len, &dec1);
1321 g_free(decoded_pdu);
1323 decoded_pdu = decode_hex(cbs2, -1, &pdu_len, 0);
1324 cbs_decode(decoded_pdu, pdu_len, &dec2);
1325 g_free(decoded_pdu);
1327 /* Add an initial page to the assembly */
1328 l = cbs_assembly_add_page(assembly, &dec1);
1330 g_assert(g_slist_length(assembly->recv_cell) == 1);
1331 g_slist_foreach(l, (GFunc)g_free, NULL);
1334 /* Can we receive new updates ? */
1335 dec1.update_number = 8;
1336 l = cbs_assembly_add_page(assembly, &dec1);
1338 g_assert(g_slist_length(assembly->recv_cell) == 1);
1339 g_slist_foreach(l, (GFunc)g_free, NULL);
1342 /* Do we ignore old pages ? */
1343 l = cbs_assembly_add_page(assembly, &dec1);
1344 g_assert(l == NULL);
1346 /* Do we ignore older pages ? */
1347 dec1.update_number = 5;
1348 l = cbs_assembly_add_page(assembly, &dec1);
1349 g_assert(l == NULL);
1351 cbs_assembly_location_changed(assembly, TRUE, TRUE, TRUE);
1352 g_assert(assembly->recv_cell == NULL);
1354 dec1.update_number = 9;
1358 dec2.update_number = 9;
1362 l = cbs_assembly_add_page(assembly, &dec2);
1363 g_assert(l == NULL);
1364 l = cbs_assembly_add_page(assembly, &dec1);
1365 g_assert(l == NULL);
1368 l = cbs_assembly_add_page(assembly, &dec1);
1371 utf8 = cbs_decode_text(l, iso639_lang);
1375 if (g_test_verbose()) {
1376 g_printf("%s\n", utf8);
1377 if (iso639_lang[0] == '\0')
1378 g_printf("Lang: Unspecified\n");
1380 g_printf("Lang: %s\n", iso639_lang);
1383 g_assert(strcmp(utf8, "BelconnenFraserBelconnen") == 0);
1386 g_slist_foreach(l, (GFunc)g_free, NULL);
1389 cbs_assembly_free(assembly);
1392 static const char *ranges[] = { "1-5, 2, 3, 600, 569-900, 999",
1393 "0-20, 33, 44, 50-60, 20-50, 1-5, 5, 3, 5",
1395 static const char *inv_ranges[] = { "1-5, 3333", "1-5, afbcd", "1-5, 3-5,,",
1396 "1-5, 3-5, c", NULL };
1398 static void test_range_minimizer(void)
1402 while (inv_ranges[i]) {
1403 GSList *l = cbs_extract_topic_ranges(inv_ranges[i]);
1405 g_assert(l == NULL);
1412 GSList *r = cbs_extract_topic_ranges(ranges[i]);
1415 g_assert(r != NULL);
1418 rangestr = cbs_topic_ranges_to_string(r);
1422 if (g_test_verbose())
1423 g_print("range: %s\n", rangestr);
1426 g_slist_foreach(r, (GFunc)g_free, NULL);
1431 static void test_sr_assembly(void)
1433 const char *sr_pdu1 = "06040D91945152991136F00160124130340A0160124130"
1435 const char *sr_pdu2 = "06050D91945152991136F00160124130640A0160124130"
1437 const char *sr_pdu3 = "0606098121436587F9019012413064A0019012413045A0"
1442 unsigned char pdu[176];
1444 struct status_report_assembly *sra;
1446 struct sms_address addr;
1447 unsigned char sha1[SMS_MSGID_LEN] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
1448 10, 11, 12, 13, 14, 15,
1450 unsigned char id[SMS_MSGID_LEN];
1452 /* international address, mr 4 & mr 5 */
1454 decode_hex_own_buf(sr_pdu1, -1, &pdu_len, 0, pdu);
1455 g_assert(sms_decode(pdu, pdu_len, FALSE, 26, &sr1) == TRUE);
1457 decode_hex_own_buf(sr_pdu2, -1, &pdu_len, 0, pdu);
1458 g_assert(sms_decode(pdu, pdu_len, FALSE, 26, &sr2) == TRUE);
1460 /* national address, mr 6 */
1462 decode_hex_own_buf(sr_pdu3, -1, &pdu_len, 0, pdu);
1463 g_assert(sms_decode(pdu, pdu_len, FALSE, 24, &sr3) == TRUE);
1465 if (g_test_verbose()) {
1466 g_print("sr1 address: %s, mr: %d\n",
1467 sms_address_to_string(&sr1.status_report.raddr),
1468 sr1.status_report.mr);
1470 g_print("sr2 address: %s, mr: %d\n",
1471 sms_address_to_string(&sr2.status_report.raddr),
1472 sr2.status_report.mr);
1474 g_print("sr3 address: %s, mr: %d\n",
1475 sms_address_to_string(&sr3.status_report.raddr),
1476 sr3.status_report.mr);
1479 sms_address_from_string(&addr, "+4915259911630");
1481 sra = status_report_assembly_new(NULL);
1483 status_report_assembly_add_fragment(sra, sha1, &addr, 4, time(NULL), 2);
1484 status_report_assembly_add_fragment(sra, sha1, &addr, 5, time(NULL), 2);
1486 status_report_assembly_expire(sra, time(NULL) + 40);
1487 g_assert(g_hash_table_size(sra->assembly_table) == 0);
1489 status_report_assembly_add_fragment(sra, sha1, &addr, 4, time(NULL), 2);
1490 status_report_assembly_add_fragment(sra, sha1, &addr, 5, time(NULL), 2);
1492 g_assert(!status_report_assembly_report(sra, &sr1, id, &delivered));
1493 g_assert(status_report_assembly_report(sra, &sr2, id, &delivered));
1495 g_assert(memcmp(id, sha1, SMS_MSGID_LEN) == 0);
1496 g_assert(delivered == TRUE);
1499 * Send sms-message in the national address-format,
1500 * but receive in the international address-format.
1502 sms_address_from_string(&addr, "9911630");
1503 status_report_assembly_add_fragment(sra, sha1, &addr, 4, time(NULL), 2);
1504 status_report_assembly_add_fragment(sra, sha1, &addr, 5, time(NULL), 2);
1506 g_assert(!status_report_assembly_report(sra, &sr1, id, &delivered));
1507 g_assert(status_report_assembly_report(sra, &sr2, id, &delivered));
1509 g_assert(memcmp(id, sha1, SMS_MSGID_LEN) == 0);
1510 g_assert(delivered == TRUE);
1511 g_assert(g_hash_table_size(sra->assembly_table) == 0);
1514 * Send sms-message in the international address-format,
1515 * but receive in the national address-format.
1517 sms_address_from_string(&addr, "+358123456789");
1518 status_report_assembly_add_fragment(sra, sha1, &addr, 6, time(NULL), 1);
1520 g_assert(status_report_assembly_report(sra, &sr3, id, &delivered));
1522 g_assert(memcmp(id, sha1, SMS_MSGID_LEN) == 0);
1523 g_assert(delivered == TRUE);
1524 g_assert(g_hash_table_size(sra->assembly_table) == 0);
1526 status_report_assembly_free(sra);
1529 struct wap_push_data {
1534 static struct wap_push_data wap_push_1 = {
1535 .pdu = "0791947122725014440185F039F501801140311480720605040B8423F00106"
1536 "246170706C69636174696F6E2F766E642E7761702E6D6D732D6D657373616"
1537 "76500AF84B4868C82984F67514B4B42008D9089088045726F74696B009650"
1538 "696E2D557073008A808E0240008805810303F48083687474703A2F2F65707"
1539 "3332E64652F4F2F5A39495A4F00",
1543 static void test_wap_push(gconstpointer data)
1545 const struct wap_push_data *test = data;
1547 unsigned char *decoded_pdu;
1552 enum sms_charset charset;
1554 unsigned char *wap_push;
1555 int dst_port, src_port;
1558 decoded_pdu = decode_hex(test->pdu, -1, &pdu_len, 0);
1560 g_assert(decoded_pdu);
1562 ret = sms_decode(decoded_pdu, pdu_len, FALSE, test->len, &sms);
1564 g_free(decoded_pdu);
1567 g_assert(sms.type == SMS_TYPE_DELIVER);
1569 if (g_test_verbose())
1572 ret = sms_dcs_decode(sms.deliver.dcs, &cls, &charset, NULL, NULL);
1574 g_assert(ret == TRUE);
1575 g_assert(charset == SMS_CHARSET_8BIT);
1577 g_assert(sms_extract_app_port(&sms, &dst_port, &src_port, &is_8bit));
1579 if (g_test_verbose()) {
1580 g_print("8bit: %d\n", is_8bit);
1581 g_print("src: %d, dst: %d\n", src_port, dst_port);
1584 g_assert(is_8bit == FALSE);
1585 g_assert(dst_port == 2948);
1587 list = g_slist_append(NULL, &sms);
1589 wap_push = sms_decode_datagram(list, &data_len);
1591 if (g_test_verbose()) {
1594 g_print("data_len: %ld\n", data_len);
1596 for (i = 0; i < data_len; i++) {
1597 g_print("%02x", wap_push[i]);
1612 int main(int argc, char **argv)
1614 char long_string[152*33 + 1];
1615 struct sms_concat_data long_string_test;
1617 g_test_init(&argc, &argv, NULL);
1619 g_test_add_func("/testsms/Test Simple Deliver", test_simple_deliver);
1620 g_test_add_func("/testsms/Test Alnum Deliver", test_alnum_sender);
1621 g_test_add_func("/testsms/Test Deliver Encode", test_deliver_encode);
1622 g_test_add_func("/testsms/Test Simple Submit", test_simple_submit);
1623 g_test_add_func("/testsms/Test Submit Encode", test_submit_encode);
1625 g_test_add_data_func("/testsms/Test "
1626 "GSM 7 bit Default Alphabet Decode",
1627 &sms_charset_default, test_sms_charset);
1629 g_test_add_data_func("/testsms/Test "
1630 "GSM 7 bit Default Alphabet Extension Table Decode",
1631 &sms_charset_default_ext, test_sms_charset);
1633 g_test_add_data_func("/testsms/Test "
1634 "Turkish National Language Locking Shift Table Decode",
1635 &sms_charset_turkey, test_sms_charset);
1637 g_test_add_data_func("/testsms/Test "
1638 "Turkish National Language Single Shift Table Decode",
1639 &sms_charset_turkey_ext, test_sms_charset);
1641 g_test_add_data_func("/testsms/Test "
1642 "Portuguese National Language Locking Shift Table Decode",
1643 &sms_charset_portugal, test_sms_charset);
1645 g_test_add_data_func("/testsms/Test "
1646 "Portuguese National Language Single Shift Table Decode",
1647 &sms_charset_portugal_ext, test_sms_charset);
1649 g_test_add_data_func("/testsms/Test "
1650 "Spanish National Language Single Shift Table Decode",
1651 &sms_charset_spain, test_sms_charset);
1653 g_test_add_data_func("/testsms/Test EMS UDH 1",
1654 &ems_udh_test_1, test_ems_udh);
1655 g_test_add_data_func("/testsms/Test EMS UDH 2",
1656 &ems_udh_test_2, test_ems_udh);
1658 g_test_add_func("/testsms/Test Assembly", test_assembly);
1659 g_test_add_func("/testsms/Test Prepare 7Bit", test_prepare_7bit);
1661 g_test_add_data_func("/testsms/Test Prepare Concat",
1662 &shakespeare_test, test_prepare_concat);
1664 memset(long_string, 'a', 152*30);
1665 memset(long_string + 152*30, 'b', 152);
1666 memset(long_string + 152*31, 'c', 152);
1667 memset(long_string + 152*32, 'd', 152);
1668 long_string[152*33] = '\0';
1670 long_string_test.str = long_string;
1671 long_string_test.segments = 33;
1673 g_test_add_data_func("/testsms/Test Prepare Concat 30+ segments",
1674 &long_string_test, test_prepare_concat);
1676 g_test_add_func("/testsms/Test Prepare Limits", test_prepare_limits);
1678 g_test_add_func("/testsms/Test CBS Encode / Decode",
1679 test_cbs_encode_decode);
1680 g_test_add_func("/testsms/Test CBS Assembly", test_cbs_assembly);
1682 g_test_add_func("/testsms/Range minimizer", test_range_minimizer);
1684 g_test_add_func("/testsms/Status Report Assembly", test_sr_assembly);
1686 g_test_add_data_func("/testsms/Test WAP Push 1", &wap_push_1,
1689 return g_test_run();