Add mbtk_ril V2 (Default close)

Change-Id: Iaa5921fd74aeeb394771110f0cec7aa7742dc83a
diff --git a/mbtk/mbtk_rild_v2/src/main.c b/mbtk/mbtk_rild_v2/src/main.c
new file mode 100755
index 0000000..45a30f6
--- /dev/null
+++ b/mbtk/mbtk_rild_v2/src/main.c
@@ -0,0 +1,2209 @@
+#include <stdio.h>

+#include <stdlib.h>

+#include <unistd.h>

+#include <sys/socket.h>

+#include <errno.h>

+#include <fcntl.h>

+#include <string.h>

+#include <netinet/in.h>

+#include <arpa/inet.h>

+#include <linux/un.h>

+#include <linux/netlink.h>

+#include <cutils/properties.h>

+#include <time.h>

+#include <sys/time.h>

+#include <signal.h>

+#include <sys/epoll.h>

+#include <pthread.h>

+

+

+//#include "cploader.h"

+#include "mbtk_log.h"

+#include "mbtk_ifc.h"

+#include "mbtk_type.h"

+#include "atchannel.h"

+#include "at_tok.h"

+#include "mbtk_utils.h"

+#include "mbtk_task.h"

+#include "ril_info.h"

+#include "mbtk_ntp.h"

+#include "mbtk_net_control.h"

+#include "mbtk_ril.h"

+#include "mbtk_str.h"

+#include "mbtk_queue.h"

+

+#define TEMP_FAILURE_RETRY(exp) ({         \

+    typeof (exp) _rc;                      \

+    do {                                   \

+        _rc = (exp);                       \

+    } while (_rc == -1 && errno == EINTR); \

+    _rc; })

+

+#define BUFFER_SIZE 2048

+#define UEVENT_USIM_DEV "/devices/virtual/usim_event/usim0"

+#define MBTK_BOOT_SERVER_READY "/etc/init.d/mbtk_boot_server_ready"

+#define MBTK_BOOT_NET_READY "/etc/init.d/mbtk_boot_net_ready"

+#define MBTK_RILD_PID_FILE "/var/run/mbtk_rild.pid"

+#define MBTK_RILD_FILE_NET_READY "/tmp/mbtk_rild.net_ready"

+#define MBTK_RILD_FILE_SER_READY "/tmp/mbtk_rild.ser_ready"

+

+static bool ril_net_ready = FALSE;  // Only one time.

+static bool ril_server_ready = FALSE;  // Only one time.

+ril_band_info_t band_info;

+ril_info_t ril_info;

+

+// int urc_msg_distribute(bool async_process, info_urc_msg_id_enum msg, void *data, int data_len);

+// int mbtk_signal_log(char *data);

+int InProduction_Mode(void);

+mbtk_ril_err_enum dev_pack_req_process(sock_cli_info_t* cli_info, ril_msg_pack_info_t* pack);

+mbtk_ril_err_enum call_pack_req_process(sock_cli_info_t* cli_info, ril_msg_pack_info_t* pack);

+mbtk_ril_err_enum sim_pack_req_process(sock_cli_info_t* cli_info, ril_msg_pack_info_t* pack);

+mbtk_ril_err_enum net_pack_req_process(sock_cli_info_t* cli_info, ril_msg_pack_info_t* pack);

+mbtk_ril_err_enum pb_pack_req_process(sock_cli_info_t* cli_info, ril_msg_pack_info_t* pack);

+mbtk_ril_err_enum sms_pack_req_process(sock_cli_info_t* cli_info, ril_msg_pack_info_t* pack);

+

+/* Called on command thread */

+static void onATTimeout()

+{

+    LOGI("AT channel timeout; closing\n");

+    at_close();

+}

+

+/* Called on command or reader thread */

+static void onATReaderClosed()

+{

+    LOGI("AT channel closed\n");

+    at_close();

+}

+

+static void sock_cli_free_func(void *data)
+{
+    if (data)
+    {
+        sock_cli_info_t *info = (sock_cli_info_t*) data;

+        LOGD("Free Socket client[fd = %d].", info->fd);

+        free(info);
+    }
+}

+

+/*

+* Will exec mbtk_boot_server_ready and mbtk_boot_net_ready if is_first_boot is true.

+*/

+static int net_ready_set()

+{

+    int ret = -1;

+    int fd = open(MBTK_RILD_FILE_NET_READY, O_CREAT | O_WRONLY | O_TRUNC, 0644);

+    if(fd > 0) {

+        if(write(fd, "1", 1) == 1) {

+            ret = 0;

+            ril_net_ready = TRUE;

+        }

+        close(fd);

+    } else {

+        LOGE("Open %s fail:%d", MBTK_RILD_FILE_NET_READY, errno);

+    }

+

+    return ret;

+}

+

+/*

+* Will exec mbtk_boot_server_ready and mbtk_boot_net_ready if is_first_boot is true.

+*/

+static int ser_ready_set()

+{

+    int ret = -1;

+    int fd = open(MBTK_RILD_FILE_SER_READY, O_CREAT | O_WRONLY | O_TRUNC, 0644);

+    if(fd > 0) {

+        if(write(fd, "1", 1) == 1) {

+            ret = 0;

+            ril_server_ready = TRUE;

+        }

+        close(fd);

+    } else {

+        LOGE("Open %s fail:%d", MBTK_RILD_FILE_SER_READY, errno);

+    }

+

+    return ret;

+}

+

+/*

+* Will exec mbtk_boot_server_ready and mbtk_boot_net_ready if is_first_boot is true.

+*/

+static void ready_state_update()

+{

+    int fd = open(MBTK_RILD_FILE_NET_READY, O_RDONLY, 0644);

+    char buff[10];

+    if(fd > 0) {

+        if(read(fd, buff, sizeof(buff)) > 0) {

+            ril_net_ready = TRUE;

+        } else {

+            ril_net_ready = FALSE;

+        }

+

+        close(fd);

+    } else {

+        ril_net_ready = FALSE;

+        LOGE("Open %s fail:%d", MBTK_RILD_FILE_NET_READY, errno);

+    }

+

+    fd = open(MBTK_RILD_FILE_SER_READY, O_RDONLY, 0644);

+    if(fd > 0) {

+        if(read(fd, buff, sizeof(buff)) > 0) {

+            ril_server_ready = TRUE;

+        } else {

+            ril_server_ready = FALSE;

+        }

+

+        close(fd);

+    } else {

+        ril_server_ready = FALSE;

+        LOGE("Open %s fail:%d", MBTK_RILD_FILE_SER_READY, errno);

+    }

+}

+

+static void mbtk_net_ready()

+{

+    // /etc/init.d/mbtk_boot_net_ready

+    if(!ril_net_ready) {

+        if(access(MBTK_BOOT_NET_READY , X_OK) == 0) {

+            LOGD("Exec : %s", MBTK_BOOT_NET_READY);

+            system(MBTK_BOOT_NET_READY);

+        } else {

+            LOGE("%s can not exec.", MBTK_BOOT_NET_READY);

+        }

+        net_ready_set();

+    } else {

+        LOGD("No exec : %s", MBTK_BOOT_NET_READY);

+    }

+}

+

+static void mbtk_ril_ready()

+{

+    // /etc/init.d/mbtk_boot_server_ready

+    if(!ril_server_ready) {

+        if(access(MBTK_BOOT_SERVER_READY , X_OK) == 0) {

+            LOGD("Exec : %s", MBTK_BOOT_SERVER_READY);

+            system(MBTK_BOOT_SERVER_READY);

+        } else {

+            LOGE("%s can not exec.", MBTK_BOOT_SERVER_READY);

+        }

+        ser_ready_set();

+    } else {

+        LOGD("No exec : %s", MBTK_BOOT_SERVER_READY);

+    }

+}

+

+static sock_cli_info_t* cli_find(int fd)

+{
+    sock_cli_info_t *result = NULL;

+    list_first(ril_info.sock_client_list);

+    while ((result = (sock_cli_info_t*) list_next(ril_info.sock_client_list)))

+    {
+        if (result->fd == fd)
+            return result;
+    }
+
+    return NULL;
+}

+

+static void cli_close(sock_cli_info_t* client)

+{
+    struct epoll_event ev;
+    memset(&ev,0,sizeof(struct epoll_event));
+    ev.data.fd = client->fd;
+    ev.events = EPOLLIN | EPOLLERR | EPOLLET;
+    epoll_ctl(ril_info.epoll_fd, EPOLL_CTL_DEL, client->fd, &ev);

+
+    close(client->fd);
+
+    if(list_remove(ril_info.sock_client_list, client))

+    {
+        sock_cli_free_func(client);
+    }
+}
+
+static void ril_error_pack_send(int fd, int ril_id, int msg_index, int err)

+{
+    ril_msg_pack_info_t* pack = ril_msg_pack_creat(RIL_MSG_TYPE_RSP, ril_id, msg_index, NULL, 0);

+    if(pack)
+    {

+        pack->err = (uint16)err;

+        ril_pack_send(fd, pack);

+        ril_msg_pack_free(pack);

+    }
+    else
+    {
+        LOGW("ril_msg_pack_creat() fail.");

+    }
+}
+
+void ril_rsp_pack_send(int fd, int ril_id, int msg_index, const void* data, int data_len)

+{
+    ril_msg_pack_info_t* pack = ril_msg_pack_creat(RIL_MSG_TYPE_RSP, ril_id, msg_index, data, data_len);

+    if(pack)
+    {
+        pack->err = (uint16)MBTK_RIL_ERR_SUCCESS;

+#if 0

+        if(data != NULL && data_len > 0)
+        {
+            pack->data_len = (uint16)data_len;
+            pack->data = (uint8*)mbtk_memcpy(data, data_len);

+        }

+#endif

+        ril_pack_send(fd, pack);

+        ril_msg_pack_free(pack);

+    }
+    else
+    {
+        LOGW("ril_msg_pack_creat() fail.");

+    }
+}

+

+void ril_ind_pack_send(int fd, int msg_id, const void* data, int data_len)

+{
+    ril_msg_pack_info_t* pack = ril_msg_pack_creat(RIL_MSG_TYPE_IND, msg_id, RIL_MSG_INDEX_INVALID, data, data_len);

+    if(pack)
+    {
+        pack->err = (uint16)0;

+#if 0

+        if(data != NULL && data_len > 0)
+        {
+            pack->data_len = (uint16)data_len;
+            pack->data = (uint8*)mbtk_memcpy(data, data_len);

+        }

+#endif

+        ril_pack_send(fd, pack);

+        ril_msg_pack_free(pack);

+    }
+    else
+    {
+        LOGW("ril_msg_pack_creat() fail.");

+    }
+}

+

+

+static void onUnsolicited(const char *s, const char *sms_pdu)

+{

+    LOGD("URC : %s", s);

+#if 0

+    // MBTK_AT_READY

+    if (strStartsWith(s, "MBTK_AT_READY")) // AT ready.

+    {

+

+    }

+    else if(strStartsWith(s, "*RADIOPOWER:")) // "*RADIOPOWER: 1"

+    {

+        const char* ptr = s + strlen("*RADIOPOWER:");

+        while(*ptr != '\0' && *ptr == ' ' )

+        {

+            ptr++;

+        }

+

+        uint8 state;

+        if(*ptr == '1') {

+            //net_info.radio_state = MBTK_RADIO_STATE_ON;

+            // mbtk_radio_ready_cb();

+            state = (uint8)1;

+        } else {

+            //net_info.radio_state = MBTK_RADIO_STATE_OFF;

+            state = (uint8)0;

+        }

+        urc_msg_distribute(true, INFO_URC_MSG_RADIO_STATE, &state, sizeof(uint8));

+    }

+    // "CONNECT"

+    else if(strStartsWith(s, "CONNECT"))

+    {

+        if(cgact_wait.waitting && cgact_wait.act) {

+            cgact_wait.waitting = false;

+        }

+

+        uint8 data_pdp;

+        data_pdp = 1;       //

+        urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));

+    }

+    // +CGEV:

+    // +CGEV: NW DEACT <cid>,<cid>

+    // +CGEV: ME DEACT <cid>,<cid>

+    // +CGEV: NW PDN DEACT <cid>

+    // +CGEV: ME PDN DEACT <cid>

+    // +CGEV: NW DETACH

+    // +CGEV: ME DETACH

+    //

+    // +CGEV: NW ACT <cid>,<cid>

+    // +CGEV: ME ACT <cid>,<cid>

+    // +CGEV: EPS PDN ACT <cid>

+    // +CGEV: ME PDN ACT <cid>,<reason>,<cid>

+    // +CGEV: ME PDN ACT <cid>,<reason>

+    // +CGEV: NW PDN ACT <cid>

+    // +CGEV: EPS ACT <cid>

+    // +CGEV: NW MODIFY <cid>,<reason>

+    // +CGEV: NW REATTACH

+    else if(strStartsWith(s, "+CGEV:"))

+    {

+        if(at_process) {

+            if(cgact_wait.act) {

+                if(strStartsWith(s, "+CGEV: ME PDN ACT ")) { // +CGEV: ME PDN ACT 15,4

+                    if(cgact_wait.cid == atoi(s + 18)) {

+                        cgact_wait.waitting = false;

+                    }

+

+                    uint8 data_pdp;

+                    char* tmp_s = memdup(s + 18,strlen(s + 18));

+                    char* free_ptr = tmp_s;

+                    char *line = tmp_s;

+                    int tmp_int;

+                    if (at_tok_start(&line) < 0)

+                    {

+                        goto at_PDP_CREG_EXIT;

+                    }

+                    if (at_tok_nextint(&line, &tmp_int) < 0)

+                    {

+                        goto at_PDP_CREG_EXIT;

+                    }

+                    if (at_tok_nextint(&line, &tmp_int) < 0)

+                    {

+                        goto at_PDP_CREG_EXIT;

+                    }

+                    data_pdp = tmp_int;

+at_PDP_CREG_EXIT:

+                    free(free_ptr);

+

+                    //data_pdp = (uint8)atoi(s + 20);  //reason

+                    if(cgact_wait.cid >= 1 && cgact_wait.cid < 8)

+                    {

+                        if(data_pdp == 0)

+                        {

+                            data_pdp = 25;

+                            urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));

+                            //data_pdp = cgact_wait.cid + 200;

+                        }

+                        else if(data_pdp == 1)

+                        {

+                            data_pdp = 26;

+                            urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));

+                        }

+                        else if(data_pdp == 2)

+                        {

+                            data_pdp = 27;

+                            urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));

+                        }

+                        else if(data_pdp == 3)

+                        {

+                            data_pdp = 27;

+                            urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));

+                        }

+                        else

+                        {

+

+                        }

+                        if(cgact_wait.cid != 0)

+                        {

+                            data_pdp = cgact_wait.cid + 200;

+                            urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));

+                        }

+                    }

+                } else if(strStartsWith(s, "+CGEV: NW MODIFY ")) { // +CGEV: NW MODIFY 1,4

+                    if(cgact_wait.cid == atoi(s + 17)) {

+                        cgact_wait.waitting = false;

+                    }

+                }

+            } else {

+                if(strStartsWith(s, "+CGEV: ME PDN DEACT ")) { // +CGEV: ME PDN DEACT 1

+                    if(cgact_wait.cid == atoi(s + 20)) {

+                        cgact_wait.waitting = false;

+                    }

+                    uint8 data_pdp;

+                    data_pdp = 0;       //

+                    urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));

+                    if(cgact_wait.cid != 0)

+                    {

+                        data_pdp = cgact_wait.cid + 100;

+                        urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));

+                    }

+                }

+            }

+        } else {

+            // apn_state_set

+

+            // +CGEV: NW PDN DEACT <cid>

+

+            // +CGEV: EPS PDN ACT 1

+            // +CGEV: ME PDN ACT 8,1

+

+            // +CGEV: ME PDN ACT 2,4

+            uint8 data[2] = {0xFF};

+            if(strStartsWith(s, "+CGEV: NW PDN DEACT ")) { // +CGEV: NW PDN DEACT <cid>

+                //apn_state_set(atoi(s + 20), false);

+                data[0] = (uint8)0;

+                data[1] = (uint8)atoi(s + 20);

+

+                uint8 data_pdp;

+                data_pdp = 0;       //

+                urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));

+                data_pdp = data[1] + 100;

+                urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));

+            } else if(strStartsWith(s, "+CGEV: EPS PDN ACT ")) { // +CGEV: EPS PDN ACT <cid>

+                //apn_state_set(atoi(s + 19), true);

+                data[0] = (uint8)1;

+                data[1] = (uint8)atoi(s + 19);

+            } else if(strStartsWith(s, "+CGEV: ME PDN DEACT ")) { // +CGEV: EPS PDN DEACT <cid>

+                //apn_state_set(atoi(s + 19), true);

+                data[0] = (uint8)0;

+                data[1] = (uint8)atoi(s + 20);

+

+                uint8 data_pdp;

+                data_pdp = 0;       //

+                urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));

+                data_pdp = data[1] + 100;

+                urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));

+            } else if(strStartsWith(s, "+CGEV: ME PDN ACT ")) { // +CGEV: ME PDN ACT <cid>,1

+                //apn_state_set(atoi(s + 18), true);

+                data[0] = (uint8)1;

+                data[1] = (uint8)atoi(s + 18);

+

+                uint8 data_pdp;

+                char* tmp_s = memdup(s + 18,strlen(s + 18));

+                char* free_ptr = tmp_s;

+                char *line = tmp_s;

+                int tmp_int;

+                if (at_tok_start(&line) < 0)

+                {

+                    goto PDP_CREG_EXIT;

+                }

+                if (at_tok_nextint(&line, &tmp_int) < 0)

+                {

+                    goto PDP_CREG_EXIT;

+                }

+                if (at_tok_nextint(&line, &tmp_int) < 0)

+                {

+                    goto PDP_CREG_EXIT;

+                }

+                data_pdp = tmp_int;

+PDP_CREG_EXIT:

+                free(free_ptr);

+                //data_pdp = (uint8)atoi(s + 20);  //reason

+                if(data[1] >= 1 && data[1] < 8)

+                {

+                    if(data_pdp == 0)

+                    {

+                        data_pdp = 25;

+                        urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));

+                    }

+                    else if(data_pdp == 1)

+                    {

+                        data_pdp = 26;

+                        urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));

+                    }

+                    else if(data_pdp == 2)

+                    {

+                        data_pdp = 27;

+                        urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));

+                    }

+                    else if(data_pdp == 3)

+                    {

+                        data_pdp = 27;

+                        urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));

+                    }

+                    else

+                    {

+

+                    }

+

+                    data_pdp = data[1] + 200;

+                    urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));

+					data[1] = 0;

+                }

+            } else {

+                LOGI("No process : %s", s);

+            }

+

+            urc_msg_distribute(true, INFO_URC_MSG_CGEV, data, sizeof(uint8) * 2);

+        }

+    }

+    // +CREG: 1, "8010", "000060a5", 0, 2, 0

+    // +CREG: 1, "8330", "06447347", 7, 2, 0

+    // +CEREG: 1, "8330", "06447347", 7

+    // $CREG: 1, "8330", "06447347", 7,"0d4", 2, 0

+    // $CREG: 1, "8010", "000060a7", 0,, 2, 0

+    // +CGREG: 1

+    else if(strStartsWith(s, "+CGREG:")     // GMS/WCDMA data registed.

+         || strStartsWith(s, "+CEREG:"))    // LTE data registed.

+    {

+        char* tmp_s = s + 7;

+        static bool net_led_gms_wcdma = FALSE;

+        static bool net_led_lte = FALSE;

+        while(*tmp_s && *tmp_s == ' ')

+            tmp_s++;

+        uint8 data[2];

+        data[0] = (uint8)atoi(tmp_s); // Reg State.

+

+        if(strStartsWith(s, "+CGREG:"))

+        {

+           data[1] = 0;  // GMS/WCDMA

+           if(data[0] == 1)

+           {

+               net_led_gms_wcdma = TRUE;

+           }

+           else

+           {

+               net_led_gms_wcdma = FALSE;

+           }

+

+        }

+        else

+        {

+           data[1] = 1;  // LTE

+           if(data[0] == 1)

+           {

+               net_led_lte = TRUE;

+           }

+           else

+           {

+               net_led_lte = FALSE;

+           }

+        }

+

+        if(FALSE == net_led_gms_wcdma && FALSE == net_led_lte)

+        {

+           //mbtk_net_led_set(MBTK_NET_LED_SEARCH_NETWORK);

+        }

+        else

+        {

+           //mbtk_net_led_set(MBTK_NET_LED_NET_CONNECT);

+           mbtk_net_ready();

+        }

+

+        urc_msg_distribute(true, INFO_URC_MSG_NET_PS_REG_STATE, data, sizeof(data));

+        urc_msg_distribute(true, INFO_URC_MSG_NET_STATE_LOG, NULL, 0);

+    }

+    // +CREG: 1, "8010", "000060a5", 0, 2, 0

+    // +CREG: 1, "8330", "06447347", 7, 2, 0

+    // +CREG: 0

+    else if(strStartsWith(s, "+CREG:"))     // GMS/WCDMA/LTE CS registed.

+    {

+        uint8 data[3];

+        data[0] = (uint8)MBTK_NET_CS_STATE;

+        char* tmp_s = memdup(s,strlen(s));

+        char* free_ptr = tmp_s;

+        char *line = tmp_s;

+        int tmp_int;

+        char *tmp_str;

+        if (at_tok_start(&line) < 0)

+        {

+            goto CREG_EXIT;

+        }

+        if (at_tok_nextint(&line, &tmp_int) < 0)

+        {

+            goto CREG_EXIT;

+        }

+        data[1] = (uint8)tmp_int; // Reg State.

+        if (data[1])

+        {

+            if (at_tok_nextstr(&line, &tmp_str) < 0)

+            {

+                goto CREG_EXIT;

+            }

+            if (at_tok_nextstr(&line, &tmp_str) < 0)

+            {

+                goto CREG_EXIT;

+            }

+            if (at_tok_nextint(&line, &tmp_int) < 0)

+            {

+                goto CREG_EXIT;

+            }

+            data[2] = (uint8)tmp_int; // AcT

+        } else {

+            data[2] = (uint8)0xFF; // AcT

+        }

+        if(data[1] == 5)

+        {

+            uint8 data_pdp;

+            data_pdp = 5;       //

+            urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));

+        }

+        urc_msg_distribute(false, INFO_URC_MSG_NET_CS_REG_STATE, data, sizeof(data));

+        urc_msg_distribute(true, INFO_URC_MSG_NET_STATE_LOG, NULL, 0);

+CREG_EXIT:

+        free(free_ptr);

+    }

+    // +CLCC: 1, 1, 6, 0, 0, "18981911691", 129, "",, 0

+    else if(strStartsWith(s, "+CLCC:"))

+    {

+        mbtk_call_info_t reg;

+        reg.call_wait = MBTK_CLCC;

+        char* tmp_s = memdup(s,strlen(s));

+        char* free_ptr = tmp_s;

+        char *line = tmp_s;

+        int tmp_int;

+        char *tmp_str;

+        int err;

+

+        err = at_tok_start(&line);

+        if (err < 0)

+        {

+            goto CLCC_EXIT;

+        }

+        err = at_tok_nextint(&line, &tmp_int); // dir1

+        if (err < 0)

+        {

+            goto CLCC_EXIT;

+        }

+        reg.dir1 = (uint8)tmp_int;

+        err = at_tok_nextint(&line, &tmp_int);// dir

+        if (err < 0)

+        {

+            goto CLCC_EXIT;

+        }

+        reg.dir = (uint8)tmp_int;

+        err = at_tok_nextint(&line, &tmp_int);// state

+        if (err < 0)

+        {

+            goto CLCC_EXIT;

+        }

+        reg.state = (uint8)tmp_int;

+        err = at_tok_nextint(&line, &tmp_int);// mode

+        if (err < 0)

+        {

+            goto CLCC_EXIT;

+        }

+        reg.mode = (uint8)tmp_int;

+        err = at_tok_nextint(&line, &tmp_int);// mpty

+        if (err < 0)

+        {

+            goto CLCC_EXIT;

+        }

+        reg.mpty = (uint8)tmp_int;

+        err = at_tok_nextstr(&line, &tmp_str); // phone_number

+        if (err < 0)

+        {

+            goto CLCC_EXIT;

+        }

+

+        memset(reg.phone_number,0,sizeof(reg.phone_number));

+        memcpy(reg.phone_number, tmp_str, strlen(tmp_str));

+        err = at_tok_nextint(&line, &tmp_int);// tpye

+        if (err < 0)

+        {

+            goto CLCC_EXIT;

+        }

+        reg.type = (uint8)tmp_int;

+        urc_msg_distribute(false, INFO_URC_MSG_CALL_STATE, &reg, sizeof(mbtk_call_info_t));

+CLCC_EXIT:

+        free(free_ptr);

+    }

+    // +CPAS: 4

+    else if(strStartsWith(s, "+CPAS:"))

+    {

+        mbtk_call_info_t reg;

+        reg.call_wait = 0;

+        char* tmp_s = memdup(s,strlen(s));

+        char* free_ptr = tmp_s;

+        char *line = tmp_s;

+        int tmp_int;

+        int err;

+

+        memset(&reg,0,sizeof(reg));

+

+        err = at_tok_start(&line);

+        if (err < 0)

+        {

+            goto CPAS_EXIT;

+        }

+        err = at_tok_nextint(&line, &tmp_int);

+        if (err < 0)

+        {

+            goto CPAS_EXIT;

+        }

+        reg.pas = (uint8)tmp_int;

+        reg.call_wait = MBTK_CPAS;

+        urc_msg_distribute(false, INFO_URC_MSG_CALL_STATE, &reg, sizeof(mbtk_call_info_t));

+CPAS_EXIT:

+        free(free_ptr);

+    }

+    // +CALLDISCONNECT: 1

+    else if(strStartsWith(s, "+CALLDISCONNECT:"))

+    {

+        mbtk_call_info_t reg;

+        reg.call_wait = 0;

+        char* tmp_s = memdup(s,strlen(s));

+        char* free_ptr = tmp_s;

+        char *line = tmp_s;

+        int tmp_int;

+        int err;

+

+        memset(&reg,0,sizeof(reg));

+

+        err = at_tok_start(&line);

+        if (err < 0)

+        {

+            goto CALLDISCONNECTED_EXIT;

+        }

+        err = at_tok_nextint(&line, &tmp_int);

+        if (err < 0)

+        {

+            goto CALLDISCONNECTED_EXIT;

+        }

+        reg.disconnected_id = tmp_int;

+        reg.call_wait = MBTK_DISCONNECTED;

+

+        if(reg.call_wait == MBTK_DISCONNECTED)

+        {

+            //mbtk_net_led_set(MBTK_NET_LED_CALL_DISCONNECT);

+        }

+

+        urc_msg_distribute(false, INFO_URC_MSG_CALL_STATE, &reg, sizeof(mbtk_call_info_t));

+

+CALLDISCONNECTED_EXIT:

+        free(free_ptr);

+    }

+    // *SIMDETEC:1,SIM

+    else if(strStartsWith(s, "*SIMDETEC:"))

+    {

+        if(strStartsWith(s, "*SIMDETEC:1,NOS"))

+        {

+            net_info.sim_state = MBTK_SIM_ABSENT;

+        }

+

+        sim_info_reg.sim = -1;

+        if(strStartsWith(s, "*SIMDETEC:1,NOS"))

+            sim_info_reg.sim = 0;

+        else if(strStartsWith(s, "*SIMDETEC:1,SIM"))

+            sim_info_reg.sim = 1;

+        if(sim_info_reg.sim == 0)

+        {

+            uint8 data_pdp;

+            data_pdp = 11;       //

+            urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));

+        }

+        urc_msg_distribute(false, INFO_URC_MSG_SIM_STATE, &sim_info_reg, sizeof(mbtk_sim_card_info));

+    }

+    // *EUICC:1

+/*0: SIM

+1: USIM

+2: TEST SIM

+3: TEST USIM

+4: UNKNOWN

+Note: *EUICC:

+*/

+    else if(strStartsWith(s, "*EUICC:"))

+    {

+        sim_info_reg.sim_card_type = -1;

+        if(strStartsWith(s, "*EUICC: 0"))

+            sim_info_reg.sim_card_type = 1;

+        else if(strStartsWith(s, "*EUICC: 1"))

+            sim_info_reg.sim_card_type = 2;

+        else if(strStartsWith(s, "*EUICC: 2"))

+            sim_info_reg.sim_card_type = 1;

+        else if(strStartsWith(s, "*EUICC: 3"))

+            sim_info_reg.sim_card_type = 2;

+        else if(strStartsWith(s, "*EUICC: 4"))

+            sim_info_reg.sim_card_type = 0;

+        urc_msg_distribute(false, INFO_URC_MSG_SIM_STATE, &sim_info_reg, sizeof(mbtk_sim_card_info));

+    }

+    // +CPIN: SIM PIN

+    else if(strStartsWith(s, "+CPIN:"))

+    {

+        sim_info_reg.sim = -1;

+        if(strStartsWith(s, "+CPIN: READY"))

+        {

+            sim_info_reg.sim = 1;

+            net_info.sim_state = MBTK_SIM_READY;

+        }

+        else if(strStartsWith(s, "+CPIN: SIM PIN"))

+        {

+            sim_info_reg.sim = 2;

+            net_info.sim_state = MBTK_SIM_PIN;

+        }

+        else if(strStartsWith(s, "+CPIN: SIM PUK"))

+        {

+            sim_info_reg.sim = 3;

+            net_info.sim_state = MBTK_SIM_PUK;

+        }

+        else if(strStartsWith(s, "+CPIN: PH-SIMLOCK PIN"))

+        {

+            sim_info_reg.sim = 4;

+            net_info.sim_state = MBTK_SIM_ABSENT;

+        }

+        else if(strStartsWith(s, "+CPIN: PH-SIMLOCK PUK"))

+        {

+            sim_info_reg.sim = 5;

+            net_info.sim_state = MBTK_SIM_ABSENT;

+        }

+        else if(strStartsWith(s, "+CPIN: PH-FSIM PIN"))

+        {

+            sim_info_reg.sim = 6;

+            net_info.sim_state = MBTK_SIM_ABSENT;

+        }

+        else if(strStartsWith(s, "+CPIN: PH-FSIM PUK"))

+        {

+            sim_info_reg.sim = 7;

+            net_info.sim_state = MBTK_SIM_ABSENT;

+        }

+        else if(strStartsWith(s, "+CPIN: SIM PIN2"))

+        {

+            sim_info_reg.sim = 8;

+            net_info.sim_state = MBTK_SIM_ABSENT;

+        }

+        else if(strStartsWith(s, "+CPIN: SIM PUK2"))

+        {

+            sim_info_reg.sim = 9;

+            net_info.sim_state = MBTK_SIM_ABSENT;

+        }

+        else if(strStartsWith(s, "+CPIN: PH-NET PIN"))

+        {

+            sim_info_reg.sim = 10;

+            net_info.sim_state = MBTK_SIM_NETWORK_PERSONALIZATION;

+        }

+        else if(strStartsWith(s, "+CPIN: PH-NET PUK"))

+        {

+            sim_info_reg.sim = 11;

+            net_info.sim_state = MBTK_SIM_ABSENT;

+        }

+        else if(strStartsWith(s, "+CPIN: PH-NETSUB PINMT"))

+        {

+            sim_info_reg.sim = 12;

+            net_info.sim_state = MBTK_SIM_ABSENT;

+        }

+        else if(strStartsWith(s, "+CPIN: PH-NETSUB PUK"))

+        {

+            sim_info_reg.sim = 13;

+            net_info.sim_state = MBTK_SIM_ABSENT;

+        }

+        else if(strStartsWith(s, "+CPIN: PH-SP PIN"))

+        {

+            sim_info_reg.sim = 14;

+            net_info.sim_state = MBTK_SIM_ABSENT;

+        }

+        else if(strStartsWith(s, "+CPIN: PH-SP PUK"))

+        {

+            sim_info_reg.sim = 15;

+            net_info.sim_state = MBTK_SIM_ABSENT;

+        }

+        else if(strStartsWith(s, "+CPIN: PH-CORP PIN"))

+        {

+            sim_info_reg.sim = 16;

+            net_info.sim_state = MBTK_SIM_ABSENT;

+        }

+        else if(strStartsWith(s, "+CPIN: PH-CORP PUK"))

+        {

+            sim_info_reg.sim = 17;

+            net_info.sim_state = MBTK_SIM_ABSENT;

+        }

+        else if(strStartsWith(s, "+CPIN: SIM REMOVED"))

+        {

+             sim_info_reg.sim = 18;

+             net_info.sim_state = MBTK_SIM_ABSENT;

+        }

+        else

+            sim_info_reg.sim = 20;

+

+        if(sim_info_reg.sim == 18)

+        {

+            uint8 data_pdp;

+            data_pdp = 11;       //

+            urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));

+        }

+

+        urc_msg_distribute(false, INFO_URC_MSG_SIM_STATE, &sim_info_reg, sizeof(mbtk_sim_card_info));

+    }

+    // +CMT: ,23

+    // 0891683108200855F6240D91688189911196F10000221130717445230331D90C

+    else if(strStartsWith(s, "+CMT:") || sms_cmt)

+    {

+        if(!sms_cmt){

+            sms_cmt = true;

+        }else{

+            sms_cmt = false;

+        }

+        printf("+CMT() sms_cmt:%d, s:%s, len:%d\n",sms_cmt,  s, strlen(s));

+        urc_msg_distribute(false, INFO_URC_MSG_SMS_STATE, s, strlen(s));

+    }

+#if 0

+    // LTE data registed.

+    // +CEREG: 1, "8330", "06447347", 7

+    else if(strStartsWith(s, "+CEREG:"))

+    {

+        char* tmp_s = memdup(s,strlen(s));

+        char* free_ptr = tmp_s;

+        char *line = tmp_s;

+        int tmp_int;

+        char *tmp_str;

+        if (at_tok_start(&line) < 0)

+        {

+            goto CREG_EXIT;

+        }

+        if (at_tok_nextint(&line, &tmp_int) < 0)

+        {

+            goto CREG_EXIT;

+        }

+        uint8 data = (uint8)tmp_int; // Reg State.

+

+        urc_msg_distribute(INFO_URC_MSG_NET_REG_STATE, &data, sizeof(uint8));

+CREG_EXIT:

+        free(free_ptr);

+    }

+#endif

+    /*

+    // <mcc>, <length of mnc>, <mnc>, <tac>, <PCI>, <dlEuarfcn>, < ulEuarfcn >, <band>, <dlBandwidth>,

+    // <rsrp>,<rsrq>, <sinr>,

+    // errcModeState,emmState,serviceState,IsSingleEmmRejectCause,EMMRejectCause,mmeGroupId,mmeCode,mTmsi,

+    // cellId,subFrameAssignType,specialSubframePatterns,transMode

+    // mainRsrp,diversityRsrp,mainRsrq,diversityRsrq,rssi,cqi,pathLoss,tb0DlTpt,tb1DlTpt,tb0DlPeakTpt,tb1DlPeakTpt,tb0UlPeakTpt,

+    // tb1UlPeakTpt,dlThroughPut,dlPeakThroughPut,averDlPRB,averCQITb0,averCQITb1,rankIndex,grantTotal,ulThroughPut,ulPeakThroughPut,currPuschTxPower,averUlPRB,

+    // dlBer, ulBer,

+    // diversitySinr, diversityRssi

+    +EEMLTESVC: 1120, 2, 0, 33584, 430, 40936, 40936, 41, 20,

+    0, 0, 0,

+    1, 10, 0, 1, 0, 1059, 78, 3959566565,

+    105149248, 2, 7, 7,

+    0, 0, 0, 0, 0, 0, 0, 1190919, 0, 0, 0, 16779777,

+    0, 5112867, 3959566565, 2, 0, 0, 0, 0, 0, 0, 0, 0,

+    0, 0,

+    7, 44

+    */

+    else if(strStartsWith(s, "+EEMLTESVC:"))   // LTE Server Cell

+    {

+        // tac, PCI, dlEuarfcn, ulEuarfcn, band

+        if(cell_info.running) {

+            int tmp_int;

+            int i = 0;

+            char* tmp_s = memdup(s,strlen(s));

+            char* free_ptr = tmp_s;

+            char *line = tmp_s;

+            if (at_tok_start(&line) < 0)

+            {

+                goto EEMLTESVC_EXIT;

+            }

+

+            if (at_tok_nextint(&line, &tmp_int) < 0)

+            {

+                goto EEMLTESVC_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value6 = (uint32)tmp_int;    //mcc

+            if (at_tok_nextint(&line, &tmp_int) < 0)

+            {

+                goto EEMLTESVC_EXIT;

+            }

+            if (at_tok_nextint(&line, &tmp_int) < 0)

+            {

+                goto EEMLTESVC_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value7 = (uint32)tmp_int;    //mnc

+            /*

+            // Jump 2 integer.

+            i = 0;

+            while(i < 2) {

+                if (at_tok_nextint(&line, &tmp_int) < 0)

+                {

+                    goto EEMLTESVC_EXIT;

+                }

+                i++;

+            }

+            */

+            if (at_tok_nextint(&line, &tmp_int) < 0)

+            {

+                goto EEMLTESVC_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value1 = (uint32)tmp_int;    //tac

+            if (at_tok_nextint(&line, &tmp_int) < 0)

+            {

+                goto EEMLTESVC_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value2 = (uint32)tmp_int;    //pci

+            if (at_tok_nextint(&line, &tmp_int) < 0)

+            {

+                goto EEMLTESVC_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value3 = (uint32)tmp_int;    //dl arfcn

+            if (at_tok_nextint(&line, &tmp_int) < 0)

+            {

+                goto EEMLTESVC_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value4 = (uint32)tmp_int;    //ul arfcn

+            if (at_tok_nextint(&line, &tmp_int) < 0)

+            {

+                goto EEMLTESVC_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value5 = (uint32)tmp_int;    //band

+            if (at_tok_nextint(&line, &tmp_int) < 0)

+            {

+                goto EEMLTESVC_EXIT;

+            }

+            if (at_tok_nextint(&line, &tmp_int) < 0)

+            {

+                goto EEMLTESVC_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value8 = (uint32)tmp_int;    //cid

+            if (at_tok_nextint(&line, &tmp_int) < 0)

+            {

+                goto EEMLTESVC_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value9 = (uint32)tmp_int;    //rsrp

+

+            for(i =0; i < 10; i++)

+            {

+                if (at_tok_nextint(&line, &tmp_int) < 0)

+                {

+                    goto EEMLTESVC_EXIT;

+                }

+            }

+			cell_info.cell[cell_info.cell_num].value10 = (uint32)tmp_int;   //cell identiy

+

+            cell_info.cell_num++;

+

+EEMLTESVC_EXIT:

+            free(free_ptr);

+        }

+    }

+    /*

+    // index,phyCellId,euArfcn,rsrp,rsrq

+    +EEMLTEINTER: 0, 65535, 38950, 0, 0

+    */

+    else if(strStartsWith(s, "+EEMLTEINTER:") || strStartsWith(s, "+EEMLTEINTRA:")) // LTE ÒìÆµ/Í¬ÆµÐ¡Çø

+    {

+        // phyCellId,euArfcn,rsrp,rsrq

+        if(cell_info.running) {

+            int tmp_int;

+            char* tmp_s = memdup(s,strlen(s));

+            char* free_ptr = tmp_s;

+            char *line = tmp_s;

+            if (at_tok_start(&line) < 0)

+            {

+                goto EEMLTEINTER_EXIT;

+            }

+            if (at_tok_nextint(&line, &tmp_int) < 0)

+            {

+                goto EEMLTEINTER_EXIT;

+            }

+            if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int <= 0 || tmp_int > 503)

+            {

+                goto EEMLTEINTER_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value1 = (uint32)tmp_int;

+            if (at_tok_nextint(&line, &tmp_int) < 0)

+            {

+                goto EEMLTEINTER_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value2 = (uint32)tmp_int;

+            if (at_tok_nextint(&line, &tmp_int) < 0)

+            {

+                goto EEMLTEINTER_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value3 = (uint32)tmp_int;

+            LOG("cell line : %s", line);

+            if (at_tok_nextint(&line, &tmp_int) < 0)

+            {

+                goto EEMLTEINTER_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value4 = (uint32)tmp_int;

+            if (at_tok_nextint(&line, &tmp_int) < 0)

+            {

+                LOG("cell tmp_int : %d", tmp_int);

+                goto EEMLTEINTER_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value5 = (uint32)tmp_int;

+            LOG("cell value5 : %d", cell_info.cell[cell_info.cell_num].value5);

+            cell_info.cell_num++;

+EEMLTEINTER_EXIT:

+            free(free_ptr);

+        }

+    }

+    // Do nothing

+    else if(strStartsWith(s, "+EEMLTEINTERRAT:")) // LTE RATÐ¡ÇøÐÅÏ¢

+    {

+        if(cell_info.running) {

+

+        }

+    }

+    // WCDMA

+    /*

+    // Mode, sCMeasPresent, sCParamPresent, ueOpStatusPresent,

+

+    // if sCMeasPresent == 1

+    // cpichRSCP, utraRssi, cpichEcN0, sQual, sRxLev, txPower,

+    // endif

+

+    // if sCParamPresent == 1

+    // rac, nom, mcc, mnc_len, mnc, lac, ci,

+    // uraId, psc, arfcn, t3212, t3312, hcsUsed, attDetAllowed,

+    // csDrxCycleLen, psDrxCycleLen, utranDrxCycleLen, HSDPASupport, HSUPASupport,

+    // endif

+

+    // if ueOpStatusPresent == 1

+    // rrcState, numLinks, srncId, sRnti,

+    // algPresent, cipherAlg, cipherOn, algPresent, cipherAlg, cipherOn,

+    // HSDPAActive, HSUPAActive, MccLastRegisteredNetwork, MncLastRegisteredNetwork, TMSI, PTMSI, IsSingleMmRejectCause, IsSingleGmmRejectCause,

+    // MMRejectCause, GMMRejectCause, mmState, gmmState, gprsReadyState, readyTimerValueInSecs, NumActivePDPContext, ULThroughput, DLThroughput,

+    // serviceStatus, pmmState, LAU_status, LAU_count, RAU_status, RAU_count

+    // endif

+    //

+    +EEMUMTSSVC: 3, 1, 1, 1,

+    -80, 27, -6, -18, -115, -32768,

+    1, 1, 1120, 2, 1, 61697, 168432821,

+    15, 24, 10763, 0, 0, 0, 0,

+    128, 128, 65535, 0, 0,

+    2, 255, 65535, 4294967295,

+    0, 0, 0, 0, 0, 0,

+    0, 0, 0, 0, 0, 0, 1, 1,

+    28672, 28672, 0, 0, 0, 0, 0, 0, 0,

+    0, 0, 0, 0, 0, 0

+    */

+    else if(strStartsWith(s, "+EEMUMTSSVC:")) // WCDMA Server Cell

+    {

+        // lac, ci, arfcn

+        if(cell_info.running) {

+            int tmp_int;

+            int i = 0;

+            char* tmp_s = memdup(s,strlen(s));

+            char* free_ptr = tmp_s;

+            char *line = tmp_s;

+            if (at_tok_start(&line) < 0)

+            {

+                goto EEMUMTSSVC_EXIT;

+            }

+            // Jump 12 integer.

+            i = 0;

+            while(i < 12) {

+                if (at_tok_nextint(&line, &tmp_int) < 0)

+                {

+                    goto EEMUMTSSVC_EXIT;

+                }

+                i++;

+            }

+            // mcc

+            if (at_tok_nextint(&line, &tmp_int) < 0)

+            {

+                goto EEMUMTSSVC_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value4= (uint32)tmp_int;

+            // mnc

+            if (at_tok_nextint(&line, &tmp_int) < 0)

+            {

+                goto EEMUMTSSVC_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value5= (uint32)tmp_int;

+            // lac

+            if (at_tok_nextint(&line, &tmp_int) < 0)

+            {

+                goto EEMUMTSSVC_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value1 = (uint32)tmp_int;

+            // ci

+            if (at_tok_nextint(&line, &tmp_int) < 0)

+            {

+                goto EEMUMTSSVC_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value2 = (uint32)tmp_int;

+

+            if (at_tok_nextint(&line, &tmp_int) < 0)

+            {

+                goto EEMUMTSSVC_EXIT;

+            }

+            // cpi

+            if (at_tok_nextint(&line, &tmp_int) < 0)

+            {

+                goto EEMUMTSSVC_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value6= (uint32)tmp_int;

+            /*

+            // Jump 2 integer.

+            i = 0;

+            while(i < 2) {

+                if (at_tok_nextint(&line, &tmp_int) < 0)

+                {

+                    goto EEMUMTSSVC_EXIT;

+                }

+                i++;

+            }

+            */

+            // arfcn

+            if (at_tok_nextint(&line, &tmp_int) < 0)

+            {

+                goto EEMUMTSSVC_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value3 = (uint32)tmp_int;

+

+            cell_info.cell_num++;

+EEMUMTSSVC_EXIT:

+            free(free_ptr);

+        }

+    }

+    /*

+    // index, cpichRSCP, utraRssi, cpichEcN0, sQual, sRxLev ,mcc, mnc, lac, ci, arfcn, psc

+    +EEMUMTSINTRA: 0, -32768, -1, -32768, -18, -115, 0, 0, 65534, 1, 10763, 32

+    */

+    else if(strStartsWith(s, "+EEMUMTSINTRA:")) // WCDMAÁÙ½üÐ¡Çø

+    {

+        // lac, ci, arfcn

+        if(cell_info.running) {

+            int tmp_int;

+            int i = 0;

+            char* tmp_s = memdup(s,strlen(s));

+            char* free_ptr = tmp_s;

+            char *line = tmp_s;

+            if (at_tok_start(&line) < 0)

+            {

+                goto EEMUMTSINTRA_EXIT;

+            }

+            // Jump 8 integer.

+            i = 0;

+            while(i < 8) {

+                if (at_tok_nextint(&line, &tmp_int) < 0)

+                {

+                    goto EEMUMTSINTRA_EXIT;

+                }

+                i++;

+            }

+

+            // lac

+            if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int <= 0 || tmp_int >= 65536)

+            {

+                goto EEMUMTSINTRA_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value1 = (uint32)tmp_int;

+

+            // ci

+            if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int <= 0 || tmp_int >= 65536)

+            {

+                goto EEMUMTSINTRA_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value2 = (uint32)tmp_int;

+

+            // arfcn

+            if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int <= 0 || tmp_int >= 65536)

+            {

+                goto EEMUMTSINTRA_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value3 = (uint32)tmp_int;

+

+            cell_info.cell_num++;

+EEMUMTSINTRA_EXIT:

+            free(free_ptr);

+        }

+    }

+    /*

+    // index,gsmRssi,rxLev,C1,C2,mcc,mnc,lac,ci,arfcn,bsic

+    +EEMUMTSINTERRAT: 0, -32768, -107, -1, -1, 0, 0, 65534, 0, 117, 36

+    */

+    else if(strStartsWith(s, "+EEMUMTSINTERRAT:")) // WCDMA RATÐ¡ÇøÐÅÏ¢

+    {

+        // lac, ci, arfcn

+        if(cell_info.running) {

+            int tmp_int;

+            int i = 0;

+            char* tmp_s = memdup(s,strlen(s));

+            char* free_ptr = tmp_s;

+            char *line = tmp_s;

+            if (at_tok_start(&line) < 0)

+            {

+                goto EEMUMTSINTERRAT_EXIT;

+            }

+            // Jump 7 integer.

+            i = 0;

+            while(i < 7) {

+                if (at_tok_nextint(&line, &tmp_int) < 0)

+                {

+                    goto EEMUMTSINTERRAT_EXIT;

+                }

+                i++;

+            }

+

+            // lac

+            if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int <= 0 || tmp_int >= 65536)

+            {

+                goto EEMUMTSINTERRAT_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value1 = (uint32)tmp_int;

+

+            // ci

+            if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int <= 0 || tmp_int >= 65536)

+            {

+                goto EEMUMTSINTERRAT_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value2 = (uint32)tmp_int;

+

+            // arfcn

+            if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int <= 0 || tmp_int >= 65536)

+            {

+                goto EEMUMTSINTERRAT_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value3 = (uint32)tmp_int;

+

+            cell_info.cell_num++;

+EEMUMTSINTERRAT_EXIT:

+            free(free_ptr);

+        }

+    }

+    // GSM

+    // +EEMGINFOBASIC: 2

+    // Do nothing.

+    else if(strStartsWith(s, "+EEMGINFOBASIC:")) // Basic information in GSM

+        // 0: ME in Idle mode   1: ME in Dedicated mode   2: ME in PS PTM mode

+    {

+        if(cell_info.running) {

+

+        }

+    }

+    /*

+    // mcc, mnc_len, mnc, lac, ci, nom, nco,

+    // bsic, C1, C2, TA, TxPwr,

+    // RxSig, RxSigFull, RxSigSub, RxQualFull, RxQualSub,

+    // ARFCB_tch, hopping_chnl, chnl_type, TS, PacketIdle, rac, arfcn,

+    // bs_pa_mfrms, C31, C32, t3212, t3312, pbcch_support, EDGE_support,

+    // ncc_permitted, rl_timeout, ho_count, ho_succ, chnl_access_count, chnl_access_succ_count,

+    // gsmBand,channelMode

+    +EEMGINFOSVC: 1120, 2, 0, 32784, 24741, 2, 0,

+    63, 36, 146, 1, 7,

+    46, 42, 42, 7, 0,

+    53, 0, 8, 0, 1, 6, 53,

+    2, 0, 146, 42, 54, 0, 1,

+    1, 32, 0, 0, 0, 0,

+    0, 0

+    */

+    else if(strStartsWith(s, "+EEMGINFOSVC:")) // GSM Server Cell

+    {

+        // lac, ci, arfcn, bsic

+        LOG("+EEMGINFOSVC: 1= %d\n.",cell_info.running);

+        if(cell_info.running) {

+            int tmp_int;

+            int i = 0;

+            char* tmp_s = memdup(s,strlen(s));

+            char* free_ptr = tmp_s;

+            char *line = tmp_s;

+            if (at_tok_start(&line) < 0)

+            {

+                goto EEMGINFOSVC_EXIT;

+            }

+

+            // mcc

+            if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int <= 0 || tmp_int >= 65536)

+            {

+                goto EEMGINFOSVC_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value5 = (uint32)tmp_int;

+

+            //mnc_len

+            if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int <= 0 || tmp_int >= 65536)

+            {

+                goto EEMGINFOSVC_EXIT;

+            }

+            // mnc

+            if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int <= 0 || tmp_int >= 65536)

+            {

+                goto EEMGINFOSVC_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value6 = (uint32)tmp_int;

+

+            /*

+            // Jump 3 integer.

+            i = 0;

+            while(i < 3) {

+                if (at_tok_nextint(&line, &tmp_int) < 0)

+                {

+                    goto EEMGINFOSVC_EXIT;

+                }

+                i++;

+            }

+            */

+            // lac

+            if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int < 0 || tmp_int >= 65536)

+            {

+                goto EEMGINFOSVC_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value1 = (uint32)tmp_int;

+

+            // ci

+            if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int < 0 || tmp_int >= 65536)

+            {

+                goto EEMGINFOSVC_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value2 = (uint32)tmp_int;

+

+            // Jump 2 integer.

+            i = 0;

+            while(i < 2) {

+                if (at_tok_nextint(&line, &tmp_int) < 0)

+                {

+                    goto EEMGINFOSVC_EXIT;

+                }

+                i++;

+            }

+

+            // bsic

+            if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int < 0 || tmp_int >= 65536)

+            {

+                goto EEMGINFOSVC_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value4 = (uint32)tmp_int;

+

+            // Jump 15 integer.

+            i = 0;

+            while(i < 15) {

+                if (at_tok_nextint(&line, &tmp_int) < 0)

+                {

+                    goto EEMGINFOSVC_EXIT;

+                }

+                i++;

+            }

+

+            // arfcn

+            if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int < 0 || tmp_int >= 65536)

+            {

+                goto EEMGINFOSVC_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value3 = (uint32)tmp_int;

+

+            cell_info.cell_num++;

+EEMGINFOSVC_EXIT:

+            free(free_ptr);

+        }

+    }

+    /*

+    // PS_attached, attach_type, service_type, tx_power, c_value,

+    // ul_ts, dl_ts, ul_cs, dl_cs, ul_modulation, dl_modulation,

+    // gmsk_cv_bep, 8psk_cv_bep, gmsk_mean_bep, 8psk_mean_bep, EDGE_bep_period, single_gmm_rej_cause

+    // pdp_active_num, mac_mode, network_control, network_mode, EDGE_slq_measurement_mode, edge_status

+    +EEMGINFOPS: 1, 255, 0, 0, 0,

+    0, 0, 268435501, 1, 0, 0,

+    4, 0, 96, 0, 0, 0,

+    0, 0, 0, 65535, 0, 13350

+    */

+    // Do nothing.

+    else if(strStartsWith(s, "+EEMGINFOPS:")) // PSÐÅÏ¢

+    {

+        if(cell_info.running) {

+

+        }

+    }

+    else if(strStartsWith(s, "+EEMGINFONC:")) // cell

+    {

+        if(cell_info.running) {

+            int tmp_int;

+            int i = 0;

+            char* tmp_s = memdup(s,strlen(s));

+            char* free_ptr = tmp_s;

+            char *line = tmp_s;

+            if (at_tok_start(&line) < 0)

+            {

+                goto EEMGINFOPS_EXIT;

+            }

+

+            // nc_num

+            if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int < 0 || tmp_int >= 65536)

+            {

+                LOG("cell_info.running 1= %d\n.",cell_info.running);

+                goto EEMGINFOPS_EXIT;

+            }

+            // mcc

+            if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int < 0 || tmp_int >= 65536)

+            {

+                LOG("cell_info.running 2= %d\n.",cell_info.running);

+                goto EEMGINFOPS_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value5 = (uint32)tmp_int;

+

+            // mnc

+            if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int < 0 || tmp_int >= 65536)

+            {

+                LOG("cell_info.running 3= %d\n.",cell_info.running);

+                goto EEMGINFOPS_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value6 = (uint32)tmp_int;

+

+            // lac

+            if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int < 0 || tmp_int >= 65536)

+            {

+                LOG("cell_info.running 4= %d\n.",cell_info.running);

+                goto EEMGINFOPS_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value1 = (uint32)tmp_int;

+

+            // rac

+            if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int < 0 || tmp_int >= 65536)

+            {

+                LOG("cell_info.running 5= %d\n.",cell_info.running);

+                goto EEMGINFOPS_EXIT;

+            }

+

+            // ci

+            if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int < 0 || tmp_int >= 65536)

+            {

+                LOG("cell_info.running 6= %d\n.",cell_info.running);

+                goto EEMGINFOPS_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value2 = (uint32)tmp_int;

+

+            // rx_lv

+            if (at_tok_nextint(&line, &tmp_int) < 0)

+            {

+                LOG("cell_info.running 7= %d\n.",cell_info.running);

+                goto EEMGINFOPS_EXIT;

+            }

+

+            // bsic

+            if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int < 0 || tmp_int >= 65536)

+            {

+                LOG("cell_info.running 8= %d\n.",cell_info.running);

+                goto EEMGINFOPS_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value4 = (uint32)tmp_int;

+

+            // Jump 2 integer.

+            i = 0;

+            while(i < 2) {

+                if (at_tok_nextint(&line, &tmp_int) < 0)

+                {

+                    LOG("cell_info.running 9= %d\n.",cell_info.running);

+                    goto EEMGINFOPS_EXIT;

+                }

+                i++;

+            }

+

+            // arfcn

+            if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int < 0 || tmp_int >= 65536)

+            {

+                LOG("cell_info.running 10 = %d\n.",cell_info.running);

+                goto EEMGINFOPS_EXIT;

+            }

+            cell_info.cell[cell_info.cell_num].value3 = (uint32)tmp_int;

+

+            cell_info.cell_num++;

+EEMGINFOPS_EXIT:

+            free(free_ptr);

+        }

+    }

+    else if(strStartsWith(s, "+ZGIPDNS:")) // +ZGIPDNS: 1,"IPV4V6","10.156.239.245","10.156.239.246","223.87.253.100","223.87.253.253","fe80:0000:0000:0000:0001:0001:9b8c:7c0c","fe80::1:1:9b8c:7c0d","2409:8062:2000:2::1","2409:8062:2000:2::2"

+    {

+

+    }

+    else

+    {

+        LOGV("Unknown URC : %s", s);

+    }

+#endif

+}

+

+static int openSocket(const char* sockname)

+{

+    int sock = socket(AF_UNIX, SOCK_STREAM, 0);

+    if (sock < 0)

+    {

+        LOGE("Error create socket: %s\n", strerror(errno));

+        return -1;

+    }

+    struct sockaddr_un addr;

+    memset(&addr, 0, sizeof(addr));

+    addr.sun_family = AF_UNIX;

+    strncpy(addr.sun_path, sockname, sizeof(addr.sun_path));

+    while (TEMP_FAILURE_RETRY(connect(sock,(const struct sockaddr*)&addr, sizeof(addr))) != 0)

+    {

+        LOGE("Error connect to socket %s: %s, try again", sockname, strerror(errno));

+        sleep(1);

+    }

+

+#if 0

+    int sk_flags = fcntl(sock, F_GETFL, 0);

+    fcntl(sock, F_SETFL, sk_flags | O_NONBLOCK);

+#endif

+

+    return sock;

+}

+

+static void ril_at_ready_process()
+{
+    ril_info.radio_state = ril_radio_state_get();

+    if (ril_info.radio_state != MBTK_RADIO_STATE_FULL_FUNC)

+    {
+        ril_radio_state_set(MBTK_RADIO_STATE_FULL_FUNC, FALSE);

+    }

+
+    if(ril_info.radio_state == MBTK_RADIO_STATE_FULL_FUNC)

+    {

+        at_send_command("AT+CEREG=2", NULL);
+    }
+
+    ril_info.sim_state = ril_sim_state_get();

+    if(ril_info.sim_state == MBTK_SIM_STATE_READY)

+    {
+        LOGD("SIM READY!");
+        at_send_command("AT+COPS=3", NULL);
+

+        // Set APN from prop.

+        apn_auto_conf_from_prop();

+    }
+    else
+    {
+        LOGE("SIM NOT READY!");
+    }

+}

+

+static void ind_regisger(sock_cli_info_t* cli_info, uint16 ind)

+{
+    uint32 i = 0;
+    while(i < cli_info->ind_num)
+    {
+        if(cli_info->ind_register[i] == ind)
+            break;
+        i++;
+    }
+
+    if(i == cli_info->ind_num)   // No found IND
+    {
+        cli_info->ind_register[i] = ind;
+        cli_info->ind_num++;
+        LOGD("Register IND : %s", id2str(ind));

+    }
+    else
+    {
+        LOGW("IND had exist.");

+    }
+}

+

+// Process AT URC data
+static int send_pack_to_queue(sock_cli_info_t* cli_info, void* pack)

+{
+    if(ril_info.msg_queue.count >= PACK_PROCESS_QUEUE_MAX)

+    {
+        LOGE("Packet process queue is full");

+        return -1;
+    }
+
+    ril_msg_queue_info_t *item = (ril_msg_queue_info_t*)malloc(sizeof(ril_msg_queue_info_t));

+    if(!item)
+    {
+        LOGE("malloc() fail[%d].", errno);

+        return -1;
+    }
+    item->cli_info = cli_info;
+    item->pack = pack;
+    mbtk_queue_put(&ril_info.msg_queue, item);

+
+    // If thread is waitting,continue it.
+    pthread_mutex_lock(&ril_info.msg_mutex);

+    pthread_cond_signal(&ril_info.msg_cond);

+    pthread_mutex_unlock(&ril_info.msg_mutex);

+
+    return 0;
+}

+

+

+static void pack_distribute(sock_cli_info_t* cli_info, ril_msg_pack_info_t* pack)

+{
+    // Register IND Message.
+    if(pack->msg_type == RIL_MSG_TYPE_IND)

+    {
+        mbtk_ril_err_enum err = MBTK_RIL_ERR_SUCCESS;

+        if(cli_info->ind_num >= IND_REGISTER_MAX)
+        {
+            LOGE("IND if full.");

+            err = MBTK_RIL_ERR_IND_FULL;

+        }
+        else
+        {
+            ind_regisger(cli_info, pack->msg_id);

+        }
+
+        ril_error_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, err);

+
+        ril_msg_pack_free(pack);

+    }
+    else     // Request Information.
+    {
+        LOGD("Start process REQ(%s), Length : %d", id2str(pack->msg_id), pack->data_len);

+        if(0 && pack->data_len > 0)
+        {
+            log_hex("DATA", pack->data, pack->data_len);
+        }
+
+        // Send to REQ_process_thread process.
+        send_pack_to_queue(cli_info, pack);
+
+        // For test.
+        // pack_error_send(cli_info->fd, pack->info_id + 1, MBTK_INFO_ERR_SUCCESS);
+    }
+}

+

+// Return MBTK_INFO_ERR_SUCCESS,will call pack_error_send() to send RSP.
+// Otherwise, do not call pack_error_send().
+static mbtk_ril_err_enum pack_req_process(sock_cli_info_t* cli_info, ril_msg_pack_info_t* pack)

+{
+    if(pack->msg_id > RIL_MSG_ID_DEV_BEGIN && pack->msg_id < RIL_MSG_ID_DEV_END) {

+        return dev_pack_req_process(cli_info, pack);

+    } else if(pack->msg_id > RIL_MSG_ID_SIM_BEGIN && pack->msg_id < RIL_MSG_ID_SIM_END) {

+        return sim_pack_req_process(cli_info, pack);

+    } else if(pack->msg_id > RIL_MSG_ID_NET_BEGIN && pack->msg_id < RIL_MSG_ID_NET_END) {

+        return net_pack_req_process(cli_info, pack);

+    } else if(pack->msg_id > RIL_MSG_ID_CALL_BEGIN && pack->msg_id < RIL_MSG_ID_CALL_END) {

+        return call_pack_req_process(cli_info, pack);

+    } else if(pack->msg_id > RIL_MSG_ID_SMS_BEGIN && pack->msg_id < RIL_MSG_ID_SMS_END) {

+        return sms_pack_req_process(cli_info, pack);

+    } else if(pack->msg_id > RIL_MSG_ID_PB_BEGIN && pack->msg_id < RIL_MSG_ID_PB_END) {

+        return pb_pack_req_process(cli_info, pack);

+    } else {

+        LOGW("Unknown msg id : %d", pack->msg_id);

+        return MBTK_RIL_ERR_FORMAT;

+    }

+}

+

+static void urc_msg_process(ril_urc_msg_info_t *msg)

+{
+    uint8 *data = NULL;
+    if(msg->data) {
+        data = (uint8*)msg->data;
+    }
+    switch(msg->msg) {
+        case RIL_URC_MSG_RADIO_STATE:

+        {
+            break;
+        }
+        default:
+        {
+            LOGE("Unknown URC : %d", msg->msg);
+            break;
+        }
+    }
+}

+

+// Read client conn/msg and push into ril_info.msg_queue.

+static void* ril_read_pthread(void* arg)

+{
+    UNUSED(arg);
+    ril_info.epoll_fd = epoll_create(SOCK_CLIENT_MAX + 1);

+    if(ril_info.epoll_fd < 0)

+    {
+        LOGE("epoll_create() fail[%d].", errno);

+        return NULL;
+    }
+
+    uint32 event = EPOLLIN | EPOLLET;
+    struct epoll_event ev;
+    ev.data.fd = ril_info.sock_listen_fd;

+    ev.events = event; //EPOLLIN | EPOLLERR | EPOLLET;
+    epoll_ctl(ril_info.epoll_fd, EPOLL_CTL_ADD, ril_info.sock_listen_fd, &ev);

+
+    int nready = -1;
+    struct epoll_event epoll_events[EPOLL_LISTEN_MAX];
+    while(1)
+    {
+        nready = epoll_wait(ril_info.epoll_fd, epoll_events, EPOLL_LISTEN_MAX, -1);

+        if(nready > 0)
+        {
+            sock_cli_info_t *cli_info = NULL;

+            int i;
+            for(i = 0; i < nready; i++)
+            {
+                LOG("fd[%d] event = %x",epoll_events[i].data.fd, epoll_events[i].events);
+                if(epoll_events[i].events & EPOLLHUP)   // Client Close.
+                {
+                    if((cli_info = cli_find(epoll_events[i].data.fd)) != NULL)
+                    {
+                        cli_close(cli_info);
+                    }
+                    else
+                    {
+                        LOG("Unknown client[fd = %d].", epoll_events[i].data.fd);
+                    }
+                }
+                else if(epoll_events[i].events & EPOLLIN)
+                {
+                    if(epoll_events[i].data.fd == ril_info.sock_listen_fd)   // New clients connected.

+                    {
+                        int client_fd = -1;
+                        while(1)
+                        {
+                            struct sockaddr_in cliaddr;
+                            socklen_t clilen = sizeof(cliaddr);
+                            client_fd = accept(epoll_events[i].data.fd, (struct sockaddr *) &cliaddr, &clilen);
+                            if(client_fd < 0)
+                            {
+                                if(errno == EAGAIN)
+                                {
+                                    LOG("All client connect get.");
+                                }
+                                else
+                                {
+                                    LOG("accept() error[%d].", errno);
+                                }
+                                break;
+                            }
+                            // Set O_NONBLOCK
+                            int flags = fcntl(client_fd, F_GETFL, 0);
+                            if (flags > 0)
+                            {
+                                flags |= O_NONBLOCK;
+                                if (fcntl(client_fd, F_SETFL, flags) < 0)
+                                {
+                                    LOG("Set flags error:%d", errno);
+                                }
+                            }
+
+                            memset(&ev,0,sizeof(struct epoll_event));
+                            ev.data.fd = client_fd;
+                            ev.events = event;//EPOLLIN | EPOLLERR | EPOLLET;
+                            epoll_ctl(ril_info.epoll_fd, EPOLL_CTL_ADD, client_fd, &ev);

+
+                            sock_cli_info_t *info = (sock_cli_info_t*)malloc(sizeof(sock_cli_info_t));

+                            if(info)
+                            {
+                                memset(info, 0, sizeof(sock_cli_info_t));

+                                info->fd = client_fd;

+                                list_add(ril_info.sock_client_list, info);

+                                LOG("Add New Client FD Into List.");

+

+                                // Send msg RIL_MSG_ID_IND_SER_READY to client.

+                                ril_ind_pack_send(client_fd, RIL_MSG_ID_IND_SER_READY, NULL, 0);

+                            }
+                            else
+                            {
+                                LOG("malloc() fail.");
+                            }
+                        }
+                    }
+                    else if((cli_info = cli_find(epoll_events[i].data.fd)) != NULL)    // Client 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(cli_info->fd, true, &err);

+
+                        // Parse packet error,send error response to client.
+                        if(pack == NULL)
+                        {
+                            ril_error_pack_send(cli_info->fd, RIL_MSG_ID_UNKNOWN, RIL_MSG_INDEX_INVALID, err);

+                        }
+                        else
+                        {
+                            ril_msg_pack_info_t** pack_ptr = pack;

+                            while(*pack_ptr)
+                            {
+                                pack_distribute(cli_info, *pack_ptr);
+                                // Not free,will free in pack_process() or packet process thread.
+                                //mbtk_info_pack_free(pack_ptr);
+                                pack_ptr++;
+                            }
+
+                            free(pack);
+                        }
+                    }
+                    else
+                    {
+                        LOG("Unknown socket : %d", epoll_events[i].data.fd);
+                    }
+                }
+                else
+                {
+                    LOG("Unknown event : %x", epoll_events[i].events);
+                }
+            }
+        }
+        else
+        {
+            LOG("epoll_wait() fail[%d].", errno);
+        }
+    }
+
+    return NULL;
+}

+

+static void* ril_process_thread(void* arg)

+{
+    UNUSED(arg);
+    ril_msg_queue_info_t* item = NULL;

+
+    pthread_mutex_lock(&ril_info.msg_mutex);

+    while(TRUE)
+    {
+        if(mbtk_queue_empty(&ril_info.msg_queue))

+        {
+            LOG("Packet process wait...");
+            pthread_cond_wait(&ril_info.msg_cond, &ril_info.msg_mutex);

+            LOG("Packet process continue...");
+        }
+        else
+        {
+            LOG("Packet process queue not empty,continue...");
+        }
+
+        // Process all information request.
+        mbtk_ril_err_enum err;

+        while((item = (ril_msg_queue_info_t*)mbtk_queue_get(&ril_info.msg_queue)) != NULL)

+        {
+            if(item->cli_info) { // REQ form client.
+                ril_msg_pack_info_t *pack = (ril_msg_pack_info_t*)item->pack;

+                LOGD("Process REQ %s.", id2str(pack->msg_id));

+                ril_info.at_process = true;

+                err = pack_req_process(item->cli_info, pack);
+                if(err != MBTK_RIL_ERR_SUCCESS)

+                {
+                    ril_error_pack_send(item->cli_info->fd, pack->msg_id, pack->msg_index, err);

+                }
+                ril_info.at_process = false;

+                ril_msg_pack_free(pack);

+                free(item);
+            } else { // REQ from myself.
+                ril_urc_msg_info_t *urc = (ril_urc_msg_info_t*)item->pack;

+                LOGD("Process URC %d.", urc->msg);

+                urc_msg_process(urc);
+                if(urc->data)

+                    free(urc->data);
+                free(urc);
+            }
+        }
+    }
+    pthread_mutex_unlock(&ril_info.msg_mutex);

+    return NULL;
+}

+

+/*
+AT*BAND=15,78,147,482,134742231
+
+OK
+*/
+static void* band_config_thread()
+{
+    mbtk_device_info_modem_t info_modem;
+    memset(&band_info.band_support, 0, sizeof(mbtk_band_info_t));

+    memset(&info_modem, 0, sizeof(mbtk_device_info_modem_t));
+    band_info.band_set_success = FALSE;

+    if(mbtk_dev_info_read(MBTK_DEVICE_INFO_ITEM_MODEM, &(info_modem), sizeof(mbtk_device_info_modem_t))) {
+        LOGD("mbtk_dev_info_read(MODEM) fail, use default band.");
+        band_info.band_area = MBTK_MODEM_BAND_AREA_ALL;

+        band_info.band_support.net_pref = MBTK_NET_PREF_UNUSE;

+        band_info.band_support.gsm_band = MBTK_BAND_ALL_GSM_DEFAULT;

+        band_info.band_support.umts_band = MBTK_BAND_ALL_WCDMA_DEFAULT;

+        band_info.band_support.tdlte_band = MBTK_BAND_ALL_TDLTE_DEFAULT;

+        band_info.band_support.fddlte_band = MBTK_BAND_ALL_FDDLTE_DEFAULT;

+        band_info.band_support.lte_ext_band = MBTK_BAND_ALL_EXT_LTE_DEFAULT;

+    } else {
+        band_info.band_area = info_modem.band_area;

+        band_info.band_support.net_pref = MBTK_NET_PREF_UNUSE;

+        band_info.band_support.gsm_band = info_modem.band_gsm;

+        band_info.band_support.umts_band = info_modem.band_wcdma;

+        band_info.band_support.tdlte_band = info_modem.band_tdlte;

+        band_info.band_support.fddlte_band = info_modem.band_fddlte;

+        band_info.band_support.lte_ext_band = info_modem.band_lte_ext;

+    }
+
+    bool is_first = TRUE;
+    while(!band_info.band_set_success) {

+        // Set band.

+#if 0

+        info_urc_msg_t *urc = (info_urc_msg_t*)malloc(sizeof(info_urc_msg_t));
+        if(!urc)
+        {
+            LOG("malloc() fail[%d].", errno);
+            break;
+        } else {
+            urc->msg = INFO_URC_MSG_SET_BAND;
+            urc->data = NULL;
+            urc->data_len = 0;
+            send_pack_to_queue(NULL, urc);
+
+            if(is_first) {
+                is_first = FALSE;
+            } else {
+                LOGE("*BAND exec error, will retry in 5s.");
+            }
+            sleep(5);
+        }

+#else

+        sleep(5);

+#endif

+    }
+
+    LOGD("Set Band thread exit.");
+    return NULL;
+}
+

+

+int ril_server_start()

+{
+    signal(SIGPIPE, SIG_IGN);

+

+    memset(&ril_info, 0, sizeof(ril_info_t));

+    memset(&band_info, 0, sizeof(ril_band_info_t));

+    memset(&band_info.band_support, 0xFF, sizeof(mbtk_band_info_t));

+
+    //check cfun and sim card status
+    ril_at_ready_process();
+
+    //any AT instruction that is not sent through pack_process_thread needs to precede the thread
+    //thread create
+    if(ril_info.sock_listen_fd > 0)

+    {
+        LOGE("Information Server Has Started.");

+        return -1;
+    }
+
+    struct sockaddr_un server_addr;
+    ril_info.sock_listen_fd = socket(AF_LOCAL, SOCK_STREAM, 0);

+    if(ril_info.sock_listen_fd < 0)

+    {
+        LOGE("socket() fail[%d].", errno);

+        return -1;
+    }
+
+    // Set O_NONBLOCK
+    int flags = fcntl(ril_info.sock_listen_fd, F_GETFL, 0);

+    if (flags < 0)
+    {
+        LOGE("Get flags error:%d", errno);

+        goto error;
+    }
+    flags |= O_NONBLOCK;
+    if (fcntl(ril_info.sock_listen_fd, F_SETFL, flags) < 0)

+    {
+        LOGE("Set flags error:%d", errno);

+        goto error;
+    }
+
+    unlink(RIL_SOCK_NAME);

+    memset(&server_addr, 0, sizeof(struct sockaddr_un));
+    server_addr.sun_family = AF_LOCAL;
+    strcpy(server_addr.sun_path, RIL_SOCK_NAME);

+    if(bind(ril_info.sock_listen_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)))

+    {
+        LOGE("bind() fail[%d].", errno);

+        goto error;
+    }
+
+    if(listen(ril_info.sock_listen_fd, SOCK_CLIENT_MAX))

+    {
+        LOGE("listen() fail[%d].", errno);

+        goto error;
+    }
+
+    ril_info.sock_client_list = list_create(sock_cli_free_func);

+    if(ril_info.sock_client_list == NULL)

+    {
+        LOGE("list_create() fail.");

+        goto error;
+    }

+

+    mbtk_queue_init(&ril_info.msg_queue);

+    pthread_mutex_init(&ril_info.msg_mutex, NULL);

+    pthread_cond_init(&ril_info.msg_cond, NULL);

+
+    pthread_t info_pid, pack_pid, monitor_pid, urc_pid, bootconn_pid;
+    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(&info_pid, &thread_attr, ril_read_pthread, NULL))

+    {
+        LOGE("pthread_create() fail.");

+        goto error;
+    }
+
+    if(pthread_create(&pack_pid, &thread_attr, ril_process_thread, NULL))

+    {
+        LOGE("pthread_create() fail.");

+        goto error;
+    }
+
+    // Set Band
+    // AT*BAND=15,78,147,482,134742231
+    char buff[10];
+    memset(buff, 0, 10);
+    property_get("persist.mbtk.band_config", buff, "");
+    if(strlen(buff) == 0) {
+        pthread_t band_pid;
+        if(pthread_create(&band_pid, &thread_attr, band_config_thread, NULL))
+        {
+            LOGE("pthread_create() fail.");

+        }
+    }
+
+    pthread_attr_destroy(&thread_attr);
+
+    LOGD("MBTK Ril Server Start...");

+
+    return 0;
+error:

+    if(ril_info.sock_client_list) {

+        list_free(ril_info.sock_client_list);

+        ril_info.sock_client_list = NULL;

+    }

+

+    if(ril_info.sock_listen_fd > 0) {

+        close(ril_info.sock_listen_fd);

+        ril_info.sock_listen_fd = -1;

+    }

+    return -1;
+}

+

+

+int main(int argc, char *argv[])

+{

+    mbtk_log_init("radio", "MBTK_RIL");

+

+#ifdef MBTK_DUMP_SUPPORT

+    mbtk_debug_open(NULL, TRUE);

+#endif

+

+// Using Killall,the file lock may be not release.

+#if 0

+    if(app_already_running(MBTK_RILD_PID_FILE)) {

+        LOGW("daemon already running.");

+        exit(1);

+    }

+#endif

+

+    LOGI("mbtk_rild start.");

+

+    if(InProduction_Mode()) {

+        LOGI("Is Production Mode, will exit...");

+        exit(0);

+    }

+

+    ready_state_update();

+

+    int at_sock = openSocket("/tmp/atcmd_at");

+    if(at_sock < 0)

+    {

+        LOGE("Open AT Socket Fail[%d].", errno);

+        return -1;

+    }

+    int uart_sock = openSocket("/tmp/atcmd_urc");

+    if(uart_sock < 0)

+    {

+        LOGE("Open Uart Socket Fail[%d].", errno);

+        return -1;

+    }

+

+    at_set_on_reader_closed(onATReaderClosed);

+    at_set_on_timeout(onATTimeout);

+

+    if(at_open(at_sock, uart_sock, onUnsolicited))

+    {

+        LOGE("Start AT thread fail.");

+        return -1;

+    }

+

+    if(at_handshake())

+    {

+        LOGE("AT handshake fail.");

+        return -1;

+    }

+

+    LOGD("AT OK.");

+

+    if(ril_server_start())

+    {

+        LOGE("ril_server_start() fail.");

+        return -1;

+    }

+

+    mbtk_ril_ready();

+

+    while(1)

+    {

+        sleep(24 * 60 * 60);

+    }

+

+    LOGD("!!!mbtk_ril exit!!!");

+    return 0;

+}