137 lines
3.7 KiB
C++
137 lines
3.7 KiB
C++
#include <vector>
|
||
#include <cstdint>
|
||
#include <cstring>
|
||
#include <string>
|
||
#include <stdexcept>
|
||
#include <algorithm>
|
||
#include <cctype>
|
||
#include <cstdlib>
|
||
#include "client2.h"
|
||
#include "PQSMsg.h"
|
||
|
||
// 生成带协议头的二进制报文
|
||
std::vector<unsigned char> generate_binary_message(
|
||
uint16_t msg_type,
|
||
const std::vector<unsigned char>& payload)
|
||
{
|
||
std::vector<unsigned char> packet;
|
||
|
||
// 协议头 (4字节)
|
||
packet.push_back(0xAA); // 起始标志
|
||
packet.push_back((msg_type >> 8) & 0xFF); // 消息类型高字节
|
||
packet.push_back(msg_type & 0xFF); // 消息类型低字节
|
||
uint8_t length = payload.size();
|
||
packet.push_back(length); // 载荷长度
|
||
|
||
// 载荷数据
|
||
packet.insert(packet.end(), payload.begin(), payload.end());
|
||
|
||
// 校验位 (1字节异或校验)
|
||
uint8_t checksum = 0;
|
||
for (auto byte : packet) {
|
||
checksum ^= byte;
|
||
}
|
||
packet.push_back(checksum);
|
||
|
||
return packet;
|
||
}
|
||
|
||
// 使用示例
|
||
void send_message(client_context_t* ctx) {
|
||
// 构造载荷数据
|
||
std::vector<unsigned char> payload = {
|
||
0x01, 0x02, 0x03, 0x04 // 示例数据
|
||
};
|
||
|
||
// 生成完整报文 (消息类型0x1001)
|
||
auto binary_data = generate_binary_message(0x1001, payload);
|
||
|
||
// 转换为数组形式
|
||
unsigned char* binary_array = binary_data.data();
|
||
size_t data_size = binary_data.size();
|
||
|
||
// 此处可调用发送函数
|
||
send_binary_data(ctx, binary_array, data_size);
|
||
}
|
||
|
||
// 辅助函数:解析MAC地址并填充到缓冲区
|
||
void GetMAC(const std::string& strMAC, std::vector<unsigned char>& packet, size_t startIndex) {
|
||
// 移除所有空格和短横线
|
||
std::string cleanedMAC = strMAC;
|
||
cleanedMAC.erase(std::remove(cleanedMAC.begin(), cleanedMAC.end(), ' '), cleanedMAC.end());
|
||
cleanedMAC.erase(std::remove(cleanedMAC.begin(), cleanedMAC.end(), '-'), cleanedMAC.end());
|
||
|
||
// 验证长度
|
||
if (cleanedMAC.length() != 12) {
|
||
throw std::invalid_argument("MAC地址长度必须为12个字符");
|
||
}
|
||
|
||
try {
|
||
// 解析每两个字符作为十六进制字节
|
||
for (int i = 0; i < 6; i++) {
|
||
// 提取两个字符的子串
|
||
std::string byteStr = cleanedMAC.substr(i * 2, 2);
|
||
|
||
// 转换为十六进制字节
|
||
unsigned char byte = static_cast<unsigned char>(
|
||
std::stoi(byteStr, nullptr, 16)
|
||
);
|
||
|
||
// 填充到指定位置
|
||
if (startIndex + i < packet.size()) {
|
||
packet[startIndex + i] = byte;
|
||
}
|
||
}
|
||
|
||
// 剩余部分填0 (总共需要64字节,但MAC只占6字节)
|
||
for (int i = 6; i < 64; i++) {
|
||
if (startIndex + i < packet.size()) {
|
||
packet[startIndex + i] = 0;
|
||
}
|
||
}
|
||
}
|
||
catch (const std::exception& e) {
|
||
throw std::invalid_argument("无效的MAC地址: " + std::string(e.what()));
|
||
}
|
||
}
|
||
|
||
// 生成装置云服务登录报文
|
||
std::vector<unsigned char> generate_frontlogin_message(const std::string& strMac)
|
||
{
|
||
const size_t packetSize = 150; // 报文总长150 数据体+帧序号140
|
||
std::vector<unsigned char> packet(packetSize, 0); // 初始化为全0
|
||
|
||
// 协议头
|
||
packet[0] = 0xEB; // 起始标志1
|
||
packet[1] = 0x90;
|
||
packet[2] = 0xEB; // 起始标志2
|
||
packet[3] = 0x90;
|
||
packet[4] = 0x8C; // 数据体长度 (140 = 0x008C)
|
||
packet[5] = 0x00;
|
||
// [6-7] 随机码 (保持为0)
|
||
// [8-9] 功能码 (保持为0)
|
||
// [10-11] 帧序号 (保持为0)
|
||
// 数据体1
|
||
packet[12] = 'F';
|
||
packet[13] = 'T';
|
||
packet[14] = 'I';
|
||
packet[15] = 'D';
|
||
// [16-19] 数据体2 (保持为0)
|
||
|
||
// 填充MAC地址 (从位置20开始,64字节)
|
||
GetMAC(strMac, packet, 20);
|
||
|
||
// 计算校验和 (从偏移8到137)
|
||
unsigned char checksum = 0;
|
||
for (size_t i = 8; i < packetSize - 2; i++) {
|
||
checksum += packet[i];
|
||
}
|
||
packet[packetSize - 2] = checksum;
|
||
|
||
// 结束符
|
||
packet[packetSize - 1] = 0x16;
|
||
|
||
return packet;
|
||
}
|
||
|