data_call: 同步T108和T106的代码

Change-Id: I506cfe1b344d0a09e541305508dc538ef151a543
diff --git a/mbtk/include/lynq/lynq-qser-data.h b/mbtk/include/lynq/lynq-qser-data.h
index ba4711f..35c4cd9 100755
--- a/mbtk/include/lynq/lynq-qser-data.h
+++ b/mbtk/include/lynq/lynq-qser-data.h
@@ -67,10 +67,8 @@
 	qser_data_call_ip_family_e ip_family;             /*!< IP version. */
 	qser_data_call_state_e state;                     /*!< The dial status. */
 	qser_data_call_error_e err;                       /*!< The Reason code after data call disconnected. */
-	union {
-		struct v4_address_status v4;            /*!< IPv4 information. */
-		struct v6_address_status v6;            /*!< IPv6 information. */
-	};
+	struct v4_address_status v4;            /*!< IPv4 information. */
+	struct v6_address_status v6;            /*!< IPv6 information. */
 } qser_data_call_state_s;
 
 /*
diff --git a/mbtk/liblynq_lib/src/lynq_data_call.c b/mbtk/liblynq_lib/src/lynq_data_call.c
index 33fcefb..040b96f 100755
--- a/mbtk/liblynq_lib/src/lynq_data_call.c
+++ b/mbtk/liblynq_lib/src/lynq_data_call.c
@@ -5,6 +5,9 @@
 #include <pthread.h>
 #include <cutils/properties.h>
 #include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 #include <fcntl.h>
 /****************************DEFINE***************************************/
 #define QSER_RESULT_SUCCESS 0
@@ -18,10 +21,14 @@
 //AT+CGACT range: 1 - 8
 //1 default IDX, 8 IMS IDX
 #if defined(MBTK_ALL_CID_SUPPORT)
+#if defined(MBTK_ALL_APN_SUPPORT)
 #define QSER_PROFILE_IDX_MIN 0
 #else
 #define QSER_PROFILE_IDX_MIN 1
 #endif
+#else
+#define QSER_PROFILE_IDX_MIN 1
+#endif
 #define QSER_PROFILE_IDX_MAX 6
 
 /****************************DEFINE***************************************/
@@ -35,10 +42,13 @@
 static bool qser_apn_info_state[QSER_APN_NUM] = {0};
 static char qser_apn_add_save_state[QSER_APN_NUM + 1] = {0};
 static qser_data_call_s qser_data_backup;
+static bool qser_start_async = false;
 #if defined(MBTK_ALL_CID_SUPPORT)
 static int qser_apn_default_idx = -1;
+static int qser_default_pdp_idx = -1;
 #else
 static int qser_apn_default_idx = 0xFF;
+static int qser_default_pdp_idx = 0;
 #endif
 int now_idx = 0;
 /****************************VARIABLE***************************************/
@@ -126,7 +136,7 @@
 char qser_get_apn_profile_idx(void)
 {
     char i = 0;
-    for(i = QSER_PROFILE_IDX_MIN; i < 8; i++)
+    for(i = QSER_PROFILE_IDX_MIN; i <= QSER_PROFILE_IDX_MAX; i++)
     {
         if(qser_apn_info_state[i] == FALSE)
         {
@@ -273,16 +283,167 @@
     int pdp_type_tmp = 0;
     for (;pdp_type_tmp < QSER_APN_NUM; pdp_type_tmp++)
     {
-        if (strcmp(qser_apn_info[pdp_type_tmp].apn_name, apn->apn_name) == 0 || strcmp(qser_apn_info[pdp_type_tmp].apn_type, apn->apn_type) == 0)
+        if(qser_apn_add_save_state[pdp_type_tmp] == '1')
         {
-            LOGE("[qser_data_call] qser_check_apn_name_type error!");
-            return QSER_RESULT_FAIL;
+            if (strcmp(qser_apn_info[pdp_type_tmp].apn_name, apn->apn_name) == 0 || strcmp(qser_apn_info[pdp_type_tmp].apn_type, apn->apn_type) == 0)
+            {
+                LOGE("[qser_data_call] qser_check_apn_name_type error!");
+                return QSER_RESULT_FAIL;
+            }
         }
     }
 
     return QSER_RESULT_SUCCESS;
 }
 
+int qser_get_ip(char *buf, char *check_buf, char *ip_buf)
+{
+    int i = 0, num = 0;
+    char *p1 = strstr(buf, check_buf);
+    if(p1 != NULL)
+    {
+        p1 += strlen(check_buf);
+        for(; i < 32; i++)
+        {
+            if(*(p1 + i) >= '0' && *(p1 + i) <= '9' || *(p1 + i) == '.' || *(p1 + i) == ':')
+            {
+                num++;
+            }
+            else
+            {
+                break;
+            }
+        }
+
+        memcpy(ip_buf, p1, num);
+        
+    }
+    else
+    {
+        return QSER_RESULT_FAIL;
+    }
+    
+    return QSER_RESULT_SUCCESS;
+}
+
+int qser_get_ip_info(qser_data_call_state_s *state)
+{
+    if(state == NULL)
+    {
+        LOGE("[qser_data_call] state is NULL");
+        return QSER_RESULT_FAIL;
+    }
+
+    //get ip
+    FILE *fp = NULL;
+    int ret = QSER_RESULT_FAIL;
+    char buffer[1024] = {0}; 
+    char path[32] = {0};
+    char ipv4[32] = {0};
+    char ipv6[64] = {0};
+    
+    sprintf(path, "ifconfig ccinet%d", state->profile_idx);
+    fp = popen(path, "r"); 
+    if (fp == NULL)
+    {
+        LOGE("[qser_data_call] popen fail");
+        return QSER_RESULT_FAIL;
+    }
+
+    fread(buffer,1, sizeof(buffer) -1, fp);
+    pclose(fp);
+
+    ret = qser_get_ip(buffer, "inet addr:", ipv4);
+    if(ret == QSER_RESULT_SUCCESS)
+    {
+        LOGE("[qser_data_call] ipv4: %s len: %d", ipv4, strlen(ipv4));
+        //ip and gateway is same
+    }
+    else
+    {
+        LOGE("[qser_data_call] ipv4 is invain");
+    }
+
+    ret = qser_get_ip(buffer, "inet6 addr: ", ipv6);
+    if(ret == QSER_RESULT_SUCCESS)
+    {
+        LOGE("[qser_data_call] ipv4: %s len: %d", ipv6, strlen(ipv6));
+    }
+    else
+    {
+        LOGE("[qser_data_call] ipv4 is invain");
+    }
+
+    //get DNS
+    int fd = -1;
+    int i = 0;
+    char *p = NULL;
+    char DNS_v4[32] = {0};
+    char DNS_v6[64] = {0};
+
+    fd = open("/etc/resolv.conf", O_RDWR);
+    if(fd < 0)
+    {
+        LOGE("[qser_data_call] open fail");
+        return QSER_RESULT_FAIL;
+    }
+
+    memset(buffer, 0x0, 1024);
+    ret = read(fd, buffer, 1023);
+    close(fd);
+    if(ret < 0)
+    {
+        LOGE("[qser_data_call] open fail");
+        return QSER_RESULT_FAIL;
+    }
+
+    p = buffer;
+    for(; i < 4; i++)
+    {
+        switch(i)
+        {
+            case 0:
+            case 1:
+            {
+                memset(DNS_v4, 0x0, 32);
+                ret = qser_get_ip(buffer, "nameserver ", DNS_v4);
+                if(ret == QSER_RESULT_SUCCESS)
+                {
+                    LOGE("[qser_data_call] DNS_v4: %s len: %d", DNS_v4, strlen(DNS_v4));
+                }
+                else
+                {
+                    LOGE("[qser_data_call] DNS_v4 is invain");
+                }
+                break;
+            }
+            case 2:
+            case 3:
+            {
+                memset(DNS_v6, 0x0, 64);
+                ret = qser_get_ip(buffer, "nameserver ", DNS_v6);
+                if(ret == QSER_RESULT_SUCCESS)
+                {
+                    LOGE("[qser_data_call] DNS_v6: %s len: %d", DNS_v6, strlen(DNS_v6));
+                }
+                else
+                {
+                    LOGE("[qser_data_call] DNS_v6 is invain");
+                }
+                break;
+            }
+            default:
+            {
+                break;
+            }
+        }
+        
+        p = strstr(p, "nameserver ");
+        p += strlen("nameserver ");
+    }
+
+    return QSER_RESULT_SUCCESS;
+}
 
 void qser_wan_net_state_change_cb(const void* data, int data_len)
 {
@@ -308,25 +469,34 @@
         {
             state.state = QSER_DATA_CALL_DISCONNECTED;
             state.err = QSER_DATA_CALL_ERROR_NONE;
+            if( (*net_data -200) == qser_default_pdp_idx )
+            {
+                qser_default_pdp_idx = -1;
+            }
         }
         else
         {
             return;
         }
 
-        qser_net_status_cb(&state);
+        qser_get_ip_info(&state);
+        if(qser_start_async == true)
+        {
+            qser_net_status_cb(&state);
+        }
     }
 }
 
 static void* data_call_async_thread(void* arg)
 {
     qser_data_call_error_e err;
+    qser_start_async = true;
     int ret = qser_data_call_start(&qser_data_backup, &err);
     if(ret != QSER_RESULT_SUCCESS)
     {
         LOGE("[qser_data_call] qser_data_call_start() fail.");
     }
-
+    qser_start_async = false;
     return NULL;
 }
 
@@ -462,11 +632,29 @@
         return QSER_RESULT_FAIL;
     }
 
+#if defined(MBTK_ALL_CID_SUPPORT)
+    if( ( (data_call->profile_idx == qser_apn_default_idx) || (data_call->profile_idx == 0) ) && (qser_default_pdp_idx >= 0) )
+    {
+        LOGE("[qser_data_call] default pdp exist.");
+        *err = QSER_DATA_CALL_ERROR_UNKNOWN;
+        return QSER_RESULT_FAIL;
+    }
+#endif
+
     if(qser_check_profile_idx(data_call->profile_idx) < 0)
     {
-        LOGE("[qser_data_call] profile_idx is invalid.");
-        *err = QSER_DATA_CALL_ERROR_IDX_NO_EXIST;
-        return QSER_RESULT_FAIL;
+#if defined(MBTK_ALL_CID_SUPPORT)
+        if( data_call->profile_idx == 0 )
+        {
+            LOGE("[qser_data_call] profile_idx = 0.");
+        }
+        else
+#endif
+        {
+            LOGE("[qser_data_call] profile_idx is invalid.");
+            *err = QSER_DATA_CALL_ERROR_IDX_NO_EXIST;
+            return QSER_RESULT_FAIL;
+        }
     }
 
     int ret = -1;
@@ -495,7 +683,18 @@
     if(qser_apn_default_idx == data_call->profile_idx)
     {
         qser_route_config(qser_apn_default_idx + 1);
+        qser_default_pdp_idx = data_call->profile_idx;
     }
+    else if(data_call->profile_idx == 0)
+    {
+        qser_route_config(1);
+        qser_default_pdp_idx = data_call->profile_idx;
+    }
+    else
+    {
+        //
+    }
+        
 #endif
 
     return QSER_RESULT_SUCCESS;
@@ -522,11 +721,30 @@
         return QSER_RESULT_FAIL;
     }
 
+#if defined(MBTK_ALL_CID_SUPPORT)
+        if( ( (data_call->profile_idx == qser_apn_default_idx) || (data_call->profile_idx == 0) ) && (qser_default_pdp_idx >= 0) )
+        {
+            LOGE("[qser_data_call] default pdp exist.");
+            *err = QSER_DATA_CALL_ERROR_UNKNOWN;
+            return QSER_RESULT_FAIL;
+        }
+#endif
+
     if(qser_check_profile_idx(data_call->profile_idx) < 0)
     {
-        LOGE("[qser_data_call] profile_idx is invalid.");
-        *err = QSER_DATA_CALL_ERROR_IDX_NO_EXIST;
-        return QSER_RESULT_FAIL;
+#if defined(MBTK_ALL_CID_SUPPORT)
+        if((data_call->profile_idx == 0) && (qser_default_pdp_idx < 0))
+        {
+            LOGE("[qser_data_call] profile_idx = 0 and not open default idx.");
+        }
+        else
+#endif
+        {
+            LOGE("[qser_data_call] profile_idx is invalid.");
+            *err = QSER_DATA_CALL_ERROR_IDX_NO_EXIST;
+            return QSER_RESULT_FAIL;
+        }
+
     }
 
     pthread_attr_t thread_attr;
@@ -572,9 +790,18 @@
 
     if(qser_check_profile_idx(profile_idx) < 0)
     {
-        LOGE("[qser_data_call] profile_idx is invalid.");
-        *err = QSER_DATA_CALL_ERROR_IDX_NO_EXIST;
-        return QSER_RESULT_FAIL;
+#if defined(MBTK_ALL_CID_SUPPORT)
+        if(profile_idx == 0)
+        {
+            LOGE("[qser_data_call] profile_idx = 0.");
+        }
+        else
+#endif
+        {
+            LOGE("[qser_data_call] profile_idx is invalid.");
+            *err = QSER_DATA_CALL_ERROR_IDX_NO_EXIST;
+            return QSER_RESULT_FAIL;
+        }
     }
 
     int ret = -1;
@@ -598,6 +825,13 @@
     }
 
     now_idx = 0;
+#if defined(MBTK_ALL_CID_SUPPORT)
+    if(qser_default_pdp_idx == profile_idx)
+    {
+        qser_default_pdp_idx = -1;
+    }
+#endif
+
     return QSER_RESULT_SUCCESS;
 }
 
@@ -628,9 +862,18 @@
 
     if(qser_check_profile_idx(profile_idx) < 0)
     {
-        LOGE("[qser_data_call] profile_idx is invalid.");
-        *err = QSER_DATA_CALL_ERROR_IDX_NO_EXIST;
-        return QSER_RESULT_FAIL;
+#if defined(MBTK_ALL_CID_SUPPORT)
+        if(profile_idx == 0)
+        {
+            LOGE("[qser_data_call] profile_idx = 0.");
+        }
+        else
+#endif
+        {
+            LOGE("[qser_data_call] profile_idx is invalid.");
+            *err = QSER_DATA_CALL_ERROR_IDX_NO_EXIST;
+            return QSER_RESULT_FAIL;
+        }
     }
 
     int ret = -1;
@@ -759,6 +1002,18 @@
         LOGE("[qser_data_call] apn_name is NULL.");
         return QSER_RESULT_FAIL;
     }
+
+#if 0
+    if(memcmp(apn->apn_type, "iot_default", strlen("iot_default")) == 0)
+    {
+        if(qser_apn_default_idx > -1)
+        {
+            LOGE("[qser_data_call] iot_default is exist.");
+            return QSER_RESULT_FAIL;
+        }
+    }
+#endif
+
     /*add name and type verify*/
     if (qser_check_apn_name_type(apn) < 0)
     {
@@ -766,14 +1021,6 @@
         return QSER_RESULT_FAIL;
     }
 
-#if 0
-    if(memcmp(apn->apn_type, "iot_default", strlen("iot_default")) == 0)
-    {
-        LOGE("[qser_data_call] iot_default is exist.");
-        return QSER_RESULT_FAIL;
-    }
-#endif
-
     int ret = -1;
     char mbtk_auth[32]={0};
     char qser_apn_type[32] = {0};
@@ -844,6 +1091,19 @@
     sprintf(qser_apn_type, "persist.qser.apn.type%d", apn->profile_idx);
     property_set(qser_apn_type, apn->apn_type);
     memcpy(&qser_apn_info[apn->profile_idx], apn, sizeof(qser_apn_info_s));
+
+#if defined(MBTK_ALL_CID_SUPPORT)
+    if(memcmp(apn->apn_type, "iot_default", strlen(apn->apn_type)) == 0)
+    {
+        qser_apn_add_save_state[apn->profile_idx] = '2';
+        qser_apn_default_idx = apn->profile_idx;
+    }
+    else
+#endif
+    {
+        qser_apn_add_save_state[apn->profile_idx] = '1';
+    }
+
     return QSER_RESULT_SUCCESS;
 }
 
@@ -865,8 +1125,13 @@
 
     if(qser_check_profile_idx(profile_idx) < 0)
     {
-        LOGE("[qser_data_call] profile_idx is invalid.");
-        return QSER_RESULT_FAIL;
+#if defined(MBTK_ALL_CID_SUPPORT)
+        if(profile_idx != 0)
+#endif
+        {
+            LOGE("[qser_data_call] profile_idx is invalid.");
+            return QSER_RESULT_FAIL;
+        }
     }
 
     //get apn info
@@ -921,6 +1186,7 @@
         return QSER_RESULT_FAIL;
     }
 
+#if 0
     if(memcmp(apn->apn_type, "iot_default", strlen("iot_default")) == 0)
     {
         if(qser_apn_default_idx > -1)
@@ -929,10 +1195,17 @@
             return QSER_RESULT_FAIL;
         }
     }
+    /*add name and type verify*/
+    if (qser_check_apn_name_type(apn) < 0)
+    {
+        LOGE("[qser_data_call] check param error.");
+        return QSER_RESULT_FAIL;
+    }
+#endif
 
     int ret = 0;
     char idx = qser_get_apn_profile_idx();
-    if(idx >= 8)
+    if(idx > QSER_PROFILE_IDX_MAX)
     {
         LOGE("[qser_data_call] idx is full.");
         return QSER_RESULT_FAIL;
@@ -956,17 +1229,6 @@
             return QSER_RESULT_FAIL;
         }
         *profile_idx = idx;
-#if defined(MBTK_ALL_CID_SUPPORT)
-        if(memcmp(apn->apn_type, "iot_default", strlen("iot_default")) == 0)
-        {
-            qser_apn_add_save_state[idx] = '2';
-            qser_apn_default_idx = idx;
-        }
-        else
-#endif
-        {
-            qser_apn_add_save_state[idx] = '1';
-        }
         
         property_set("persist.qser.datacall.apn", qser_apn_add_save_state);
     }
@@ -1038,8 +1300,13 @@
             {
                 if(qser_apn_add_save_state[apns[i].cid - 1] == '0')
                 {
-                    LOGE("[qser_data_call] idx no open.");
-                    continue;
+#if defined(MBTK_ALL_CID_SUPPORT)
+                    if((apns[i].cid - 1) != 0)
+#endif
+                    {
+                        LOGE("[qser_data_call] idx no open.");
+                        continue;
+                    }
                 }
                 if(qser_apn_info_param_convert(apns[i].cid - 1, &apn_list->apn[i], &apns[i]) != 0)
                 {