doubao_chat/apps/common/product_test_tool/communication.c

590 lines
16 KiB
C

#include "product_main.h"
#ifdef PRODUCT_TEST_ENABLE
#ifndef PRODUCT_NET_CLIENT_ENABLE
static OS_SEM cdc_sem;
static u8 product_usb_id, online_flag = 0;
static int product_device_event_handler(struct sys_event *e)
{
struct device_event *event = (struct device_event *)e->payload;
const char *usb_msg = (const char *)event->value;
if (e->from == DEVICE_EVENT_FROM_OTG) {
if (usb_msg[0] == 's') {
if (event->event == DEVICE_EVENT_IN) {
product_info("usb %c online", usb_msg[2]);
online_flag = 1;
product_usb_id = usb_msg[2] - '0';
#ifdef PRODUCT_NET_SERVER_ENABLE
void audio_transmit_init(u8 id);
audio_transmit_init(product_usb_id);
#endif
} else if (event->event == DEVICE_EVENT_OUT) {
product_info("usb %c offline", usb_msg[2]);
online_flag = 0;
}
}
}
return 0;
}
SYS_EVENT_STATIC_HANDLER_REGISTER(product_device_event) = {
.event_type = SYS_DEVICE_EVENT,
.prob_handler = product_device_event_handler,
.post_handler = NULL,
};
u8 product_tool_cdc_post(void)
{
if (is_product_mode()) {
os_sem_post(&cdc_sem);
}
return is_product_mode();
}
static s8 comm_dev_init(void)
{
os_sem_create(&cdc_sem, 0);
return 0;
}
static s8 comm_dev_online(void)
{
if (!online_flag) {
product_err("communication devices no online\n");
}
online_flag = 1;
return online_flag;
}
static s32 comm_dev_read(u8 *data, u32 size)
{
//os_sem_set(&cdc_sem, 0);
os_sem_pend(&cdc_sem, 0);
return cdc_read_data(product_usb_id, data, size);
}
static s32 comm_dev_write(u8 *data, u32 size)
{
return cdc_write_data(product_usb_id, data, size);
}
static prod_comm_type comm = {
.init = comm_dev_init,
.online = comm_dev_online,
.read = comm_dev_read,
.write = comm_dev_write,
};
int host_data_read(u8 *data, u32 len)
{
return comm_ops()->read(data, len);
}
int host_data_write(u8 *data, u32 len)
{
return comm_ops()->write(data, len);
}
u8 get_product_id(void)
{
return product_usb_id;
}
#else
#include "sock_api/sock_api.h"
#include "os/os_api.h"
#include "app_config.h"
#include "system/includes.h"
#include "wifi/wifi_connect.h"
#include "lwip.h"
#include "lwip/sockets.h"
#include "lwip/netdb.h"
#define TXINFO_SIZE 4
#define USB_DIR_OUT 0
#define USB_DIR_IN 0x80
#define WIFI_TXWI_HEAD_SIZE 20
#define WIFI_80211_FILL_SIZE 27 //保留一些字节不填充, 为了避开duration段和上层发送1个字节也支持
static void *host_sock = NULL;
static u8 online_flag = 0;
static u8 conn_flag = 0, reset;
static struct product_conn conn;
static __attribute__((aligned(4))) u8 *wifi_send_pkg = NULL;
static void wifi_tx_data(u8 *pkg, int len, u32 rate, u8 bw, u8 short_gi)// 最大包1513
{
u16 *PktLen = &wifi_send_pkg[0];
u16 *MPDUtotalByteCount = &wifi_send_pkg[10];
*PktLen = WIFI_80211_FILL_SIZE + len + WIFI_TXWI_HEAD_SIZE + 4 - 8;
*MPDUtotalByteCount = WIFI_80211_FILL_SIZE + len;
const struct {
const char *string;
u8 phy;
u8 mcs;
} tx_rate_tab[] = {
{"1M", 0, 0},
{"2M", 0, 1},
{"5.5M", 0, 2},
{"11M", 0, 3},
{"6M", 1, 0},
{"9M", 1, 1},
{"12M", 1, 2},
{"18M", 1, 3},
{"24M", 1, 4},
{"36M", 1, 5},
{"48M", 1, 6},
{"54M", 1, 7},
{"HTMCS0", 2, 0},
{"HTMCS1", 2, 1},
{"HTMCS2", 2, 2},
{"HTMCS3", 2, 3},
{"HTMCS4", 2, 4},
{"HTMCS5", 2, 5},
{"HTMCS6", 2, 6},
{"HTMCS7", 2, 7},
};
if (pkg) {
//put_buf(pkg, len);
memcpy(&wifi_send_pkg[WIFI_TXWI_HEAD_SIZE + WIFI_80211_FILL_SIZE], pkg, len);
} else {
memset(&wifi_send_pkg[WIFI_TXWI_HEAD_SIZE + WIFI_80211_FILL_SIZE], 0xaa, len);
}
struct urb urb;
urb.pipe = USB_DIR_OUT;
urb.complete = NULL;
urb.transfer_buffer = wifi_send_pkg;
urb.transfer_buffer_length = len + WIFI_TXWI_HEAD_SIZE + WIFI_80211_FILL_SIZE + 4;
PTXWI_STRUC pTxWI = TXINFO_SIZE + (u8 *)urb.transfer_buffer;
pTxWI->PHYMODE = tx_rate_tab[rate].phy;
pTxWI->MCS = tx_rate_tab[rate].mcs;
pTxWI->BW = bw;
pTxWI->ShortGI = !short_gi;
usb_submit_urb(&urb, 0);
}
static void broadcast_resp_task(void *priv)
{
u8 idx = 0, mac[6];
struct wifi_store_info *info = get_cur_wifi_info();
//u8 ch[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
u8 ch[] = {2, 4, 6, 8, 10, 12};
//u8 ch[] = {1, 3, 5, 7, 9, 11, 13};
struct product_conn conn = {
.str = "product_resp",
.reset = 0,
};
u8 head[] = {
0xc6, 0x00, 0x00, 0x04, 0xB0, 0x00, 0x04, 0x80, 0x35, 0x01, 0xB6, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x08, 0x00, 0x88, 0x88, /*dst*/ 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6,/*src*/0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,/*BSSID*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /*Seq,Frag num*/0x88, 0x88,
};
if (!wifi_send_pkg) {
wifi_send_pkg = zalloc(1564);
ASSERT(wifi_send_pkg);
memcpy(wifi_send_pkg, head, sizeof(head));
}
conn.mode = info->mode;
if (info->mode == AP_MODE) {
wifi_get_mac(mac);
sprintf(conn.ssid, PRODUCT_AP_PREFIX"%02x%02x%02x%02x%02x%02x", \
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
sprintf(conn.pwd, PRODUCT_AP_PWD);
}
for (u8 i = 0; i < ARRAY_SIZE(ch) * 2; i++) {
wifi_set_channel(ch[(++idx) % ARRAY_SIZE(ch)]);
for (u8 i = 0; i < 5; i++) {
wifi_tx_data(&conn, sizeof(struct product_conn), 0, 0, 0);
}
product_info("%s, ch = idx = %d\n", __FUNCTION__, idx);
}
if (reset) {
cpu_reset();
} else {
wifi_off();
product_main();
}
}
static u8 broadcast_resp(void)
{
return thread_fork("broadcast_resp_task", 30, 1024, 0, NULL, broadcast_resp_task, NULL);
}
static void breathe_task(void *priv)
{
void *socket_fd;
int recv_len = 0;
u8 recv_buf[50] = {0};
struct sockaddr_in local_addr = {0};
struct sockaddr_in remote_addr = {0};
socklen_t len = sizeof(remote_addr);
local_addr.sin_family = AF_INET;
local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
local_addr.sin_port = htons(BREATHE_PORT);
if (!(socket_fd = sock_reg(AF_INET, SOCK_DGRAM, 0, NULL, NULL))) {
product_err("%s build socket fail\n", __FILE__);
return;
}
if (sock_bind(socket_fd, (struct sockaddr *)&local_addr, sizeof(struct sockaddr))) {
product_err("%s sock_bind fail\n", __FILE__);
return;
}
for (;;) {
if ((recv_len = sock_recvfrom(socket_fd, recv_buf, sizeof(recv_buf), 0, (struct sockaddr *)&remote_addr, &len)) > 0) {
//product_info("\n recv_len is %d, %s\n", recv_len, recv_buf);
sock_sendto(socket_fd, recv_buf, sizeof(recv_buf), 0, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr_in));
}
}
}
static void breathe_init(void)
{
thread_fork("breathe_task", 30, 512, 0, NULL, breathe_task, NULL);
}
static void host_conn_task(void *priv)
{
u32 opt = 1;
void *s_sock;
struct sockaddr_in local_addr = {0};
struct sockaddr_in remote_addr = {0};
socklen_t len = sizeof(struct sockaddr_in);
local_addr.sin_family = AF_INET;
local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
local_addr.sin_port = htons(HOST_PORT);
if (!(s_sock = sock_reg(AF_INET, SOCK_STREAM, 0, NULL, NULL))) {
product_err("%s build socket fail\n", __FILE__);
return;
}
if (sock_setsockopt(s_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
product_err("%s sock_setsockopt fail\n", __FILE__);
return;
}
if (sock_bind(s_sock, (struct sockaddr *)&local_addr, sizeof(struct sockaddr))) {
product_err("%s sock_bind fail\n", __FILE__);
return;
}
if (sock_listen(s_sock, 0x2)) {
product_err("%s sock_listen fail\n", __FILE__);
return;
}
if (!(host_sock = sock_accept(s_sock, (struct sockaddr *)&remote_addr, &len, NULL, NULL))) {
product_err("%s socket_accept fail\n", __FILE__);
return;
} else {
product_info("host socket conn succ\n");
online_flag = 1;
}
}
static void host_conn_init(void)
{
thread_fork("host_conn_task", 20, 512, 0, NULL, host_conn_task, NULL);
}
static int wifi_event_callback(void *network_ctx, enum WIFI_EVENT event)
{
u8 mac[6];
struct wifi_store_info wifi_default_mode_parm = {0};
static u8 ssid[33] = {0}, pwd[65] = {0};
switch (event) {
case WIFI_EVENT_MODULE_INIT:
puts("|network_user_callback->WIFI_EVENT_MODULE_INIT\n");
if (conn.mode == AP_MODE) {
strcpy(ssid, conn.ssid);
strcpy(pwd, conn.pwd);
wifi_default_mode_parm.mode = STA_MODE;
} else {
init_net_device_mac_addr((char *)mac, 1);
sprintf((char *)ssid, PRODUCT_AP_PREFIX"%02x%02x%02x%02x%02x%02x", \
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
sprintf((char *)pwd, PRODUCT_AP_PWD);
wifi_default_mode_parm.mode = AP_MODE;
}
if (wifi_default_mode_parm.mode <= AP_MODE) {
strncpy((char *)wifi_default_mode_parm.ssid[wifi_default_mode_parm.mode - STA_MODE], ssid, sizeof(wifi_default_mode_parm.ssid[wifi_default_mode_parm.mode - STA_MODE]) - 1);
strncpy((char *)wifi_default_mode_parm.pwd[wifi_default_mode_parm.mode - STA_MODE], pwd, sizeof(wifi_default_mode_parm.pwd[wifi_default_mode_parm.mode - STA_MODE]) - 1);
}
wifi_set_default_mode(&wifi_default_mode_parm, 1, 0);//wifi_default_mode_parm.mode == STA_MODE);
break;
case WIFI_EVENT_MODULE_START:
puts("|network_user_callback->WIFI_EVENT_MODULE_START\n");
break;
case WIFI_EVENT_MODULE_STOP:
puts("|network_user_callback->WIFI_EVENT_MODULE_STOP\n");
break;
case WIFI_EVENT_AP_START:
printf("|network_user_callback->WIFI_EVENT_AP_START,CH=%d\n", wifi_get_channel());
host_conn_init();
breathe_init();
camera_conn_init();
#ifdef CONFIG_AUDIO_ENABLE
audio_conn_init(conn.spk_value, conn.mic_value, conn.mic_res);
#endif
break;
case WIFI_EVENT_AP_STOP:
puts("|network_user_callback->WIFI_EVENT_AP_STOP\n");
break;
case WIFI_EVENT_STA_START:
puts("|network_user_callback->WIFI_EVENT_STA_START\n");
host_conn_init();
breathe_init();
camera_conn_init();
#ifdef CONFIG_AUDIO_ENABLE
audio_conn_init(conn.spk_value, conn.mic_value, conn.mic_res);
#endif
break;
case WIFI_EVENT_MODULE_START_ERR:
puts("|network_user_callback->WIFI_EVENT_MODULE_START_ERR\n");
break;
case WIFI_EVENT_STA_STOP:
puts("|network_user_callback->WIFI_EVENT_STA_STOP\n");
break;
case WIFI_EVENT_STA_DISCONNECT:
puts("|network_user_callback->WIFI_STA_DISCONNECT\n");
break;
case WIFI_EVENT_STA_SCAN_COMPLETED:
puts("|network_user_callback->WIFI_STA_SCAN_COMPLETED\n");
break;
case WIFI_EVENT_STA_CONNECT_SUCC:
printf("|network_user_callback->WIFI_STA_CONNECT_SUCC,CH=%d\r\n", wifi_get_channel());
break;
case WIFI_EVENT_MP_TEST_START:
puts("|network_user_callback->WIFI_EVENT_MP_TEST_START\n");
break;
case WIFI_EVENT_MP_TEST_STOP:
puts("|network_user_callback->WIFI_EVENT_MP_TEST_STOP\n");
break;
case WIFI_EVENT_STA_CONNECT_TIMEOUT_NOT_FOUND_SSID:
puts("|network_user_callback->WIFI_STA_CONNECT_TIMEOUT_NOT_FOUND_SSID\n");
break;
case WIFI_EVENT_STA_NETWORK_STACK_DHCP_SUCC:
puts("|network_user_callback->WIFI_EVENT_STA_NETWPRK_STACK_DHCP_SUCC\n");
break;
case WIFI_EVENT_STA_NETWORK_STACK_DHCP_TIMEOUT:
puts("|network_user_callback->WIFI_EVENT_STA_NETWPRK_STACK_DHCP_TIMEOUT\n");
break;
case WIFI_EVENT_P2P_START:
puts("|network_user_callback->WIFI_EVENT_P2P_START\n");
break;
case WIFI_EVENT_P2P_STOP:
puts("|network_user_callback->WIFI_EVENT_P2P_STOP\n");
break;
case WIFI_EVENT_P2P_GC_DISCONNECTED:
puts("|network_user_callback->WIFI_EVENT_P2P_GC_DISCONNECTED\n");
break;
case WIFI_EVENT_P2P_GC_NETWORK_STACK_DHCP_SUCC:
puts("|network_user_callback->WIFI_EVENT_P2P_GC_NETWORK_STACK_DHCP_SUCC\n");
break;
case WIFI_EVENT_P2P_GC_NETWORK_STACK_DHCP_TIMEOUT:
puts("|network_user_callback->WIFI_EVENT_P2P_GC_NETWORK_STACK_DHCP_TIMEOUT\n");
break;
case WIFI_EVENT_SMP_CFG_START:
puts("|network_user_callback->WIFI_EVENT_SMP_CFG_START\n");
break;
case WIFI_EVENT_SMP_CFG_STOP:
puts("|network_user_callback->WIFI_EVENT_SMP_CFG_STOP\n");
break;
case WIFI_EVENT_SMP_CFG_TIMEOUT:
puts("|network_user_callback->WIFI_EVENT_SMP_CFG_TIMEOUT\n");
break;
case WIFI_EVENT_SMP_CFG_COMPLETED:
puts("|network_user_callback->WIFI_EVENT_SMP_CFG_COMPLETED\n");
break;
case WIFI_EVENT_PM_SUSPEND:
puts("|network_user_callback->WIFI_EVENT_PM_SUSPEND\n");
break;
case WIFI_EVENT_PM_RESUME:
puts("|network_user_callback->WIFI_EVENT_PM_RESUME\n");
break;
case WIFI_EVENT_AP_ON_ASSOC:
puts("WIFI_EVENT_AP_ON_ASSOC\n");
break;
case WIFI_EVENT_AP_ON_DISCONNECTED:
puts("WIFI_EVENT_AP_ON_DISCONNECTED\n");
break;
default:
break;
}
return 0;
}
u8 product_info_check(void)
{
static u8 init = 0;
struct product_conn clean = {0};
if (conn_flag) {
syscfg_write(CFG_PRODUCT_CFG_INDEX, &clean, sizeof(struct product_conn));
return TRUE;
}
if (!init) {
init = 1;
syscfg_read(CFG_PRODUCT_CFG_INDEX, &conn, sizeof(struct product_conn));
}
if (!strcmp(conn.str, "product_ask")) {
product_info("str = %s, mode = %d, ssid = %s, pwd = %s\n", conn.str, conn.mode, conn.ssid, conn.pwd);
syscfg_write(CFG_PRODUCT_CFG_INDEX, &clean, sizeof(struct product_conn));
return TRUE;
}
return FALSE;
}
static void wifi_rx_frame_cb(void *rxwi, void *header, void *data, u32 len, void *reserve)
{
u32 size = len;
u8 *buf, offset;
struct product_conn *conn;
PRXWI_STRUC pRxWI = (PRXWI_STRUC *)rxwi;
s8 rssi0 = pRxWI->RSSI0;
if (rssi0 < PRODUCT_CLI_RSSI_THR) {
product_info("RSSI = %d, THR = %d\n", rssi0, PRODUCT_CLI_RSSI_THR);
return;
}
struct wifi_store_info *info = get_cur_wifi_info();
offset = (info->mode == AP_MODE) ? 27 : 51;
size = len - offset;
//if (size < sizeof(struct product_conn)) {
// putchar('N');
// return;
//}
buf = ((u8 *)data) + offset;
conn = buf;
if (!strcmp(conn->str, "product_ask") && !conn_flag) {
conn_flag = 1;
reset = conn->reset;
product_info("str = %s, mode = %d, ssid = %s, pwd = %s\n", conn->str, conn->mode, conn->ssid, conn->pwd);
syscfg_write(CFG_PRODUCT_CFG_INDEX, conn, sizeof(struct product_conn));
broadcast_resp();
}
}
static void net_check_timer_hdl(void *priv)
{
product_info("%s\n", __FUNCTION__);
wifi_set_frame_cb(NULL, NULL);
}
void product_net_client_init(void)
{
wifi_set_frame_cb(wifi_rx_frame_cb, NULL);
if (PRODUCT_NET_CHECK_TIMEOUT) {
sys_timeout_add(NULL, net_check_timer_hdl, PRODUCT_NET_CHECK_TIMEOUT);
}
}
static s8 comm_dev_init(void)
{
wifi_set_event_callback(wifi_event_callback);
wifi_on();
}
static s8 comm_dev_online(void)
{
return online_flag;
}
static s32 comm_dev_read(u8 *data, u32 size)
{
if (!online_flag) {
return 0;
}
return sock_recvfrom(host_sock, data, size, 0, NULL, NULL);
}
static s32 comm_dev_write(u8 *data, u32 size)
{
if (!online_flag) {
return 0;
}
return sock_send(host_sock, data, size, 0);
}
static prod_comm_type comm = {
.init = comm_dev_init,
.online = comm_dev_online,
.read = comm_dev_read,
.write = comm_dev_write,
};
#endif
prod_comm_type *comm_ops(void)
{
return &comm;
}
#endif