add data call auto reconnect for v2

Change-Id: Ib334d46c343abed5d232ed66c5805322ed675208
diff --git a/mbtk/mbtk_rild_v2/inc/ril_info.h b/mbtk/mbtk_rild_v2/inc/ril_info.h
index df7c786..c07e3f0 100755
--- a/mbtk/mbtk_rild_v2/inc/ril_info.h
+++ b/mbtk/mbtk_rild_v2/inc/ril_info.h
@@ -110,6 +110,8 @@
 } ril_act_state_enum;
 
 typedef struct {
+    bool valid;
+
     mbtk_apn_info_t apn_info;
     ril_act_state_enum act_state;
 } ril_data_call_info_t;
diff --git a/mbtk/mbtk_rild_v2/src/main.c b/mbtk/mbtk_rild_v2/src/main.c
index e2020fc..939585f 100755
--- a/mbtk/mbtk_rild_v2/src/main.c
+++ b/mbtk/mbtk_rild_v2/src/main.c
@@ -70,6 +70,8 @@
 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_retry(mbtk_ril_net_reg_state_info_t *reg_state);

+

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

 

@@ -686,7 +688,8 @@
         mbtk_net_ready();

     }

 

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

+    // Should restart data call if necessary.

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

 CGREG_EXIT:

     free(tmp_s);

 }

@@ -799,8 +802,8 @@
 

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

+            data_call_state_change_cb(cgev_info.cid, cgev_info.action, cgev_info.auto_change, cgev_info.reason);

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

         }

 

@@ -2186,6 +2189,12 @@
             LOGD("Radio state : %d", state->radio_state);

             break;
         }

+        case RIL_MSG_ID_IND_NET_REG_STATE_CHANGE:

+        {

+            mbtk_ril_net_reg_state_info_t *reg_state = (mbtk_ril_net_reg_state_info_t*)msg->data;

+            data_call_retry(reg_state);

+            break;

+        }

         default:
         {
             LOGE("Unknown URC : %d", msg->msg);
diff --git a/mbtk/mbtk_rild_v2/src/ril_data_call.c b/mbtk/mbtk_rild_v2/src/ril_data_call.c
index d5bcb2c..aef3ac9 100755
--- a/mbtk/mbtk_rild_v2/src/ril_data_call.c
+++ b/mbtk/mbtk_rild_v2/src/ril_data_call.c
@@ -28,6 +28,8 @@
 static int req_apn_set(mbtk_apn_info_t *apn, int *cme_err);
 static void apn_prop_get(mbtk_apn_info_array_t *apns);
 void ril_rsp_pack_send(int fd, int ril_id, int msg_index, const void* data, int data_len);
+static int req_data_call_start(mbtk_ril_cid_enum cid, int *cme_err);
+static int req_data_call_state_get(mbtk_ril_cid_enum cid, mbtk_ip_info_t *ip_info, int *cme_err);
 
 /*
 IPv4 : 10.255.74.26
@@ -274,6 +276,18 @@
     memset(&apns, 0, sizeof(mbtk_apn_info_array_t));
     apn_prop_get(&apns);
     while(i < apns.num) {
+        // Update apn info in buffer.
+        int cid = apns.apns[i].cid;
+        info_list[cid - 1].valid = true;
+//        info_list[cid - 1].act_state = RIL_ACT_STATE_DISCONNECTED;
+        memcpy(&(info_list[cid - 1].apn_info), &(apns.apns[i]), sizeof(mbtk_apn_info_t));
+
+        LOGD("CID - %d, ip_type - %d, auth - %d, auto_save - %d, auto_boot_call - %d, def_route - %d, as_dns - %d, apn - %s",
+            cid, info_list[cid - 1].apn_info.ip_type,
+            info_list[cid - 1].apn_info.auth, info_list[cid - 1].apn_info.auto_save,
+            info_list[cid - 1].apn_info.auto_boot_call, info_list[cid - 1].apn_info.def_route,
+            info_list[cid - 1].apn_info.as_dns, info_list[cid - 1].apn_info.apn);
+
         int cme_err = MBTK_RIL_ERR_CME_NON;
         if(req_apn_set(&(apns.apns[i]), &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
         {
@@ -445,7 +459,15 @@
 #else
         if(apn_file_read(prop_name, prop_data, sizeof(prop_data)) > 0 && !str_empty(prop_data)) {
 #endif
+            apns->apns[apns->num].auto_save = 1;
             apns->apns[apns->num].cid = (mbtk_ril_cid_enum)cid;
+
+            if(apns->cid_for_def_dns == apns->apns[apns->num].cid)
+                apns->apns[apns->num].as_dns = 1;
+
+            if(apns->cid_for_def_route == apns->apns[apns->num].cid)
+                apns->apns[apns->num].def_route = 1;
+
             char *ptr_1 = prop_data;
             apns->apns[apns->num].ip_type = (mbtk_ip_type_enum)atoi(ptr_1);
             ptr_1 = strstr(ptr_1, ",");
@@ -688,20 +710,40 @@
         prop_data[0] = '0' + apn->cid;
         ret = property_set(MBTK_DEF_DNS_CID, prop_data);
     }
+
+    // Update apn info in buffer.
+    if(!str_empty(apn->apn)) {
+        memset(&(info_list[apn->cid - 1]), 0, sizeof(ril_data_call_info_t));
+    } else {
+        info_list[apn->cid - 1].valid = true;
+        memcpy(&(info_list[apn->cid - 1].apn_info), apn, sizeof(mbtk_apn_info_t));
+    }
+
     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);
+    if(data_info->auto_boot_call != MBTK_DATA_CALL_ITEM_STATE_NON
+        || data_info->def_route != MBTK_DATA_CALL_ITEM_STATE_NON
+        || data_info->as_dns != MBTK_DATA_CALL_ITEM_STATE_NON) {
+        mbtk_apn_info_t apn;
+        if(apn_prop_get_by_cid(data_info->cid, &apn)) {
+            return -1;
+        } else {
+            if(data_info->auto_boot_call != MBTK_DATA_CALL_ITEM_STATE_NON)
+                apn.auto_boot_call = (data_info->auto_boot_call == MBTK_DATA_CALL_ITEM_STATE_ENABLE) ? 1 : 0;
+
+            if(data_info->def_route != MBTK_DATA_CALL_ITEM_STATE_NON)
+                apn.def_route = (data_info->def_route == MBTK_DATA_CALL_ITEM_STATE_ENABLE) ? 1 : 0;
+
+            if(data_info->as_dns != MBTK_DATA_CALL_ITEM_STATE_NON)
+                apn.as_dns = (data_info->as_dns == MBTK_DATA_CALL_ITEM_STATE_ENABLE) ? 1 : 0;
+            return apn_prop_set(&apn);
+        }
     }
+
+    return 0;
 }
 
 static int wait_cgact_complete(int timeout)
@@ -722,6 +764,74 @@
     }
 }
 
+void data_call_retry(mbtk_ril_net_reg_state_info_t *reg_state)
+{
+    LOGV("NET_REG_STATE_CHANGE : type - %d, tech - %d, reg_state - %d", reg_state->type, reg_state->tech, reg_state->reg_state);
+    // Only for 2g/3g/4g data domain.
+    if(reg_state->type == MBTK_NET_REG_TYPE_DATA_GSM_WCDMA
+        || reg_state->type == MBTK_NET_REG_TYPE_DATA_LTE) {
+        if(reg_state->tech >= MBTK_RADIO_TECH_UTRAN) { // No for GSM(No GPRS)
+            if(reg_state->reg_state == MBTK_NET_REG_STATE_HOME
+                || reg_state->reg_state == MBTK_NET_REG_STATE_ROAMING) { // Only Home and Roaming network.
+                int cid = MBTK_APN_CID_MIN;
+                mbtk_ip_info_t ip_info;
+                for(; cid <= MBTK_APN_CID_MAX; cid++) {
+                    LOGV("cid - %d, valid - %d, act_state - %d", cid, info_list[cid - 1].valid,
+                        info_list[cid - 1].act_state);
+                    if(info_list[cid - 1].valid && info_list[cid - 1].act_state == RIL_ACT_STATE_CONNECTED_RETRY) {
+                        // Reset ip information.
+                        char dev[20] = {0};
+                        sprintf(dev, "ccinet%d", cid - 1);
+                        if(mbtk_ifc_configure2(dev, NULL, 0, NULL, NULL)) {
+                            LOGD("Config %s IPv4 0 fail.", dev);
+                        } else {
+                            LOGD("Config %s IPv4 0 success.", dev);
+                        }
+
+                        // PDP active
+                        int cme_err = MBTK_RIL_ERR_CME_NON;
+                        if(req_data_call_start(cid, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                        {
+                            LOGE("Restart data call fail.");
+                            return;
+                        }
+                        else
+                        {
+                            // Wait for "CONNECT" or "+CGEV:"
+                            if(wait_cgact_complete(5000)) { // Timeout
+                                LOGE("PDP active timeout.");
+                                return;
+                            }
+
+                            // Get Ip informations.
+                            memset(&ip_info, 0, sizeof(ip_info));
+                            cme_err = MBTK_RIL_ERR_CME_NON;
+                            if(req_data_call_state_get(cid, &ip_info, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                            {
+                                LOGE("Get net informations fail.");
+                                return;
+                            }
+                            else
+                            {
+                                // Config network informations.
+                                LOGV("def_route - %d, as_dns - %d", info_list[cid - 1].apn_info.def_route,
+                                    info_list[cid - 1].apn_info.as_dns);
+                                if(net_ifc_reconfig(cid, info_list[cid - 1].apn_info.def_route,
+                                    info_list[cid - 1].apn_info.as_dns, &ip_info)) {
+                                    LOGE("Set net informations fail.");
+                                    return;
+                                }
+
+                                info_list[cid - 1].act_state = RIL_ACT_STATE_CONNECTED;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
 /*
 AT+CGDCONT?
 
@@ -1143,6 +1253,7 @@
 
 void data_call_state_change_cb(int cid, bool action, bool auto_change, int reason)
 {
+    // Will restart data call.
     if(auto_change && !action) {
         info_list[cid - 1].act_state = RIL_ACT_STATE_CONNECTED_RETRY;
     }
@@ -1200,8 +1311,6 @@
                                 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 {