184 lines
4.9 KiB
C++
184 lines
4.9 KiB
C++
#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();
|
||
} |