Add mbtk_ril V2 (Default close)
Change-Id: Iaa5921fd74aeeb394771110f0cec7aa7742dc83a
diff --git a/mbtk/libmbtk_ril_v2/Makefile b/mbtk/libmbtk_ril_v2/Makefile
new file mode 100755
index 0000000..617a549
--- /dev/null
+++ b/mbtk/libmbtk_ril_v2/Makefile
@@ -0,0 +1,36 @@
+BUILD_ROOT = $(shell pwd)/..
+include $(BUILD_ROOT)/Make.defines
+
+LOCAL_PATH=$(BUILD_ROOT)/libmbtk_ril_v2
+
+INC_DIR +=
+
+LIB_DIR +=
+
+LIBS += -llog -lmbtk_lib -lmbtk_net
+
+CFLAGS += -shared -Wl,-shared,-Bsymbolic
+
+LOCAL_SRC_FILES = $(wildcard src/*.cpp) $(wildcard src/*.c)
+OBJS = $(patsubst %.c, %.o, $(LOCAL_SRC_FILES))
+$(info OBJS = $(OBJS))
+
+OBJS = $(patsubst %.c, %.o, $(patsubst %.cpp, %.o, $(LOCAL_SRC_FILES)))
+$(info OBJS = $(OBJS))
+
+dtarget := $(OUT_DIR)/lib/libmbtk_ril.so
+
+all: $(dtarget)
+
+$(dtarget):$(OBJS)
+ $(CC) $(CFLAGS) $(DEFINE) $(LIB_DIR) $(LIBS) $(OBJS) -o $@
+
+%.o:%.c
+ $(CC) $(CFLAGS) $(INC_DIR) $(DEFINE) -c $< -o $@
+
+%.o:%.cpp
+ $(CC) $(CFLAGS) $(INC_DIR) $(DEFINE) -c $< -o $@
+
+clean:
+ rm -f $(OBJS) $(dtarget)
+
diff --git a/mbtk/libmbtk_ril_v2/inc/mbtk_alphabet.h b/mbtk/libmbtk_ril_v2/inc/mbtk_alphabet.h
new file mode 100755
index 0000000..1ffece7
--- /dev/null
+++ b/mbtk/libmbtk_ril_v2/inc/mbtk_alphabet.h
@@ -0,0 +1,140 @@
+//
+// Created by hitmoon on 15-12-10.
+//
+
+
+struct map_node {
+ unsigned short key;
+ unsigned short value;
+};
+
+
+#define map_size(map) (sizeof(map) / sizeof(struct map_node))
+
+
+// Unicode编码到GSM编码转换
+struct map_node UCS2ToBIT7[] = {
+ {0x000C, 0x1B0A},
+ {0x0024, 0x0002},
+ {0x0040, 0x0000},
+ {0x005B, 0x1B3C},
+ {0x005C, 0x1B2F},
+ {0x005D, 0x1B3E},
+ {0x005E, 0x1B14},
+ {0x005F, 0x0011},
+ {0x007B, 0x1B28},
+ {0x007C, 0x1B40},
+ {0x007D, 0x1B29},
+ {0x007E, 0x1B3D},
+ {0x00A0, 0x001B},
+ {0x00A1, 0x0040},
+ {0x00A3, 0x0001},
+ {0x00A4, 0x0024},
+ {0x00A5, 0x0003},
+ {0x00A7, 0x005F},
+ {0x00BF, 0x0060},
+ {0x00C4, 0x005B},
+ {0x00C5, 0x000E},
+ {0x00C6, 0x001C},
+ {0x00C9, 0x001F},
+ {0x00D1, 0x005D},
+ {0x00D6, 0x005C},
+ {0x00D8, 0x000B},
+ {0x00DC, 0x005E},
+ {0x00DF, 0x001E},
+ {0x00E0, 0x007F},
+ {0x00E4, 0x007B},
+ {0x00E5, 0x000F},
+ {0x00E6, 0x001D},
+ {0x00E7, 0x0009},
+ {0x00E8, 0x0004},
+ {0x00E9, 0x0005},
+ {0x00EC, 0x0007},
+ {0x00F1, 0x007D},
+ {0x00F2, 0x0008},
+ {0x00F6, 0x007C},
+ {0x00F8, 0x000C},
+ {0x00F9, 0x0006},
+ {0x00FC, 0x007E},
+ {0x0393, 0x0013},
+ {0x0394, 0x0010},
+ {0x0398, 0x0019},
+ {0x039B, 0x0014},
+ {0x039E, 0x001A},
+ {0x03A0, 0x0016},
+ {0x03A3, 0x0018},
+ {0x03A6, 0x0012},
+ {0x03A8, 0x0017},
+ {0x03A9, 0x0015},
+ {0x20AC, 0x1B65}
+};
+
+// GSM编码到Unicode编码转换
+struct map_node BIT7ToUCS2[] = {
+ {0x0000, 0x0040},
+ {0x0001, 0x00A3},
+ {0x0002, 0x0024},
+ {0x0003, 0x00A5},
+ {0x0004, 0x00E8},
+ {0x0005, 0x00E9},
+ {0x0006, 0x00F9},
+ {0x0007, 0x00EC},
+ {0x0008, 0x00F2},
+ {0x0009, 0x00E7},
+ {0x000B, 0x00D8},
+ {0x000C, 0x00F8},
+ {0x000E, 0x00C5},
+ {0x000F, 0x00E5},
+ {0x0010, 0x0394},
+ {0x0011, 0x005F},
+ {0x0012, 0x03A6},
+ {0x0013, 0x0393},
+ {0x0014, 0x039B},
+ {0x0015, 0x03A9},
+ {0x0016, 0x03A0},
+ {0x0017, 0x03A8},
+ {0x0018, 0x03A3},
+ {0x0019, 0x0398},
+ {0x001A, 0x039E},
+ {0x001B, 0x00A0},
+ {0x001C, 0x00C6},
+ {0x001D, 0x00E6},
+ {0x001E, 0x00DF},
+ {0x001F, 0x00C9},
+ {0x0024, 0x00A4},
+ {0x0040, 0x00A1},
+ {0x005B, 0x00C4},
+ {0x005C, 0x00D6},
+ {0x005D, 0x00D1},
+ {0x005E, 0x00DC},
+ {0x005F, 0x00A7},
+ {0x0060, 0x00BF},
+ {0x007B, 0x00E4},
+ {0x007C, 0x00F6},
+ {0x007D, 0x00F1},
+ {0x007E, 0x00FC},
+ {0x007F, 0x00E0}
+};
+// GSM编码转义序列到Unicode编码转换
+struct map_node BIT7EToUCS2[] = {
+ {0x000A, 0x000C},
+ {0x0014, 0x005E},
+ {0x0028, 0x007B},
+ {0x0029, 0x007D},
+ {0x002F, 0x005C},
+ {0x003C, 0x005B},
+ {0x003D, 0x007E},
+ {0x003E, 0x005D},
+ {0x0040, 0x007C},
+ {0x0065, 0x20AC}
+};
+
+// map 中查询键值
+int32_t map_get_value(struct map_node *map, unsigned int size, unsigned short key) {
+ int i = 0;
+ for (i = 0; i < size; i++) {
+ if (map[i].key == key)
+ return map[i].value;
+ }
+ return -1;
+}
diff --git a/mbtk/libmbtk_ril_v2/inc/mbtk_ril.h b/mbtk/libmbtk_ril_v2/inc/mbtk_ril.h
new file mode 100755
index 0000000..9303e26
--- /dev/null
+++ b/mbtk/libmbtk_ril_v2/inc/mbtk_ril.h
@@ -0,0 +1,355 @@
+#ifndef MBTK_INFO_INCLUDE
+#define MBTK_INFO_INCLUDE
+#include <netinet/in.h>
+#include <pthread.h>
+
+#include "mbtk_type.h"
+#include "mbtk_list.h"
+#include "mbtk_log.h"
+#include "mbtk_utils.h"
+#include "mbtk_ril_api.h"
+
+#define RIL_SOCK_PACKET_TAG 0x5F6F7F8F
+#define RIL_SOCK_NAME "/tmp/mbtk_ril_sock"
+#define RIL_SOCK_MSG_LEN_MAX 2048
+
+// Tag(4) + Packet_Length(2)
+#define RIL_SOCK_PACK_EXTRA_LEN 6
+// RIL_SOCK_PACK_EXTRA_LEN + Index(2) + Type(2) + Id(2) + Error(2) + data_len(2)
+#define RIL_SOCK_PACK_LEN_MIN (RIL_SOCK_PACK_EXTRA_LEN + 10)
+
+#define RIL_MSG_INDEX_AUTO (-1) // automatically , refor to : ril_index
+#define RIL_MSG_INDEX_INVALID (0) // Invalid msg index.
+
+typedef enum
+{
+ RIL_MSG_TYPE_REQ,
+ RIL_MSG_TYPE_RSP,
+ RIL_MSG_TYPE_IND
+} ril_msg_type_enum;
+
+typedef enum
+{
+ // Device Information
+ RIL_MSG_ID_DEV_BEGIN = 0,
+ // <string> IMEI
+ RIL_MSG_ID_DEV_IMEI,
+ // <string> SN
+ RIL_MSG_ID_DEV_SN,
+ // <string> MEID
+ RIL_MSG_ID_DEV_MEID,
+ // <string> VERSION
+ RIL_MSG_ID_DEV_VERSION,
+ // <string> MODEL
+ RIL_MSG_ID_DEV_MODEL,
+ // <uint8> 0:Close 1:Open
+ RIL_MSG_ID_DEV_VOLTE,
+ // <string> Temperature
+ RIL_MSG_ID_DEV_TEMP, // Temperature
+ // <string> 23/03/20,01:58:00+32
+ RIL_MSG_ID_DEV_CELL_TIME, // Time
+ // <uint8><uint8>
+ RIL_MSG_ID_DEV_MODEM,
+
+ RIL_MSG_ID_DEV_END,
+
+ // Sim Information
+ RIL_MSG_ID_SIM_BEGIN = 1000,
+ // <uint8> 0:NOT_EXIST 1:READY ...
+ RIL_MSG_ID_SIM_STATE,
+ // <uint8> 0: SIM 1: USIM 2: TEST SIM 3: TEST USIM 4: UNKNOWN
+ RIL_MSG_ID_SIM_TYPE,
+ // <string> IMSI
+ RIL_MSG_ID_SIM_IMSI,
+ // <string> ICCID
+ RIL_MSG_ID_SIM_ICCID,
+ // <string> Phone Number
+ RIL_MSG_ID_SIM_PN,
+ // <string> PUK
+ RIL_MSG_ID_SIM_LOCK,
+ // <uint8> <uint8> <uint8> <uint8> PIN PUK LAST TIMES
+ RIL_MSG_ID_SIM_PINPUK_TIMES,
+ // <string> PLMN
+ RIL_MSG_ID_SIM_PLMN,
+
+ RIL_MSG_ID_SIM_END,
+
+ // Network Information
+ RIL_MSG_ID_NET_BEGIN = 2000,
+ // sel_mode(uint8)type(uint8)plmn(uint32)...sel_mode(uint8)type(uint8)plmn(uint32)
+ RIL_MSG_ID_NET_AVAILABLE,
+ // <uint8> 0: automatic 1: manual
+ // or
+ // sel_mode(uint8)type(uint8)plmn(uint32)
+ RIL_MSG_ID_NET_SEL_MODE,
+ // mbtk_band_info_t
+ RIL_MSG_ID_NET_BAND,
+ // mbtk_signal_info_t
+ RIL_MSG_ID_NET_SIGNAL,
+ // mbtk_net_reg_info_t
+ RIL_MSG_ID_NET_REG,
+ // mbtk_cell_info_t[]
+ RIL_MSG_ID_NET_CELL,
+ // mbtk_apn_info_t
+ RIL_MSG_ID_NET_APN,
+ // REQ:
+ // <call_type[1]><cid[1]><timeout[1]>
+ // call_type : mbtk_data_call_type_enum
+ // cid : 1 - 15
+ // timeout : second
+ // RSP:
+ // <type[1]><ipv4><ipv6>
+ // type : 0-IPV4 1-IPV6 2-IPV4V6
+ // ipv4 : mbtk_ipv4_info_t
+ // ipv6 : mbtk_ipv6_info_t
+ RIL_MSG_ID_NET_DATA_CALL,
+
+ RIL_MSG_ID_NET_END,
+
+
+ // Call Information
+ RIL_MSG_ID_CALL_BEGIN = 3000,
+ RIL_MSG_ID_CALL_STATE,
+
+ // Start call.
+ RIL_MSG_ID_CALL_START,
+ //answer call
+ RIL_MSG_ID_CALL_ANSWER,
+ //hang up all call
+ RIL_MSG_ID_CALL_HANGUP,
+ //hang up a call
+ RIL_MSG_ID_CALL_HANGUP_A,
+ //hang up waiting or background call
+ RIL_MSG_ID_CALL_HANGUP_B,
+ //hang up foreground resume background
+ RIL_MSG_ID_CALL_HANGUP_C,
+ //wait in call
+ RIL_MSG_ID_CALL_WAITIN,
+ //mute call
+ RIL_MSG_ID_CALL_MUTE,
+ //dtmf call
+ RIL_MSG_ID_CALL_DTMF,
+ RIL_MSG_ID_CALL_END,
+
+ // SMS Information
+ RIL_MSG_ID_SMS_BEGIN = 4000,
+ RIL_MSG_ID_SMS_STATE,
+ RIL_MSG_ID_SMS_CMGF,
+ RIL_MSG_ID_SMS_CPMS,
+ RIL_MSG_ID_SMS_CMGS,
+ RIL_MSG_ID_SMS_CMSS,
+ RIL_MSG_ID_SMS_CMGR,
+ RIL_MSG_ID_SMS_CMGW,
+ RIL_MSG_ID_SMS_CMGD,
+ RIL_MSG_ID_SMS_CMGL,
+ RIL_MSG_ID_SMS_CSCA,
+ RIL_MSG_ID_SMS_CSMP,
+ RIL_MSG_ID_SMS_CSCB,
+ RIL_MSG_ID_SMS_CNMI,
+
+ RIL_MSG_ID_SMS_END,
+
+ // PhoneBook Information
+ RIL_MSG_ID_PB_BEGIN = 5000,
+ RIL_MSG_ID_PB_STATE,
+
+ RIL_MSG_ID_PB_END,
+
+ // IND Information
+ RIL_MSG_ID_IND_BEGIN = 10000,
+ // NULL
+ RIL_MSG_ID_IND_SER_READY,
+ // <uint8> State
+ RIL_MSG_ID_IND_NET_STATE_CHANGE,
+ // <uint8> State
+ RIL_MSG_ID_IND_CALL_STATE_CHANGE,
+ // <uint8> State
+ RIL_MSG_ID_IND_SMS_STATE_CHANGE,
+ // <uint8> State
+ RIL_MSG_ID_IND_RADIO_STATE_CHANGE,
+ // <uint8> State
+ RIL_MSG_ID_IND_SIM_STATE_CHANGE,
+ // <uint8> State
+ RIL_MSG_ID_IND_PDP_STATE_CHANGE,
+ // <uint8> State
+ RIL_MSG_ID_IND_SIGNAL_STATE_CHANGE,
+
+
+ RIL_MSG_ID_IND_END,
+ RIL_MSG_ID_UNKNOWN // Unknown information.
+} ril_msg_id_enum;
+
+typedef struct {
+ uint32 tag; // Refor to : RIL_SOCK_PACKET_TAG
+ uint16 msg_len;
+
+ uint16 msg_index; // Message index(Start from 1)
+ // 0 : For unknown msg id
+ uint16 msg_type; // Refor to : ril_msg_type_enum
+ uint16 msg_id; // Refor to : ril_msg_id_enum
+ uint16 err; // Only for RSP(Refor to : mbtk_ril_err_enum)
+ uint16 data_len;
+ uint8 *data;
+} __attribute__((packed)) ril_msg_pack_info_t;
+
+typedef struct {
+ pthread_t pid;
+ char name[20];
+ bool is_waitting;
+ pthread_cond_t cond;
+ pthread_mutex_t mutex;
+} ril_cli_thread_info_t;
+
+typedef struct {
+ pthread_t pid;
+ bool is_async;
+ int *rsp_data_len; // Save response data length.
+ char *rsp_data; // Save response date.
+ int *rsp_err; // Save response error, refor to mbtk_ril_err_enum .
+ ril_msg_pack_info_t *pack;
+} ril_msg_info_t;
+
+/*
+GSM band��
+ 1 �C PGSM 900 (standard or primary)
+ 2 �C DCS GSM 1800
+ 4 �C PCS GSM 1900
+ 8 �C EGSM 900 (extended)
+ 16 �C GSM 450
+ 32 �C GSM 480
+ 64 �C GSM 850
+ 512 - BAND_LOCK_BIT // used for GSM band setting
+*/
+typedef enum
+{
+ MBTK_GSM_BAND_PGSM_900 = 1,
+ MBTK_GSM_BAND_DCS_GSM_1800 = 2,
+ MBTK_GSM_BAND_PCS_GSM_1900 = 4,
+ MBTK_GSM_BAND_EGSM_900 = 8,
+ MBTK_GSM_BAND_GSM_450 = 16,
+ MBTK_GSM_BAND_GSM_480 = 32,
+ MBTK_GSM_BAND_GSM_850 = 64,
+ MBTK_GSM_BAND_BAND_LOCK_BIT = 512
+} mbtk_gsm_band_enum;
+
+/*
+UMTS band��
+ 1 �C UMTS_BAND_1
+ 2 �C UMTS_BAND_2
+ 4 �C UMTS_BAND_3
+ 8 �C UMTS_BAND_4
+ 16 �C UMTS_BAND_5
+ 32 �C UMTS_BAND_6
+ 64 �C UMTS_BAND_7
+ 128 �C UMTS_BAND_8
+ 256 �C UMTS_BAND_9
+*/
+typedef enum
+{
+ MBTK_UMTS_BAND_1 = 1,
+ MBTK_UMTS_BAND_2 = 2,
+ MBTK_UMTS_BAND_3 = 4,
+ MBTK_UMTS_BAND_4 = 8,
+ MBTK_UMTS_BAND_5 = 16,
+ MBTK_UMTS_BAND_6 = 32,
+ MBTK_UMTS_BAND_7 = 64,
+ MBTK_UMTS_BAND_8 = 128,
+ MBTK_UMTS_BAND_9 = 256
+} mbtk_umts_band_enum;
+
+/*
+LTEbandH(TDD-LTE band)
+ 32 �C TDLTE_BAND_38
+ 64 �C TDLTE_BAND_39
+ 128 �C TDLTE_BAND_40
+ 256 �C TDLTE_BAND_41
+*/
+typedef enum
+{
+ MBTK_TDLTE_BAND_38 = 32,
+ MBTK_TDLTE_BAND_39 = 64,
+ MBTK_TDLTE_BAND_40 = 128,
+ MBTK_TDLTE_BAND_41 = 256
+} mbtk_tdlte_band_enum;
+
+/*
+LTEbandL(FDD-LTE band)
+ 1 �C FDDLTE_BAND_1
+ 4 �C FDDLTE _BAND_3
+ 8 �C FDDLTE _BAND_4
+ 64 �C FDDLTE _BAND_7
+ 65536 �C FDDLTE _BAND_17
+ 524288 �C FDDLTE _BAND_20
+*/
+typedef enum
+{
+ MBTK_FDDLTE_BAND_1 = 1,
+ MBTK_FDDLTE_BAND_3 = 4,
+ MBTK_FDDLTE_BAND_4 = 8,
+ MBTK_FDDLTE_BAND_7 = 64,
+ MBTK_FDDLTE_BAND_17 = 65536,
+ MBTK_FDDLTE_BAND_20 = 524288
+} mbtk_fddlte_band_enum;
+
+typedef enum
+{
+ MBTK_LTE_EXT_BAND_65 = 1,
+ MBTK_LTE_EXT_BAND_66 = 2,
+ MBTK_LTE_EXT_BAND_67 = 4,
+ MBTK_LTE_EXT_BAND_68 = 8,
+ MBTK_LTE_EXT_BAND_69 = 16
+} mbtk_lte_ext_band_enum;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+char* type2str(ril_msg_type_enum type);
+
+char* apn2str(mbtk_ip_type_enum type);
+
+/*
+IPv6 : 254.128.0.0.0.0.0.0.0.1.0.2.144.5.212.239 -> uint128
+*/
+int str_2_ipv6(const void *ip_str, void *ipv6);
+
+/*
+IPv6 : uint128 -> fe80::215:1dff:fe81:484c
+*/
+int ipv6_2_str(const void *ipv6, void *ipv6_str);
+
+char* id2str(int id);
+
+char* err2str(mbtk_ril_err_enum err);
+
+void *mbtk_memcpy(const void *src, unsigned int n);
+
+/*
+0 GSM
+1 GSM_COMPACT
+2 UTRAN
+3 GSM_EGPRS
+4 UTRAN_HSDPA
+5 UTRAN_HSUPA
+6 UTRAN_HSDPA_HSUPA
+7 EUTRAN
+8 ECGSM
+*/
+mbtk_net_type_enum mbtk_net_type_get(mbtk_radio_technology_enum radio_tech);
+
+void ril_msg_pack_free(ril_msg_pack_info_t* pack);
+
+ril_msg_pack_info_t* ril_msg_pack_creat(int msg_type, int msg_id, int msg_index, const void *data, int data_len);
+
+int ril_pack_send(int fd, ril_msg_pack_info_t *pack);
+
+ril_msg_pack_info_t** ril_pack_recv(int fd, bool is_server, mbtk_ril_err_enum *err);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* MBTK_INFO_INCLUDE */
+
+
diff --git a/mbtk/libmbtk_ril_v2/src/mbtk_pdu_sms.c b/mbtk/libmbtk_ril_v2/src/mbtk_pdu_sms.c
new file mode 100755
index 0000000..5825cb6
--- /dev/null
+++ b/mbtk/libmbtk_ril_v2/src/mbtk_pdu_sms.c
@@ -0,0 +1,1086 @@
+//
+// Created by hitmoon on 15-12-9.
+//
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "mbtk_pdu_sms.h"
+#include "mbtk_alphabet.h"
+
+#define SUB_STR_SIZE 512
+char temp[SUB_STR_SIZE];
+
+// some constant
+
+//长短信信息元素参考号
+enum EnumCSMIEI mCSMIEI;
+// 服务中心地址
+char *mSCA;
+// 请求状态报告
+bool mSRR;
+// 拒绝副本
+bool mRD;
+// 短信有效期
+char *mVP;
+// 长短信信息元素消息参考号
+int mCSMMR;
+
+// initialize PDU constants
+void sms_init()
+{
+ mCSMMR = 0;
+ mRD = false;
+ mSRR = false;
+ mSCA = "";
+ mVP = "";
+ mCSMIEI = BIT8MIEI;
+}
+
+
+char *sub_str(const char *str, int start, int size) {
+ memset(temp, '\0', SUB_STR_SIZE);
+ if (size > 0)
+ strncpy(temp, str + start, size);
+ else if (size < 0)
+ strcpy(temp, str + start);
+
+ return temp;
+}
+
+struct SMS_Struct PDUDecoding(const char *data) {
+
+ struct SMS_Struct sms;
+ int end_index;
+ int PDUType;
+ // 短信中心
+ sms.SCA = SCADecoding(data, &end_index);
+
+ // 协议数据单元类型
+ PDUType = strtol(sub_str(data, end_index, 2), NULL, 16);
+ end_index += 2;
+
+ sms.RP = PDUType & (1 << 7) ? true : false; // 应答路径
+ sms.UDHI = PDUType & (1 << 6) ? true : false; // 用户数据头标识
+ sms.SRI = PDUType & (1 << 5) ? true : false; // 状态报告指示
+ sms.MMS = PDUType & (1 << 2) ? false : true; // 更多信息发送
+ sms.MTI = PDUType & 3; // 信息类型指示
+
+ // 发送方SME的地址
+ sms.OA = OADecoding(data, end_index, &end_index);
+
+ // 协议标识
+ sms.PID = strtol(sub_str(data, end_index, 2), NULL, 16);
+ end_index += 2;
+
+ // 数据编码方案
+ int DCSType = strtol(sub_str(data, end_index, 2), NULL, 16);
+ end_index += 2;
+
+ // 文本压缩指示
+ sms.TC = DCSType & (1 << 5);
+ // 编码字符集
+ sms.DCS = (enum EnumDCS) ((DCSType >> 2) & 3);
+
+ if (DCSType & (1 << 4)) {
+ // 信息类型信息 0:立即显示 1:移动设备特定类型 2:SIM特定类型 3:终端设备特定类型
+ sms.MC = DCSType & 3;
+ }
+ else {
+ // 不含信息类型信息
+ sms.MC = -1;
+ }
+ // 服务中心时间戳(BCD编码)
+ sms.SCTS = SCTSDecoding(data, end_index);
+ end_index += 14;
+
+ // 用户数据头
+ if (sms.UDHI) {
+ sms.UDH = UDHDecoding(data, end_index + 2);
+ }
+ else {
+ sms.UDH = NULL;
+ }
+
+ // 用户数据
+ sms.UD = UserDataDecoding(data, end_index, sms.UDHI, sms.DCS);
+
+ return sms;
+}
+
+
+char *SCADecoding(const char *data, int *EndIndex) {
+ int len;
+
+ char *result;
+ char *buf;
+ int i = 0;
+
+ len = strtol(sub_str(data, 0, 2), NULL, 16);
+ if (len == 0) {
+ *EndIndex = 2;
+ return NULL;
+ }
+
+ *EndIndex = (len + 1) * 2;
+
+ result = (char *) malloc(sizeof(char) * len * 2);
+ //wmemset(result, '0', sizeof(char) * (len * 2 + 1));
+
+ buf = result;
+ len *= 2;
+
+ // 服务中心地址类型
+ if (strncmp(data + 2, "91", 2) == 0) {
+ sprintf(buf++, "+");
+ }
+
+ // 服务中心地
+
+ for (i = 4; i < *EndIndex; i += 2) {
+ sprintf(buf++, "%c", data[i + 1]);
+ sprintf(buf++, "%c", data[i]);
+ }
+
+ // 去掉填充的 'F'
+ if (result[strlen(result) - 1] == L'F') {
+ result[strlen(result) - 1] = L'\0';
+ }
+
+ return result;
+}
+
+char *OADecoding(const char *data, int index, int *EndIndex) {
+ int len;
+ char *result, *buf;
+
+ len = strtol(sub_str(data, index, 2), NULL, 16);
+
+ if (len == 0) {
+ *EndIndex = index + 2;
+ return NULL;
+ }
+
+ *EndIndex = index + 4 + len;
+
+ result = (char *) malloc(sizeof(char) * (len + 2));
+ //wmemset(result, 0, sizeof(char) * (len + 1));
+ buf = result;
+
+ if (strncmp(data + index + 2, "91", 2) == 0) {
+ sprintf(buf++, "+");
+ }
+
+ // 电话号码
+ int i = 0;
+ for (i = 0; i < len; i += 2) {
+ sprintf(buf++, "%c", data[index + i + 5]);
+ sprintf(buf++, "%c", data[index + i + 4]);
+
+ }
+
+ if (len % 2 != 0) {
+ result[strlen(result) - 1] = '\0';
+ (*EndIndex)++;
+ }
+ return result;
+}
+
+char *SCTSDecoding(const char *data, int index) {
+
+ char *result;
+
+ result = (char *) malloc(sizeof(char) * 32);
+ sprintf(result, "20%02d-%02d-%02d %02d:%02d:%02d",
+ BCDDecoding(data, index, 0), // 年
+ BCDDecoding(data, index + 2, 0), // 月
+ BCDDecoding(data, index + 4, 0), // 日
+ BCDDecoding(data, index + 6, 0), // 时
+ BCDDecoding(data, index + 8, 0), // 分
+ BCDDecoding(data, index + 10, 0) // 秒
+
+ );
+ return result;
+}
+
+int BCDDecoding(const char *data, int index, bool isMSB) {
+
+ int n1, n10;
+
+ n1 = strtol(sub_str(data, index, 1), NULL, 10);
+ n10 = strtol(sub_str(data, index + 1, 1), NULL, 10);
+
+ if (isMSB) {
+ if (n10 >= 8)
+ return -((n10 - 8) * 10 + n1); // 负值
+ else
+ return n10 * 10 + n1;
+ }
+ else {
+ return n10 * 10 + n1;
+ }
+}
+
+struct UDHS *UDHDecoding(const char *data, int index) {
+
+ int len;
+ struct UDHS *result;
+
+ len = strtol(sub_str(data, index, 2), NULL, 16);
+ index += 2;
+ int i = 0;
+
+ result = (struct UDHS *) malloc(sizeof(struct UDHS));
+ result->UDH = (struct PDUUDH *) malloc(sizeof(struct PDUUDH) * len);
+ result->count = 0;
+ memset(result->UDH, 0, sizeof(struct PDUUDH) * len);
+
+ while (i < len) {
+ // 信息元素标识(Information Element Identifier
+ char IEI = strtol(sub_str(data, index, 2), NULL, 16);
+ index += 2;
+ // 信息元素数据长度(Length of Information Element)
+ int IEDL = strtol(sub_str(data, index, 2), NULL, 16);
+ index += 2;
+ // 信息元素数据(Information Element Data)
+ char *IED = (char *) malloc(sizeof(char) * (IEDL + 1));
+ int j = 0;
+ for (j = 0; j < IEDL; j++) {
+ IED[j] = strtol(sub_str(data, index, 2), NULL, 16);
+ index += 2;
+ }
+ result->UDH[result->count].IEI = IEI;
+ result->UDH[result->count].IED = IED;
+ result->count++;
+ i += IEDL + 2;
+ }
+
+ return result;
+}
+
+char *UserDataDecoding(const char *data, int index, bool UDHI, enum EnumDCS dcs) {
+ char *result = NULL;
+ char *buf;
+
+ // 用户数据区长度
+ int UDL = strtol(sub_str(data, index, 2), NULL, 16);
+ index += 2;
+
+ // 跳过用户数据头
+ int UDHL = 0;
+ if (UDHI) {
+ // 用户数据头长度
+ UDHL = strtol(sub_str(data, index, 2), NULL, 16);
+ UDHL++;
+ index += UDHL << 1;
+
+ }
+
+ // 获取用户数据
+ if (dcs == UCS2) {
+ int len = (UDL - UDHL) >> 1;
+ int utf8_len;
+
+ result = (char *) malloc(sizeof(char) * (len * 3));
+ buf = result;
+ u_int32_t code[2];
+
+ int i = 0;
+ for (i = 0; i < len; i++) {
+ code[0] = strtol(sub_str(data, (i << 2) + index, 4), NULL, 16);
+ code[1] = 0;
+ utf32toutf8((wchar_t*)code, (unsigned char*)buf, len * 3, &utf8_len);
+ buf += utf8_len;
+ }
+
+ buf[0] = '\0';
+ return result;
+ }
+ else if (dcs == BIT7) {
+ int Septets = UDL - (UDHL * 8 + 6) / 7; // 7-Bit编码字符数
+
+ int FillBits = (UDHL * 8 + 6) / 7 * 7 - UDHL * 8; // 填充位数
+ return BIT7Decoding(BIT7Unpack(data, index, Septets, FillBits), Septets);
+ }
+ else {// 8Bit编码
+ // 获取数据长度
+ UDL -= UDHL;
+ result = (char *) malloc(sizeof(char) * (UDL + 1));
+ int i = 0;
+ for (i = 0; i < UDL; i++) {
+ result[i] = strtol(sub_str(data, (i << 1) + index, 2), NULL, 16);
+ }
+ return result;
+ }
+
+ return "Error!";
+}
+
+char *BIT7Unpack(const char *data, int index, int Septets, int FillBits) {
+ char *result;
+
+ result = (char *) malloc(sizeof(char) * (Septets + 1));
+ // 每8个7-Bit编码字符存放到7个字节
+ int PackLen = (Septets * 7 + FillBits + 7) / 8;
+ int n = 0;
+ int left = 0;
+
+// printf("Unapck data = %s\n", data + index);
+// printf("Septets = %d\n", Septets);
+// printf("pack len = %d\n", PackLen);
+// printf("fillbits = %d\n", FillBits);
+
+ int i = 0;
+ for (i = 0; i < PackLen; i++) {
+
+ int Order = (i + (7 - FillBits)) % 7;
+ int Value = strtol(sub_str(data, (i << 1) + index, 2), NULL, 16);
+ if (i != 0 || FillBits == 0) {
+ result[n++] = ((Value << Order) + left) & 0x7F;
+ }
+// printf("left = %d, i = %d, order = %d, value = %d\n", left, i, Order, Value);
+// printf("result[%d] = %d\n", n - 1, result[n - 1]);
+ left = Value >> (7 - Order);
+ if (Order == 6) {
+ if (n == Septets)
+ break;
+ result[n++] = left;
+ //printf("result[%d] = %d\n", n - 1, result[n - 1]);
+ left = 0;
+ }
+ }
+
+ return result;
+}
+
+char *BIT7Decoding(char *BIT7Data, unsigned int size)
+{
+ char *result, *buf;
+
+ result = (char *) malloc(sizeof(char) * (size + 1));
+ buf = result;
+
+ int i = 0;
+ for (i = 0; i < size; i++) {
+ u_int16_t key = BIT7Data[i];
+ if (isBIT7Same(key)) {
+ sprintf(buf++, "%c", key);
+ }
+ else if (map_get_value(BIT7ToUCS2, map_size(BIT7ToUCS2), key) >= 0) {
+ u_int16_t value;
+ if (key == 0x1B) { // 转义字符
+ value = map_get_value(BIT7EToUCS2, map_size(BIT7EToUCS2), BIT7Data[i + 1]);
+ if (i < size - 1 && value > 0) {
+ sprintf(buf++, "%c", value);
+ i++;
+ }
+ else {
+ value = map_get_value(BIT7ToUCS2, map_size(BIT7ToUCS2), key);
+ sprintf(buf++, "%c", value);
+ }
+ }
+ else {
+ //printf("go b\n");
+ value = map_get_value(BIT7ToUCS2, map_size(BIT7ToUCS2), key);
+ //printf("value = %u\n", value);
+ sprintf(buf++, "%c", value);
+
+ }
+ }
+ else {// 异常数据
+ sprintf(buf++, "?");
+ }
+
+ }
+ return result;
+
+}
+
+int isBIT7Same(u_int16_t UCS2) {
+ if ((UCS2 >= 0x61 && UCS2 <= 0x7A) ||
+ (UCS2 >= 0x41 && UCS2 <= 0x5A) ||
+ (UCS2 >= 0x25 && UCS2 <= 0x3F) ||
+ (UCS2 >= 0x20 && UCS2 <= 0x23) ||
+ UCS2 == 0x0A || UCS2 == 0x0D) {
+ return 1;
+ }
+ return 0;
+}
+
+struct PDUS *PDUEncoding(char *SCA, char *DA, char *UDC, struct UDHS *udhs) {
+ enum EnumDCS DCS;
+
+ sms_init();
+
+// if (isGSMString(UDC))
+// DCS = BIT7;
+// else
+ DCS = UCS2;
+
+ return PDUDoEncoding(SCA, DA, UDC, udhs, DCS);
+}
+
+struct PDUS *PDUDoEncoding(char *SCA, char *DA, char *UDC, struct UDHS *udhs, enum EnumDCS DCS) {
+ // 短信拆分
+ struct UDS *uds = UDCSplit(UDC, udhs, DCS);
+ struct PDUS *pdus;
+
+ if (uds == NULL)
+ return NULL;
+ pdus = (struct PDUS *) malloc(sizeof(struct PDUS));
+ pdus->count = 0;
+ pdus->PDU = (char **) malloc(sizeof(char *) * uds->total);
+
+ if (uds->total > 1) {
+ // 长短信
+ int CSMMR = mCSMMR;
+ if (++mCSMMR > 0xFFFF)
+ mCSMMR = 0;
+ // 生成短信编码序列
+ int i = 0;
+ for (i = 0; i < uds->total; i++) {
+ // 更新用户数据头
+ struct UDHS *CSMUDH = UpdateUDH(udhs, CSMMR, uds->total, i);
+ pdus->PDU[i] = SoloPDUEncoding(SCA, DA, uds->Data[i], CSMUDH, DCS);
+ pdus->count++;
+ }
+
+ }
+ else { // 单条短信
+ pdus->PDU[0] = SoloPDUEncoding(SCA, DA, uds->Data[0], udhs, DCS);
+ pdus->count = 1;
+ }
+
+ return pdus;
+}
+
+int isGSMString(char *Data) {
+
+ if (Data == NULL || strcmp(Data, "") == 0)
+ return 1;
+
+ if (is_acsii((unsigned char*)Data) == 0) {
+ int len;
+ len = utf8len((unsigned char *) Data);
+
+ u_int16_t *code = (u_int16_t *) malloc(sizeof(u_int16_t) * len);
+ utf8toutf16((unsigned char *) Data, code, len, &len);
+
+ while (*code) {
+ if (!(isBIT7Same(*code) || map_get_value(UCS2ToBIT7, map_size(UCS2ToBIT7), *code) >= 0))
+ return 0;
+ code++;
+ }
+
+ return 1;
+ }
+ else
+ return 1;
+
+}
+
+struct UDS *UDCSplit(char *UDC, struct UDHS *udhs, enum EnumDCS DCS) {
+ int UDHL = getUDHL(udhs);
+ struct UDS *result;
+
+ if (DCS == BIT7) {
+ // 7-Bit编码
+ // 计算剩余房间数
+ int room = BIT7UDL - (UDHL * 8 + 6) / 7;
+ if (room < 1) {
+ if (UDC == NULL || strcmp(UDC, "") == 0) {
+ result = (struct UDS *) malloc(sizeof(struct UDS));
+ result->Data = (char **)malloc(sizeof(char *));
+ result->total = 1;
+ result->Data[0] = UDC;
+ return result;
+ }
+ else
+ return NULL;
+ }
+
+ // 不需要拆分
+ if (SeptetsLength(UDC) <= room) {
+ result = (struct UDS *) malloc(sizeof(struct UDS));
+ result->Data = (char **)malloc(sizeof(char *));
+ result->total = 1;
+ result->Data[0] = UDC;
+ return result;
+ }
+ else // 拆分短信
+ {
+ if (UDHL == 0)
+ UDHL++;
+ if (mCSMIEI == BIT8MIEI)
+ UDHL += 5; // 1字节消息参考号
+ else
+ UDHL += 6; // 2字节消息参考号
+ // 更新剩余房间数
+ room = BIT7UDL - (UDHL * 8 + 6) / 7;
+ if (room < 1)
+ return NULL;
+
+ int i = 0;
+ int len = strlen(UDC);
+
+ result = (struct UDS *) malloc(sizeof(struct UDS));
+ result->total = 0;
+ result->Data = (char **) malloc(MAX_SMS_NR * sizeof(char *));
+
+ while (i < len) {
+ int step = SeptetsToChars(UDC, i, room);
+ if (i + step < len) {
+ result->Data[result->total] = (char *) malloc(sizeof(char) * (step + 1));
+ strcpy(result->Data[result->total++], sub_str(UDC, i, step));
+ }
+ else {
+ result->Data[result->total] = (char *) malloc(sizeof(char) * (len - i + 1));
+ strcpy(result->Data[result->total++], sub_str(UDC, i, -1));
+ }
+
+ i += step;
+
+ }
+ return result;
+
+ }
+ }
+ else { // UCS2编码
+ // 计算剩余房间数
+ int room = (BIT8UDL - UDHL) >> 1;
+ if (room < 1) {
+ if (UDC == NULL || strcmp(UDC, "") == 0) {
+ result = (struct UDS *) malloc(sizeof(struct UDS));
+ result->Data = (char **)malloc(sizeof(char *));
+ result->total = 1;
+ result->Data[0] = UDC;
+ return result;
+ }
+ else
+ return NULL;
+ }
+ if (UDC == NULL || utf8len(UDC) <= room) {
+ result = (struct UDS *) malloc(sizeof(struct UDS));
+ result->Data = (char **)malloc(sizeof(char *));
+ result->total = 1;
+ result->Data[0] = UDC;
+ return result;
+ }
+ else // 需要拆分成多条短信
+ {
+ if (UDHL == 0)
+ UDHL++;
+ if (mCSMIEI == BIT8MIEI)
+ UDHL += 5; // 1字节消息参考号
+ else
+ UDHL += 6; // 2字节消息参考号
+
+ // 更新剩余房间数
+ room = (BIT8UDL - UDHL) >> 1;
+ if (room < 1)
+ return NULL;
+
+ int len = utf8len(UDC);
+
+ result = (struct UDS *) malloc(sizeof(struct UDS));
+ result->total = 0;
+ result->Data = (char **) malloc(MAX_SMS_NR * sizeof(char *));
+ int index = 0;
+ int i = 0;
+ for (i = 0; i < len; i += room) {
+ int real_size;
+ if (i + room < len) {
+ real_size = utf8_get_size(UDC + index, room);
+ result->Data[result->total] = (char*)malloc(sizeof(char) * (real_size + 1));
+ strcpy(result->Data[result->total++],sub_str(UDC, index, real_size));
+ }
+ else {
+ real_size = utf8_get_size(UDC + index, len - i);
+ result->Data[result->total] = (char*)malloc(sizeof(char) * (real_size + 1));
+ strcpy(result->Data[result->total++], sub_str(UDC, index, -1));
+ }
+ index += real_size;
+ }
+ return result;
+ }
+
+ }
+}
+
+int getUDHL(struct UDHS *udhs) {
+ if (udhs == NULL)
+ return 0;
+
+ // 加上1字节的用户数据头长度
+ int UDHL = 1;
+ int i = 0;
+ for (i = 0; i < udhs->count; i++) {
+ UDHL += strlen(udhs->UDH[i].IED) + 2;
+ }
+ return UDHL;
+}
+
+int SeptetsLength(char *source) {
+ if (source == NULL || strcmp(source, "") == 0) {
+ return 0;
+ }
+ int len = strlen(source);
+ while (*source) {
+ u_int16_t code = (u_int16_t) *source;
+ if (map_get_value(UCS2ToBIT7, map_size(UCS2ToBIT7), code) > 0xFF) {
+ len++;
+ }
+ source++;
+ }
+ return len;
+}
+
+int SeptetsToChars(char *source, int index, int septets) {
+ if (source == NULL || strcmp(source, "") == 0)
+ return 0;
+ int count = 0;
+ int i;
+
+ for (i = index; i < strlen(source); i++) {
+ u_int16_t code = (u_int16_t) source[i];
+ if (map_get_value(UCS2ToBIT7, map_size(UCS2ToBIT7), code) > 0xFF)
+ count++;
+
+ if (++count >= septets) {
+ if (count == septets)
+ i++;
+ break;
+ }
+ }
+ return i - index;
+}
+
+struct UDHS *UpdateUDH(struct UDHS *udhs, int CSMMR, int total, int index) {
+ struct UDHS *result;
+
+ result = (struct UDHS *) malloc(sizeof(struct UDHS));
+
+ if (udhs == NULL || udhs->count == 0) {
+ result->UDH = (struct PDUUDH *) malloc(sizeof(struct PDUUDH));
+ result->count = 1;
+
+ }
+ else {
+ result->UDH = (struct PDUUDH *) malloc(sizeof(struct PDUUDH) * (udhs->count + 1));
+ result->count = udhs->count + 1;
+ // 复制 UDH
+ memcpy(&result->UDH[1], udhs->UDH, sizeof(struct PDUUDH) * udhs->count);
+ }
+ // 插入第一个位置
+ if (mCSMIEI == BIT8MIEI) {
+ result->UDH[0].IED = (char *) malloc(sizeof(char) * 3);
+ result->UDH[0].count = 3;
+ result->UDH[0].IED[0] = CSMMR & 0xFF;
+ result->UDH[0].IED[1] = total;
+ result->UDH[0].IED[2] = index + 1;
+ result->UDH[0].IEI = 0;
+ }
+ else {
+ result->UDH[0].IED = (char *) malloc(sizeof(char) * 4);
+ result->UDH[0].count = 4;
+ result->UDH[0].IED[0] = (CSMMR >> 8) & 0xFF;
+ result->UDH[0].IED[1] = CSMMR & 0xFF;
+ result->UDH[0].IED[2] = total;
+ result->UDH[0].IED[3] = index + 1;
+ result->UDH[0].IEI = 8;
+ }
+
+ return result;
+}
+
+char *SoloPDUEncoding(char *SCA, char *DA, char *UC, struct UDHS *udhs, enum EnumDCS DCS) {
+ char *result;
+ char *buf, *ret;
+ int index;
+
+ result = (char *) malloc(sizeof(char) * 400);
+ buf = result;
+
+/* // 短信中心
+ ret = SCAEncoding(SCA);
+ index = strlen(ret);
+ sprintf(buf, "%s", ret);
+ printf("buf:%s\n",buf);
+ buf += index;
+
+*/
+ // 协议数据单元类型
+ if (udhs == NULL || udhs->count == 0) {
+ ret = PDUTypeEncoding(false);
+ sprintf(buf, "%s", ret);
+ buf += strlen(ret);
+ }
+ else {
+ ret = PDUTypeEncoding(true);
+ sprintf(buf, "%s", ret);
+ buf += strlen(ret);
+ }
+ // 消息参考值
+ ret = MREncoding();
+ sprintf(buf, "%s", ret);
+ buf += strlen(ret);
+ // 接收方SME地址
+ ret = DAEncoding(DA);
+ sprintf(buf, "%s", ret);
+ buf += strlen(ret);
+ // 协议标识
+ ret = PIDEncoding();
+ sprintf(buf, "%s", ret);
+ buf += strlen(ret);
+ // 编码方案
+ ret = DCSEncoding(UC, DCS);
+ sprintf(buf, "%s", ret);
+ buf += strlen(ret);
+ // 有效期
+ sprintf(buf, "%s", mVP);
+ buf += strlen(mVP);
+
+ // 用户数据长度及内容
+ ret = UDEncoding(UC, udhs, DCS);
+ sprintf(buf, "%s", ret);
+
+ return result;
+}
+
+char *SCAEncoding(char *SCA) {
+
+ if (SCA == NULL || strcmp(SCA, "") == 0) {
+ // 表示使用SIM卡内部的设置值,该值通过AT+CSCA指令设置
+ return "00";
+ }
+
+ char *result;
+ char *buf;
+ int len;
+ len = strlen(SCA);
+ result = (char *) malloc((len + 5) * sizeof(char));
+ buf = result;
+
+ int index = 0;
+ if (SCA[0] == '+') {
+ // 国际号码
+ sprintf(buf, "%02X", len / 2 + 1);
+ buf += 2;
+ sprintf(buf, "91");
+ buf += 2;
+ index = 1;
+ }
+ else {
+ // 国内号码
+ sprintf(buf, "%02X", len / 2 + 1);
+ buf += 2;
+ sprintf(buf, "81");
+ buf += 2;
+ }
+ // SCA地址编码
+ for (; index < len; index += 2) {
+ if (index == len - 1) {
+ // 补“F”凑成偶数个
+ sprintf(buf++, "F");
+ sprintf(buf++, "%c", SCA[index]);
+
+ }
+ else {
+ sprintf(buf++, "%c", SCA[index + 1]);
+ sprintf(buf++, "%c", SCA[index]);
+ }
+ }
+
+ return result;
+}
+
+char *PDUTypeEncoding(bool UDH) {
+ // 信息类型指示(Message Type Indicator)
+ // 01 SMS-SUBMIT(MS -> SMSC)
+ int PDUType = 0x11; // 508TLC change
+// int PDUType = 0x01;
+ char *result;
+ result = (char *) malloc(3 * sizeof(char));
+
+ // 用户数据头标识(User Data Header Indicator)
+ if (UDH) {
+ PDUType |= 0x40;
+ }
+ // 有效期格式(Validity Period Format)
+ if (strlen(mVP) == 2) {
+ // VP段以整型形式提供(相对的)
+ PDUType |= 0x10;
+ }
+ else if (strlen(mVP) == 14) {
+ // VP段以8位组的一半(semi-octet)形式提供(绝对的)
+ PDUType |= 0x18;
+ }
+
+ // 请求状态报告(Status Report Request)
+ if (mSRR) {
+ // 请求状态报告
+ PDUType |= 0x20;
+ }
+
+ // 拒绝复本(Reject Duplicate)
+ if (mRD) {
+ PDUType |= 0x04;
+ }
+ sprintf(result, "%02X", PDUType);
+ return result;
+}
+
+char *MREncoding() {
+ // 由手机设置
+ return "00";
+}
+
+char *DAEncoding(char *DA) {
+ if (DA == NULL || strcmp(DA, "") == 0) {
+ // 地址长度0,地址类型未知
+ return "0080";
+ }
+ char *result, *buf;
+ int len = strlen(DA);
+ int index;
+
+ result = (char *) malloc(sizeof(char) * (len + 5));
+ buf = result;
+
+ if (DA[0] == '+') {
+ // 国际号码
+ // 地址长度编码
+ sprintf(buf, "%02X", len - 1);
+ buf += 2;
+ // 地址类型
+ sprintf(buf, "91");
+ buf += 2;
+ index = 1;
+ }
+ else {
+ // 国内号码
+ // 地址长度编码
+ sprintf(buf, "%02X", len);
+ buf += 2;
+ // 地址类型
+ sprintf(buf, "81");
+ buf += 2;
+ }
+
+ for (; index < len; index += 2) {
+ // 号码部分奇偶位对调
+ if (index == len - 1) {
+ sprintf(buf++, "F");
+ sprintf(buf++, "%c", DA[index]);
+ }
+ else {
+ sprintf(buf++, "%c", DA[index + 1]);
+ sprintf(buf++, "%c", DA[index]);
+ }
+ }
+ return result;
+
+}
+
+char *PIDEncoding() {
+ return "00";
+}
+
+char *DCSEncoding(char *UD, enum EnumDCS DCS) {
+ if (DCS == BIT7) {
+ // 7-Bit编码
+ return "00";
+ }
+ else {
+ // UCS2编码
+ return "0800";
+ }
+}
+
+char *UDEncoding(char *UD, struct UDHS *udhs, enum EnumDCS DCS) {
+ int UDHL;
+
+ char *result;
+
+ // 用户数据头编码
+ char *header = UDHEncoding(udhs, &UDHL);
+
+ // 用户数据内容编码
+ int UDCL;
+ char *body;
+
+ body = UDCEncoding(UD, &UDCL, UDHL, DCS);
+
+ // 用户数据区长度
+ int UDL;
+ if (DCS == BIT7) {
+ // 7-Bit编码
+ UDL = (UDHL * 8 + 6) / 7 + UDCL;
+ }
+ else {
+ // UCS2编码或者8-Bit编码
+ UDL = UDHL + UDCL;
+ }
+
+ int len = strlen(header) + strlen(body) + 2;
+ result = (char *) malloc(sizeof(char) * (len + 1));
+ sprintf(result, "%02X%s%s", UDL, header, body);
+
+ return result;
+
+}
+
+char *UDHEncoding(struct UDHS *udhs, int *UDHL) {
+
+ *UDHL = 0;
+
+ if (udhs == NULL || udhs->count == 0)
+ return "";
+ int i = 0;
+ for (i = 0; i < udhs->count; i++) {
+ *UDHL += udhs->UDH[i].count + 2;
+ }
+
+ char *result;
+ char *buf;
+ result = (char *) malloc(sizeof(char) * ((*UDHL + 1) * 2 + 1));
+ buf = result;
+
+ sprintf(buf, "%02X", *UDHL);
+ buf += 2;
+
+ for (i = 0; i < udhs->count; i++) {
+ // 信息元素标识1字节
+ sprintf(buf, "%02X", udhs->UDH[i].IEI);
+ buf += 2;
+ // 信息元素长度1字节
+ sprintf(buf, "%02X", udhs->UDH[i].count);
+ buf += 2;
+ // 信息元素数据
+ int j = 0;
+ for (j = 0; j < udhs->UDH[i].count; j++) {
+ sprintf(buf, "%02X", udhs->UDH[i].IED[j]);
+ buf += 2;
+ }
+
+ }
+ // 加上1字节的用户数据头长度
+ (*UDHL)++;
+ return result;
+
+}
+
+char *UDCEncoding(char *UDC, int *UDCL, int UDHL, enum EnumDCS DCS) {
+ if (UDC == NULL || strcmp(UDC, "") == 0) {
+ *UDCL = 0;
+ return "";
+ }
+
+ if (DCS == BIT7) {
+ // 7-Bit编码,需要参考用户数据头长度,已保证7-Bit边界对齐
+ return BIT7Pack(BIT7Encoding(UDC, UDCL), UDHL);
+ }
+ else {
+ // UCS2编码
+
+ int len = utf8len((unsigned char*)UDC);
+ int len2;
+ unsigned short *code;
+
+ code = (unsigned short*)malloc(sizeof(unsigned short) * len);
+ utf8toutf16((unsigned char*)UDC, code, len, &len2);
+ *UDCL = len * 2;
+ char *result = (char *) malloc(sizeof(char) * (*UDCL * 2 + 1));
+ char *buf = result;
+
+ int i = 0;
+ for (i = 0; i < len; i++) {
+ sprintf(buf, "%04X", code[i]);
+ buf += 4;
+ }
+ free(code);
+ return result;
+ }
+}
+
+struct ByteArray *BIT7Encoding(char *UDC, int *Septets) {
+ struct ByteArray *result;
+
+ int len = strlen(UDC);
+
+ result = (struct ByteArray *) malloc(sizeof(struct ByteArray));
+ result->len = 0;
+ result->array = (char *) malloc(sizeof(char) * (len * 2 + 1));
+ *Septets = 0;
+
+ int i = 0;
+ for (i = 0; i < len; i++) {
+ u_int16_t code = (u_int16_t) UDC[i];
+ if (isBIT7Same(code)) {
+ // 编码不变
+ result->array[(*Septets)++] = code;
+ }
+ else {
+ u_int16_t value = map_get_value(UCS2ToBIT7, map_size(UCS2ToBIT7), code);
+ if (value >= 0) {
+ if (value > 0xFF) {
+ // 转义序列
+ result->array[(*Septets)++] = value >> 8;
+ result->array[(*Septets)++] = value & 0xFF;
+ }
+ else {
+ result->array[(*Septets)++] = value;
+ }
+ }
+ else {
+ // 未知字符
+ result->array[(*Septets)++] = (u_int16_t) '?';
+ }
+ }
+ }
+ // 重新调整大小
+ result->len = *Septets;
+
+ return result;
+}
+
+char *BIT7Pack(struct ByteArray *Bit7Array, int UDHL) {
+ // 7Bit对齐需要的填充位
+ int fillBits = (UDHL * 8 + 6) / 7 * 7 - (UDHL * 8);
+
+ // 压缩字节数
+ int len = Bit7Array->len;
+ int packLen = (len * 7 + fillBits + 7) / 8;
+ char *result;
+ char *buf;
+
+ result = (char *) malloc(sizeof(char) * (packLen * 2 + 1));
+ buf = result;
+
+ int left = 0;
+ int i = 0;
+ for (i = 0; i < len; i++) {
+ // 每8个字节压缩成7个字节
+ int32_t Value = Bit7Array->array[i];
+ int32_t index = (i + 8 - fillBits) % 8;
+ if (index == 0) {
+ left = Value;
+ }
+ else {
+ int32_t n = ((Value << (8 - index)) | left) & 0xFF;
+ sprintf(buf, "%02X", n);
+ buf += 2;
+ left = Value >> index;
+ }
+ }
+
+
+ if ((len * 7 + fillBits) % 8 != 0) {
+ // 写入剩余数据
+ sprintf(buf, "%02X", left);
+ buf += 2;
+ }
+ buf[0] = '\0';
+ return result;
+}
+
diff --git a/mbtk/libmbtk_ril_v2/src/mbtk_ril_api.c b/mbtk/libmbtk_ril_v2/src/mbtk_ril_api.c
new file mode 100755
index 0000000..b18e9d0
--- /dev/null
+++ b/mbtk/libmbtk_ril_v2/src/mbtk_ril_api.c
@@ -0,0 +1,2265 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <pthread.h>
+#include <sys/epoll.h>
+#include <string.h>
+#include <fcntl.h>
+#include <signal.h>
+
+#include "mbtk_ril.h"
+#include "mbtk_list.h"
+#include "mbtk_utils.h"
+#include "mbtk_log.h"
+
+typedef struct {
+ int cli_fd;
+ bool ril_ready;
+ int exit_fd[2];
+ pthread_t read_thread_id;
+ pthread_mutex_t send_mutex;
+ list_node_t* msg_list; // ril_msg_info_t
+ list_node_t* cli_thread_list; // ril_cli_thread_info_t
+} ril_cli_info_t;
+
+#define EPOLL_LISTEN_MAX 100
+
+static ril_cli_info_t ril_cli;
+static int pthread_id_index = 1;
+
+static ril_cli_thread_info_t* thread_find_by_pid(pthread_t pid)
+{
+ ril_cli_thread_info_t* cli_thread = NULL;
+ list_first(ril_cli.cli_thread_list);
+ while ((cli_thread = (ril_cli_thread_info_t*)list_next(ril_cli.cli_thread_list)))
+ {
+ if(pid == cli_thread->pid) {
+ break;
+ }
+ }
+
+ if(!cli_thread) { // No found cli thread in list.
+ cli_thread = (ril_cli_thread_info_t*)malloc(sizeof(ril_cli_thread_info_t));
+ memset(cli_thread, 0, sizeof(ril_cli_thread_info_t));
+ cli_thread->pid = pid;
+ sprintf(cli_thread->name, "PID-%d", pthread_id_index++);
+ pthread_mutex_init(&cli_thread->mutex, NULL);
+ pthread_cond_init(&cli_thread->cond, NULL);
+ cli_thread->is_waitting = FALSE;
+ list_add(ril_cli.cli_thread_list, cli_thread);
+ }
+
+ return cli_thread;
+}
+
+static void ril_thread_wait(ril_cli_thread_info_t* cli_thread)
+{
+ if(!cli_thread->is_waitting) {
+ LOGD("Thread(%s) waitting...", cli_thread->name);
+ cli_thread->is_waitting = TRUE;
+ pthread_mutex_lock(&cli_thread->mutex);
+ pthread_cond_wait(&cli_thread->cond, &cli_thread->mutex);
+ pthread_mutex_unlock(&cli_thread->mutex);
+ cli_thread->is_waitting = FALSE;
+ LOGD("Thread(%s) running...", cli_thread->name);
+ } else {
+ LOGD("RSP befor SEND, not waitting...");
+ cli_thread->is_waitting = FALSE;
+ }
+}
+
+
+static void ril_thread_continue(pthread_t pid)
+{
+ ril_cli_thread_info_t* cli_thread = NULL;
+ list_first(ril_cli.cli_thread_list);
+ while ((cli_thread = (ril_cli_thread_info_t*) list_next(ril_cli.cli_thread_list)))
+ {
+ if(pid == cli_thread->pid) {
+ break;
+ }
+ }
+
+ if(cli_thread) { // Found cli thread in list.
+ if(cli_thread->is_waitting) {
+ LOGD("Thread(%s) will continue...", cli_thread->name);
+ pthread_mutex_lock(&cli_thread->mutex);
+ pthread_cond_signal(&cli_thread->cond);
+ pthread_mutex_unlock(&cli_thread->mutex);
+ } else {
+ LOGD("Thread(%s) not continue...", cli_thread->name);
+ cli_thread->is_waitting = TRUE;
+ }
+ } else {
+ LOGE("No found cli thread[Cannot occur].");
+ }
+}
+
+static int ril_ind_process(ril_msg_pack_info_t* pack)
+{
+ switch(pack->msg_id) {
+ case RIL_MSG_ID_IND_SER_READY: // rild service ready.
+ {
+ ril_cli.ril_ready = TRUE;
+ return 0;
+ }
+ case RIL_MSG_ID_IND_NET_STATE_CHANGE:
+ {
+ return 0;
+ }
+ case RIL_MSG_ID_IND_CALL_STATE_CHANGE:
+ {
+ return 0;
+ }
+ case RIL_MSG_ID_IND_SMS_STATE_CHANGE:
+ {
+ return 0;
+ }
+ case RIL_MSG_ID_IND_RADIO_STATE_CHANGE:
+ {
+ return 0;
+ }
+ case RIL_MSG_ID_IND_SIM_STATE_CHANGE:
+ {
+ return 0;
+ }
+ case RIL_MSG_ID_IND_PDP_STATE_CHANGE:
+ {
+ return 0;
+ }
+ case RIL_MSG_ID_IND_SIGNAL_STATE_CHANGE:
+ {
+ return 0;
+ }
+ default:
+ {
+ LOGE("Unknown IND : %d", pack->msg_id);
+ return -1;
+ }
+ }
+}
+
+static int ril_rsp_process(ril_msg_pack_info_t* pack)
+{
+ if(pack->msg_index == RIL_MSG_INDEX_INVALID) {
+ LOGE("Invalid message index.");
+ return -1;
+ }
+
+ pthread_mutex_lock(&ril_cli.send_mutex);
+ ril_msg_info_t* msg = NULL;
+ list_first(ril_cli.msg_list);
+ while ((msg = (ril_msg_info_t*) list_next(ril_cli.msg_list)))
+ {
+ if(pack->msg_index == msg->pack->msg_index) {
+ break;
+ }
+ }
+
+ if(NULL == msg) { // No found message in msg list.
+ LOGW("Unknown msg : Index - %d, Type - %s, ID - %s, Result - %s ,Length - %d",
+ pack->msg_index, type2str(pack->msg_type), id2str(pack->msg_id), err2str(pack->err),
+ pack->data_len);
+ pthread_mutex_unlock(&ril_cli.send_mutex);
+ return -1;
+ } else {
+ int result = 0;
+ LOGD("Msg : Index - %d, Type - %s, ID - %s, Result - %s ,Length - %d", pack->msg_index,
+ type2str(pack->msg_type),
+ id2str(pack->msg_id),
+ err2str(pack->err),
+ pack->data_len);
+ if(msg->pack->msg_id != pack->msg_id) {
+ LOGE("msg id not match : %d , %d", msg->pack->msg_id ,pack->msg_id);
+ result = -1;
+ *(msg->rsp_err) = MBTK_RIL_ERR_FORMAT;
+ goto rm_msg_from_list;
+ }
+
+ if(msg->rsp_data && pack->data && pack->data_len > 0) {
+ memcpy(msg->rsp_data, pack->data, pack->data_len);
+ }
+
+ *(msg->rsp_data_len) = pack->data_len;
+ *(msg->rsp_err) = pack->err;
+
+ if(!msg->is_async) {
+ ril_thread_continue(msg->pid);
+ }
+
+rm_msg_from_list:
+ if(list_remove(ril_cli.msg_list, msg)) {
+ ril_msg_pack_free(msg->pack);
+ free(msg);
+ }
+ pthread_mutex_unlock(&ril_cli.send_mutex);
+ return result;
+ }
+}
+
+static int ril_pack_process(ril_msg_pack_info_t* pack)
+{
+ if(pack->msg_type == RIL_MSG_TYPE_IND) { // IND message.
+ return ril_ind_process(pack);
+ } else if(pack->msg_type == RIL_MSG_TYPE_RSP) {// Response message.
+ return ril_rsp_process(pack);
+ } else {
+ LOGE("Pack must be RSP or IND.");
+ return -1;
+ }
+}
+
+static void* ril_read_run(void* arg)
+{
+ int epoll_fd = epoll_create(5);
+ if(epoll_fd < 0)
+ {
+ LOGE("epoll_create() fail[%d].", errno);
+ return NULL;
+ }
+
+ uint32 event = EPOLLIN | EPOLLET;
+ struct epoll_event ev_cli, ev_exit;
+ ev_cli.data.fd = ril_cli.cli_fd;
+ ev_cli.events = event; //EPOLLIN | EPOLLERR | EPOLLET;
+ epoll_ctl(epoll_fd,EPOLL_CTL_ADD, ril_cli.cli_fd, &ev_cli);
+
+ ev_exit.data.fd = ril_cli.exit_fd[0];
+ ev_exit.events = event; //EPOLLIN | EPOLLERR | EPOLLET;
+ epoll_ctl(epoll_fd,EPOLL_CTL_ADD, ril_cli.exit_fd[0], &ev_exit);
+
+ int nready = -1;
+ struct epoll_event epoll_events[EPOLL_LISTEN_MAX];
+ while(1)
+ {
+ nready = epoll_wait(epoll_fd, epoll_events, EPOLL_LISTEN_MAX, -1);
+ if(nready > 0)
+ {
+ int i;
+ for(i = 0; i < nready; i++)
+ {
+ LOGD("fd[%d] event = %x",epoll_events[i].data.fd, epoll_events[i].events);
+ if(epoll_events[i].events & EPOLLHUP) // Closed by server.
+ {
+ LOGD("Closed by server.");
+ goto read_thread_exit;
+ }
+ else if(epoll_events[i].events & EPOLLIN)
+ {
+ if(ril_cli.cli_fd == epoll_events[i].data.fd) // Server data arrive.
+ {
+ // Read and process every message.
+ mbtk_ril_err_enum err = MBTK_RIL_ERR_SUCCESS;
+ ril_msg_pack_info_t **pack = ril_pack_recv(ril_cli.cli_fd, false, &err);
+
+ // Parse packet error,send error response to client.
+ if(pack == NULL)
+ {
+ if(err != MBTK_RIL_ERR_SUCCESS)
+ {
+ LOGE("RSP packet error[%s].", err2str(err));
+ }
+ }
+ else
+ {
+ ril_msg_pack_info_t** pack_ptr = pack;
+ while(*pack_ptr)
+ {
+ ril_pack_process(*pack_ptr);
+ ril_msg_pack_free(*pack_ptr);
+ pack_ptr++;
+ }
+ free(pack);
+ }
+ }
+ else if(ril_cli.exit_fd[0] == epoll_events[i].data.fd) //
+ {
+ char buff[100] = {0};
+ int len = read(ril_cli.exit_fd[0], buff, 100);
+ if(len > 0)
+ {
+ LOGI("CMD : %s", buff);
+ if(strcmp(buff, "EXIT") == 0)
+ {
+ goto read_thread_exit;
+ }
+ else
+ {
+ LOGE("Unkonw cmd : %s", buff);
+ }
+ }
+ else
+ {
+ LOGE("sock_read() fail.");
+ }
+ }
+ else
+ {
+ LOGE("Unknown socket : %d", epoll_events[i].data.fd);
+ }
+ }
+ else
+ {
+ LOGE("Unknown event : %x", epoll_events[i].events);
+ }
+ }
+ }
+ else
+ {
+ LOGE("epoll_wait() fail[%d].", errno);
+ }
+ }
+
+read_thread_exit:
+ LOGD("info_read thread exit.");
+ return NULL;
+}
+
+/*
+* Return recv data length.
+* -1 : fail.
+*/
+static mbtk_ril_err_enum ril_req_process(ril_msg_id_enum id,
+ const void *req,
+ int req_len,
+ void *rsp,
+ bool is_async)
+{
+ ril_msg_pack_info_t* pack = ril_msg_pack_creat(RIL_MSG_TYPE_REQ, id, RIL_MSG_INDEX_AUTO, req, req_len);
+ if(pack == NULL)
+ {
+ return MBTK_RIL_ERR_MEMORY;
+ }
+
+ ril_msg_info_t *msg_info = (ril_msg_info_t*)malloc(sizeof(ril_msg_info_t));
+ if(msg_info == NULL)
+ {
+ ril_msg_pack_free(pack);
+ return MBTK_RIL_ERR_MEMORY;
+ }
+
+ int rsp_data_len = 0;
+ int rsp_err = MBTK_RIL_ERR_SUCCESS;
+
+ pthread_mutex_lock(&ril_cli.send_mutex);
+ // Add to msg list.
+ msg_info->pid = pthread_self();
+ msg_info->pack = pack;
+ msg_info->rsp_data_len = &rsp_data_len;
+ msg_info->rsp_err = &rsp_err;
+ if(!is_async) { // Waitting for response for sync request.
+ msg_info->rsp_data = rsp; // Save response data.
+ } else {
+ msg_info->rsp_data = NULL;
+ }
+ msg_info->is_async = is_async;
+ list_add(ril_cli.msg_list, msg_info);
+ pthread_mutex_unlock(&ril_cli.send_mutex);
+
+ ril_cli_thread_info_t* cli_thread = thread_find_by_pid(msg_info->pid);
+ // Send pack to server success.
+ if(ril_pack_send(ril_cli.cli_fd, pack) >= RIL_SOCK_PACK_LEN_MIN) {
+ if(!is_async) { // Waitting for response for sync request.
+ ril_thread_wait(cli_thread);
+ }
+
+ LOGD("REQ(%s) success.", id2str(id));
+ return rsp_err;
+ } else {
+ if(list_remove(ril_cli.msg_list, msg_info)) {
+ ril_msg_pack_free(msg_info->pack);
+ free(msg_info);
+ }
+ return MBTK_RIL_ERR_SEND_PACK;
+ }
+}
+
+static void msg_list_free_cb(void *data)
+{
+ if(data) {
+ ril_msg_info_t *msg = (ril_msg_info_t*)data;
+ if(msg->pack) {
+ free(msg->pack);
+ }
+ free(msg);
+ }
+}
+
+static void cli_thread_list_free_cb(void *data)
+{
+ if(data) {
+ ril_cli_thread_info_t *cli_thread = (ril_cli_thread_info_t*)data;
+ pthread_mutex_destroy(&cli_thread->mutex);
+ pthread_cond_destroy(&cli_thread->cond);
+ free(cli_thread);
+ }
+}
+
+mbtk_ril_err_enum mbtk_ril_init()
+{
+ if(ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_INITED;
+ }
+
+ ril_cli.cli_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
+ if(ril_cli.cli_fd < 0)
+ {
+ LOGE("socket() fail[%d].", errno);
+ return MBTK_RIL_ERR_UNKNOWN;
+ }
+
+ // Set O_NONBLOCK
+ int flags = fcntl(ril_cli.cli_fd, F_GETFL, 0);
+ if (flags < 0)
+ {
+ LOGE("Get flags error:%d", errno);
+ goto error;
+ }
+ flags |= O_NONBLOCK;
+ if (fcntl(ril_cli.cli_fd, F_SETFL, flags) < 0)
+ {
+ LOGE("Set flags error:%d", errno);
+ goto error;
+ }
+
+ struct sockaddr_un cli_addr;
+ memset(&cli_addr, 0, sizeof(cli_addr));
+ cli_addr.sun_family = AF_LOCAL;
+ strcpy(cli_addr.sun_path, RIL_SOCK_NAME);
+ if(connect(ril_cli.cli_fd, (struct sockaddr *)&cli_addr, sizeof(cli_addr)))
+ {
+ LOGE("connect() fail[%d].", errno);
+ goto error;
+ }
+
+ if(pipe(ril_cli.exit_fd))
+ {
+ LOGE("pipe() fail[%d].", errno);
+ goto error;
+ }
+
+#if 1
+ pthread_attr_t thread_attr;
+ pthread_attr_init(&thread_attr);
+ if(pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED))
+ {
+ LOGE("pthread_attr_setdetachstate() fail.");
+ goto error;
+ }
+
+ if(pthread_create(&ril_cli.read_thread_id, &thread_attr, ril_read_run, NULL))
+ {
+ LOGE("pthread_create() fail.");
+ goto error;
+ }
+ pthread_attr_destroy(&thread_attr);
+#else
+ if(pthread_create(&read_thread_id, NULL, ril_read_run, NULL))
+ {
+ LOGE("pthread_create() fail.");
+ goto error;
+ }
+#endif
+
+ pthread_mutex_init(&ril_cli.send_mutex, NULL);
+ ril_cli.msg_list = list_create(msg_list_free_cb);
+ if(ril_cli.msg_list == NULL) {
+ LOGE("list_create(msg_list) fail.");
+ goto error;
+ }
+
+ ril_cli.cli_thread_list = list_create(cli_thread_list_free_cb);
+ if(ril_cli.cli_thread_list == NULL) {
+ LOGE("list_create(cli_thread_list) fail.");
+ goto error;
+ }
+
+ ril_cli.ril_ready = FALSE;
+
+ // Waitting mbtk_rild ready...
+ while(!ril_cli.ril_ready) {
+ usleep(100000);
+ }
+
+ LOGD("RIL server ready...");
+
+ return MBTK_RIL_ERR_SUCCESS;
+error:
+ if(ril_cli.cli_fd > 0)
+ {
+ close(ril_cli.cli_fd);
+ ril_cli.cli_fd = -1;
+ }
+ if(ril_cli.exit_fd[0] > 0)
+ {
+ close(ril_cli.exit_fd[0]);
+ ril_cli.exit_fd[0] = -1;
+ }
+ if(ril_cli.exit_fd[1] > 0)
+ {
+ close(ril_cli.exit_fd[1]);
+ ril_cli.exit_fd[1] = -1;
+ }
+
+ return MBTK_RIL_ERR_UNKNOWN;
+}
+
+mbtk_ril_err_enum mbtk_ril_deinit()
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(ril_cli.exit_fd[1] > 0)
+ {
+ if(write(ril_cli.exit_fd[1], "EXIT", 4) != 4) {
+ return MBTK_RIL_ERR_UNKNOWN;
+ }
+ }
+
+ // Wait read_thread exit.
+ pthread_join(ril_cli.read_thread_id,NULL);
+
+ if(ril_cli.exit_fd[0] > 0)
+ {
+ close(ril_cli.exit_fd[0]);
+ ril_cli.exit_fd[0] = -1;
+ }
+
+ if(ril_cli.exit_fd[1] > 0)
+ {
+ close(ril_cli.exit_fd[1]);
+ ril_cli.exit_fd[1] = -1;
+ }
+
+ if(ril_cli.cli_fd > 0)
+ {
+ close(ril_cli.cli_fd);
+ ril_cli.cli_fd = -1;
+ }
+
+ pthread_mutex_destroy(&ril_cli.send_mutex);
+ if(ril_cli.msg_list) {
+ list_free(ril_cli.msg_list);
+ }
+ if(ril_cli.cli_thread_list) {
+ list_free(ril_cli.cli_thread_list);
+ }
+
+ ril_cli.ril_ready = FALSE;
+
+ return MBTK_RIL_ERR_SUCCESS;
+}
+
+/*
+* Get platform version.
+*/
+mbtk_ril_err_enum mbtk_version_get(void *version)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(version == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_DEV_VERSION, NULL, 0, version, FALSE);
+}
+
+/*
+* Get platform version.
+*/
+mbtk_ril_err_enum mbtk_model_get(void *model)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(model == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_DEV_MODEL, NULL, 0, model, FALSE);
+}
+
+/*
+* Get platform IMEI.
+*/
+mbtk_ril_err_enum mbtk_imei_get(void *imei)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(imei == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_DEV_IMEI, NULL, 0, imei, FALSE);
+}
+
+
+/*
+* Get platform SN.
+*/
+mbtk_ril_err_enum mbtk_sn_get(void *sn)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(sn == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_DEV_SN, NULL, 0, sn, FALSE);
+}
+
+
+/*
+* Get platform MEID.
+*/
+mbtk_ril_err_enum mbtk_meid_get(void *meid)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(meid == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_DEV_MEID, NULL, 0, meid, FALSE);
+}
+
+
+/*
+* Return VoLTE state.
+*/
+mbtk_ril_err_enum mbtk_volte_state_get(int *volte_state)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(volte_state == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_DEV_VOLTE, NULL, 0, volte_state, FALSE);
+}
+
+/*
+* Set VoLTE state.
+*
+* volte_state:
+* 0 : Close VoLTE.
+* 1 : Open VoLTE.
+*
+* Restarting takes effect after execution.
+*/
+mbtk_ril_err_enum mbtk_volte_state_set(int volte_state)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(volte_state != 0 && volte_state != 1)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_DEV_VOLTE, &volte_state, 1, NULL, FALSE);
+}
+
+/*
+* Return radio state.
+*/
+mbtk_ril_err_enum mbtk_radio_state_get(mbtk_radio_state_enum *radio_state)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(radio_state == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ uint8 result;
+ mbtk_ril_err_enum err = ril_req_process(RIL_MSG_ID_DEV_MODEM, NULL, 0, &result, FALSE);
+ *radio_state = (mbtk_radio_state_enum)result;
+ return err;
+}
+
+/*
+* Set radio state.
+*
+* Refor to : mbtk_radio_state_enum
+*
+* Restarting takes effect after execution.
+*/
+mbtk_ril_err_enum mbtk_radio_state_set(mbtk_radio_state_enum radio_state, bool reset_modem)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(radio_state == MBTK_RADIO_STATE_UNKNOWN)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ uint8 buff[2];
+ buff[0] = (uint8)radio_state;
+ buff[1] = reset_modem ? 1 : 0;
+
+ return ril_req_process(RIL_MSG_ID_DEV_MODEM, buff, 2, NULL, FALSE);
+}
+
+/*
+* Get system temperature.
+*
+* type[IN]:
+* 0: Soc temperature.
+* 1: RF temperature.
+* temp[OUT]:
+* temperature in celsius.
+*/
+mbtk_ril_err_enum mbtk_temp_get(mbtk_temp_type_enum type, int* temp)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(temp == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ int16 result;
+ uint8 temp_temp = (uint8)type;
+ mbtk_ril_err_enum err = ril_req_process(RIL_MSG_ID_DEV_TEMP, &temp_temp, 1, &result, FALSE);
+ *temp = (int16)result;
+ return err;
+}
+
+
+/*
+* Get time type.
+* "23/05/24,06:09:32+32" -> "23/05/24 06:09:32 +32 00"
+*/
+mbtk_ril_err_enum mbtk_cell_time_get(char* time_str)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(time_str == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ char buff[RIL_SOCK_MSG_LEN_MAX] = {0};
+ mbtk_ril_err_enum err = ril_req_process(RIL_MSG_ID_DEV_CELL_TIME, NULL, 0, &buff, FALSE);
+ if(MBTK_RIL_ERR_SUCCESS == err)
+ {
+ memcpy(time_str,buff,strlen(buff));
+
+ char *temp = strstr(time_str, ",");
+ if(temp)
+ {
+ *temp = ' '; // ',' -> ' '
+
+ temp = strstr(time_str, "+");
+ if(temp == NULL)
+ {
+ temp = strstr(time_str, "-");
+ }
+
+ if(temp)
+ {
+ // Copy +XX or -XX
+ char *last_ptr = temp + strlen(temp) + 1;
+ while(last_ptr > temp)
+ {
+ *last_ptr = *(last_ptr - 1);
+ last_ptr--;
+ }
+
+ *last_ptr = ' ';
+
+ memcpy(temp + strlen(temp), " 00", 3);
+
+ LOGD("%s -> %s", buff, time_str);
+ return MBTK_RIL_ERR_SUCCESS;
+ }
+ else
+ {
+ LOGE("Time error:%s",buff);
+ return MBTK_RIL_ERR_TIME_FORMAT;
+ }
+ }
+ else
+ {
+ LOGE("Time error:%s",buff);
+ return MBTK_RIL_ERR_TIME_FORMAT;
+ }
+ }
+ else
+ {
+ return err;
+ }
+}
+
+/*
+* Get sim state.
+*/
+mbtk_ril_err_enum mbtk_sim_state_get(mbtk_sim_state_enum *sim_state)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(sim_state == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ uint8 result;
+ mbtk_ril_err_enum err = ril_req_process(RIL_MSG_ID_SIM_STATE, NULL, 0, &result, FALSE);
+ *sim_state = (mbtk_sim_state_enum)result;
+ return err;
+}
+
+/*
+* Get sim card type.
+*/
+mbtk_ril_err_enum mbtk_sim_type_get(mbtk_sim_card_type_enum *sim_card_type)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(sim_card_type == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ uint8 result;
+ mbtk_ril_err_enum err = ril_req_process(RIL_MSG_ID_SIM_TYPE, NULL, 0, &result, FALSE);
+ *sim_card_type = (mbtk_sim_card_type_enum)result;
+ return err;
+}
+
+/*
+* Get platform IMSI.
+*/
+mbtk_ril_err_enum mbtk_imsi_get(void *imsi)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(imsi == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_SIM_IMSI, NULL, 0, imsi, FALSE);
+}
+
+/*
+* Get platform ICCID.
+*/
+mbtk_ril_err_enum mbtk_iccid_get(void *iccid)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(iccid == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_SIM_ICCID, NULL, 0, iccid, FALSE);
+}
+
+/*
+* Get current phone number.
+*/
+mbtk_ril_err_enum mbtk_phone_number_get(void *phone_number)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(phone_number == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_SIM_PN, NULL, 0, phone_number, FALSE);
+}
+
+/*
+* Get platform ICCID.
+*/
+mbtk_ril_err_enum mbtk_sim_lock_get(int *lock_state)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(lock_state == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ uint8 result;
+ mbtk_ril_err_enum err = ril_req_process(RIL_MSG_ID_SIM_LOCK, NULL, 0, &result, FALSE);
+ *lock_state = result;
+ return err;
+}
+
+
+/*
+* Get platform ICCID.
+*/
+mbtk_ril_err_enum mbtk_sim_lock_set(mbtk_sim_lock_info_t *lock_info)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(lock_info == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_SIM_LOCK, lock_info, sizeof(mbtk_sim_lock_info_t), NULL, FALSE);
+}
+
+/*
+* Get PIN’s number of remaining retry
+*/
+mbtk_ril_err_enum mbtk_sim_lock_retry_times_get(mbtk_pin_puk_last_times_t *retry_times)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(retry_times == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_SIM_PINPUK_TIMES, NULL, 0, retry_times, FALSE);
+}
+
+/*
+* Get plmn list
+*/
+mbtk_ril_err_enum mbtk_plmn_list_get(mbtk_plmn_info *plmn_list)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(plmn_list == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_SIM_PLMN, NULL, 0, plmn_list, FALSE);
+}
+
+/*
+* Get available network.
+*/
+mbtk_ril_err_enum mbtk_available_net_get(mbtk_net_info_array_t *net_array)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(net_array == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_NET_AVAILABLE, NULL, 0, net_array, FALSE);
+}
+
+/*
+* Set network select mode. (+COPS=...)
+*/
+mbtk_ril_err_enum mbtk_net_sel_mode_set(const mbtk_net_info_t *net)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(net == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_NET_SEL_MODE, net, sizeof(mbtk_net_info_t), NULL, FALSE);
+}
+
+/*
+* Get network select mode. (+COPS?)
+*/
+mbtk_ril_err_enum mbtk_net_sel_mode_get(mbtk_net_info_t *net)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(net == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_NET_SEL_MODE, NULL, 0, net, FALSE);
+}
+
+/*
+* Get platform support bands.
+*/
+mbtk_ril_err_enum mbtk_support_band_get(mbtk_band_info_t *band)
+{
+ uint8 type = 0; // Get support bands.
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(band == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_NET_BAND, &type, sizeof(uint8), band, FALSE);
+}
+
+/*
+* Get platform current bands.
+*/
+mbtk_ril_err_enum mbtk_current_band_get(mbtk_band_info_t *band)
+{
+ uint8 type = 1; // Get current bands.
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(band == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_NET_BAND, &type, sizeof(uint8), band, FALSE);
+}
+
+/*
+* Set platform current bands.
+*/
+mbtk_ril_err_enum mbtk_current_band_set(const mbtk_band_info_t *band)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(band == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_NET_BAND, band, sizeof(mbtk_band_info_t), NULL, FALSE);
+}
+
+/*
+* Get current cell infomation.
+*/
+mbtk_ril_err_enum mbtk_cell_get(mbtk_cell_info_array_t *cell_array)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(cell_array == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_NET_CELL, NULL, 0, cell_array, FALSE);
+}
+/*
+* Set cell info.
+*
+* at*CELL=<mode>,<act>,< band>,<freq>,<cellId>
+* at*cell=2,3,,40936,429 //
+* at*cell=0 //
+*
+* Restarting takes effect after execution.
+*/
+mbtk_ril_err_enum mbtk_cell_set(const mbtk_cell_info_t *cell_info)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(cell_info == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_NET_CELL, cell_info, sizeof(mbtk_cell_info_t), NULL, FALSE);
+}
+
+/*
+* Get current network signal.
+*/
+mbtk_ril_err_enum mbtk_net_signal_get(mbtk_signal_info_t *signal)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(signal == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_NET_SIGNAL, NULL, 0, signal, FALSE);
+}
+
+/*
+* Get current network register information.
+*/
+mbtk_ril_err_enum mbtk_net_reg_get(mbtk_net_reg_info_t *reg)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(reg == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_NET_REG, NULL, 0, reg, FALSE);
+}
+
+/*
+* Get all APN informations.
+*/
+mbtk_ril_err_enum mbtk_apn_get(mbtk_apn_info_array_t *apns)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(apns == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_NET_APN, NULL, 0, apns, FALSE);
+}
+
+
+/*
+* Set current APN informations.
+*/
+mbtk_ril_err_enum mbtk_apn_set(const mbtk_apn_info_t *apn)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(apn == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_NET_APN, apn, sizeof(mbtk_apn_info_t), NULL, FALSE);
+}
+
+/*
+* Start data call.
+*/
+mbtk_ril_err_enum mbtk_data_call_start(mbtk_ril_cid_enum cid, bool auto_boot_call,
+ bool def_route, int retry_interval, int timeout, mbtk_ip_info_t *rsp_info)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ mbtk_data_call_info_t info;
+ memset(&info, 0, sizeof(mbtk_data_call_info_t));
+ info.type = MBTK_DATA_CALL_START;
+ info.auto_boot_call = (uint8)auto_boot_call;
+ info.def_route = (uint8)def_route;
+ info.retry_interval = (uint16)retry_interval;
+ if(timeout > 0) {
+ info.timeout = (uint16)timeout;
+ }
+
+ return ril_req_process(RIL_MSG_ID_NET_DATA_CALL, &info, sizeof(mbtk_data_call_info_t), rsp_info, FALSE);
+}
+
+/*
+* Stop data call.
+*/
+mbtk_ril_err_enum mbtk_data_call_stop(mbtk_ril_cid_enum cid, int timeout)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ mbtk_data_call_info_t info;
+ memset(&info, 0, sizeof(mbtk_data_call_info_t));
+ info.type = MBTK_DATA_CALL_STOP;
+ if(timeout > 0) {
+ info.timeout = (uint16)timeout;
+ }
+ return ril_req_process(RIL_MSG_ID_NET_DATA_CALL, &info, sizeof(mbtk_data_call_info_t), NULL, FALSE);
+}
+
+/*
+* Get data call state.
+*/
+mbtk_ril_err_enum mbtk_data_call_state_get(int cid, mbtk_ip_info_t *ip)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(ip == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ mbtk_data_call_info_t info;
+ memset(&info, 0, sizeof(mbtk_data_call_info_t));
+ info.type = MBTK_DATA_CALL_STATE;
+
+ return ril_req_process(RIL_MSG_ID_NET_DATA_CALL, &info, sizeof(mbtk_data_call_info_t), ip, FALSE);
+}
+
+/*
+* Return sms cmgf.
+*/
+mbtk_ril_err_enum mbtk_sms_cmgf_get(int *sms_state)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(sms_state == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ uint8 state;
+ mbtk_ril_err_enum err = ril_req_process(RIL_MSG_ID_SMS_CMGF, NULL, 0, &state, FALSE);
+ *sms_state = state;
+ return err;
+}
+
+/*
+* Set sms cmgf.
+*
+* volte_state:
+* 0 : PDU mode.
+* 1 : text mode.
+*
+* Restarting takes effect after execution.
+*/
+mbtk_ril_err_enum mbtk_sms_cmgf_set(int mode)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ return ril_req_process(RIL_MSG_ID_SMS_CMGF, &mode, sizeof(uint8), NULL, FALSE);
+}
+
+/*
+* Set sms cmgs.
+*
+if PDU mode (+CMGF=0):
++CMGS=<length><CR>
+PDU is given<ctrl-Z/ESC>
+
+if text mode (+CMGF=1):
++CMGS=<da>[,<toda>]<CR>
+text is entered<ctrl-Z/ESC>
+
+* Restarting takes effect after execution.
+*/
+mbtk_ril_err_enum mbtk_sms_cmgs_set(char * cmgs, char *resp)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(cmgs == NULL || resp == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_SMS_CMGS, cmgs, strlen(cmgs), resp, FALSE);
+}
+
+/*
+* Set sms cmgw.
+*
+if text mode (+CMGF=1):
++CMGW=<oa/da>[,<tooa/toda>[,<stat>]]
+<CR>
+text is entered<ctrl-Z/ESC>
+if PDU mode (+CMGF=0):
++CMGW=<length>[,<stat>]<CR>PDU is
+given<ctrl-Z/ESC>
+
+*/
+mbtk_ril_err_enum mbtk_sms_cmgw_set(char * cmgw, char *resp)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(cmgw == NULL || resp == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_SMS_CMGW, cmgw, strlen(cmgw), resp, FALSE);
+}
+
+/*
+* Set sms cmgd.
+*
+* +CMGD=<index>[,<delflag>]
+*
+* Restarting takes effect after execution.
+*/
+mbtk_ril_err_enum mbtk_sms_cmgd_set(char * cmdg)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(cmdg == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_SMS_CMGD, cmdg, strlen(cmdg), NULL, FALSE);
+}
+
+/*
+* Get sms cmgd.
+*
+* +CMGD: (XXX,XXX)(0-4)
+*
+* Restarting takes effect after execution.
+*/
+mbtk_ril_err_enum mbtk_sms_cmgd_get(char * cmdg)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(cmdg == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_SMS_CMGD, NULL, 0, cmdg, FALSE);
+}
+
+
+/*
+* Set sms cmgl.
+*
+* AT+CMGL[=<stat>]
+*
+* Restarting takes effect after execution.
+*/
+mbtk_ril_err_enum mbtk_sms_cmgl_set(char * cmgl, char *resp)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(cmgl == NULL || resp == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_SMS_CMGL, cmgl, strlen(cmgl), resp, FALSE);
+}
+
+/*
+* Return sms csca.
+*/
+mbtk_ril_err_enum mbtk_sms_csca_get(char *buf)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(buf == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_SMS_CSCA, NULL, 0, buf, FALSE);
+}
+
+/*
+* Set sms csca.
+*
+* AT+CSCA=<number> [,<type>]
+*
+* Restarting takes effect after execution.
+*/
+mbtk_ril_err_enum mbtk_sms_csca_set(char * csca)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(csca == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_SMS_CSCA, csca, strlen(csca), NULL, FALSE);
+}
+
+/*
+* Set sms csmp.
+*
+* AT+CSMP=[<fo>[,<vp>[,<pid>[,<dcs>]]]]
+*
+* Restarting takes effect after execution.
+*/
+mbtk_ril_err_enum mbtk_sms_csmp_set(char * csmp)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(csmp == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_SMS_CSMP, csmp, strlen(csmp), NULL, FALSE);
+}
+
+/*
+* Set sms cscb.
+*
+* AT+CSCB=<[<mode>[,<mids>[,<dcss>]]]>
+*
+* Restarting takes effect after execution.
+*/
+mbtk_ril_err_enum mbtk_sms_cscb_set(char * cscb)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(cscb == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_SMS_CSCB, cscb, strlen(cscb), NULL, FALSE);
+}
+
+/*
+* Set sms cnmi.
+*
+at+cnmi=1,2
+
+OK
+if sending fails:
++CMS ERROR: <err>
+*/
+mbtk_ril_err_enum mbtk_sms_cnmi_set()
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ return ril_req_process(RIL_MSG_ID_SMS_CNMI, NULL, 0, NULL, FALSE);
+}
+
+/*
+* Set sms cmss.
+*
++CMSS=<index>[,<da>[,<toda>]]
+
+if sending successful:
++CMSS: <mr>
+OK
+if sending fails:
++CMS ERROR: <err>
+*/
+mbtk_ril_err_enum mbtk_sms_cmss_set(char * cmss, char *resp)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(cmss == NULL || resp == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_SMS_CMSS, cmss, strlen(cmss), resp, FALSE);
+}
+
+/*
+* Return sms cmgf.
+*/
+mbtk_ril_err_enum mbtk_sms_cpms_get(char * mem)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(mem == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_SMS_CPMS, NULL, 0, mem, FALSE);
+}
+
+
+/*
+* Set sms cpms.
+*
+* AT+CPMS=<mem1>[,<mem2>[,<mem3>]]
+*
+* Restarting takes effect after execution.
+*/
+mbtk_ril_err_enum mbtk_sms_cpms_set(char * mem, char* resp)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(mem == NULL || resp == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_SMS_CPMS, mem, strlen(mem), resp, FALSE);
+}
+
+/*
+* Set sms cm.
+*
+* +CMGR=<index>
+
+if PDU mode (+CMGF=0) ��command successful:
++CMGR: <stat>,[<alpha>],<length><CR><LF><pdu>
+OK
+if text mode (+CMGF=1), command successful and SMS-DELIVER:
++CMGR:<stat>,<oa>,[<alpha>],<scts>[,<tooa>,<fo>,<pid>,<dcs
+>, <sca>,<tosca>,<length>]<CR><LF><data>
+OK
+if text mode (+CMGF=1), command successful and SMS-SUBMIT:
++CMGR:
+<stat>,<da>,[<alpha>][,<toda>,<fo>,<pid>,<dcs>,[<vp>],
+<sca>,<tosca>,<length>]<CR><LF><data>
+OK
+otherwise:
++CMS ERROR: <err>
+*
+* Restarting takes effect after execution.
+*/
+mbtk_ril_err_enum mbtk_sms_cmgr_set(int index, char *resp)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(resp == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_SMS_CMGR, &index, sizeof(uint8), resp, FALSE);
+}
+
+
+#if 0
+
+/*
+* Set sim power state.
+* power:
+* 0: Sim power off.
+* 1: Sim power on.
+*/
+int mbtk_sim_power_set(int power)
+{
+ if(power != 0 && power != 1)
+ {
+ return -1;
+ }
+
+ // /sys/devices/virtual/usim_event/usim0/send_event
+ char cmd[100] = {0};
+ sprintf(cmd, "echo %d > /sys/devices/virtual/usim_event/usim0/send_event", power ? 0 : 1);
+ system(cmd);
+
+ return 0;
+}
+
+/*
+* System power.
+* type:
+* 0: Reboot system.
+* 1: Poweroff system.
+* 2: Halt system.
+*/
+int mbtk_system_reboot(int type)
+{
+ if(type != 0 && type != 1 && type != 2)
+ {
+ return -1;
+ }
+
+ switch(type)
+ {
+ case 0:
+ {
+ system("reboot");
+ break;
+ }
+ case 1:
+ {
+ system("poweroff");
+ break;
+ }
+ case 2:
+ {
+ system("halt");
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ return 0;
+}
+
+/*
+* Get time type.
+*/
+int mbtk_time_get(mbtk_info_handle_t* handle, int *time_type)
+{
+ uint8 state;
+ if(handle == NULL || time_type == NULL)
+ {
+ LOGE("ARG error.");
+ return -1;
+ }
+ if(info_item_process(handle, MBTK_INFO_ID_DEV_TIME_REQ, NULL, 0, &state) > 0)
+ {
+ LOG("Time type : %d", state);
+ *time_type = state;
+ return 0;
+ }
+ else
+ {
+ return handle->info_err;
+ }
+}
+
+/*
+*Get Absolute time
+*"23/05/24 06:09:32 +32 00"
+*/
+int mbtk_get_abs_time(char *time_str, time_t *time_out)
+{
+ struct tm tm_;
+
+ char *ptr = strstr(time_str + 10, " ");
+ *ptr = '\0';
+
+ LOGD("time : \"%s\"", time_str);
+#if 1
+ if(strptime(time_str, "%y/%m/%d %T", &tm_) == NULL)
+ {
+ LOGE("strptime() fail.");
+ return -1;
+ }
+#else
+ int year, month, day, hour, minute,second,time_zone;
+ if(strstr(time_str, "+"))
+ {
+ sscanf(time_str, "%d/%d/%d %d:%d:%d +%d",&year,&month,&day,&hour,&minute,&second,&time_zone);
+ }
+ else if(strstr(time_str, "-"))
+ {
+ sscanf(time_str, "%d/%d/%d %d:%d:%d -%d",&year,&month,&day,&hour,&minute,&second,&time_zone);
+ }
+ else
+ {
+ LOGE("Time format error:%s", time_str);
+ return -1;
+ }
+
+ // 1970+
+ if(year < 70) // 20xx
+ {
+ tm_.tm_year = 2000 + year;
+ }
+ else // 19xx
+ {
+ tm_.tm_year = 1900 + year;
+ }
+ tm_.tm_mon = month - 1;
+ tm_.tm_mday = day;
+ tm_.tm_hour = hour;
+ tm_.tm_min = minute;
+ tm_.tm_sec = second;
+ tm_.tm_isdst = 0;
+#endif
+
+ time_t timeStamp = mktime(&tm_);
+ LOGD("tm_.tm_year = %d,tm_.tm_mon = %d,tm_.tm_mday = %d,tm_.tm_hour = %d,tm_.tm_min = %d,tm_.tm_sec = %d,tm_.tm_isdst = %d",tm_.tm_year,tm_.tm_mon,tm_.tm_mday,tm_.tm_hour,tm_.tm_min,tm_.tm_sec,tm_.tm_isdst);
+ LOGD("time = %ld,%x", timeStamp,timeStamp);
+ *time_out = timeStamp;
+
+ return 0;
+}
+
+/*
+* Set time.
+*
+* time_type:
+* 0: Cell time
+* 1: NTP time
+* 2: User time
+* time_str: "YYYY-MM-DD HH:MM:SS"
+*/
+int mbtk_time_set(mbtk_info_handle_t* handle, mbtk_time_type_enum time_type, char* time_str)
+{
+ if(handle == NULL)
+ {
+ LOGE("ARG error.");
+ return -1;
+ }
+ uint8 buffer[100] = {0};
+ buffer[0] = (uint8)time_type;
+ if(time_type == MBTK_TIME_TYPE_USER)
+ {
+ if(!str_empty(time_str))
+ {
+ memcpy(buffer + sizeof(uint8), time_str, strlen(time_str));
+ return info_item_process(handle, MBTK_INFO_ID_DEV_TIME_REQ,
+ buffer, sizeof(uint8) + strlen(time_str), NULL) ? handle->info_err : 0;
+ }
+ else
+ {
+ return -1;
+ }
+ }
+ else
+ {
+ return info_item_process(handle, MBTK_INFO_ID_DEV_TIME_REQ,
+ buffer, sizeof(uint8), NULL) ? handle->info_err : 0;
+ }
+}
+
+
+#endif
+
+/*
+* call_start
+*
+*/
+mbtk_ril_err_enum mbtk_call_start(char* phone_number)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(phone_number == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_CALL_START, phone_number, strlen(phone_number), NULL, FALSE);
+}
+
+/*
+* Answer the phone call.
+*
+*/
+mbtk_ril_err_enum mbtk_call_answer()
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ return ril_req_process(RIL_MSG_ID_CALL_ANSWER, NULL, 0, NULL, FALSE);
+}
+
+/*
+* Hang up all call.
+*
+*/
+mbtk_ril_err_enum mbtk_call_hang()
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ return ril_req_process(RIL_MSG_ID_CALL_HANGUP, NULL, 0, NULL, FALSE);
+}
+
+/*
+* Hang up a call.
+*
+*/
+mbtk_ril_err_enum mbtk_a_call_hang(int phone_id)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ return ril_req_process(RIL_MSG_ID_CALL_HANGUP_A, &phone_id, sizeof(uint8), NULL, FALSE);
+}
+
+/*
+* Hang up waiting or background call.
+*
+*/
+mbtk_ril_err_enum mbtk_waiting_or_background_call_hang()
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ return ril_req_process(RIL_MSG_ID_CALL_HANGUP_B, NULL, 0, NULL, FALSE);
+}
+
+/*
+* Hang up foreground resume background call.
+*
+*/
+mbtk_ril_err_enum mbtk_foreground_resume_background_call_hang()
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ return ril_req_process(RIL_MSG_ID_CALL_HANGUP_C, NULL, 0, NULL, FALSE);
+}
+
+/*
+* Get current call phone number.
+*/
+mbtk_ril_err_enum mbtk_call_reg_get(mbtk_call_info_t *reg)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(reg == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_CALL_WAITIN, NULL, 0, reg, FALSE);
+}
+
+/*
+* Return mute state.
+*/
+mbtk_ril_err_enum mbtk_mute_state_get(int *mute_state)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(mute_state == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_CALL_MUTE, NULL, 0, mute_state, FALSE);
+}
+
+/*
+* Set mute state.
+*
+* mute_state:
+* 0 : of mute.
+* 1 : on mute.
+*
+* Restarting takes effect after execution.
+*/
+mbtk_ril_err_enum mbtk_mute_state_set(int mute_state)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ return ril_req_process(RIL_MSG_ID_CALL_MUTE, &mute_state, sizeof(uint8), NULL, FALSE);
+}
+
+/*
+* Set DTMF character.
+*
+*/
+mbtk_ril_err_enum mbtk_dtmf_send(mbtk_call_dtmf_info_t *dtmf_character)
+{
+ if(!ril_cli.ril_ready)
+ {
+ return MBTK_RIL_ERR_NOT_INIT;
+ }
+
+ if(dtmf_character == NULL)
+ {
+ LOGE("ARG error.");
+ return MBTK_RIL_ERR_PARAMETER;
+ }
+
+ return ril_req_process(RIL_MSG_ID_CALL_DTMF, dtmf_character, sizeof(mbtk_call_dtmf_info_t), NULL, FALSE);
+}
+
+
+#if 0
+/*
+* Set wakeup state.
+*
+* wakeup_state:(0~31)
+* 0 : means resume all
+* 1~31 means suspend
+* Control the active reporting of some platform modems to reduce wakeup
+*/
+
+int mbtk_wakeup_state_set(mbtk_info_handle_t* handle, uint32 wakeup_state)
+{
+ return info_item_process(handle, MBTK_INFO_ID_WAKEUP_STA_REQ, (uint32*)&wakeup_state, sizeof(uint32), NULL) ? handle->info_err : 0;
+}
+
+/*
+* oos get.
+*/
+int mbtk_oos_get(mbtk_info_handle_t* handle, mbtk_oos_info *oos_info)
+{
+ if(info_item_process(handle, MBTK_INFO_ID_OOS_STA_REQ, NULL, 0, oos_info) > 0)
+ {
+ return 0;
+ }
+ else
+ {
+ return handle->info_err;
+ }
+}
+
+/*
+* oos set .
+*/
+int mbtk_oos_set(mbtk_info_handle_t* handle, mbtk_oos_info *oos_info)
+{
+ if(handle == NULL)
+ {
+ LOGE("ARG error.");
+ return -1;
+ }
+
+ return info_item_process(handle, MBTK_INFO_ID_OOS_STA_REQ, oos_info, sizeof(mbtk_oos_info), NULL) ? handle->info_err : 0;
+}
+
+
+#endif
+
+#if 0
+/*
+* Set pdp state change callback function.
+*/
+int mbtk_pdp_state_change_cb_reg(mbtk_info_handle_t* handle, mbtk_info_callback_func cb)
+{
+ if(handle == NULL)
+ {
+ LOGE("ARG error.");
+ return -1;
+ }
+ if(info_item_process(handle, MBTK_INFO_ID_IND_PDP_STATE_CHANGE, NULL, 0, NULL) < 0)
+ {
+ return handle->info_err;
+ }
+ else
+ {
+ handle->pdp_state_cb = cb;
+ return 0;
+ }
+}
+
+/*
+* Set network state change callback function.
+*/
+int mbtk_net_state_change_cb_reg(mbtk_info_handle_t* handle, mbtk_info_callback_func cb)
+{
+ if(handle == NULL)
+ {
+ LOGE("ARG error.");
+ return -1;
+ }
+ if(info_item_process(handle, MBTK_INFO_ID_IND_NET_STATE_CHANGE, NULL, 0, NULL) < 0)
+ {
+ return handle->info_err;
+ }
+ else
+ {
+ handle->net_state_cb = cb;
+ return 0;
+ }
+}
+
+/*
+* Set call state change callback function.
+*/
+int mbtk_call_state_change_cb_reg(mbtk_info_handle_t* handle, mbtk_info_callback_func cb)
+{
+ if(handle == NULL)
+ {
+ LOGE("ARG error.");
+ return -1;
+ }
+ if(info_item_process(handle, MBTK_INFO_ID_IND_CALL_STATE_CHANGE, NULL, 0, NULL) < 0)
+ {
+ return handle->info_err;
+ }
+ else
+ {
+ handle->call_state_cb = cb;
+ return 0;
+ }
+}
+
+/*
+* Set sms state change callback function.
+*/
+int mbtk_sms_state_change_cb_reg(mbtk_info_handle_t* handle, mbtk_info_callback_func cb)
+{
+ if(handle == NULL)
+ {
+ LOGE("ARG error.");
+ return -1;
+ }
+ if(info_item_process(handle, MBTK_INFO_ID_IND_SMS_STATE_CHANGE, NULL, 0, NULL) < 0)
+ {
+ return handle->info_err;
+ }
+ else
+ {
+ handle->sms_state_cb = cb;
+ return 0;
+ }
+}
+
+/*
+* Set radio state change callback function.
+*/
+int mbtk_radio_state_change_cb_reg(mbtk_info_handle_t* handle, mbtk_info_callback_func cb)
+{
+ if(handle == NULL)
+ {
+ LOGE("ARG error.");
+ return -1;
+ }
+ if(info_item_process(handle, MBTK_INFO_ID_IND_RADIO_STATE_CHANGE, NULL, 0, NULL) < 0)
+ {
+ return handle->info_err;
+ }
+ else
+ {
+ handle->radio_state_cb = cb;
+ return 0;
+ }
+}
+
+/*
+* Set sim state change callback function.
+*/
+int mbtk_sim_state_change_cb_reg(mbtk_info_handle_t* handle, mbtk_info_callback_func cb)
+{
+ if(handle == NULL)
+ {
+ LOGE("ARG error.");
+ return -1;
+ }
+ if(info_item_process(handle, MBTK_INFO_ID_IND_SIM_STATE_CHANGE, NULL, 0, NULL) < 0)
+ {
+ return handle->info_err;
+ }
+ else
+ {
+ handle->sim_state_cb = cb;
+ return 0;
+ }
+}
+
+/*
+* Set signal state change callback function.
+*/
+int mbtk_signal_state_change_cb_reg(mbtk_info_handle_t* handle, mbtk_info_callback_func cb)
+{
+ if(handle == NULL)
+ {
+ LOGE("ARG error.");
+ return -1;
+ }
+ if(info_item_process(handle, MBTK_INFO_ID_IND_SIGNAL_STATE_CHANGE, NULL, 0, NULL) < 0)
+ {
+ return handle->info_err;
+ }
+ else
+ {
+ handle->signal_state_cb = cb;
+ return 0;
+ }
+}
+#endif
diff --git a/mbtk/libmbtk_ril_v2/src/ril_utils.c b/mbtk/libmbtk_ril_v2/src/ril_utils.c
new file mode 100755
index 0000000..f71b2dd
--- /dev/null
+++ b/mbtk/libmbtk_ril_v2/src/ril_utils.c
@@ -0,0 +1,556 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <string.h>
+
+#include "mbtk_ril.h"
+#include "mbtk_list.h"
+#include "mbtk_utils.h"
+
+static uint16 ril_index = 1;
+
+static int sock_read(int fd, uint8 *msg, int data_len)
+{
+ memset(msg, 0, data_len);
+ int len = 0;
+ int read_len = 0;
+ while(1)
+ {
+ len = read(fd, msg + read_len, data_len - read_len);
+ if(len > 0)
+ {
+ read_len += len;
+ }
+ else if(len == 0)
+ {
+ LOG("read() end.");
+ break;
+ }
+ else
+ {
+ if(EAGAIN == errno)
+ {
+ LOG("Read end, lenght = %d", read_len);
+ }
+ else
+ {
+ LOG("read() error[%d].", errno);
+ }
+ break;
+ }
+ }
+
+ if(read_len > 0)
+ {
+ log_hex("DATA_RECV", msg, read_len);
+ return read_len;
+ }
+ else
+ {
+ return -1;
+ }
+}
+
+static int sock_write(int fd, uint8 *msg, int data_len)
+{
+ int len = 0;
+ int write_len = 0;
+ while(write_len < data_len)
+ {
+ len = write(fd, msg + write_len, data_len - write_len);
+ if(len > 0)
+ {
+ write_len += len;
+ }
+ else if(len == 0)
+ {
+ LOG("write() end.");
+ break;
+ }
+ else
+ {
+ LOG("write() error[%d].", errno);
+ break;
+ }
+ }
+
+ if(write_len > 0)
+ {
+ // log_hex("DATA_SEND", msg, write_len);
+ return write_len;
+ }
+ else
+ {
+ return -1;
+ }
+}
+
+static int pack_num_check(const void* data, int data_len)
+{
+ int count = 0;
+ int pack_len;
+ const uint8* ptr = (const uint8*)data;
+ while(ptr < (const uint8*)data + data_len)
+ {
+ if(RIL_SOCK_PACKET_TAG != byte_2_uint32(ptr, false))
+ {
+ LOG("pack_num_check() - TAG error.");
+ break;
+ }
+ ptr += sizeof(uint32);
+
+ pack_len = byte_2_uint16(ptr, false);
+ if(pack_len < RIL_SOCK_PACK_LEN_MIN - RIL_SOCK_PACK_EXTRA_LEN)
+ {
+ LOG("pack_num_check() - Packet length error.");
+ break;
+ }
+ ptr += sizeof(uint16);
+ ptr += pack_len;
+
+ count++;
+ }
+
+ return count;
+}
+
+char* type2str(ril_msg_type_enum type)
+{
+ switch(type)
+ {
+ case RIL_MSG_TYPE_REQ:
+ return "REQ";
+ case RIL_MSG_TYPE_RSP:
+ return "RSP";
+ case RIL_MSG_TYPE_IND:
+ return "IND";
+ default:
+ {
+ return "UNKNOWN";
+ }
+ }
+}
+
+char* apn2str(mbtk_ip_type_enum type)
+{
+ switch(type)
+ {
+ case MBTK_IP_TYPE_IP:
+ return "IP";
+ case MBTK_IP_TYPE_IPV6:
+ return "IPV6";
+ case MBTK_IP_TYPE_IPV4V6:
+ return "IPV4V6";
+ case MBTK_IP_TYPE_PPP:
+ return "PPP";
+ default:
+ {
+ return "UNKNOWN";
+ }
+ }
+}
+
+/*
+IPv6 : 254.128.0.0.0.0.0.0.0.1.0.2.144.5.212.239 -> uint128
+*/
+int str_2_ipv6(const void *ip_str, void *ipv6)
+{
+ const uint8 *ptr = (const uint8*)ip_str;
+ uint8 *ipv6_ptr = (uint8*)ipv6;
+ ipv6_ptr[0] = (uint8)atoi(ptr);
+ int i = 1;
+ while(i < 16) {
+ ptr = (const uint8*)strstr(ptr, ".");
+ if(ptr == NULL)
+ return -1;
+ ptr++;
+ ipv6_ptr[i] = (uint8)atoi(ptr);
+ i++;
+ }
+
+ return 0;
+}
+
+/*
+IPv6 : uint128 -> fe80::215:1dff:fe81:484c
+*/
+int ipv6_2_str(const void *ipv6, void *ipv6_str)
+{
+ const uint8 *ptr = (const uint8*)ipv6;
+ uint8 *ipv6_ptr = (uint8*)ipv6_str;
+ int i = 0;
+ int index = 0;
+ while(i < 16) {
+ index += sprintf(ipv6_ptr + index, "%02x%02x", ptr[i], ptr[i + 1]);
+ index += sprintf(ipv6_ptr + index, ":");
+ i += 2;
+ }
+
+ ipv6_ptr[index - 1] = '\0'; // Delete last ':'
+
+ return 0;
+}
+
+
+
+char* id2str(int id)
+{
+ switch(id)
+ {
+ // <string> IMEI
+ case RIL_MSG_ID_DEV_IMEI:
+ return "IMEI";
+ // <string> SN
+ case RIL_MSG_ID_DEV_SN:
+ return "SN";
+ // <string> MEID
+ case RIL_MSG_ID_DEV_MEID:
+ return "MEID";
+ // <string> VERSION
+ case RIL_MSG_ID_DEV_VERSION:
+ return "VERSION";
+ case RIL_MSG_ID_DEV_MODEL:
+ return "MODEL";
+ // <uint8> 0:Close 1:Open
+ case RIL_MSG_ID_DEV_VOLTE:
+ return "VOLTE";
+ // <string> Temperature
+ case RIL_MSG_ID_DEV_TEMP: // Temperature
+ return "TEMPERATURE";
+ case RIL_MSG_ID_DEV_CELL_TIME:
+ return "CELL_TIME";
+ case RIL_MSG_ID_DEV_MODEM:
+ return "MODEM";
+
+ // Sim Information
+
+ // <uint8> 0:NOT_EXIST 1:READY ...
+ case RIL_MSG_ID_SIM_STATE:
+ return "SIM_STATE";
+ case RIL_MSG_ID_SIM_TYPE:
+ return "SIM_TYPE";
+ // <string> IMSI
+ case RIL_MSG_ID_SIM_IMSI:
+ return "IMSI";
+ // <string> ICCID
+ case RIL_MSG_ID_SIM_ICCID:
+ return "ICCID";
+ // <string> Phone Number
+ case RIL_MSG_ID_SIM_PN:
+ return "PHONE_NUMBER";
+ case RIL_MSG_ID_SIM_LOCK:
+ return "SIM_LOCK";
+ case RIL_MSG_ID_SIM_PINPUK_TIMES:
+ return "SIM_PINPUK_TIMES";
+ case RIL_MSG_ID_SIM_PLMN:
+ return "SIM_PLMN";
+ case RIL_MSG_ID_NET_AVAILABLE:
+ return "NET_AVAILABLE";
+ case RIL_MSG_ID_NET_SEL_MODE:
+ return "NET_SEL_MODE";
+ case RIL_MSG_ID_NET_BAND:
+ return "NET_BNAD";
+ // <uint16>[4] rssi,rscp,rsrp,snr
+ case RIL_MSG_ID_NET_SIGNAL:
+ return "SIGNAL";
+ case RIL_MSG_ID_NET_REG:
+ return "NET_REG";
+ // <string> cmnet/ctnet/3gnet/...
+ case RIL_MSG_ID_NET_APN:
+ return "APN";
+ // Lock net/cell/frequency
+ case RIL_MSG_ID_NET_CELL:
+ return "NET_CELL";
+ case RIL_MSG_ID_NET_DATA_CALL:
+ return "DATA_CALL";
+ // Call Information
+ case RIL_MSG_ID_CALL_STATE:
+ return "CALL_STATE";
+ // SMS Information
+ case RIL_MSG_ID_SMS_STATE:
+ return "SMS_STATE";
+ // PhoneBook Information
+ case RIL_MSG_ID_PB_STATE:
+ return "PB_STATE";
+ // IND Information
+ // <uint8> State
+ case RIL_MSG_ID_IND_SER_READY:
+ return "IND_SER_READY";
+ // <uint8> State
+ case RIL_MSG_ID_IND_NET_STATE_CHANGE:
+ return "IND_NET_STATE";
+ // <uint8> State
+ case RIL_MSG_ID_IND_CALL_STATE_CHANGE:
+ return "IND_CALL_STATE";
+ // <uint8> State
+ case RIL_MSG_ID_IND_SMS_STATE_CHANGE:
+ return "IND_SMS_STATE";
+ // <uint8> State
+ case RIL_MSG_ID_IND_RADIO_STATE_CHANGE:
+ return "IND_RADIO_STATE";
+ // <uint8> State
+ case RIL_MSG_ID_IND_SIM_STATE_CHANGE:
+ return "IND_SIM_STATE";
+ // <uint8> State
+ case RIL_MSG_ID_IND_PDP_STATE_CHANGE:
+ return "IND_PDP_STATE";
+ // <uint8> State
+ case RIL_MSG_ID_IND_SIGNAL_STATE_CHANGE:
+ return "IND_SIGNAL_STATE";
+ default:
+ {
+ return "UNKNOWN";
+ }
+ }
+}
+
+char* err2str(mbtk_ril_err_enum err)
+{
+ switch(err)
+ {
+ case MBTK_RIL_ERR_SUCCESS:
+ return "SUCCESS";
+ case MBTK_RIL_ERR_FORMAT:
+ return "ERR_FORMAT";
+ case MBTK_RIL_ERR_REQ_UNKNOWN:
+ return "ERR_REQ_UNKNOWN";
+ case MBTK_RIL_ERR_REQ_PARAMETER:
+ return "ERR_REQ_PARAMETER";
+ case MBTK_RIL_ERR_UNSUPPORTED:
+ return "ERR_UNSUPPORTED";
+ case MBTK_RIL_ERR_MEMORY:
+ return "ERR_MEMORY";
+ case MBTK_RIL_ERR_IND_FULL:
+ return "ERR_IND_FULL";
+ case MBTK_RIL_ERR_IND_UNKNOWN:
+ return "ERR_IND_UNKNOWN";
+ default:
+ {
+ if(err >= MBTK_RIL_ERR_CME) {
+ return "CME ERROR";
+ }
+
+ return "UNKNOWN";
+ }
+ }
+}
+
+void *mbtk_memcpy(const void *src, unsigned int n)
+{
+ void *dest = malloc(n);
+ if(dest) {
+ return memcpy(dest, src, n);
+ } else {
+ return NULL;
+ }
+}
+
+/*
+0 GSM
+1 GSM_COMPACT
+2 UTRAN
+3 GSM_EGPRS
+4 UTRAN_HSDPA
+5 UTRAN_HSUPA
+6 UTRAN_HSDPA_HSUPA
+7 EUTRAN
+8 ECGSM
+*/
+mbtk_net_type_enum mbtk_net_type_get(mbtk_radio_technology_enum radio_tech)
+{
+ switch(radio_tech)
+ {
+ case MBTK_RADIO_TECH_GSM:
+ case MBTK_RADIO_TECH_GSM_COMPACT:
+ case MBTK_RADIO_TECH_GSM_EGPRS:
+ case MBTK_RADIO_TECH_UTRAN_HSPA:
+ {
+ return MBTK_NET_TYPE_GSM;
+ }
+ case MBTK_RADIO_TECH_UTRAN:
+ case MBTK_RADIO_TECH_UTRAN_HSDPA:
+ case MBTK_RADIO_TECH_UTRAN_HSUPA:
+ case MBTK_RADIO_TECH_UTRAN_HSDPA_HSUPA:
+ {
+ return MBTK_NET_TYPE_UMTS;
+ }
+ case MBTK_RADIO_TECH_E_UTRAN:
+ {
+ return MBTK_NET_TYPE_LTE;
+ }
+ default:
+ {
+ return MBTK_NET_TYPE_UNKNOWN;
+ }
+ }
+}
+
+void ril_msg_pack_free(ril_msg_pack_info_t* pack)
+{
+ if(pack) {
+ LOGV("Free msg pack - %s", id2str(pack->msg_id));
+ if(pack->data) {
+ free(pack->data);
+ }
+ free(pack);
+ }
+}
+
+ril_msg_pack_info_t* ril_msg_pack_creat(int msg_type, int msg_id, int msg_index, const void *data, int data_len)
+{
+ ril_msg_pack_info_t *pack = (ril_msg_pack_info_t *)malloc(sizeof(ril_msg_pack_info_t));
+ if(!pack)
+ {
+ LOGE("malloc() error[%d]", errno);
+ return NULL;
+ }
+
+ pack->tag = RIL_SOCK_PACKET_TAG;
+
+ if(msg_index < 0) {
+ pack->msg_index = ril_index++;
+ } else {
+ pack->msg_index = msg_index;
+ }
+ pack->msg_type = (uint16)msg_type;
+ pack->msg_id = (uint16)msg_id;
+ pack->err = (uint16)0;
+ if(data && data_len > 0) {
+ pack->msg_len = data_len + RIL_SOCK_PACK_LEN_MIN - RIL_SOCK_PACK_EXTRA_LEN;
+ pack->data_len = (uint16)data_len;
+ pack->data = (uint8*)malloc(data_len);
+ if(pack->data == NULL) {
+ LOGE("malloc(%d) fail.", data_len);
+ free(pack);
+ return NULL;
+ }
+ memcpy(pack->data, data, data_len);
+ } else {
+ pack->msg_len = RIL_SOCK_PACK_LEN_MIN - RIL_SOCK_PACK_EXTRA_LEN;
+ pack->data_len = (uint16)0;
+ pack->data = NULL;
+ }
+
+ return pack;
+}
+
+int ril_pack_send(int fd, ril_msg_pack_info_t *pack)
+{
+ if(!pack)
+ {
+ LOG("Packet is NULL.");
+ return -1;
+ }
+
+ uint8 buff[RIL_SOCK_MSG_LEN_MAX] = {0};
+ if(pack->data && pack->data_len > 0) {
+ memcpy(buff, pack, RIL_SOCK_PACK_LEN_MIN);
+ memcpy(buff + RIL_SOCK_PACK_LEN_MIN, pack->data, pack->data_len);
+ return sock_write(fd, buff, RIL_SOCK_PACK_LEN_MIN + pack->data_len);
+ } else {
+ memcpy(buff, pack, RIL_SOCK_PACK_LEN_MIN);
+ return sock_write(fd, buff, RIL_SOCK_PACK_LEN_MIN);
+ }
+}
+
+ril_msg_pack_info_t** ril_pack_recv(int fd, bool is_server, mbtk_ril_err_enum *err)
+{
+ uint8 msg[RIL_SOCK_MSG_LEN_MAX + 1];
+ *err = MBTK_RIL_ERR_SUCCESS;
+ int len = sock_read(fd, msg, RIL_SOCK_MSG_LEN_MAX + 1);
+ if(len < RIL_SOCK_PACK_LEN_MIN)
+ {
+ if(len > 0)
+ {
+ *err = MBTK_RIL_ERR_FORMAT;
+ LOGE("Insufficient packet data.");
+ }
+ return NULL;
+ }
+
+ int pack_count = pack_num_check(msg, len);
+ LOGD("Packet number : %d", pack_count);
+ if(pack_count < 1)
+ {
+ *err = MBTK_RIL_ERR_FORMAT;
+ LOGE("Packet not found.");
+ return NULL;
+ }
+ uint8 *ptr = msg;
+ ril_msg_pack_info_t** packs = (ril_msg_pack_info_t**)malloc(sizeof(ril_msg_pack_info_t*) * (pack_count + 1));
+ int i = 0;
+ while(i < pack_count)
+ {
+ packs[i] = (ril_msg_pack_info_t*)malloc(sizeof(ril_msg_pack_info_t));
+ if(packs[i] == NULL){
+ *err = MBTK_RIL_ERR_MEMORY;
+ goto error;
+ }
+ memcpy(packs[i], ptr, RIL_SOCK_PACK_LEN_MIN);
+
+ // TAG
+ if(RIL_SOCK_PACKET_TAG != packs[i]->tag)
+ {
+ *err = MBTK_RIL_ERR_FORMAT;
+ LOGE("Packet TAG error.");
+ goto error;
+ }
+
+ if(is_server)
+ {
+ // For server,"info_type" must by REQ or IND(Register IND).
+ if(packs[i]->msg_type != RIL_MSG_TYPE_REQ && packs[i]->msg_type != RIL_MSG_TYPE_IND)
+ {
+ *err = MBTK_RIL_ERR_FORMAT;
+ LOGE("Packet Type error : %d", packs[i]->msg_type);
+ goto error;
+ }
+ }
+ else
+ {
+ // For client,"info_type" must by RSP or IND.
+ if(packs[i]->msg_type != RIL_MSG_TYPE_RSP && packs[i]->msg_type != RIL_MSG_TYPE_IND)
+ {
+ *err = MBTK_RIL_ERR_FORMAT;
+ LOG("Packet Type error.");
+ goto error;
+ }
+ }
+
+ ptr += RIL_SOCK_PACK_LEN_MIN;
+ if(packs[i]->data_len > 0) {
+ packs[i]->data = (uint8*)malloc(packs[i]->data_len);
+ if(packs[i]->data == NULL) {
+ *err = MBTK_RIL_ERR_MEMORY;
+ goto error;
+ }
+ memcpy(packs[i]->data, ptr, packs[i]->data_len);
+ ptr += packs[i]->data_len;
+ } else {
+ packs[i]->data = NULL;
+ }
+
+ i++;
+ }
+ packs[i] = NULL;
+
+ return packs;
+
+error:
+ LOGD("mbtk_ril_pack_recv error, will free().");
+ if(packs)
+ {
+ ril_msg_pack_info_t** pack_ptr = packs;
+ while(*pack_ptr)
+ {
+ ril_msg_pack_free(*pack_ptr);
+ pack_ptr++;
+ }
+
+ free(packs);
+ }
+ return NULL;
+}
+