#include "codec.h" #include "base/crc.h" #include "interface/codec_ym.h" // 重载接收字节函数 bool CodecYm::recvByte(int byte) { bool ack = false; if (fullFrame == true) { return fullFrame; } data.append(uint8_t(byte)); switch (data.size()) { case 2: if (uint8_t(data[0]) == 0x59u && uint8_t(data[1]) == 0x6du) { is_big_data = false; num_to_read = 4; // 帧头+2byte负载长度 } else { data.remove(0, 1); num_to_read = 0; } break; case 4: { int len = data[2] | (data[3] << 8); if (len < 65535) { is_big_data = false; num_to_read += len + 2; // 负载+2byte校验 qDebug("normal data. len=%d", len); } else { is_big_data = true; num_to_read = 11; // 扩展数据长度 qDebug("big data."); } } break; case 11: { if (is_big_data == true) { int len = data[7] | (data[8] << 8) | (data[9] << 16) | (data[10] << 24); num_to_read = 4 + len + 2; // 负载+2byte校验 qDebug("big data. len=%d", len); } } default: break; } // 此时一帧数据已完成 if (num_to_read > 0 && num_to_read == data.size()) { ack = true; num_to_read = 0; } fullFrame = ack; return fullFrame; } // 重载解码函数 myarray CodecYm::decode(int &srcAddr, int &dstAddr, int &cmd, myarray data) { Q_UNUSED(srcAddr); Q_UNUSED(dstAddr); myarray r; if (packCheck(data) >0) { qDebug("offset=%d",offset); cmd = this->cmd; if (is_big_data == false) r = data.mid(offset+7, len - 3); else r = data.mid(offset+11, len - 7); } return r; } int CodecYm::packCheck(myarray data) { int ack = 0; offset=0; while(data.size()>=2){ if ((uint8_t(data[0]) != 0x59u) || (uint8_t(data[1]) != 0x6du)) { // 帧头不对 // qWarning("frame head not 0x59 0x6d"); // return ack; data.remove(0,1); offset++; }else{ break; } } if (data.size() < 9) { // 主机一帧数据至少9字节 // qWarning("recv data len too less"); return ack; } len = (data[2] | (data[3] << 8)); if (len == 65535) { // 重新设置数据长度 len = data[7] | (data[8] << 8) | (data[9] << 16) | (data[10] << 24); is_big_data = true; } else { is_big_data = false; } if (len + 6 > data.size()) { // 如果长度不相等则产生了数据丢失 // qWarning("recv data have lossed"); return ack; } uint8_t chk_a = 0, chk_b = 0; crc::crc16((uint8_t *)data.data(), 2, len + 4, &chk_a, &chk_b); if (chk_a != uint8_t(data[data.size() - 2]) || chk_b != uint8_t(data[data.size() - 1])) { // crc校验不对 qWarning("recv data check error:%02x,%02x %02x,%02x", chk_a, chk_b, int(data[data.size() - 2]), int(data[data.size() - 1])); } // 保存此流水号 cmd_no = data[5] | (data[6] << 8); cmd = data[4]; // 数据负载 return len+offset+6; } myarray CodecYm::encode(int srcAddr, int dstAddr, int cmd, myarray data) { Q_UNUSED(srcAddr); Q_UNUSED(dstAddr); myarray t; uint32_t len = data.size() + 3; t.append(0x59u); t.append(0x6du); t.append(0x43u); if (len < 65535) { t.append((len) & 0xff); t.append((len) >> 8); t.append(cmd); t.append(cmd_no & 0xff); t.append(cmd_no >> 8); } else { len += 4; t.append(0xff); t.append(0xff); t.append(cmd); t.append(cmd_no & 0xff); t.append(cmd_no >> 8); t.append(len & 0xff); t.append((len >> 8) & 0xff); t.append((len >> 16) & 0xff); t.append((len >> 24) & 0xff); } t.append(data); uint8_t chk_a, chk_b; crc::crc16((uint8_t *)t.data(), 3, len + 5, &chk_a, &chk_b); t.append(chk_a); t.append(chk_b); return t; } Codec *codec_ym_get() { static Codec *codec_ = nullptr; if (codec_ == nullptr) { codec_ = new CodecYm(); } return codec_; } codec_export(codec_ym, codec_ym_get);