437 lines
13 KiB
C
437 lines
13 KiB
C
#include <stdint.h>
|
|
#include <stddef.h>
|
|
#include <stdbool.h>
|
|
#include <string.h>
|
|
|
|
#define TAG "model_wifi"
|
|
|
|
#include "lisa_ui_invoke.h"
|
|
#include "lisa_ui_log.h"
|
|
|
|
#include "model_wifi.h"
|
|
|
|
#ifdef LISA_UI_PLATFORM_ARCS
|
|
#include "wifi_manager/wifi_manager.h"
|
|
#include "voice_msg.h"
|
|
#endif
|
|
|
|
struct model_wifi_context {
|
|
uint32_t inited: 1;
|
|
uint32_t scanning: 1;
|
|
|
|
const struct model_wifi_cb *cbs;
|
|
void *arg;
|
|
|
|
model_wifi_status_t status;
|
|
model_wifi_scan_info_t scan_list[WIFI_MAX_SCAN_APS];
|
|
int scan_count;
|
|
};
|
|
|
|
static struct model_wifi_context model_wifi_ctx = {
|
|
.inited = 0,
|
|
.scanning = 0,
|
|
.status = MODEL_WIFI_STATUS_DISCONNECTED,
|
|
.scan_count = 0,
|
|
};
|
|
|
|
#ifdef LISA_UI_PLATFORM_ARCS
|
|
|
|
// WiFi Manager 到 Model 的加密模式转换
|
|
static model_wifi_encryption_mode_t convert_encryption_mode(wifi_mgr_wifi_encryption_mode_t mode)
|
|
{
|
|
switch (mode) {
|
|
case WIFI_MGR_WIFI_AUTH_AUTO:
|
|
return MODEL_WIFI_AUTH_AUTO;
|
|
case WIFI_MGR_WIFI_AUTH_OPEN:
|
|
return MODEL_WIFI_AUTH_OPEN;
|
|
case WIFI_MGR_WIFI_AUTH_WEP:
|
|
return MODEL_WIFI_AUTH_WEP;
|
|
case WIFI_MGR_WIFI_AUTH_WPA_PSK:
|
|
return MODEL_WIFI_AUTH_WPA_PSK;
|
|
case WIFI_MGR_WIFI_AUTH_WPA2_PSK:
|
|
return MODEL_WIFI_AUTH_WPA2_PSK;
|
|
case WIFI_MGR_WIFI_AUTH_WPA_WPA2_PSK:
|
|
return MODEL_WIFI_AUTH_WPA_WPA2_PSK;
|
|
case WIFI_MGR_WIFI_AUTH_WPA2_ENTERPRISE:
|
|
return MODEL_WIFI_AUTH_WPA2_ENTERPRISE;
|
|
case WIFI_MGR_WIFI_AUTH_WPA3_PSK:
|
|
return MODEL_WIFI_AUTH_WPA3_PSK;
|
|
case WIFI_MGR_WIFI_AUTH_WPA2_WPA3_PSK:
|
|
return MODEL_WIFI_AUTH_WPA2_WPA3_PSK;
|
|
default:
|
|
return MODEL_WIFI_AUTH_UNKNOWN;
|
|
}
|
|
}
|
|
|
|
// Model 到 WiFi Manager 的加密模式转换
|
|
static wifi_mgr_wifi_encryption_mode_t convert_to_wifi_mgr_encryption_mode(model_wifi_encryption_mode_t mode)
|
|
{
|
|
switch (mode) {
|
|
case MODEL_WIFI_AUTH_AUTO:
|
|
return WIFI_MGR_WIFI_AUTH_AUTO;
|
|
case MODEL_WIFI_AUTH_OPEN:
|
|
return WIFI_MGR_WIFI_AUTH_OPEN;
|
|
case MODEL_WIFI_AUTH_WEP:
|
|
return WIFI_MGR_WIFI_AUTH_WEP;
|
|
case MODEL_WIFI_AUTH_WPA_PSK:
|
|
return WIFI_MGR_WIFI_AUTH_WPA_PSK;
|
|
case MODEL_WIFI_AUTH_WPA2_PSK:
|
|
return WIFI_MGR_WIFI_AUTH_WPA2_PSK;
|
|
case MODEL_WIFI_AUTH_WPA_WPA2_PSK:
|
|
return WIFI_MGR_WIFI_AUTH_WPA_WPA2_PSK;
|
|
case MODEL_WIFI_AUTH_WPA2_ENTERPRISE:
|
|
return WIFI_MGR_WIFI_AUTH_WPA2_ENTERPRISE;
|
|
case MODEL_WIFI_AUTH_WPA3_PSK:
|
|
return WIFI_MGR_WIFI_AUTH_WPA3_PSK;
|
|
case MODEL_WIFI_AUTH_WPA2_WPA3_PSK:
|
|
return WIFI_MGR_WIFI_AUTH_WPA2_WPA3_PSK;
|
|
default:
|
|
return WIFI_MGR_WIFI_AUTH_UNKNOWN;
|
|
}
|
|
}
|
|
|
|
// WiFi Manager 到 Model 的状态转换
|
|
static model_wifi_status_t convert_wifi_status(wifi_mgr_connection_status_t status)
|
|
{
|
|
switch (status) {
|
|
case WIFI_MGR_STA_CONNECTED:
|
|
return MODEL_WIFI_STATUS_CONNECTED;
|
|
case WIFI_MGR_STA_CONNECTING:
|
|
return MODEL_WIFI_STATUS_CONNECTING;
|
|
case WIFI_MGR_STA_DISCONNECTED:
|
|
return MODEL_WIFI_STATUS_DISCONNECTED;
|
|
default:
|
|
return MODEL_WIFI_STATUS_UNKNOWN;
|
|
}
|
|
}
|
|
|
|
// WiFi 连接状态回调
|
|
static void wifi_connection_event_handler(wifi_mgr_connection_info_t *connection_info, void *arg)
|
|
{
|
|
if (!connection_info) {
|
|
return;
|
|
}
|
|
LISA_UI_LOGI("wifi connecting info, ssid: %s, reason: %d", connection_info->sta_info->ssid,
|
|
connection_info->reason);
|
|
wifi_mgr_connection_status_t status = connection_info->status;
|
|
int reason = connection_info->reason;
|
|
|
|
LISA_UI_INVOKE_UI_ARG_BASE(status, {
|
|
model_wifi_ctx.status = convert_wifi_status(_invoke_status);
|
|
|
|
if (model_wifi_ctx.cbs) {
|
|
switch (_invoke_status) {
|
|
case WIFI_MGR_STA_CONNECTED:
|
|
if (model_wifi_ctx.cbs->on_connected) {
|
|
model_wifi_sta_config_t sta_info;
|
|
if (model_wifi_get_connected_info(&sta_info) == 0) {
|
|
model_wifi_ctx.cbs->on_connected(&sta_info, model_wifi_ctx.arg);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WIFI_MGR_STA_CONNECTING:
|
|
if (model_wifi_ctx.cbs->on_connecting) {
|
|
model_wifi_ctx.cbs->on_connecting(model_wifi_ctx.arg);
|
|
}
|
|
break;
|
|
|
|
case WIFI_MGR_STA_DISCONNECTED:
|
|
if (model_wifi_ctx.cbs->on_disconnected) {
|
|
model_wifi_ctx.cbs->on_disconnected(0, model_wifi_ctx.arg);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// WiFi 扫描完成回调
|
|
static void wifi_scan_done_handler(wifi_mgr_scan_info_t *aps_info, int ap_num, void *arg)
|
|
{
|
|
if (ap_num > 0 && aps_info) {
|
|
// 计算需要拷贝的AP数量
|
|
int copy_count = ap_num > WIFI_MAX_SCAN_APS ? WIFI_MAX_SCAN_APS : ap_num;
|
|
uint32_t data_len = sizeof(wifi_mgr_scan_info_t) * copy_count;
|
|
|
|
LISA_UI_INVOKE_UI_ARG_PTR(aps_info, data_len, {
|
|
wifi_mgr_scan_info_t *scan_result = (wifi_mgr_scan_info_t *)_invoke_aps_info;
|
|
int count = _invoke_len / sizeof(wifi_mgr_scan_info_t);
|
|
|
|
model_wifi_ctx.scanning = 0;
|
|
model_wifi_ctx.scan_count = count;
|
|
|
|
// 转换扫描结果到 model 层数据结构
|
|
for (int i = 0; i < count; i++) {
|
|
strncpy(model_wifi_ctx.scan_list[i].ssid, scan_result[i].ssid, WIFI_SSID_MAX_LEN - 1);
|
|
model_wifi_ctx.scan_list[i].ssid[WIFI_SSID_MAX_LEN - 1] = '\0';
|
|
|
|
strncpy(model_wifi_ctx.scan_list[i].bssid, scan_result[i].bssid, WIFI_BSSID_MAX_LEN - 1);
|
|
model_wifi_ctx.scan_list[i].bssid[WIFI_BSSID_MAX_LEN - 1] = '\0';
|
|
|
|
model_wifi_ctx.scan_list[i].channel = scan_result[i].channel;
|
|
model_wifi_ctx.scan_list[i].rssi = scan_result[i].rssi;
|
|
model_wifi_ctx.scan_list[i].encryption_mode = convert_encryption_mode(scan_result[i].encryption_mode);
|
|
}
|
|
|
|
if (model_wifi_ctx.cbs && model_wifi_ctx.cbs->on_scan_done) {
|
|
model_wifi_ctx.cbs->on_scan_done(model_wifi_ctx.scan_list, count, model_wifi_ctx.arg);
|
|
}
|
|
});
|
|
} else {
|
|
// 扫描失败
|
|
int num = ap_num;
|
|
LISA_UI_INVOKE_UI_ARG_BASE(num, {
|
|
model_wifi_ctx.scanning = 0;
|
|
model_wifi_ctx.scan_count = 0;
|
|
|
|
if (model_wifi_ctx.cbs && model_wifi_ctx.cbs->on_scan_failed) {
|
|
model_wifi_ctx.cbs->on_scan_failed(_invoke_num, model_wifi_ctx.arg);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
static void wifi_disconnected_msg_handle(void *unused, uint32_t msg_id, void *data, uint32_t len, void *user_data)
|
|
{
|
|
LISA_UI_INVOKE_UI_ARG_NONE({
|
|
model_wifi_ctx.status = MODEL_WIFI_STATUS_DISCONNECTED;
|
|
});
|
|
}
|
|
|
|
static void wifi_ip_got_msg_handle(void *unused, uint32_t msg_id, void *data, uint32_t len, void *user_data)
|
|
{
|
|
LISA_UI_INVOKE_UI_ARG_NONE({
|
|
model_wifi_ctx.status = MODEL_WIFI_STATUS_CONNECTED;
|
|
});
|
|
}
|
|
|
|
#endif // LISA_UI_PLATFORM_ARCS
|
|
|
|
int model_wifi_init(void)
|
|
{
|
|
if (model_wifi_ctx.inited) {
|
|
return 0;
|
|
}
|
|
|
|
#ifdef LISA_UI_PLATFORM_ARCS
|
|
int ret;
|
|
|
|
ret = wifi_mgr_sta_add_connection_cb(wifi_connection_event_handler, NULL);
|
|
if (ret != 0) {
|
|
LISA_UI_LOGE("Failed to add connection callback: %d", ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = wifi_mgr_add_scan_done_cb(wifi_scan_done_handler, NULL);
|
|
if (ret != 0) {
|
|
LISA_UI_LOGE("Failed to add scan done callback: %d", ret);
|
|
wifi_mgr_sta_remove_connection_cb(wifi_connection_event_handler);
|
|
return ret;
|
|
}
|
|
|
|
wifi_mgr_connection_status_t status = wifi_mgr_sta_get_status();
|
|
model_wifi_ctx.status = convert_wifi_status(status);
|
|
|
|
LISA_UI_LOGD("WiFi model initialized, status: %d", model_wifi_ctx.status);
|
|
|
|
voice_msg_sub(VOICE_MSG_WIFI_DISCONNECTED, wifi_disconnected_msg_handle, NULL);
|
|
voice_msg_sub(VOICE_MSG_WIFI_IP_GOT, wifi_ip_got_msg_handle, NULL);
|
|
#endif
|
|
|
|
model_wifi_ctx.inited = 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int model_wifi_deinit(void)
|
|
{
|
|
if (!model_wifi_ctx.inited) {
|
|
return 0;
|
|
}
|
|
|
|
#ifdef LISA_UI_PLATFORM_ARCS
|
|
wifi_mgr_sta_remove_connection_cb(wifi_connection_event_handler);
|
|
wifi_mgr_remove_scan_done_cb(wifi_scan_done_handler);
|
|
voice_msg_unsub(VOICE_MSG_WIFI_DISCONNECTED, wifi_disconnected_msg_handle);
|
|
#endif
|
|
|
|
model_wifi_ctx.inited = 0;
|
|
model_wifi_ctx.cbs = NULL;
|
|
model_wifi_ctx.arg = NULL;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int model_wifi_cb_register(const struct model_wifi_cb *cb, void *arg)
|
|
{
|
|
model_wifi_ctx.cbs = cb;
|
|
model_wifi_ctx.arg = arg;
|
|
return 0;
|
|
}
|
|
|
|
int model_wifi_cb_unregister(const struct model_wifi_cb *cb)
|
|
{
|
|
model_wifi_ctx.cbs = NULL;
|
|
model_wifi_ctx.arg = NULL;
|
|
return 0;
|
|
}
|
|
|
|
int model_wifi_scan_start(void)
|
|
{
|
|
if (!model_wifi_ctx.inited) {
|
|
LISA_UI_LOGE("WiFi model not initialized");
|
|
return -1;
|
|
}
|
|
|
|
// if (model_wifi_ctx.scanning) {
|
|
// LISA_UI_LOGW("WiFi scan already in progress");
|
|
// return -2;
|
|
// }
|
|
|
|
#ifdef LISA_UI_PLATFORM_ARCS
|
|
model_wifi_ctx.scanning = 1;
|
|
|
|
LISA_UI_INVOKE_BN_ARG_NONE({
|
|
wifi_mgr_scan_info_t ap_info[WIFI_MAX_SCAN_APS];
|
|
int ret = wifi_mgr_scan_ap(ap_info, WIFI_MAX_SCAN_APS, false);
|
|
|
|
// 扫描结果会通过回调返回
|
|
if (ret < 0) {
|
|
LISA_UI_LOGE("WiFi scan failed: %d", ret);
|
|
}
|
|
});
|
|
#else
|
|
LISA_UI_LOGW("WiFi scan not supported on this platform");
|
|
return -3;
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
model_wifi_status_t model_wifi_get_status(void)
|
|
{
|
|
return model_wifi_ctx.status;
|
|
}
|
|
|
|
int model_wifi_connect(const char *ssid, const char *pwd, const char *bssid)
|
|
{
|
|
if (!model_wifi_ctx.inited) {
|
|
LISA_UI_LOGE("WiFi model not initialized");
|
|
return -1;
|
|
}
|
|
|
|
if (!ssid) {
|
|
LISA_UI_LOGE("SSID cannot be NULL");
|
|
return -2;
|
|
}
|
|
|
|
#ifdef LISA_UI_PLATFORM_ARCS
|
|
wifi_mgr_sta_config_t sta_config;
|
|
memset(&sta_config, 0, sizeof(sta_config));
|
|
|
|
strncpy(sta_config.ssid, ssid, sizeof(sta_config.ssid) - 1);
|
|
sta_config.ssid[sizeof(sta_config.ssid) - 1] = '\0';
|
|
|
|
if (pwd) {
|
|
strncpy(sta_config.pwd, pwd, sizeof(sta_config.pwd) - 1);
|
|
sta_config.pwd[sizeof(sta_config.pwd) - 1] = '\0';
|
|
}
|
|
|
|
if (bssid) {
|
|
strncpy(sta_config.bssid, bssid, sizeof(sta_config.bssid) - 1);
|
|
sta_config.bssid[sizeof(sta_config.bssid) - 1] = '\0';
|
|
}
|
|
|
|
sta_config.encryption_mode = WIFI_MGR_WIFI_AUTH_AUTO;
|
|
|
|
wifi_mgr_sta_config_t *config = &sta_config;
|
|
LISA_UI_INVOKE_BN_ARG_PTR(config, sizeof(sta_config), {
|
|
wifi_mgr_sta_config_t *cfg = (wifi_mgr_sta_config_t *)_invoke_config;
|
|
int ret = wifi_mgr_sta_connect(cfg, false);
|
|
|
|
if (ret != 0) {
|
|
LISA_UI_INVOKE_UI_ARG_NONE({
|
|
if (model_wifi_ctx.cbs && model_wifi_ctx.cbs->on_connection_failed) {
|
|
model_wifi_ctx.cbs->on_connection_failed(-1, model_wifi_ctx.arg);
|
|
}
|
|
});
|
|
}
|
|
});
|
|
#else
|
|
LISA_UI_LOGW("WiFi connect not supported on this platform");
|
|
return -3;
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
int model_wifi_disconnect(void)
|
|
{
|
|
if (!model_wifi_ctx.inited) {
|
|
LISA_UI_LOGE("WiFi model not initialized");
|
|
return -1;
|
|
}
|
|
|
|
#ifdef LISA_UI_PLATFORM_ARCS
|
|
LISA_UI_INVOKE_BN_ARG_NONE({
|
|
int ret = wifi_mgr_sta_disconnect(false);
|
|
if (ret != 0) {
|
|
LISA_UI_LOGE("WiFi disconnect failed: %d", ret);
|
|
} else {
|
|
LISA_UI_LOGD("WiFi disconnected");
|
|
}
|
|
});
|
|
#else
|
|
LISA_UI_LOGW("WiFi disconnect not supported on this platform");
|
|
return -2;
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
int model_wifi_get_connected_info(model_wifi_sta_config_t *sta_info)
|
|
{
|
|
if (!model_wifi_ctx.inited) {
|
|
LISA_UI_LOGE("WiFi model not initialized");
|
|
return -1;
|
|
}
|
|
|
|
if (!sta_info) {
|
|
LISA_UI_LOGE("sta_info cannot be NULL");
|
|
return -2;
|
|
}
|
|
|
|
#ifdef LISA_UI_PLATFORM_ARCS
|
|
wifi_mgr_sta_config_t wifi_sta_info;
|
|
int ret = wifi_mgr_sta_get_connected_info(&wifi_sta_info);
|
|
|
|
if (ret != 0) {
|
|
LISA_UI_LOGE("Failed to get WiFi connected info: %d", ret);
|
|
return ret;
|
|
}
|
|
|
|
// 转换数据结构
|
|
strncpy(sta_info->ssid, wifi_sta_info.ssid, WIFI_SSID_MAX_LEN - 1);
|
|
sta_info->ssid[WIFI_SSID_MAX_LEN - 1] = '\0';
|
|
|
|
strncpy(sta_info->bssid, wifi_sta_info.bssid, WIFI_BSSID_MAX_LEN - 1);
|
|
sta_info->bssid[WIFI_BSSID_MAX_LEN - 1] = '\0';
|
|
|
|
strncpy(sta_info->pwd, wifi_sta_info.pwd, WIFI_PWD_MAX_LEN - 1);
|
|
sta_info->pwd[WIFI_PWD_MAX_LEN - 1] = '\0';
|
|
|
|
sta_info->channel = wifi_sta_info.channel;
|
|
sta_info->rssi = wifi_sta_info.rssi;
|
|
sta_info->encryption_mode = convert_encryption_mode(wifi_sta_info.encryption_mode);
|
|
|
|
return 0;
|
|
#else
|
|
LISA_UI_LOGW("Get WiFi connected info not supported on this platform");
|
|
return -3;
|
|
#endif
|
|
}
|