/*
* Copyright (c) 2020 Nanjing Xiaoxiongpai Intelligent Technology Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "lwip/netif.h"
#include "lwip/netifapi.h"
#include "lwip/ip4_addr.h"
#include "lwip/api_shell.h"
#include "cmsis_os2.h"
#include "hos_types.h"
#include "wifi_device.h"
#include "wifiiot_errno.h"
#include "ohos_init.h"
#include "wifi_connect.h"
#define DEF_TIMEOUT 15
#define ONE_SECOND 1
#define SELECT_WIFI_SECURITYTYPE WIFI_SEC_TYPE_PSK
static void WiFiInit(void);
static void WaitSacnResult(void);
static int WaitConnectResult(void);
static void OnWifiScanStateChangedHandler(int state, int size);
static void OnWifiConnectionChangedHandler(int state, WifiLinkedInfo *info);
static void OnHotspotStaJoinHandler(StationInfo *info);
static void OnHotspotStateChangedHandler(int state);
static void OnHotspotStaLeaveHandler(StationInfo *info);
// findMyTargetSSID == 1,SSID匹配成功
static int findMyTargetSSID = 0;
// 递归查询匹配SSID次数,超过10次,终止
static int repeatFindMyTargetSSIDCount = 0;
// g_staScanSuccess == 1,扫描成功
static int g_staScanSuccess = 0;
// g_ConnectSuccess == 1,连接成功
static int g_ConnectSuccess = 0;
// ssid 数量
static int ssid_count = 0;
WifiEvent g_wifiEventHandler = {0};
WifiErrorCode error;
#define SELECT_WLAN_PORT "wlan0"
int WifiConnect(wifi_profile_connect_t *wifi_profile)
{
// 进来直接先拷贝要连接的热点信息,下面只需要保证扫描到无线网络就行了
WifiDeviceConfig select_ap_config = {0};
strcpy(select_ap_config.ssid, wifi_profile->wifi_ssid);
strcpy(select_ap_config.preSharedKey, wifi_profile->wifi_passwd);
select_ap_config.securityType = SELECT_WIFI_SECURITYTYPE;
WifiScanInfo *info = NULL;
static struct netif *g_lwip_netif = NULL;
unsigned int size = WIFI_SCAN_HOTSPOT_LIMIT;
osDelay(200);
printf("<--System Init-->\r\n");
// 初始化WIFI
WiFiInit();
// 使能WIFI
if (EnableWifi() != WIFI_SUCCESS)
{
printf("EnableWifi failed, error = %d\r\n", error);
return -1;
}
// 判断WIFI是否激活
if (IsWifiActive() == 0)
{
printf("Wifi station is not actived.\r\n");
return -1;
}
// 分配空间,保存WiFi信息
info = malloc(sizeof(WifiScanInfo) * WIFI_SCAN_HOTSPOT_LIMIT);
if (info == NULL)
{
return -1;
}
// do{
// //重置标志位
// ssid_count = 0;
// g_staScanSuccess = 0;
// //开始扫描
// Scan();
// //等待扫描结果
// WaitSacnResult();
// //获取扫描列表
// error = GetScanInfoList(info, &size);
// }while(g_staScanSuccess != 1);
// //打印WiFi列表
// printf("********************\r\n");
// for(uint8_t i = 0; i < ssid_count; i++)
// {
// printf("no:%03d, ssid:%-30s, rssi:%5d\r\n", i+1, info[i].ssid, info[i].rssi/100);
// }
// printf("********************\r\n");
// //连接指定的WiFi热点
// for(uint8_t i = 0; i < ssid_count; i++)
// {
// printf(">>>>>>马上进行匹配:%s",select_ap_config.ssid);
// if (strcmp(select_ap_config.ssid, info[i].ssid) == 0)
// {
// int result;
// printf(">>>>>匹配到的ssid:%s\r\n",info[i].ssid);
// printf("Select:%3d wireless, Waiting...\r\n", i+1);
// // 拷贝要连接的热点信息,直接传ssid和psk进来,到这里就丢失了
// // WifiDeviceConfig select_ap_config = {0};
// // strcpy(select_ap_config.ssid, info[i].ssid);
// // strcpy(select_ap_config.preSharedKey, wifi_profile->wifi_passwd);
// select_ap_config.securityType = SELECT_WIFI_SECURITYTYPE;
// if (AddDeviceConfig(&select_ap_config, &result) == WIFI_SUCCESS)
// {
// if (ConnectTo(result) == WIFI_SUCCESS && WaitConnectResult() == 1)
// {
// printf("WiFi connect succeed!\r\n");
// g_lwip_netif = netifapi_netif_find(SELECT_WLAN_PORT);
// break;
// }
// }
// }
// if(i == ssid_count-1)
// {
// printf("ERROR: No wifi as expected\r\n");
// while(1) osDelay(100);
// }
// }
for (;;)
{
if(NULL != g_lwip_netif || repeatFindMyTargetSSIDCount>=10) {
// 连接成功或者次数超过10次,跳出循环
break;
}
printf(">>>>>>第%d次循环<<<<<<<\r\n",(repeatFindMyTargetSSIDCount+1));
do
{
// 重置标志位
ssid_count = 0;
g_staScanSuccess = 0;
// 开始扫描
Scan();
// 等待扫描结果
WaitSacnResult();
// 获取扫描列表
error = GetScanInfoList(info, &size);
} while (g_staScanSuccess != 1);
// 打印WiFi列表
printf("********************\r\n");
for (uint8_t i = 0; i < ssid_count; i++)
{
printf("no:%03d, ssid:%-30s, rssi:%5d\r\n", i + 1, info[i].ssid, info[i].rssi / 100);
}
printf("********************\r\n");
// 连接指定的WiFi热点
for (uint8_t i = 0; i < ssid_count; i++)
{
if (strcmp(select_ap_config.ssid, info[i].ssid) == 0)
{
int result;
printf(">>>>>匹配到的ssid:%s\r\n", info[i].ssid);
printf("Select:%3d wireless, Waiting...\r\n", i + 1);
// 拷贝要连接的热点信息,直接传ssid和psk进来,到这里就丢失了
// WifiDeviceConfig select_ap_config = {0};
// strcpy(select_ap_config.ssid, info[i].ssid);
// strcpy(select_ap_config.preSharedKey, wifi_profile->wifi_passwd);
select_ap_config.securityType = SELECT_WIFI_SECURITYTYPE;
if (AddDeviceConfig(&select_ap_config, &result) == WIFI_SUCCESS)
{
if (ConnectTo(result) == WIFI_SUCCESS && WaitConnectResult() == 1)
{
printf("WiFi connect succeed!\r\n");
g_lwip_netif = netifapi_netif_find(SELECT_WLAN_PORT);
break;
}
}
}
if (i == ssid_count - 1)
{
printf("NotFound Avaliable Wifi SSID, Waiting 200ms Retry...\r\n");
repeatFindMyTargetSSIDCount += 1;
// 每次间隔200毫秒,扫描网络列表
osDelay(200);
}
}
}
if(repeatFindMyTargetSSIDCount >=10 && NULL == g_lwip_netif) {
printf("Retry connect wifi count >=10 ,Error:No wifi as expected.\r\n");
// 挂起
while (1) osDelay(100);
}
// 启动DHCP
if (g_lwip_netif)
{
dhcp_start(g_lwip_netif);
printf("begain to dhcp\r\n");
}
// 等待DHCP
for (;;)
{
if (dhcp_is_bound(g_lwip_netif) == ERR_OK)
{
printf("<-- DHCP state:OK -->\r\n");
// 打印获取到的IP信息
netifapi_netif_common(g_lwip_netif, dhcp_clients_info_show, NULL);
break;
}
printf("<-- DHCP