UniversalCanCore/Src/SocketApiProtocol.cpp
2025-12-15 21:21:12 +08:00

184 lines
4.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <time.h>
#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<asio::ip::udp::socket> 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<asio::ip::udp::socket>(
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();
}