package com.ard.tianyu.netty.handler;// MessageProtocolDecoder.java
|
|
import com.ard.tianyu.netty.command.*;
|
import com.ard.tianyu.netty.command.camera.CameraModeReplyCmd;
|
import com.ard.tianyu.netty.command.camera.CapturePicReplyCmd;
|
import com.ard.tianyu.netty.command.camera.RecordStartReplyCmd;
|
import com.ard.tianyu.netty.command.camera.RecordStopReplyCmd;
|
import com.ard.tianyu.netty.command.manual.*;
|
import com.ard.tianyu.netty.command.notice.BoxPowerStatusReplyCmd;
|
import com.ard.tianyu.netty.command.notice.FlyWayEndReplyCmd;
|
import com.ard.tianyu.netty.command.notice.UavReadyReplyCmd;
|
import com.ard.tianyu.netty.command.real.SignalInfoCmd;
|
import com.ard.tianyu.netty.command.real.UavStateCmd;
|
import com.ard.tianyu.netty.command.real.UavTelemetryDataCmd;
|
import com.ard.tianyu.netty.command.register.HeartbeatReplyCmd;
|
import com.ard.tianyu.netty.command.register.RegisterReplyCmd;
|
import com.ard.tianyu.netty.command.register.UavInitReplyCmd;
|
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();
|
BaseCmd baseCmd = null;
|
switch (cmdCode) {
|
case 0x01:
|
byte success = in.readByte(); // 读取是否成功
|
log.warn("注册回复: {}", success == 0x01 ? "成功" : "失败");
|
baseCmd = new RegisterReplyCmd(success);
|
break;
|
case 0x02:
|
long timestamp = in.readLong(); // 读取时间戳
|
baseCmd = new HeartbeatReplyCmd(timestamp);
|
log.debug("心跳回复: 时间戳 {}", timestamp);
|
break;
|
case 0x03:
|
case 0x04:
|
break;
|
case 0x0A:
|
byte status = in.readByte();
|
baseCmd = new BoxPowerStatusReplyCmd(status);
|
log.debug("云盒开机/关机通知回复: 状态 {}", String.format("0x%02X", status & 0xFF));
|
break;
|
case (byte) 0xA8:
|
byte[] uavStatus = new byte[dataLength - 1];
|
in.readBytes(uavStatus); // 读取 ProtoBuf 数据
|
TelemetryDataPB.UavState uavState = TelemetryDataPB.UavState.parseFrom(uavStatus);
|
baseCmd = new UavStateCmd(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);
|
baseCmd = new UavTelemetryDataCmd(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);
|
baseCmd = new SignalInfoCmd(signalInfo);
|
log.debug("信道质量数据: {}", delayTime);
|
break;
|
case (byte) 0xD1:
|
byte encryptionFlag = in.readByte();
|
byte actionCode = in.readByte();
|
switch (actionCode) {
|
case 0x11:
|
byte result = in.readByte();
|
int errorCode = in.readInt();
|
uavData = new byte[15];
|
in.readBytes(uavData);
|
String boxSn = new String(uavData);
|
baseCmd = new TakeOffReplyCmd(boxSn, result, errorCode);
|
log.debug("起飞回复: {}", boxSn);
|
break;
|
case 0x12:
|
result = in.readByte();
|
errorCode = in.readInt();
|
uavData = new byte[15];
|
in.readBytes(uavData);
|
boxSn = new String(uavData);
|
baseCmd = new ReturnHomeReplyCmd(boxSn, result, errorCode);
|
log.debug("返航回复: {}", boxSn);
|
break;
|
case 0x13:
|
result = in.readByte();
|
errorCode = in.readInt();
|
uavData = new byte[15];
|
in.readBytes(uavData);
|
boxSn = new String(uavData);
|
baseCmd = new ReturnHomeCancelReplyCmd(boxSn, result, errorCode);
|
log.debug("取消返航回复: {}", boxSn);
|
break;
|
case 0x14:
|
result = in.readByte();
|
errorCode = in.readInt();
|
uavData = new byte[15];
|
in.readBytes(uavData);
|
boxSn = new String(uavData);
|
baseCmd = new LandReplyCmd(boxSn, result, errorCode);
|
log.debug("降落回复: {}", boxSn);
|
break;
|
case 0x15:
|
result = in.readByte();
|
errorCode = in.readInt();
|
uavData = new byte[15];
|
in.readBytes(uavData);
|
boxSn = new String(uavData);
|
baseCmd = new LandCancelReplyCmd(boxSn, result, errorCode);
|
log.debug("取消降落回复: {}", boxSn);
|
break;
|
case 0x29:
|
result = in.readByte();
|
errorCode = in.readInt();
|
uavData = new byte[15];
|
in.readBytes(uavData);
|
boxSn = new String(uavData);
|
baseCmd = new LandForcedReplyCmd(boxSn, result, errorCode);
|
log.debug("强制降落回复: {}", boxSn);
|
break;
|
case 0x32:
|
result = in.readByte();
|
errorCode = in.readInt();
|
uavData = new byte[15];
|
in.readBytes(uavData);
|
boxSn = new String(uavData);
|
baseCmd = new EmergencyBrakeReplyCmd(boxSn, result, errorCode);
|
log.debug("紧急制动回复: {}", boxSn);
|
break;
|
case 0x39:
|
result = in.readByte();
|
errorCode = in.readInt();
|
uavData = new byte[15];
|
in.readBytes(uavData);
|
boxSn = new String(uavData);
|
baseCmd = new PointControlReachedReplyCmd(boxSn, result, errorCode);
|
log.debug("到达指点飞行位置回复: {}", boxSn);
|
break;
|
case 0x22:
|
result = in.readByte();
|
errorCode = in.readInt();
|
uavData = new byte[15];
|
in.readBytes(uavData);
|
boxSn = new String(uavData);
|
baseCmd = new CameraModeReplyCmd(boxSn, result, errorCode);
|
log.debug("设置相机模式回复: {}", boxSn);
|
break;
|
case 0x23:
|
result = in.readByte();
|
errorCode = in.readInt();
|
uavData = new byte[15];
|
in.readBytes(uavData);
|
boxSn = new String(uavData);
|
baseCmd = new CapturePicReplyCmd(boxSn, result, errorCode);
|
log.debug("拍照回复: {}", boxSn);
|
break;
|
case 0x24:
|
result = in.readByte();
|
errorCode = in.readInt();
|
uavData = new byte[15];
|
in.readBytes(uavData);
|
boxSn = new String(uavData);
|
baseCmd = new RecordStartReplyCmd(boxSn, result, errorCode);
|
log.debug("开始录像回复: {}", boxSn);
|
break;
|
case 0x25:
|
result = in.readByte();
|
errorCode = in.readInt();
|
uavData = new byte[15];
|
in.readBytes(uavData);
|
boxSn = new String(uavData);
|
baseCmd = new RecordStopReplyCmd(boxSn, result, errorCode);
|
log.debug("停止录像回复: {}", boxSn);
|
break;
|
case 0x2E:
|
result = in.readByte();
|
errorCode = in.readInt();
|
uavData = new byte[15];
|
in.readBytes(uavData);
|
boxSn = new String(uavData);
|
baseCmd = new FlyWayEndReplyCmd(boxSn, result, errorCode);
|
log.debug("航线结束通知回复: {}", boxSn);
|
break;
|
case 0x3D:
|
byte batteryPower = in.readByte();
|
double longitude = in.readDouble();
|
double latitude = in.readDouble();
|
int altitude = in.readInt();
|
uavData = new byte[dataLength - 24];
|
in.readBytes(uavData);
|
boxSn = new String(uavData);
|
baseCmd = new UavReadyReplyCmd(boxSn, batteryPower, longitude, latitude, altitude);
|
log.debug("无人机准备完成通知回复: 电池电量 {}", String.format("0x%02X", batteryPower & 0xFF));
|
break;
|
case 0x42:
|
byte[] uavData1 = new byte[dataLength - 18];
|
in.readBytes(uavData1);
|
byte[] uavData2 = new byte[15];
|
in.readBytes(uavData2);
|
boxSn = new String(uavData2);
|
TelemetryDataPB.UavInitInfo uavInitInfo = TelemetryDataPB.UavInitInfo.parseFrom(uavData1);
|
baseCmd = new UavInitReplyCmd(boxSn, uavInitInfo);
|
log.debug("无人机初始化数据: {}", boxSn);
|
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 (baseCmd != null) {
|
out.add(baseCmd);
|
}
|
}
|
}
|