package com.ard.tianyu.netty.handler;// MessageProtocolDecoder.java
|
|
import com.ard.tianyu.netty.command.*;
|
import com.ard.tianyu.netty.protobuf.TelemetryDataPB;
|
import io.netty.buffer.ByteBuf;
|
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.handler.codec.ByteToMessageDecoder;
|
import lombok.extern.slf4j.Slf4j;
|
|
import java.util.List;
|
|
@Slf4j
|
public class MessageProtocolDecoder extends ByteToMessageDecoder {
|
@Override
|
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
|
// 检查可读字节数是否足够
|
if (in.readableBytes() < 4) {
|
return; // 不足以读取头部
|
}
|
|
in.markReaderIndex(); // 标记当前读取位置
|
short dataHead = in.readShort();
|
if (dataHead != 0x6A77) {
|
return;
|
}
|
short dataLength = in.readShort();
|
|
if (in.readableBytes() < dataLength) {
|
in.resetReaderIndex(); // 如果不足,重置读取位置
|
return;
|
}
|
byte cmdCode = in.readByte();
|
BaseCommand baseCommand = null;
|
switch (cmdCode) {
|
case 0x01:
|
byte success = in.readByte(); // 读取是否成功
|
log.warn("注册回复: {}", success == 0x01 ? "成功" : "失败");
|
baseCommand = new RegisterReplyCommand(success);
|
break;
|
case 0x02:
|
long timestamp = in.readLong(); // 读取时间戳
|
baseCommand = new HeartbeatReplyCommand(timestamp);
|
log.debug("心跳回复: 时间戳 {}", timestamp);
|
break;
|
case 0x03:
|
case 0x04:
|
break;
|
case (byte) 0xA8:
|
byte[] uavStatus = new byte[dataLength - 1];
|
in.readBytes(uavStatus); // 读取 ProtoBuf 数据
|
TelemetryDataPB.UavState uavState = TelemetryDataPB.UavState.parseFrom(uavStatus);
|
baseCommand = new UavStateCommand(uavState);
|
log.debug("无人机状态数据: {}", uavState.getBoxSn());
|
break;
|
case (byte) 0xA9:
|
byte[] uavData = new byte[dataLength - 1];
|
in.readBytes(uavData);
|
TelemetryDataPB.TelemetryData telemetryData = TelemetryDataPB.TelemetryData.parseFrom(uavData);
|
baseCommand = new UavTelemetryDataCommand(telemetryData);
|
log.debug("遥测数据: {}", telemetryData.getBoxSn());
|
break;
|
case (byte) 0x0C:
|
int delayTime = in.readInt();
|
uavData = new byte[15];
|
in.readBytes(uavData);
|
// String boxSn12 = new String(uavData);
|
uavData = new byte[dataLength - 20];
|
in.readBytes(uavData);
|
TelemetryDataPB.SignalInfo signalInfo = TelemetryDataPB.SignalInfo.parseFrom(uavData);
|
baseCommand = new SignalInfoCommand(signalInfo);
|
log.debug("信道质量数据: {}", delayTime);
|
break;
|
case (byte) 0xD1:
|
byte encryptionFlag = in.readByte();
|
byte actionCode = in.readByte();
|
switch (actionCode) {
|
case 0x42:
|
byte[] uavData1 = new byte[dataLength - 18];
|
in.readBytes(uavData1);
|
byte[] uavData2 = new byte[15];
|
in.readBytes(uavData2);
|
String boxSn = new String(uavData2);
|
TelemetryDataPB.UavInitInfo uavInitInfo = TelemetryDataPB.UavInitInfo.parseFrom(uavData1);
|
baseCommand = new DroneReadyNotificationCommand(boxSn, uavInitInfo, actionCode);
|
log.info("无人机初始化数据: {}", uavInitInfo.getUavModel());
|
break;
|
default:
|
log.warn("无法识别的命令码动作编号:{}", String.format("0x%02X", actionCode & 0xFF));
|
break;
|
}
|
break;
|
default:
|
encryptionFlag = in.readByte();
|
actionCode = in.readByte();
|
log.warn("无法识别的命令码: {},加密标志:{},动作编号:{}",
|
String.format("0x%02X", cmdCode & 0xFF),
|
String.format("0x%02X", encryptionFlag & 0xFF),
|
String.format("0x%02X", actionCode & 0xFF));//String.format("0x%02X", cmdCode & 0xFF)
|
|
}
|
if (baseCommand != null) {
|
out.add(baseCommand);
|
}
|
}
|
}
|