#include #include "SocketApiProtocol.h" #define RECV_BUFFER_SIZE 26 //接收缓冲区大小 #define PKG_CORE_STATUS 0x00 //读取核心状态 #define PKG_CAN_STATUS 0x01 //CAN盒子状态 #define PKG_TRANS_CAN 0x02 //收发CAN包 static asio::io_context io_ctx; static std::unique_ptr udp_socket; uint8_t recv_buffer[RECV_BUFFER_SIZE] = {0x00}; uint8_t send_buffer[RECV_BUFFER_SIZE] = {0x00}; char TimeBuff[32] = {0x00}; char log[64] = {0x00}; asio::ip::udp::endpoint remote_endpoint; time_t now; struct tm* t; void SocketApiProtocolRun(void); void start_receive(void); void UdpAnalysis(uint8_t* RxData); int UdpSendData(const char* ip, uint16_t port, const uint8_t* data, size_t len); void CallBackCoreStatus(uint8_t* RxData,uint8_t* TxData); void SocketApiProtocolInit(uint32_t SocketPort) { udp_socket = std::make_unique( io_ctx, asio::ip::udp::endpoint(asio::ip::udp::v4(), SocketPort) ); if(udp_socket && udp_socket->is_open()) { std::cout << "[UDP] Listening successfully" << std::endl; } else { std::cerr << "[UDP] Socket not open" << std::endl; } std::thread UdpReceiveTask(SocketApiProtocolRun); UdpReceiveTask.detach(); start_receive(); // 注册第一次接收 std::cout << "[UDP] Listening on port " << SocketPort << std::endl; } void start_receive(void) { udp_socket->async_receive_from( asio::buffer(recv_buffer, RECV_BUFFER_SIZE), remote_endpoint, [](const asio::error_code& ec, std::size_t bytes_recvd) { if(!ec && bytes_recvd == RECV_BUFFER_SIZE && recv_buffer[0] == 0x55 && recv_buffer[RECV_BUFFER_SIZE - 1] == 0xAA) { UdpAnalysis(recv_buffer); } // 再次注册接收,保持持续监听 start_receive(); } ); } void transTimeToData(uint8_t* TxData, struct tm* t) { uint8_t data[7] = {0x00}; data[0] = t->tm_year & 0xFF; data[1] = (t->tm_year >> 8) & 0xFF; data[2] = t->tm_mon; data[3] = t->tm_wday; data[4] = t->tm_hour; data[5] = t->tm_min; data[6] = t->tm_sec; memcpy(TxData,data,7); } void UdpAnalysis(uint8_t* RxData) { int command = RxData[1]; if (SystemCall.logEn == ENABLE) { now = time(NULL); // 获取当前时间戳(从1970-01-01秒数) t = localtime(&now); // 转成本地时间 sprintf(TimeBuff,"%d-%d-%d.log",t->tm_year,t->tm_mon,t->tm_wday); } memset(send_buffer,0x00,RECV_BUFFER_SIZE); /* 添加报文头尾 */ send_buffer[0] = 0x55; send_buffer[RECV_BUFFER_SIZE - 1] = 0xAA; switch(command) { case PKG_CORE_STATUS: if (SystemCall.logEn == ENABLE) { logAdd(TimeBuff,"查询Core状态"); } CallBackCoreStatus(RxData, send_buffer); break; case PKG_CAN_STATUS: break; case PKG_TRANS_CAN: break; } //如果调试使能,则加入时间 if (SystemCall.logEn == ENABLE) { transTimeToData(&send_buffer[2],t); } UdpSendData("127.0.0.1", 12346, send_buffer, RECV_BUFFER_SIZE); //调试使能就记录一下,记录使用队列保证不影响收发 if (SystemCall.logEn == ENABLE) { sprintf(log,"发送报文:"); for (int i = 0;i < RECV_BUFFER_SIZE;i++) { sprintf(&log[10],"0x%02X ",send_buffer[i]); } if (SystemCall.logEn == ENABLE) { logAdd(TimeBuff,""); } logAdd(TimeBuff,TimeBuff); } } void CallBackCoreStatus(uint8_t* RxData, uint8_t* TxData) { uint8_t data[4] = {0x00}; data[0] = SystemCall.ProductInfo; //产品信息 data[1] = SystemCall.CanOpenStatus[0]; //通道0打开状态 data[2] = SystemCall.CanOpenStatus[1]; //通道1打开状态 data[3] = SystemCall.logEn; //日志启用状态 memcpy(&TxData[9],data,4); } int UdpSendData(const char* ip, uint16_t port, const uint8_t* data, size_t len) { if(!udp_socket) return 0; asio::error_code ec; asio::ip::udp::endpoint remote(asio::ip::make_address(ip), port); size_t sent = udp_socket->send_to(asio::buffer(data, len), remote, 0, ec); if(ec) { if (SystemCall.logEn == ENABLE) { printf("[UDP] Send failed: %s\n", ec.message().c_str()); } return 0; } if (SystemCall.logEn == ENABLE) { printf("[UDP] Sent %zu bytes to %s:%u\n", sent, ip, port); } return 1; } // 让你的系统循环运行 ASIO void SocketApiProtocolRun(void) { io_ctx.run(); }