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