移植T106 8bit编码解码,长短信配置代码
Change-Id: I4fc1e1ba6fac4f73233efabe1edad070bdd73cdb
diff --git a/mbtk/include/mbtk/mbtk_pdu_sms.h b/mbtk/include/mbtk/mbtk_pdu_sms.h
index c6416df..bd29b80 100755
--- a/mbtk/include/mbtk/mbtk_pdu_sms.h
+++ b/mbtk/include/mbtk/mbtk_pdu_sms.h
@@ -83,6 +83,350 @@
};
+#define REPLACEMENT_CHAR (UTF32)0x0000FFFD
+#define MAX_UNI_BMP (UTF32)0x0000FFFF
+#define MAX_UNI_UCS2 MAX_UNI_BMP
+#define MAX_UTF16 (UTF32)0x0010FFFF
+#define MAX_UTF32 (UTF32)0x7FFFFFFF
+#define MAX_LEGAL_UTF32 (UTF32)0x0010FFFF
+
+#define MDAPI_TIME_STR_SIZE 22
+#define MDAPI_PHONE_NUMBER_SIZE 32
+#define MDAPI_MAX_PDU_SIZE 512
+#define MAX_CONCATENATED_MSG 32
+#define MAX_7BIT_MSG_LEN 153
+#define MAX_UCS2_MSG_LEN 67
+#define MAX_8BIT_MSG_LEN 268 //134*2
+
+#define SMS_DELIVER 0x00
+#define SMS_DELIVER_REPORT 0x00
+#define SMS_SUBMIT 0x01
+#define SMS_SUBMIT_REPORT 0x01
+#define SMS_STATUS_REPORT 0x02
+#define SMS_STATUS_COMMAND 0x02
+
+
+#define STATUS_SUCCESS 0
+#define STATUS_MEM_EXHAUSTED (-0xC0000)
+#define STATUS_ILLEGAL_UTF8 (-0xC0001)
+#define STATUS_ILLEGAL_UTF16 (-0xC0002)
+#define STATUS_ILLEGAL_UTF32 (-0xC0003)
+#define STATUS_ILLEGAL_UCS2 (-0xC0004)
+#define STATUS_NULL_POINTER (-0x00001)
+
+
+#define SUR_HIGH_START (UTF32)0xD800
+#define SUR_HIGH_END (UTF32)0xDBFF
+#define SUR_LOW_START (UTF32)0xDC00
+#define SUR_LOW_END (UTF32)0xDFFF
+
+
+
+/*
+ * Unix/Linux
+ */
+typedef char kal_int8;
+
+typedef unsigned char kal_uint8;
+
+typedef short kal_int16;
+
+typedef unsigned short kal_uint16;
+
+typedef int kal_int32;
+
+typedef unsigned int kal_uint32;
+
+/**/
+typedef long long kal_int64;
+
+/**/
+typedef unsigned long long kal_uint64;
+
+typedef char kal_char;
+
+
+
+
+enum SMS_VPF_E
+{
+ SMS_VPF_NO_PRESENT = 0x00,
+ SMS_VPF_RESORVED = 0x01,
+ SMS_VPF_RELATIVE = 0x02,
+ SMS_VPF_ABSOLUTE = 0x03,
+ SMS_VPF_INVALID = 0xFF,
+};
+
+
+enum SMS_ADDR_NUM_PLAN
+{
+ SMS_NP_UNKOWN = 0x00,
+ SMS_NP_ISDNTEL = 0x01,
+ SMS_NP_DATA = 0x03,
+ SMS_NP_TELIX = 0x04,
+ SMS_NP_NATIONAL = 0x08,
+ SMS_NP_PRIVATE = 0x09,
+ SMS_NP_RESERVED = 0xFF,
+};
+
+enum SMS_ADDR_TYPE
+{
+ SMS_TON_UNKNOWN = 0,
+ SMS_TON_INTERNATIONAL = 1,
+ SMS_TON_NATIONAL = 2,
+ SMS_TON_NETWORKSPECIFIC = 3,
+ SMS_TON_SUBSCRIBER = 4,
+ SMS_TON_ALPHANUMERIC = 5,
+ SMS_TON_ABBREVIATED = 6,
+ SMS_TON_RESERVED = 7
+};
+
+enum SMS_ADDR_ENCODE_TYPE
+{
+ SMS_ENCODE_SCA = 0,
+ SMS_ENCODE_OADA = 1,
+ SMS_ENCODE_INVALID = 0xFF,
+};
+
+enum MDAPI_RET_e {
+ MDAPI_RET_SUCCESS = 0,
+ MDAPI_RET_ERROR = 1,
+ MDAPI_RET_TIMEOUT = 2,
+ MDAPI_RET_NOT_SUPPORT = 3,
+};
+
+enum MDAPI_SMS_CHARSET_E
+{
+ MDAPI_SMS_CHARSET_GSM_7BIT = 0x00000000,
+ MDAPI_SMS_CHARSET_GSM_8BIT = 0x00000001,
+ MDAPI_SMS_CHARSET_UCS2 = 0x00000002,
+ MDAPI_SMS_CHARSET_INVALID,
+};
+
+enum MDAPI_SMS_POSITION_E
+{
+ MDAPI_SMS_POS_INBOX = 0x00000001,
+ MDAPI_SMS_POS_SENTBOX = 0x00000002,
+ MDAPI_SMS_POS_DRAFBOX = 0x00000003,
+ MDAPI_SMS_POS_OUTBOX = 0x00000004,
+ MDAPI_SMS_POS_INVALID,
+};
+
+/* */
+enum MDAPI_SMS_MSGTYPE_E
+{
+ MDAPI_SMS_NORMAL_MSG = 0x00000000,
+ MDAPI_SMS_MSG_REPORT = 0x00000001,
+ MDAPI_SMS_MMS_ALERT = 0x00000002,
+ MDAPI_SMS_VOICE_MAIL = 0x00000003,
+ MDAPI_SMS_MSGTYPE_INVALID,
+};
+
+typedef struct _mdapi_sms_setting {
+ kal_int8 rd; /* reject duplicate */
+ kal_int8 vpf; /* validity peroid format */
+ kal_int8 srr; /* status report request */
+ kal_int8 rp; /* replay path */
+ kal_int32 validity_period; /* validity peroid */
+} mdapi_sms_settings_t;
+
+typedef struct _mdapi_sms_record {
+ kal_int32 msg_id;
+ kal_int32 is_read;
+ kal_int32 position;
+ kal_int32 result;
+ kal_int32 msg_type;
+ kal_int32 sms_class;
+ kal_int32 total_pack;
+ kal_int32 curr_pack;
+ kal_int32 ref_num;
+ kal_int32 msg_location;
+ kal_int16 charset;
+ kal_char time[MDAPI_TIME_STR_SIZE]; /*YYYY-MM-DD HH:MM:SS*/
+ kal_char phone_number[MDAPI_PHONE_NUMBER_SIZE];
+ kal_char *msg_content;
+} mdapi_sms_record_t;
+
+typedef struct _smsbuf {
+ kal_uint8 *curbyte;
+ kal_uint8 *finalbyte;
+ kal_uint8 *septet_start;
+ kal_uint8 curbit;
+ kal_uint8 smsbuf[512];
+} smsbuf_t;
+
+static const kal_int32 UTF16_HALF_SHIFT = 10; /* used for shifting by 10 bits */
+static const UTF32 UTF16_HALF_BASE = 0x0010000UL;
+static const UTF32 UTF16_HALF_MASK = 0x3FFUL;
+
+static const unsigned char utf8_tailing_bytes[256] = {
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
+};
+
+static const UTF32 utf8_offsets[6] = {
+ 0x00000000UL,
+ 0x00003080UL,
+ 0x000E2080UL,
+ 0x03C82080UL,
+ 0xFA082080UL,
+ 0x80282080UL
+};
+
+#define MAX_OUT_SIZE 512
+#define MAX_PDU_SIZE 512
+
+typedef struct latin1_to_gsm_extable {
+ kal_int8 symbol;
+ kal_uint8 value;
+} Latin1_to_Gsm_ExTable;
+
+#define NOP ('_')
+
+static kal_uint8 latin1_to_gsm_table[] =
+{
+ //0x00 -, -, -, -, -, -, -, -,
+ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP,
+ //0x08 -, -, LF, -, -, CR, -, -,
+ NOP, NOP, 10, NOP, NOP, 13, NOP, NOP,
+ //0x10 -, -, -, -, -, -, -, -,
+ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP,
+ //0x18 -, -, -, -, -, -, -, -,
+ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP,
+ //0x20 ' ', '!', '"', '#', -, '%', '&', ''',
+ ' ', '!', '"', '#', 0x2, '%', '&', '\'',
+ //0x28 '(', ')', '*', '+', ',', '-', '.', '/',
+ '(', ')', '*', '+', ',', '-', '.', '/',
+ //0x30 '0', '1', '2', '3', '4', '5', '6', '7',
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ //0x38 '8', '9', ':', ';', '<', '=', '>', '?',
+ '8', '9', ':', ';', '<', '=', '>', '?',
+ //0x40 -, 'A', 'B', 'C', 'D', 'E', 'F', 'G',
+ 0x0, 'A', 'B', 'C', 'D', 'E', 'F', 'G',
+ //0x48 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
+ 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
+ //0x50 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
+ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
+ //0x58 'X', 'Y', 'Z', -, -, -, -, -,
+ 'X', 'Y', 'Z', NOP, NOP, NOP, NOP,0x11,
+ //0x60 -, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
+ NOP, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
+ //0x68 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+ //0x70 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
+ //0x78 'x', 'y', 'z', -, -, -, -, -,
+ 'x', 'y', 'z', NOP, NOP, NOP, NOP, NOP,
+ //0x80 -, -, -, -, -, -, -, -,
+ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP,
+ //0x88 -, -, -, -, -, -, -, -,
+ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP,
+ //0x90 -, -, -, -, -, -, -, -,
+ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP,
+ //0x98 -, -, -, -, -, -, -, -,
+ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP,
+ //0xA0 -, -, -, -, -, -, -, -,
+ NOP, 0x40,NOP, 0x1, 0x24,0x3, NOP,0x5F,
+ //0xA8 -, -, -, -, -, -, -, -,
+ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP,
+ //0xB0 -, -, -, -, -, -, -, -,
+ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP,
+ //0xB8 -, -, -, -, -, -, -, -,
+ NOP, NOP, NOP, NOP, NOP, NOP, NOP,0x60,
+ //0xC0 'A', 'A', 'A', 'A', -, -, -, -,
+ 'A', 'A', 'A', 'A', 0x5B,0xE, 0x1C,0x9,
+ //0xC8 'E', -, 'E', 'E', 'I', 'I', 'I', 'I',
+ 'E',0x1F, 'E', 'E', 'I', 'I', 'I', 'I',
+ //0xD0 -, -, 'O', 'O', 'O', 'O', -, -,
+ NOP,0x5D, 'O', 'O', 'O', 'O',0x5C, NOP,
+ //0xD8 -, 'U', 'U', 'U', -, -, 'Y', -,
+ 0x0B,'U', 'U', 'U',0x5E, 'Y', NOP,0x1E,
+ //0xE0 -, 'a', 'a', 'a', -, -, -, -,
+ 0x7F,'a', 'a', 'a',0x7B, 0xF,0x1D, 0x9,
+ //0xE8 -, -, 'e', 'e', -, 'i', 'i', 'i',
+ 0x4, 0x5, 'e', 'e', 0x7, 'i', 'i', 'i',
+ //0xF0 -, -, -, 'o', 'o', 'o', -, -,
+ NOP,0x7D, 0x8, 'o', 'o', 'o',0x7C, NOP,
+ //0xF8 -, -, 'u', 'u', -, 'y', -, 'y',
+ 0xC, 0x6, 'u', 'u',0x7E, 'y', NOP, 'y'
+};
+
+static Latin1_to_Gsm_ExTable latin1_to_gsm_tableEx[]=
+{
+ {'^', 0x14,},
+ {'{', 0x28,},
+ {'}', 0x29,},
+ {'\\',0x2f,},
+ {'[', 0x3C,},
+ {'~', 0x3d,},
+ {']', 0x3e,},
+ {'|', 0x40,},
+ {0,0x00,},
+};
+
+static const UTF8 first_byte_mark[7] = {
+ 0x00,
+ 0x00,
+ 0xC0,
+ 0xE0,
+ 0xF0,
+ 0xF8,
+ 0xFC
+};
+
+static kal_uint8 gsm_to_latin1_table[] =
+{
+ //0x00 '@', -, '$', -, -, -, -, -,
+ '@', 163, '$', 165, 232, 233, 249, 236,
+ //0x08 -, -, LF, -, -, CR, -, -,
+ 242, 199, 10, 216, 248, 13, 197, 229,
+ //0x10 -, '_', -, -, -, -, -, -,
+ NOP, '_', NOP, NOP, NOP, NOP, NOP, NOP,
+ //0x18 -, -, -, -, -, -, -, -,
+ NOP, NOP, NOP, NOP, 198, 230, 223, 201,
+ //0x20 ' ', '!', '"', '#', '?, '%', '&', ''',
+ ' ', '!', '"', '#', 164, '%', '&', '\'',
+ //0x28 '(', ')', '*', '+', ',', '-', '.', '/',
+ '(', ')', '*', '+', ',', '-', '.', '/',
+ //0x30 '0', '1', '2', '3', '4', '5', '6', '7',
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ //0x38 '8', '9', ':', ';', '<', '=', '>', '?',
+ '8', '9', ':', ';', '<', '=', '>', '?',
+ //0x40 -, 'A', 'B', 'C', 'D', 'E', 'F', 'G',
+ 161, 'A', 'B', 'C', 'D', 'E', 'F', 'G',
+ //0x48 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
+ 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
+ //0x50 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
+ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
+ //0x58 'X', 'Y', 'Z', -, -, -, -, -,
+ 'X', 'Y', 'Z', 196, 214, 209, 220, 167,
+ //0x60 -, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
+ 191, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
+ //0x68 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+ //0x70 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
+ //0x78 'x', 'y', 'z', -, -, -, -, -,
+ 'x', 'y', 'z', 228, 246, 241, 252, 224
+};
+
+int smsPduEncode(const char *smsc, const char *da_num, const char *msg, int charset, char *smsc_pdu, char **pdu);
+
+
// 短信解码
struct SMS_Struct PDUDecoding(const char *data);
diff --git a/mbtk/libmbtk_lib/ril/mbtk_pdu_sms.c b/mbtk/libmbtk_lib/ril/mbtk_pdu_sms.c
index d2be3c7..553c691 100755
--- a/mbtk/libmbtk_lib/ril/mbtk_pdu_sms.c
+++ b/mbtk/libmbtk_lib/ril/mbtk_pdu_sms.c
@@ -5,6 +5,11 @@
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
+#include <sys/timeb.h>
+#include <sys/time.h>
+#include <time.h>
+#include <arpa/inet.h>
+#include <ctype.h>
#include "mbtk_pdu_sms.h"
#include "mbtk_alphabet.h"
#include "mbtk_log.h"
@@ -1090,3 +1095,1519 @@
return result;
}
+
+
+
+
+
+
+
+
+
+
+
+
+int hexChar_To_Int(char c)
+{
+ if (c >= '0' && c <= '9')
+ return (c - '0');
+ if (c >= 'A' && c <= 'F')
+ return (c - 'A' + 10);
+ if (c >= 'a' && c <= 'f')
+ return (c - 'a' + 10);
+
+ return 0;
+}
+
+
+void hexString_To_Bytes(char *in, int inLength, char *out)
+{
+ int i;
+
+ if (in == NULL || out == NULL)
+ {
+ return;
+ }
+
+ for (i = 0 ; i < inLength ; i += 2)
+ {
+ out[i/2] = (char)((hexChar_To_Int(in[i]) << 4)
+ | hexChar_To_Int(in[i+1]));
+ }
+}
+
+/* RFC3629 chapter 4. Syntax of UTF-8 Byte Sequences */
+static kal_int32 is_legal_utf8(const UTF8 *start, kal_int32 len)
+{
+ UTF8 tmp = 0;
+ const UTF8 *ptr = start + len;
+
+ switch (len) {
+ default:
+ return FALSE;
+
+ case 4:
+ tmp = *--ptr;
+ if (tmp < 0x80 || tmp > 0xBF) {
+ return FALSE;
+ }
+
+ case 3:
+ tmp = *--ptr;
+ if (tmp < 0x80 || tmp > 0xBF) {
+ return FALSE;
+ }
+
+ case 2:
+ tmp = *--ptr;
+ if (tmp > 0xBF) {
+ return FALSE;
+ }
+
+ switch (*start) {
+ case 0xE0:
+ if (tmp < 0xA0) {
+ return FALSE;
+ }
+ break;
+
+ case 0xED:
+ if (tmp > 0x9F) {
+ return FALSE;
+ }
+ break;
+
+ case 0xF0:
+ if (tmp < 0x90) {
+ return FALSE;
+ }
+ break;
+
+ case 0xF4:
+ if (tmp > 0x8F) {
+ return FALSE;
+ }
+ break;
+
+ default:
+ if (tmp < 0x80) {
+ return FALSE;
+ }
+ break;
+ }
+
+ case 1:
+ if (*start >= 0x80 && *start < 0xC2) {
+ return FALSE;
+ }
+ }
+
+ if (*start > 0xF4) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+kal_int32 kal_utf16_to_utf8(UTF8 *dest, const UTF16 *src, kal_int32 size)
+{
+ kal_int32 result = STATUS_SUCCESS;
+ const UTF16 *start = src;
+ const UTF16 *end = src;
+ const UTF32 TAIL_MASK = 0xBF;
+ const UTF32 TAIL_MARK = 0x80;
+
+ UTF8 *target = dest;
+
+ if (!src) { return STATUS_NULL_POINTER; }
+ while (*end) {
+ end++;
+ }
+
+ while (start < end) {
+ UTF32 tmp = 0;
+ unsigned long bytes = 0;
+
+ tmp = *start++;
+ //LOGE("tmp = [%X]\n", tmp);
+ /* */
+ if (tmp >= SUR_HIGH_START && tmp <= SUR_HIGH_END) {
+ if (start < end) {
+ UTF32 tmp2 = *start;
+ if (tmp2 >= SUR_LOW_START && tmp2 <= SUR_LOW_END) {
+ tmp = ((tmp - SUR_HIGH_START) << UTF16_HALF_SHIFT)
+ + (tmp2 - SUR_LOW_START) + UTF16_HALF_BASE;
+ start++;
+ } else {
+ result = STATUS_ILLEGAL_UTF16;
+ break;
+ }
+ } else {
+ result = STATUS_MEM_EXHAUSTED;
+ break;
+ }
+ } else if (tmp >= SUR_LOW_START && tmp <= SUR_LOW_END) {
+ result = STATUS_ILLEGAL_UTF16;
+ break;
+ }
+
+ if (tmp < (UTF32)0x80) {
+ bytes = 1;
+ } else if (tmp < (UTF32)0x800) {
+ bytes = 2;
+ } else if (tmp < (UTF32)0x10000) {
+ bytes = 3;
+ } else if (tmp < (UTF32)0x110000) {
+ bytes = 4;
+ } else {
+ result = STATUS_ILLEGAL_UTF16;
+ break;
+ }
+
+ if (target && size > 0) {
+ size -= bytes;
+ if (0 >= size) {
+ break;
+ }
+
+ switch (bytes) {
+ case 4:
+ *(target + 3) = (UTF8)((tmp | TAIL_MARK) & TAIL_MASK);
+ tmp >>= 6;
+ case 3:
+ *(target + 2) = (UTF8)((tmp | TAIL_MARK) & TAIL_MASK);
+ tmp >>= 6;
+ case 2:
+ *(target + 1) = (UTF8)((tmp | TAIL_MARK) & TAIL_MASK);
+ tmp >>= 6;
+ case 1:
+ *target = (UTF8)(tmp | first_byte_mark[bytes]);
+ }
+ target += bytes;
+ }
+ result += bytes;
+ }
+
+ if (target)
+ *target = 0;
+
+ return result;
+}
+
+kal_int32 kal_ext_ascii_to_utf8(UTF8 *dest, const kal_uint8 *src, kal_int32 size)
+{
+ kal_int32 result = STATUS_SUCCESS;
+ const kal_uint8 *start = src, *end = src;
+ const UTF32 TAIL_MASK = 0xBF;
+ const UTF32 TAIL_MARK = 0x80;
+ UTF8 *target = dest;
+
+ if (!src) { return STATUS_NULL_POINTER; }
+ while (*end) {
+ end++;
+ }
+
+ while (start < end) {
+ UTF32 tmp = 0;
+ unsigned long bytes = 0;
+
+ tmp = *start++;
+
+ if (tmp < (UTF32)0x80) {
+ bytes = 1;
+ } else {
+ bytes = 2;
+ }
+
+ if (target && size > 0) {
+ size -= bytes;
+ if (size <= 0) {
+ break;
+ }
+
+ switch (bytes) {
+ case 2:
+ *(target + 1) = (UTF8)((tmp | TAIL_MARK) & TAIL_MASK);
+ tmp >>= 6;
+ case 1:
+ *target = (UTF8)(tmp | first_byte_mark[bytes]);
+ }
+ target += bytes;
+ }
+ result += bytes;
+ }
+
+ if (target) {
+ *target = 0;
+ }
+
+ return result;
+}
+
+kal_int32 kal_utf8_to_utf16(UTF16 *dest,
+ const UTF8 *src,
+ kal_int32 size)
+{
+ kal_int32 result = STATUS_SUCCESS;
+ const UTF8 *start = src;
+ const UTF8 *end = src;
+ UTF16 *target = dest;
+
+ while(*end) {
+ end++;
+ }
+
+ while (start < end) {
+ unsigned long tmp = 0;
+ unsigned int extra_bytes = utf8_tailing_bytes[*start];
+ //UTF8 *next = start + extra_bytes + 1;
+
+ if (target && target >= dest + size) {
+ result = STATUS_MEM_EXHAUSTED;
+ break;
+ }
+
+ if (start + extra_bytes >= end) {
+ result = STATUS_MEM_EXHAUSTED;
+ break;
+ }
+
+ if (!is_legal_utf8(start, extra_bytes + 1)) {
+ result = STATUS_ILLEGAL_UTF8;
+ break;
+ }
+
+ switch (extra_bytes) {
+ case 5:
+ tmp += *start++;
+ tmp <<= 6; /* illegal UTF8 */
+ case 4:
+ tmp += *start++;
+ tmp <<= 6; /* illegal UTF8 */
+ case 3:
+ tmp += *start++;
+ tmp <<= 6;
+ case 2:
+ tmp += *start++;
+ tmp <<= 6;
+ case 1:
+ tmp += *start++;
+ tmp <<= 6;
+ case 0:
+ tmp += *start++;
+ }
+
+ tmp -= utf8_offsets[extra_bytes];
+
+ if (tmp <= MAX_UNI_BMP) {
+ if (tmp >= SUR_HIGH_START && tmp <= SUR_LOW_END) {
+ result = STATUS_ILLEGAL_UTF8;
+ break;
+ } else {
+ if (target) {
+ *target++ = (UTF16)tmp;
+ }
+
+ result++;
+ }
+ } else if (tmp > MAX_UTF16) {
+ result = STATUS_ILLEGAL_UTF8;
+ break;
+ } else {
+ if (target && target + 1 >= dest + size) {
+ result = STATUS_MEM_EXHAUSTED;
+ break;
+ }
+
+ tmp -= UTF16_HALF_BASE;
+
+ if (target) {
+ *target++ = (UTF16)((tmp >> UTF16_HALF_SHIFT) + SUR_HIGH_START);
+ *target++ = (UTF16)((tmp & UTF16_HALF_MASK) + SUR_LOW_START);
+ }
+
+ result += 2;
+ }
+ }
+
+ if (target) {
+ *target = 0;
+ }
+
+ return result;
+}
+
+static kal_int32 _mdapi_sms_set_timestamp(mdapi_sms_record_t *sms)
+{
+ struct tm *p;
+ kal_int32 y = 0;
+
+ struct timeval tv;
+ struct timezone tz;
+
+ gettimeofday (&tv, &tz);
+
+ sms->time[6] = tz.tz_minuteswest;
+
+ p = localtime(&tv.tv_sec);
+ y = 1900 + p->tm_year;
+ sms->time[0] = y % 100;
+ sms->time[1] = 1 + p->tm_mon;
+ sms->time[2] = p->tm_mday;
+ sms->time[3] = p->tm_hour;
+ sms->time[4] = p->tm_min;
+ sms->time[5] = p->tm_sec;
+
+ LOGE("sms time: %d-%02d-%02d %02d:%02d:%02d\n", y, sms->time[1],sms->time[2],sms->time[3],sms->time[4], sms->time[5]);
+ LOGE("timezone = %d\n", sms->time[6]);
+
+ return MDAPI_RET_SUCCESS;
+}
+
+kal_uint8 lookup_latin1_to_gsm_ex_table(kal_int8 character)
+{
+ int i;
+ for( i=0; latin1_to_gsm_tableEx[i].symbol != 0; i++) {
+ if (character == latin1_to_gsm_tableEx[i].symbol)
+ return latin1_to_gsm_tableEx[i].value;
+ }
+ return 255;
+}
+
+
+
+
+void _smsbuf_byte_align(smsbuf_t *buf)
+{
+ if (buf->curbyte > buf->finalbyte) {
+ return;
+ }
+ if (buf->curbit != 0) {
+ buf->curbit = 0;
+ buf->curbyte++;
+ }
+}
+
+void _smsbuf_init(smsbuf_t *buf)
+{
+ buf->curbyte = buf->smsbuf;
+ buf->curbit = 0;
+ memset(buf->smsbuf, 0, sizeof(buf->smsbuf));
+ buf->finalbyte = buf->curbyte + sizeof(buf->smsbuf);
+}
+
+void _smsbuf_set1bit(smsbuf_t *buf, kal_uint8 b)
+{
+ if (buf->curbyte > buf->finalbyte)
+ return;
+
+ if (b != 0)
+ *buf->curbyte |= (1 << buf->curbit);
+
+ buf->curbit++;
+ if (buf->curbit == 8) {
+ buf->curbit = 0;
+ buf->curbyte++;
+ }
+}
+
+void _smsbuf_set_multi_bits(smsbuf_t *buf, kal_uint32 value, kal_uint8 bit_num)
+{
+ kal_int32 i = 0;
+
+ for (i = 0; i < bit_num; i++) {
+ _smsbuf_set1bit(buf, (value & (1 << i)) != 0);
+ }
+}
+
+void _smsbuf_set_octet(smsbuf_t *buf, kal_uint8 c)
+{
+ _smsbuf_byte_align(buf);
+ *(buf->curbyte) = c;
+ buf->curbyte++;
+}
+
+void _smsbuf_septet_align(smsbuf_t *buf)
+{
+ if (buf->curbyte > buf->finalbyte)
+ return;
+ while (((buf->curbyte - buf->septet_start) * 8 + buf->curbit) % 7 != 0)
+ _smsbuf_set1bit(buf, 0);
+}
+
+void _smsbuf_set_septet_start(smsbuf_t *buf)
+{
+ _smsbuf_byte_align(buf);
+ buf->septet_start = buf->curbyte;
+}
+
+void _smsbuf_set_string(smsbuf_t *buf, kal_int8 *str, kal_int32 size)
+{
+ kal_int32 i = 0;
+ _smsbuf_septet_align(buf);
+
+ //LOGE("%s, %s, %d. string is:[%s],size is:[%d]", __FILE__, __FUNCTION__, __LINE__, (char*)str, size);
+ while (*str && size) {
+ /* change the iso8859latin1 charactor to gsm support charactor */
+ //LOGE("%s, %s, %d. character is:[%d]-[0x%x]", __FILE__, __FUNCTION__, __LINE__, (int)*str,*str);
+ kal_uint8 c = lookup_latin1_to_gsm_ex_table(*str);
+ if(c != 255)
+ {
+ //LOGE("extent table!");
+ for (i = 0; i < 7; i++) {
+ _smsbuf_set1bit(buf, ((1 << i) & 0x1b) != 0);
+ }
+ size--;
+ } else {
+ c = latin1_to_gsm_table[(kal_uint8)*str];
+ }
+ //LOGE("%s, %s, %d. character is:[%d]-[0x%x]", __FILE__, __FUNCTION__, __LINE__, (int)c,c);
+ str++;
+ size--;
+ for (i = 0; i < 7; i++) {
+ _smsbuf_set1bit(buf, ((1 << i) & c) != 0);
+ //LOGE(KAL_LOG_INFO, LOG_TAG, "curbit = [%d] curbyte=[%X]", buf->curbit, *buf->curbyte);
+ }
+ //LOGE(KAL_LOG_INFO, LOG_TAG, "size = [%d] c = [%c]", size, c);
+ }
+}
+
+void _smsbuf_set_addr(smsbuf_t *buf, kal_int8 *str)
+{
+ _smsbuf_byte_align(buf);
+
+ while (*str) {
+ kal_uint8 c = *str;
+
+ if (*str == '*') {
+ c = 0xa;
+ } else if (*str == '#') {
+ c = 0xb;
+ } else if (*str == 'p') {
+ c = 0xc;
+ } else if (*str == 'w') {
+ c = 0xd;
+ } else if (*str == '+') {
+ c = 0xe;
+ } else {
+ c = *str - '0';
+ }
+
+ if (buf->curbit == 0) {
+ *buf->curbyte = c;
+ buf->curbit = 4;
+ } else {
+ *buf->curbyte |= (c << 4);
+ buf->curbyte++;
+ buf->curbit = 0;
+ }
+
+ str++;
+ }
+
+ if (buf->curbit == 4) {
+ *buf->curbyte |= 0xF0;
+ buf->curbyte++;
+ buf->curbit = 0;
+ }
+}
+
+
+kal_int32 _smsbuf_hex_string(smsbuf_t *buf, kal_int8 *output, kal_int32 size)
+{
+ kal_int32 len = 0;
+ kal_uint8 *str = buf->smsbuf;
+
+ _smsbuf_byte_align(buf);
+ while (str != buf->curbyte && (size - len) > 3) {
+ len += snprintf(output + len, size - len, "%02X", *str);
+ str++;
+ }
+
+ return len;
+}
+
+kal_int32 _mdapi_sms_get_msg_num(const char *msg, int charset, kal_int32 *msg_num, kal_int32 *msg_len)
+{
+ LOGE("%s, %s, %d, send sms content = [%s]",__FILE__, __FUNCTION__, __LINE__, msg);
+ *msg_num = 0;
+ *msg_len = 0;
+ kal_int32 max_len = 0;
+
+ if (charset == MDAPI_SMS_CHARSET_GSM_7BIT) {
+ *msg_len = strlen(msg);
+
+ //special char
+ kal_int32 extenSize =0;
+ kal_char* point = (kal_char*)msg;
+ kal_int32 size = *msg_len;
+ while (*point && size) {
+ kal_uint8 c = lookup_latin1_to_gsm_ex_table((kal_int8)*point);
+ if(c != 255)
+ extenSize++;
+ point++;
+ size--;
+ }
+ //special char
+ if (*msg_len + extenSize > 160) {
+ *msg_num = (*msg_len + extenSize + MAX_7BIT_MSG_LEN - 1) / MAX_7BIT_MSG_LEN;
+ max_len = MAX_7BIT_MSG_LEN;
+ } else {
+ *msg_num = 1;
+ }
+
+ if (*msg_num > MAX_CONCATENATED_MSG) {
+ LOGE("message is too long. msg_len[%d], msg_num[%d], max_len[%d]", *msg_len, *msg_num, max_len);
+ return MDAPI_RET_ERROR;
+ }
+ LOGE("%s, %s, %d, 7bit msg_len = [%d] ,msg_num=[%d]", __FILE__, __FUNCTION__, __LINE__, *msg_len, *msg_num);
+ } else if (charset == MDAPI_SMS_CHARSET_UCS2) {
+ //UTF16 *dest = NULL;
+ *msg_len = kal_utf8_to_utf16(NULL, (const UTF8 *)msg, 0);
+ if (*msg_len > 70) {
+ *msg_num = (*msg_len + MAX_UCS2_MSG_LEN - 1) / MAX_UCS2_MSG_LEN;
+ max_len = MAX_UCS2_MSG_LEN * 2;
+ } else {
+ *msg_num = 1;
+ }
+
+ if (*msg_num > MAX_CONCATENATED_MSG) {
+ LOGE("message is too long. msg_len[%d], msg_num[%d], max_len[%d]", msg_len, msg_num, max_len);
+ return MDAPI_RET_ERROR;
+ }
+ } else if (charset == MDAPI_SMS_CHARSET_GSM_8BIT) {
+ *msg_len = strlen(msg);
+ if(*msg_len > (140 * 2))
+ {
+ *msg_num = (*msg_len + MAX_8BIT_MSG_LEN - 1) / MAX_8BIT_MSG_LEN;
+ max_len = MAX_8BIT_MSG_LEN;
+
+ if (*msg_num > MAX_CONCATENATED_MSG) {
+ LOGE("message is too long. msg_len[%d], msg_num[%d], max_len[%d]", *msg_len, *msg_num, max_len);
+ return MDAPI_RET_ERROR;
+ }
+ }
+ else {
+ *msg_num = 1;
+ }
+ } else{
+ LOGE("Not support charset");
+ return MDAPI_RET_ERROR;
+ }
+
+ return MDAPI_RET_SUCCESS;
+}
+
+kal_int32 _mdapi_sms_encode_addr(smsbuf_t *buf, kal_int8 *smsc, kal_int32 type)
+{
+ kal_int32 len = strlen(smsc);
+ kal_int8 *str = smsc;
+
+ kal_uint8 addr_plane = SMS_NP_ISDNTEL;
+ kal_uint8 addr_type = SMS_TON_UNKNOWN;
+
+ if (len <= 0) {
+ /* use default sca for sms message */
+ _smsbuf_set_octet(buf, 0);
+ return 1;;
+ }
+
+ if (len > 255) {
+ LOGE("input number is too long. len[%d] smsc[%s] ", len, smsc);
+ return 0;
+ }
+
+ /* check the type of address */
+ while (*str) {
+ if (!isdigit(*str) && *str != '+' && *str != '*'
+ && *str != '#' && *str != 'p' && *str != 'w')
+ addr_type = SMS_TON_ALPHANUMERIC;
+ str++;
+ }
+
+ if (smsc[0] == '+' && addr_type != SMS_TON_ALPHANUMERIC) {
+ addr_type = SMS_TON_INTERNATIONAL;
+ /* */
+ str = &smsc[1];
+ len--;
+ } else {
+ str = smsc;
+ }
+
+ /* set len */
+ if (type == SMS_ENCODE_SCA)
+ _smsbuf_set_octet(buf, len / 2 + len % 2 + 1);
+ else {
+ _smsbuf_set_octet(buf, len);
+ }
+
+ LOGE("%02X, %d ", *(buf->curbyte), buf->curbyte - buf->smsbuf);
+
+ _smsbuf_set_multi_bits(buf, addr_plane, 4);
+ _smsbuf_set_multi_bits(buf, addr_type, 3);
+ _smsbuf_set1bit(buf, 1);
+
+ LOGE("%02X, %d ", *(buf->curbyte), buf->curbyte - buf->smsbuf);
+
+ if (addr_type == SMS_TON_ALPHANUMERIC) {
+ _smsbuf_set_septet_start(buf);
+ _smsbuf_set_string(buf, str, len);
+ } else {
+ _smsbuf_set_addr(buf, str);
+ }
+
+ _smsbuf_byte_align(buf);
+
+ return buf->curbyte - buf->smsbuf;
+}
+
+kal_int32 _mdapi_sms_encode_pdu(mdapi_sms_record_t *sms,
+ kal_int8 *smsc,
+ mdapi_sms_settings_t *settings,
+ kal_char *start,
+ kal_int32 send_size,
+ kal_uint8 *udh,
+ kal_char *output,
+ kal_int32 out_len,
+ kal_int32 *sca_out_len)
+{
+ smsbuf_t smsbuf;
+ kal_int32 udh_len = 0;
+ kal_int32 len = 0;
+ kal_int32 sca_len = 0;
+
+ if (udh) {
+ udh_len = udh[0];
+ } else {
+ udh_len = 0;
+ }
+
+ memset(&smsbuf, 0, sizeof(smsbuf));
+ _smsbuf_init(&smsbuf);
+
+ /* SMSC */
+ sca_len = _mdapi_sms_encode_addr(&smsbuf, smsc, SMS_ENCODE_SCA);
+
+ /* Encode PDU Type */
+ {
+ _smsbuf_byte_align(&smsbuf);
+
+ /* Message Type Indicator */
+ _smsbuf_set_multi_bits(&smsbuf, SMS_SUBMIT, 2);
+ //LOGE(KAL_LOG_INFO, LOG_TAG, "curbit = [%d] curbyte=[%02X]", smsbuf.curbit, *smsbuf.curbyte);
+ /* Reject Duplicate */
+ _smsbuf_set1bit(&smsbuf, 0);
+ //LOGE(KAL_LOG_INFO, LOG_TAG, "curbit = [%d] curbyte=[%02X]", smsbuf.curbit, *smsbuf.curbyte);
+ /* Validity Period Format */
+ _smsbuf_set_multi_bits(&smsbuf, settings->vpf, 2);
+ //LOGE(KAL_LOG_INFO, LOG_TAG, "curbit = [%d] curbyte=[%02X]", smsbuf.curbit, *smsbuf.curbyte);
+
+ /* Status Report Request */
+ if (settings->srr)
+ _smsbuf_set1bit(&smsbuf, 1);
+ else
+ _smsbuf_set1bit(&smsbuf, 0);
+ //LOGE(KAL_LOG_INFO, LOG_TAG, "curbit = [%d] curbyte=[%02X]", smsbuf.curbit, *smsbuf.curbyte);
+
+ /* User Data Header Indicator */
+ if (udh_len)
+ _smsbuf_set1bit(&smsbuf, 1);
+ else
+ _smsbuf_set1bit(&smsbuf, 0);
+
+ //LOGE(KAL_LOG_INFO, LOG_TAG, "curbit = [%d] curbyte=[%02X]", smsbuf.curbit, *smsbuf.curbyte);
+
+ /* Replay Path */
+ _smsbuf_set1bit(&smsbuf, settings->rp);
+
+ //LOGE(KAL_LOG_INFO, LOG_TAG, "curbit = [%d] curbyte=[%02X]", smsbuf.curbit, *smsbuf.curbyte);
+ }
+
+ /* Encode MR */
+ {
+ /* Message Reference Count, Long Message should use this */
+ _smsbuf_set_octet(&smsbuf, 0);
+ }
+
+ /* Encode OA/DA */
+ _mdapi_sms_encode_addr(&smsbuf, sms->phone_number, SMS_ENCODE_OADA);
+
+ /* Encode Protocol Identifier */
+ _smsbuf_set_octet(&smsbuf, 0x00);
+
+ /* Encode DCS */
+ {
+ /* Bit 0,1, Class */
+ _smsbuf_set_multi_bits(&smsbuf, sms->sms_class, 2);
+ /* Bit 2,3, Class */
+ _smsbuf_set_multi_bits(&smsbuf, sms->charset, 2);
+ /* Bit 4 */
+ _smsbuf_set1bit(&smsbuf, 0);
+ /* Bit 5 */
+ /* No text compressed */
+ _smsbuf_set1bit(&smsbuf, 0);
+ /* Bit 6, 7 */
+ _smsbuf_set_multi_bits(&smsbuf, 0, 0);
+ }
+ //_smsbuf_byte_align(&smsbuf);
+
+ /* Validity Period */
+ {
+ if (settings->vpf == SMS_VPF_ABSOLUTE) {
+ // TODO: add absolute validity period
+
+ } else if (settings->vpf == SMS_VPF_RELATIVE) {
+ // TODO: add validity period support
+ kal_uint8 validity_period = 0xAA;
+ _smsbuf_set_octet(&smsbuf, validity_period);
+ }
+ }
+
+ /* User Data Header */
+ {
+ if (udh_len) {
+ kal_int32 i = 0;
+ if (sms->charset == MDAPI_SMS_CHARSET_UCS2) {
+ _smsbuf_set_octet(&smsbuf, 1 + udh_len + send_size);
+ } else if (sms->charset == MDAPI_SMS_CHARSET_GSM_7BIT) {
+ _smsbuf_set_octet(&smsbuf, (((1 + udh_len) * 8 + 6) / 7) + send_size);
+ } else if (sms->charset == MDAPI_SMS_CHARSET_GSM_8BIT) {
+ _smsbuf_set_octet(&smsbuf, 1 + udh_len + send_size/2);
+ }
+
+ /* set the start byte of septet(7bits) align */
+ _smsbuf_set_septet_start(&smsbuf);
+ for (i = 0; i < udh_len + 1; i++) {
+ _smsbuf_set_octet(&smsbuf, udh[i]);
+ }
+ } else {
+ if(sms->charset == MDAPI_SMS_CHARSET_GSM_8BIT)
+ {
+ _smsbuf_set_octet(&smsbuf, send_size/2);
+ }
+ else
+ {
+ _smsbuf_set_octet(&smsbuf, send_size);
+ }
+
+ /* set the start byte of septet(7bits) align */
+ _smsbuf_set_septet_start(&smsbuf);
+ }
+ }
+
+ /* Get the Hex String */
+ len = _smsbuf_hex_string(&smsbuf, output, out_len);
+ LOGE("encoded pdu = (%s), len = (%d) ", output, len);
+
+ /* Set User Data */
+ if (sms->charset == MDAPI_SMS_CHARSET_GSM_7BIT) {
+ //_sms_iso8859latin1_to_gsm(start, gsm, *size + 1);
+ _smsbuf_set_string(&smsbuf, start, send_size);
+ } else if(sms->charset == MDAPI_SMS_CHARSET_GSM_8BIT) {
+ kal_int32 i = 0;
+ char outhex[MAX_PDU_SIZE] = {0};
+ hexString_To_Bytes(start, send_size, outhex);
+ for (i = 0; i < send_size/2; i++) {
+ _smsbuf_set_octet(&smsbuf, outhex[i]);
+ }
+ } else {
+ kal_int32 i = 0;
+ for (i = 0; i < send_size; i += 2) {
+ kal_uint16 tmp = 0;
+ kal_uint8 *ptr = (kal_uint8 *)&tmp;
+
+ *ptr = *(start + i);
+ *(ptr + 1) = *(start + i + 1);
+ tmp = htons(tmp);
+ _smsbuf_set_octet(&smsbuf, *(ptr));
+ _smsbuf_set_octet(&smsbuf, *(ptr + 1));
+ }
+ }
+
+ /* Get the Hex String */
+ len = _smsbuf_hex_string(&smsbuf, output, out_len);
+ *sca_out_len = sca_len * 2;
+ LOGE("start = [%p] size = [%d] encoded pdu = (%s), len = (%d)", start, send_size, output, len);
+
+ return len;
+}
+
+
+
+
+
+int smsPduEncode(const char *smsc, const char *da_num, const char *msg, int charset,
+ char *smsc_pdu, char **pdu)
+{
+ mdapi_sms_record_t record;
+ mdapi_sms_settings_t sms_settings;
+ //kal_int32 status = MDAPI_RET_ERROR;
+ kal_int32 msg_num = 0;
+ kal_int32 msg_len = 0;
+ kal_int32 max_len = 0;
+ kal_char *msg_content = NULL;
+ kal_int32 out_len = 0;
+ kal_int8 output[MAX_PDU_SIZE] = {0};
+ kal_int32 sca_out_len;
+ mdapi_sms_record_t *sms = &record;
+
+ memset(sms, 0, sizeof(mdapi_sms_record_t));
+
+ snprintf(sms->phone_number, sizeof(sms->phone_number), "%s", da_num);
+ sms->msg_content = (kal_char *)msg;
+ sms->charset = charset;
+
+ sms_settings.rd = 1;
+ sms_settings.vpf = SMS_VPF_RELATIVE;
+ sms_settings.srr = 1;
+ sms_settings.rp = 0;
+ sms_settings.validity_period = 0;
+
+ // status = _mdapi_sms_get_msg_num(msg, charset, &msg_num, &msg_len);
+
+ /*if (sms->charset == MDAPI_SMS_CHARSET_GSM_7BIT) {
+ msg_content = sms->msg_content;
+ } else if (sms->charset == MDAPI_SMS_CHARSET_UCS2) {
+ UTF16 *dest = NULL;
+ msg_content = (kal_char *)malloc((msg_len + 1) * sizeof(UTF16));
+ dest = (UTF16 *)msg_content;
+ msg_len = kal_utf8_to_utf16(dest, (const UTF8 *)sms->msg_content, (msg_len + 1) * sizeof(UTF16));
+ if (msg_len <= 0) {
+ free(msg_content);
+ msg_content = NULL;
+ return MDAPI_RET_ERROR;
+ }
+ msg_len *= 2;
+ LOGE("ucs2 msg_len = [%d] ,msg_num=[%d] ", msg_len,msg_num);
+ }else {
+ LOGE("Not support charset");
+ return MDAPI_RET_ERROR;
+ }*/
+ if (sms->charset == MDAPI_SMS_CHARSET_GSM_7BIT) {
+ msg_len = strlen(sms->msg_content);
+
+ //for special char
+ kal_int32 extenTotalSize =0;
+ //kal_int32 i = 0;
+ kal_char* point = sms->msg_content;
+ LOGE("XXX msg len %d \n",msg_len);
+ kal_int32 size = msg_len;
+ while (*point && size) {
+ kal_uint8 c = lookup_latin1_to_gsm_ex_table((kal_int8)*point);
+ if(c != 255){
+ extenTotalSize++;
+ }
+ point++;
+ size--;
+ }
+ //for specail char
+ msg_len += extenTotalSize;
+ LOGE("XXX msg_len %d extenTotalSize %d \n",msg_len,extenTotalSize);
+ if (msg_len > 160) {
+ msg_num = (msg_len + MAX_7BIT_MSG_LEN - 1) / MAX_7BIT_MSG_LEN;
+ max_len = MAX_7BIT_MSG_LEN;
+ } else {
+ msg_num = 1;
+ }
+
+ if (msg_num > MAX_CONCATENATED_MSG) {
+ LOGE("message is too long. msg_len[%d], msg_num[%d]", msg_len, msg_num);
+ return MDAPI_RET_ERROR;
+ }
+ LOGE("7bit msg_len = [%d] ,msg_num=[%d]", msg_len,msg_num);
+ msg_content = sms->msg_content;
+ } else if (sms->charset == MDAPI_SMS_CHARSET_UCS2) {
+ UTF16 *dest = NULL;
+ msg_len = kal_utf8_to_utf16(NULL, (const UTF8 *)sms->msg_content, 0);
+ if (msg_len > 70) {
+ msg_num = (msg_len + MAX_UCS2_MSG_LEN - 1) / MAX_UCS2_MSG_LEN;
+ max_len = MAX_UCS2_MSG_LEN * 2;
+ } else {
+ msg_num = 1;
+ }
+
+ if (msg_num > MAX_CONCATENATED_MSG) {
+ LOGE("message is too long. msg_len[%d], msg_num[%d]", msg_len, msg_num);
+ return MDAPI_RET_ERROR;
+ }
+
+ msg_content = (kal_char *)malloc((msg_len + 1) * sizeof(UTF16));
+ dest = (UTF16 *)msg_content;
+ msg_len = kal_utf8_to_utf16(dest, (const UTF8 *)sms->msg_content, (msg_len + 1) * sizeof(UTF16));
+ if (msg_len <= 0) {
+ free(msg_content);
+ msg_content = NULL;
+ return MDAPI_RET_ERROR;
+ }
+ msg_len *= 2;
+ LOGE("ucs2 msg_len = [%d] ,msg_num=[%d] ", msg_len,msg_num);
+ } else if (sms->charset == MDAPI_SMS_CHARSET_GSM_8BIT) {
+ msg_len = strlen(sms->msg_content);
+ msg_content = sms->msg_content;
+ if (msg_len > (140 * 2)) {
+ msg_num = (msg_len + MAX_8BIT_MSG_LEN - 1) / MAX_8BIT_MSG_LEN;
+ max_len = MAX_8BIT_MSG_LEN;
+ } else {
+ msg_num = 1;
+ }
+
+ if (msg_num > MAX_CONCATENATED_MSG) {
+ LOGE("message is too long. msg_len[%d], msg_num[%d]", msg_len, msg_num);
+ return MDAPI_RET_ERROR;
+ }
+ LOGE("8bit msg_len = [%d] ,msg_num=[%d] ", msg_len,msg_num);
+ }else {
+ LOGE("Not support charset");
+ return MDAPI_RET_ERROR;
+ }
+
+ // set sms record
+ _mdapi_sms_set_timestamp(sms);
+ if (msg_num == 1) {
+ out_len = _mdapi_sms_encode_pdu(sms, (kal_int8 *)smsc, &sms_settings, msg_content, msg_len, NULL, output, sizeof(output), &sca_out_len);
+ memcpy(smsc_pdu, output, sca_out_len);
+ //LOGE("%s, %s, %d, returned encoded smsc_pdu:%s", __FILE__, __FUNCTION__, __LINE__, smsc_pdu);
+ //LOGE("%s, %s, %d, output + sca_out_len:%s, out_len - sca_out_len: %d", __FILE__, __FUNCTION__, __LINE__, output + sca_out_len, out_len - sca_out_len);
+
+ //LOGE("%s, %s, %d, pdu:%s sizeof(pdu[0])=%d", __FILE__, __FUNCTION__, __LINE__, pdu[0], sizeof(pdu[0]));
+
+ memset(pdu[0], 0, MAX_PDU_SIZE);
+ LOGE("%s, %s, %d, pdu:%s", __FILE__, __FUNCTION__, __LINE__, pdu[0]);
+ strncpy(pdu[0], output + sca_out_len, out_len - sca_out_len);
+ LOGE("%s, %s, %d, returned encoded pdu:%s\n, len=%d", __FILE__, __FUNCTION__, __LINE__, pdu[0], strlen(pdu[0]));
+ } else {
+ // send long sms
+ kal_int32 index = 0;
+ kal_int32 offset = 0;
+ static kal_uint8 concat_msgid;
+ concat_msgid += (rand() + 1) % 256;
+ LOGE("start send one long msg, total has %d part msg", msg_num);
+ for (index = 0; index < msg_num; index++) {
+ kal_uint8 udh[] = {5, 0, 3, concat_msgid, msg_num, index + 1};
+ kal_uint32 size = 0;
+ kal_int8 *start = NULL;
+ size = msg_len > max_len ? max_len : msg_len;
+ msg_len -= size;
+ start = msg_content + offset;
+ int exterSize = 0;
+ if (sms->charset == MDAPI_SMS_CHARSET_GSM_7BIT){
+ char* point = start;
+ int calsize = size;
+ while (*point && calsize) {
+ kal_uint8 c = lookup_latin1_to_gsm_ex_table((kal_int8)*point);
+ if(c != 255){
+ exterSize++;
+ calsize--;
+ }
+ point++;
+ calsize--;
+ }
+ }
+ offset = offset + size - exterSize;
+ //calculate offset
+ LOGE(" msg_len %d size %d offset %d exterSize %d", msg_len,size ,offset,exterSize);
+ out_len = _mdapi_sms_encode_pdu(sms, (kal_int8 *)smsc, &sms_settings, start, size, udh, output, sizeof(output), &sca_out_len);
+ memcpy(smsc_pdu, output, sca_out_len);
+ memset(pdu[index], 0, MAX_PDU_SIZE);
+ memcpy(pdu[index], output + sca_out_len, out_len - sca_out_len);
+ }
+ }
+ if (sms->charset == MDAPI_SMS_CHARSET_UCS2) {
+ if(msg_content != NULL)
+ free(msg_content);
+ }
+ return MDAPI_RET_SUCCESS;
+}
+
+
+
+//decode
+static unsigned char
+internal_mdapi_hex2int(char *s) {
+ int ret = 0;
+ int len = 2, i = 0;
+ while (i < len) {
+ if (s[i] == 0) {
+ return -1;
+ } else if (s[i] >= 'a' && s[i] <= 'f') {
+ ret = (s[i] - 'a' + 10) + (ret << 4);
+ } else if (s[i] >= 'A' && s[i] <= 'F') {
+ ret = (s[i] - 'A' + 10) + (ret << 4);
+ } else if (s[i] >= '0' && s[i] <= '9') {
+ ret = (s[i] - '0') + (ret << 4);
+ } else {
+ return -1;
+ }
+ i++;
+ }
+ return ret;
+}
+
+int internal_mdapi_sms_7bit_decode(char * message, char * output, int output_size, int padding_bits, int octect)
+{
+ int i = 0, len = 0;
+ char * ptr = message;
+ int output_len = 0;
+ int cur_val = 0;
+ int val = 0;
+ int last_val = 0;//used to save last 1 octet
+ int offset;
+
+ if( padding_bits < 0||padding_bits > 6 )
+ {
+ return 0;
+ }
+ //Calc how many octets are there
+ len = strlen(message) >> 1;
+
+ for(i = 0; i < len - 1; i++){
+ offset = i % 0x7;
+ //Add padding bit, realign to septets.
+ cur_val = ((internal_mdapi_hex2int(ptr)>>padding_bits)&0xFF)+((internal_mdapi_hex2int(ptr+2)<<(8-padding_bits))&0xFF);
+ val = ((cur_val << offset) & 0x7F)+((last_val >> (8 - offset))&0xFF);
+ last_val = cur_val;
+ //printf("val raw = 0x%X, val = 0x%X\n", val, gsm_to_latin1_table[(kal_uint8)(val & 0xFF)]);
+ output[output_len++] = (char)gsm_to_latin1_table[(kal_uint8)(val & 0xFF)];
+ if (output_len == output_size - 1) {
+ output[output_len] = 0;
+ return output_len;
+ }
+
+ if(offset == 6){
+ val = ((cur_val>>1)&0x7F) ;
+ //printf("val raw = 0x%X, val = 0x%X\n", val, gsm_to_latin1_table[(kal_uint8)(val & 0xFF)]);
+ output[output_len++] = (char)gsm_to_latin1_table[(kal_uint8)(val & 0xFF)];
+ if (output_len == output_size - 1) {
+ output[output_len] = 0;
+ return output_len;
+ }
+ }
+ ptr += 2;
+ }
+
+ /* decode the last octet */
+ cur_val = (internal_mdapi_hex2int(ptr) >> padding_bits) & 0xFF;
+ offset = i % 7;
+ val = ((cur_val << offset) & 0x7F)+((last_val >> (8 - offset))&0xFF);
+ //printf("val raw = 0x%X, val = 0x%X\n", val, gsm_to_latin1_table[(kal_uint8)(val & 0xFF)]);
+ output[output_len++] = (char)gsm_to_latin1_table[(kal_uint8)(val & 0xFF)];
+ if (output_len == output_size - 1) {
+ output[output_len] = 0;
+ return output_len;
+ }
+
+ //printf("output = [%s], output_len = [%d]\n", output, output_len);
+ if(offset == 6){
+ val = ((cur_val >> 1) & 0x7F);
+ //printf("val raw = 0x%X, val = 0x%X\n", val, gsm_to_latin1_table[(kal_uint8)(val & 0xFF)]);
+ if (val || octect) {
+ output[output_len++] = (char)gsm_to_latin1_table[(kal_uint8)(val & 0xFF)];
+ if (output_len == output_size - 1) {
+ output[output_len] = 0;
+ return output_len;
+ }
+ }
+ }
+ output[output_len] = 0;
+
+ return output_len;
+}
+
+
+
+
+
+
+
+int internal_mdapi_address_decode(char *number, char *output, int output_size, int type) {
+ // 81 90 21 43 65 87 --> 0912345678
+ LOGE("%s, %s, %d", __FILE__, __FUNCTION__, __LINE__);
+
+ int len = 0;
+ int output_len = 0;
+ int val = 0;
+ char *ptr = number;
+ int padding_bit = 0;//To identify the number is even or odd
+ //LOGE("before internal_mdapi_hex2int(ptr), ptr :%s",ptr);
+ // Length
+ len = internal_mdapi_hex2int(ptr);
+ //LOGE("after internal_mdapi_hex2int(ptr), ptr :%s",ptr);
+ ptr += 2;
+ //LOGE("after +=2, ptr :%s",ptr);
+
+ if (len == 0) {
+ return 2;
+ } else if (len < 0) {
+ return -1;
+ }
+
+ if (type) {
+ len = (len) << 1;
+ } else {
+ len += 2;
+ }
+
+ LOGE("Address length = %d ", len);
+
+ // Type-of-address
+ val = internal_mdapi_hex2int(ptr);
+ ptr += 2;
+ len -= 2;
+ if (val == 0x91) {
+ // international number
+ output_len += snprintf(output+output_len, output_size-output_len-1, "+");
+ } else if (val == 0x81) {
+ // national number
+ } else if ((val & 0x50) == 0x50 ){
+ // alphabet number
+ } else {
+ LOGE("Invalid type-of-address : %02X " , val);
+ }
+
+ // decode alphabet number
+ if (0x50 == (val & 0x50)) {
+ kal_int32 octect = (((len * 4) / 7 ) % 8 == 0) ? 1 : 0;
+ kal_char * tmp = (kal_char * )malloc(len + 1);
+ if (!tmp) {
+ LOGE("Invalid type-of-address : %02X ", val);
+ return -1;
+ }
+ memcpy(tmp, ptr, len);
+ tmp[len] = 0;
+ output_len += internal_mdapi_sms_7bit_decode(tmp, output, output_size - output_len - 1, 0, octect);
+ free(tmp);
+ tmp = NULL;
+ } else {
+ do {
+ if (len > 1) {
+ if (*ptr == 'F') {
+ output_len += snprintf(output + output_len, output_size - output_len - 1, "%c", *(ptr + 1));
+ } else {
+ output_len += snprintf(output + output_len, output_size - output_len - 1, "%c%c", *(ptr + 1), *(ptr));
+ }
+
+ len -= 2;
+ ptr += 2;
+ } else {
+ output_len += snprintf(output + output_len, output_size - output_len - 1, "%c", *(ptr + 1));
+ len -= 1;
+ ptr += 1;
+ padding_bit = 1;
+ }
+ } while (len > 0);
+ }
+
+ return (ptr-number+padding_bit);
+}
+
+
+static kal_int32 _mdapi_sms_decode_pdu(mdapi_sms_record_t *sms,
+ kal_int8 *smsc,
+ kal_int8 *content,
+ kal_int32 content_size,
+ kal_int32 *record_size,
+ kal_int32 *curr_pack,
+ kal_int32 *total_pack)
+{
+
+
+ kal_int32 ret = 0;
+
+ kal_int8 *ptr = content;
+ kal_int32 udh = 0;
+
+ /*
+ * Service Centre address informaction element
+ */
+ LOGE("%s, %s, %d, ptr_len: %d, ptr: %s\n", __FILE__,__FUNCTION__, __LINE__, content_size, ptr);
+ ret = internal_mdapi_address_decode(ptr, smsc, 512, 1);
+ if (ret <= 0) {
+ LOGE("can't get SMSC address");
+ return MDAPI_RET_ERROR;
+ }
+ ptr += ret;
+ LOGE("SMSC = [%s]\n", smsc);
+
+ /* Protocol Data Unit Type(PDU Type) */
+ {
+ kal_int32 pdu_type = internal_mdapi_hex2int(ptr);
+ if ((pdu_type & 0x03) == SMS_DELIVER) {
+ sms->msg_type = MDAPI_SMS_NORMAL_MSG;
+ } else if ((pdu_type & 0x03) == SMS_STATUS_REPORT){
+ sms->msg_type = MDAPI_SMS_MSG_REPORT;
+ } else {
+ LOGE("unkown PDU type = %02X(%02X), content = %s", pdu_type, pdu_type & 0x03, content);
+ return MDAPI_RET_ERROR;
+ }
+
+ if ((pdu_type & 0x40) == 0x40) {
+ udh = 1; /* find UDH header */
+ }
+
+ LOGE("PDU Type = [%d]\n", pdu_type);
+ }
+ ptr += 2;
+
+ /* decode originator address(OA) destination address(DA)*/
+ ret = internal_mdapi_address_decode(ptr, sms->phone_number, sizeof(sms->phone_number), 0);
+ if (ret <= 0) {
+ LOGE("can't get sender address");
+ return MDAPI_RET_ERROR;
+ }
+ ptr += ret;
+ LOGE("sender = [%s]\n", sms->phone_number);
+
+ /* protocol identifiler(PID) */
+ ptr += 2;
+
+ /* Data Coding Scheme (DCS) */
+ {
+ //kal_int32 text_compressed = 0;
+ kal_int32 dcs = 0;
+
+ dcs = internal_mdapi_hex2int(ptr);
+ if (dcs < 0) {
+ LOGE("can't get the DCS\n");
+ return MDAPI_RET_ERROR;
+ }
+
+ if ( (dcs & 0xC0) == 0x00) {
+ /* General Data Coding indication */
+ if (dcs & 0x20) {
+ //text_compressed = 1;
+ }
+
+ if (dcs & 0x10) {
+ sms->sms_class = dcs & 0xF;
+ }
+
+ if (dcs & 0x04) {
+ sms->charset = MDAPI_SMS_CHARSET_GSM_8BIT;
+
+ } else if (dcs & 0x08) {
+ sms->charset = MDAPI_SMS_CHARSET_UCS2;
+ } else {
+ sms->charset = MDAPI_SMS_CHARSET_GSM_7BIT;
+ }
+ } else {
+ LOGE("un-supported dcs type\n");
+ return MDAPI_RET_ERROR;
+ }
+ ptr += 2;
+ }
+
+ /* Time */
+ {
+ kal_int32 i = 0;
+ kal_int8 tmp[4] = {0};
+ kal_uint8 time[7] = {0};
+ char temp_buff[64] = {0};
+
+ for (i = 0; i < 7; i++) {
+ tmp[0] = *(ptr + 1);
+ tmp[1] = *ptr;
+ tmp[2] = 0;
+ time[i] = strtoul(tmp, 0, 10);
+ ptr += 2;
+ }
+
+ if (time[0] < 80) {
+ time[0] += 100;
+ }
+
+ memset(temp_buff, 0, sizeof(temp_buff));
+ snprintf(temp_buff, sizeof(temp_buff), "%04u-%02u-%02u %02u:%02u:%02u",time[0] + 1900, time[1], time[2], time[3], time[4], time[5]);
+ strncpy(sms->time, temp_buff, sizeof(sms->time));
+
+ //snprintf(sms->time, sizeof(sms->time), "%04u-%02u-%02u %02u:%02u:%02u", time[0] + 1900, time[1], time[2], time[3], time[4], time[5]);
+
+ LOGE("sms time = [%s]\n", sms->time);
+ }
+ {
+ kal_int32 i = 0;
+ kal_int32 udh_len = 0;
+ kal_int32 data_len = 0;
+ kal_int32 buf_len = 0;
+ kal_int32 octect = 0;
+
+ data_len = internal_mdapi_hex2int(ptr);
+ ptr += 2;
+
+ /* parse UDH header, to parse log SMS header */
+ if (udh) {
+ kal_int8 *ptr_udh = NULL;
+ udh_len = internal_mdapi_hex2int(ptr);
+ ptr += 2;
+ ptr_udh = ptr;
+ while (i < udh_len) {
+ kal_int32 iei = 0;
+ kal_int32 iei_len = 0;
+
+ iei = internal_mdapi_hex2int(ptr);
+ ptr += 2;
+ iei_len = internal_mdapi_hex2int(ptr);
+ ptr += 2;
+
+ if (iei != 0x00 && iei != 0x08) {
+ ptr += (iei_len) * 2;
+ i += 2 + iei_len;
+ continue;
+ }
+
+ if (iei == 0x00) {
+ sms->ref_num = internal_mdapi_hex2int(ptr);
+ ptr += 2;
+ } else {
+ sms->ref_num = ((internal_mdapi_hex2int(ptr) & 0xFF) << 8)
+ | (internal_mdapi_hex2int(ptr + 2) & 0xFF);
+ ptr += 4;
+ }
+ /*lei modify for gsw 2022/5/12*/
+ sms->total_pack = internal_mdapi_hex2int(ptr);
+ LOGE("sms->total_pack = [%d]", sms->curr_pack);
+ *total_pack = sms->total_pack;
+ sms->curr_pack = internal_mdapi_hex2int(ptr+2);
+ LOGE("sms->curr_pack = [%d]", sms->curr_pack);
+ *curr_pack = sms->curr_pack;
+ /*lei modify for gsw 2022/5/12*/
+ break;
+ }
+
+ ptr = ptr_udh + (udh_len) * 2;
+ }
+
+ LOGE("sms->charset = [%d] \n", sms->charset);
+ switch (sms->charset) {
+ case MDAPI_SMS_CHARSET_GSM_7BIT:
+ octect = (data_len % 8 == 0) ? 1 : 0;
+ // decode 7bit
+ if (1 == udh) {
+ kal_int32 padding_bits = ((udh_len + 1) * 8) % 7;
+ if (padding_bits) {
+ padding_bits = 7 - padding_bits;
+ }
+ data_len = internal_mdapi_sms_7bit_decode(ptr, sms->msg_content, content_size, padding_bits, octect);
+ } else {
+ data_len = internal_mdapi_sms_7bit_decode(ptr, sms->msg_content, content_size, 0, octect);
+ }
+
+ *(sms->msg_content + data_len++) = '\0';
+ *(sms->msg_content + data_len++) = '\0';
+
+ *record_size = data_len;
+ break;
+
+ case MDAPI_SMS_CHARSET_GSM_8BIT:
+ sms->msg_content = ptr;
+ content_size = strlen(sms->msg_content);
+ #if 0
+ if( 1 == udh ) {
+ data_len -= (udh_len + 1);
+ }
+ if (data_len >= *record_size - 2) {
+ data_len = *record_size - 2;
+ }
+
+ sms->msg_content[0] = '\0';
+ for (i = 0 ; i < data_len ; i++) {
+ kal_uint8 tmp[2] = {0, 0};
+
+ tmp[0] = internal_mdapi_hex2int(ptr);
+ ptr += 2;
+
+ buf_len += kal_ext_ascii_to_utf8((UTF8 *)(sms->msg_content + buf_len), tmp, *record_size - buf_len);
+ if (*record_size - buf_len < 0) {
+ return MDAPI_RET_ERROR;
+ }
+ }
+
+ *(sms->msg_content + buf_len++) = '\0';
+ *(sms->msg_content + buf_len++) = '\0';
+
+ *record_size = buf_len;
+
+ //LOGE(KAL_LOG_INFO, LOG_TAG, "is utf8 = [%d]", is_utf8_sequence((UTF8 *)sms->msg_content, (UTF8 *)sms->msg_content + data_len - 2));
+ #endif
+ break;
+
+ case MDAPI_SMS_CHARSET_UCS2:
+ buf_len = 0;
+
+ if( 1 == udh ) {
+ data_len -= (udh_len + 1);
+ }
+
+ sms->msg_content[0] = '\0';
+
+ for (i=0 ; i < data_len ; i = i + 2) {
+ UTF16 tmp[2] = {0, 0};
+ kal_uint8 *tmp_ptr = (kal_uint8 *)tmp;
+
+ tmp_ptr[0] = internal_mdapi_hex2int(ptr);
+ ptr += 2;
+ tmp_ptr[1] = internal_mdapi_hex2int(ptr);
+ ptr += 2;
+ tmp[0] = ntohs(tmp[0]);
+ //LOGE(KAL_LOG_INFO, LOG_TAG, "tmp = [%04X]", tmp);
+
+ buf_len += kal_utf16_to_utf8((UTF8 *)(sms->msg_content + buf_len), tmp, *record_size - buf_len);
+ if (*record_size - buf_len < 0) {
+ return MDAPI_RET_ERROR;
+ }
+ }
+
+ *(sms->msg_content + buf_len++) = '\0';
+ *(sms->msg_content + buf_len++) = '\0';
+
+ *record_size = buf_len;
+
+
+ break;
+
+ default:
+ return MDAPI_RET_ERROR;
+ }
+ }
+
+ sms->position = MDAPI_SMS_POS_INBOX;
+ return MDAPI_RET_SUCCESS;
+}
+
+
+int smsPduDecode(const char *pdu_str, int pdu_len,
+ char *da_num, char *smsc, char *msg, int *charset, int *curr_pack, int *total_pack, char *date)
+{
+ kal_char msg_tmp[MAX_PDU_SIZE] = {0};
+ mdapi_sms_record_t record;
+ kal_int32 status = MDAPI_RET_ERROR;
+ kal_int32 out_len = 210;
+
+ LOGE("%s\n",__FILE__);
+ LOGE("%s\n",__FUNCTION__);
+ LOGE("%d\n",__LINE__);
+ LOGE("%d\n",pdu_len);
+ LOGE("%s\n",pdu_str);
+
+ record.msg_content = msg_tmp;
+ /*lei modify for gsw 2022/5/11*/
+ status = _mdapi_sms_decode_pdu(&record, smsc, (kal_int8 *)pdu_str,
+ pdu_len, &out_len, curr_pack, total_pack);
+ /*lei modify for gsw 2022/5/11*/
+ if(status == MDAPI_RET_SUCCESS) {
+ memcpy(da_num, record.phone_number, strlen(record.phone_number));
+ memcpy(msg, record.msg_content, strlen(record.msg_content));
+ *charset = record.charset;
+ memcpy(date, record.time, strlen(record.time));
+
+ #if 0
+ /*lei modify for gsw 2022/5/11*/
+ *curr_pack = record.curr_pack;
+ *total_pack = record.total_pack;
+ /*lei modify for gsw 2022/5/11*/
+ #endif
+ } else {
+ LOGE("PDU decode error");
+ }
+
+ return status;
+}
\ No newline at end of file