| #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; |
| } |
| } |
| |
| |