481 lines
11 KiB
C
481 lines
11 KiB
C
#include "system/includes.h"
|
||
|
||
#include <string.h>
|
||
|
||
#include "app_log.h"
|
||
#include "wifi/wifi_connect.h"
|
||
|
||
#include "wifi_sta.h"
|
||
#include "wifi_manager.h"
|
||
|
||
|
||
static struct wifi_manager_status wifi_manager_status_data;
|
||
|
||
/*
|
||
* 第一次启动 Wi-Fi 前保存的目标凭据。
|
||
*
|
||
* 当前只保存在 RAM。
|
||
*/
|
||
static char wifi_manager_target_ssid[33];
|
||
static char wifi_manager_target_password[64];
|
||
static u8 wifi_manager_target_valid;
|
||
|
||
|
||
/*
|
||
* 在 WIFI_EVENT_MODULE_INIT 阶段配置启动 STA。
|
||
*
|
||
* 当前诊断阶段与已经验证可联网的官方 demo_wifi 保持一致:
|
||
*
|
||
* force = 0:
|
||
* 使用 SDK 最后记忆的模式启动。
|
||
*
|
||
* store = 1:
|
||
* STA 模式下保存本次默认 SSID / password。
|
||
*/
|
||
static int wifi_manager_set_startup_sta_mode(void)
|
||
{
|
||
struct wifi_store_info parm;
|
||
int index;
|
||
|
||
if (!wifi_manager_target_valid) {
|
||
return -1;
|
||
}
|
||
|
||
memset(
|
||
&parm,
|
||
0,
|
||
sizeof(parm)
|
||
);
|
||
|
||
parm.mode = STA_MODE;
|
||
parm.connect_best_network = 0;
|
||
|
||
index = parm.mode - STA_MODE;
|
||
|
||
strncpy(
|
||
(char *)parm.ssid[index],
|
||
wifi_manager_target_ssid,
|
||
sizeof(parm.ssid[index]) - 1
|
||
);
|
||
|
||
strncpy(
|
||
(char *)parm.pwd[index],
|
||
wifi_manager_target_password,
|
||
sizeof(parm.pwd[index]) - 1
|
||
);
|
||
|
||
return wifi_set_default_mode(
|
||
&parm,
|
||
0, /* force: 与当前官方 demo 测试路径一致 */
|
||
1 /* store: STA 默认配置写入 SDK 存储 */
|
||
);
|
||
}
|
||
|
||
|
||
/*
|
||
* AC79NN SDK Wi-Fi 事件回调。
|
||
*
|
||
* SDK 事件来到这里后直接处理,
|
||
* 不经过额外 wifi_event 转发层。
|
||
*/
|
||
static int wifi_manager_sdk_event_callback(
|
||
void *network_ctx,
|
||
enum WIFI_EVENT event
|
||
)
|
||
{
|
||
int ret;
|
||
int mode_ret;
|
||
|
||
(void)network_ctx;
|
||
|
||
switch (event) {
|
||
|
||
case WIFI_EVENT_MODULE_INIT:
|
||
wifi_manager_status_data.module_initialized = 1;
|
||
|
||
/*
|
||
* STA 的通用参数配置。
|
||
*/
|
||
ret = wifi_sta_configure();
|
||
|
||
/*
|
||
* Wi-Fi 启动时的默认 STA 配置必须在
|
||
* WIFI_EVENT_MODULE_INIT 阶段完成。
|
||
*/
|
||
mode_ret = wifi_manager_set_startup_sta_mode();
|
||
|
||
APP_LOG(
|
||
"[WIFI_MANAGER] module init "
|
||
"sta_configure_ret=%d startup_mode_ret=%d\n",
|
||
ret,
|
||
mode_ret
|
||
);
|
||
break;
|
||
|
||
case WIFI_EVENT_MODULE_START:
|
||
{
|
||
/*
|
||
* 与已经验证可联网的官方 demo_wifi 保持一致:
|
||
* 开启 CCK / OFDM / HT MCS0~MCS7 全部发送速率。
|
||
*
|
||
* BIT(0) ~ BIT(19) 全部置位:
|
||
* mask = 0x000FFFFF
|
||
*/
|
||
u32 tx_rate_control_tab =
|
||
0
|
||
| BIT(0) /* CCK 1M */
|
||
| BIT(1) /* CCK 2M */
|
||
| BIT(2) /* CCK 5.5M */
|
||
| BIT(3) /* OFDM 6M */
|
||
| BIT(4) /* MCS0 / 7.2M */
|
||
| BIT(5) /* OFDM 9M */
|
||
| BIT(6) /* CCK 11M */
|
||
| BIT(7) /* OFDM 12M */
|
||
| BIT(8) /* MCS1 / 14.4M */
|
||
| BIT(9) /* OFDM 18M */
|
||
| BIT(10) /* MCS2 / 21.7M */
|
||
| BIT(11) /* OFDM 24M */
|
||
| BIT(12) /* MCS3 / 28.9M */
|
||
| BIT(13) /* OFDM 36M */
|
||
| BIT(14) /* MCS4 / 43.3M */
|
||
| BIT(15) /* OFDM 48M */
|
||
| BIT(16) /* OFDM 54M */
|
||
| BIT(17) /* MCS5 / 57.8M */
|
||
| BIT(18) /* MCS6 / 65.0M */
|
||
| BIT(19); /* MCS7 / 72.2M */
|
||
|
||
wifi_set_tx_rate_control_tab(
|
||
tx_rate_control_tab
|
||
);
|
||
|
||
wifi_manager_status_data.module_started = 1;
|
||
|
||
APP_LOG(
|
||
"[WIFI_MANAGER] module started "
|
||
"tx_rate_mask=0x%08x\n",
|
||
(unsigned int)tx_rate_control_tab
|
||
);
|
||
break;
|
||
}
|
||
|
||
case WIFI_EVENT_MODULE_STOP:
|
||
wifi_manager_status_data.module_initialized = 0;
|
||
wifi_manager_status_data.module_started = 0;
|
||
wifi_manager_status_data.sta_started = 0;
|
||
wifi_manager_status_data.connecting = 0;
|
||
wifi_manager_status_data.sta_associated = 0;
|
||
wifi_manager_status_data.network_ready = 0;
|
||
|
||
APP_LOG("[WIFI_MANAGER] module stopped\n");
|
||
break;
|
||
|
||
case WIFI_EVENT_MODULE_START_ERR:
|
||
wifi_manager_status_data.module_started = 0;
|
||
wifi_manager_status_data.sta_started = 0;
|
||
wifi_manager_status_data.connecting = 0;
|
||
wifi_manager_status_data.sta_associated = 0;
|
||
wifi_manager_status_data.network_ready = 0;
|
||
|
||
APP_LOG("[WIFI_MANAGER] module start failed\n");
|
||
break;
|
||
|
||
case WIFI_EVENT_STA_START:
|
||
wifi_manager_status_data.sta_started = 1;
|
||
|
||
APP_LOG("[WIFI_MANAGER] sta started\n");
|
||
break;
|
||
|
||
case WIFI_EVENT_STA_STOP:
|
||
wifi_manager_status_data.sta_started = 0;
|
||
wifi_manager_status_data.connecting = 0;
|
||
wifi_manager_status_data.sta_associated = 0;
|
||
wifi_manager_status_data.network_ready = 0;
|
||
|
||
APP_LOG("[WIFI_MANAGER] sta stopped\n");
|
||
break;
|
||
|
||
/*
|
||
* 只表示 802.11 关联成功。
|
||
* DHCP 还没有完成,因此不能认为网络已经可用。
|
||
*/
|
||
case WIFI_EVENT_STA_CONNECT_SUCC:
|
||
wifi_manager_status_data.sta_associated = 1;
|
||
wifi_manager_status_data.network_ready = 0;
|
||
|
||
APP_LOG(
|
||
"[WIFI_MANAGER] sta associated, waiting dhcp\n"
|
||
);
|
||
break;
|
||
|
||
case WIFI_EVENT_STA_DISCONNECT:
|
||
wifi_manager_status_data.connecting = 0;
|
||
wifi_manager_status_data.sta_associated = 0;
|
||
wifi_manager_status_data.network_ready = 0;
|
||
|
||
APP_LOG("[WIFI_MANAGER] sta disconnected\n");
|
||
break;
|
||
|
||
case WIFI_EVENT_STA_CONNECT_TIMEOUT_NOT_FOUND_SSID:
|
||
wifi_manager_status_data.connecting = 0;
|
||
wifi_manager_status_data.sta_associated = 0;
|
||
wifi_manager_status_data.network_ready = 0;
|
||
|
||
APP_LOG("[WIFI_MANAGER] ssid not found\n");
|
||
break;
|
||
|
||
case WIFI_EVENT_STA_CONNECT_ASSOCIAT_FAIL:
|
||
wifi_manager_status_data.connecting = 0;
|
||
wifi_manager_status_data.sta_associated = 0;
|
||
wifi_manager_status_data.network_ready = 0;
|
||
|
||
APP_LOG("[WIFI_MANAGER] association failed\n");
|
||
break;
|
||
|
||
case WIFI_EVENT_STA_CONNECT_ASSOCIAT_TIMEOUT:
|
||
wifi_manager_status_data.connecting = 0;
|
||
wifi_manager_status_data.sta_associated = 0;
|
||
wifi_manager_status_data.network_ready = 0;
|
||
|
||
APP_LOG("[WIFI_MANAGER] association timeout\n");
|
||
break;
|
||
|
||
/*
|
||
* DHCP 成功后,才认为 IPv4 网络真正可用。
|
||
*/
|
||
case WIFI_EVENT_STA_NETWORK_STACK_DHCP_SUCC:
|
||
wifi_manager_status_data.connecting = 0;
|
||
wifi_manager_status_data.sta_associated = 1;
|
||
wifi_manager_status_data.network_ready = 1;
|
||
|
||
APP_LOG(
|
||
"[WIFI_MANAGER] network ready rssi=%d\n",
|
||
(int)wifi_get_rssi()
|
||
);
|
||
break;
|
||
|
||
/*
|
||
* DHCP 超时不等价于 802.11 已断开。
|
||
*/
|
||
case WIFI_EVENT_STA_NETWORK_STACK_DHCP_TIMEOUT:
|
||
wifi_manager_status_data.connecting = 0;
|
||
wifi_manager_status_data.network_ready = 0;
|
||
|
||
APP_LOG("[WIFI_MANAGER] dhcp timeout\n");
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
int wifi_manager_init(void)
|
||
{
|
||
if (wifi_manager_status_data.initialized) {
|
||
return 0;
|
||
}
|
||
|
||
/*
|
||
* manager 必须在 Wi-Fi 启动前取得 SDK callback 所有权,
|
||
* 否则 MODULE_INIT / MODULE_START 等早期事件会丢失。
|
||
*/
|
||
if (wifi_is_on()) {
|
||
APP_LOG(
|
||
"[WIFI_MANAGER] init failed: wifi already on\n"
|
||
);
|
||
return -1;
|
||
}
|
||
|
||
memset(
|
||
&wifi_manager_status_data,
|
||
0,
|
||
sizeof(wifi_manager_status_data)
|
||
);
|
||
|
||
memset(
|
||
wifi_manager_target_ssid,
|
||
0,
|
||
sizeof(wifi_manager_target_ssid)
|
||
);
|
||
|
||
memset(
|
||
wifi_manager_target_password,
|
||
0,
|
||
sizeof(wifi_manager_target_password)
|
||
);
|
||
|
||
wifi_manager_target_valid = 0;
|
||
|
||
/*
|
||
* 与 AC79NN 官方 demo_wifi 的启动顺序保持一致:
|
||
* 在注册 callback / wifi_on() 之前先设置 STA 可保存的 SSID 数量。
|
||
*/
|
||
wifi_set_store_ssid_cnt(5);
|
||
|
||
wifi_set_event_callback(
|
||
wifi_manager_sdk_event_callback
|
||
);
|
||
|
||
/*
|
||
* 这里只初始化 manager,不立即 wifi_on()。
|
||
*
|
||
* 等 wifi_manager_connect() 先拿到目标凭据后再启动 Wi-Fi,
|
||
* 这样 MODULE_INIT 才能取得本次目标 STA 信息。
|
||
*/
|
||
wifi_manager_status_data.initialized = 1;
|
||
|
||
APP_LOG("[WIFI_MANAGER] init success\n");
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
int wifi_manager_connect(
|
||
const char *ssid,
|
||
const char *password
|
||
)
|
||
{
|
||
size_t ssid_len;
|
||
size_t password_len;
|
||
int ret;
|
||
|
||
if (!wifi_manager_status_data.initialized) {
|
||
return -1;
|
||
}
|
||
|
||
if (!ssid || !password) {
|
||
return -2;
|
||
}
|
||
|
||
ssid_len = strlen(ssid);
|
||
password_len = strlen(password);
|
||
|
||
if (ssid_len == 0 || ssid_len > 32) {
|
||
APP_LOG(
|
||
"[WIFI_MANAGER] connect failed: invalid ssid len=%u\n",
|
||
(unsigned int)ssid_len
|
||
);
|
||
return -3;
|
||
}
|
||
|
||
if (password_len > 63) {
|
||
APP_LOG(
|
||
"[WIFI_MANAGER] connect failed: invalid password len=%u\n",
|
||
(unsigned int)password_len
|
||
);
|
||
return -4;
|
||
}
|
||
|
||
memset(
|
||
wifi_manager_target_ssid,
|
||
0,
|
||
sizeof(wifi_manager_target_ssid)
|
||
);
|
||
|
||
memset(
|
||
wifi_manager_target_password,
|
||
0,
|
||
sizeof(wifi_manager_target_password)
|
||
);
|
||
|
||
memcpy(
|
||
wifi_manager_target_ssid,
|
||
ssid,
|
||
ssid_len
|
||
);
|
||
|
||
memcpy(
|
||
wifi_manager_target_password,
|
||
password,
|
||
password_len
|
||
);
|
||
|
||
wifi_manager_target_valid = 1;
|
||
|
||
wifi_manager_status_data.connecting = 1;
|
||
wifi_manager_status_data.sta_associated = 0;
|
||
wifi_manager_status_data.network_ready = 0;
|
||
|
||
/*
|
||
* 第一次连接:
|
||
* 先保存目标凭据,再启动 Wi-Fi。
|
||
*
|
||
* wifi_on() 过程中会产生 MODULE_INIT,
|
||
* callback 在该阶段完成默认 STA 配置。
|
||
*/
|
||
if (!wifi_is_on()) {
|
||
ret = wifi_on();
|
||
|
||
if (ret != 0) {
|
||
wifi_manager_status_data.connecting = 0;
|
||
|
||
APP_LOG(
|
||
"[WIFI_MANAGER] wifi_on failed ret=%d\n",
|
||
ret
|
||
);
|
||
|
||
return ret;
|
||
}
|
||
|
||
APP_LOG(
|
||
"[WIFI_MANAGER] wifi start/connect submitted ssid=%s\n",
|
||
wifi_manager_target_ssid
|
||
);
|
||
|
||
return 0;
|
||
}
|
||
|
||
/*
|
||
* Wi-Fi 已经启动后的运行期连接/切换仍使用 wifi_sta。
|
||
*/
|
||
ret = wifi_sta_connect(
|
||
wifi_manager_target_ssid,
|
||
wifi_manager_target_password
|
||
);
|
||
|
||
if (ret != 0) {
|
||
wifi_manager_status_data.connecting = 0;
|
||
|
||
APP_LOG(
|
||
"[WIFI_MANAGER] runtime connect request failed ret=%d\n",
|
||
ret
|
||
);
|
||
|
||
return ret;
|
||
}
|
||
|
||
APP_LOG(
|
||
"[WIFI_MANAGER] runtime connect request submitted ssid=%s\n",
|
||
wifi_manager_target_ssid
|
||
);
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
int wifi_manager_get_status(
|
||
struct wifi_manager_status *out
|
||
)
|
||
{
|
||
if (!out) {
|
||
return -1;
|
||
}
|
||
|
||
*out = wifi_manager_status_data;
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
int wifi_manager_is_sta_associated(void)
|
||
{
|
||
return wifi_manager_status_data.sta_associated ? 1 : 0;
|
||
}
|
||
|
||
|
||
int wifi_manager_is_network_ready(void)
|
||
{
|
||
return wifi_manager_status_data.network_ready ? 1 : 0;
|
||
} |