18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Copyright (C) 2007-2008 The Android Open Source Project 28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** 38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This software is licensed under the terms of the GNU General Public 48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** License version 2, as published by the Free Software Foundation, and 58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** may be copied, distributed, and modified under those terms. 68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** 78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This program is distributed in the hope that it will be useful, 88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** but WITHOUT ANY WARRANTY; without even the implied warranty of 98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** GNU General Public License for more details. 118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/ 128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "sms.h" 138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "gsm.h" 148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <memory.h> 158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdlib.h> 167891dd35fa2439a70f43ab8572778a398365bf24David 'Digit' Turner#include <string.h> 178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <assert.h> 188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DEBUG 1 208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 1 228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# include "android/utils/debug.h" 238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define D_ACTIVE VERBOSE_CHECK(modem) 248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define D_ACTIVE DEBUG 268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if DEBUG 298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define D(...) VERBOSE_PRINT(modem,__VA_ARGS__) 308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define D(...) ((void)0) 328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* maximum number of data bytes in a SMS data message */ 358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define MAX_USER_DATA_BYTES 140 368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* maximum number of 7-bit septets in a SMS text message */ 388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define MAX_USER_DATA_SEPTETS 160 398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* size of the user data header in bytes */ 418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define USER_DATA_HEADER_SIZE 6 428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/** MESSAGE TEXT 448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project **/ 458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsms_utf8_from_message_str( const char* str, int strlen, unsigned char* utf8, int utf8len ) 478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t p = (cbytes_t)str; 498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t end = p + strlen; 508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int count = 0; 518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int escaped = 0; 528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (p < end) 548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int c = p[0]; 568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* read the value from the string */ 588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p += 1; 598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (c >= 128) { 608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((c & 0xe0) == 0xc0) 618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project c &= 0x1f; 628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else if ((c & 0xf0) == 0xe0) 638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project c &= 0x0f; 648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project c &= 0x07; 668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p++; 678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (p < end && (p[0] & 0xc0) == 0x80) { 688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project c = (c << 6) | (p[0] & 0x3f); 698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p++; 708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (escaped) { 738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (c) { 748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case '\\': 758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 'n': /* \n is line feed */ 778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project c = 10; 788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 'x': /* \xNN, where NN is a 2-digit hexadecimal value */ 818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (p+2 > end) 828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project c = gsm_hex2_to_byte( (const char*)p ); 848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (c < 0) 858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p += 2; 878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 'u': /* \uNNNN where NNNN is a 4-digiti hexadecimal value */ 908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (p + 4 > end) 918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project c = gsm_hex4_to_short( (const char*)p ); 938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (c < 0) 948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p += 4; 968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: /* invalid escape, return -1 */ 998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project escaped = 0; 1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else if (c == '\\') 1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project escaped = 1; 1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project continue; 1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* now, try to write it to the destination */ 1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (c < 128) { 1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (count < utf8len) 1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project utf8[count] = (byte_t) c; 1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project count += 1; 1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else if (c < 0x800) { 1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (count < utf8len) 1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project utf8[count] = (byte_t)(0xc0 | ((c >> 6) & 0x1f)); 1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (count+1 < utf8len) 1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project utf8[count+1] = (byte_t)(0x80 | (c & 0x3f)); 1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project count += 2; 1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else { 1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (count < utf8len) 1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project utf8[count] = (byte_t)(0xc0 | ((c >> 12) & 0xf)); 1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (count+1 < utf8len) 1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project utf8[count+1] = (byte_t)(0x80 | ((c >> 6) & 0x3f)); 1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (count+2 < utf8len) 1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project utf8[count+2] = (byte_t)(0x80 | (c & 0x3f)); 1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project count += 3; 1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (escaped) /* bad final escape */ 1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return count; 1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* to convert utf-8 to a message string, we only need to deal with control characters 1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * and that's it */ 1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint sms_utf8_to_message_str( const unsigned char* utf8, int utf8len, char* str, int strlen ) 1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t p = utf8; 1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t end = p + utf8len; 1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int count = 0; 1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (p < end) 1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int c = p[0]; 1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int escape = 0; 1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* read the value from the string */ 1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p += 1; 1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (c >= 128) { 1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((c & 0xe0) == 0xc0) 1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project c &= 0x1f; 1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else if ((c & 0xf0) == 0xe0) 1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project c &= 0x0f; 1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project c &= 0x07; 1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p++; 1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (p < end && (p[0] & 0xc0) == 0x80) { 1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project c = (c << 6) | (p[0] & 0x3f); 1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p++; 1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (c < ' ') { 1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project escape = 1; 1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (c == '\n') { 1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project c = 'n'; 1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project escape = 2; 1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else if (c == '\\') 1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project escape = 2; 1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (escape) { 1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: 1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (c < 128) { 1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (count < strlen) 1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project str[count] = (char) c; 1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project count += 1; 1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else if (c < 0x800) { 1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (count < strlen) 1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project str[count] = (byte_t)(0xc0 | ((c >> 6) & 0x1f)); 1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (count+1 < strlen) 1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project str[count+1] = (byte_t)(0x80 | (c & 0x3f)); 1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project count += 2; 1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else { 1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (count < strlen) 1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project str[count] = (byte_t)(0xc0 | ((c >> 12) & 0xf)); 1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (count+1 < strlen) 1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project str[count+1] = (byte_t)(0x80 | ((c >> 6) & 0x3f)); 1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (count+2 < strlen) 1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project str[count+2] = (byte_t)(0x80 | (c & 0x3f)); 1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project count += 3; 2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: 2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (count+3 < strlen) { 2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project str[count+0] = '\\'; 2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project str[count+1] = 'x'; 2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gsm_hex_from_byte(str + count + 2, c); 2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project count += 4; 2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (count+2 < strlen) { 2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project str[count+0] = '\\'; 2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project str[count+1] = (char) c; 2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project count += 2; 2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return count; 2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/** TIMESTAMPS 2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project **/ 2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsms_timestamp_now( SmsTimeStamp stamp ) 2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project time_t now_time = time(NULL); 2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct tm gm = *(gmtime(&now_time)); 2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct tm local = *(localtime(&now_time)); 2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int tzdiff = 0; 2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project stamp->data[0] = gsm_int_to_bcdi( local.tm_year % 100 ); 2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project stamp->data[1] = gsm_int_to_bcdi( local.tm_mon+1 ); 2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project stamp->data[2] = gsm_int_to_bcdi( local.tm_mday ); 2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project stamp->data[3] = gsm_int_to_bcdi( local.tm_hour ); 2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project stamp->data[4] = gsm_int_to_bcdi( local.tm_min ); 2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project stamp->data[5] = gsm_int_to_bcdi( local.tm_sec ); 2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tzdiff = (local.tm_hour*4 + local.tm_min/15) - (gm.tm_hour*4 + gm.tm_min/15); 2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (local.tm_yday > gm.tm_yday) 2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tzdiff += 24*4; 2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else if (local.tm_yday < gm.tm_yday) 2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tzdiff -= 24*4; 2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project stamp->data[6] = gsm_int_to_bcdi( tzdiff >= 0 ? tzdiff : -tzdiff ); 2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tzdiff < 0) 2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project stamp->data[6] |= 0x08; 2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsms_timestamp_to_tm( SmsTimeStamp stamp, struct tm* tm ) 2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int tzdiff; 2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tm->tm_year = gsm_int_from_bcdi( stamp->data[0] ); 2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tm->tm_year < 50) 2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tm->tm_year += 100; 2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tm->tm_mon = gsm_int_from_bcdi( stamp->data[1] ) -1; 2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tm->tm_mday = gsm_int_from_bcdi( stamp->data[2] ); 2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tm->tm_hour = gsm_int_from_bcdi( stamp->data[3] ); 2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tm->tm_min = gsm_int_from_bcdi( stamp->data[4] ); 2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tm->tm_sec = gsm_int_from_bcdi( stamp->data[5] ); 2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tm->tm_isdst = -1; 2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tzdiff = gsm_int_from_bcdi( stamp->data[6] & 0xf7 ); 2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (stamp->data[6] & 0x8) 2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tzdiff = -tzdiff; 2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return tzdiff; 2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectgsm_rope_add_timestamp( GsmRope rope, const SmsTimeStampRec* ts ) 2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gsm_rope_add( rope, ts->data, 7 ); 2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/** SMS ADDRESSES 2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project **/ 2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsms_address_from_str( SmsAddress address, const char* src, int srclen ) 2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char* end = src + srclen; 2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int shift = 0, len = 0; 2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bytes_t data = address->data; 2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project address->len = 0; 2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project address->toa = 0x81; 2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (src >= end) 2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ( src[0] == '+' ) { 2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project address->toa = 0x91; 3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (++src == end) 3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Fail; 3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memset( address->data, 0, sizeof(address->data) ); 3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project shift = 0; 3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (src < end) { 3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int c = *src++ - '0'; 3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ( (unsigned)c >= 10 || 3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project data >= address->data + sizeof(address->data) ) 3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Fail; 3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project data[0] |= c << shift; 3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len += 1; 3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project shift += 4; 3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (shift == 8) { 3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project shift = 0; 3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project data += 1; 3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (shift != 0) 3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project data[0] |= 0xf0; 3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project address->len = len; 3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectFail: 3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsms_address_to_str( SmsAddress address, char* str, int strlen ) 3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project static const char dialdigits[16] = "0123456789*#,N%"; 3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int n, count = 0; 3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (address->toa == 0x91) { 3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (count < strlen) 3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project str[count] = '+'; 3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project count++; 3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (n = 0; n < address->len; n += 2) 3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int c = address->data[n/2]; 3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (count < strlen) 3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project str[count] = dialdigits[c & 0xf]; 3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project count += 1; 3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (n+1 > address->len) 3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (count < strlen) 3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project str[count] = dialdigits[(c >> 4) & 0xf]; 357a1b379c65f787fc85bd9c6f4a6d14d8a2bebc9d5Marc Petit-Huguenin if (str[count]) 358a1b379c65f787fc85bd9c6f4a6d14d8a2bebc9d5Marc Petit-Huguenin count += 1; 3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return count; 3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsms_address_from_bytes( SmsAddress address, const unsigned char* buf, int buflen ) 3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int len = sizeof(address->data), num_digits; 3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (buflen < 2) 3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project address->len = num_digits = buf[0]; 3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project address->toa = buf[1]; 3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = (num_digits+1)/2; 3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ( len > sizeof(address->data) ) 3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy( address->data, buf+2, len ); 3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsms_address_to_bytes( SmsAddress address, unsigned char* buf, int bufsize ) 3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int len = (address->len + 1)/2 + 2; 3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (buf == NULL) 3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bufsize = 0; 3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bufsize < 1) goto Exit; 3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[0] = address->len; 3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bufsize < 2) goto Exit; 3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[1] = address->toa; 3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf += 2; 3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bufsize -= 2; 3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bufsize > len-2) 3998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bufsize = len - 2; 4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy( buf, address->data, bufsize ); 4028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectExit: 4038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return len; 4048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 4078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsms_address_from_hex ( SmsAddress address, const char* hex, int hexlen ) 4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char* hexend = hex + hexlen; 4108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int nn, len, num_digits; 4118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (hexlen < 4) 4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project address->len = num_digits = gsm_hex2_to_byte( hex ); 4168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project address->toa = gsm_hex2_to_byte( hex+2 ); 4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hex += 4; 4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = (num_digits + 1)/2; 4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (hex + len*2 > hexend) 4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for ( nn = 0; nn < len; nn++ ) 4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project address->data[nn] = gsm_hex2_to_byte( hex + nn*2 ); 4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsms_address_to_hex ( SmsAddress address, char* hex, int hexlen ) 4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int len = (address->len + 1)/2 + 2; 4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int nn; 4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (hex == NULL) 4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hexlen = 0; 4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (hexlen < 2) goto Exit; 4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gsm_hex_from_byte( hex, address->len ); 4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (hexlen < 4) goto Exit; 4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gsm_hex_from_byte( hex+2, address->toa ); 4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hex += 4; 4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hexlen -= 4; 4448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ( hexlen > 2*(len - 2) ) 4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hexlen = (len - 2)/2; 4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for ( nn = 0; nn < hexlen; nn += 2 ) 4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gsm_hex_from_byte( hex+nn, address->data[nn/2] ); 4498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectExit: 4518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return len*2; 4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 4558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectgsm_rope_add_address( GsmRope rope, const SmsAddressRec* addr ) 4568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gsm_rope_add_c( rope, addr->len ); 4588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gsm_rope_add_c( rope, addr->toa ); 4598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gsm_rope_add( rope, addr->data, (addr->len+1)/2 ); 4608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (addr->len & 1) { 4618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!rope->error && rope->data != NULL) 4628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project rope->data[ rope->pos-1 ] |= 0xf0; 4638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int 4678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsms_address_eq( const SmsAddressRec* addr1, const SmsAddressRec* addr2 ) 4688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ( addr1->toa != addr2->toa || 4708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project addr1->len != addr2->len ) 4718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 4728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ( !memcmp( addr1->data, addr2->data, addr1->len ) ); 4748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/** SMS PARSER 4778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project **/ 4788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int 4798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsms_get_byte( cbytes_t *pcur, cbytes_t end ) 4808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t cur = *pcur; 4828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int result = -1; 4838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (cur < end) { 4858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project result = cur[0]; 4868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *pcur = cur + 1; 4878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return result; 4898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* parse a service center address, returns -1 in case of error */ 4928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int 4938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsms_get_sc_address( cbytes_t *pcur, 4948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t end, 4958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SmsAddress address ) 4968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t cur = *pcur; 4988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int result = -1; 4998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (cur < end) { 5018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int len = cur[0]; 5028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int dlen, adjust = 0; 5038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cur += 1; 5058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (len == 0) { /* empty address */ 5078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project address->len = 0; 5088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project address->toa = 0x00; 5098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project result = 0; 5108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Exit; 5118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (cur + len > end) { 5148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Exit; 5158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project address->toa = *cur++; 5188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len -= 1; 5198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project result = 0; 5208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (dlen = 0; dlen < len; dlen+=1) 5228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 5238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int c = cur[dlen]; 5248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int v; 5258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project adjust = 0; 5278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (dlen >= sizeof(address->data)) { 5288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project result = -1; 5298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 5308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project v = (c & 0xf); 5338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (v >= 0xe) 5348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 5358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project adjust = 1; 5378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project address->data[dlen] = (byte_t) c; 5388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project v = (c >> 4) & 0xf; 5408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (v >= 0xe) { 5418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 5428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project address->len = 2*dlen + adjust; 5458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectExit: 5478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!result) 5488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *pcur = cur; 5498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return result; 5518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int 5548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsms_skip_sc_address( cbytes_t *pcur, 5558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t end ) 5568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t cur = *pcur; 5588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int result = -1; 5598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int len; 5608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (cur >= end) 5628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Exit; 5638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = cur[0]; 5658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cur += 1 + len; 5668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (cur > end) 5678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Exit; 5688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *pcur = cur; 5708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project result = 0; 5718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectExit: 5728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return result; 5738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* parse a sender/receiver address, returns -1 in case of error */ 5768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int 5778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsms_get_address( cbytes_t *pcur, 5788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t end, 5798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SmsAddress address ) 5808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t cur = *pcur; 5828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int result = -1; 5838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int len, dlen; 5848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (cur >= end) 5868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Exit; 5878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dlen = *cur++; 5898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (dlen == 0) { 5918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project address->len = 0; 5928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project address->toa = 0; 5938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project result = 0; 5948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Exit; 5958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (cur + 1 + (dlen+1)/2 > end) 5988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Exit; 5998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project address->len = dlen; 6018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project address->toa = *cur++; 6028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = (dlen + 1)/2; 6048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (len > sizeof(address->data)) 6058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Exit; 6068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy( address->data, cur, len ); 6088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cur += len; 6098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project result = 0; 6108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectExit: 6128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!result) 6138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *pcur = cur; 6148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return result; 6168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int 6198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsms_skip_address( cbytes_t *pcur, 6208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t end ) 6218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 6228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t cur = *pcur; 6238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int result = -1; 6248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int dlen; 6258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (cur + 2 > end) 6278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Exit; 6288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dlen = cur[0]; 6308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cur += 2 + (dlen + 1)/2; 6318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (cur > end) 6328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Exit; 6338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project result = 0; 6358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectExit: 6368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return result; 6378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* parse a service center timestamp */ 6408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int 6418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsms_get_timestamp( cbytes_t *pcur, 6428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t end, 6438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SmsTimeStamp ts ) 6448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 6458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t cur = *pcur; 6468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (cur + 7 > end) 6488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 6498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy( ts->data, cur, 7 ); 6518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *pcur = cur + 7; 6528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 6538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int 6568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsms_skip_timestamp( cbytes_t *pcur, 6578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t end ) 6588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 6598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t cur = *pcur; 6608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (cur + 7 > end) 6628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 6638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *pcur = cur + 7; 6658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 6668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int 6708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsms_skip_validity_period( cbytes_t *pcur, 6718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t end, 6728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int mtiByte ) 6738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 6748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t cur = *pcur; 6758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch ((mtiByte >> 3) & 3) { 6778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: /* relative format */ 6788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cur += 1; 6798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 6808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 2: /* enhanced format */ 6828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 3: /* absolute format */ 6838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cur += 7; 6848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (cur > end) 6868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 6878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *pcur = cur; 6898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 6908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/** SMS PDU 6938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project **/ 6948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct SmsPDURec { 6968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bytes_t base; 6978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bytes_t end; 6988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bytes_t tpdu; 6998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} SmsPDURec; 7008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 7028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsmspdu_free( SmsPDU pdu ) 7038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 7048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (pdu) { 7058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project free( pdu->base ); 7068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pdu->base = NULL; 7078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pdu->end = NULL; 7088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pdu->tpdu = NULL; 7098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 7118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectSmsPduType 7138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsmspdu_get_type( SmsPDU pdu ) 7148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 7158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t data = pdu->tpdu; 7168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t end = pdu->end; 7178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int mtiByte = sms_get_byte(&data, end); 7188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (mtiByte & 3) { 7208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: return SMS_PDU_DELIVER; 7218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: return SMS_PDU_SUBMIT; 7228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 2: return SMS_PDU_STATUS_REPORT; 7238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: return SMS_PDU_INVALID; 7248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 7268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 7288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsmspdu_get_sender_address( SmsPDU pdu, SmsAddress address ) 7298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 7308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t data = pdu->tpdu; 7318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t end = pdu->end; 7328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int mtiByte = sms_get_byte(&data, end); 7338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (mtiByte & 3) { 7358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: /* SMS_PDU_DELIVER; */ 7368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return sms_get_sc_address( &data, end, address ); 7378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: return -1; 7398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 7418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 7438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsmspdu_get_sc_timestamp( SmsPDU pdu, SmsTimeStamp ts ) 7448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 7458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t data = pdu->tpdu; 7468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t end = pdu->end; 7478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int mtiByte = sms_get_byte( &data, end ); 7488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (mtiByte & 3) { 7508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: /* SMS_PDU_DELIVER */ 7518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 7528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SmsAddressRec address; 7538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ( sms_get_sc_address( &data, end, &address ) < 0 ) 7558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 7568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project data += 2; /* skip protocol identifer + coding scheme */ 7588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return sms_get_timestamp( &data, end, ts ); 7608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: return -1; 7638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 7658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 7678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsmspdu_get_receiver_address( SmsPDU pdu, SmsAddress address ) 7688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 7698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t data = pdu->tpdu; 7708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t end = pdu->end; 7718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int mtiByte = sms_get_byte( &data, end ); 7728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (mtiByte & 3) { 7748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: /* SMS_PDU_SUBMIT */ 7758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 7768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project data += 1; /* skip message reference */ 7778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return sms_get_address( &data, end, address ); 7788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: return -1; 7818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 7838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef enum { 7858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SMS_CODING_SCHEME_UNKNOWN = 0, 7868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SMS_CODING_SCHEME_GSM7, 7878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SMS_CODING_SCHEME_UCS2 7888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} SmsCodingScheme; 7908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* see TS 23.038 Section 5 for details */ 7928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic SmsCodingScheme 7938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsms_get_coding_scheme( cbytes_t *pcur, 7948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t end ) 7958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 7968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t cur = *pcur; 7978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int dataCoding; 7988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (cur >= end) 8008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return SMS_CODING_SCHEME_UNKNOWN; 8018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dataCoding = *cur++; 8038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *pcur = cur; 8048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (dataCoding >> 4) { 8068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0x00: 8078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0x02: 8088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0x03: 8098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return SMS_CODING_SCHEME_GSM7; 8108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0x01: 8128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (dataCoding == 0x10) return SMS_CODING_SCHEME_GSM7; 8138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (dataCoding == 0x11) return SMS_CODING_SCHEME_UCS2; 8148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 8158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0x04: case 0x05: case 0x06: case 0x07: 8178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (dataCoding & 0x20) return SMS_CODING_SCHEME_UNKNOWN; /* compressed 7-bits */ 8188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (((dataCoding >> 2) & 3) == 0) return SMS_CODING_SCHEME_GSM7; 8198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (((dataCoding >> 2) & 3) == 2) return SMS_CODING_SCHEME_UCS2; 8208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 8218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0xF: 8238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!(dataCoding & 4)) return SMS_CODING_SCHEME_GSM7; 8248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 8258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return SMS_CODING_SCHEME_UNKNOWN; 8278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 8288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* see TS 23.040 section 9.2.3.24 for details */ 8318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int 8328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsms_get_text_utf8( cbytes_t *pcur, 8338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t end, 8348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int hasUDH, 8358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SmsCodingScheme coding, 8368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project GsmRope rope ) 8378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 8388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t cur = *pcur; 8398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int result = -1; 8408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int len; 8418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (cur >= end) 8438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Exit; 8448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = *cur++; 8468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* skip user data header if any */ 8488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ( hasUDH ) 8498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 8508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int hlen; 8518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (cur >= end) 8538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Exit; 8548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hlen = *cur++; 8568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (cur + hlen > end) 8578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Exit; 8588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cur += hlen; 8608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (coding == SMS_CODING_SCHEME_GSM7) 8628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len -= 2*(hlen+1); 8638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 8648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len -= hlen+1; 8658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (len < 0) 8678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Exit; 8688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* switch the user data header if any */ 8718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (coding == SMS_CODING_SCHEME_GSM7) 8728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 8738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int count = utf8_from_gsm7( cur, 0, len, NULL ); 8748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (rope != NULL) 8768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 8778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bytes_t dst = gsm_rope_reserve( rope, count ); 8788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (dst != NULL) 8798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project utf8_from_gsm7( cur, 0, len, dst ); 8808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cur += (len+1)/2; 8828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else if (coding == SMS_CODING_SCHEME_UCS2) 8848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 8858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int count = ucs2_to_utf8( cur, len/2, NULL ); 8868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (rope != NULL) 8888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 8898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bytes_t dst = gsm_rope_reserve( rope, count ); 8908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (dst != NULL) 8918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ucs2_to_utf8( cur, len/2, dst ); 8928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cur += len; 8948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project result = 0; 8968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectExit: 8988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!result) 8998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *pcur = cur; 9008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return result; 9028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 9038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* get the message embedded in a SMS PDU as a utf8 byte array, returns the length of the message in bytes */ 9058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* or -1 in case of error */ 9068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 9078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsmspdu_get_text_message( SmsPDU pdu, unsigned char* utf8, int utf8len ) 9088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 9098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t data = pdu->tpdu; 9108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t end = pdu->end; 9118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int mtiByte = sms_get_byte( &data, end ); 9128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (mtiByte & 3) { 9148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: /* SMS_PDU_DELIVER */ 9158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 9168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SmsAddressRec address; 9178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SmsTimeStampRec timestamp; 9188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SmsCodingScheme coding; 9198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project GsmRopeRec rope[1]; 9208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int result; 9218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ( sms_get_sc_address( &data, end, &address ) < 0 ) 9238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Fail; 9248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project data += 1; /* skip protocol identifier */ 9268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project coding = sms_get_coding_scheme( &data, end ); 9278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (coding == SMS_CODING_SCHEME_UNKNOWN) 9288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Fail; 9298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ( sms_get_timestamp( &data, end, ×tamp ) < 0 ) 9318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Fail; 9328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ( sms_get_text_utf8( &data, end, (mtiByte & 0x40), coding, rope ) < 0 ) 9348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Fail; 9358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project result = rope->pos; 9378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (utf8len > result) 9388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project utf8len = result; 9398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (utf8len > 0) 9418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy( utf8, rope->data, utf8len ); 9428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gsm_rope_done( rope ); 9448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return result; 9458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: /* SMS_PDU_SUBMIT */ 9488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 9498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SmsAddressRec address; 9508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SmsCodingScheme coding; 9518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project GsmRopeRec rope[1]; 9528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int result; 9538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project data += 1; /* message reference */ 9558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ( sms_get_address( &data, end, &address ) < 0 ) 9578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Fail; 9588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project data += 1; /* skip protocol identifier */ 9608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project coding = sms_get_coding_scheme( &data, end ); 9618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (coding == SMS_CODING_SCHEME_UNKNOWN) 9628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Fail; 9638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gsm_rope_init_alloc( rope, 0 ); 9658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ( sms_get_text_utf8( &data, end, (mtiByte & 0x40), coding, rope ) < 0 ) { 9668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gsm_rope_done( rope ); 9678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Fail; 9688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project result = rope->pos; 9718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (utf8len > result) 9728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project utf8len = result; 9738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (utf8len > 0) 9758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy( utf8, rope->data, utf8len ); 9768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gsm_rope_done( rope ); 9788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return result; 9798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectFail: 9828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 9838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 9848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic cbytes_t 9868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsmspdu_get_user_data_ref( SmsPDU pdu ) 9878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 9888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t data = pdu->tpdu; 9898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t end = pdu->end; 9908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int mtiByte = sms_get_byte( &data, end ); 9918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int len; 9928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* if there is no user-data-header, there is no message reference here */ 9948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((mtiByte & 0x40) == 0) 9958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Fail; 9968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (mtiByte & 3) { 9988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: /* SMS_PDU_DELIVER */ 9998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ( sms_skip_address( &data, end ) < 0 ) 10008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Fail; 10018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project data += 2; /* skip protocol identifier + coding scheme */ 10038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ( sms_skip_timestamp( &data, end ) < 0 ) 10058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Fail; 10068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 10088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: /* SMS_PDU_SUBMIT */ 10108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project data += 1; /* skip message reference */ 10118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ( sms_skip_address( &data, end ) < 0 ) 10138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Fail; 10148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project data += 2; /* protocol identifier + oding schene */ 10168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ( sms_skip_validity_period( &data, end, mtiByte ) < 0 ) 10178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Fail; 10188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 10208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 10228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Fail; 10238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* skip user-data length */ 10268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (data+1 >= end) 10278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Fail; 10288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = data[1]; 10308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project data += 2; 10318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (len >= 2 && data + 2 <= end) { 10338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int htype = data[0]; 10348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int hlen = data[1]; 10358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (htype == 00 && hlen == 3 && data + 5 <= end) { 10378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return data + 2; 10388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project data += hlen; 10418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len -= hlen - 2; 10428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectFail: 10448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 10458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 10468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 10488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsmspdu_get_ref( SmsPDU pdu ) 10498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 10508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t user_ref = smspdu_get_user_data_ref( pdu ); 10518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (user_ref != NULL) 10538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 10548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return user_ref[0]; 10558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 10578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 10588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t data = pdu->tpdu; 10598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t end = pdu->end; 10608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int mtiByte = sms_get_byte( &data, end ); 10618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((mtiByte & 3) == 1) { 10638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* try to extract directly the reference for a SMS-SUBMIT */ 10648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (data < end) 10658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return data[0]; 10668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 10698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 10708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 10728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsmspdu_get_max_index( SmsPDU pdu ) 10738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 10748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t user_ref = smspdu_get_user_data_ref( pdu ); 10758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (user_ref != NULL) { 10778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return user_ref[1]; 10788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 10798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 10808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 10828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 10848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsmspdu_get_cur_index( SmsPDU pdu ) 10858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 10868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t user_ref = smspdu_get_user_data_ref( pdu ); 10878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (user_ref != NULL) { 10898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return user_ref[2] - 1; 10908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 10918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 10928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 10948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 10978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectgsm_rope_add_sms_user_header( GsmRope rope, 10988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ref_number, 10998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int pdu_count, 11008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int pdu_index ) 11018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 11028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gsm_rope_add_c( rope, 0x05 ); /* total header length == 5 bytes */ 11038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gsm_rope_add_c( rope, 0x00 ); /* element id: concatenated message reference number */ 11048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gsm_rope_add_c( rope, 0x03 ); /* element len: 3 bytes */ 11058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gsm_rope_add_c( rope, (byte_t)ref_number ); /* reference number */ 11068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gsm_rope_add_c( rope, (byte_t)pdu_count ); /* max pdu index */ 11078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gsm_rope_add_c( rope, (byte_t)pdu_index+1 ); /* current pdu index */ 11088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 11098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* write a SMS-DELIVER PDU into a rope */ 11118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 11128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectgsm_rope_add_sms_deliver_pdu( GsmRope rope, 11138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t utf8, 11148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int utf8len, 11158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int use_gsm7, 11168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const SmsAddressRec* sender_address, 11178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const SmsTimeStampRec* timestamp, 11188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ref_num, 11198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int pdu_count, 11208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int pdu_index) 11218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 11228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int coding; 11238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int mtiByte = 0x20; /* message type - SMS DELIVER */ 11248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (pdu_count > 1) 11268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mtiByte |= 0x40; /* user data header indicator */ 11278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gsm_rope_add_c( rope, 0 ); /* no SC Address */ 11298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gsm_rope_add_c( rope, mtiByte ); /* message type - SMS-DELIVER */ 11308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gsm_rope_add_address( rope, sender_address ); 11318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gsm_rope_add_c( rope, 0 ); /* protocol identifier */ 11328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* data coding scheme - GSM 7 bits / no class - or - 16-bit UCS2 / class 1 */ 11348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project coding = (use_gsm7 ? 0x00 : 0x09); 11358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gsm_rope_add_c( rope, coding ); /* data coding scheme */ 11378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gsm_rope_add_timestamp( rope, timestamp ); /* service center timestamp */ 11388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (use_gsm7) { 11408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bytes_t dst; 11418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int count = utf8_to_gsm7( utf8, utf8len, NULL, 0 ); 11428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int pad = 0; 11438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project assert( count <= MAX_USER_DATA_SEPTETS - USER_DATA_HEADER_SIZE ); 11458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (pdu_count > 1) 11478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 11488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int headerBits = 6*8; /* 6 is size of header in bytes */ 11498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int headerSeptets = headerBits / 7; 11508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (headerBits % 7 > 0) 11518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project headerSeptets += 1; 11528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pad = headerSeptets*7 - headerBits; 11548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gsm_rope_add_c( rope, count + headerSeptets ); 11568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gsm_rope_add_sms_user_header(rope, ref_num, pdu_count, pdu_index); 11578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 11598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gsm_rope_add_c( rope, count ); 11608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project count = (count*7+pad+7)/8; /* convert to byte count */ 11628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dst = gsm_rope_reserve( rope, count ); 11648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (dst != NULL) { 11658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project utf8_to_gsm7( utf8, utf8len, dst, pad ); 11668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 11688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bytes_t dst; 11698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int count = utf8_to_ucs2( utf8, utf8len, NULL ); 11708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project assert( count*2 <= MAX_USER_DATA_BYTES - USER_DATA_HEADER_SIZE ); 11728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (pdu_count > 1) 11748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 11758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gsm_rope_add_c( rope, count*2 + 6 ); 11768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gsm_rope_add_sms_user_header( rope, ref_num, pdu_count, pdu_index ); 11778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 11798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gsm_rope_add_c( rope, count*2 ); 11808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gsm_rope_add_c( rope, count*2 ); 11828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dst = gsm_rope_reserve( rope, count*2 ); 11838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (dst != NULL) { 11848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project utf8_to_ucs2( utf8, utf8len, dst ); 11858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 11888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic SmsPDU 11918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsmspdu_create_deliver( cbytes_t utf8, 11928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int utf8len, 11938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int use_gsm7, 11948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const SmsAddressRec* sender_address, 11958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const SmsTimeStampRec* timestamp, 11968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ref_num, 11978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int pdu_count, 11988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int pdu_index ) 11998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 12008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SmsPDU p; 12018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project GsmRopeRec rope[1]; 12028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int size; 12038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = calloc( sizeof(*p), 1 ); 12058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!p) goto Exit; 12068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gsm_rope_init( rope ); 12088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gsm_rope_add_sms_deliver_pdu( rope, utf8, utf8len, use_gsm7, 12098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sender_address, timestamp, 12108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ref_num, pdu_count, pdu_index); 12118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (rope->error) 12128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Fail; 12138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gsm_rope_init_alloc( rope, rope->pos ); 12158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gsm_rope_add_sms_deliver_pdu( rope, utf8, utf8len, use_gsm7, 12178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sender_address, timestamp, 12188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ref_num, pdu_count, pdu_index ); 12198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p->base = gsm_rope_done_acquire( rope, &size ); 12218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (p->base == NULL) 12228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Fail; 12238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p->end = p->base + size; 12258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p->tpdu = p->base + 1; 12268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectExit: 12278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return p; 12288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectFail: 12308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project free(p); 12318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 12328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 12338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 12368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsmspdu_free_list( SmsPDU* pdus ) 12378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 12388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (pdus) { 12398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int nn; 12408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (nn = 0; pdus[nn] != NULL; nn++) 12418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project smspdu_free( pdus[nn] ); 12428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project free( pdus ); 12448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 12468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectSmsPDU* 12508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsmspdu_create_deliver_utf8( const unsigned char* utf8, 12518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int utf8len, 12528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const SmsAddressRec* sender_address, 12538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const SmsTimeStampRec* timestamp ) 12548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 12558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SmsTimeStampRec ts0; 12568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int use_gsm7; 12578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int count, block; 12588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int num_pdus = 0; 12598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int leftover = 0; 12608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SmsPDU* list = NULL; 12618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project static unsigned char ref_num = 0; 12638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (timestamp == NULL) { 12658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sms_timestamp_now( &ts0 ); 12668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project timestamp = &ts0; 12678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* can we encode the message with the GSM 7-bit alphabet ? */ 12708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project use_gsm7 = utf8_check_gsm7( utf8, utf8len ); 12718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* count the number of SMS PDUs we'll need */ 12738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project block = MAX_USER_DATA_SEPTETS - USER_DATA_HEADER_SIZE; 12748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (use_gsm7) { 12768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project count = utf8_to_gsm7( utf8, utf8len, NULL, 0 ); 12778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 12788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project count = utf8_to_ucs2( utf8, utf8len, NULL ); 12798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project block = MAX_USER_DATA_BYTES - USER_DATA_HEADER_SIZE; 12808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project num_pdus = count / block; 12838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project leftover = count - num_pdus*block; 12848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (leftover > 0) 12858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project num_pdus += 1; 12868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project list = calloc( sizeof(SmsPDU*), num_pdus + 1 ); 12888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (list == NULL) 12898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 12908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* now create each SMS PDU */ 12928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 12938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t src = utf8; 12948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t src_end = utf8 + utf8len; 12958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int nn; 12968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (nn = 0; nn < num_pdus; nn++) 12988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 12998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int skip = block; 13008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t src_next; 13018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (leftover > 0 && nn == num_pdus-1) 13038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skip = leftover; 13048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project src_next = utf8_skip_gsm7( src, src_end, skip ); 13068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project list[nn] = smspdu_create_deliver( src, src_next - src, use_gsm7, sender_address, timestamp, 13088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ref_num, num_pdus, nn ); 13098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (list[nn] == NULL) 13108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Fail; 13118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project src = src_next; 13138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 13148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 13158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ref_num++; 13178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return list; 13188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectFail: 13208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project smspdu_free_list(list); 13218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 13228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 13238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectSmsPDU 13268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsmspdu_create_from_hex( const char* hex, int hexlen ) 13278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 13288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SmsPDU p; 13298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbytes_t data; 13308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = calloc( sizeof(*p), 1 ); 13328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!p) goto Exit; 13338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p->base = malloc( (hexlen+1)/2 ); 13358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (p->base == NULL) { 13368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project free(p); 13378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = NULL; 13388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Exit; 13398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 13408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ( gsm_hex_to_bytes( (cbytes_t)hex, hexlen, p->base ) < 0 ) 13428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Fail; 13438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p->end = p->base + (hexlen+1)/2; 13458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project data = p->base; 13478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ( sms_skip_sc_address( &data, p->end ) < 0 ) 13488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Fail; 13498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p->tpdu = (bytes_t) data; 13518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectExit: 13538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return p; 13548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectFail: 13568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project free(p->base); 13578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project free(p); 13588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 13598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 13608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 13628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsmspdu_to_hex( SmsPDU pdu, char* hex, int hexlen ) 13638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 13648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int result = (pdu->end - pdu->base)*2; 13658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int nn; 13668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (hexlen > result) 13688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hexlen = result; 13698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (nn = 0; nn*2 < hexlen; nn++) { 13718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gsm_hex_from_byte( &hex[nn*2], pdu->base[nn] ); 13728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 13738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return result; 13748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 13758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/** SMS SUBMIT RECEIVER 13788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ** collects one or more SMS-SUBMIT PDUs to generate a single message to deliver 13798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project **/ 13808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct SmsFragmentRec { 13828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct SmsFragmentRec* next; 13838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SmsAddressRec from[1]; 13848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project byte_t ref; 13858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project byte_t max; 13868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project byte_t count; 13878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int index; 13888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SmsPDU* pdus; 13898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} SmsFragmentRec, *SmsFragment; 13918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct SmsReceiverRec { 13948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int last; 13958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SmsFragment fragments; 13968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} SmsReceiverRec; 13988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 14018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsms_fragment_free( SmsFragment frag ) 14028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 14038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int nn; 14048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (nn = 0; nn < frag->max; nn++) { 14068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (frag->pdus[nn] != NULL) { 14078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project smspdu_free( frag->pdus[nn] ); 14088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project frag->pdus[nn] = NULL; 14098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 14108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 14118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project frag->pdus = NULL; 14128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project frag->count = 0; 14138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project frag->max = 0; 14148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project frag->index = 0; 14158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project free( frag ); 14168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 14178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic SmsFragment 14198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsms_fragment_alloc( SmsReceiver rec, const SmsAddressRec* from, int ref, int max ) 14208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 14218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SmsFragment frag = calloc(sizeof(*frag) + max*sizeof(SmsPDU), 1 ); 14228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (frag != NULL) { 14248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project frag->from[0] = from[0]; 14258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project frag->ref = ref; 14268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project frag->max = max; 14278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project frag->pdus = (SmsPDU*)(frag + 1); 14288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project frag->index = ++rec->last; 14298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 14308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return frag; 14318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 14328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectSmsReceiver sms_receiver_create( void ) 14368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 14378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SmsReceiver rec = calloc(sizeof(*rec),1); 14388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return rec; 14398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 14408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 14428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsms_receiver_destroy( SmsReceiver rec ) 14438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 14448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (rec->fragments) { 14458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SmsFragment frag = rec->fragments; 14468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project rec->fragments = frag->next; 14478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sms_fragment_free(frag); 14488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 14498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 14508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic SmsFragment* 14528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsms_receiver_find_p( SmsReceiver rec, const SmsAddressRec* from, int ref ) 14538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 14548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SmsFragment* pnode = &rec->fragments; 14558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SmsFragment node; 14568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (;;) { 14588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project node = *pnode; 14598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (node == NULL) 14608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 14618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (node->ref == ref && sms_address_eq( node->from, from )) 14628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 14638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pnode = &node->next; 14648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 14658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return pnode; 14668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 14678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic SmsFragment* 14698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsms_receiver_find_index_p( SmsReceiver rec, int index ) 14708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 14718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SmsFragment* pnode = &rec->fragments; 14728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SmsFragment node; 14738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (;;) { 14758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project node = *pnode; 14768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (node == NULL) 14778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 14788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (node->index == index) 14798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 14808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pnode = &node->next; 14818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 14828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return pnode; 14838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 14848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 14868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsms_receiver_add_submit_pdu( SmsReceiver rec, SmsPDU submit_pdu ) 14878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 14888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SmsAddressRec from[1]; 14898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ref, max, cur; 14908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SmsFragment* pnode; 14918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SmsFragment frag; 14928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ( smspdu_get_receiver_address( submit_pdu, from ) < 0 ) { 14948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project D( "%s: could not extract receiver address\n", __FUNCTION__ ); 14958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 14968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 14978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ref = smspdu_get_ref( submit_pdu ); 14998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ref < 0) { 15008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project D( "%s: could not extract message reference from pdu\n", __FUNCTION__ ); 15018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 15028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project max = smspdu_get_max_index( submit_pdu ); 15048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (max < 0) { 15058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project D( "%s: invalid max fragment value: %d should be >= 1\n", 15068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project __FUNCTION__, max ); 15078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 15088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pnode = sms_receiver_find_p( rec, from, ref ); 15108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project frag = *pnode; 15118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (frag == NULL) { 15128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project frag = sms_fragment_alloc( rec, from, ref, max ); 15138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (frag == NULL) { 15148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project D("%s: not enough memory to allocate new fragment\n", __FUNCTION__ ); 15158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 15168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (D_ACTIVE) { 15188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char tmp[32]; 15198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int len; 15208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = sms_address_to_str( from, tmp, sizeof(tmp) ); 15228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (len < 0) { 15238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strcpy( tmp, "<unknown>" ); 15248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = strlen(tmp); 15258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project D("%s: created SMS index %d, from %.*s, ref %d, max %d\n", __FUNCTION__, 15278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project frag->index, len, tmp, frag->ref, frag->max); 15288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *pnode = frag; 15308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cur = smspdu_get_cur_index( submit_pdu ); 15338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (cur < 0) { 15348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project D("%s: SMS fragment index is too small: %d should be >= 1\n", __FUNCTION__, cur+1 ); 15358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 15368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (cur >= max) { 15388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project D("%s: SMS fragment index is too large (%d >= %d)\n", __FUNCTION__, cur, max); 15398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 15408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ( frag->pdus[cur] != NULL ) { 15428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project D("%s: receiving duplicate SMS fragment for %d/%d, ref=%d, discarding old one\n", 15438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project __FUNCTION__, cur+1, max, ref); 15448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project smspdu_free( frag->pdus[cur] ); 15458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project frag->count -= 1; 15468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project frag->pdus[cur] = submit_pdu; 15488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project frag->count += 1; 15498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (frag->count >= frag->max) { 15518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* yes, we received all fragments for this SMS */ 15528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project D( "%s: SMS index %d, received all %d fragments\n", __FUNCTION__, frag->index, frag->count ); 15538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return frag->index; 15548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else { 15568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* still waiting for more */ 15578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project D( "%s: SMS index %d, received %d/%d, waiting for %d more\n", __FUNCTION__, 15588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project frag->index, cur+1, max, frag->max - frag->count ); 15598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 15608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 15628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 15658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsms_receiver_get_text_message( SmsReceiver rec, int index, bytes_t utf8, int utf8len ) 15668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 15678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SmsFragment* pnode = sms_receiver_find_index_p( rec, index ); 15688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SmsFragment frag = *pnode; 15698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int nn, total; 15708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (frag == NULL) { 15728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project D( "%s: invalid SMS index %d\n", __FUNCTION__, index ); 15738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 15748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (frag->count != frag->max) { 15768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project D( "%s: SMS index %d still needs %d fragments\n", __FUNCTION__, 15778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project frag->index, frag->max - frag->count ); 15788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 15798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* get the size of all combined text */ 15818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project total = 0; 15828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for ( nn = 0; nn < frag->count; nn++ ) { 15838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int partial; 15848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (utf8 && utf8len > 0) { 15858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project partial = smspdu_get_text_message( frag->pdus[nn], utf8, utf8len ); 15868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project utf8 += partial; 15878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project utf8len -= partial; 15888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 15898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project partial = smspdu_get_text_message( frag->pdus[nn], NULL, 0 ); 15908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project total += partial; 15928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return total; 15948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 15958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 15988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsms_receiver_remove( SmsReceiver rec, int index ) 15998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 16008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SmsFragment* pnode = sms_receiver_find_index_p( rec, index ); 16018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SmsFragment frag = *pnode; 16028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (frag != NULL) { 16038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *pnode = frag->next; 16048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sms_fragment_free(frag); 16058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 16068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 16078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectSmsPDU* 16108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsms_receiver_create_deliver( SmsReceiver rec, int index, const SmsAddressRec* from ) 16118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 16128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SmsPDU* result = NULL; 16138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SmsFragment* pnode = sms_receiver_find_index_p( rec, index ); 16148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SmsFragment frag = *pnode; 16158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SmsTimeStampRec now[1]; 16168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int nn, total; 16178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bytes_t utf8; 16188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int utf8len; 16198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (frag == NULL) { 16218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project D( "%s: invalid SMS index %d\n", __FUNCTION__, index ); 16228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 16238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 16248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (frag->count != frag->max) { 16258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project D( "%s: SMS index %d still needs %d fragments\n", __FUNCTION__, 16268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project frag->index, frag->max - frag->count ); 16278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 16288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 16298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* get the combined text message */ 16318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project utf8len = sms_receiver_get_text_message( rec, index, NULL, 0 ); 16328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (utf8len < 0) 16338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Exit; 16348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project utf8 = malloc( utf8len + 1 ); 16368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (utf8 == NULL) { 16378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project D( "%s: not enough memory to allocate %d bytes\n", 16388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project __FUNCTION__, utf8len+1 ); 16398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Exit; 16408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 16418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project total = 0; 16438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for ( nn = 0; nn < frag->count; nn++ ) { 16448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project total += smspdu_get_text_message( frag->pdus[nn], utf8 + total, utf8len - total ); 16458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 16468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sms_timestamp_now( now ); 16488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project result = smspdu_create_deliver_utf8( utf8, utf8len, from, now ); 16508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project free(utf8); 16528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectExit: 16548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sms_receiver_remove( rec, index ); 16558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return result; 16568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 16578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1658