You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

197 lines
7.3 KiB

#include "project_configs.h"
#include "project_dep.h"
//
#include "base_service/config_service.h"
#include "cmsis_os.h"
#include "reg_manager.h"
#define TAG "extern_if_service"
typedef struct {
zaf_packet_header_t *rxpacket;
zaf_buf_t receipt;
bool resetBoard;
} extern_if_service_context_t;
static udp_t m_udp_cmd_server; //
osThreadId m_cmd_uart_receiver_thread; //
extern DMA_HandleTypeDef COMMAND_UART_DMA_HANDLER;
extern UART_HandleTypeDef COMMAND_UART;
// static udp_broadcast_handler_t m_udp_camera_sync_sender; //
static struct sockaddr_in m_last_rxpacket_client;
static bool m_last_rxpacket_client_valid = false;
static uint8_t txbuf[2048];
/*******************************************************************************
* 包构造 *
*******************************************************************************/
static void create_receipt(extern_if_service_context_t *context, uint32_t ecode, uint32_t *data, size_t ndata) {
zaf_packet_header_t *txpacket = (zaf_packet_header_t *)txbuf;
uint32_t txpacklen = sizeof(zaf_packet_header_t) + (ndata + 1) * sizeof(uint32_t) + 1 /*checksum*/ + 2 /*tail*/;
txpacket->packet_header = PACKET_HEADER;
txpacket->packet_type = kzaf_packet_type_receipt;
txpacket->index = context->rxpacket->index;
txpacket->cmd = context->rxpacket->cmd;
txpacket->ndata = ndata + 1;
txpacket->data[0] = ecode;
memcpy(&txpacket->data[1], data, ndata * sizeof(uint32_t));
uint8_t checksum = 0;
for (int i = 2; i < txpacklen - 3; i++) {
checksum += txbuf[i];
}
txbuf[txpacklen - 3] = checksum;
txbuf[txpacklen - 2] = PACKET_TAIL & 0xFF;
txbuf[txpacklen - 1] = (PACKET_TAIL >> 8) & 0xFF;
zaf_buf_t buf;
buf.data = txbuf;
buf.len = txpacklen;
context->receipt = buf;
}
/*******************************************************************************
* 接收消息处理 *
*******************************************************************************/
static bool process_rx_packet(extern_if_service_context_t *cx, uint8_t *data, uint16_t len) {
// ZLOGI(TAG, "process_rx_packet %d:", len);
// for (int i = 0; i < len; i++) {
// printf("%02x ", data[i]);
// }
// printf("\n");
zaf_packet_header_t *rxpacket = (zaf_packet_header_t *)data;
cx->rxpacket = rxpacket;
if (rxpacket->packet_type != kzaf_packet_type_cmd) return false;
/*******************************************************************************
* 寄存器读 *
*******************************************************************************/
if (rxpacket->cmd == kzaf_cmd_reg_read) {
uint32_t readbak_regval = reg_manager_read_reg(rxpacket->data[0]); // regdata
create_receipt(cx, 0, &readbak_regval, 1);
}
/*******************************************************************************
* 寄存器写 *
*******************************************************************************/
else if (rxpacket->cmd == kzaf_cmd_reg_write) {
uint32_t readbak_regval = reg_manager_write_reg(rxpacket->data[0], rxpacket->data[1]);
create_receipt(cx, 0, &readbak_regval, 1);
}
/*******************************************************************************
* 多寄存器读 *
*******************************************************************************/
else if (rxpacket->cmd == kzaf_cmd_reg_read_regs) {
static uint32_t regcache[MAX_REG_NUM + 1];
uint32_t len = MAX_REG_NUM;
reg_manager_read_regs(rxpacket->data[0], rxpacket->data[1], &regcache[0], &len);
create_receipt(cx, 0, regcache, len);
}
else if (rxpacket->cmd == kzaf_cmd_reg_read_regs) {
static uint32_t regcache[MAX_REG_NUM + 1];
uint32_t len = MAX_REG_NUM;
reg_manager_read_regs(rxpacket->data[0], rxpacket->data[1], &regcache[0], &len);
create_receipt(cx, 0, regcache, len);
}
/*******************************************************************************
* 产生新的MAC *
*******************************************************************************/
else if (rxpacket->cmd == kzaf_cmd_generator_new_mac) {
config_generate_random_mac();
config_flush();
create_receipt(cx, 0, NULL, 0);
} else if (rxpacket->cmd == kzaf_cmd_factory_reset) {
config_factory_reset();
cx->resetBoard = true;
create_receipt(cx, 0, NULL, 0);
} else if (rxpacket->cmd == kzaf_cmd_reboot) {
cx->resetBoard = true;
create_receipt(cx, 0, NULL, 0);
} else if (rxpacket->cmd == kzaf_cmd_storage_cfg) {
config_flush();
create_receipt(cx, 0, NULL, 0);
} else if (rxpacket->cmd == kzaf_cmd_ping) {
create_receipt(cx, 0, NULL, 0);
}
return true;
}
/*******************************************************************************
* 框架 *
*******************************************************************************/
/**
* @brief UDP消息接收消息处理
*
* @param server
* @param client
* @param data
* @param len
*/
static void udp_on_packet(udp_t *server, struct sockaddr_in *client, uint8_t *data, uint16_t len) {
extern_if_service_context_t cx = {0};
bool ret = process_rx_packet(&cx, data, len);
if (ret) {
zaf_udp_send_message2(server, client, (const char *)cx.receipt.data, cx.receipt.len);
m_last_rxpacket_client_valid = true;
memcpy(&m_last_rxpacket_client, client, sizeof(struct sockaddr_in));
osDelay(5);
if (cx.resetBoard) NVIC_SystemReset();
}
}
static void uart_on_packet(uint8_t *packet, uint32_t len) {
extern_if_service_context_t cx = {0};
bool ret = process_rx_packet(&cx, packet, len);
if (ret) {
HAL_UART_Transmit(&COMMAND_UART, (uint8_t *)cx.receipt.data, cx.receipt.len, 1000);
osDelay(2);
if (cx.resetBoard) NVIC_SystemReset();
}
}
static uint8_t g_uart_rx_buf[128];
static uint32_t g_uart_rx_buf_index = 0;
bool uart_is_rxing(UART_HandleTypeDef *huart) { //
uint32_t uartstate = HAL_UART_GetState(huart);
if (uartstate & 0x02) {
return true;
}
return false;
}
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) { g_uart_rx_buf_index = Size; }
static void uart_receiver_thread(const void *) {
while (1) {
if (!uart_is_rxing(&COMMAND_UART)) {
if (g_uart_rx_buf_index != 0) {
uart_on_packet(g_uart_rx_buf, g_uart_rx_buf_index);
}
g_uart_rx_buf_index = 0;
memset(g_uart_rx_buf, 0, sizeof(g_uart_rx_buf));
HAL_UARTEx_ReceiveToIdle_DMA(&COMMAND_UART, g_uart_rx_buf, sizeof(g_uart_rx_buf) - 1);
}
osDelay(1);
}
}
void extern_if_service_init() { //
ZASSERT(zaf_udp_init(&m_udp_cmd_server, "extern_if_udp", ZAF_SERVICE_DEVICE_PORT, udp_on_packet, 1024, NULL));
osThreadDef(cmdUartReceiverThread, uart_receiver_thread, osPriorityNormal, 0, 512);
m_cmd_uart_receiver_thread = osThreadCreate(osThread(cmdUartReceiverThread), NULL);
ZASSERT(m_cmd_uart_receiver_thread != NULL);
}