Add mbtk_source git commit info

Change-Id: I9867613657db269bba81d28c4b3712062ae41bdd
diff --git a/mbtk/mbtk_rild_v2/inc/ril_info.h b/mbtk/mbtk_rild_v2/inc/ril_info.h
index 896a73c..595d603 100755
--- a/mbtk/mbtk_rild_v2/inc/ril_info.h
+++ b/mbtk/mbtk_rild_v2/inc/ril_info.h
@@ -26,6 +26,7 @@
 
 #define MBTK_APN_PROP       "persist.mbtk.apn"
 #define MBTK_DEF_ROUTE_CID  "persist.mbtk.def_route_cid"
+#define MBTK_DEF_DNS_CID  "persist.mbtk.def_dns_cid"
 
 typedef struct
 {
@@ -104,11 +105,19 @@
 
 typedef struct {
     mbtk_ril_cid_enum cid_for_def_route;
+    mbtk_ril_cid_enum cid_for_dns;
 
     int num;
     mbtk_apn_info_t apns[MBTK_APN_CID_MAX];
 } ril_apn_info_array_t;
 
+typedef struct
+{
+    int cid;
+    bool act;
+    bool waitting;
+} ril_cgact_wait_t;
+
 extern ril_info_t ril_info;
 
 
@@ -121,4 +130,8 @@
 
 bool is_ipv4(const char *ip);
 
+int net_ifc_config(mbtk_ril_cid_enum cid, bool def_route, bool as_dns, mbtk_ip_info_t *ip_info);
+
+int net_ifc_reconfig(mbtk_ril_cid_enum cid, bool def_route, bool as_dns, mbtk_ip_info_t *ip_info);
+
 #endif /* _RIL_INFO_H */
diff --git a/mbtk/mbtk_rild_v2/src/main.c b/mbtk/mbtk_rild_v2/src/main.c
index 24a74a3..7f68de3 100755
--- a/mbtk/mbtk_rild_v2/src/main.c
+++ b/mbtk/mbtk_rild_v2/src/main.c
@@ -52,6 +52,7 @@
 ril_band_info_t band_info;

 ril_info_t ril_info;

 extern mbtk_cell_pack_info_t cell_info;

+extern ril_cgact_wait_t cgact_wait;

 

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

 // int mbtk_signal_log(char *data);

@@ -282,7 +283,297 @@
     }
 }

 

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

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

+{

+    // "CONNECT"

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

+    {

+#if 1

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

+            cgact_wait.waitting = false;

+        }

+#endif

+    }

+    // +CGEV:

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

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

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

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

+    // +CGEV: NW DETACH

+    // +CGEV: ME DETACH

+    //

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

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

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

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

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

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

+    // +CGEV: EPS ACT <cid>

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

+    // +CGEV: NW REATTACH

+

+    /*

+    +CGEV: NW DETACH

+    +CGEV: ME DETACH

+    +CGEV: NW CLASS <class>

+    +CGEV: ME CLASS <class>

+    +CGEV: NW PDN ACT <cid>

+    +CGEV: ME PDN ACT <cid>[,<reason>[,<cid_other>]]

+    +CGEV: NW ACT <p_cid>, <cid>, <event_type>

+    +CGEV: ME ACT <p_cid>, <cid>, <event_type>

+    +CGEV: NW DEACT <PDP_type>, <PDP_addr>, [<cid>]

+    +CGEV: ME DEACT <PDP_type>, <PDP_addr>, [<cid>]

+    +CGEV: NW PDN DEACT <cid>

+    +CGEV: NW DEACT <PDP_type>, <PDP_addr>, [<cid>]

+    +CGEV: ME PDN DEACT <cid>

+    +CGEV: ME DEACT <PDP_type>, <PDP_addr>, [<cid>]

+    +CGEV: NW DEACT <p_cid>, <cid>, <event_type>

+    +CGEV: NW DEACT <PDP_type>, <PDP_addr>, [<cid>]

+    +CGEV: ME DEACT <p_cid>, <cid>, <event_type>

+    +CGEV: ME DEACT <PDP_type>, <PDP_addr>, [<cid>]

+    +CGEV: NW MODIFY <cid>, <change_reason>, <event_type>

+    +CGEV: ME MODIFY <cid>, <change_reason>, <event_type>

+    +CGEV: REJECT <PDP_type>, <PDP_addr>

+    +CGEV: NW REACT <PDP_type>, <PDP_addr>, [<cid>]

+    */

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

+    {

+#if 1

+        // "+CGEV: ME PDN ACT ")) { // +CGEV: ME PDN ACT <cid>[,<reason>[,<cid_other>]]

+        // "+CGEV: NW MODIFY ")) { //  +CGEV: NW MODIFY <cid>, <change_reason>, <event_type>

+        // "+CGEV: ME PDN DEACT ")) { // +CGEV: ME PDN DEACT 1

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

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

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

+            if(cgact_wait.waitting) {

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

+        } else {

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

+            return;

+        }

+

+        if(cgact_wait.act) {

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

+                cgact_wait.waitting = false;

+            }

+        } else {

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

+                cgact_wait.waitting = false;

+            }

+        }

+

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

+#else

+        if(at_process) {

+            if(cgact_wait.act) {

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

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

+                        cgact_wait.waitting = false;

+                    }

+

+                    uint8 data_pdp;

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

+                    char* free_ptr = tmp_s;

+                    char *line = tmp_s;

+                    int tmp_int;

+                    if (at_tok_start(&line) < 0)

+                    {

+                        goto at_PDP_CREG_EXIT;

+                    }

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

+                    {

+                        goto at_PDP_CREG_EXIT;

+                    }

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

+                    {

+                        goto at_PDP_CREG_EXIT;

+                    }

+                    data_pdp = tmp_int;

+at_PDP_CREG_EXIT:

+                    free(free_ptr);

+

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

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

+                    {

+                        if(data_pdp == 0)

+                        {

+                            data_pdp = 25;

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

+                            //data_pdp = cgact_wait.cid + 200;

+                        }

+                        else if(data_pdp == 1)

+                        {

+                            data_pdp = 26;

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

+                        }

+                        else if(data_pdp == 2)

+                        {

+                            data_pdp = 27;

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

+                        }

+                        else if(data_pdp == 3)

+                        {

+                            data_pdp = 27;

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

+                        }

+                        else

+                        {

+

+                        }

+                        if(cgact_wait.cid != 0)

+                        {

+                            data_pdp = cgact_wait.cid + 200;

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

+                        }

+                    }

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

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

+                        cgact_wait.waitting = false;

+                    }

+                }

+            } else {

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

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

+                        cgact_wait.waitting = false;

+                    }

+                    uint8 data_pdp;

+                    data_pdp = 0;       //

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

+                    if(cgact_wait.cid != 0)

+                    {

+                        data_pdp = cgact_wait.cid + 100;

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

+                    }

+                }

+            }

+        } else {

+            // apn_state_set

+

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

+

+            // +CGEV: EPS PDN ACT 1

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

+

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

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

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

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

+                data[0] = (uint8)0;

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

+

+                uint8 data_pdp;

+                data_pdp = 0;       //

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

+                data_pdp = data[1] + 100;

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

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

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

+#if (defined(MBTK_AF_SUPPORT) || defined(MBTK_ALL_CID_SUPPORT))

+				//data[0] = (uint8)1;

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

+#else

+                data[0] = (uint8)1;

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

+#endif

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

+        }

+#endif

+    } else {

+        LOGW("Unknown PDP URC : %s", s);

+    }

+}

+

+

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

 {

     /*

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

@@ -925,6 +1216,15 @@
     if (strStartsWith(s, "MBTK_AT_READY")) // AT ready.

     {

 

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

+        urc_pdp_state_process(s, sms_pdu);

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

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

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

+        || strStartsWith(s, "+EEMUMTSINTERRAT:") || strStartsWith(s, "+EEMGINFOBASIC:")

+        || strStartsWith(s, "+EEMGINFOSVC:") || strStartsWith(s, "+EEMGINFOPS:")

+        || strStartsWith(s, "+EEMGINFONC:")) {

+        urc_cell_info_process(s, sms_pdu);

     }

 #if 0

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

@@ -946,119 +1246,7 @@
         }

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

     }

-    // "CONNECT"

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

-    {

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

-            cgact_wait.waitting = false;

-        }

-

-        uint8 data_pdp;

-        data_pdp = 1;       //

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

-    }

-    // +CGEV:

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

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

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

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

-    // +CGEV: NW DETACH

-    // +CGEV: ME DETACH

-    //

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

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

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

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

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

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

-    // +CGEV: EPS ACT <cid>

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

-    // +CGEV: NW REATTACH

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

-    {

-        if(at_process) {

-            if(cgact_wait.act) {

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

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

-                        cgact_wait.waitting = false;

-                    }

-

-                    uint8 data_pdp;

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

-                    char* free_ptr = tmp_s;

-                    char *line = tmp_s;

-                    int tmp_int;

-                    if (at_tok_start(&line) < 0)

-                    {

-                        goto at_PDP_CREG_EXIT;

-                    }

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

-                    {

-                        goto at_PDP_CREG_EXIT;

-                    }

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

-                    {

-                        goto at_PDP_CREG_EXIT;

-                    }

-                    data_pdp = tmp_int;

-at_PDP_CREG_EXIT:

-                    free(free_ptr);

-

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

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

-                    {

-                        if(data_pdp == 0)

-                        {

-                            data_pdp = 25;

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

-                            //data_pdp = cgact_wait.cid + 200;

-                        }

-                        else if(data_pdp == 1)

-                        {

-                            data_pdp = 26;

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

-                        }

-                        else if(data_pdp == 2)

-                        {

-                            data_pdp = 27;

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

-                        }

-                        else if(data_pdp == 3)

-                        {

-                            data_pdp = 27;

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

-                        }

-                        else

-                        {

-

-                        }

-                        if(cgact_wait.cid != 0)

-                        {

-                            data_pdp = cgact_wait.cid + 200;

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

-                        }

-                    }

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

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

-                        cgact_wait.waitting = false;

-                    }

-                }

-            } else {

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

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

-                        cgact_wait.waitting = false;

-                    }

-                    uint8 data_pdp;

-                    data_pdp = 0;       //

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

-                    if(cgact_wait.cid != 0)

-                    {

-                        data_pdp = cgact_wait.cid + 100;

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

-                    }

-                }

-            }

-        } else {

+    else {

             // apn_state_set

 

             // +CGEV: NW PDN DEACT <cid>

@@ -1581,14 +1769,6 @@
 #endif

 

 #endif

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

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

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

-        || strStartsWith(s, "+EEMUMTSINTERRAT:") || strStartsWith(s, "+EEMGINFOBASIC:")

-        || strStartsWith(s, "+EEMGINFOSVC:") || strStartsWith(s, "+EEMGINFOPS:")

-        || strStartsWith(s, "+EEMGINFONC:")) {

-        urc_cell_process(s, sms_pdu);

-    }

     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"

     {

 

@@ -2151,11 +2331,12 @@
     return -1;
 }

 

-

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

 {

     mbtk_log_init("radio", "MBTK_RIL");

 

+    MBTK_SOURCE_INFO_PRINT("mbtk_rild");

+

 #ifdef MBTK_DUMP_SUPPORT

     mbtk_debug_open(NULL, TRUE);

 #endif

diff --git a/mbtk/mbtk_rild_v2/src/ril_data_call.c b/mbtk/mbtk_rild_v2/src/ril_data_call.c
index a0f3eeb..4fbeca5 100755
--- a/mbtk/mbtk_rild_v2/src/ril_data_call.c
+++ b/mbtk/mbtk_rild_v2/src/ril_data_call.c
@@ -38,4 +38,165 @@
     }
 }
 
+static void net_if_as_def_route(mbtk_ril_cid_enum cid)
+{
+    if(cid != MBTK_RIL_CID_NUL) {
+        char buf[100] = {0};
+
+        // Delete all default route in the first.
+
+
+        // Add default route.
+        memset(buf, 0, sizeof(buf));
+        sprintf(buf, "route add default dev ccinet%d", cid - 1);
+        system(buf);
+    }
+}
+
+static int net_if_as_dns(mbtk_ril_cid_enum cid, mbtk_ipv4_info_t *ipv4, mbtk_ipv6_info_t *ipv6)
+{
+    char buf[1024] = {0};
+    char dns[128] = {0};
+    int offset = 0;
+    int fd = -1;
+
+    memset(buf, 0x0, 1024);
+    memset(dns, 0x0, 128);
+    offset = sprintf(buf, "search lan\n");
+    if(ipv4->valid)
+    {
+        if(inet_ntop(AF_INET, &(ipv4->PrimaryDNS), dns, 32) == NULL) {
+            LOGE("PrimaryDNS error.");
+        } else {
+            LOGD("PrimaryDNS : %s", dns);
+        }
+        offset += sprintf(buf + offset, "nameserver %s\n", dns);
+        memset(dns, 0x0, 128);
+        if(inet_ntop(AF_INET, &(ipv4->SecondaryDNS), dns, 32) == NULL) {
+            LOGE("SecondaryDNS error.");
+        } else {
+            LOGD("SecondaryDNS : %s", dns);
+        }
+        offset += sprintf(buf + offset, "nameserver %s\n", dns);
+    }
+    if(ipv6->valid)
+    {
+        memset(dns, 0x0, 128);
+		if(ipv6_2_str(&(ipv6->PrimaryDNS), dns))
+        {
+			LOGE("PrimaryDNS error.");
+		} else {
+			LOGD("PrimaryDNS : %s", dns);
+		}
+        offset += sprintf(buf + offset, "nameserver %s\n", dns);
+        memset(dns, 0x0, 128);
+		if(ipv6_2_str(&(ipv6->SecondaryDNS), dns))
+        {
+			LOGE("SecondaryDNS error.");
+		} else {
+			LOGD("SecondaryDNS : %s", dns);
+		}
+        offset += sprintf(buf + offset, "nameserver %s\n", dns);
+    }
+
+    if(offset > 0)
+    {
+        fd = open("/tmp/resolv.conf", O_WRONLY | O_TRUNC);
+        if(fd < 0)
+        {
+            LOGE("/tmp/resolv.conf : open fail.");
+            return -1;
+        }
+
+        int ret = write(fd, buf, offset);
+        if(ret < 0)
+        {
+            LOGE("/tmp/resolv.conf : write fail.");
+            close(fd);
+            return -1;
+        }
+
+        close(fd);
+    }
+    return 0;
+}
+
+int net_ifc_config(mbtk_ril_cid_enum cid, bool def_route, bool as_dns, mbtk_ip_info_t *ip_info)
+{
+    int ret = -1;
+    char dev[20] = {0};
+    sprintf(dev, "ccinet%d", cid - 1);
+    if(ip_info) { // Config IP.
+        // Config IPv4 address.
+        if(ip_info->ipv4.valid) {
+            char ip[20] = {0};
+            if(inet_ntop(AF_INET, &(ip_info->ipv4.IPAddr), ip, 20) == NULL) {
+                LOGE("inet_ntop ipv4 ip fail.");
+                goto exit;
+            }
+
+            if(mbtk_ifc_configure2(dev, ip, 0, NULL, "255.255.255.0")) {
+                LOGD("Config %s IPv4 %s fail.", dev, ip);
+                goto exit;
+            } else {
+                LOGD("Config %s IPv4 %s success.", dev, ip);
+            }
+        }
+
+        // Config IPv6 address.
+        if(ip_info->ipv6.valid) {
+            char ip[50] = {0};
+
+            if(inet_ntop(AF_INET6, &(ip_info->ipv6.IPV6Addr), ip, 50) == NULL) {
+                LOGE("inet_ntop ipv6 ip fail.");
+                goto exit;
+            }
+
+            if(mbtk_ipv6_config(dev, ip, 64)) {
+                LOGD("Config %s IPv6 %s fail.", dev, ip);
+                goto exit;
+            } else {
+                LOGD("Config %s IPv6 %s success.", dev, ip);
+            }
+        }
+
+        // mbtk_qser_route_config(cid, &ip_info->ipv4, &ip_info->ipv6);
+        if(def_route && (ip_info->ipv4.valid || ip_info->ipv6.valid)) {
+            net_if_as_def_route(cid);
+        }
+
+        if(as_dns) {
+            ret = net_if_as_dns(cid, &(ip_info->ipv4), &(ip_info->ipv6));
+        }
+    } else { // Del IP
+        if(mbtk_ifc_configure2(dev, NULL, 0, NULL, NULL)) {
+            LOGD("Config %s IPv4 0 fail.", dev);
+            goto exit;
+        } else {
+            LOGD("Config %s IPv4 0 success.", dev);
+        }
+#if 0
+        if(mbtk_ipv6_config(dev, NULL, 64)) {
+            LOGD("Config %s IPv6 0 fail.", dev);
+            goto exit;
+        } else {
+            LOGD("Config %s IPv6 0 success.", dev);
+        }
+#endif
+    }
+
+    ret = 0;
+exit:
+    return ret;
+}
+
+int net_ifc_reconfig(mbtk_ril_cid_enum cid, bool def_route, bool as_dns, mbtk_ip_info_t *ip_info)
+{
+    int ret = net_ifc_config(cid, FALSE, FALSE, NULL);
+    if(ret) {
+        return ret;
+    }
+
+    return net_ifc_config(cid, def_route, as_dns, ip_info);
+}
 
diff --git a/mbtk/mbtk_rild_v2/src/ril_net.c b/mbtk/mbtk_rild_v2/src/ril_net.c
index 6e0cd8c..3592850 100755
--- a/mbtk/mbtk_rild_v2/src/ril_net.c
+++ b/mbtk/mbtk_rild_v2/src/ril_net.c
@@ -21,10 +21,11 @@
 #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(mbtk_apn_info_array_t *apns, int *cme_err);
+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(ril_apn_info_array_t *apns);
 
@@ -66,7 +67,7 @@
     return TRUE;
 }
 
-static int apn_cid_reset(mbtk_apn_info_t *apn)
+static int apn_check_and_cid_reset(mbtk_apn_info_t *apn)
 {
     // Delete apn
     if(str_empty(apn->apn)) {
@@ -76,10 +77,11 @@
         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(&apns, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+        if(req_apn_get(FALSE, &apns, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
         {
             LOGW("Get APN fail.");
             return 0;
@@ -94,27 +96,33 @@
             }
             return -1;
         }
-    } else {
-        if(apn->cid == MBTK_RIL_CID_NUL) {
-            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(&apns, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
-            {
-                LOGW("Get APN fail.");
+    } 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
-            {
+        }
+        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++) {
-                    int index = 0;
+                    index = 0;
                     while(index < apns.num) {
                         if(apns.apns[index].cid == start_cid)
                             break;
@@ -124,7 +132,8 @@
                     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;
+                        // return 0;
+                        break;
                     }
                 }
 
@@ -132,6 +141,28 @@
                     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++;
+                }
             }
         }
     }
@@ -149,11 +180,16 @@
     // 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_dns = MBTK_RIL_CID_DEF;
         cid = MBTK_RIL_CID_2;
     } else {
         if(property_get(MBTK_DEF_ROUTE_CID, prop_data, "") > 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, "") > 0 && !str_empty(prop_data)) {
+            apns->cid_for_dns = (mbtk_ril_cid_enum)atoi(prop_data);
+        }
         cid = MBTK_APN_CID_MIN;
     }
     for(; cid <= MBTK_APN_CID_MAX; cid++) {
@@ -295,6 +331,11 @@
         prop_data[0] = '0' + apn->cid;
         ret = property_set(MBTK_DEF_ROUTE_CID, prop_data);
     }
+    if(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;
 }
 
@@ -306,10 +347,28 @@
     } 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=?
@@ -1484,7 +1543,7 @@
 OK
 
 */
-static int req_apn_get(mbtk_apn_info_array_t *apns, int *cme_err)
+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);
@@ -1500,6 +1559,16 @@
     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>
@@ -1519,7 +1588,7 @@
             goto exit;
         }
         // Only get CID 1-7
-        if(tmp_int >= MBTK_APN_CID_MIN && tmp_int <= MBTK_APN_CID_MAX) {
+        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
@@ -1655,12 +1724,16 @@
 OK
 
 */
-static int req_data_call_start(mbtk_ril_cid_enum cid, bool def_route,
-                int retry_interval, int timeout, mbtk_ip_info_t *ip_info, int *cme_err)
+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);
@@ -1687,6 +1760,11 @@
     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){
@@ -2089,7 +2167,7 @@
             {
                 mbtk_apn_info_array_t apns;
                 memset(&apns, 0, sizeof(mbtk_apn_info_array_t));
-                if(req_apn_get(&apns, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                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;
@@ -2107,7 +2185,7 @@
             else     // Set
             {
                 mbtk_apn_info_t *apn = (mbtk_apn_info_t*)pack->data;
-                if(apn_cid_reset(apn)) {
+                if(apn_check_and_cid_reset(apn)) {
                     err = MBTK_RIL_ERR_CID;
                 } else {
                     if(apn_conf_support(apn->cid)) {
@@ -2144,58 +2222,104 @@
             else     // Set
             {
                 mbtk_data_call_info_t *call_info = (mbtk_data_call_info_t*)pack->data;
-                if(call_info->type == MBTK_DATA_CALL_START) {
-                    mbtk_ip_info_t ip_info;
-                    memset(&ip_info, 0, sizeof(ip_info));
-                    if(apn_prop_reset(call_info)) {
-                        err = MBTK_RIL_ERR_REQ_UNKNOWN;
-                        LOG("apn_prop_reset() fail.");
-                    } else {
-                        if(req_data_call_start(call_info->cid, call_info->def_route,
-                                call_info->retry_interval, call_info->timeout, &ip_info, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                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("Start data call fail.");
+                            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));
                         }
                     }
-                } 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
-                    {
-                        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;
@@ -2211,8 +2335,3 @@
     return err;
 }
 
-
-
-
-
-