Add ril v2 support.

Change-Id: I14f4d5f3650f0d397c38a72e8bea2600c17b07de
diff --git a/mbtk/mbtk_rild_v2/src/atchannel.c b/mbtk/mbtk_rild_v2/src/atchannel.c
index bf0384c..316e62a 100755
--- a/mbtk/mbtk_rild_v2/src/atchannel.c
+++ b/mbtk/mbtk_rild_v2/src/atchannel.c
@@ -36,7 +36,7 @@
 #define MAX_AT_RESPONSE (8 * 1024)
 #define HANDSHAKE_RETRY_COUNT 20
 #define HANDSHAKE_TIMEOUT_MSEC 500
-#define AT_BUFF_MAX 100
+#define AT_BUFF_MAX 1024
 
 static pthread_t s_tid_reader;
 static int s_at_fd = -1;    /* fd of the AT channel */
diff --git a/mbtk/mbtk_rild_v2/src/main.c b/mbtk/mbtk_rild_v2/src/main.c
index 5565621..f0dfb60 100755
--- a/mbtk/mbtk_rild_v2/src/main.c
+++ b/mbtk/mbtk_rild_v2/src/main.c
@@ -46,11 +46,13 @@
 #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"

+#define RIL_CALL_NUM_MAX 10

 

 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;

+static mbtk_ril_call_state_info_t call_list[RIL_CALL_NUM_MAX];

 extern mbtk_cell_pack_info_t cell_info;

 extern ril_cgact_wait_t cgact_wait;

 

@@ -61,8 +63,13 @@
 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 data_call_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);

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

+

+void data_call_state_change_cb(int cid, bool action, bool auto_change, int reason);

+static int send_pack_to_queue(sock_cli_info_t* cli_info, void* pack);

 

 /* Called on command thread */

 static void onATTimeout()

@@ -283,7 +290,401 @@
     }
 }

 

-static void urc_pdp_state_process(const char *s, const char *sms_pdu)

+static void ril_state_change(ril_msg_id_enum msg_id, void *data, int data_len)

+{
+    sock_cli_info_t *cli = NULL;

+    list_first(ril_info.sock_client_list);

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

+    {
+        if(cli->ind_num > 0) {
+            int i;
+            for(i = 0; i < IND_REGISTER_MAX; i++) {
+                if(cli->ind_register[i] == msg_id) {

+                    ril_ind_pack_send(cli->fd, msg_id, data, data_len);

+                    break;
+                }
+            }
+        }
+    }
+}

+

+static int urc_msg_distribute(bool async_process, ril_msg_id_enum msg_id, void *data, int data_len)

+{

+    // Send urc msg to client.

+    if(msg_id > RIL_MSG_ID_IND_BEGIN && msg_id < RIL_MSG_ID_IND_END) {

+        ril_state_change(msg_id, data, data_len);

+    }

+

+    // Async process urc msg.

+    if(async_process) {
+        ril_urc_msg_info_t *msg = (ril_urc_msg_info_t*)malloc(sizeof(ril_urc_msg_info_t));

+        if(msg) {

+            msg->msg = msg_id;

+            msg->data = mbtk_memcpy(data, data_len);

+            msg->data_len = data_len;

+            if(msg->data == NULL) {

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

+                return -1;

+            }

+

+            return send_pack_to_queue(NULL, msg);

+        } else {

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

+            return -1;

+        }

+    }

+

+    return 0;

+}

+

+// *SIMDETEC:1,SIM

+// *EUICC:1

+// +CPIN: SIM PIN

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

+{

+    mbtk_ril_sim_state_info_t state;

+    memset(&state, 0, sizeof(mbtk_ril_sim_state_info_t));

+    state.sim_type = MBTK_UNKNOWN;

+

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

+    char *line = tmp_s;

+    int tmp_int;

+    char *tmp_str;

+

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

+        if (at_tok_start(&line) < 0)

+        {

+            goto SIM_STATE_EXIT;

+        }

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

+        {

+            goto SIM_STATE_EXIT;

+        }

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

+        {

+            goto SIM_STATE_EXIT;

+        }

+

+        if(tmp_str) {

+            if(strcmp(tmp_str, "NOS") == 0) {

+                state.sim_type = ril_info.sim_type;

+                state.sim_state = MBTK_SIM_STATE_ABSENT;

+                ril_info.sim_state = MBTK_SIM_STATE_ABSENT;

+                urc_msg_distribute(false, RIL_MSG_ID_IND_SIM_STATE_CHANGE, &state, sizeof(mbtk_ril_sim_state_info_t));

+            } else if(strcmp(tmp_str, "SIM") == 0) {

+                state.sim_type = ril_info.sim_type;

+                state.sim_state = MBTK_SIM_STATE_NOT_READY;

+                ril_info.sim_state = MBTK_SIM_STATE_NOT_READY;

+                urc_msg_distribute(false, RIL_MSG_ID_IND_SIM_STATE_CHANGE, &state, sizeof(mbtk_ril_sim_state_info_t));

+            }

+        }

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

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

+        {

+            state.sim_state = MBTK_SIM_STATE_READY;

+        }

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

+        {

+            state.sim_state = MBTK_SIM_STATE_SIM_PIN;

+        }

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

+        {

+            state.sim_state = MBTK_SIM_STATE_SIM_PUK;

+        }

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

+        {

+            state.sim_state = MBTK_SIM_STATE_PH_SIMLOCK_PIN;

+        }

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

+        {

+            state.sim_state = MBTK_SIM_STATE_PH_SIMLOCK_PUK;

+        }

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

+        {

+            state.sim_state = MBTK_SIM_STATE_PH_FSIM_PIN;

+        }

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

+        {

+            state.sim_state = MBTK_SIM_STATE_PH_FSIM_PUK;

+        }

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

+        {

+            state.sim_state = MBTK_SIM_STATE_SIM_PIN2;

+        }

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

+        {

+            state.sim_state = MBTK_SIM_STATE_SIM_PUK2;

+        }

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

+        {

+            state.sim_state = MBTK_SIM_STATE_PH_NET_PIN;

+        }

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

+        {

+            state.sim_state = MBTK_SIM_STATE_PH_NET_PUK;

+        }

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

+        {

+            state.sim_state = MBTK_SIM_STATE_PH_NETSUB_PIN;

+        }

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

+        {

+            state.sim_state = MBTK_SIM_STATE_PH_NETSUB_PUK;

+        }

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

+        {

+            state.sim_state = MBTK_SIM_STATE_PH_SP_PIN;

+        }

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

+        {

+            state.sim_state = MBTK_SIM_STATE_PH_SP_PUK;

+        }

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

+        {

+            state.sim_state = MBTK_SIM_STATE_PH_CORP_PIN;

+        }

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

+        {

+            state.sim_state = MBTK_SIM_STATE_PH_CORP_PUK;

+        }

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

+        {

+             state.sim_state = MBTK_SIM_STATE_ABSENT;

+        }

+

+        state.sim_type = ril_info.sim_type;

+        ril_info.sim_state = state.sim_state;

+

+        urc_msg_distribute(false, RIL_MSG_ID_IND_SIM_STATE_CHANGE, &state, sizeof(mbtk_ril_sim_state_info_t));

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

+        if (at_tok_start(&line) < 0)

+        {

+            goto SIM_STATE_EXIT;

+        }

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

+        {

+            goto SIM_STATE_EXIT;

+        }

+        ril_info.sim_type = (mbtk_sim_card_type_enum)tmp_int;

+    } else {

+        LOGW("Unknown URC.");

+    }

+

+SIM_STATE_EXIT:

+    free(tmp_s);

+}

+

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

+// +CALLDISCONNECT: 1

+// +CPAS: 4

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

+{

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

+    char *line = tmp_s;

+    int tmp_int;

+    char *tmp_str;

+

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

+        if (at_tok_start(&line) < 0)

+        {

+            goto CALL_STATE_EXIT;

+        }

+        if (at_tok_nextint(&line, &tmp_int) < 0) // call id

+        {

+            goto CALL_STATE_EXIT;

+        }

+

+        int i = 0;

+        while(i < RIL_CALL_NUM_MAX) {

+            if(call_list[i].call_id == tmp_int)

+                break;

+            i++;

+        }

+        if(i == RIL_CALL_NUM_MAX) { // No found this call id.

+            i = 0;

+            while(i < RIL_CALL_NUM_MAX) { // Find next empty call item.

+                if(call_list[i].call_id == 0)

+                    break;

+                i++;

+            }

+            call_list[i].call_id = tmp_int;

+        }

+

+        LOGD("Found call id : %d", call_list[i].call_id);

+

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

+        {

+            goto CALL_STATE_EXIT;

+        }

+        call_list[i].dir = (mbtk_ril_call_dir_enum)tmp_int;

+

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

+        {

+            goto CALL_STATE_EXIT;

+        }

+        call_list[i].state = (mbtk_ril_call_state_enum)tmp_int;

+

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

+        {

+            goto CALL_STATE_EXIT;

+        }

+

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

+        {

+            goto CALL_STATE_EXIT;

+        }

+

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

+        {

+            goto CALL_STATE_EXIT;

+        }

+        memset(call_list[i].call_number, 0, sizeof(call_list[i].call_number));

+        if(tmp_str && strlen(tmp_str) > 0) {

+            memcpy(call_list[i].call_number, tmp_str, strlen(tmp_str));

+        }

+

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

+        {

+            goto CALL_STATE_EXIT;

+        }

+        call_list[i].num_type = (mbtk_ril_call_num_type_enum)tmp_int;

+

+        urc_msg_distribute(false, RIL_MSG_ID_IND_CALL_STATE_CHANGE, &(call_list[i]), sizeof(mbtk_ril_call_state_info_t));

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

+        if (at_tok_start(&line) < 0)

+        {

+            goto CALL_STATE_EXIT;

+        }

+        if (at_tok_nextint(&line, &tmp_int) < 0) // call id

+        {

+            goto CALL_STATE_EXIT;

+        }

+

+        int i = 0;

+        while(i < RIL_CALL_NUM_MAX) {

+            if(call_list[i].call_id == tmp_int)

+                break;

+            i++;

+        }

+

+        if(i == RIL_CALL_NUM_MAX) { // No found this call id.

+            LOGE("No found this call id : %d", tmp_int);

+            goto CALL_STATE_EXIT;

+        }

+

+        call_list[i].state = MBTK_RIL_CALL_STATE_DISCONNECT;

+

+        urc_msg_distribute(false, RIL_MSG_ID_IND_CALL_STATE_CHANGE, &(call_list[i]), sizeof(mbtk_ril_call_state_info_t));

+

+        // Reset after call disconnect.

+        memset(&(call_list[i]), 0, sizeof(mbtk_ril_call_state_info_t));

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

+

+    } else {

+        LOGW("Unknown URC.");

+    }

+

+CALL_STATE_EXIT:

+    free(tmp_s);

+}

+

+// *ECALLDATA: <urc_id>[,<urc_data>]

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

+{

+    mbtk_ril_ecall_state_info_t ecall_state;

+    memset(&ecall_state, 0, sizeof(mbtk_ril_ecall_state_info_t));

+

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

+    char *line = tmp_s;

+    int tmp_int;

+    char *tmp_str;

+    if (at_tok_start(&line) < 0)

+    {

+        goto ECALLDATA_EXIT;

+    }

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

+    {

+        goto ECALLDATA_EXIT;

+    }

+    ecall_state.urc_id = (uint8)tmp_int; // urc_id

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

+    {

+        goto ECALLDATA_EXIT;

+    }

+

+    if(tmp_str && strlen(tmp_str) > 0) {

+        memcpy(ecall_state.urc_data, tmp_str, strlen(tmp_str));

+    }

+

+    urc_msg_distribute(false, RIL_MSG_ID_IND_ECALL_STATE_CHANGE, &ecall_state, sizeof(mbtk_ril_ecall_state_info_t));

+ECALLDATA_EXIT:

+    free(tmp_s);

+}

+

+// +CMT: ,23

+// 0891683108200855F6240D91688189911196F10000221130717445230331D90C

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

+{

+

+}

+

+// +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

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

+{

+    mbtk_ril_net_reg_state_info_t state;

+    memset(&state, 0, sizeof(mbtk_ril_net_reg_state_info_t));

+    state.tech = MBTK_RADIO_TECH_UNKNOWN;

+

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

+    {

+        state.type = MBTK_NET_REG_TYPE_CALL;

+    } else if(strStartsWith(s, "+CGREG:")) {

+        state.type = MBTK_NET_REG_TYPE_DATA_GSM_WCDMA;

+    } else {

+        state.type = MBTK_NET_REG_TYPE_DATA_LTE;

+    }

+

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

+    char *line = tmp_s;

+    int tmp_int;

+    char *tmp_str;

+    if (at_tok_start(&line) < 0)

+    {

+        goto CGREG_EXIT;

+    }

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

+    {

+        goto CGREG_EXIT;

+    }

+    state.reg_state = (mbtk_net_reg_state_enum)tmp_int; // Reg State.

+    if (state.reg_state) // Reg

+    {

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

+        {

+            goto CGREG_EXIT;

+        }

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

+        {

+            goto CGREG_EXIT;

+        }

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

+        {

+            goto CGREG_EXIT;

+        }

+        state.tech = (mbtk_radio_technology_enum)tmp_int; // AcT

+    }

+

+    urc_msg_distribute(false, RIL_MSG_ID_IND_NET_REG_STATE_CHANGE, &state, sizeof(mbtk_ril_net_reg_state_info_t));

+CGREG_EXIT:

+    free(tmp_s);

+}

+

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

 {

     // "CONNECT"

     if(strStartsWith(s, "CONNECT"))

@@ -346,41 +747,47 @@
         // "+CGEV: EPS PDN ACT ")) { // +CGEV: EPS PDN ACT <cid>

         // "+CGEV: ME PDN DEACT ")) { // +CGEV: EPS PDN DEACT <cid>

         // "+CGEV: ME PDN ACT ")) { // +CGEV: ME PDN ACT <cid>,1

-        int cid = -1;

-        int reason = -1;

-        bool act = FALSE;

-        if (sscanf(s, "+CGEV: NW PDN DEACT %d", &cid) == 1) {

-            act = FALSE;

-        } else if (sscanf(s, "+CGEV: ME PDN DEACT %d", &cid) == 1) {

-            act = FALSE;

-        } else if(sscanf(s, "+CGEV: ME PDN ACT %d,%d", &cid, &reason) == 2

-                || sscanf(s, "+CGEV: ME PDN ACT %d", &cid) == 1) {

-            act = TRUE;

+        mbtk_ril_pdp_state_info_t cgev_info;

+        memset(&cgev_info, 0, sizeof(mbtk_ril_pdp_state_info_t));

+        if (sscanf(s, "+CGEV: NW PDN DEACT %d", &(cgev_info.cid)) == 1) {

+            cgev_info.action = FALSE;

+        } else if (sscanf(s, "+CGEV: ME PDN DEACT %d", &(cgev_info.cid)) == 1) {

+            cgev_info.action = FALSE;

+        } else if(sscanf(s, "+CGEV: ME PDN ACT %d,%d", &(cgev_info.cid), &(cgev_info.reason)) == 2

+                || sscanf(s, "+CGEV: ME PDN ACT %d", &(cgev_info.cid)) == 1) {

+            cgev_info.action = TRUE;

         } else if (!strcmp(s, "+CGEV: ME DETACH")) {

             if(cgact_wait.waitting) {

-                cid = cgact_wait.cid;

+                cgev_info.cid = cgact_wait.cid;

             }

-            act = FALSE;

-        } else if (sscanf(s, "+CGEV: NW MODIFY %d,%d", &cid, &reason) == 2) {

-            act = TRUE;

-        } else if(sscanf(s, "+CGEV: EPS PDN ACT %d", &cid) == 1) {

-            act = TRUE;

+            cgev_info.action = FALSE;

+        } else if (sscanf(s, "+CGEV: NW MODIFY %d,%d", &(cgev_info.cid), &(cgev_info.reason)) == 2) {

+            cgev_info.action = TRUE;

+        } else if(sscanf(s, "+CGEV: EPS PDN ACT %d", &(cgev_info.cid)) == 1) {

+            cgev_info.action = TRUE;

         } else {

             LOGD(">>>>>>>>>No process +CGEV <<<<<<<<<");

             return;

         }

+        cgev_info.auto_change = !cgact_wait.waitting;

 

         if(cgact_wait.act) {

-            if(cgact_wait.waitting && act && cgact_wait.cid == cid) {

+            if(cgact_wait.waitting && cgev_info.action && cgact_wait.cid == cgev_info.cid) {

                 cgact_wait.waitting = false;

             }

         } else {

-            if(cgact_wait.waitting && !act && cgact_wait.cid == cid) {

+            if(cgact_wait.waitting && !cgev_info.action && cgact_wait.cid == cgev_info.cid) {

                 cgact_wait.waitting = false;

             }

         }

 

-        LOGD("+CGEV:cid - %d, act - %d, reason - %d", cid, act, reason);

+        LOGD("+CGEV:cid - %d, act - %d, auto_change - %d, reason - %d", cgev_info.cid, cgev_info.action,

+            cgev_info.auto_change, cgev_info.reason);

+

+        if(cgev_info.cid >= MBTK_APN_CID_MIN && cgev_info.cid <= MBTK_APN_CID_MAX) {

+            urc_msg_distribute(false, RIL_MSG_ID_IND_PDP_STATE_CHANGE, &cgev_info, sizeof(mbtk_ril_pdp_state_info_t));

+        }

+

 #else

         if(at_process) {

             if(cgact_wait.act) {

@@ -1217,7 +1624,7 @@
     {

 

     } else if(strStartsWith(s, "CONNECT") || strStartsWith(s, "+CGEV:")) {

-        urc_pdp_state_process(s, sms_pdu);

+        urc_pdp_state_change_process(s, sms_pdu);

     } else if(strStartsWith(s, "+EEMLTESVC:") || strStartsWith(s, "+EEMLTEINTER:")

         || strStartsWith(s, "+EEMLTEINTRA:") || strStartsWith(s, "+EEMLTEINTERRAT:")

         || strStartsWith(s, "+EEMUMTSSVC:") || strStartsWith(s, "+EEMUMTSINTRA:")

@@ -1226,7 +1633,6 @@
         || strStartsWith(s, "+EEMGINFONC:")) {

         urc_cell_info_process(s, sms_pdu);

     }

-#if 0

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

     {

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

@@ -1235,114 +1641,14 @@
             ptr++;

         }

 

-        uint8 state;

+        mbtk_ril_radio_state_info_t state;

+        memset(&state, 0, sizeof(mbtk_ril_radio_state_info_t));

         if(*ptr == '1') {

-            //net_info.radio_state = MBTK_RADIO_STATE_ON;

-            // mbtk_radio_ready_cb();

-            state = (uint8)1;

+            state.radio_state = MBTK_RADIO_STATE_FULL_FUNC;

         } else {

-            //net_info.radio_state = MBTK_RADIO_STATE_OFF;

-            state = (uint8)0;

+            state.radio_state = MBTK_RADIO_STATE_MINI_FUNC;

         }

-        urc_msg_distribute(true, INFO_URC_MSG_RADIO_STATE, &state, 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);

-        }

+        urc_msg_distribute(true, RIL_MSG_ID_IND_RADIO_STATE_CHANGE, &state, sizeof(mbtk_ril_radio_state_info_t));

     }

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

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

@@ -1351,105 +1657,33 @@
     // $CREG: 1, "8010", "000060a7", 0,, 2, 0

     // +CGREG: 1

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

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

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

+         || strStartsWith(s, "+CREG:"))     // GMS/WCDMA/LTE CS 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);

+        urc_net_reg_state_change_process(s, sms_pdu);

     }

-    // +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.

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

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

+        || strStartsWith(s, "+CPAS:")

+        || strStartsWith(s, "+CALLDISCONNECT:"))

     {

-        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);

+        urc_call_state_change_process(s, sms_pdu);

     }

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

+        || strStartsWith(s, "*EUICC:")

+        || strStartsWith(s, "+CPIN:"))

+    {

+        urc_sim_state_change_process(s, sms_pdu);

+    }

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

+    {

+        urc_sms_state_change_process(s, sms_pdu);

+    }

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

+    {

+        urc_ecall_state_change_process(s, sms_pdu);

+    }

+#if 0

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

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

     {

@@ -1742,32 +1976,6 @@
         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

-

 #endif

     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"

     {

@@ -1886,37 +2094,40 @@
 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);
-    }
+    if(pack->msg_type == RIL_MSG_TYPE_REQ)

+    {

+        if(pack->msg_id > RIL_MSG_ID_IND_BEGIN

+            && pack->msg_id < RIL_MSG_ID_IND_END) {

+            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 {

+            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);

+        }

+    } else {

+        LOGE("Pack type error : %d", pack->msg_type);

+    }

 }

 

 // Return MBTK_INFO_ERR_SUCCESS,will call pack_error_send() to send RSP.
@@ -1929,12 +2140,16 @@
         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_DATA_CALL_BEGIN && pack->msg_id < RIL_MSG_ID_DATA_CALL_END) {

+        return data_call_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 if(pack->msg_id > RIL_MSG_ID_ECALL_BEGIN && pack->msg_id < RIL_MSG_ID_ECALL_END) {

+        return ecall_pack_req_process(cli_info, pack);

     } else {

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

         return MBTK_RIL_ERR_FORMAT;

@@ -1943,15 +2158,18 @@
 

 static void urc_msg_process(ril_urc_msg_info_t *msg)

 {
-    uint8 *data = NULL;
-    if(msg->data) {
-        data = (uint8*)msg->data;
-    }
+    if(!msg->data || msg->data_len <= 0) {

+        LOGE("URC data is NULL.");

+        return;

+    }

+

     switch(msg->msg) {
-        case RIL_URC_MSG_RADIO_STATE:

-        {
+        case RIL_MSG_ID_IND_RADIO_STATE_CHANGE:

+        {

+            mbtk_ril_radio_state_info_t *state = (mbtk_ril_radio_state_info_t*)msg->data;

+            LOGD("Radio state : %d", state->radio_state);

             break;
-        }
+        }

         default:
         {
             LOGE("Unknown URC : %d", msg->msg);
@@ -2046,8 +2264,9 @@
                                 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);

+                                // Send msg RIL_MSG_ID_IND_SER_STATE_CHANGE to client.

+                                mbtk_ril_ser_state_enum state = MBTK_RIL_SER_STATE_READY;

+                                ril_ind_pack_send(client_fd, RIL_MSG_ID_IND_SER_STATE_CHANGE, &state, 1);

                             }
                             else
                             {
@@ -2135,13 +2354,15 @@
                 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);
+            } else { // REQ from myself.

+                if(item->pack) {

+                    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);

+                }

             }
         }
     }
diff --git a/mbtk/mbtk_rild_v2/src/ril_data_call.c b/mbtk/mbtk_rild_v2/src/ril_data_call.c
index 97ff338..14d1128 100755
--- a/mbtk/mbtk_rild_v2/src/ril_data_call.c
+++ b/mbtk/mbtk_rild_v2/src/ril_data_call.c
@@ -17,6 +17,13 @@
 #include "mbtk_utils.h"
 #include "ril_info.h"
 
+ril_cgact_wait_t cgact_wait;
+static ril_data_call_info_t info_list[MBTK_APN_CID_MAX];
+
+static int req_apn_get(bool get_def_cid, mbtk_apn_info_array_t *apns, int *cme_err);
+static int req_apn_set(mbtk_apn_info_t *apn, int *cme_err);
+static void apn_prop_get(mbtk_apn_info_array_t *apns);
+
 /*
 IPv4 : 10.255.74.26
 IPv6 : 254.128.0.0.0.0.0.0.0.1.0.2.144.5.212.239
@@ -200,3 +207,1140 @@
     return net_ifc_config(cid, def_route, as_dns, ip_info);
 }
 
+static int apn_file_save(const char *file, char *data, int data_len)
+{
+    if(!file) {
+        return -1;
+    }
+
+    if(str_empty(data) || data_len <= 0) { // Delete file
+        return unlink(file);
+    } else {
+        int fd = open(file, O_CREAT | O_WRONLY | O_TRUNC, 0644);
+        if(fd < 0) {
+            LOGE("open(%s) fail:%d", file, errno);
+            return -1;
+        }
+
+        if(write(fd, data, data_len) != data_len) {
+            LOGE("write fail:%d", errno);
+            close(fd);
+            return -1;
+        }
+        close(fd);
+        return 0;
+    }
+}
+
+static int apn_file_read(const char *file, char *data, int data_len)
+{
+    if(!file) {
+        LOGE("file is null");
+        return -1;
+    }
+
+    if(data == NULL || data_len <= 100) {
+        LOGE("apn_file_read() arg error.");
+        return -1;
+    } else {
+        int len = -1;
+        int fd = open(file, O_RDONLY, 0644);
+        if(fd < 0) {
+            LOGE("open(%s) fail:%d", file, errno);
+            return -1;
+        }
+
+        memset(data, 0, data_len);
+        if((len = read(fd, data, data_len)) < 0) {
+            LOGE("read fail:%d", errno);
+            close(fd);
+            return -1;
+        }
+        close(fd);
+        return len;
+    }
+}
+
+
+void apn_auto_conf_from_prop()
+{
+    mbtk_apn_info_array_t apns;
+    int i = 0;
+    memset(&apns, 0, sizeof(mbtk_apn_info_array_t));
+    apn_prop_get(&apns);
+    while(i < apns.num) {
+        int cme_err = MBTK_RIL_ERR_CME_NON;
+        if(req_apn_set(&(apns.apns[i]), &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+        {
+            LOGD("Set APN fail.");
+        }
+        else
+        {
+            LOGD("Set APN - %d success.", apns.apns[i].cid);
+        }
+        i++;
+    }
+}
+
+static bool apn_conf_support(mbtk_ril_cid_enum cid)
+{
+    if(cid == MBTK_RIL_CID_DEF) {
+        /*
+        uci show wan_default.default.enable
+        wan_default.default.enable='1'
+
+        uci get wan_default.default.enable
+        1
+        */
+        char buff[128] = {0};
+        if(mbtk_cmd_line("uci get wan_default.default.enable", buff, sizeof(buff)) && strlen(buff) > 0) {
+            return buff[0] == '1' ? FALSE : TRUE;
+        }
+    }
+    return TRUE;
+}
+
+static int apn_check_and_cid_reset(mbtk_apn_info_t *apn)
+{
+    // Delete apn
+    if(str_empty(apn->apn)) {
+        if(apn->cid == MBTK_RIL_CID_NUL)
+            return -1;
+
+        if(!apn_conf_support(MBTK_RIL_CID_DEF) && apn->cid == MBTK_RIL_CID_DEF)
+            return -1;
+
+        // The cid no use,so can not delete.
+        mbtk_apn_info_array_t apns;
+        int cme_err = MBTK_RIL_ERR_CME_NON;
+        memset(&apns, 0, sizeof(mbtk_apn_info_array_t));
+        if(req_apn_get(FALSE, &apns, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+        {
+            LOGW("Get APN fail.");
+            return 0;
+        }
+        else
+        {
+            int index = 0;
+            while(index < apns.num) {
+                if(apns.apns[index].cid == apn->cid)
+                    return 0;
+                index++;
+            }
+            return -1;
+        }
+    } else { // Add or change APN.
+        int start_cid;
+        bool asr_auto_call_open = !apn_conf_support(MBTK_RIL_CID_DEF);
+        mbtk_apn_info_array_t apns;
+        int cme_err = MBTK_RIL_ERR_CME_NON;
+
+        if(asr_auto_call_open) {
+            start_cid = MBTK_RIL_CID_2;
+        } else {
+            start_cid = MBTK_APN_CID_MIN;
+        }
+        memset(&apns, 0, sizeof(mbtk_apn_info_array_t));
+        if(req_apn_get(TRUE, &apns, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+        {
+            LOGW("Get APN fail.");
+            if(apn->cid == MBTK_RIL_CID_NUL) {
+                apn->cid = start_cid;
+            }
+        }
+        else
+        {
+            int index = 0;
+            bool is_change = FALSE;  // Is add APN default.
+
+            if(apn->cid == MBTK_RIL_CID_NUL) { // Is add (auto set cid).
+                for(; start_cid <= MBTK_APN_CID_MAX; start_cid++) {
+                    index = 0;
+                    while(index < apns.num) {
+                        if(apns.apns[index].cid == start_cid)
+                            break;
+                        index++;
+                    }
+
+                    if(index == apns.num) { // Found not used cid : start_cid.
+                        LOGD("Change CID : %d -> %d", apn->cid, start_cid);
+                        apn->cid = start_cid;
+                        // return 0;
+                        break;
+                    }
+                }
+
+                if(start_cid > MBTK_APN_CID_MAX) {
+                    LOGE("APN full.");
+                    return -1;
+                }
+                is_change = FALSE;
+            } else {
+                index = 0;
+                while(index < apns.num) {
+                    if(apns.apns[index].cid == apn->cid) {
+                        is_change = TRUE;
+                        break;
+                    }
+                    index++;
+                }
+            }
+
+            // Is add,the APN can't same.
+            if(!is_change) {
+                index = 0;
+                while(index < apns.num) {
+                    if(strcmp(apns.apns[index].apn,apn->apn) == 0) {
+                        LOGW("APN : %s exist.", apn->apn);
+                        return -1;
+                    }
+                    index++;
+                }
+            }
+        }
+    }
+    return 0;
+}
+
+static void apn_prop_get(mbtk_apn_info_array_t *apns)
+{
+    char prop_name[128] = {0};
+    char prop_data[1024] = {0};
+    int cid;
+    memset(apns, 0, sizeof(mbtk_apn_info_array_t));
+    bool asr_auto_call_open = !apn_conf_support(MBTK_RIL_CID_DEF);
+
+    // If auto data call is open,the default route is CID 1.
+    if(asr_auto_call_open) {
+        //apns->cid_for_def_route = MBTK_RIL_CID_DEF;
+        //apns->cid_for_def_dns = MBTK_RIL_CID_DEF;
+        cid = MBTK_RIL_CID_2;
+    } else {
+        cid = MBTK_APN_CID_MIN;
+    }
+
+    char def_cid[10] = {0};
+    sprintf(def_cid, "%d", MBTK_RIL_CID_DEF);
+    if(property_get(MBTK_DEF_ROUTE_CID, prop_data, def_cid) > 0 && !str_empty(prop_data)) {
+        apns->cid_for_def_route = (mbtk_ril_cid_enum)atoi(prop_data);
+    }
+    memset(prop_data, 0, sizeof(prop_data));
+    if(property_get(MBTK_DEF_DNS_CID, prop_data, def_cid) > 0 && !str_empty(prop_data)) {
+        apns->cid_for_def_dns = (mbtk_ril_cid_enum)atoi(prop_data);
+    }
+
+    for(; cid <= MBTK_APN_CID_MAX; cid++) {
+        memset(prop_name, 0, sizeof(prop_name));
+        memset(prop_data, 0, sizeof(prop_data));
+
+        sprintf(prop_name, "%s_%d",MBTK_APN_PROP,cid);
+        // ip_type,auth,auto_data_call,apn,user,pass
+#if 0
+        if(property_get(prop_name, prop_data, "") > 0 && !str_empty(prop_data)) {
+#else
+        if(apn_file_read(prop_name, prop_data, sizeof(prop_data)) > 0 && !str_empty(prop_data)) {
+#endif
+            apns->apns[apns->num].cid = (mbtk_ril_cid_enum)cid;
+            char *ptr_1 = prop_data;
+            apns->apns[apns->num].ip_type = (mbtk_ip_type_enum)atoi(ptr_1);
+            ptr_1 = strstr(ptr_1, ",");
+            if(!ptr_1) {
+                continue;
+            }
+            ptr_1++; // Jump ',' to auth
+
+            apns->apns[apns->num].auth = (mbtk_apn_auth_type_enum)atoi(ptr_1);
+            ptr_1 = strstr(ptr_1, ",");
+            if(!ptr_1) {
+                continue;
+            }
+            ptr_1++; // Jump ',' to auto_data_call
+
+            apns->apns[apns->num].auto_boot_call = (uint8)atoi(ptr_1);
+            ptr_1 = strstr(ptr_1, ",");
+            if(!ptr_1) {
+                continue;
+            }
+            ptr_1++; // Jump ',' to apn
+
+            char *ptr_2 = strstr(ptr_1, ",");
+            if(!ptr_2) {
+                continue;
+            }
+            if(memcmp(ptr_1, "NULL", 4)) { // Not "NULL"
+                memcpy(apns->apns[apns->num].apn, ptr_1, ptr_2 - ptr_1); // apn
+            }
+
+            ptr_2++; // Jump ',' to user
+            ptr_1 = strstr(ptr_2, ",");
+            if(!ptr_1) {
+                continue;
+            }
+            if(memcmp(ptr_2, "NULL", 4)) { // Not "NULL"
+                memcpy(apns->apns[apns->num].user, ptr_2, ptr_1 - ptr_2); // user
+            }
+
+            ptr_1++; // Jump ',' to pass
+            ptr_2 = strstr(ptr_1, ",");
+            if(!ptr_2) {
+                continue;
+            }
+            if(memcmp(ptr_1, "NULL", 4)) { // Not "NULL"
+                memcpy(apns->apns[apns->num].pass, ptr_1, ptr_2 - ptr_1); // pass
+            }
+
+            ptr_2++; // Jump ',' to type
+            if(memcmp(ptr_1, "NULL", 4)) { // Not "NULL"
+                memcpy(apns->apns[apns->num].type, ptr_2, strlen(ptr_2)); // type
+            }
+
+            apns->num++;
+        }
+    }
+}
+
+static int apn_prop_get_by_cid(mbtk_ril_cid_enum cid, mbtk_apn_info_t *apn)
+{
+    char prop_name[128] = {0};
+    char prop_data[1024] = {0};
+    memset(apn, 0, sizeof(mbtk_apn_info_t));
+
+    sprintf(prop_name, "%s_%d",MBTK_APN_PROP,cid);
+    // ip_type,auth,auto_data_call,apn,user,pass
+#if 0
+    if(property_get(prop_name, prop_data, "") > 0 && !str_empty(prop_data)) {
+#else
+    if(apn_file_read(prop_name, prop_data, sizeof(prop_data)) > 0 && !str_empty(prop_data)) {
+#endif
+        apn->cid = cid;
+        apn->auto_save = (uint8)1;
+        char *ptr_1 = prop_data;
+        apn->ip_type = (mbtk_ip_type_enum)atoi(ptr_1);
+        ptr_1 = strstr(ptr_1, ",");
+        if(!ptr_1) {
+            return -1;
+        }
+        ptr_1++; // Jump ',' to auth
+
+        apn->auth = (mbtk_apn_auth_type_enum)atoi(ptr_1);
+        ptr_1 = strstr(ptr_1, ",");
+        if(!ptr_1) {
+            return -1;
+        }
+        ptr_1++; // Jump ',' to auto_data_call
+
+        apn->auto_boot_call = (uint8)atoi(ptr_1);
+        ptr_1 = strstr(ptr_1, ",");
+        if(!ptr_1) {
+            return -1;
+        }
+        ptr_1++; // Jump ',' to apn
+
+        char *ptr_2 = strstr(ptr_1, ",");
+        if(!ptr_2) {
+            return -1;
+        }
+        if(memcmp(ptr_1, "NULL", 4)) { // Not "NULL"
+            memcpy(apn->apn, ptr_1, ptr_2 - ptr_1); // apn
+        }
+
+        ptr_2++; // Jump ',' to user
+        ptr_1 = strstr(ptr_2, ",");
+        if(!ptr_1) {
+            return -1;
+        }
+        if(memcmp(ptr_2, "NULL", 4)) { // Not "NULL"
+            memcpy(apn->user, ptr_2, ptr_1 - ptr_2); // user
+        }
+
+        ptr_1++; // Jump ',' to pass
+        ptr_2 = strstr(ptr_1, ",");
+        if(!ptr_2) {
+            return -1;
+        }
+        if(memcmp(ptr_1, "NULL", 4)) { // Not "NULL"
+            memcpy(apn->user, ptr_1, ptr_2 - ptr_1); // pass
+        }
+
+        ptr_2++; // Jump ',' to type
+        if(memcmp(ptr_1, "NULL", 4)) { // Not "NULL"
+            memcpy(apn->type, ptr_2, strlen(ptr_2)); // pass
+        }
+        return 0;
+    }
+    return -1;
+}
+
+static int apn_prop_get_by_cid_without_cgdcont(mbtk_ril_cid_enum cid, mbtk_apn_info_t *apn)
+{
+    char prop_name[128] = {0};
+    char prop_data[1024] = {0};
+
+    sprintf(prop_name, "%s_%d",MBTK_APN_PROP,cid);
+    // ip_type,auth,auto_data_call,apn,user,pass
+#if 0
+    if(property_get(prop_name, prop_data, "") > 0 && !str_empty(prop_data)) {
+#else
+    if(apn_file_read(prop_name, prop_data, sizeof(prop_data)) > 0 && !str_empty(prop_data)) {
+#endif
+        LOGD("APN : %s", prop_data);
+        char *ptr_1 = prop_data;
+        apn->auto_save = (uint8)1;
+        //apn->ip_type = (mbtk_ip_type_enum)atoi(ptr_1);
+        ptr_1 = strstr(ptr_1, ",");
+        if(!ptr_1) {
+            return -1;
+        }
+        ptr_1++; // Jump ',' to auth
+
+        apn->auth = (mbtk_apn_auth_type_enum)atoi(ptr_1);
+        ptr_1 = strstr(ptr_1, ",");
+        if(!ptr_1) {
+            return -1;
+        }
+        ptr_1++; // Jump ',' to auto_data_call
+
+        apn->auto_boot_call = (uint8)atoi(ptr_1);
+        ptr_1 = strstr(ptr_1, ",");
+        if(!ptr_1) {
+            return -1;
+        }
+        ptr_1++; // Jump ',' to apn
+
+        char *ptr_2 = strstr(ptr_1, ",");
+        if(!ptr_2) {
+            return -1;
+        }
+#if 0
+        if(memcmp(ptr_1, "NULL", 4)) { // Not "NULL"
+            memcpy(apn->apn, ptr_1, ptr_2 - ptr_1); // apn
+        }
+#endif
+
+        ptr_2++; // Jump ',' to user
+        ptr_1 = strstr(ptr_2, ",");
+        if(!ptr_1) {
+            return -1;
+        }
+        if(memcmp(ptr_2, "NULL", 4)) { // Not "NULL"
+            memcpy(apn->user, ptr_2, ptr_1 - ptr_2); // user
+        }
+
+        ptr_1++; // Jump ',' to pass
+        ptr_2 = strstr(ptr_1, ",");
+        if(!ptr_2) {
+            return -1;
+        }
+        if(memcmp(ptr_1, "NULL", 4)) { // Not "NULL"
+            memcpy(apn->user, ptr_1, ptr_2 - ptr_1); // pass
+        }
+
+        ptr_2++; // Jump ',' to type
+        if(memcmp(ptr_1, "NULL", 4)) { // Not "NULL"
+            memcpy(apn->type, ptr_2, strlen(ptr_2)); // pass
+        }
+        return 0;
+    } else {
+        apn->auto_save = (uint8)0;
+    }
+    return -1;
+}
+
+static int apn_prop_set(mbtk_apn_info_t *apn)
+{
+    char prop_name[20] = {0};
+    char prop_data[1024] = {0};
+    int ret = -1;
+    if(apn->auto_save) {
+        sprintf(prop_name, "%s_%d", MBTK_APN_PROP, apn->cid);
+        // Delete apn
+        if(!str_empty(apn->apn)) {
+            snprintf(prop_data, 1024, "%d,%d,%d,%s,%s,%s,%s", apn->ip_type, apn->auth, apn->auto_boot_call,
+                apn->apn,
+                str_empty(apn->user) ? "NULL" : apn->user,
+                str_empty(apn->pass) ? "NULL" : apn->pass,
+                str_empty(apn->pass) ? "NULL" : apn->type);
+        }
+
+#if 0
+        ret = property_set(prop_name, prop_data);
+#else
+        if(str_empty(apn->apn)) { // Delete APN
+            ret = apn_file_save(prop_name, NULL, 0);
+        } else {
+            ret = apn_file_save(prop_name, prop_data, strlen(prop_data));
+        }
+#endif
+    }
+
+    if(!ret && apn->def_route) {
+        memset(prop_data, 0, sizeof(prop_data));
+        prop_data[0] = '0' + apn->cid;
+        ret = property_set(MBTK_DEF_ROUTE_CID, prop_data);
+    }
+    if(!ret && apn->as_dns) {
+        memset(prop_data, 0, sizeof(prop_data));
+        prop_data[0] = '0' + apn->cid;
+        ret = property_set(MBTK_DEF_DNS_CID, prop_data);
+    }
+    return ret;
+}
+
+static int apn_prop_reset(mbtk_data_call_info_t *data_info)
+{
+    mbtk_apn_info_t apn;
+    if(apn_prop_get_by_cid(data_info->cid, &apn)) {
+        return -1;
+    } else {
+        apn.auto_boot_call = data_info->auto_boot_call;
+        apn.def_route = data_info->def_route;
+        apn.as_dns = data_info->as_dns;
+        return apn_prop_set(&apn);
+    }
+}
+
+static int wait_cgact_complete(int timeout)
+{
+    int count = timeout * 10; // timeout * 1000 / 100
+    int i = 0;
+
+    while(cgact_wait.waitting && i < count) {
+        i++;
+        usleep(100000); // 100ms
+    }
+
+    memset(&cgact_wait, 0, sizeof(ril_cgact_wait_t));
+    if(i == count) { // Timeout
+        return -1;
+    } else {
+        return 0;
+    }
+}
+
+/*
+AT+CGDCONT?
+
++CGDCONT: 1,"IPV4V6","ctnet","10.142.64.116 254.128.0.0.0.0.0.0.0.0.0.0.0.0.0.1",0,0,0,2,0,0
+
++CGDCONT: 8,"IPV4V6","IMS","254.128.0.0.0.0.0.0.0.0.0.0.0.0.0.1",0,0,0,2,1,1
+
+OK
+
+*/
+static int req_apn_get(bool get_def_cid, mbtk_apn_info_array_t *apns, int *cme_err)
+{
+    ATResponse *response = NULL;
+    int err = at_send_command_multiline("AT+CGDCONT?", "+CGDCONT:", &response);
+
+    if (err < 0 || response->success == 0 || !response->p_intermediates){
+        if(cme_err) {
+            *cme_err = at_get_cme_error(response);
+        }
+        goto exit;
+    }
+
+    ATLine* lines_ptr = response->p_intermediates;
+    char *line = NULL;
+    int tmp_int;
+    char *tmp_str = NULL;
+    int cid_start;
+    if(apn_conf_support(MBTK_RIL_CID_DEF)) {
+        cid_start = MBTK_RIL_CID_DEF;
+    } else {
+        if(get_def_cid) {
+            cid_start = MBTK_RIL_CID_DEF;
+        } else {
+            cid_start = MBTK_RIL_CID_2;
+        }
+    }
+    /*
+    <apn_num[1]><cid[1]><ip_type[1]><apn_len[2]><apn><user_len[2]><user><pass_len[2]><pass><auth_len[2]><auth>...
+                <cid[1]><ip_type[1]><apn_len[2]><apn><user_len[2]><user><pass_len[2]><pass><auth_len[2]><auth>
+    */
+    while(lines_ptr)
+    {
+        line = lines_ptr->line;
+        err = at_tok_start(&line);
+        if (err < 0)
+        {
+            goto exit;
+        }
+
+        err = at_tok_nextint(&line, &tmp_int); // cid
+        if (err < 0)
+        {
+            goto exit;
+        }
+        // Only get CID 1-7
+        if(tmp_int >= cid_start && tmp_int <= MBTK_APN_CID_MAX) {
+            apns->apns[apns->num].cid = (mbtk_ril_cid_enum)tmp_int;
+
+            err = at_tok_nextstr(&line, &tmp_str);// ip type
+            if (err < 0)
+            {
+                goto exit;
+            }
+            if(!strcasecmp(tmp_str, "IP")) {
+                apns->apns[apns->num].ip_type = MBTK_IP_TYPE_IP;
+            } else if(!strcasecmp(tmp_str, "IPV6")) {
+                apns->apns[apns->num].ip_type = MBTK_IP_TYPE_IPV6;
+            } else if(!strcasecmp(tmp_str, "IPV4V6")) {
+                apns->apns[apns->num].ip_type = MBTK_IP_TYPE_IPV4V6;
+            } else {
+                apns->apns[apns->num].ip_type = MBTK_IP_TYPE_PPP;
+            }
+
+            err = at_tok_nextstr(&line, &tmp_str); // apn
+            if (err < 0)
+            {
+                goto exit;
+            }
+            if(!str_empty(tmp_str)) {
+                memcpy(apns->apns[apns->num].apn, tmp_str, strlen(tmp_str));
+            }
+
+            // Get other arg from proc or file.
+            apn_prop_get_by_cid_without_cgdcont(apns->apns[apns->num].cid, &(apns->apns[apns->num]));
+
+            apns->num++;
+        }
+
+        lines_ptr = lines_ptr->p_next;
+    }
+
+    char prop_name[128] = {0};
+    char prop_data[1024] = {0};
+    char def_cid[10] = {0};
+    sprintf(def_cid, "%d", MBTK_RIL_CID_DEF);
+
+    if(property_get(MBTK_DEF_ROUTE_CID, prop_data, def_cid) > 0 && !str_empty(prop_data)) {
+        apns->cid_for_def_route = (mbtk_ril_cid_enum)atoi(prop_data);
+    }
+    memset(prop_data, 0, sizeof(prop_data));
+    if(property_get(MBTK_DEF_DNS_CID, prop_data, def_cid) > 0 && !str_empty(prop_data)) {
+        apns->cid_for_def_dns = (mbtk_ril_cid_enum)atoi(prop_data);
+    }
+
+    goto exit;
+exit:
+    at_response_free(response);
+    return err;
+}
+
+/*
+AT+CGDCONT=1,"IPV4V6","cmnet"
+OK
+
+AT*AUTHReq=1,1,marvell,123456
+OK
+
+*/
+static int req_apn_set(mbtk_apn_info_t *apn, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char cmd[400] = {0};
+    int index = 0;
+    int err = 0;
+
+    // Delete apn
+    if(str_empty(apn->apn)) {
+        sprintf(cmd, "AT+CGDCONT=%d", apn->cid);
+        err = at_send_command(cmd, &response);
+        if (err < 0 || response->success == 0){
+            if(cme_err) {
+                *cme_err = at_get_cme_error(response);
+            }
+            goto exit;
+        }
+    } else {
+        index += sprintf(cmd, "AT+CGDCONT=%d,", apn->cid);
+        switch(apn->ip_type) {
+            case MBTK_IP_TYPE_IP: {
+                index += sprintf(cmd + index,"\"IP\",");
+                break;
+            }
+            case MBTK_IP_TYPE_IPV6: {
+                index += sprintf(cmd + index,"\"IPV6\",");
+                break;
+            }
+            case MBTK_IP_TYPE_IPV4V6: {
+                index += sprintf(cmd + index,"\"IPV4V6\",");
+                break;
+            }
+            default: {
+                index += sprintf(cmd + index,"\"PPP\",");
+                break;
+            }
+        }
+        if(strlen(apn->apn) > 0) {
+            index += sprintf(cmd + index,"\"%s\"", apn->apn);
+        }
+
+        err = at_send_command(cmd, &response);
+        if (err < 0 || response->success == 0){
+            if(cme_err) {
+                *cme_err = at_get_cme_error(response);
+            }
+            goto exit;
+        }
+
+        if(!str_empty(apn->user) || !str_empty(apn->pass)) {
+            at_response_free(response);
+
+            memset(cmd,0,400);
+            int cmd_auth=0;
+            if(apn->auth == MBTK_APN_AUTH_PROTO_NONE)
+                cmd_auth = 0;
+            else if(apn->auth == MBTK_APN_AUTH_PROTO_PAP)
+                cmd_auth = 1;
+            else if(apn->auth == MBTK_APN_AUTH_PROTO_CHAP)
+                cmd_auth = 2;
+            else
+                goto exit;
+
+            sprintf(cmd, "AT*AUTHREQ=%d,%d,%s,%s",apn->cid,cmd_auth,apn->user,apn->pass);
+            err = at_send_command(cmd, &response);
+            if (err < 0 || response->success == 0){
+                if(cme_err) {
+                    *cme_err = at_get_cme_error(response);
+                }
+                goto exit;
+            }
+        }
+    }
+
+exit:
+    at_response_free(response);
+    return err;
+}
+
+/*
+AT+CGACT?
++CGACT: 1,1
++CGACT: 8,1
+OK
+
+AT+CGACT=1,<cid>
+OK
+
+*/
+static int req_data_call_start(mbtk_ril_cid_enum cid, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char cmd[400] = {0};
+    int err = 0;
+    memset(&cgact_wait, 0, sizeof(ril_cgact_wait_t));
+    cgact_wait.waitting = true;
+    cgact_wait.cid = cid;
+    cgact_wait.act = true;
+
+    sprintf(cmd, "AT+CGACT=1,%d", cid);
+    err = at_send_command(cmd, &response);
+    if (err < 0 || response->success == 0){
+        if(cme_err) {
+            *cme_err = at_get_cme_error(response);
+        }
+        goto exit;
+    }
+
+exit:
+    at_response_free(response);
+    return err;
+}
+
+/*
+AT+CGACT=0,<cid>
+OK
+
+*/
+static int req_data_call_stop(mbtk_ril_cid_enum cid, int timeout, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char cmd[400] = {0};
+    int err = 0;
+
+    memset(&cgact_wait, 0, sizeof(ril_cgact_wait_t));
+    cgact_wait.waitting = true;
+    cgact_wait.cid = cid;
+    cgact_wait.act = false;
+
+    sprintf(cmd, "AT+CGACT=0,%d", cid);
+    err = at_send_command(cmd, &response);
+    if (err < 0 || response->success == 0){
+        if(cme_err) {
+            *cme_err = at_get_cme_error(response);
+        }
+        goto exit;
+    }
+
+exit:
+    at_response_free(response);
+    return err;
+}
+
+/*
+AT+CGCONTRDP=1
++CGCONTRDP: 1,7,"cmnet-2.MNC000.MCC460.GPRS","10.255.74.26","","223.87.253.100","223.87.253.253","","",0,0
++CGCONTRDP: 1,7,"cmnet-2.MNC000.MCC460.GPRS","254.128.0.0.0.0.0.0.0.1.0.2.144.5.212.239","","36.9.128.98.32.0.0.2.0.0.0.0.0.0.0.1","36.9.128.98.32.0.0.2.0.0.0.0.0.0.0.2","","",0,0
+
+OK
+
+*/
+static int req_data_call_state_get(mbtk_ril_cid_enum cid, mbtk_ip_info_t *ip_info, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char cmd[50] = {0};
+    int err = 0;
+
+    sprintf(cmd, "AT+CGCONTRDP=%d", cid);
+
+    err = at_send_command_multiline(cmd, "+CGCONTRDP:", &response);
+    if (err < 0 || response->success == 0 || !response->p_intermediates){
+        *cme_err = at_get_cme_error(response);
+        goto exit;
+    }
+    ATLine* lines_ptr = response->p_intermediates;
+    char *line = NULL;
+    int tmp_int;
+    char *tmp_ptr = NULL;
+    while(lines_ptr)
+    {
+        line = lines_ptr->line;
+        err = at_tok_start(&line);
+        if (err < 0)
+        {
+            goto exit;
+        }
+
+        err = at_tok_nextint(&line, &tmp_int); // cid
+        if (err < 0)
+        {
+            goto exit;
+        }
+        err = at_tok_nextint(&line, &tmp_int); // bearer_id
+        if (err < 0)
+        {
+            goto exit;
+        }
+        err = at_tok_nextstr(&line, &tmp_ptr); // APN
+        if (err < 0)
+        {
+            goto exit;
+        }
+
+        err = at_tok_nextstr(&line, &tmp_ptr); // IP
+        if (err < 0 || str_empty(tmp_ptr))
+        {
+            goto exit;
+        }
+        if(is_ipv4(tmp_ptr)) {
+            if(inet_pton(AF_INET, tmp_ptr, &(ip_info->ipv4.IPAddr)) < 0) {
+                LOGE("inet_pton() fail.");
+                err = -1;
+                goto exit;
+            }
+
+            ip_info->ipv4.valid = true;
+            //log_hex("IPv4", &(ipv4->IPAddr), sizeof(struct in_addr));
+        } else {
+            if(str_2_ipv6(tmp_ptr, &(ip_info->ipv6.IPV6Addr))) {
+                LOGE("str_2_ipv6() fail.");
+                err = -1;
+                goto exit;
+            }
+
+            ip_info->ipv6.valid = true;
+            //log_hex("IPv6", &(ipv6->IPV6Addr), 16);
+        }
+
+        err = at_tok_nextstr(&line, &tmp_ptr); // Gateway
+        if (err < 0)
+        {
+            goto exit;
+        }
+        if(!str_empty(tmp_ptr)) { // No found gateway
+            if(is_ipv4(tmp_ptr)) {
+                if(inet_pton(AF_INET, tmp_ptr, &(ip_info->ipv4.GateWay)) < 0) {
+                    LOGE("inet_pton() fail.");
+                    err = -1;
+                    goto exit;
+                }
+
+                //log_hex("IPv4", &(ipv4->GateWay), sizeof(struct in_addr));
+            } else {
+                if(str_2_ipv6(tmp_ptr, &(ip_info->ipv6.GateWay))) {
+                    LOGE("str_2_ipv6() fail.");
+                    err = -1;
+                    goto exit;
+                }
+
+                //log_hex("IPv6", &(ipv6->GateWay), 16);
+            }
+        }
+
+        err = at_tok_nextstr(&line, &tmp_ptr); // prim_DNS
+        if (err < 0)
+        {
+            goto exit;
+        }
+        if(!str_empty(tmp_ptr)) { // No found Primary DNS
+            if(is_ipv4(tmp_ptr)) {
+                if(inet_pton(AF_INET, tmp_ptr, &(ip_info->ipv4.PrimaryDNS)) < 0) {
+                    LOGE("inet_pton() fail.");
+                    err = -1;
+                    goto exit;
+                }
+
+                //log_hex("IPv4", &(ipv4->PrimaryDNS), sizeof(struct in_addr));
+            } else {
+                if(str_2_ipv6(tmp_ptr, &(ip_info->ipv6.PrimaryDNS))) {
+                    LOGE("str_2_ipv6() fail.");
+                    err = -1;
+                    goto exit;
+                }
+
+                //log_hex("IPv6", &(ipv6->PrimaryDNS), 16);
+            }
+        }
+
+        err = at_tok_nextstr(&line, &tmp_ptr); // sec_DNS
+        if (err < 0)
+        {
+            goto exit;
+        }
+        if(!str_empty(tmp_ptr)) { // No found Secondary DNS
+            if(is_ipv4(tmp_ptr)) {
+                if(inet_pton(AF_INET, tmp_ptr, &(ip_info->ipv4.SecondaryDNS)) < 0) {
+                    LOGE("inet_pton() fail.");
+                    err = -1;
+                    goto exit;
+                }
+
+                //log_hex("IPv4", &(ipv4->SecondaryDNS), sizeof(struct in_addr));
+            } else {
+                if(str_2_ipv6(tmp_ptr, &(ip_info->ipv6.SecondaryDNS))) {
+                    LOGE("str_2_ipv6() fail.");
+                    err = -1;
+                    goto exit;
+                }
+
+                //log_hex("IPv6", &(ipv6->SecondaryDNS), 16);
+            }
+        }
+
+        lines_ptr = lines_ptr->p_next;
+    }
+
+exit:
+    at_response_free(response);
+    return err;
+}
+
+void data_call_state_change_cb(int cid, bool action, bool auto_change, int reason)
+{
+    if(auto_change && !action) {
+        info_list[cid - 1].act_state = RIL_ACT_STATE_CONNECTED_RETRY;
+    }
+}
+
+//void net_list_free(void *data);
+// Return MBTK_INFO_ERR_SUCCESS,will call pack_error_send() to send RSP.
+// Otherwise, do not call pack_error_send().
+mbtk_ril_err_enum data_call_pack_req_process(sock_cli_info_t* cli_info, ril_msg_pack_info_t* pack)
+{
+    mbtk_ril_err_enum err = MBTK_RIL_ERR_SUCCESS;
+    int cme_err = MBTK_RIL_ERR_CME_NON;
+    switch(pack->msg_id)
+    {
+        case RIL_MSG_ID_DATA_CALL_APN:
+        {
+            if(pack->data_len == 0 || pack->data == NULL)
+            {
+                mbtk_apn_info_array_t apns;
+                memset(&apns, 0, sizeof(mbtk_apn_info_array_t));
+                if(req_apn_get(FALSE, &apns, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_RIL_ERR_CME_NON) {
+                        err = MBTK_RIL_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_RIL_ERR_UNKNOWN;
+                    }
+                    LOGD("Get APN fail.");
+                }
+                else
+                {
+                    LOGD("size - %d", sizeof(mbtk_apn_info_array_t));
+                    ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &apns, sizeof(mbtk_apn_info_array_t));
+                }
+            }
+            else     // Set
+            {
+                mbtk_apn_info_t *apn = (mbtk_apn_info_t*)pack->data;
+                if(apn_check_and_cid_reset(apn)) {
+                    err = MBTK_RIL_ERR_CID;
+                } else {
+                    if(apn_conf_support(apn->cid)) {
+                        if(req_apn_set(apn, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                        {
+                            if(cme_err != MBTK_RIL_ERR_CME_NON) {
+                                err = MBTK_RIL_ERR_CME + cme_err;
+                            } else {
+                                err = MBTK_RIL_ERR_UNKNOWN;
+                            }
+                            LOGD("Set APN fail.");
+                        }
+                        else
+                        {
+                            if(apn_prop_set(apn)) {
+                                LOGE("Save APN fail.");
+                            }
+
+                            memcpy(&(info_list[apn->cid - 1].apn_info), apn, sizeof(mbtk_apn_info_t));
+
+                            ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+                        }
+                    } else {
+                        err = MBTK_RIL_ERR_UNSUPPORTED;
+                        LOGD("Can not set APN for CID : %d", apn->cid);
+                    }
+                }
+            }
+            break;
+        }
+        case RIL_MSG_ID_DATA_CALL_OPT:
+        {
+            if(pack->data_len == 0 || pack->data == NULL)
+            {
+                err = MBTK_RIL_ERR_UNSUPPORTED;
+            }
+            else     // Set
+            {
+                mbtk_data_call_info_t *call_info = (mbtk_data_call_info_t*)pack->data;
+                // Check for cid 1.
+                if(!apn_conf_support(call_info->cid)) {
+                    err = MBTK_RIL_ERR_UNSUPPORTED;
+                    LOGD("Can not data call for CID : %d", call_info->cid);
+                } else {
+                    if(call_info->type == MBTK_DATA_CALL_START) {
+                        mbtk_ip_info_t ip_info;
+                        memset(&ip_info, 0, sizeof(ip_info));
+#if 0
+                        if(apn_prop_reset(call_info)) {
+                            err = MBTK_RIL_ERR_REQ_UNKNOWN;
+                            LOG("apn_prop_reset() fail.");
+                        } else
+#else
+                        if(apn_prop_reset(call_info)) {
+                            LOG("apn_prop_reset() fail.");
+                        }
+#endif
+                        {
+                            int index = 0;
+                            info_list[call_info->cid - 1].act_state = RIL_ACT_STATE_CONNECTING;
+data_call_retry:
+                            if(req_data_call_start(call_info->cid, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                            {
+                                if(call_info->retry_interval[index] > 0) {
+                                    LOGD("Start data call fail, will retry in %d s.", call_info->retry_interval[index]);
+                                    sleep(call_info->retry_interval[index]);
+                                    index++;
+                                    goto data_call_retry;
+                                } else {
+                                    if(cme_err != MBTK_RIL_ERR_CME_NON) {
+                                        err = MBTK_RIL_ERR_CME + cme_err;
+                                    } else {
+                                        err = MBTK_RIL_ERR_UNKNOWN;
+                                    }
+                                    LOGD("Start data call fail.");
+                                }
+                            }
+                            else
+                            {
+                                // Wait for "CONNECT" or "+CGEV:"
+                                if(wait_cgact_complete(call_info->timeout)) { // Timeout
+                                    err = MBTK_RIL_ERR_TIMEOUT;
+                                    break;
+                                }
+
+                                // Get Ip informations.
+                                cme_err = MBTK_RIL_ERR_CME_NON;
+                                if(req_data_call_state_get(call_info->cid ,&ip_info, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                                {
+                                    LOGD("Get net informations fail.");
+                                    err = MBTK_RIL_ERR_NET_CONF;
+                                }
+                                else
+                                {
+                                    // Config network informations.
+                                    if(net_ifc_reconfig(call_info->cid, call_info->def_route, call_info->as_dns, &ip_info)) {
+                                        err = MBTK_RIL_ERR_NET_CONF;
+                                        break;
+                                    }
+
+                                    info_list[call_info->cid - 1].act_state = RIL_ACT_STATE_CONNECTED;
+
+                                    ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &ip_info, sizeof(mbtk_ip_info_t));
+                                }
+                            }
+                        }
+                    } else if(call_info->type == MBTK_DATA_CALL_STOP) {
+                        info_list[call_info->cid - 1].act_state = RIL_ACT_STATE_DISCONNECTING;
+                        if(req_data_call_stop(call_info->cid, call_info->timeout, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                        {
+                            if(cme_err != MBTK_RIL_ERR_CME_NON) {
+                                err = MBTK_RIL_ERR_CME + cme_err;
+                            } else {
+                                err = MBTK_RIL_ERR_UNKNOWN;
+                            }
+                            LOGD("Stop data call fail.");
+                        }
+                        else
+                        {
+                            // Wait for "CONNECT" or "+CGEV:"
+                            if(wait_cgact_complete(call_info->timeout)) { // Timeout
+                                err = MBTK_RIL_ERR_TIMEOUT;
+                                break;
+                            }
+
+                            // Clean network config.
+                            if(net_ifc_config(call_info->cid, FALSE, FALSE, NULL)) {
+                                err = MBTK_RIL_ERR_NET_CONF;
+                                break;
+                            }
+
+                            info_list[call_info->cid - 1].act_state = RIL_ACT_STATE_DISCONNECTED;
+                            ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+                        }
+                    } else {
+                        mbtk_ip_info_t ip_info;
+                        memset(&ip_info, 0, sizeof(ip_info));
+                        if(req_data_call_state_get(call_info->cid ,&ip_info, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                        {
+                            if(cme_err != MBTK_RIL_ERR_CME_NON) {
+                                err = MBTK_RIL_ERR_CME + cme_err;
+                            } else {
+                                err = MBTK_RIL_ERR_UNKNOWN;
+                            }
+                            LOGD("Get data call state fail.");
+                        }
+                        else
+                        {
+                            ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &ip_info, sizeof(mbtk_ip_info_t));
+                        }
+                    }
+                }
+            }
+            break;
+        }
+        default:
+        {
+            err = MBTK_RIL_ERR_REQ_UNKNOWN;
+            LOG("Unknown request : %s", id2str(pack->msg_id));
+            break;
+        }
+    }
+
+    return err;
+}
+
+
diff --git a/mbtk/mbtk_rild_v2/src/ril_ecall.c b/mbtk/mbtk_rild_v2/src/ril_ecall.c
new file mode 100755
index 0000000..dfb4ace
--- /dev/null
+++ b/mbtk/mbtk_rild_v2/src/ril_ecall.c
@@ -0,0 +1,1141 @@
+#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 <fcntl.h>
+#include <signal.h>
+
+#include "mbtk_type.h"
+#include "mbtk_ril.h"
+#include "atchannel.h"
+#include "at_tok.h"
+#include "mbtk_utils.h"
+#include "ril_info.h"
+
+static mbtk_ecall_mode_type_enum ecall_mode = MBTK_ECALL_MODE_TYPE_EU;
+
+void ril_rsp_pack_send(int fd, int ril_id, int msg_index, const void* data, int data_len);
+
+static int req_ecall_msdcfg(mbtk_ecall_msd_cfg_info_t *cfg_info, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char cmd[1024] = {0};
+    sprintf(cmd, "AT*ECALLMSDCFG=%d,\"%s\",0", cfg_info->item_type, cfg_info->data);
+    int err = at_send_command(cmd, &response);
+    if (err < 0 || response->success == 0){
+        *cme_err = at_get_cme_error(response);
+        goto exit;
+    }
+
+exit:
+    at_response_free(response);
+    return err;
+}
+
+static int req_ecall_msdgen(int *cme_err)
+{
+    ATResponse *response = NULL;
+    int err = at_send_command("AT*ECALLMSDGEN", &response);
+    if (err < 0 || response->success == 0){
+        *cme_err = at_get_cme_error(response);
+        goto exit;
+    }
+
+exit:
+    at_response_free(response);
+    return err;
+}
+
+static int req_ecall_msd_set(const uint8 *msd, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char cmd[1024] = {0};
+    sprintf(cmd, "AT*ECALLMSD=\"%s\"", msd);
+    int err = at_send_command(cmd, &response);
+    if (err < 0 || response->success == 0){
+        *cme_err = at_get_cme_error(response);
+        goto exit;
+    }
+
+exit:
+    at_response_free(response);
+    return err;
+}
+
+static int req_ecall_msd_get(uint8 *msd, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char *tmp_ptr = NULL;
+    int err = at_send_command_singleline("AT*ECALLMSD?", "*ECALLMSD:", &response);
+
+    if (err < 0 || response->success == 0 || !response->p_intermediates){
+        *cme_err = at_get_cme_error(response);
+        goto exit;
+    }
+
+    char *line = response->p_intermediates->line;
+    err = at_tok_start(&line);
+    if (err < 0)
+    {
+        goto exit;
+    }
+
+    err = at_tok_nextstr(&line, &tmp_ptr);
+    if (err < 0)
+    {
+        goto exit;
+    }
+
+    if(tmp_ptr && strlen(tmp_ptr) > 0) {
+        memcpy(msd, tmp_ptr, strlen(tmp_ptr));
+    }
+
+    goto exit;
+exit:
+    at_response_free(response);
+    return err;
+}
+
+static int req_ecall_push(int *cme_err)
+{
+    ATResponse *response = NULL;
+    int err = at_send_command("AT*ECALLPUSH", &response);
+    if (err < 0 || response->success == 0){
+        *cme_err = at_get_cme_error(response);
+        goto exit;
+    }
+
+exit:
+    at_response_free(response);
+    return err;
+}
+
+/*
+AT*ECALLONLY?
+*ECALLONLY: 0,0,18981911691,18981911691
+
+OK
+
+*/
+static int req_ecall_only_get(mbtk_ecall_only_info_t *only_info, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char *tmp_ptr = NULL;
+    int tmp_int;
+    int err = at_send_command_singleline("AT*ECALLONLY?", "*ECALLONLY:", &response);
+
+    if (err < 0 || response->success == 0 || !response->p_intermediates){
+        *cme_err = at_get_cme_error(response);
+        goto exit;
+    }
+
+    char *line = response->p_intermediates->line;
+    err = at_tok_start(&line);
+    if (err < 0)
+    {
+        goto exit;
+    }
+
+    err = at_tok_nextint(&line, &tmp_int);
+    if (err < 0)
+    {
+        goto exit;
+    }
+    only_info->active = (mbtk_ecall_only_type_enum)tmp_int;
+
+    err = at_tok_nextint(&line, &tmp_int);
+    if (err < 0)
+    {
+        goto exit;
+    }
+    only_info->sim_type = (mbtk_ecall_sim_type_enum)tmp_int;
+
+    err = at_tok_nextstr(&line, &tmp_ptr);
+    if (err < 0)
+    {
+        goto exit;
+    }
+
+    if(tmp_ptr && strlen(tmp_ptr) > 0) {
+        memcpy(only_info->test_num, tmp_ptr, strlen(tmp_ptr));
+    }
+
+    err = at_tok_nextstr(&line, &tmp_ptr);
+    if (err < 0)
+    {
+        goto exit;
+    }
+
+    if(tmp_ptr && strlen(tmp_ptr) > 0) {
+        memcpy(only_info->reconfig_num, tmp_ptr, strlen(tmp_ptr));
+    }
+
+    goto exit;
+exit:
+    at_response_free(response);
+    return err;
+}
+
+/*
+AT*ECALLONLY?
+*ECALLONLY: 0,0,18981911691,18981911691
+
+OK
+
+*/
+static int req_ecall_only_set(const mbtk_ecall_only_info_t *only_info, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char cmd[1024] = {0};
+    sprintf(cmd, "AT*ECALLONLY=%d,%s,%s", only_info->active,only_info->test_num,only_info->reconfig_num);
+    int err = at_send_command(cmd, &response);
+    if (err < 0 || response->success == 0){
+        *cme_err = at_get_cme_error(response);
+        goto exit;
+    }
+
+exit:
+    at_response_free(response);
+    return err;
+}
+
+/*
+AT*ECALLREG=0/1
+
+*/
+static int req_ecall_reg_set(uint8 reg, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char cmd[30] = {0};
+    sprintf(cmd, "AT*ECALLREG=%d", reg);
+    int err = at_send_command(cmd, &response);
+    if (err < 0 || response->success == 0){
+        *cme_err = at_get_cme_error(response);
+        goto exit;
+    }
+
+exit:
+    at_response_free(response);
+    return err;
+}
+
+/*
+AT+CECALL?
++CECALL: 4
+
+OK
+
+*/
+static int req_ecall_dial_state_get(mbtk_ecall_dial_type_enum *type, int *cme_err)
+{
+    ATResponse *response = NULL;
+    int tmp_int;
+    int err = at_send_command_singleline("AT+CECALL?", "+CECALL:", &response);
+
+    if (err < 0 || response->success == 0 || !response->p_intermediates){
+        *cme_err = at_get_cme_error(response);
+        goto exit;
+    }
+
+    char *line = response->p_intermediates->line;
+    err = at_tok_start(&line);
+    if (err < 0)
+    {
+        goto exit;
+    }
+
+    err = at_tok_nextint(&line, &tmp_int);
+    if (err < 0)
+    {
+        goto exit;
+    }
+    *type = (mbtk_ecall_dial_type_enum)tmp_int;
+
+    goto exit;
+exit:
+    at_response_free(response);
+    return err;
+}
+
+/*
+AT+CECALL=<ecalltype>
+OK
+*/
+static int req_ecall_dial_start(mbtk_ecall_dial_type_enum type, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char cmd[1024] = {0};
+    sprintf(cmd, "AT+CECALL=%d", type);
+    int err = at_send_command(cmd, &response);
+    if (err < 0 || response->success == 0){
+        *cme_err = at_get_cme_error(response);
+        goto exit;
+    }
+
+exit:
+    at_response_free(response);
+    return err;
+}
+
+
+/*
+AT*ECALLMODE?
+*ECALLMODE: "ERA"
+
+OK
+
+*/
+static int req_ecall_mode_get(mbtk_ecall_mode_type_enum *mode, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char *tmp_ptr = NULL;
+    int err = at_send_command_singleline("AT*ECALLMODE?", "*ECALLMODE:", &response);
+
+    if (err < 0 || response->success == 0 || !response->p_intermediates){
+        *cme_err = at_get_cme_error(response);
+        goto exit;
+    }
+
+    char *line = response->p_intermediates->line;
+    err = at_tok_start(&line);
+    if (err < 0)
+    {
+        goto exit;
+    }
+
+    err = at_tok_nextstr(&line, &tmp_ptr);
+    if (err < 0)
+    {
+        goto exit;
+    }
+
+    if(tmp_ptr && strlen(tmp_ptr) > 0) {
+        if(strcmp(tmp_ptr, "ERA") == 0) {
+            *mode = MBTK_ECALL_MODE_TYPE_ERA;
+        } else {
+            *mode = MBTK_ECALL_MODE_TYPE_EU;
+        }
+
+        ecall_mode = *mode;
+    } else {
+        err =  -1;
+    }
+
+    goto exit;
+exit:
+    at_response_free(response);
+    return err;
+}
+
+/*
+AT*ECALLMODE="ERA"
+OK
+
+*/
+static int req_ecall_mode_set(mbtk_ecall_mode_type_enum mode, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char cmd[1024] = {0};
+    if(mode == MBTK_ECALL_MODE_TYPE_EU) {
+        sprintf(cmd, "AT*ECALLMODE=\"EU\"");
+    } else {
+        sprintf(cmd, "AT*ECALLMODE=\"ERA\"");
+    }
+    int err = at_send_command(cmd, &response);
+    if (err < 0 || response->success == 0){
+        *cme_err = at_get_cme_error(response);
+        goto exit;
+    }
+
+    ecall_mode = mode;
+
+exit:
+    at_response_free(response);
+    return err;
+}
+
+/*
+AT*ECALLDATA=5,2
+*ECALLDATA: 5,2,250
+
+OK
+
+AT*ECALLTIMER?
+*ECALLTIMER: ERA mode, callback timer: 1200s, dial setup timer: 30s, NAD deregister timer: 7200s, cleardown timer: 3600s, redial attempts count: 10, redial wait timer: 30s, smsprocess: 1, SMS resend timer: 3600s, sms msd send count: 10.
+
+OK
+
+*/
+static int req_ecall_cfg_get(mbtk_ecall_cfg_item_enum type, mbtk_ecall_cfg_info_t *cfg, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char *tmp_ptr = NULL;
+    int tmp_int;
+    char cmd[1024] = {0};
+    int err = 0;
+
+    cfg->type = type;
+    switch(type)
+    {
+        case MBTK_ECALL_CFG_ITEM_T3:
+        case MBTK_ECALL_CFG_ITEM_T5:
+        case MBTK_ECALL_CFG_ITEM_T6:
+        case MBTK_ECALL_CFG_ITEM_T7:
+        case MBTK_ECALL_CFG_ITEM_TH:
+            snprintf(cmd, sizeof(cmd), "AT*ECALLDATA=5,%d", type);
+
+            err = at_send_command_singleline(cmd, "*ECALLDATA:", &response);
+            break;
+        default:
+            snprintf(cmd, sizeof(cmd), "AT*ECALLTIMER?");
+
+            err = at_send_command_singleline(cmd, "*ECALLTIMER:", &response);
+            break;
+    }
+
+    if (err < 0 || response->success == 0 || !response->p_intermediates){
+        *cme_err = at_get_cme_error(response);
+        goto exit;
+    }
+
+    char *line = response->p_intermediates->line;
+    err = at_tok_start(&line);
+    if (err < 0)
+    {
+        goto exit;
+    }
+
+    if(strstr(cmd, "AT*ECALLDATA")) {
+        err = at_tok_nextint(&line, &tmp_int);
+        if (err < 0)
+        {
+            goto exit;
+        }
+
+        err = at_tok_nextint(&line, &tmp_int);
+        if (err < 0)
+        {
+            goto exit;
+        }
+
+        err = at_tok_nextint(&line, &tmp_int);
+        if (err < 0)
+        {
+            goto exit;
+        }
+
+        cfg->data = (uint32)(tmp_int * 20);   // ms
+    } else {
+        // *ECALLTIMER: ERA mode, callback timer: 1200s,
+        // dial setup timer: 30s, NAD deregister timer: 7200s,
+        // cleardown timer: 3600s, redial attempts count: 10,
+        // redial wait timer: 30s, smsprocess: 1, SMS resend timer: 3600s,
+        // sms msd send count: 10.
+
+        if(strstr(line, "ERA mode") != NULL) {
+            ecall_mode = MBTK_ECALL_MODE_TYPE_ERA;
+        } else {
+            ecall_mode = MBTK_ECALL_MODE_TYPE_EU;
+        }
+
+        switch(type)
+        {
+            case MBTK_ECALL_CFG_ITEM_TIMER_CALLBACK:
+            {
+                if((tmp_ptr = strstr(line, "callback timer: ")) != NULL) {
+                    cfg->data = (uint32)atoi(tmp_ptr + 16);   // s
+                    cfg->data *= 1000; // s -> ms
+                }
+                break;
+            }
+            case MBTK_ECALL_CFG_ITEM_TIMER_CLEARDOWN:
+            {
+                if((tmp_ptr = strstr(line, "cleardown timer: ")) != NULL) {
+                    cfg->data = (uint32)atoi(tmp_ptr + 17);   // s
+                    cfg->data *= 1000; // s -> ms
+                }
+                break;
+            }
+            case MBTK_ECALL_CFG_ITEM_TIMER_DEREG:
+            {
+                if((tmp_ptr = strstr(line, "deregister timer: ")) != NULL) {
+                    cfg->data = (uint32)atoi(tmp_ptr + 18);   // s
+                    cfg->data *= 1000; // s -> ms
+                }
+                break;
+            }
+            case MBTK_ECALL_CFG_ITEM_TIMER_DIAL:
+            {
+                if((tmp_ptr = strstr(line, "dial setup timer: ")) != NULL) {
+                    cfg->data = (uint32)atoi(tmp_ptr + 18);   // s
+                }
+                break;
+            }
+            case MBTK_ECALL_CFG_ITEM_TIMER_REDIAL:
+            {
+                if((tmp_ptr = strstr(line, "redial wait timer: ")) != NULL) {
+                    cfg->data = (uint32)atoi(tmp_ptr + 19);   // s
+                    cfg->data *= 1000; // s -> ms
+                }
+                break;
+            }
+            case MBTK_ECALL_CFG_ITEM_TIMER_SMS:
+            {
+                if((tmp_ptr = strstr(line, "SMS resend timer: ")) != NULL) {
+                    cfg->data = (uint32)atoi(tmp_ptr + 18);
+                    cfg->data *= 1000; // s -> ms
+                }
+                break;
+            }
+            case MBTK_ECALL_CFG_ITEM_REDIALCNT:
+            {
+                if((tmp_ptr = strstr(line, "redial attempts count: ")) != NULL) {
+                    cfg->data = (uint32)atoi(tmp_ptr + 23);
+                }
+                break;
+            }
+            case MBTK_ECALL_CFG_ITEM_SMSPROCESS:
+            {
+                if((tmp_ptr = strstr(line, "smsprocess: ")) != NULL) {
+                    cfg->data = (uint32)atoi(tmp_ptr + 12);
+                }
+                break;
+            }
+            case MBTK_ECALL_CFG_ITEM_SMSMSDCNT:
+            {
+                if((tmp_ptr = strstr(line, "sms msd send count: ")) != NULL) {
+                    cfg->data = (uint32)atoi(tmp_ptr + 20);
+                }
+                break;
+            }
+            default:
+                LOGE("Unknown config item : %d", type);
+                err = -1;
+                break;
+        }
+    }
+
+    goto exit;
+exit:
+    at_response_free(response);
+    return err;
+}
+
+/*
+AT*ECALLDATA=5,2,250
+OK
+
+AT*ECALLTIMER=dereg,300
+OK
+*/
+static int req_ecall_cfg_set(const mbtk_ecall_cfg_info_t *cfg_info, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char cmd[1024] = {0};
+    int err = 0;
+
+    if(ecall_mode == MBTK_ECALL_MODE_TYPE_EU) {
+        if(cfg_info->type != MBTK_ECALL_CFG_ITEM_TIMER_CALLBACK
+            && cfg_info->type != MBTK_ECALL_CFG_ITEM_TIMER_DIAL
+            && cfg_info->type != MBTK_ECALL_CFG_ITEM_TIMER_DEREG
+            && cfg_info->type != MBTK_ECALL_CFG_ITEM_TIMER_CLEARDOWN){
+            LOGW("No support for EU.");
+            return -1;
+        }
+    }
+
+    switch(cfg_info->type)
+    {
+        case MBTK_ECALL_CFG_ITEM_T3:
+        case MBTK_ECALL_CFG_ITEM_T5:
+        case MBTK_ECALL_CFG_ITEM_T6:
+        case MBTK_ECALL_CFG_ITEM_T7:
+        case MBTK_ECALL_CFG_ITEM_TH:
+            snprintf(cmd, sizeof(cmd), "AT*ECALLDATA=5,%d,%d", cfg_info->type, cfg_info->data / 20);
+            break;
+        case MBTK_ECALL_CFG_ITEM_TIMER_CALLBACK:
+        {
+            snprintf(cmd, sizeof(cmd), "AT*ECALLTIMER=callback,%d", cfg_info->data / 1000);
+            break;
+        }
+        case MBTK_ECALL_CFG_ITEM_TIMER_CLEARDOWN:
+        {
+            snprintf(cmd, sizeof(cmd), "AT*ECALLTIMER=cleardown,%d", cfg_info->data / 1000);
+            break;
+        }
+        case MBTK_ECALL_CFG_ITEM_TIMER_DEREG:
+        {
+            snprintf(cmd, sizeof(cmd), "AT*ECALLTIMER=dereg,%d", cfg_info->data / 1000);
+            break;
+        }
+        case MBTK_ECALL_CFG_ITEM_TIMER_DIAL:
+        {
+            snprintf(cmd, sizeof(cmd), "AT*ECALLTIMER=dial,%d", cfg_info->data / 1000);
+            break;
+        }
+        case MBTK_ECALL_CFG_ITEM_TIMER_REDIAL:
+        {
+            snprintf(cmd, sizeof(cmd), "AT*ECALLTIMER=redialtmr,%d", cfg_info->data / 1000);
+            break;
+        }
+        case MBTK_ECALL_CFG_ITEM_TIMER_SMS:
+        {
+            snprintf(cmd, sizeof(cmd), "AT*ECALLTIMER=sms,%d", cfg_info->data / 1000);
+            break;
+        }
+        case MBTK_ECALL_CFG_ITEM_REDIALCNT:
+        {
+            snprintf(cmd, sizeof(cmd), "AT*ECALLTIMER=redialcnt,%d", cfg_info->data);
+            break;
+        }
+        case MBTK_ECALL_CFG_ITEM_SMSPROCESS:
+        {
+            snprintf(cmd, sizeof(cmd), "AT*ECALLTIMER=smsprocess,%d", cfg_info->data);
+            break;
+        }
+        case MBTK_ECALL_CFG_ITEM_SMSMSDCNT:
+        {
+            snprintf(cmd, sizeof(cmd), "AT*ECALLTIMER=smsmsdcnt,%d", cfg_info->data);
+            break;
+        }
+        default:
+            LOGE("Unknown config item : %d", cfg_info->type);
+            err = -1;
+            goto exit;
+    }
+
+    err = at_send_command(cmd, &response);
+    if (err < 0 || response->success == 0){
+        *cme_err = at_get_cme_error(response);
+        goto exit;
+    }
+
+exit:
+    at_response_free(response);
+    return err;
+}
+
+/*
+AT*ECALLMUTESPK=1
+OK
+
+*/
+static int req_ecall_spkmute_set(int mute, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char cmd[100] = {0};
+    sprintf(cmd, "AT*ECALLMUTESPK=%d", mute);
+    int err = at_send_command(cmd, &response);
+    if (err < 0 || response->success == 0){
+        *cme_err = at_get_cme_error(response);
+        goto exit;
+    }
+
+exit:
+    at_response_free(response);
+    return err;
+}
+
+
+/*
+AT*ECALLSMSNUM?
+*ECALLSMSNUM: "18981991452"
+
+OK
+
+*/
+static int req_ecall_sms_num_get(uint8 *number, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char *tmp_ptr = NULL;
+    int err = at_send_command_singleline("AT*ECALLSMSNUM?", "*ECALLSMSNUM:", &response);
+
+    if (err < 0 || response->success == 0 || !response->p_intermediates){
+        *cme_err = at_get_cme_error(response);
+        goto exit;
+    }
+
+    char *line = response->p_intermediates->line;
+    err = at_tok_start(&line);
+    if (err < 0)
+    {
+        goto exit;
+    }
+
+    err = at_tok_nextstr(&line, &tmp_ptr);
+    if (err < 0)
+    {
+        goto exit;
+    }
+
+    if(tmp_ptr && strlen(tmp_ptr) > 0) {
+        memcpy(number, tmp_ptr, strlen(tmp_ptr));
+    }
+
+    goto exit;
+exit:
+    at_response_free(response);
+    return err;
+}
+
+/*
+AT*ECALLSMSNUM=18981991452
+OK
+
+*/
+static int req_ecall_sms_num_set(const uint8 *number, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char cmd[100] = {0};
+    sprintf(cmd, "AT*ECALLSMSNUM=%s", number);
+    int err = at_send_command(cmd, &response);
+    if (err < 0 || response->success == 0){
+        *cme_err = at_get_cme_error(response);
+        goto exit;
+    }
+
+exit:
+    at_response_free(response);
+    return err;
+}
+
+/*
+AT*AUDGAIN=8,1 // Set Rx voice gain = 8dB
+OK
+
+*/
+static int req_ecall_gain_set(mbtk_ecall_gain_info_t *gain, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char cmd[100] = {0};
+    sprintf(cmd, "AT*AUDGAIN=%d,%d", gain->gain, gain->mode);
+    int err = at_send_command(cmd, &response);
+    if (err < 0 || response->success == 0){
+        *cme_err = at_get_cme_error(response);
+        goto exit;
+    }
+
+exit:
+    at_response_free(response);
+    return err;
+}
+
+//void net_list_free(void *data);
+// Return MBTK_INFO_ERR_SUCCESS,will call pack_error_send() to send RSP.
+// Otherwise, do not call pack_error_send().
+mbtk_ril_err_enum ecall_pack_req_process(sock_cli_info_t* cli_info, ril_msg_pack_info_t* pack)
+{
+    mbtk_ril_err_enum err = MBTK_RIL_ERR_SUCCESS;
+    int cme_err = MBTK_RIL_ERR_CME_NON;
+    switch(pack->msg_id)
+    {
+        case RIL_MSG_ID_ECALL_MSDCFG:       // mbtk_ecall_msd_cfg_info_t
+        {
+            if(pack->data_len == 0 || pack->data == NULL)
+            {
+                err = MBTK_RIL_ERR_UNSUPPORTED;
+            }
+            else     // Set
+            {
+                mbtk_ecall_msd_cfg_info_t *cfg_info = (mbtk_ecall_msd_cfg_info_t*)(pack->data);
+                if(req_ecall_msdcfg(cfg_info, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_RIL_ERR_CME_NON) {
+                        err = MBTK_RIL_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_RIL_ERR_UNKNOWN;
+                    }
+                    LOG("AT*ECALLMSDCFG fail.");
+                }
+                else
+                {
+                    ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+                }
+            }
+            break;
+        }
+        case RIL_MSG_ID_ECALL_MSDGEN:
+        {
+            if(pack->data_len == 0 || pack->data == NULL)
+            {
+                if(req_ecall_msdgen(&cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_RIL_ERR_CME_NON) {
+                        err = MBTK_RIL_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_RIL_ERR_UNKNOWN;
+                    }
+                    LOG("AT*ECALLMSDGEN fail.");
+                }
+                else
+                {
+                    ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+                }
+            }
+            else     // Set
+            {
+                err = MBTK_RIL_ERR_UNSUPPORTED;
+            }
+            break;
+        }
+        case RIL_MSG_ID_ECALL_MSD: // uint8[]
+        {
+            uint8 msd[MBTK_ECALL_MSD_LEN_MAX];
+            memset(msd, 0, sizeof(msd));
+            if(pack->data_len == 0 || pack->data == NULL)
+            {
+                if(req_ecall_msd_get(msd, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_RIL_ERR_CME_NON) {
+                        err = MBTK_RIL_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_RIL_ERR_UNKNOWN;
+                    }
+                    LOG("Get MSD fail.");
+                }
+                else
+                {
+                    ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, msd, strlen(msd));
+                }
+            }
+            else     // Set
+            {
+                memcpy(msd, pack->data, pack->data_len);
+                if(req_ecall_msd_set(msd, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_RIL_ERR_CME_NON) {
+                        err = MBTK_RIL_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_RIL_ERR_UNKNOWN;
+                    }
+                    LOG("AT*ECALLMSD fail.");
+                }
+                else
+                {
+                    ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+                }
+            }
+            break;
+        }
+        case RIL_MSG_ID_ECALL_PUSH:
+        {
+            if(pack->data_len == 0 || pack->data == NULL)
+            {
+                if(req_ecall_push(&cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_RIL_ERR_CME_NON) {
+                        err = MBTK_RIL_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_RIL_ERR_UNKNOWN;
+                    }
+                    LOG("AT*ECALLPUSH fail.");
+                }
+                else
+                {
+                    ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+                }
+            }
+            else     // Set
+            {
+                err = MBTK_RIL_ERR_UNSUPPORTED;
+            }
+            break;
+        }
+        case RIL_MSG_ID_ECALL_ONLY:     // mbtk_ecall_only_info_t
+        {
+            if(pack->data_len == 0 || pack->data == NULL)
+            {
+                mbtk_ecall_only_info_t only_info;
+                memset(&only_info, 0, sizeof(mbtk_ecall_only_info_t));
+                if(req_ecall_only_get(&only_info, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_RIL_ERR_CME_NON) {
+                        err = MBTK_RIL_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_RIL_ERR_UNKNOWN;
+                    }
+                    LOG("Get ecall only mode fail.");
+                }
+                else
+                {
+                    ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &only_info, sizeof(mbtk_ecall_only_info_t));
+                }
+            }
+            else     // Set
+            {
+                mbtk_ecall_only_info_t *only_info = (mbtk_ecall_only_info_t*)(pack->data);
+                if(req_ecall_only_set(only_info, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_RIL_ERR_CME_NON) {
+                        err = MBTK_RIL_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_RIL_ERR_UNKNOWN;
+                    }
+                    LOG("AT*ECALLONLY fail.");
+                }
+                else
+                {
+                    ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+                }
+            }
+            break;
+        }
+        case RIL_MSG_ID_ECALL_REG:  // reg <uint8>
+        {
+            if(pack->data_len == 0 || pack->data == NULL)
+            {
+                err = MBTK_RIL_ERR_UNSUPPORTED;
+            }
+            else
+            {
+                uint8 reg = pack->data[0];
+                if(req_ecall_reg_set(reg, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_RIL_ERR_CME_NON) {
+                        err = MBTK_RIL_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_RIL_ERR_UNKNOWN;
+                    }
+                    LOG("ecall reg(%d) fail.", reg);
+                }
+                else
+                {
+                    ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+                }
+            }
+            break;
+        }
+        case RIL_MSG_ID_ECALL_DIAL: // mbtk_ecall_dial_type_enum
+        {
+            if(pack->data_len == 0 || pack->data == NULL)
+            {
+                mbtk_ecall_dial_type_enum type;
+                if(req_ecall_dial_state_get(&type, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_RIL_ERR_CME_NON) {
+                        err = MBTK_RIL_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_RIL_ERR_UNKNOWN;
+                    }
+                    LOG("Get ecall type fail.");
+                }
+                else
+                {
+                    ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &type, sizeof(uint8));
+                }
+            }
+            else
+            {
+                mbtk_ecall_dial_type_enum type = (mbtk_ecall_dial_type_enum)pack->data[0];
+                if(req_ecall_dial_start(type, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_RIL_ERR_CME_NON) {
+                        err = MBTK_RIL_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_RIL_ERR_UNKNOWN;
+                    }
+                    LOG("Start ecall %d fail.", type);
+                }
+                else
+                {
+                    ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+                }
+            }
+            break;
+        }
+        case RIL_MSG_ID_ECALL_MODE:  // mbtk_ecall_cfg_item_enum / mbtk_ecall_cfg_info_t
+        {
+            if(pack->data_len == 0 || pack->data == NULL)
+            {
+                mbtk_ecall_mode_type_enum mode;
+                if(req_ecall_mode_get(&mode, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_RIL_ERR_CME_NON) {
+                        err = MBTK_RIL_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_RIL_ERR_UNKNOWN;
+                    }
+                    LOG("Get ecall mode fail.");
+                }
+                else
+                {
+                    ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &mode, sizeof(uint8));
+                }
+            }
+            else
+            {
+                mbtk_ecall_mode_type_enum mode = (mbtk_ecall_mode_type_enum)pack->data[0];
+                if(req_ecall_mode_set(mode, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_RIL_ERR_CME_NON) {
+                        err = MBTK_RIL_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_RIL_ERR_UNKNOWN;
+                    }
+                    LOG("Set ecall mode %d fail.", mode);
+                }
+                else
+                {
+                    ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+                }
+            }
+            break;
+        }
+        case RIL_MSG_ID_ECALL_CFG:  // mbtk_ecall_cfg_item_enum / mbtk_ecall_cfg_info_t
+        {
+            if(pack->data_len == 0 || pack->data == NULL)
+            {
+                err = MBTK_RIL_ERR_UNSUPPORTED;
+            }
+            else
+            {
+                if(pack->data_len == sizeof(mbtk_ecall_cfg_info_t)) { // Set
+                    mbtk_ecall_cfg_info_t *cfg_info = (mbtk_ecall_cfg_info_t*)pack->data;
+                    if(req_ecall_cfg_set(cfg_info, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                    {
+                        if(cme_err != MBTK_RIL_ERR_CME_NON) {
+                            err = MBTK_RIL_ERR_CME + cme_err;
+                        } else {
+                            err = MBTK_RIL_ERR_UNKNOWN;
+                        }
+                        LOG("Set ecall config[%d] fail.", cfg_info->type);
+                    }
+                    else
+                    {
+                        ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+                    }
+                } else { // Get
+                    mbtk_ecall_cfg_info_t cfg_info;
+                    memset(&cfg_info, 0, sizeof(mbtk_ecall_cfg_info_t));
+                    mbtk_ecall_cfg_item_enum type = (mbtk_ecall_cfg_item_enum)pack->data[0];
+                    if(req_ecall_cfg_get(type, &cfg_info, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                    {
+                        if(cme_err != MBTK_RIL_ERR_CME_NON) {
+                            err = MBTK_RIL_ERR_CME + cme_err;
+                        } else {
+                            err = MBTK_RIL_ERR_UNKNOWN;
+                        }
+                        LOG("Get ecall config[%d] fail.", type);
+                    }
+                    else
+                    {
+                        ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &cfg_info, sizeof(mbtk_ecall_cfg_info_t));
+                    }
+                }
+            }
+            break;
+        }
+        case RIL_MSG_ID_ECALL_SMS_NUM: // uint8[]
+        {
+            uint8 number[RIL_MAX_NUMBER_LEN];
+            memset(number, 0, sizeof(number));
+            if(pack->data_len == 0 || pack->data == NULL)
+            {
+                if(req_ecall_sms_num_get(number, &cme_err) || strlen(number) == 0 || cme_err != MBTK_RIL_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_RIL_ERR_CME_NON) {
+                        err = MBTK_RIL_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_RIL_ERR_UNKNOWN;
+                    }
+                    LOG("Get ecall sms number fail.");
+                }
+                else
+                {
+                    ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, number, strlen(number));
+                }
+            }
+            else     // Set
+            {
+                memcpy(number, pack->data, pack->data_len);
+                if(req_ecall_sms_num_set(number, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_RIL_ERR_CME_NON) {
+                        err = MBTK_RIL_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_RIL_ERR_UNKNOWN;
+                    }
+                    LOG("Set ecall sms number fail.");
+                }
+                else
+                {
+                    ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+                }
+            }
+            break;
+        }
+        case RIL_MSG_ID_ECALL_MUTESPK:
+        {
+            if(pack->data_len == 0 || pack->data == NULL)
+            {
+                err = MBTK_RIL_ERR_UNSUPPORTED;
+            }
+            else     // Set mute state.
+            {
+                uint8 mute = pack->data[0];
+                if(pack->data_len != sizeof(uint8) || (mute != 0 && mute != 1))
+                {
+                    err = MBTK_RIL_ERR_REQ_PARAMETER;
+                    LOG("Set spk mute parameter error.");
+                    break;
+                }
+
+                if(req_ecall_spkmute_set(mute, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_RIL_ERR_CME_NON) {
+                        err = MBTK_RIL_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_RIL_ERR_UNKNOWN;
+                    }
+                    LOG("Set spk mute state fail.");
+                }
+                else
+                {
+                    ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+                }
+            }
+            break;
+        }
+        case RIL_MSG_ID_ECALL_DSP_GAIN: // mbtk_ecall_gain_info_t
+        {
+            if(pack->data_len == 0 || pack->data == NULL)
+            {
+                err = MBTK_RIL_ERR_UNSUPPORTED;
+            }
+            else     // Set
+            {
+                mbtk_ecall_gain_info_t *gain_info = (mbtk_ecall_gain_info_t *)pack->data;
+                if(req_ecall_gain_set(gain_info, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_RIL_ERR_CME_NON) {
+                        err = MBTK_RIL_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_RIL_ERR_UNKNOWN;
+                    }
+                    LOGE("Set ecall gain fail.");
+                }
+                else
+                {
+                    ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+                }
+            }
+            break;
+        }
+        default:
+        {
+            err = MBTK_RIL_ERR_REQ_UNKNOWN;
+            LOG("Unknown request : %s", id2str(pack->msg_id));
+            break;
+        }
+    }
+
+    return err;
+}
+
+
+
diff --git a/mbtk/mbtk_rild_v2/src/ril_net.c b/mbtk/mbtk_rild_v2/src/ril_net.c
index 6ca5d65..16d3118 100755
--- a/mbtk/mbtk_rild_v2/src/ril_net.c
+++ b/mbtk/mbtk_rild_v2/src/ril_net.c
@@ -21,523 +21,9 @@
 #include "mbtk_str.h"
 
 mbtk_cell_pack_info_t cell_info;
-ril_cgact_wait_t cgact_wait;
 
 extern ril_band_info_t band_info;
 void ril_rsp_pack_send(int fd, int ril_id, int msg_index, const void* data, int data_len);
-static int req_apn_get(bool get_def_cid, mbtk_apn_info_array_t *apns, int *cme_err);
-static int req_apn_set(mbtk_apn_info_t *apn, int *cme_err);
-static void apn_prop_get(mbtk_apn_info_array_t *apns);
-
-static int apn_file_save(const char *file, char *data, int data_len)
-{
-    if(!file) {
-        return -1;
-    }
-
-    if(str_empty(data) || data_len <= 0) { // Delete file
-        return unlink(file);
-    } else {
-        int fd = open(file, O_CREAT | O_WRONLY | O_TRUNC, 0644);
-        if(fd < 0) {
-            LOGE("open(%s) fail:%d", file, errno);
-            return -1;
-        }
-
-        if(write(fd, data, data_len) != data_len) {
-            LOGE("write fail:%d", errno);
-            close(fd);
-            return -1;
-        }
-        close(fd);
-        return 0;
-    }
-}
-
-static int apn_file_read(const char *file, char *data, int data_len)
-{
-    if(!file) {
-        LOGE("file is null");
-        return -1;
-    }
-
-    if(data == NULL || data_len <= 100) {
-        LOGE("apn_file_read() arg error.");
-        return -1;
-    } else {
-        int len = -1;
-        int fd = open(file, O_RDONLY, 0644);
-        if(fd < 0) {
-            LOGE("open(%s) fail:%d", file, errno);
-            return -1;
-        }
-
-        memset(data, 0, data_len);
-        if((len = read(fd, data, data_len)) < 0) {
-            LOGE("read fail:%d", errno);
-            close(fd);
-            return -1;
-        }
-        close(fd);
-        return len;
-    }
-}
-
-
-void apn_auto_conf_from_prop()
-{
-    mbtk_apn_info_array_t apns;
-    int i = 0;
-    memset(&apns, 0, sizeof(mbtk_apn_info_array_t));
-    apn_prop_get(&apns);
-    while(i < apns.num) {
-        int cme_err = MBTK_RIL_ERR_CME_NON;
-        if(req_apn_set(&(apns.apns[i]), &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
-        {
-            LOGD("Set APN fail.");
-        }
-        else
-        {
-            LOGD("Set APN - %d success.", apns.apns[i].cid);
-        }
-        i++;
-    }
-}
-
-static bool apn_conf_support(mbtk_ril_cid_enum cid)
-{
-    if(cid == MBTK_RIL_CID_DEF) {
-        /*
-        uci show wan_default.default.enable
-        wan_default.default.enable='1'
-
-        uci get wan_default.default.enable
-        1
-        */
-        char buff[128] = {0};
-        if(mbtk_cmd_line("uci get wan_default.default.enable", buff, sizeof(buff)) && strlen(buff) > 0) {
-            return buff[0] == '1' ? FALSE : TRUE;
-        }
-    }
-    return TRUE;
-}
-
-static int apn_check_and_cid_reset(mbtk_apn_info_t *apn)
-{
-    // Delete apn
-    if(str_empty(apn->apn)) {
-        if(apn->cid == MBTK_RIL_CID_NUL)
-            return -1;
-
-        if(!apn_conf_support(MBTK_RIL_CID_DEF) && apn->cid == MBTK_RIL_CID_DEF)
-            return -1;
-
-        // The cid no use,so can not delete.
-        mbtk_apn_info_array_t apns;
-        int cme_err = MBTK_RIL_ERR_CME_NON;
-        memset(&apns, 0, sizeof(mbtk_apn_info_array_t));
-        if(req_apn_get(FALSE, &apns, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
-        {
-            LOGW("Get APN fail.");
-            return 0;
-        }
-        else
-        {
-            int index = 0;
-            while(index < apns.num) {
-                if(apns.apns[index].cid == apn->cid)
-                    return 0;
-                index++;
-            }
-            return -1;
-        }
-    } else { // Add or change APN.
-        int start_cid;
-        bool asr_auto_call_open = !apn_conf_support(MBTK_RIL_CID_DEF);
-        mbtk_apn_info_array_t apns;
-        int cme_err = MBTK_RIL_ERR_CME_NON;
-
-        if(asr_auto_call_open) {
-            start_cid = MBTK_RIL_CID_2;
-        } else {
-            start_cid = MBTK_APN_CID_MIN;
-        }
-        memset(&apns, 0, sizeof(mbtk_apn_info_array_t));
-        if(req_apn_get(TRUE, &apns, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
-        {
-            LOGW("Get APN fail.");
-            if(apn->cid == MBTK_RIL_CID_NUL) {
-                apn->cid = start_cid;
-            }
-        }
-        else
-        {
-            int index = 0;
-            bool is_change = FALSE;  // Is add APN default.
-
-            if(apn->cid == MBTK_RIL_CID_NUL) { // Is add (auto set cid).
-                for(; start_cid <= MBTK_APN_CID_MAX; start_cid++) {
-                    index = 0;
-                    while(index < apns.num) {
-                        if(apns.apns[index].cid == start_cid)
-                            break;
-                        index++;
-                    }
-
-                    if(index == apns.num) { // Found not used cid : start_cid.
-                        LOGD("Change CID : %d -> %d", apn->cid, start_cid);
-                        apn->cid = start_cid;
-                        // return 0;
-                        break;
-                    }
-                }
-
-                if(start_cid > MBTK_APN_CID_MAX) {
-                    LOGE("APN full.");
-                    return -1;
-                }
-                is_change = FALSE;
-            } else {
-                index = 0;
-                while(index < apns.num) {
-                    if(apns.apns[index].cid == apn->cid) {
-                        is_change = TRUE;
-                        break;
-                    }
-                    index++;
-                }
-            }
-
-            // Is add,the APN can't same.
-            if(!is_change) {
-                index = 0;
-                while(index < apns.num) {
-                    if(strcmp(apns.apns[index].apn,apn->apn) == 0) {
-                        LOGW("APN : %s exist.", apn->apn);
-                        return -1;
-                    }
-                    index++;
-                }
-            }
-        }
-    }
-    return 0;
-}
-
-static void apn_prop_get(mbtk_apn_info_array_t *apns)
-{
-    char prop_name[128] = {0};
-    char prop_data[1024] = {0};
-    int cid;
-    memset(apns, 0, sizeof(mbtk_apn_info_array_t));
-    bool asr_auto_call_open = !apn_conf_support(MBTK_RIL_CID_DEF);
-
-    // If auto data call is open,the default route is CID 1.
-    if(asr_auto_call_open) {
-        //apns->cid_for_def_route = MBTK_RIL_CID_DEF;
-        //apns->cid_for_def_dns = MBTK_RIL_CID_DEF;
-        cid = MBTK_RIL_CID_2;
-    } else {
-        cid = MBTK_APN_CID_MIN;
-    }
-
-    char def_cid[10] = {0};
-    sprintf(def_cid, "%d", MBTK_RIL_CID_DEF);
-    if(property_get(MBTK_DEF_ROUTE_CID, prop_data, def_cid) > 0 && !str_empty(prop_data)) {
-        apns->cid_for_def_route = (mbtk_ril_cid_enum)atoi(prop_data);
-    }
-    memset(prop_data, 0, sizeof(prop_data));
-    if(property_get(MBTK_DEF_DNS_CID, prop_data, def_cid) > 0 && !str_empty(prop_data)) {
-        apns->cid_for_def_dns = (mbtk_ril_cid_enum)atoi(prop_data);
-    }
-
-    for(; cid <= MBTK_APN_CID_MAX; cid++) {
-        memset(prop_name, 0, sizeof(prop_name));
-        memset(prop_data, 0, sizeof(prop_data));
-
-        sprintf(prop_name, "%s_%d",MBTK_APN_PROP,cid);
-        // ip_type,auth,auto_data_call,apn,user,pass
-#if 0
-        if(property_get(prop_name, prop_data, "") > 0 && !str_empty(prop_data)) {
-#else
-        if(apn_file_read(prop_name, prop_data, sizeof(prop_data)) > 0 && !str_empty(prop_data)) {
-#endif
-            apns->apns[apns->num].cid = (mbtk_ril_cid_enum)cid;
-            char *ptr_1 = prop_data;
-            apns->apns[apns->num].ip_type = (mbtk_ip_type_enum)atoi(ptr_1);
-            ptr_1 = strstr(ptr_1, ",");
-            if(!ptr_1) {
-                continue;
-            }
-            ptr_1++; // Jump ',' to auth
-
-            apns->apns[apns->num].auth = (mbtk_apn_auth_type_enum)atoi(ptr_1);
-            ptr_1 = strstr(ptr_1, ",");
-            if(!ptr_1) {
-                continue;
-            }
-            ptr_1++; // Jump ',' to auto_data_call
-
-            apns->apns[apns->num].auto_boot_call = (uint8)atoi(ptr_1);
-            ptr_1 = strstr(ptr_1, ",");
-            if(!ptr_1) {
-                continue;
-            }
-            ptr_1++; // Jump ',' to apn
-
-            char *ptr_2 = strstr(ptr_1, ",");
-            if(!ptr_2) {
-                continue;
-            }
-            if(memcmp(ptr_1, "NULL", 4)) { // Not "NULL"
-                memcpy(apns->apns[apns->num].apn, ptr_1, ptr_2 - ptr_1); // apn
-            }
-
-            ptr_2++; // Jump ',' to user
-            ptr_1 = strstr(ptr_2, ",");
-            if(!ptr_1) {
-                continue;
-            }
-            if(memcmp(ptr_2, "NULL", 4)) { // Not "NULL"
-                memcpy(apns->apns[apns->num].user, ptr_2, ptr_1 - ptr_2); // user
-            }
-
-            ptr_1++; // Jump ',' to pass
-            ptr_2 = strstr(ptr_1, ",");
-            if(!ptr_2) {
-                continue;
-            }
-            if(memcmp(ptr_1, "NULL", 4)) { // Not "NULL"
-                memcpy(apns->apns[apns->num].pass, ptr_1, ptr_2 - ptr_1); // pass
-            }
-
-            ptr_2++; // Jump ',' to type
-            if(memcmp(ptr_1, "NULL", 4)) { // Not "NULL"
-                memcpy(apns->apns[apns->num].type, ptr_2, strlen(ptr_2)); // type
-            }
-
-            apns->num++;
-        }
-    }
-}
-
-static int apn_prop_get_by_cid(mbtk_ril_cid_enum cid, mbtk_apn_info_t *apn)
-{
-    char prop_name[128] = {0};
-    char prop_data[1024] = {0};
-    memset(apn, 0, sizeof(mbtk_apn_info_t));
-
-    sprintf(prop_name, "%s_%d",MBTK_APN_PROP,cid);
-    // ip_type,auth,auto_data_call,apn,user,pass
-#if 0
-    if(property_get(prop_name, prop_data, "") > 0 && !str_empty(prop_data)) {
-#else
-    if(apn_file_read(prop_name, prop_data, sizeof(prop_data)) > 0 && !str_empty(prop_data)) {
-#endif
-        apn->cid = cid;
-        apn->auto_save = (uint8)1;
-        char *ptr_1 = prop_data;
-        apn->ip_type = (mbtk_ip_type_enum)atoi(ptr_1);
-        ptr_1 = strstr(ptr_1, ",");
-        if(!ptr_1) {
-            return -1;
-        }
-        ptr_1++; // Jump ',' to auth
-
-        apn->auth = (mbtk_apn_auth_type_enum)atoi(ptr_1);
-        ptr_1 = strstr(ptr_1, ",");
-        if(!ptr_1) {
-            return -1;
-        }
-        ptr_1++; // Jump ',' to auto_data_call
-
-        apn->auto_boot_call = (uint8)atoi(ptr_1);
-        ptr_1 = strstr(ptr_1, ",");
-        if(!ptr_1) {
-            return -1;
-        }
-        ptr_1++; // Jump ',' to apn
-
-        char *ptr_2 = strstr(ptr_1, ",");
-        if(!ptr_2) {
-            return -1;
-        }
-        if(memcmp(ptr_1, "NULL", 4)) { // Not "NULL"
-            memcpy(apn->apn, ptr_1, ptr_2 - ptr_1); // apn
-        }
-
-        ptr_2++; // Jump ',' to user
-        ptr_1 = strstr(ptr_2, ",");
-        if(!ptr_1) {
-            return -1;
-        }
-        if(memcmp(ptr_2, "NULL", 4)) { // Not "NULL"
-            memcpy(apn->user, ptr_2, ptr_1 - ptr_2); // user
-        }
-
-        ptr_1++; // Jump ',' to pass
-        ptr_2 = strstr(ptr_1, ",");
-        if(!ptr_2) {
-            return -1;
-        }
-        if(memcmp(ptr_1, "NULL", 4)) { // Not "NULL"
-            memcpy(apn->user, ptr_1, ptr_2 - ptr_1); // pass
-        }
-
-        ptr_2++; // Jump ',' to type
-        if(memcmp(ptr_1, "NULL", 4)) { // Not "NULL"
-            memcpy(apn->type, ptr_2, strlen(ptr_2)); // pass
-        }
-        return 0;
-    }
-    return -1;
-}
-
-static int apn_prop_get_by_cid_without_cgdcont(mbtk_ril_cid_enum cid, mbtk_apn_info_t *apn)
-{
-    char prop_name[128] = {0};
-    char prop_data[1024] = {0};
-
-    sprintf(prop_name, "%s_%d",MBTK_APN_PROP,cid);
-    // ip_type,auth,auto_data_call,apn,user,pass
-#if 0
-    if(property_get(prop_name, prop_data, "") > 0 && !str_empty(prop_data)) {
-#else
-    if(apn_file_read(prop_name, prop_data, sizeof(prop_data)) > 0 && !str_empty(prop_data)) {
-#endif
-        LOGD("APN : %s", prop_data);
-        char *ptr_1 = prop_data;
-        apn->auto_save = (uint8)1;
-        //apn->ip_type = (mbtk_ip_type_enum)atoi(ptr_1);
-        ptr_1 = strstr(ptr_1, ",");
-        if(!ptr_1) {
-            return -1;
-        }
-        ptr_1++; // Jump ',' to auth
-
-        apn->auth = (mbtk_apn_auth_type_enum)atoi(ptr_1);
-        ptr_1 = strstr(ptr_1, ",");
-        if(!ptr_1) {
-            return -1;
-        }
-        ptr_1++; // Jump ',' to auto_data_call
-
-        apn->auto_boot_call = (uint8)atoi(ptr_1);
-        ptr_1 = strstr(ptr_1, ",");
-        if(!ptr_1) {
-            return -1;
-        }
-        ptr_1++; // Jump ',' to apn
-
-        char *ptr_2 = strstr(ptr_1, ",");
-        if(!ptr_2) {
-            return -1;
-        }
-#if 0
-        if(memcmp(ptr_1, "NULL", 4)) { // Not "NULL"
-            memcpy(apn->apn, ptr_1, ptr_2 - ptr_1); // apn
-        }
-#endif
-
-        ptr_2++; // Jump ',' to user
-        ptr_1 = strstr(ptr_2, ",");
-        if(!ptr_1) {
-            return -1;
-        }
-        if(memcmp(ptr_2, "NULL", 4)) { // Not "NULL"
-            memcpy(apn->user, ptr_2, ptr_1 - ptr_2); // user
-        }
-
-        ptr_1++; // Jump ',' to pass
-        ptr_2 = strstr(ptr_1, ",");
-        if(!ptr_2) {
-            return -1;
-        }
-        if(memcmp(ptr_1, "NULL", 4)) { // Not "NULL"
-            memcpy(apn->user, ptr_1, ptr_2 - ptr_1); // pass
-        }
-
-        ptr_2++; // Jump ',' to type
-        if(memcmp(ptr_1, "NULL", 4)) { // Not "NULL"
-            memcpy(apn->type, ptr_2, strlen(ptr_2)); // pass
-        }
-        return 0;
-    } else {
-        apn->auto_save = (uint8)0;
-    }
-    return -1;
-}
-
-static int apn_prop_set(mbtk_apn_info_t *apn)
-{
-    char prop_name[20] = {0};
-    char prop_data[1024] = {0};
-    int ret = -1;
-    if(apn->auto_save) {
-        sprintf(prop_name, "%s_%d", MBTK_APN_PROP, apn->cid);
-        // Delete apn
-        if(!str_empty(apn->apn)) {
-            snprintf(prop_data, 1024, "%d,%d,%d,%s,%s,%s,%s", apn->ip_type, apn->auth, apn->auto_boot_call,
-                apn->apn,
-                str_empty(apn->user) ? "NULL" : apn->user,
-                str_empty(apn->pass) ? "NULL" : apn->pass,
-                str_empty(apn->pass) ? "NULL" : apn->type);
-        }
-
-#if 0
-        ret = property_set(prop_name, prop_data);
-#else
-        if(str_empty(apn->apn)) { // Delete APN
-            ret = apn_file_save(prop_name, NULL, 0);
-        } else {
-            ret = apn_file_save(prop_name, prop_data, strlen(prop_data));
-        }
-#endif
-    }
-
-    if(!ret && apn->def_route) {
-        memset(prop_data, 0, sizeof(prop_data));
-        prop_data[0] = '0' + apn->cid;
-        ret = property_set(MBTK_DEF_ROUTE_CID, prop_data);
-    }
-    if(!ret && apn->as_dns) {
-        memset(prop_data, 0, sizeof(prop_data));
-        prop_data[0] = '0' + apn->cid;
-        ret = property_set(MBTK_DEF_DNS_CID, prop_data);
-    }
-    return ret;
-}
-
-static int apn_prop_reset(mbtk_data_call_info_t *data_info)
-{
-    mbtk_apn_info_t apn;
-    if(apn_prop_get_by_cid(data_info->cid, &apn)) {
-        return -1;
-    } else {
-        apn.auto_boot_call = data_info->auto_boot_call;
-        apn.def_route = data_info->def_route;
-        apn.as_dns = data_info->as_dns;
-        return apn_prop_set(&apn);
-    }
-}
-
-static int wait_cgact_complete(int timeout)
-{
-    int count = timeout * 10; // timeout * 1000 / 100
-    int i = 0;
-
-    while(cgact_wait.waitting && i < count) {
-        i++;
-        usleep(100000); // 100ms
-    }
-
-    memset(&cgact_wait, 0, sizeof(ril_cgact_wait_t));
-    if(i == count) { // Timeout
-        return -1;
-    } else {
-        return 0;
-    }
-}
 
 /*
 AT+COPS=?
@@ -1701,428 +1187,6 @@
     return err;
 }
 
-
-/*
-AT+CGDCONT?
-
-+CGDCONT: 1,"IPV4V6","ctnet","10.142.64.116 254.128.0.0.0.0.0.0.0.0.0.0.0.0.0.1",0,0,0,2,0,0
-
-+CGDCONT: 8,"IPV4V6","IMS","254.128.0.0.0.0.0.0.0.0.0.0.0.0.0.1",0,0,0,2,1,1
-
-OK
-
-*/
-static int req_apn_get(bool get_def_cid, mbtk_apn_info_array_t *apns, int *cme_err)
-{
-    ATResponse *response = NULL;
-    int err = at_send_command_multiline("AT+CGDCONT?", "+CGDCONT:", &response);
-
-    if (err < 0 || response->success == 0 || !response->p_intermediates){
-        if(cme_err) {
-            *cme_err = at_get_cme_error(response);
-        }
-        goto exit;
-    }
-
-    ATLine* lines_ptr = response->p_intermediates;
-    char *line = NULL;
-    int tmp_int;
-    char *tmp_str = NULL;
-    int cid_start;
-    if(apn_conf_support(MBTK_RIL_CID_DEF)) {
-        cid_start = MBTK_RIL_CID_DEF;
-    } else {
-        if(get_def_cid) {
-            cid_start = MBTK_RIL_CID_DEF;
-        } else {
-            cid_start = MBTK_RIL_CID_2;
-        }
-    }
-    /*
-    <apn_num[1]><cid[1]><ip_type[1]><apn_len[2]><apn><user_len[2]><user><pass_len[2]><pass><auth_len[2]><auth>...
-                <cid[1]><ip_type[1]><apn_len[2]><apn><user_len[2]><user><pass_len[2]><pass><auth_len[2]><auth>
-    */
-    while(lines_ptr)
-    {
-        line = lines_ptr->line;
-        err = at_tok_start(&line);
-        if (err < 0)
-        {
-            goto exit;
-        }
-
-        err = at_tok_nextint(&line, &tmp_int); // cid
-        if (err < 0)
-        {
-            goto exit;
-        }
-        // Only get CID 1-7
-        if(tmp_int >= cid_start && tmp_int <= MBTK_APN_CID_MAX) {
-            apns->apns[apns->num].cid = (mbtk_ril_cid_enum)tmp_int;
-
-            err = at_tok_nextstr(&line, &tmp_str);// ip type
-            if (err < 0)
-            {
-                goto exit;
-            }
-            if(!strcasecmp(tmp_str, "IP")) {
-                apns->apns[apns->num].ip_type = MBTK_IP_TYPE_IP;
-            } else if(!strcasecmp(tmp_str, "IPV6")) {
-                apns->apns[apns->num].ip_type = MBTK_IP_TYPE_IPV6;
-            } else if(!strcasecmp(tmp_str, "IPV4V6")) {
-                apns->apns[apns->num].ip_type = MBTK_IP_TYPE_IPV4V6;
-            } else {
-                apns->apns[apns->num].ip_type = MBTK_IP_TYPE_PPP;
-            }
-
-            err = at_tok_nextstr(&line, &tmp_str); // apn
-            if (err < 0)
-            {
-                goto exit;
-            }
-            if(!str_empty(tmp_str)) {
-                memcpy(apns->apns[apns->num].apn, tmp_str, strlen(tmp_str));
-            }
-
-            // Get other arg from proc or file.
-            apn_prop_get_by_cid_without_cgdcont(apns->apns[apns->num].cid, &(apns->apns[apns->num]));
-
-            apns->num++;
-        }
-
-        lines_ptr = lines_ptr->p_next;
-    }
-
-    char prop_name[128] = {0};
-    char prop_data[1024] = {0};
-    char def_cid[10] = {0};
-    sprintf(def_cid, "%d", MBTK_RIL_CID_DEF);
-
-    if(property_get(MBTK_DEF_ROUTE_CID, prop_data, def_cid) > 0 && !str_empty(prop_data)) {
-        apns->cid_for_def_route = (mbtk_ril_cid_enum)atoi(prop_data);
-    }
-    memset(prop_data, 0, sizeof(prop_data));
-    if(property_get(MBTK_DEF_DNS_CID, prop_data, def_cid) > 0 && !str_empty(prop_data)) {
-        apns->cid_for_def_dns = (mbtk_ril_cid_enum)atoi(prop_data);
-    }
-
-    goto exit;
-exit:
-    at_response_free(response);
-    return err;
-}
-
-/*
-AT+CGDCONT=1,"IPV4V6","cmnet"
-OK
-
-AT*AUTHReq=1,1,marvell,123456
-OK
-
-*/
-static int req_apn_set(mbtk_apn_info_t *apn, int *cme_err)
-{
-    ATResponse *response = NULL;
-    char cmd[400] = {0};
-    int index = 0;
-    int err = 0;
-
-    // Delete apn
-    if(str_empty(apn->apn)) {
-        sprintf(cmd, "AT+CGDCONT=%d", apn->cid);
-        err = at_send_command(cmd, &response);
-        if (err < 0 || response->success == 0){
-            if(cme_err) {
-                *cme_err = at_get_cme_error(response);
-            }
-            goto exit;
-        }
-    } else {
-        index += sprintf(cmd, "AT+CGDCONT=%d,", apn->cid);
-        switch(apn->ip_type) {
-            case MBTK_IP_TYPE_IP: {
-                index += sprintf(cmd + index,"\"IP\",");
-                break;
-            }
-            case MBTK_IP_TYPE_IPV6: {
-                index += sprintf(cmd + index,"\"IPV6\",");
-                break;
-            }
-            case MBTK_IP_TYPE_IPV4V6: {
-                index += sprintf(cmd + index,"\"IPV4V6\",");
-                break;
-            }
-            default: {
-                index += sprintf(cmd + index,"\"PPP\",");
-                break;
-            }
-        }
-        if(strlen(apn->apn) > 0) {
-            index += sprintf(cmd + index,"\"%s\"", apn->apn);
-        }
-
-        err = at_send_command(cmd, &response);
-        if (err < 0 || response->success == 0){
-            if(cme_err) {
-                *cme_err = at_get_cme_error(response);
-            }
-            goto exit;
-        }
-
-        if(!str_empty(apn->user) || !str_empty(apn->pass)) {
-            at_response_free(response);
-
-            memset(cmd,0,400);
-            int cmd_auth=0;
-            if(apn->auth == MBTK_APN_AUTH_PROTO_NONE)
-                cmd_auth = 0;
-            else if(apn->auth == MBTK_APN_AUTH_PROTO_PAP)
-                cmd_auth = 1;
-            else if(apn->auth == MBTK_APN_AUTH_PROTO_CHAP)
-                cmd_auth = 2;
-            else
-                goto exit;
-
-            sprintf(cmd, "AT*AUTHREQ=%d,%d,%s,%s",apn->cid,cmd_auth,apn->user,apn->pass);
-            err = at_send_command(cmd, &response);
-            if (err < 0 || response->success == 0){
-                if(cme_err) {
-                    *cme_err = at_get_cme_error(response);
-                }
-                goto exit;
-            }
-        }
-    }
-
-exit:
-    at_response_free(response);
-    return err;
-}
-
-/*
-AT+CGACT?
-+CGACT: 1,1
-+CGACT: 8,1
-OK
-
-AT+CGACT=1,<cid>
-OK
-
-*/
-static int req_data_call_start(mbtk_ril_cid_enum cid, bool def_route, bool as_dns,
-                int retry_interval, int timeout, int *cme_err)
-{
-    ATResponse *response = NULL;
-    char cmd[400] = {0};
-    int err = 0;
-    memset(&cgact_wait, 0, sizeof(ril_cgact_wait_t));
-    cgact_wait.waitting = true;
-    cgact_wait.cid = cid;
-    cgact_wait.act = true;
-
-    sprintf(cmd, "AT+CGACT=1,%d", cid);
-    err = at_send_command(cmd, &response);
-    if (err < 0 || response->success == 0){
-        if(cme_err) {
-            *cme_err = at_get_cme_error(response);
-        }
-        goto exit;
-    }
-
-exit:
-    at_response_free(response);
-    return err;
-}
-
-/*
-AT+CGACT=0,<cid>
-OK
-
-*/
-static int req_data_call_stop(mbtk_ril_cid_enum cid, int timeout, int *cme_err)
-{
-    ATResponse *response = NULL;
-    char cmd[400] = {0};
-    int err = 0;
-
-    memset(&cgact_wait, 0, sizeof(ril_cgact_wait_t));
-    cgact_wait.waitting = true;
-    cgact_wait.cid = cid;
-    cgact_wait.act = false;
-
-    sprintf(cmd, "AT+CGACT=0,%d", cid);
-    err = at_send_command(cmd, &response);
-    if (err < 0 || response->success == 0){
-        if(cme_err) {
-            *cme_err = at_get_cme_error(response);
-        }
-        goto exit;
-    }
-
-exit:
-    at_response_free(response);
-    return err;
-}
-
-/*
-AT+CGCONTRDP=1
-+CGCONTRDP: 1,7,"cmnet-2.MNC000.MCC460.GPRS","10.255.74.26","","223.87.253.100","223.87.253.253","","",0,0
-+CGCONTRDP: 1,7,"cmnet-2.MNC000.MCC460.GPRS","254.128.0.0.0.0.0.0.0.1.0.2.144.5.212.239","","36.9.128.98.32.0.0.2.0.0.0.0.0.0.0.1","36.9.128.98.32.0.0.2.0.0.0.0.0.0.0.2","","",0,0
-
-OK
-
-*/
-static int req_data_call_state_get(mbtk_ril_cid_enum cid, mbtk_ip_info_t *ip_info, int *cme_err)
-{
-    ATResponse *response = NULL;
-    char cmd[50] = {0};
-    int err = 0;
-
-    sprintf(cmd, "AT+CGCONTRDP=%d", cid);
-
-    err = at_send_command_multiline(cmd, "+CGCONTRDP:", &response);
-    if (err < 0 || response->success == 0 || !response->p_intermediates){
-        *cme_err = at_get_cme_error(response);
-        goto exit;
-    }
-    ATLine* lines_ptr = response->p_intermediates;
-    char *line = NULL;
-    int tmp_int;
-    char *tmp_ptr = NULL;
-    while(lines_ptr)
-    {
-        line = lines_ptr->line;
-        err = at_tok_start(&line);
-        if (err < 0)
-        {
-            goto exit;
-        }
-
-        err = at_tok_nextint(&line, &tmp_int); // cid
-        if (err < 0)
-        {
-            goto exit;
-        }
-        err = at_tok_nextint(&line, &tmp_int); // bearer_id
-        if (err < 0)
-        {
-            goto exit;
-        }
-        err = at_tok_nextstr(&line, &tmp_ptr); // APN
-        if (err < 0)
-        {
-            goto exit;
-        }
-
-        err = at_tok_nextstr(&line, &tmp_ptr); // IP
-        if (err < 0 || str_empty(tmp_ptr))
-        {
-            goto exit;
-        }
-        if(is_ipv4(tmp_ptr)) {
-            if(inet_pton(AF_INET, tmp_ptr, &(ip_info->ipv4.IPAddr)) < 0) {
-                LOGE("inet_pton() fail.");
-                err = -1;
-                goto exit;
-            }
-
-            ip_info->ipv4.valid = true;
-            //log_hex("IPv4", &(ipv4->IPAddr), sizeof(struct in_addr));
-        } else {
-            if(str_2_ipv6(tmp_ptr, &(ip_info->ipv6.IPV6Addr))) {
-                LOGE("str_2_ipv6() fail.");
-                err = -1;
-                goto exit;
-            }
-
-            ip_info->ipv6.valid = true;
-            //log_hex("IPv6", &(ipv6->IPV6Addr), 16);
-        }
-
-        err = at_tok_nextstr(&line, &tmp_ptr); // Gateway
-        if (err < 0)
-        {
-            goto exit;
-        }
-        if(!str_empty(tmp_ptr)) { // No found gateway
-            if(is_ipv4(tmp_ptr)) {
-                if(inet_pton(AF_INET, tmp_ptr, &(ip_info->ipv4.GateWay)) < 0) {
-                    LOGE("inet_pton() fail.");
-                    err = -1;
-                    goto exit;
-                }
-
-                //log_hex("IPv4", &(ipv4->GateWay), sizeof(struct in_addr));
-            } else {
-                if(str_2_ipv6(tmp_ptr, &(ip_info->ipv6.GateWay))) {
-                    LOGE("str_2_ipv6() fail.");
-                    err = -1;
-                    goto exit;
-                }
-
-                //log_hex("IPv6", &(ipv6->GateWay), 16);
-            }
-        }
-
-        err = at_tok_nextstr(&line, &tmp_ptr); // prim_DNS
-        if (err < 0)
-        {
-            goto exit;
-        }
-        if(!str_empty(tmp_ptr)) { // No found Primary DNS
-            if(is_ipv4(tmp_ptr)) {
-                if(inet_pton(AF_INET, tmp_ptr, &(ip_info->ipv4.PrimaryDNS)) < 0) {
-                    LOGE("inet_pton() fail.");
-                    err = -1;
-                    goto exit;
-                }
-
-                //log_hex("IPv4", &(ipv4->PrimaryDNS), sizeof(struct in_addr));
-            } else {
-                if(str_2_ipv6(tmp_ptr, &(ip_info->ipv6.PrimaryDNS))) {
-                    LOGE("str_2_ipv6() fail.");
-                    err = -1;
-                    goto exit;
-                }
-
-                //log_hex("IPv6", &(ipv6->PrimaryDNS), 16);
-            }
-        }
-
-        err = at_tok_nextstr(&line, &tmp_ptr); // sec_DNS
-        if (err < 0)
-        {
-            goto exit;
-        }
-        if(!str_empty(tmp_ptr)) { // No found Secondary DNS
-            if(is_ipv4(tmp_ptr)) {
-                if(inet_pton(AF_INET, tmp_ptr, &(ip_info->ipv4.SecondaryDNS)) < 0) {
-                    LOGE("inet_pton() fail.");
-                    err = -1;
-                    goto exit;
-                }
-
-                //log_hex("IPv4", &(ipv4->SecondaryDNS), sizeof(struct in_addr));
-            } else {
-                if(str_2_ipv6(tmp_ptr, &(ip_info->ipv6.SecondaryDNS))) {
-                    LOGE("str_2_ipv6() fail.");
-                    err = -1;
-                    goto exit;
-                }
-
-                //log_hex("IPv6", &(ipv6->SecondaryDNS), 16);
-            }
-        }
-
-        lines_ptr = lines_ptr->p_next;
-    }
-
-exit:
-    at_response_free(response);
-    return err;
-}
-
-
 //void net_list_free(void *data);
 // Return MBTK_INFO_ERR_SUCCESS,will call pack_error_send() to send RSP.
 // Otherwise, do not call pack_error_send().
@@ -2346,169 +1410,6 @@
             }
             break;
         }
-        case RIL_MSG_ID_NET_APN:
-        {
-            if(pack->data_len == 0 || pack->data == NULL)
-            {
-                mbtk_apn_info_array_t apns;
-                memset(&apns, 0, sizeof(mbtk_apn_info_array_t));
-                if(req_apn_get(FALSE, &apns, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
-                {
-                    if(cme_err != MBTK_RIL_ERR_CME_NON) {
-                        err = MBTK_RIL_ERR_CME + cme_err;
-                    } else {
-                        err = MBTK_RIL_ERR_UNKNOWN;
-                    }
-                    LOGD("Get APN fail.");
-                }
-                else
-                {
-                    LOGD("size - %d", sizeof(mbtk_apn_info_array_t));
-                    ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &apns, sizeof(mbtk_apn_info_array_t));
-                }
-            }
-            else     // Set
-            {
-                mbtk_apn_info_t *apn = (mbtk_apn_info_t*)pack->data;
-                if(apn_check_and_cid_reset(apn)) {
-                    err = MBTK_RIL_ERR_CID;
-                } else {
-                    if(apn_conf_support(apn->cid)) {
-                        if(req_apn_set(apn, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
-                        {
-                            if(cme_err != MBTK_RIL_ERR_CME_NON) {
-                                err = MBTK_RIL_ERR_CME + cme_err;
-                            } else {
-                                err = MBTK_RIL_ERR_UNKNOWN;
-                            }
-                            LOGD("Set APN fail.");
-                        }
-                        else
-                        {
-                            if(apn_prop_set(apn)) {
-                                LOGE("Save APN fail.");
-                            }
-                            ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
-                        }
-                    } else {
-                        err = MBTK_RIL_ERR_UNSUPPORTED;
-                        LOGD("Can not set APN for CID : %d", apn->cid);
-                    }
-                }
-            }
-            break;
-        }
-        case RIL_MSG_ID_NET_DATA_CALL:
-        {
-            if(pack->data_len == 0 || pack->data == NULL)
-            {
-                err = MBTK_RIL_ERR_UNSUPPORTED;
-            }
-            else     // Set
-            {
-                mbtk_data_call_info_t *call_info = (mbtk_data_call_info_t*)pack->data;
-                if(!apn_conf_support(call_info->cid)) {
-                    err = MBTK_RIL_ERR_UNSUPPORTED;
-                    LOGD("Can not data call for CID : %d", call_info->cid);
-                } else {
-                    if(call_info->type == MBTK_DATA_CALL_START) {
-                        mbtk_ip_info_t ip_info;
-                        memset(&ip_info, 0, sizeof(ip_info));
-#if 0
-                        if(apn_prop_reset(call_info)) {
-                            err = MBTK_RIL_ERR_REQ_UNKNOWN;
-                            LOG("apn_prop_reset() fail.");
-                        } else
-#else
-                        if(apn_prop_reset(call_info)) {
-                            LOG("apn_prop_reset() fail.");
-                        }
-#endif
-                        {
-                            if(req_data_call_start(call_info->cid, call_info->def_route, call_info->as_dns,
-                                    call_info->retry_interval, call_info->timeout, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
-                            {
-                                if(cme_err != MBTK_RIL_ERR_CME_NON) {
-                                    err = MBTK_RIL_ERR_CME + cme_err;
-                                } else {
-                                    err = MBTK_RIL_ERR_UNKNOWN;
-                                }
-                                LOGD("Start data call fail.");
-                            }
-                            else
-                            {
-                                // Wait for "CONNECT" or "+CGEV:"
-                                if(wait_cgact_complete(call_info->timeout)) { // Timeout
-                                    err = MBTK_RIL_ERR_TIMEOUT;
-                                    break;
-                                }
-
-                                // Get Ip informations.
-                                cme_err = MBTK_RIL_ERR_CME_NON;
-                                if(req_data_call_state_get(call_info->cid ,&ip_info, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
-                                {
-                                    LOGD("Get net informations fail.");
-                                    err = MBTK_RIL_ERR_NET_CONF;
-                                }
-                                else
-                                {
-                                    // Config network informations.
-                                    if(net_ifc_reconfig(call_info->cid, call_info->def_route, call_info->as_dns, &ip_info)) {
-                                        err = MBTK_RIL_ERR_NET_CONF;
-                                        break;
-                                    }
-
-                                    ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &ip_info, sizeof(mbtk_ip_info_t));
-                                }
-                            }
-                        }
-                    } else if(call_info->type == MBTK_DATA_CALL_STOP) {
-                        if(req_data_call_stop(call_info->cid, call_info->timeout, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
-                        {
-                            if(cme_err != MBTK_RIL_ERR_CME_NON) {
-                                err = MBTK_RIL_ERR_CME + cme_err;
-                            } else {
-                                err = MBTK_RIL_ERR_UNKNOWN;
-                            }
-                            LOGD("Stop data call fail.");
-                        }
-                        else
-                        {
-                            // Wait for "CONNECT" or "+CGEV:"
-                            if(wait_cgact_complete(call_info->timeout)) { // Timeout
-                                err = MBTK_RIL_ERR_TIMEOUT;
-                                break;
-                            }
-
-                            // Clean network config.
-                            if(net_ifc_config(call_info->cid, FALSE, FALSE, NULL)) {
-                                err = MBTK_RIL_ERR_NET_CONF;
-                                break;
-                            }
-
-                            ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
-                        }
-                    } else {
-                        mbtk_ip_info_t ip_info;
-                        memset(&ip_info, 0, sizeof(ip_info));
-                        if(req_data_call_state_get(call_info->cid ,&ip_info, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
-                        {
-                            if(cme_err != MBTK_RIL_ERR_CME_NON) {
-                                err = MBTK_RIL_ERR_CME + cme_err;
-                            } else {
-                                err = MBTK_RIL_ERR_UNKNOWN;
-                            }
-                            LOGD("Get data call state fail.");
-                        }
-                        else
-                        {
-                            ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &ip_info, sizeof(mbtk_ip_info_t));
-                        }
-                    }
-                }
-            }
-            break;
-        }
         default:
         {
             err = MBTK_RIL_ERR_REQ_UNKNOWN;