添加 USB 主机、BLE 和 Socket 数据端口驱动程序:
- 支持大容量存储类(MSC)的 USB 主机驱动程序 - BLE SPP(串行端口配置文件)客户端和服务器实现 - Socket(UDP/TCP)数据端口驱动程序 - 相关的 shell 接口用于配置和测试
This commit is contained in:
15
app/drivers/data_port/socket_inet/socket_inet.c
Normal file
15
app/drivers/data_port/socket_inet/socket_inet.c
Normal file
@@ -0,0 +1,15 @@
|
||||
#include "socket_inet.h"
|
||||
|
||||
/**
|
||||
* @brief 初始化数据接口。
|
||||
* 这将一同初始化 ESP32 的 WIFI
|
||||
*
|
||||
* @return 0
|
||||
*/
|
||||
int socket_inet_init(void)
|
||||
{
|
||||
extern void socket_inet_server_init(void);
|
||||
socket_inet_server_init();
|
||||
|
||||
return 0;
|
||||
}
|
||||
41
app/drivers/data_port/socket_inet/socket_inet.h
Normal file
41
app/drivers/data_port/socket_inet/socket_inet.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* @file socket_inet.h
|
||||
* @author LokLiang
|
||||
* @brief 主要把 sockets 标准接口封装为 sb_data_port.h::sb_data_port_t 接口
|
||||
* @version 0.1
|
||||
* @date 2023-11-10
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include "drivers/data_port/sb_data_port.h"
|
||||
#include "os/os.h"
|
||||
|
||||
typedef void *socket_listen_t;
|
||||
typedef socket_listen_t socket_listen_tcp_t;
|
||||
|
||||
typedef void (*connect_cb)(bool is_connect, sb_data_port_t *port);
|
||||
typedef void (*rx_event_cb)(sb_data_port_t *port);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t rx_buf_size; // 为该接口提供多大的接收缓存(建议取值 256..512,更多依赖协议栈的缓存)
|
||||
rx_event_cb rx_event; // 当该接口收到数据时执行的回调函数,可取值为 NULL
|
||||
os_work_t *rx_resume_work; // 当该接口收到数据时唤醒的工作项,可取值为 NULL
|
||||
} socket_server_bind_t;
|
||||
|
||||
int socket_inet_init(void);
|
||||
|
||||
sb_data_port_t *socket_inet_server_bind_udp(uint16_t listen_port, const socket_server_bind_t *bind_param);
|
||||
void socket_inet_server_unbind_udp(sb_data_port_t *port);
|
||||
|
||||
int socket_inet_server_udp_read_addr(sb_data_port_t *port, in_addr_t *s_addr, in_port_t *sin_port);
|
||||
int socket_inet_server_udp_broadcast(sb_data_port_t *port, uint8_t ip_v4[4], uint16_t broadcast_port, const void *data, uint32_t size);
|
||||
|
||||
socket_listen_tcp_t socket_inet_server_listen_tcp(uint16_t listen_port, uint8_t tcp_backlog, const connect_cb connect);
|
||||
sb_data_port_t *socket_inet_server_bind_tcp(socket_listen_tcp_t listen_tcp, const socket_server_bind_t *bind_param);
|
||||
void socket_inet_server_unbind_tcp(socket_listen_tcp_t listen_tcp);
|
||||
1503
app/drivers/data_port/socket_inet/socket_inet_server.c
Normal file
1503
app/drivers/data_port/socket_inet/socket_inet_server.c
Normal file
File diff suppressed because it is too large
Load Diff
265
app/drivers/data_port/socket_inet/socket_inet_server_shell.c
Normal file
265
app/drivers/data_port/socket_inet/socket_inet_server_shell.c
Normal file
@@ -0,0 +1,265 @@
|
||||
/**
|
||||
* @file socket_inet_server_shell.c
|
||||
* @author LokLiang
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2023-11-28
|
||||
*
|
||||
* @copyright Copyright (c) 2024
|
||||
*
|
||||
* 用于测试 socket 数据接口。
|
||||
* 注意事项:
|
||||
* 需要配合 wifi_shell 模块使用。
|
||||
* 操作:
|
||||
* 通过命令行,输入 inet open 打开连接,输入 wifi oa 或 wifi os 选择 wifi 模式;
|
||||
* 在 wifi_shell.c::wifi_shell_register() 部分包含了连接信息,可根据这些信息连接或修改必要参数;
|
||||
* 无线连接成功后,可通过工具测试发送和接收的速度等。
|
||||
*/
|
||||
|
||||
#include "socket_inet_server_shell.h"
|
||||
#include "socket_inet.h"
|
||||
#include "shell/sh.h"
|
||||
|
||||
#include <string.h>
|
||||
#include "os/os.h"
|
||||
|
||||
#include "drivers/data_port/sb_data_port.h"
|
||||
|
||||
#define CONFIG_SYS_LOG_LEVEL SYS_LOG_LEVEL_INF
|
||||
#define SYS_LOG_DOMAIN "SH"
|
||||
#include "sys_log.h"
|
||||
|
||||
static void _server_tcp_connect_cb(bool is_connect, sb_data_port_t *port);
|
||||
static void _bind_and_open_tcp(uint8_t hdl_id);
|
||||
static void _bind_and_open_udp(uint8_t hdl_id, uint16_t listen_port);
|
||||
static void _unbind_and_close(uint8_t hdl_id);
|
||||
static void _work_speed_handler(void *arg);
|
||||
static void _work_read_handler(void *arg);
|
||||
|
||||
static struct
|
||||
{
|
||||
socket_listen_tcp_t tcp_listen;
|
||||
|
||||
struct
|
||||
{
|
||||
sb_data_port_t *data_port;
|
||||
os_work_t work_hdl;
|
||||
int stype; // 0: udp, 1: tcp
|
||||
} hdl[4];
|
||||
|
||||
os_work_t s_speed_work_hdl;
|
||||
int recv_size;
|
||||
int err_size;
|
||||
int s_recv_total_tcp;
|
||||
int recv_total;
|
||||
} s_cm;
|
||||
|
||||
SH_CMD_FN(_open);
|
||||
SH_CMD_FN(_close);
|
||||
|
||||
SH_DEF_SUB_CMD(
|
||||
sub_wifi,
|
||||
SH_SETUP_CMD("open", "打开接口", _open, NULL), //
|
||||
SH_SETUP_CMD("close", "关闭接口", _close, NULL), //
|
||||
);
|
||||
|
||||
SH_DEF_CMD(
|
||||
_register_tcp_wifi,
|
||||
SH_SETUP_CMD("inet", "操作 WIFI 数据接口", NULL, sub_wifi), //
|
||||
);
|
||||
|
||||
void socket_server_shell_register(void)
|
||||
{
|
||||
sh_register_cmd(&_register_tcp_wifi);
|
||||
|
||||
socket_inet_init();
|
||||
|
||||
os_work_create(&s_cm.s_speed_work_hdl, "work-speed", _work_speed_handler, NULL, OS_PRIORITY_LOWEST);
|
||||
os_work_submit(default_os_work_q_hdl, &s_cm.s_speed_work_hdl, 0);
|
||||
|
||||
s_cm.tcp_listen = socket_inet_server_listen_tcp(4278, 2, _server_tcp_connect_cb);
|
||||
}
|
||||
|
||||
void socket_server_shell_unregister(void)
|
||||
{
|
||||
sh_unregister_cmd(&_register_tcp_wifi);
|
||||
}
|
||||
|
||||
static void _server_tcp_connect_cb(bool is_connect, sb_data_port_t *port)
|
||||
{
|
||||
SYS_LOG_INF("%s", is_connect ? "connected" : "disconnected");
|
||||
if (is_connect)
|
||||
{
|
||||
os_thread_sleep(10);
|
||||
sb_data_port_write(port, "hello\r\n", 7, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void _bind_and_open_tcp(uint8_t hdl_id)
|
||||
{
|
||||
SYS_ASSERT(hdl_id < __ARRAY_SIZE(s_cm.hdl), "");
|
||||
|
||||
if (s_cm.hdl[hdl_id].data_port == NULL)
|
||||
{
|
||||
socket_server_bind_t bind_param = {
|
||||
.rx_buf_size = 0x1000,
|
||||
.rx_event = NULL,
|
||||
.rx_resume_work = &s_cm.hdl[hdl_id].work_hdl,
|
||||
};
|
||||
s_cm.hdl[hdl_id].data_port = socket_inet_server_bind_tcp(s_cm.tcp_listen, &bind_param);
|
||||
s_cm.hdl[hdl_id].stype = 1;
|
||||
}
|
||||
|
||||
if (s_cm.hdl[hdl_id].data_port)
|
||||
{
|
||||
sb_data_port_start(s_cm.hdl[hdl_id].data_port);
|
||||
|
||||
os_work_create(&s_cm.hdl[hdl_id].work_hdl, "work-read", _work_read_handler, s_cm.hdl[hdl_id].data_port, OS_PRIORITY_LOWEST);
|
||||
os_work_submit(default_os_work_q_hdl, &s_cm.hdl[hdl_id].work_hdl, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void _bind_and_open_udp(uint8_t hdl_id, uint16_t listen_port)
|
||||
{
|
||||
SYS_ASSERT(hdl_id < __ARRAY_SIZE(s_cm.hdl), "");
|
||||
|
||||
if (s_cm.hdl[hdl_id].data_port)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
socket_server_bind_t bind_param = {
|
||||
.rx_buf_size = 0x1000,
|
||||
.rx_event = NULL,
|
||||
.rx_resume_work = &s_cm.hdl[hdl_id].work_hdl,
|
||||
};
|
||||
s_cm.hdl[hdl_id].data_port = socket_inet_server_bind_udp(listen_port, &bind_param);
|
||||
s_cm.hdl[hdl_id].stype = 0;
|
||||
|
||||
if (s_cm.hdl[hdl_id].data_port)
|
||||
{
|
||||
sb_data_port_start(s_cm.hdl[hdl_id].data_port);
|
||||
|
||||
os_work_create(&s_cm.hdl[hdl_id].work_hdl, "work-read", _work_read_handler, s_cm.hdl[hdl_id].data_port, OS_PRIORITY_LOWEST);
|
||||
os_work_submit(default_os_work_q_hdl, &s_cm.hdl[hdl_id].work_hdl, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void _unbind_and_close(uint8_t hdl_id)
|
||||
{
|
||||
SYS_ASSERT(hdl_id < __ARRAY_SIZE(s_cm.hdl), "");
|
||||
|
||||
if (os_work_is_valid(&s_cm.hdl[hdl_id].work_hdl))
|
||||
os_work_delete(&s_cm.hdl[hdl_id].work_hdl);
|
||||
|
||||
if (s_cm.hdl[hdl_id].data_port)
|
||||
{
|
||||
if (s_cm.hdl[hdl_id].stype == 0)
|
||||
{
|
||||
socket_inet_server_unbind_udp(s_cm.hdl[hdl_id].data_port);
|
||||
s_cm.hdl[hdl_id].data_port = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
sb_data_port_stop(s_cm.hdl[hdl_id].data_port);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void _work_speed_handler(void *arg)
|
||||
{
|
||||
static os_time_t last_time;
|
||||
os_time_t curr_time = os_get_sys_time();
|
||||
int time_cost = curr_time - last_time;
|
||||
bool recv_flag = false;
|
||||
|
||||
os_work_later(1000);
|
||||
|
||||
time_cost += !time_cost;
|
||||
|
||||
for (int i = 0; i < __ARRAY_SIZE(s_cm.hdl); i++)
|
||||
{
|
||||
sb_data_port_t *port = s_cm.hdl[i].data_port;
|
||||
if (port && sb_data_port_is_started(port))
|
||||
{
|
||||
if (s_cm.recv_size)
|
||||
{
|
||||
int result = s_cm.recv_size * 1000 / time_cost;
|
||||
s_cm.recv_total += s_cm.recv_size;
|
||||
s_cm.recv_size = 0;
|
||||
SYS_LOG_INF("val trans speed: %2u.%02u KiB/S, recv total: %d bytes", result / 0x400, result % 0x400 * 100 / 0x400, s_cm.recv_total);
|
||||
if (s_cm.err_size)
|
||||
{
|
||||
SYS_LOG_DBG("err total: %d times", s_cm.err_size);
|
||||
s_cm.err_size = 0;
|
||||
}
|
||||
recv_flag = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (recv_flag == false)
|
||||
{
|
||||
s_cm.recv_total = 0;
|
||||
}
|
||||
|
||||
last_time = curr_time;
|
||||
}
|
||||
|
||||
static void _work_read_handler(void *arg)
|
||||
{
|
||||
sb_data_port_t *port = arg;
|
||||
static uint8_t val_log = '0';
|
||||
|
||||
while (sb_data_port_is_started(port))
|
||||
{
|
||||
uint8_t buf[1500];
|
||||
int r_size = sb_data_port_read(port, buf, sizeof(buf), 0);
|
||||
if (r_size <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
sb_data_port_write(port, buf, r_size, 0);
|
||||
|
||||
s_cm.recv_size += r_size;
|
||||
SYS_LOG_DUMP(buf, r_size, 0, 0);
|
||||
for (int i = 0; i < r_size; i++)
|
||||
{
|
||||
if (buf[i] != val_log)
|
||||
{
|
||||
s_cm.err_size++;
|
||||
val_log = buf[i];
|
||||
}
|
||||
val_log = '0' + (val_log - '0' + 1) % 10;
|
||||
}
|
||||
|
||||
os_work_later(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SH_CMD_FN(_open)
|
||||
{
|
||||
_bind_and_open_udp(0, 14550);
|
||||
_bind_and_open_udp(1, 14550 + 1);
|
||||
_bind_and_open_tcp(2);
|
||||
_bind_and_open_tcp(3);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SH_CMD_FN(_close)
|
||||
{
|
||||
_unbind_and_close(0);
|
||||
_unbind_and_close(1);
|
||||
_unbind_and_close(2);
|
||||
_unbind_and_close(3);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
soc base free
|
||||
wifi open
|
||||
wifi close
|
||||
*/
|
||||
@@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
void socket_server_shell_register(void);
|
||||
void socket_server_shell_unregister(void);
|
||||
405
app/drivers/data_port/socket_inet/wifi.c
Normal file
405
app/drivers/data_port/socket_inet/wifi.c
Normal file
@@ -0,0 +1,405 @@
|
||||
#include "wifi.h"
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "esp_mac.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_netif_types.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
#define CONFIG_SYS_LOG_LEVEL SYS_LOG_LEVEL_INF
|
||||
#define SYS_LOG_DOMAIN "WIFI"
|
||||
#include "sys_log.h"
|
||||
|
||||
static struct
|
||||
{
|
||||
uint8_t init;
|
||||
uint8_t curr_mode; // 0: 已关闭, 1: ap, 2: sta, 3: ap+sta
|
||||
wifi_netif_mode_t cfg_mode;
|
||||
wifi_init_t init_param;
|
||||
esp_netif_t *netif;
|
||||
uint8_t mac[6];
|
||||
union
|
||||
{
|
||||
wifi_ap_connect_status_t ap_status;
|
||||
wifi_sta_connect_status_t sta_status;
|
||||
};
|
||||
} s_cm;
|
||||
|
||||
static void _wifi_start_ap(void);
|
||||
static void _wifi_start_sta(void);
|
||||
static void _wiri_stop_ap(void);
|
||||
static void _wiri_stop_sta(void);
|
||||
static void _wifi_event_handler_ap(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data); // 由 _wifi_start_ap() 启动时设置的事件回调函数,处理 AP 模式下客户端的连接状态
|
||||
static void _wifi_event_handler_sta(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data); // 由 _wifi_start_sta() 启动时设置的事件回调函数,处理 STA 模式下的连接状态
|
||||
|
||||
/**
|
||||
* @brief 初始化设置。可重复设置
|
||||
*
|
||||
* @param init_struct
|
||||
*/
|
||||
void wifi_netif_init(wifi_init_t *init_struct)
|
||||
{
|
||||
if (s_cm.init == 0)
|
||||
{
|
||||
s_cm.init = 1;
|
||||
ESP_ERROR_CHECK(esp_netif_init());
|
||||
}
|
||||
s_cm.init_param = *init_struct;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置 WIFI 模式。在下次执行 wifi_start() 时根据此模式启动 WIFI
|
||||
*
|
||||
* @param mode @ref wifi_netif_mode_t
|
||||
*/
|
||||
void wifi_set_mode(wifi_netif_mode_t mode)
|
||||
{
|
||||
s_cm.cfg_mode = mode;
|
||||
}
|
||||
|
||||
void wifi_start(void)
|
||||
{
|
||||
switch (s_cm.cfg_mode)
|
||||
{
|
||||
case WIFI_NETIF_MODE_AP:
|
||||
_wifi_start_ap();
|
||||
break;
|
||||
|
||||
case WIFI_NETIF_MODE_STA:
|
||||
default:
|
||||
_wifi_start_sta();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 关闭 WIFI
|
||||
*
|
||||
*/
|
||||
void wifi_stop(void)
|
||||
{
|
||||
if (s_cm.curr_mode == 0)
|
||||
{
|
||||
SYS_LOG_WRN("wifi has been stoped");
|
||||
return;
|
||||
}
|
||||
|
||||
if (s_cm.curr_mode == 1)
|
||||
{
|
||||
_wiri_stop_ap();
|
||||
}
|
||||
else if (s_cm.curr_mode == 2)
|
||||
{
|
||||
_wiri_stop_sta();
|
||||
}
|
||||
|
||||
s_cm.curr_mode = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief (仅在 AP 模式下)获取已连接的工作站信息
|
||||
*
|
||||
* @param netif_sta_list
|
||||
* @return int
|
||||
*/
|
||||
int wifi_get_sta_list(wifi_sta_mac_ip_list_t *netif_sta_list)
|
||||
{
|
||||
wifi_sta_list_t sta_list;
|
||||
memset(&sta_list, 0, sizeof(sta_list));
|
||||
memset(netif_sta_list, 0, sizeof(wifi_sta_mac_ip_list_t));
|
||||
esp_err_t err = esp_wifi_ap_get_sta_list(&sta_list);
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
return esp_wifi_ap_get_sta_list_with_ip(&sta_list, netif_sta_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief (仅在 AP 模式下)获取已连接的 AP 信息
|
||||
*
|
||||
* @param netif_ap[out]
|
||||
* @return int
|
||||
*/
|
||||
int wifi_get_ap_info(esp_netif_ip_info_t *netif_ap)
|
||||
{
|
||||
if (s_cm.curr_mode == 2)
|
||||
{
|
||||
return esp_netif_get_ip_info(s_cm.netif, netif_ap);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 初始化 WIFI 协议栈,启动 WIFI 的 AP 模式,启动 DHCP 服务
|
||||
*
|
||||
*/
|
||||
static void _wifi_start_ap(void)
|
||||
{
|
||||
if (s_cm.curr_mode == 1)
|
||||
{
|
||||
SYS_LOG_WRN("wifi has been started");
|
||||
return;
|
||||
}
|
||||
|
||||
if (s_cm.curr_mode)
|
||||
{
|
||||
wifi_stop();
|
||||
}
|
||||
|
||||
s_cm.curr_mode = 1;
|
||||
|
||||
// Initialize networking stack
|
||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||
|
||||
// start the DHCP server
|
||||
if (s_cm.netif == NULL)
|
||||
{
|
||||
s_cm.netif = esp_netif_create_default_wifi_ap();
|
||||
assert(s_cm.netif);
|
||||
// stop DHCP server
|
||||
ESP_ERROR_CHECK(esp_netif_dhcps_stop(s_cm.netif));
|
||||
// assign a static IP to the network interface
|
||||
esp_netif_ip_info_t info;
|
||||
memset(&info, 0, sizeof(info));
|
||||
IP4_ADDR(&info.ip, s_cm.init_param.ap.ip_v4[0], s_cm.init_param.ap.ip_v4[1], s_cm.init_param.ap.ip_v4[2], s_cm.init_param.ap.ip_v4[3]);
|
||||
IP4_ADDR(&info.gw, s_cm.init_param.ap.gw_v4[0], s_cm.init_param.ap.gw_v4[1], s_cm.init_param.ap.gw_v4[2], s_cm.init_param.ap.gw_v4[3]); // ESP acts as router, so gw addr will be its own addr
|
||||
IP4_ADDR(&info.netmask, s_cm.init_param.ap.mask_v4[0], s_cm.init_param.ap.mask_v4[1], s_cm.init_param.ap.mask_v4[2], s_cm.init_param.ap.mask_v4[3]);
|
||||
ESP_ERROR_CHECK(esp_netif_set_ip_info(s_cm.netif, &info));
|
||||
ESP_ERROR_CHECK(esp_netif_dhcps_start(s_cm.netif));
|
||||
}
|
||||
|
||||
/* Initialise ESP32 in SoftAP curr_mode */
|
||||
const char *ssid = s_cm.init_param.ap.ssid;
|
||||
const char *password = s_cm.init_param.ap.password;
|
||||
wifi_config_t wifi_config;
|
||||
memset(&wifi_config, 0, sizeof(wifi_config_t));
|
||||
memcpy(wifi_config.ap.ssid, ssid, strlen(ssid));
|
||||
wifi_config.ap.ssid_len = strlen(ssid);
|
||||
wifi_config.ap.max_connection = s_cm.init_param.ap.max_connection;
|
||||
if (strlen(password) == 0)
|
||||
{
|
||||
wifi_config.ap.authmode = WIFI_AUTH_OPEN;
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy((char *)wifi_config.ap.password, password);
|
||||
wifi_config.ap.authmode = WIFI_AUTH_WPA_WPA2_PSK;
|
||||
}
|
||||
|
||||
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, _wifi_event_handler_ap, NULL));
|
||||
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
|
||||
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_AP, &wifi_config));
|
||||
ESP_ERROR_CHECK(esp_wifi_start());
|
||||
|
||||
wifi_ap_connect_cb connect_cb = s_cm.init_param.ap.connect_cb;
|
||||
if (connect_cb)
|
||||
{
|
||||
s_cm.ap_status = WIFI_AP_CONNECT_GOT_STA;
|
||||
connect_cb(s_cm.ap_status, 0);
|
||||
}
|
||||
|
||||
SYS_LOG_INF("done");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 初始化 WIFI 协议栈,启动 WIFI 的 STA 模式
|
||||
*
|
||||
*/
|
||||
static void _wifi_start_sta(void)
|
||||
{
|
||||
if (s_cm.curr_mode == 2)
|
||||
{
|
||||
SYS_LOG_WRN("wifi has been started");
|
||||
return;
|
||||
}
|
||||
|
||||
if (s_cm.curr_mode)
|
||||
{
|
||||
wifi_stop();
|
||||
}
|
||||
|
||||
s_cm.curr_mode = 2;
|
||||
|
||||
/* 参考自 examples/wifi/fast_scan/main/fast_scan.c */
|
||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||
|
||||
// Initialize default station as network interface instance (esp-netif)
|
||||
if (s_cm.netif == NULL)
|
||||
{
|
||||
s_cm.netif = esp_netif_create_default_wifi_sta();
|
||||
assert(s_cm.netif);
|
||||
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &_wifi_event_handler_sta, s_cm.netif, NULL));
|
||||
ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &_wifi_event_handler_sta, s_cm.netif, NULL));
|
||||
}
|
||||
|
||||
// Initialize and start WiFi
|
||||
const char *ssid = s_cm.init_param.sta.ssid;
|
||||
const char *password = s_cm.init_param.sta.password;
|
||||
wifi_config_t wifi_config;
|
||||
memset(&wifi_config, 0, sizeof(wifi_config_t));
|
||||
strncpy((char *)wifi_config.sta.ssid, ssid, sizeof(wifi_config.sta.ssid));
|
||||
strncpy((char *)wifi_config.sta.password, password, sizeof(wifi_config.sta.password));
|
||||
wifi_config.sta.scan_method = WIFI_FAST_SCAN;
|
||||
wifi_config.sta.sort_method = WIFI_CONNECT_AP_BY_SIGNAL;
|
||||
wifi_config.sta.threshold.rssi = -127;
|
||||
wifi_config.sta.threshold.authmode = WIFI_AUTH_OPEN;
|
||||
|
||||
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
|
||||
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
|
||||
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
|
||||
ESP_ERROR_CHECK(esp_wifi_start());
|
||||
|
||||
wifi_sta_connect_cb connect_cb = s_cm.init_param.sta.connect_cb;
|
||||
if (connect_cb)
|
||||
{
|
||||
uint8_t ip_v4[4];
|
||||
memset(ip_v4, 0, sizeof(ip_v4));
|
||||
s_cm.sta_status = WIFI_STA_CONNECT_CONNECTING;
|
||||
connect_cb(s_cm.sta_status, ip_v4);
|
||||
}
|
||||
|
||||
SYS_LOG_INF("done");
|
||||
}
|
||||
|
||||
static void _wiri_stop_ap(void)
|
||||
{
|
||||
/* Deinitialise ESP32 netif */
|
||||
ESP_ERROR_CHECK(esp_wifi_stop());
|
||||
if (s_cm.netif)
|
||||
{
|
||||
esp_netif_dhcp_status_t status;
|
||||
ESP_ERROR_CHECK(esp_netif_dhcps_get_status(s_cm.netif, &status));
|
||||
if (ESP_NETIF_DHCP_STARTED == status)
|
||||
{
|
||||
ESP_ERROR_CHECK(esp_netif_dhcps_stop(s_cm.netif));
|
||||
}
|
||||
esp_netif_destroy_default_wifi(s_cm.netif);
|
||||
s_cm.netif = NULL;
|
||||
}
|
||||
ESP_ERROR_CHECK(esp_wifi_deinit());
|
||||
|
||||
// Deinitialize networking stack
|
||||
ESP_ERROR_CHECK(esp_event_loop_delete_default());
|
||||
|
||||
wifi_ap_connect_cb connect_cb = s_cm.init_param.ap.connect_cb;
|
||||
if (connect_cb)
|
||||
{
|
||||
s_cm.ap_status = WIFI_AP_CONNECT_STOPED;
|
||||
connect_cb(s_cm.ap_status, 0);
|
||||
}
|
||||
|
||||
SYS_LOG_INF("done");
|
||||
|
||||
s_cm.curr_mode = 0;
|
||||
}
|
||||
|
||||
static void _wiri_stop_sta(void)
|
||||
{
|
||||
/* Deinitialise ESP32 netif */
|
||||
ESP_ERROR_CHECK(esp_wifi_stop());
|
||||
if (s_cm.netif)
|
||||
{
|
||||
esp_netif_destroy_default_wifi(s_cm.netif);
|
||||
s_cm.netif = NULL;
|
||||
}
|
||||
ESP_ERROR_CHECK(esp_wifi_deinit());
|
||||
|
||||
// Deinitialize networking stack
|
||||
ESP_ERROR_CHECK(esp_event_loop_delete_default());
|
||||
|
||||
wifi_sta_connect_cb connect_cb = s_cm.init_param.sta.connect_cb;
|
||||
if (connect_cb)
|
||||
{
|
||||
uint8_t ip_v4[4];
|
||||
memset(ip_v4, 0, sizeof(ip_v4));
|
||||
s_cm.sta_status = WIFI_STA_CONNECT_STOPED;
|
||||
connect_cb(s_cm.sta_status, ip_v4);
|
||||
}
|
||||
|
||||
SYS_LOG_INF("done");
|
||||
|
||||
s_cm.curr_mode = 0;
|
||||
}
|
||||
|
||||
static void _wifi_event_handler_ap(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
|
||||
{
|
||||
switch (event_id)
|
||||
{
|
||||
case WIFI_EVENT_AP_STACONNECTED:
|
||||
{
|
||||
wifi_event_ap_staconnected_t *event = (wifi_event_ap_staconnected_t *)event_data;
|
||||
SYS_LOG_INF("station " MACSTR " join, AID=%d",
|
||||
MAC2STR(event->mac), event->aid);
|
||||
memcpy(s_cm.mac, event->mac, 6);
|
||||
break;
|
||||
}
|
||||
|
||||
case WIFI_EVENT_AP_STADISCONNECTED:
|
||||
{
|
||||
wifi_event_ap_stadisconnected_t *event = (wifi_event_ap_stadisconnected_t *)event_data;
|
||||
SYS_LOG_INF("station " MACSTR " leave, AID=%d",
|
||||
MAC2STR(event->mac), event->aid);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
wifi_ap_connect_cb connect_cb = s_cm.init_param.ap.connect_cb;
|
||||
if (connect_cb)
|
||||
{
|
||||
wifi_sta_mac_ip_list_t netif_sta_list;
|
||||
wifi_get_sta_list(&netif_sta_list);
|
||||
s_cm.ap_status = WIFI_AP_CONNECT_GOT_STA;
|
||||
connect_cb(s_cm.ap_status, netif_sta_list.num);
|
||||
}
|
||||
}
|
||||
|
||||
void get_wifi_mac(uint8_t *mac)
|
||||
{
|
||||
memcpy(mac, s_cm.mac, 6);
|
||||
}
|
||||
|
||||
static void _wifi_event_handler_sta(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
|
||||
{
|
||||
wifi_sta_connect_status_t status;
|
||||
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START)
|
||||
{
|
||||
status = WIFI_STA_CONNECT_CONNECTING;
|
||||
esp_wifi_connect();
|
||||
}
|
||||
else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED)
|
||||
{
|
||||
status = WIFI_STA_CONNECT_CONNECTING;
|
||||
esp_wifi_connect();
|
||||
}
|
||||
else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP)
|
||||
{
|
||||
status = WIFI_STA_CONNECT_GOT_IP;
|
||||
ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
|
||||
SYS_LOG_INF("got ip: " IPSTR, IP2STR(&event->ip_info.ip));
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
wifi_sta_connect_cb connect_cb = s_cm.init_param.sta.connect_cb;
|
||||
if (connect_cb)
|
||||
{
|
||||
uint8_t ip_v4[4];
|
||||
memset(ip_v4, 0, sizeof(ip_v4));
|
||||
if (s_cm.sta_status != status)
|
||||
{
|
||||
s_cm.sta_status = status;
|
||||
connect_cb(s_cm.sta_status, ip_v4);
|
||||
}
|
||||
}
|
||||
}
|
||||
78
app/drivers/data_port/socket_inet/wifi.h
Normal file
78
app/drivers/data_port/socket_inet/wifi.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* @file wifi.h
|
||||
* @author LokLiang
|
||||
* @brief 操作 ESP32 WIFI 的两种基本模式的开关
|
||||
* @version 0.1
|
||||
* @date 2023-11-24
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "esp_wifi_ap_get_sta_list.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
WIFI_AP_CONNECT_STOPED,
|
||||
WIFI_AP_CONNECT_GOT_STA,
|
||||
} wifi_ap_connect_status_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
WIFI_STA_CONNECT_STOPED,
|
||||
WIFI_STA_CONNECT_CONNECTING,
|
||||
WIFI_STA_CONNECT_GOT_IP,
|
||||
} wifi_sta_connect_status_t;
|
||||
|
||||
/**
|
||||
* @brief AP 模式下的连接状态回调函数。
|
||||
* 提示:可使用 wifi_get_sta_list() 读出所有已连接的客户端信息
|
||||
*/
|
||||
typedef void (*wifi_ap_connect_cb)(wifi_ap_connect_status_t status, uint8_t connect_cnt);
|
||||
|
||||
/**
|
||||
* @brief STA 模式下的连接状态回调函数。
|
||||
*/
|
||||
typedef void (*wifi_sta_connect_cb)(wifi_sta_connect_status_t status, uint8_t ip_v4[4]);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
char ssid[33]; /**< SSID of soft-AP. If ssid_len field is 0, this must be a Null terminated string. Otherwise, length is set according to ssid_len. */
|
||||
char password[65]; /**< Password of soft-AP. */
|
||||
uint8_t ip_v4[4];
|
||||
uint8_t gw_v4[4];
|
||||
uint8_t mask_v4[4];
|
||||
uint8_t max_connection; // 最大连接数
|
||||
wifi_ap_connect_cb connect_cb;
|
||||
} ap;
|
||||
struct
|
||||
{
|
||||
char ssid[33];
|
||||
char password[65];
|
||||
wifi_sta_connect_cb connect_cb;
|
||||
} sta;
|
||||
} wifi_init_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
WIFI_NETIF_MODE_AP,
|
||||
WIFI_NETIF_MODE_STA,
|
||||
} wifi_netif_mode_t;
|
||||
|
||||
void wifi_netif_init(wifi_init_t *init_struct);
|
||||
|
||||
void wifi_set_mode(wifi_netif_mode_t mode);
|
||||
|
||||
void wifi_start(void);
|
||||
void wifi_stop(void);
|
||||
|
||||
int wifi_get_sta_list(wifi_sta_mac_ip_list_t *netif_sta_list);
|
||||
|
||||
int wifi_get_ap_info(esp_netif_ip_info_t *netif_ap);
|
||||
|
||||
void get_wifi_mac(uint8_t *mac);
|
||||
82
app/drivers/data_port/socket_inet/wifi_shell.c
Normal file
82
app/drivers/data_port/socket_inet/wifi_shell.c
Normal file
@@ -0,0 +1,82 @@
|
||||
#include "wifi_shell.h"
|
||||
#include "wifi.h"
|
||||
#include "shell/sh.h"
|
||||
|
||||
#include <string.h>
|
||||
#include "os/os.h"
|
||||
|
||||
#define CONFIG_SYS_LOG_LEVEL SYS_LOG_LEVEL_INF
|
||||
#define SYS_LOG_DOMAIN "SH"
|
||||
#include "sys_log.h"
|
||||
|
||||
SH_CMD_FN(_open_ap);
|
||||
SH_CMD_FN(_open_sta);
|
||||
SH_CMD_FN(_close);
|
||||
|
||||
SH_DEF_SUB_CMD(
|
||||
sub_wifi,
|
||||
SH_SETUP_CMD("oa", "打开 wifi ap 模式", _open_ap, NULL), //
|
||||
SH_SETUP_CMD("os", "打开 wifi sta 模式", _open_sta, NULL), //
|
||||
SH_SETUP_CMD("close", "关闭 wifi", _close, NULL), //
|
||||
);
|
||||
|
||||
SH_DEF_CMD(
|
||||
_register_tcp_wifi,
|
||||
SH_SETUP_CMD("wifi", "操作 WIFI 接口", NULL, sub_wifi), //
|
||||
);
|
||||
|
||||
void wifi_shell_register(void)
|
||||
{
|
||||
sh_register_cmd(&_register_tcp_wifi);
|
||||
|
||||
/* 初始化 WIFI */
|
||||
wifi_init_t init_struct = {
|
||||
.ap = {
|
||||
.ssid = "wifi-test", /**< SSID of soft-AP. If ssid_len field is 0, this must be a Null terminated string. Otherwise, length is set according to ssid_len. */
|
||||
.password = "12345678", /**< Password of soft-AP. */
|
||||
.ip_v4 = {192, 168, 1, 1},
|
||||
.gw_v4 = {192, 168, 1, 1},
|
||||
.mask_v4 = {255, 255, 255, 0},
|
||||
.max_connection = 1,
|
||||
.connect_cb = NULL,
|
||||
},
|
||||
.sta = {
|
||||
#if 0
|
||||
.ssid = "KFXJ",
|
||||
.password = "Kfdx201*",
|
||||
#else
|
||||
.ssid = "SDWAN",
|
||||
.password = "Dxltkj201",
|
||||
#endif
|
||||
.connect_cb = NULL,
|
||||
},
|
||||
};
|
||||
wifi_netif_init(&init_struct);
|
||||
|
||||
wifi_set_mode(WIFI_NETIF_MODE_STA);
|
||||
}
|
||||
|
||||
void wifi_shell_unregister(void)
|
||||
{
|
||||
sh_unregister_cmd(&_register_tcp_wifi);
|
||||
}
|
||||
|
||||
SH_CMD_FN(_open_ap)
|
||||
{
|
||||
wifi_set_mode(WIFI_NETIF_MODE_AP);
|
||||
wifi_start();
|
||||
return 0;
|
||||
}
|
||||
|
||||
SH_CMD_FN(_open_sta)
|
||||
{
|
||||
wifi_set_mode(WIFI_NETIF_MODE_STA);
|
||||
wifi_start();
|
||||
return 0;
|
||||
}
|
||||
|
||||
SH_CMD_FN(_close)
|
||||
{
|
||||
wifi_stop();
|
||||
return 0;
|
||||
}
|
||||
4
app/drivers/data_port/socket_inet/wifi_shell.h
Normal file
4
app/drivers/data_port/socket_inet/wifi_shell.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
void wifi_shell_register(void);
|
||||
void wifi_shell_unregister(void);
|
||||
Reference in New Issue
Block a user