#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], ®cache[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], ®cache[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); }