blob: 218e14bd8d637ab22dc01ece640a279677f28f57 [file] [log] [blame]
#include "ql/DSI_ConnectManager.h"
#include "mbtk_info_api.h"
#include <fcntl.h>
extern mbtk_info_handle_t* ql_info_handle;
extern int ql_info_handle_num;
static bool inited = FALSE;
typedef struct
{
bool active;
uint8 cid;
int ip_type;
char user[128];
char pass[128];
QL_DSI_AUTH_PREF_T auth;
} apn_info;
// 2 - 7
static apn_info ql_apn_info[9]={0};
static int mbtk_interval_sec = 0;
static nw_status_cb ql_net_status_cb = NULL;
static ex_conn_status_cb ql_net_ex_status_cb = NULL;
static int now_cid = 0;
void ql_wan_net_state_change_cb(const void* data, int data_len)
{
uint8 *net_data = NULL;
net_data = (uint8 *)data;
if(*net_data > 100 && *net_data < 200)
{
int cid;
cid = *net_data;
cid = cid - 100;
ql_apn_info[cid].active = FALSE;//close
if(ql_net_ex_status_cb != NULL)
{
ql_net_ex_status_cb(cid, ql_apn_info[cid].ip_type, CONNECT_DISCON, 0);
}
}
else if(*net_data > 200)
{
int cid;
cid = *net_data;
cid = cid - 200;
ql_apn_info[cid].active = TRUE;//open
}
else
{
if(ql_net_status_cb != NULL)
{
ql_net_status_cb(*net_data);
if(*net_data == 25 || *net_data == 26 || *net_data == 27)
{
ql_net_status_cb(CONNECT_CONSUCCESS);
}
}
if(ql_net_ex_status_cb != NULL)
{
if(*net_data == 1)
{
ql_net_ex_status_cb(now_cid, ql_apn_info[now_cid].ip_type, CONNECT_CONSUCCESS, 0);
}
}
}
}
int ql_wan_init(void)
{
if(!inited && ql_info_handle == NULL)
{
ql_info_handle = mbtk_info_handle_get();
if(ql_info_handle)
{
ql_info_handle_num++;
inited = TRUE;
mbtk_pdp_state_change_cb_reg(ql_info_handle, ql_wan_net_state_change_cb);
//return 0;
} else {
LOGE("mbtk_info_handle_get() fail.");
return -1;
}
} else {
if(!inited) {
ql_info_handle_num++;
inited = TRUE;
mbtk_pdp_state_change_cb_reg(ql_info_handle, ql_wan_net_state_change_cb);
}
//return 0;
}
mbtk_apn_info_t apns[10] = {0};
int apn_num = MBTK_APN_CID_MAX;
int ret = mbtk_apn_get(ql_info_handle, &apn_num, apns);
if(ret != 0)
{
LOGD("mbtk_apn_get ret = %d",ret);
}
else
{
int i;
int profile_idx;
for(i=0;i<MBTK_APN_CID_MAX;i++)
{
if(apns[i].cid > 0 && apns[i].cid <= MBTK_APN_CID_MAX)
{
profile_idx = apns[i].cid;
if(apns[i].ip_type == MBTK_IP_TYPE_IPV4V6) // IPV4V6
ql_apn_info[profile_idx].ip_type = 0;
else if(apns[i].ip_type == MBTK_IP_TYPE_IP) // IPV4
ql_apn_info[profile_idx].ip_type = 1;
else if(apns[i].ip_type == MBTK_IP_TYPE_IPV6) // IPV6
ql_apn_info[profile_idx].ip_type = 2;
else
ql_apn_info[profile_idx].ip_type = 0;
}
}
}
return 0;
}
int ql_wan_release(void)
{
if(ql_info_handle)
{
LOGD("ql_info_handle_num = %d", ql_info_handle_num);
if(ql_info_handle_num == 1) { // 最后一个引用,可释放。
int ret = mbtk_info_handle_free(&ql_info_handle);
if(ret) {
LOGE("mbtk_info_handle_free() fail.");
return -1;
}
else
{
ql_info_handle_num = 0;
ql_info_handle = NULL;
return 0;
}
} else {
ql_info_handle_num--;
return 0;
}
}
else
{
LOGE("DATA handle not inited.");
return -1;
}
}
/*
*Set data call over time.
*/
int ql_wan_set_autoconnect(int auto_status, int interval_sec)
{
if(auto_status == 0) //不开启失败重连
mbtk_interval_sec = 0;
else //开启失败重连等待时间
{
if(interval_sec <= 0)
mbtk_interval_sec = interval_sec;
else
mbtk_interval_sec = 5; // 默认为5s
}
return 0;
}
#ifdef MBTK_AF_SUPPORT
int mbtk_route_config(int profile_idx)
{
char buf[1024] = {0};
char dns[128] = {0};
int offset = 0;
int fd = -1;
mbtk_ipv4_info_t ipv4;
mbtk_ipv6_info_t ipv6;
sprintf(buf, "route add default dev ccinet%d", profile_idx -1);
system(buf);
int ret = mbtk_data_call_state_get(ql_info_handle, profile_idx, &ipv4, &ipv6);
if(ret != 0)
return -1;
else
{
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) {
LOGD("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) {
LOGD("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))
{
LOGD("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))
{
LOGD("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)
{
LOGD("mbtk_route_config : open fail.");
return -1;
}
ret = write(fd, buf, offset);
if(ret < 0)
{
LOGD("mbtk_route_config : write fail.");
}
close(fd);
}
}
return 0;
}
#endif
int ql_wan_start_ex(int profile_idx, int op, ex_conn_status_cb nw_cb)
{
int ret = -1;
int count = 0;
if(ql_info_handle == NULL)
{
return -1;
}
ql_net_ex_status_cb = nw_cb;
ql_net_status_cb = NULL;
now_cid = profile_idx;
if(profile_idx < MBTK_APN_CID_MIN || profile_idx > MBTK_APN_CID_MAX)
{
LOGD("ql_wan_start_ex() cid out of range.");
#if 0
if(ql_net_ex_status_cb)
ql_net_ex_status_cb(profile_idx, ql_apn_info[profile_idx].ip_type ,PDP_CID_EXIST_FAIL, 0);
#endif
return -1;
}
//ql_netw_status_cb(ql_apn_info[profile_idx].cid);
if(op == 0)
{
ret = ql_wan_stop(profile_idx);
goto exit;
}
#if 0
if(ql_apn_info[profile_idx].active)
{
if(ql_net_ex_status_cb)
ql_net_ex_status_cb(profile_idx, ql_apn_info[profile_idx].ip_type, PDP_CID_EXIST_FAIL, 0);
return -1;
}
#endif
if(ql_net_ex_status_cb) {
ql_net_ex_status_cb(profile_idx, ql_apn_info[profile_idx].ip_type, CONNECT_DIAL_IMMEDIATELY, 0);
ql_net_ex_status_cb(profile_idx, ql_apn_info[profile_idx].ip_type, CONNECT_CONNING, 0);
}
data_call_continue:
ret = mbtk_data_call_start(ql_info_handle, profile_idx, 0, op == 3 ? TRUE : FALSE, 0);
if(ret != 0)
{
if(mbtk_interval_sec <= 0)
{
if(ql_net_ex_status_cb)
ql_net_ex_status_cb(profile_idx, ql_apn_info[profile_idx].ip_type, CONNECT_DISCON, 0);
return ret;
}
else
{
if(count >= 5)
goto exit;
sleep(mbtk_interval_sec);
count++;
if(ql_net_ex_status_cb)
ql_net_ex_status_cb(profile_idx, ql_apn_info[profile_idx].ip_type, CONNECT_REDIAL, 0);
goto data_call_continue;
}
LOGD("mbtk_data_call_start() fail.");
}
else
{
//ql_apn_info[8].cid=profile_idx;
//ql_netw_status_cb(CONNECT_CONSUCCESS);
#ifdef MBTK_AF_SUPPORT
if(profile_idx == 1)
{
mbtk_route_config(profile_idx);
}
#endif
LOGD("mbtk_data_call_start() success.");
}
exit:
return ret;
}
/*
* Start data call.
*/
int ql_wan_start(int profile_idx, int op, nw_status_cb nw_cb)
{
int ret = -1;
int count = 0;
if(ql_info_handle == NULL)
{
return -1;
}
ql_net_status_cb = nw_cb;
ql_net_ex_status_cb = NULL;
if(profile_idx < MBTK_APN_CID_MIN || profile_idx > MBTK_APN_CID_MAX)
{
ql_net_status_cb(PDP_ERROR_UNSPECIFIED);
return -1;
}
//ql_netw_status_cb(ql_apn_info[profile_idx].cid);
if(op == 0)
{
ret = ql_wan_stop(profile_idx);
goto exit;
}
if(ql_apn_info[profile_idx].active)
{
ql_net_status_cb(PDP_CID_EXIST_FAIL);
return -1;
}
ql_net_status_cb(CONNECT_DIAL_IMMEDIATELY);
ql_net_status_cb(CONNECT_CONNING);
data_call_continue:
ret = mbtk_data_call_start(ql_info_handle, profile_idx, 0, op == 3 ? TRUE : FALSE, 0);
if(ret != 0)
{
if(mbtk_interval_sec <= 0)
{
ql_net_status_cb(CONNECT_DISCON);
return ret;
}
else
{
if(count >= 5)
goto exit;
sleep(mbtk_interval_sec);
count++;
ql_net_status_cb(CONNECT_REDIAL);
goto data_call_continue;
}
}
else
{
//ql_apn_info[8].cid=profile_idx;
//ql_netw_status_cb(CONNECT_CONSUCCESS);
LOGD("mbtk_data_call_start() success.");
}
exit:
return ret;
}
/*
* Stop data call.
*/
int ql_wan_stop(int profile_idx)
{
int err;
if(ql_info_handle == NULL)
{
return -1;
}
if(profile_idx < MBTK_APN_CID_MIN || profile_idx > MBTK_APN_CID_MAX)
{
LOGE("CID error.");
return -1;
}
#if 0 //mbtk wyq for data_call add "if 0"
if(!ql_apn_info[profile_idx].active)
{
if(ql_net_ex_status_cb)
ql_net_ex_status_cb(profile_idx, ql_apn_info[profile_idx].ip_type ,PDP_CID_EXIST_FAIL, 0);
if(ql_net_status_cb)
ql_net_status_cb(PDP_CID_EXIST_FAIL);
return -1;
}
#endif
err = mbtk_data_call_stop(ql_info_handle, profile_idx, 15);
return err;
}
/*
* Query data call state.
*/
int ql_get_data_call_info(int profile_idx, ql_data_call_info *info)
{
if(ql_info_handle == NULL || info == NULL)
{
return -1;
}
if(profile_idx < MBTK_APN_CID_MIN || profile_idx > MBTK_APN_CID_MAX)
{
LOGE("CID error.");
return -1;
}
mbtk_ipv4_info_t ipv4;
mbtk_ipv6_info_t ipv6;
memset(info, 0, sizeof(ql_data_call_info));
int ret = mbtk_data_call_state_get(ql_info_handle, profile_idx, &ipv4, &ipv6);
if(ret != 0)
return -1;
else
{
info->profile_idx = profile_idx;
if(ipv4.valid)
{
info->ip_type = 1; // IPV4
info->v4.state = 1;
sprintf(info->v4.addr.name, "ccinet%d", profile_idx - 1);
if(inet_ntop(AF_INET, &(ipv4.IPAddr), info->v4.addr.ip, 32) == NULL) {
LOGD("IP error.");
} else {
LOGD("IP : %s", info->v4.addr.ip);
}
if(inet_ntop(AF_INET, &(ipv4.PrimaryDNS), info->v4.addr.pri_dns, 32) == NULL) {
LOGD("PrimaryDNS error.");
} else {
LOGD("PrimaryDNS : %s", info->v4.addr.pri_dns);
}
if(inet_ntop(AF_INET, &(ipv4.SecondaryDNS), info->v4.addr.sec_dns, 32) == NULL) {
LOGD("SecondaryDNS error.");
} else {
LOGD("SecondaryDNS : %s", info->v4.addr.sec_dns);
}
}
if(ipv6.valid)
{
info->ip_type = 2; // IPV6
info->v6.state = 1;
sprintf(info->v6.addr.name, "ccinet%d", profile_idx - 1);
if(ipv6_2_str(&(ipv6.IPV6Addr), info->v6.addr.ip))
{
LOGD("IP error.");
} else {
LOGD("IP : %s", info->v6.addr.ip);
}
if(ipv6_2_str(&(ipv6.PrimaryDNS), info->v6.addr.pri_dns))
{
LOGD("PrimaryDNS error.");
} else {
LOGD("PrimaryDNS : %s", info->v6.addr.pri_dns);
}
if(ipv6_2_str(&(ipv6.SecondaryDNS), info->v6.addr.sec_dns))
{
LOGD("SecondaryDNS error.");
} else {
LOGD("SecondaryDNS : %s", info->v6.addr.sec_dns);
}
}
if(ipv4.valid && ipv6.valid)
info->ip_type = 0; // IPV4V6
if(!ipv4.valid && !ipv6.valid)
{
info->v4.state = 0;
info->v6.state = 0;
}
return 0;
}
}
/*
* Set specific APN informations.
*
* cid : 2-7
*/
int ql_wan_setapn(int profile_idx, int ip_type, const char *apn, const char *userName,
const char *password, QL_DSI_AUTH_PREF_T auth)
{
if(ql_info_handle == NULL)
{
return -1;
}
if(profile_idx < MBTK_APN_CID_MIN || profile_idx > MBTK_APN_CID_MAX)
{
LOGE("CID error.");
return -1;
}
/*
QL_DSI_AUTH_PREF_NULL = 0, //无认证
QL_DSI_AUTH_PREF_ONLY_PAP, //PAP 认证
QL_DSI_AUTH_PREF_ONLY_CHAP, //CHAP 认证
QL_DSI_AUTH_PREF_BOTH_PAP_CHAP //PAP 和 CHAP 认证
*/
char mbtk_auth[64]={0};
if(auth == QL_DSI_AUTH_PREF_NULL)
memcpy(mbtk_auth,"NONE",strlen("NONE")+1);
else if(auth == QL_DSI_AUTH_PREF_ONLY_PAP)
memcpy(mbtk_auth,"PAP",strlen("PAP")+1);
else if(auth == QL_DSI_AUTH_PREF_ONLY_CHAP)
memcpy(mbtk_auth,"CHAP",strlen("CHAP")+1);
else
{
LOGD("auth input error!");
return -1;
}
memset(&(ql_apn_info[profile_idx]), 0, sizeof(apn_info));
ql_apn_info[profile_idx].cid = profile_idx;
ql_apn_info[profile_idx].ip_type = ip_type;
if(!str_empty(userName) && !str_empty(password)) {
memcpy(ql_apn_info[profile_idx].user, userName, strlen(userName));
memcpy(ql_apn_info[profile_idx].pass, password, strlen(password));
ql_apn_info[profile_idx].auth = auth;
LOGD("ql_wan_setapn: %d, %d, %s, %s, %s, %s",profile_idx, ip_type, apn, userName, password, mbtk_auth);
} else {
LOGD("ql_wan_setapn: %d, %d, %s, NULL, NULL, %s",profile_idx, ip_type, apn, mbtk_auth);
}
/*
if(ip_type < 0 || ip_type > 3)
ql_netw_status_cb(PDP_UNKNOWN_PDP_ADDRESS_TYPE);
*/
if(ip_type == 0) // IPV4V6
ip_type = MBTK_IP_TYPE_IPV4V6;
else if(ip_type == 1) // IPV4
ip_type = MBTK_IP_TYPE_IP;
else if(ip_type == 2) // IPV6
ip_type = MBTK_IP_TYPE_IPV6;
return mbtk_apn_set(ql_info_handle, profile_idx, ip_type, apn, userName, password, mbtk_auth);
}
/*
* Get current all APN informations.
*/
int __ql_wan_getapn(int profile_idx, int *ip_type, char *apn, int apnLen, char *userName, int userLen, char *password, int pwdLen,int* auth)
{
if(ql_info_handle == NULL || apn == NULL)
{
return -1;
}
if(profile_idx < MBTK_APN_CID_MIN || profile_idx > MBTK_APN_CID_MAX)
{
LOGE("CID error.");
return -1;
}
mbtk_apn_info_t apns[10];
int apn_num = MBTK_APN_CID_MAX;
int ret = mbtk_apn_get(ql_info_handle, &apn_num, apns);
if(ret != 0)
{
LOGD("mbtk_apn_get ret = %d",ret);
return -1;
}
else
{
int i;
for(i=0;i<MBTK_APN_CID_MAX;i++)
{
if(apns[i].cid == profile_idx)
break;
}
if(i == MBTK_APN_CID_MAX)
return -1;
LOGD("cid = %d",i);
if(apns[i].ip_type == MBTK_IP_TYPE_IPV4V6) // IPV4V6
*ip_type = 0;
else if(apns[i].ip_type == MBTK_IP_TYPE_IP) // IPV4
*ip_type = 1;
else if(apns[i].ip_type == MBTK_IP_TYPE_IPV6) // IPV6
*ip_type = 2;
else
*ip_type = 0;
if(strlen(apns[i].apn)+1 > apnLen)
return -1;
else
memcpy(apn, apns[i].apn,strlen(apns[i].apn)+1);
if(strlen(apns[i].user)+1 > userLen)
return -1;
else
{
if(strlen(apns[i].user) > 0)
memcpy(userName, apns[i].user, strlen(apns[i].user)+1);
else
memcpy(userName, ql_apn_info[profile_idx].user, strlen(ql_apn_info[profile_idx].user)+1);
}
if(strlen(apns[i].pass)+1 > pwdLen)
return -1;
else
{
if(strlen(apns[i].pass) > 0)
memcpy(password, apns[i].pass, strlen(apns[i].pass)+1);
else
memcpy(password, ql_apn_info[profile_idx].pass, strlen(ql_apn_info[profile_idx].pass)+1);
}
if(strlen(apns[i].auth) > 0) {
if(strcmp(apns[i].auth, "NONE") == 0)
*auth = QL_DSI_AUTH_PREF_NULL;
else if(strcmp(apns[i].auth, "PAP") == 0)
*auth = QL_DSI_AUTH_PREF_ONLY_PAP;
else if(strcmp(apns[i].auth, "CHAP") == 0)
*auth = QL_DSI_AUTH_PREF_ONLY_CHAP;
else
{
LOGD("auth error!");
return -1;
}
} else {
*auth = ql_apn_info[profile_idx].auth;
}
return 0;
}
}