Changeset 4619
- Timestamp:
- 09/02/08 10:47:21 (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-sms.c
r4260 r4619 289 289 switch (sms->payload.coding_scheme) { 290 290 case ALPHABET_DEFAULT : 291 g_debug ("Decoding 7-bit ASCII message:"); 292 message = g_malloc0 (GSMD_SMS_DATA_MAXLEN); 293 unpacking_7bit_character (&sms->payload, message); 294 break; 291 { 292 gint i; 293 gint l; 294 gchar *gsmdefault; 295 gchar *dest; 296 g_debug ("Decoding GSM 7-bit default alphabet message:"); 297 gsmdefault = g_malloc0 (GSMD_SMS_DATA_MAXLEN + 1); 298 l = unpacking_7bit_character (&sms->payload, gsmdefault); 299 message = g_malloc0 (1 + 3 * l); 300 dest = message; 301 for (i = 0; i < l; i++) { 302 /* Decoding based on the mapping at 303 * http://unicode.org/Public/MAPPINGS/ETSI/GSM0338.TXT 304 */ 305 switch (gsmdefault[i]) { 306 case 0x00: // COMMERCIAL AT 307 *(dest++) = '@'; break; 308 case 0x01: // POUND SIGN 309 *(dest++) = 0xc2; *(dest++) = 0xa3; break; 310 case 0x02: // DOLLAR SIGN 311 *(dest++) = '$'; break; 312 case 0x03: // YEN SIGN 313 *(dest++) = 0xc2; *(dest++) = 0xa5; break; 314 case 0x04: // LATIN SMALL LETTER E WITH GRAVE 315 *(dest++) = 0xc3; *(dest++) = 0xa8; break; 316 case 0x05: // LATIN SMALL LETTER E WITH ACUTE 317 *(dest++) = 0xc3; *(dest++) = 0xa9; break; 318 case 0x06: // LATIN SMALL LETTER U WITH GRAVE 319 *(dest++) = 0xc3; *(dest++) = 0xb9; break; 320 case 0x07: // LATIN SMALL LETTER I WITH GRAVE 321 *(dest++) = 0xc3; *(dest++) = 0xac; break; 322 case 0x08: // LATIN SMALL LETTER O WITH GRAVE 323 *(dest++) = 0xc3; *(dest++) = 0xb2; break; 324 case 0x09: // LATIN SMALL LETTER C WITH CEDILLA 325 *(dest++) = 0xc3; *(dest++) = 0xa7; break; 326 case 0x0b: // LATIN CAPITAL LETTER O WITH STROKE 327 *(dest++) = 0xc3; *(dest++) = 0x98; break; 328 case 0x0c: // LATIN SMALL LETTER O WITH STROKE 329 *(dest++) = 0xc3; *(dest++) = 0xb8; break; 330 case 0x0e: // LATIN CAPITAL LETTER A WITH RING ABOVE 331 *(dest++) = 0xc3; *(dest++) = 0x85; break; 332 case 0x0f: // LATIN SMALL LETTER A WITH RING ABOVE 333 *(dest++) = 0xc3; *(dest++) = 0xa5; break; 334 case 0x10: // GREEK CAPITAL LETTER DELTA 335 *(dest++) = 0xce; *(dest++) = 0x94; break; 336 case 0x11: // LOW LINE 337 *(dest++) = '_'; break; 338 case 0x12: // GREEK CAPITAL LETTER PHI 339 *(dest++) = 0xce; *(dest++) = 0xa6; break; 340 case 0x13: // GREEK CAPITAL LETTER GAMMA 341 *(dest++) = 0xce; *(dest++) = 0x93; break; 342 case 0x14: // GREEK CAPITAL LETTER LAMDA 343 *(dest++) = 0xce; *(dest++) = 0x9b; break; 344 case 0x15: // GREEK CAPITAL LETTER OMEGA 345 *(dest++) = 0xce; *(dest++) = 0xa9; break; 346 case 0x16: // GREEK CAPITAL LETTER PI 347 *(dest++) = 0xce; *(dest++) = 0xa0; break; 348 case 0x17: // GREEK CAPITAL LETTER PSI 349 *(dest++) = 0xce; *(dest++) = 0xa8; break; 350 case 0x18: // GREEK CAPITAL LETTER SIGMA 351 *(dest++) = 0xce; *(dest++) = 0xa3; break; 352 case 0x19: // GREEK CAPITAL LETTER THETA 353 *(dest++) = 0xce; *(dest++) = 0x98; break; 354 case 0x1a: // GREEK CAPITAL LETTER XI 355 *(dest++) = 0xce; *(dest++) = 0x9e; break; 356 case 0x1b: // Escape character 357 switch (gsmdefault[++i]) { 358 case 0x0a: // FORM FEED 359 *(dest++) = 0x0c; break; 360 case 0x14: // CIRCUMFLEX ACCENT 361 *(dest++) = '^'; break; 362 case 0x28: // LEFT CURLY BRACKET 363 *(dest++) = '{'; break; 364 case 0x29: // RIGHT CURLY BRACKET 365 *(dest++) = '}'; break; 366 case 0x2f: // REVERSE SOLIDUS 367 *(dest++) = '\\'; break; 368 case 0x3c: // LEFT SQUARE BRACKET 369 *(dest++) = '['; break; 370 case 0x3d: // TILDE 371 *(dest++) = '~'; break; 372 case 0x3e: // RIGHT SQUARE BRACKET 373 *(dest++) = ']'; break; 374 case 0x40: // VERTICAL LINE 375 *(dest++) = '|'; break; 376 case 0x65: // EURO SIGN 377 *(dest++) = 0xe2; *(dest++) = 0x82; 378 *(dest++) = 0xac; break; 379 default: // NBSP (for compatibility) 380 *(dest++) = 0xc2; *(dest++) = 0xa0; 381 i--; // Do not consume next character 382 } 383 break; 384 case 0x1c: // LATIN CAPITAL LETTER AE 385 *(dest++) = 0xc3; *(dest++) = 0x86; break; 386 case 0x1d: // LATIN SMALL LETTER AE 387 *(dest++) = 0xc3; *(dest++) = 0xa6; break; 388 case 0x1e: // LATIN SMALL LETTER SHARP S 389 *(dest++) = 0xc3; *(dest++) = 0x9f; break; 390 case 0x1f: // LATIN CAPITAL LETTER E WITH ACUTE 391 *(dest++) = 0xc3; *(dest++) = 0x89; break; 392 case 0x24: // CURRENCY SIGN 393 *(dest++) = 0xc2; *(dest++) = 0xa4; break; 394 case 0x40: // INVERTED EXCLAMATION MARK 395 *(dest++) = 0xc2; *(dest++) = 0xa1; break; 396 case 0x5b: // LATIN CAPITAL LETTER A WITH DIAERESIS 397 *(dest++) = 0xc3; *(dest++) = 0x84; break; 398 case 0x5c: // LATIN CAPITAL LETTER O WITH DIAERESIS 399 *(dest++) = 0xc3; *(dest++) = 0x96; break; 400 case 0x5d: // LATIN CAPITAL LETTER N WITH TILDE 401 *(dest++) = 0xc3; *(dest++) = 0x91; break; 402 case 0x5e: // LATIN CAPITAL LETTER U WITH DIAERESIS 403 *(dest++) = 0xc3; *(dest++) = 0x9c; break; 404 case 0x5f: // SECTION SIGN 405 *(dest++) = 0xc2; *(dest++) = 0xa7; break; 406 case 0x60: // INVERTED QUESTION MARK 407 *(dest++) = 0xc2; *(dest++) = 0xbf; break; 408 case 0x7b: // LATIN SMALL LETTER A WITH DIAERESIS 409 *(dest++) = 0xc3; *(dest++) = 0xa4; break; 410 case 0x7c: // LATIN SMALL LETTER O WITH DIAERESIS 411 *(dest++) = 0xc3; *(dest++) = 0xb6; break; 412 case 0x7d: // LATIN SMALL LETTER N WITH TILDE 413 *(dest++) = 0xc3; *(dest++) = 0xb1; break; 414 case 0x7e: // LATIN SMALL LETTER U WITH DIAERESIS 415 *(dest++) = 0xc3; *(dest++) = 0xbc; break; 416 case 0x7f: // LATIN SMALL LETTER A WITH GRAVE 417 *(dest++) = 0xc3; *(dest++) = 0xa0; break; 418 default: // Untranslated 419 *(dest++) = gsmdefault[i]; 420 } 421 } 422 g_free (gsmdefault); 423 break; 424 } 295 425 case ALPHABET_8BIT : 296 426 /* TODO: Verify: Is this encoding just UTF-8? (it is on my Samsung phone) */ … … 745 875 struct lgsm_sms sms; 746 876 gint msg_length, c; 747 gboolean ascii; 877 glong msg16_length; 878 gboolean gsm7bit; 748 879 JanaNote *note; 749 880 gchar *dialcode = NULL; 750 881 gchar *sub_num = NULL; 882 gunichar2 *message16; 751 883 752 884 g_assert (self && number && message); … … 783 915 strcpy (sms.addr, number); 784 916 } 785 786 917 /* Set message */ 787 /* Check if the text is ascii (and pack in 7 bits if so) */ 788 ascii = TRUE; 789 for (c = 0; message[c] != '\0'; c++) { 790 if (((guint8)message[c]) > 0x7F) { 791 ascii = FALSE; 792 break; 793 } 794 } 918 /* Try to encode to the 7-bit default alphabet, fall back to UTF-8 */ 919 message16 = g_utf8_to_utf16 (message, -1, NULL, &msg16_length, NULL); 920 gsm7bit = TRUE; 795 921 796 922 /* TODO: Multi-part messages using UDH */ 797 923 msg_length = strlen (message); 798 if ((ascii && (msg_length > 160)) || (msg_length > 140)) { 924 gchar *smschars = g_malloc0 (162); 925 gint i = 0; 926 for (c = 0; c < msg16_length; c++) { 927 /* See http://unicode.org/Public/MAPPINGS/ETSI/GSM0338.TXT for details */ 928 switch (message16[c]) { 929 case 0x000c: smschars[i++] = 0x1b; smschars[i++] = 0x0a; break; 930 case 0x0024: smschars[i++] = 0x02; break; 931 /* HACK: 0x80 instead of 0x00, avoids string termination */ 932 case 0x0040: smschars[i++] = 0x80; break; 933 case 0x005b: smschars[i++] = 0x1b; smschars[i++] = 0x3c; break; 934 case 0x005c: smschars[i++] = 0x1b; smschars[i++] = 0x2f; break; 935 case 0x005d: smschars[i++] = 0x1b; smschars[i++] = 0x3e; break; 936 case 0x005e: smschars[i++] = 0x1b; smschars[i++] = 0x14; break; 937 case 0x005f: smschars[i++] = 0x11; break; 938 case 0x007b: smschars[i++] = 0x1b; smschars[i++] = 0x28; break; 939 case 0x007c: smschars[i++] = 0x1b; smschars[i++] = 0x40; break; 940 case 0x007d: smschars[i++] = 0x1b; smschars[i++] = 0x29; break; 941 case 0x007e: smschars[i++] = 0x1b; smschars[i++] = 0x3d; break; 942 case 0x00a1: smschars[i++] = 0x40; break; 943 case 0x00a3: smschars[i++] = 0x01; break; 944 case 0x00a4: smschars[i++] = 0x24; break; 945 case 0x00a5: smschars[i++] = 0x03; break; 946 case 0x00a7: smschars[i++] = 0x5f; break; 947 case 0x00bf: smschars[i++] = 0x60; break; 948 case 0x00c4: smschars[i++] = 0x5b; break; 949 case 0x00c5: smschars[i++] = 0x0e; break; 950 case 0x00c6: smschars[i++] = 0x1c; break; 951 case 0x00c9: smschars[i++] = 0x1f; break; 952 case 0x00d1: smschars[i++] = 0x5d; break; 953 case 0x00d6: smschars[i++] = 0x5c; break; 954 case 0x00d8: smschars[i++] = 0x0b; break; 955 case 0x00dc: smschars[i++] = 0x5e; break; 956 case 0x00df: smschars[i++] = 0x1e; break; 957 case 0x00e0: smschars[i++] = 0x7f; break; 958 case 0x00e4: smschars[i++] = 0x7b; break; 959 case 0x00e5: smschars[i++] = 0x0f; break; 960 case 0x00e6: smschars[i++] = 0x1d; break; 961 case 0x00e7: smschars[i++] = 0x09; break; 962 case 0x00e8: smschars[i++] = 0x04; break; 963 case 0x00e9: smschars[i++] = 0x05; break; 964 case 0x00ec: smschars[i++] = 0x07; break; 965 case 0x00f1: smschars[i++] = 0x7d; break; 966 case 0x00f2: smschars[i++] = 0x08; break; 967 case 0x00f6: smschars[i++] = 0x7c; break; 968 case 0x00f8: smschars[i++] = 0x0c; break; 969 case 0x00f9: smschars[i++] = 0x06; break; 970 case 0x00fc: smschars[i++] = 0x7e; break; 971 /* Greek characters have the same mapping as capital Latin characters where 972 * they both have the same form. 973 */ 974 case 0x0391: smschars[i++] = 0x41; break; 975 case 0x0392: smschars[i++] = 0x42; break; 976 case 0x0393: smschars[i++] = 0x13; break; 977 case 0x0394: smschars[i++] = 0x10; break; 978 case 0x0395: smschars[i++] = 0x45; break; 979 case 0x0396: smschars[i++] = 0x5a; break; 980 case 0x0397: smschars[i++] = 0x48; break; 981 case 0x0398: smschars[i++] = 0x19; break; 982 case 0x0399: smschars[i++] = 0x49; break; 983 case 0x039a: smschars[i++] = 0x4b; break; 984 case 0x039b: smschars[i++] = 0x14; break; 985 case 0x039c: smschars[i++] = 0x4d; break; 986 case 0x039d: smschars[i++] = 0x4e; break; 987 case 0x039e: smschars[i++] = 0x1a; break; 988 case 0x039f: smschars[i++] = 0x4f; break; 989 case 0x03a0: smschars[i++] = 0x16; break; 990 case 0x03a1: smschars[i++] = 0x50; break; 991 case 0x03a3: smschars[i++] = 0x18; break; 992 case 0x03a4: smschars[i++] = 0x54; break; 993 case 0x03a5: smschars[i++] = 0x55; break; 994 case 0x03a6: smschars[i++] = 0x12; break; 995 case 0x03a7: smschars[i++] = 0x58; break; 996 case 0x03a8: smschars[i++] = 0x17; break; 997 case 0x03a9: smschars[i++] = 0x15; break; 998 case 0x20ac: smschars[i++] = 0x1b; smschars[i++] = 0x65; break; 999 default: 1000 { 1001 gunichar2 d = message16[c]; 1002 if (d == 0x000a || d == 0x000d || 1003 (d >= 0x0020 && d < 0x005b) || (d >= 0x0061 && d < 0x0080)) 1004 smschars[i++] = (gchar) d; 1005 else 1006 gsm7bit = FALSE; 1007 } 1008 } 1009 if (i > 160 || !gsm7bit) break; 1010 } 1011 if ((i > 160 && gsm7bit) || (msg_length > 140 && !gsm7bit)) { 799 1012 *error = g_error_new (PHONE_KIT_SMS_ERROR, PK_SMS_ERROR_MSG_TOOLONG, 800 1013 "Message too long"); 1014 g_free (smschars); 801 1015 return FALSE; 802 1016 } 803 if (ascii) { 804 packing_7bit_character (message, &sms); 805 } else { 1017 if (gsm7bit) { 1018 packing_7bit_character (smschars, &sms); 1019 } 1020 else { 806 1021 sms.alpha = ALPHABET_8BIT; 807 1022 strcpy ((gchar *)sms.data, message); 808 } 809 sms.length = msg_length; 1023 sms.length = msg_length; 1024 } 1025 g_free (smschars); 810 1026 811 1027 /* Send message */
Note: See TracChangeset
for help on using the changeset viewer.
