[v0.0.1] 移植插件的上线、认证、重连功能;增加uavId,fkId,哈勃sn的映射管理;增加HTTP\JSON工具类处理
parent
f016e02e75
commit
e1467baf2b
@ -1,2 +1,3 @@
|
|||||||
/target/
|
/target/
|
||||||
/.idea/
|
/.idea/
|
||||||
|
/log/
|
||||||
|
@ -0,0 +1,107 @@
|
|||||||
|
package com.platform.cac.tcp;
|
||||||
|
|
||||||
|
|
||||||
|
import com.platform.cac.GcsService;
|
||||||
|
import com.platform.cac.tcp.message.dataframe.send.TcpHeartBeatRequest;
|
||||||
|
import com.platform.info.GlobalData;
|
||||||
|
import com.platform.info.enums.GcsTypeEnum;
|
||||||
|
import com.platform.info.enums.RemoteFrameEnum;
|
||||||
|
import io.netty.channel.ChannelHandler;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||||
|
import io.netty.handler.timeout.IdleState;
|
||||||
|
import io.netty.handler.timeout.IdleStateEvent;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author : shiyi
|
||||||
|
* @Date : 2024/1/3 14:14
|
||||||
|
* @Description : 处理连接、断联、重连等逻辑
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
@ChannelHandler.Sharable
|
||||||
|
public class CacConnectionHandler extends ChannelInboundHandlerAdapter {
|
||||||
|
@Resource
|
||||||
|
CacClient cacClient;
|
||||||
|
@Resource
|
||||||
|
GcsService gcsService;
|
||||||
|
|
||||||
|
@Value("${airport.enable:#{false}}")
|
||||||
|
boolean isAirport = false;
|
||||||
|
/**
|
||||||
|
* 建立连接时
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void channelActive(ChannelHandlerContext ctx) throws Exception {
|
||||||
|
InetSocketAddress ipSocket = (InetSocketAddress) ctx.channel().remoteAddress();
|
||||||
|
int port = ipSocket.getPort();
|
||||||
|
String host = ipSocket.getHostString();
|
||||||
|
log.info("与中心指控{}:{}建立tcp连接!", host, port);
|
||||||
|
cacClient.channel = ctx.channel();
|
||||||
|
|
||||||
|
log.info("地面站发送上线请求");
|
||||||
|
if (gcsService.gcsSignInRequest()) {
|
||||||
|
gcsService.gcsAuthRequestToCtrl();
|
||||||
|
}
|
||||||
|
log.debug("connect-channel: {}", ctx.channel());
|
||||||
|
ctx.fireChannelActive();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭连接时
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
|
||||||
|
InetSocketAddress ipSocket = (InetSocketAddress) ctx.channel().remoteAddress();
|
||||||
|
int port = ipSocket.getPort();
|
||||||
|
String host = ipSocket.getHostString();
|
||||||
|
log.error("与中心指控{}:{}连接断开!", host, port);
|
||||||
|
log.info("断线重连......");
|
||||||
|
cacClient.connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 心跳机制
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
|
||||||
|
if (evt instanceof IdleStateEvent) {
|
||||||
|
IdleState state = ((IdleStateEvent) evt).state();
|
||||||
|
if (IdleState.WRITER_IDLE.equals(state)) {
|
||||||
|
//心跳
|
||||||
|
TcpHeartBeatRequest tcpHeartBeatRequest = buildHeatBeatRequest();
|
||||||
|
ctx.channel().writeAndFlush(tcpHeartBeatRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private TcpHeartBeatRequest buildHeatBeatRequest(){
|
||||||
|
TcpHeartBeatRequest tcpHeartBeatRequest = new TcpHeartBeatRequest();
|
||||||
|
tcpHeartBeatRequest.setMagicCode(GlobalData.REMOTE_HEAD);
|
||||||
|
tcpHeartBeatRequest.setVersion(GlobalData.REMOTE_VERSION2);
|
||||||
|
tcpHeartBeatRequest.setSerializationAlgorithm(GlobalData.REMOTE_SER_ALG);
|
||||||
|
tcpHeartBeatRequest.setType(RemoteFrameEnum.HEART_BEAT_REQUEST.getCode());
|
||||||
|
tcpHeartBeatRequest.setGcsIdLength((byte) GlobalData.GCS_ID.getBytes().length);
|
||||||
|
tcpHeartBeatRequest.setGcsId(GlobalData.GCS_ID);
|
||||||
|
tcpHeartBeatRequest.setGcsAuthLength((byte) GlobalData.GCS_TOKEN.getBytes().length);
|
||||||
|
tcpHeartBeatRequest.setGcsAuth(GlobalData.GCS_TOKEN);
|
||||||
|
tcpHeartBeatRequest.setUavIdLength((byte) 0);
|
||||||
|
tcpHeartBeatRequest.setCurrentTime(System.currentTimeMillis());
|
||||||
|
byte[] readableDataBytes = ByteBuffer.allocate(Long.SIZE / Byte.SIZE).putLong(tcpHeartBeatRequest.getCurrentTime()).array();
|
||||||
|
tcpHeartBeatRequest.setReadableDataBytesLength(Long.SIZE / Byte.SIZE);
|
||||||
|
tcpHeartBeatRequest.setReadableDataBytes(readableDataBytes);
|
||||||
|
return tcpHeartBeatRequest;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
package com.platform.cac.tcp.codec;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import com.platform.cac.tcp.message.dataframe.RemoteTcpBaseDataFrame;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.handler.codec.MessageToByteEncoder;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class RemoteTcpBaseDataEncoder extends MessageToByteEncoder<RemoteTcpBaseDataFrame> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void encode(ChannelHandlerContext ctx, RemoteTcpBaseDataFrame dataFrame, ByteBuf buf) {
|
||||||
|
if (dataFrame != null) {
|
||||||
|
buf.writeShort(dataFrame.getMagicCode());
|
||||||
|
buf.writeByte(dataFrame.getVersion());
|
||||||
|
buf.writeByte(dataFrame.getSerializationAlgorithm());
|
||||||
|
buf.writeByte(dataFrame.getType());
|
||||||
|
buf.writeByte(dataFrame.getGcsIdLength());
|
||||||
|
if (dataFrame.getGcsIdLength() > 0) {
|
||||||
|
buf.writeBytes(dataFrame.getGcsId().getBytes(), 0, dataFrame.getGcsIdLength());
|
||||||
|
}
|
||||||
|
buf.writeByte(dataFrame.getGcsAuthLength());
|
||||||
|
if (dataFrame.getGcsAuthLength() > 0) {
|
||||||
|
buf.writeBytes(dataFrame.getGcsAuth().getBytes(), 0, dataFrame.getGcsAuthLength());
|
||||||
|
}
|
||||||
|
buf.writeByte(dataFrame.getUavIdLength());
|
||||||
|
if (dataFrame.getUavIdLength() > 0) {
|
||||||
|
buf.writeBytes(dataFrame.getUavId().getBytes(), 0, dataFrame.getUavIdLength());
|
||||||
|
}
|
||||||
|
if (dataFrame.getReadableDataBytesLength() > 0) {
|
||||||
|
buf.writeBytes(dataFrame.getReadableDataBytes(), 0, dataFrame.getReadableDataBytesLength());
|
||||||
|
}
|
||||||
|
// TODO: 2023/6/13 测试之后记得删除此log
|
||||||
|
// log.debug("[encode]连接({}) 编码了一条消息: {}", ctx.channel().id(), ByteUtils.bytes2HexString(ByteBufUtil.getBytes(buf)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
package com.platform.cac.tcp.message;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import com.platform.cac.tcp.message.handler.IRemoteMessageHandler;
|
||||||
|
import com.platform.info.enums.RemoteFrameEnum;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author sunjipeng
|
||||||
|
* @Date 2023/6/14
|
||||||
|
* @Description 描述
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class RemoteMessageHandlerContainer implements InitializingBean {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消息类型与 IGcsMessageHandler 的映射
|
||||||
|
*/
|
||||||
|
private final Map<RemoteFrameEnum, IRemoteMessageHandler> handlers = new HashMap<>();
|
||||||
|
@Autowired
|
||||||
|
private ApplicationContext applicationContext;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
// 通过 ApplicationContext 获得所有 MessageHandler Bean
|
||||||
|
applicationContext.getBeansOfType(IRemoteMessageHandler.class).values()
|
||||||
|
.forEach(messageHandler -> handlers.put(messageHandler.getFrameType(), messageHandler));
|
||||||
|
log.info("[afterPropertiesSet] IRemoteMessageHandler 数量:{}", handlers.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得类型对应的 IMessageHandler
|
||||||
|
*/
|
||||||
|
public IRemoteMessageHandler getMessageHandler(RemoteFrameEnum remoteFrameEnum) {
|
||||||
|
return handlers.get(remoteFrameEnum);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
package com.platform.cac.tcp.message.dataframe;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class RemoteTcpBaseDataFrame {
|
||||||
|
|
||||||
|
private short magicCode;
|
||||||
|
private byte version;
|
||||||
|
private byte serializationAlgorithm;
|
||||||
|
private byte type;
|
||||||
|
private byte gcsIdLength;
|
||||||
|
private String gcsId;
|
||||||
|
private byte gcsAuthLength;
|
||||||
|
private String gcsAuth;
|
||||||
|
private byte uavIdLength;
|
||||||
|
private String uavId;
|
||||||
|
private int readableDataBytesLength;
|
||||||
|
private byte[] readableDataBytes;
|
||||||
|
|
||||||
|
public RemoteTcpBaseDataFrame() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 属性复制
|
||||||
|
*/
|
||||||
|
public RemoteTcpBaseDataFrame(RemoteTcpBaseDataFrame data) {
|
||||||
|
// 将data的基础属性复制过来
|
||||||
|
this.magicCode = data.getMagicCode();
|
||||||
|
this.version = data.getVersion();
|
||||||
|
this.serializationAlgorithm = data.getSerializationAlgorithm();
|
||||||
|
this.type = data.getType();
|
||||||
|
this.gcsIdLength = data.getGcsIdLength();
|
||||||
|
this.gcsId = data.getGcsId();
|
||||||
|
this.gcsAuthLength = data.getGcsAuthLength();
|
||||||
|
this.gcsAuth = data.getGcsAuth();
|
||||||
|
this.uavIdLength = data.getUavIdLength();
|
||||||
|
this.uavId = data.getUavId();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
package com.platform.cac.tcp.message.dataframe.receive;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import com.platform.cac.tcp.message.dataframe.RemoteTcpBaseDataFrame;
|
||||||
|
import com.platform.util.ByteUtils;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.ToString;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@ToString
|
||||||
|
@Slf4j
|
||||||
|
public class CacReceiveUavControlMessage extends RemoteTcpBaseDataFrame {
|
||||||
|
private byte receiveGcsIdLength;
|
||||||
|
private String receiveGcsId;
|
||||||
|
private byte uavControlAccept;
|
||||||
|
private byte uavControlAppplyIdLength;
|
||||||
|
private String uavControlApplyId;
|
||||||
|
|
||||||
|
public CacReceiveUavControlMessage(RemoteTcpBaseDataFrame data) {
|
||||||
|
super(data);
|
||||||
|
|
||||||
|
ByteBuffer buffer = ByteBuffer.allocate(data.getReadableDataBytesLength()).put(data.getReadableDataBytes());
|
||||||
|
buffer.flip();
|
||||||
|
try {
|
||||||
|
receiveGcsIdLength = buffer.get();
|
||||||
|
receiveGcsId = ByteUtils.getString(buffer, receiveGcsIdLength);
|
||||||
|
|
||||||
|
uavControlAccept = buffer.get();
|
||||||
|
|
||||||
|
uavControlAppplyIdLength = buffer.get();
|
||||||
|
uavControlApplyId = ByteUtils.getString(buffer, uavControlAppplyIdLength);
|
||||||
|
} catch (Exception e){
|
||||||
|
log.error("中心指控-控制权接收数据解析异常");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
package com.platform.cac.tcp.message.dataframe.receive;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import com.platform.cac.tcp.message.dataframe.RemoteTcpBaseDataFrame;
|
||||||
|
import com.platform.util.ByteUtils;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.ToString;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@ToString
|
||||||
|
@Slf4j
|
||||||
|
public class CacReplyUavControlMessage extends RemoteTcpBaseDataFrame {
|
||||||
|
|
||||||
|
private byte replyGcsIdLength;
|
||||||
|
private String replyGcsId;
|
||||||
|
private byte uavControlApprove;
|
||||||
|
private byte uavControlApplyIdLength;
|
||||||
|
private String uavControlApplyId;
|
||||||
|
|
||||||
|
public CacReplyUavControlMessage(RemoteTcpBaseDataFrame data) {
|
||||||
|
super(data);
|
||||||
|
|
||||||
|
ByteBuffer buffer = ByteBuffer.allocate(data.getReadableDataBytesLength()).put(data.getReadableDataBytes());
|
||||||
|
buffer.flip();
|
||||||
|
|
||||||
|
try {
|
||||||
|
replyGcsIdLength = buffer.get();
|
||||||
|
replyGcsId = ByteUtils.getString(buffer, replyGcsIdLength);
|
||||||
|
|
||||||
|
uavControlApprove = buffer.get();
|
||||||
|
|
||||||
|
uavControlApplyIdLength = buffer.get();
|
||||||
|
uavControlApplyId = ByteUtils.getString(buffer, uavControlApplyIdLength);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("中心指控-控制权回复数据解析异常");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
package com.platform.cac.tcp.message.dataframe.receive;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import com.platform.cac.tcp.message.dataframe.RemoteTcpBaseDataFrame;
|
||||||
|
import com.platform.util.ByteUtils;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.ToString;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Getter
|
||||||
|
@ToString
|
||||||
|
public class CacUavCommandMessage extends RemoteTcpBaseDataFrame {
|
||||||
|
|
||||||
|
private byte uavCommandCodeIdLength;
|
||||||
|
private byte[] uavCommandCodeId;
|
||||||
|
private byte uavControlUniIdLength;
|
||||||
|
private String uavControlUniId;
|
||||||
|
|
||||||
|
public CacUavCommandMessage(RemoteTcpBaseDataFrame data){
|
||||||
|
super(data);
|
||||||
|
ByteBuffer buffer = ByteBuffer.allocate(data.getReadableDataBytesLength()).put(data.getReadableDataBytes());
|
||||||
|
buffer.flip();
|
||||||
|
|
||||||
|
try {
|
||||||
|
uavCommandCodeIdLength = buffer.get();
|
||||||
|
uavCommandCodeId = new byte[uavCommandCodeIdLength];
|
||||||
|
buffer.get(uavCommandCodeId);
|
||||||
|
uavControlUniIdLength=buffer.get();
|
||||||
|
uavControlUniId = ByteUtils.getString(buffer, uavControlUniIdLength);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("中心指控-指令数据解析异常");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
package com.platform.cac.tcp.message.dataframe.receive;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import com.platform.cac.tcp.message.dataframe.RemoteTcpBaseDataFrame;
|
||||||
|
import com.platform.util.ByteUtils;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Slf4j
|
||||||
|
public class CacUavControlApplyMessage extends RemoteTcpBaseDataFrame {
|
||||||
|
|
||||||
|
private byte applyGcsIdLength;
|
||||||
|
private String applyGcsId;
|
||||||
|
private byte uavControlApplyReasonLength;
|
||||||
|
private String uavControlApplyReason;
|
||||||
|
private byte uavControlApplyIdLength;
|
||||||
|
private String uavControlApplyId;
|
||||||
|
|
||||||
|
public CacUavControlApplyMessage(RemoteTcpBaseDataFrame data){
|
||||||
|
super(data);
|
||||||
|
ByteBuffer buffer = ByteBuffer.allocate(data.getReadableDataBytesLength()).put(data.getReadableDataBytes());
|
||||||
|
buffer.flip();
|
||||||
|
try {
|
||||||
|
applyGcsIdLength = buffer.get();
|
||||||
|
applyGcsId = ByteUtils.getString(buffer, applyGcsIdLength);
|
||||||
|
|
||||||
|
uavControlApplyReasonLength = buffer.get();
|
||||||
|
uavControlApplyReason = ByteUtils.getString(buffer, uavControlApplyReasonLength);
|
||||||
|
|
||||||
|
uavControlApplyIdLength = buffer.get();
|
||||||
|
uavControlApplyId = ByteUtils.getString(buffer, uavControlApplyIdLength);
|
||||||
|
} catch (Exception e){
|
||||||
|
log.error("中心指控-控制权申请数据解析异常");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package com.platform.cac.tcp.message.dataframe.receive;
|
||||||
|
|
||||||
|
|
||||||
|
import com.platform.cac.tcp.message.dataframe.RemoteTcpBaseDataFrame;
|
||||||
|
import com.platform.util.ByteUtils;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Slf4j
|
||||||
|
public class TcpRemoteAuthorization extends RemoteTcpBaseDataFrame {
|
||||||
|
|
||||||
|
private byte success;
|
||||||
|
private int code;
|
||||||
|
private byte messageLength;
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
public TcpRemoteAuthorization(RemoteTcpBaseDataFrame data) {
|
||||||
|
super(data);
|
||||||
|
ByteBuffer buffer = ByteBuffer.allocate(data.getReadableDataBytesLength()).put(data.getReadableDataBytes());
|
||||||
|
buffer.flip();
|
||||||
|
|
||||||
|
try {
|
||||||
|
success = buffer.get();
|
||||||
|
code = buffer.getInt();
|
||||||
|
|
||||||
|
messageLength = buffer.get();
|
||||||
|
message = ByteUtils.getString(buffer, messageLength);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("中心指控-地面站认证数据解析异常");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package com.platform.cac.tcp.message.dataframe.send;
|
||||||
|
|
||||||
|
|
||||||
|
import com.platform.cac.tcp.message.dataframe.RemoteTcpBaseDataFrame;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author sunjipeng
|
||||||
|
* @Date 2023/6/14
|
||||||
|
* @Description 描述
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class TcpFlightPlanReplyRequest extends RemoteTcpBaseDataFrame {
|
||||||
|
|
||||||
|
private byte applyFlightPlanIdLength;
|
||||||
|
private String applyFlightPlanId;
|
||||||
|
private byte replyFlightPlanIdLength;
|
||||||
|
private String replyFlightPlanId;
|
||||||
|
private byte flightPlanPass;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package com.platform.cac.tcp.message.dataframe.send;
|
||||||
|
|
||||||
|
|
||||||
|
import com.platform.cac.tcp.message.dataframe.RemoteTcpBaseDataFrame;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author sunjipeng
|
||||||
|
* @Date 2023/6/28
|
||||||
|
* @Description 描述
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class TcpFlightPlanRevokeRequest extends RemoteTcpBaseDataFrame {
|
||||||
|
|
||||||
|
private byte applyFlightPlanIdLength;
|
||||||
|
private String applyFlightPlanId;
|
||||||
|
private byte revokeReasonLength;
|
||||||
|
private String revokeReason;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package com.platform.cac.tcp.message.dataframe.send;
|
||||||
|
|
||||||
|
|
||||||
|
import com.platform.cac.tcp.message.dataframe.RemoteTcpBaseDataFrame;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author sunjipeng
|
||||||
|
* @Date 2023/6/14
|
||||||
|
* @Description 描述
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class TcpFlyReplyRequest extends RemoteTcpBaseDataFrame {
|
||||||
|
|
||||||
|
private byte applyFlyIdLength;
|
||||||
|
private String applyFlyId;
|
||||||
|
private byte replyFlyIdLength;
|
||||||
|
private String replyFlyId;
|
||||||
|
private byte flyPass;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package com.platform.cac.tcp.message.dataframe.send;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import com.platform.cac.tcp.message.dataframe.RemoteTcpBaseDataFrame;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author sunjipeng
|
||||||
|
* @Date 2023/6/14
|
||||||
|
* @Description 描述
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class TcpHeartBeatRequest extends RemoteTcpBaseDataFrame {
|
||||||
|
|
||||||
|
long currentTime;
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package com.platform.cac.tcp.message.dataframe.send;
|
||||||
|
|
||||||
|
|
||||||
|
import com.platform.cac.tcp.message.dataframe.RemoteTcpBaseDataFrame;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author sunjipeng
|
||||||
|
* @Date 2023/6/14
|
||||||
|
* @Description 描述
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class TcpReceiveAlarmRequest extends RemoteTcpBaseDataFrame {
|
||||||
|
|
||||||
|
private int alarmLevel;
|
||||||
|
private byte contentLength;
|
||||||
|
private String content;
|
||||||
|
private long effectTime;
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package com.platform.cac.tcp.message.dataframe.send;
|
||||||
|
|
||||||
|
|
||||||
|
import com.platform.cac.tcp.message.dataframe.RemoteTcpBaseDataFrame;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author sunjipeng
|
||||||
|
* @Date 2023/6/14
|
||||||
|
* @Description 描述
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class TcpReceiveAtcRequest extends RemoteTcpBaseDataFrame {
|
||||||
|
|
||||||
|
private int atcType;
|
||||||
|
private long effectTime;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
package com.platform.cac.tcp.message.dataframe.send;
|
||||||
|
|
||||||
|
|
||||||
|
import com.platform.cac.tcp.message.dataframe.RemoteTcpBaseDataFrame;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author sunjipeng
|
||||||
|
* @Date 2023/6/14
|
||||||
|
* @Description 描述
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class TcpRemoteAuthCacRequest extends RemoteTcpBaseDataFrame {
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
package com.platform.cac.tcp.message.handler;
|
||||||
|
|
||||||
|
|
||||||
|
import com.platform.cac.GcsService;
|
||||||
|
import com.platform.cac.tcp.message.dataframe.RemoteTcpBaseDataFrame;
|
||||||
|
import com.platform.cac.tcp.message.dataframe.receive.CacUavCommandMessage;
|
||||||
|
import com.platform.info.enums.GcsFrameEnum;
|
||||||
|
import com.platform.info.enums.RemoteFrameEnum;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
import io.netty.channel.Channel;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author : shiyi
|
||||||
|
* @Date : 2024/1/9 11:28
|
||||||
|
* @Description : 远程中心指控指令下发
|
||||||
|
*/
|
||||||
|
@Component @Slf4j
|
||||||
|
public class CacUavCommandIssuedHandler implements IRemoteMessageHandler {
|
||||||
|
@Resource
|
||||||
|
GcsService gcsService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(Channel channel, RemoteTcpBaseDataFrame remoteTcpBaseDataFrame) {
|
||||||
|
if (gcsService.isSignIn()){
|
||||||
|
CacUavCommandMessage uavCommand = new CacUavCommandMessage(remoteTcpBaseDataFrame);
|
||||||
|
log.info("对地面站下发指令...{}", uavCommand);
|
||||||
|
// GcsService.commandUniId = uavCommand.getUavControlUniId();
|
||||||
|
// log.debug("commandUniId Info: {}", GcsService.commandUniId);
|
||||||
|
// issuedUavCommandToGcs(uavCommand);
|
||||||
|
} else {
|
||||||
|
log.warn("无法下发指令");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 下发指令到地面站
|
||||||
|
* @param uavCommand
|
||||||
|
*/
|
||||||
|
// private void issuedUavCommandToGcs(CacUavCommandMessage uavCommand) {
|
||||||
|
// String uavId = uavCommand.getUavId();
|
||||||
|
// int fkUavId = UavIdMap.getFkId(uavId);
|
||||||
|
//
|
||||||
|
// ByteBuf bufToGcs = Unpooled.buffer();
|
||||||
|
// bufToGcs.writeByte((byte) fkUavId);
|
||||||
|
// bufToGcs.writeByte(uavCommand.getUavCommandCodeIdLength());
|
||||||
|
// bufToGcs.writeBytes(uavCommand.getUavCommandCodeId());
|
||||||
|
// gcsService.sendToGcs(GcsFrameEnum.ISSUED_COMMAND.getCode(), bufToGcs);
|
||||||
|
// }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RemoteFrameEnum getFrameType() {
|
||||||
|
return RemoteFrameEnum.UAV_COMMAND_ISSUED;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
package com.platform.cac.tcp.message.handler;
|
||||||
|
|
||||||
|
|
||||||
|
import com.platform.cac.GcsService;
|
||||||
|
import com.platform.cac.tcp.message.dataframe.RemoteTcpBaseDataFrame;
|
||||||
|
import com.platform.cac.tcp.message.dataframe.receive.CacUavCommandMessage;
|
||||||
|
import com.platform.info.enums.GcsFrameEnum;
|
||||||
|
import com.platform.info.enums.RemoteFrameEnum;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
import io.netty.channel.Channel;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author : shiyi
|
||||||
|
* @Date : 2024/1/24 17:38
|
||||||
|
* @Description : 查询指令是否完成
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class CacUavCommandResultHandler implements IRemoteMessageHandler {
|
||||||
|
@Resource
|
||||||
|
GcsService gcsService;
|
||||||
|
@Override
|
||||||
|
public void execute(Channel channel, RemoteTcpBaseDataFrame remoteTcpBaseDataFrame) {
|
||||||
|
if (gcsService.isSignIn()){
|
||||||
|
CacUavCommandMessage uavCommand = new CacUavCommandMessage(remoteTcpBaseDataFrame);
|
||||||
|
log.debug("向地面站查询指令...{}", uavCommand);
|
||||||
|
|
||||||
|
// GcsService.queryCommandUniId= uavCommand.getUavControlUniId();
|
||||||
|
// log.debug("queryCommandUniId Info: {}", GcsService.queryCommandUniId);
|
||||||
|
queryUavCommandResult(uavCommand);
|
||||||
|
} else {
|
||||||
|
log.warn("无法查询指令");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 向地面站查询指令
|
||||||
|
* @param uavCommand
|
||||||
|
*/
|
||||||
|
private void queryUavCommandResult(CacUavCommandMessage uavCommand) {
|
||||||
|
// String uavId = uavCommand.getUavId();
|
||||||
|
// int fkUavId = UavIdMap.getFkId(uavId);
|
||||||
|
// ByteBuf bufToGcs = Unpooled.buffer();
|
||||||
|
// bufToGcs.writeByte((byte) fkUavId);
|
||||||
|
// bufToGcs.writeByte(uavCommand.getUavCommandCodeIdLength());
|
||||||
|
// bufToGcs.writeBytes(uavCommand.getUavCommandCodeId());
|
||||||
|
// gcsService.sendToGcs(GcsFrameEnum.QUERY_COMMAND.getCode(), bufToGcs);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public RemoteFrameEnum getFrameType() {
|
||||||
|
return RemoteFrameEnum.UAV_COMMAND_QUERY;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
package com.platform.cac.tcp.message.handler;
|
||||||
|
|
||||||
|
|
||||||
|
import com.platform.cac.GcsService;
|
||||||
|
import com.platform.cac.RemoteService;
|
||||||
|
import com.platform.cac.tcp.message.dataframe.RemoteTcpBaseDataFrame;
|
||||||
|
import com.platform.cac.tcp.message.dataframe.receive.TcpRemoteAuthorization;
|
||||||
|
import com.platform.info.GlobalData;
|
||||||
|
import com.platform.info.enums.RemoteFrameEnum;
|
||||||
|
import io.netty.channel.Channel;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author : shiyi
|
||||||
|
* @Date : 2024/1/3 14:11
|
||||||
|
* @Description : 地面站接入校验的回复
|
||||||
|
*/
|
||||||
|
@Component @Slf4j
|
||||||
|
public class GcsAuthResponseHandler implements IRemoteMessageHandler {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
RemoteService remoteService;
|
||||||
|
@Resource
|
||||||
|
GcsService gcsService;
|
||||||
|
@Override
|
||||||
|
public void execute(Channel channel, RemoteTcpBaseDataFrame remoteTcpBaseDataFrame) {
|
||||||
|
TcpRemoteAuthorization authResponse = new TcpRemoteAuthorization(remoteTcpBaseDataFrame);
|
||||||
|
|
||||||
|
GlobalData.GCS_SIGNIN = (0x01==authResponse.getSuccess());
|
||||||
|
if (GlobalData.GCS_SIGNIN){
|
||||||
|
remoteService.queryCacDirectControlMapping(); // 同步操作
|
||||||
|
// List<Integer> controlFkUavList = remoteService.queryGcsControlUav();
|
||||||
|
// log.info("当前在控无人机: {}", remoteService.queryGcsControlUav());
|
||||||
|
}
|
||||||
|
log.info("[tcp auth]认证上线{}, code={}, message: {}", GlobalData.GCS_SIGNIN ? "成功":"失败",authResponse.getCode(), authResponse.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RemoteFrameEnum getFrameType() {
|
||||||
|
return RemoteFrameEnum.GCS_AUTH_CAC_RESPONSE;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package com.platform.cac.tcp.message.handler;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import com.platform.cac.tcp.message.dataframe.RemoteTcpBaseDataFrame;
|
||||||
|
import com.platform.info.enums.RemoteFrameEnum;
|
||||||
|
import io.netty.channel.Channel;
|
||||||
|
|
||||||
|
|
||||||
|
public interface IRemoteMessageHandler {
|
||||||
|
/**
|
||||||
|
* 执行处理消息
|
||||||
|
*
|
||||||
|
* @param channel 通道
|
||||||
|
* @param gcsTcpBaseDataFrame 消息
|
||||||
|
*/
|
||||||
|
void execute(Channel channel, RemoteTcpBaseDataFrame remoteTcpBaseDataFrame);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return 消息类型
|
||||||
|
*/
|
||||||
|
RemoteFrameEnum getFrameType();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package com.platform.config;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Configuration
|
||||||
|
@ConfigurationProperties(prefix = "remote-cac")
|
||||||
|
public class CacRemoteConfig {
|
||||||
|
public String ip;
|
||||||
|
public int remoteTcpPort;
|
||||||
|
public String udpIp;
|
||||||
|
public int remoteUdpPort;
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package com.platform.info.enums;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author : shiyi
|
||||||
|
* @Date : 2024/1/3 9:28
|
||||||
|
* @Description : 帧头枚举
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public enum ClientTypeEnum {
|
||||||
|
//
|
||||||
|
GCS((short) 0xCC06, (short) 0xCC06,"地面站"),
|
||||||
|
AUTO_AIRPORT((short) 0xCC07, (short) 0xCC07,"自动化机场"),
|
||||||
|
;
|
||||||
|
private final short readHead;
|
||||||
|
private final short writeHead;
|
||||||
|
private final String info;
|
||||||
|
|
||||||
|
ClientTypeEnum(short readHead, short writeHead, String info) {
|
||||||
|
|
||||||
|
this.readHead = readHead;
|
||||||
|
this.writeHead = writeHead;
|
||||||
|
this.info = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static ClientTypeEnum getByHead(int head) {
|
||||||
|
for (ClientTypeEnum clientTypeEnum : ClientTypeEnum.values()) {
|
||||||
|
if (clientTypeEnum.getReadHead() == head) {
|
||||||
|
return clientTypeEnum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
package com.platform.info.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author : shiyi
|
||||||
|
* @Date : 2024/1/2 13:46
|
||||||
|
* @Description : 地面站帧类型枚举
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
public enum GcsFrameEnum implements IClientFrameEnum {
|
||||||
|
// 与地面站之间TCP传输的报文类型枚举
|
||||||
|
|
||||||
|
LOGIN((byte) 0x00, "接入校验"),
|
||||||
|
TELEMETRY_DATA_TRANSFER((byte) 0x02, "遥测数据透传"),
|
||||||
|
HEART_BEAT((byte) 0x03, "心跳"),
|
||||||
|
CONTROL_APPLY((byte) 0x04, "控制权申请,运管在控无人机更新"),
|
||||||
|
CONTROL_FREE((byte) 0x0A, "控制权释放"),
|
||||||
|
CONTROL_ISSUE((byte) 0x0B, "控制权下发"),
|
||||||
|
CONTROL_RECEIVE((byte) 0x0C, "控制权接收"),
|
||||||
|
ISSUED_COMMAND((byte) 0x05, "通知指令下发"),
|
||||||
|
RECONNECT((byte) 0x06, "地面站重连"),
|
||||||
|
SNAPSHOT((byte) 0x07, "发送地面站快照"),
|
||||||
|
SIGN_IN((byte) 0x08, "连接中心指控"),
|
||||||
|
SIGN_OUT((byte) 0x09, "断开中心指控"),
|
||||||
|
COMMAND_NOTIFY((byte) 0x0D, "遥控指令回报"),
|
||||||
|
UPDATE_UAV_CONTROL((byte) 0x0E, "中心指控在控无人机更新"),
|
||||||
|
QUERY_COMMAND((byte) 0x20, "查询指令是否完成"),
|
||||||
|
UAV_MASTER_CONTROL((byte) 0x21, "地面站主控通知"),
|
||||||
|
UPDATE_REMOTE_CONTROL_STATE((byte) 0x22, "远程控制状态"),
|
||||||
|
QUERY_REMOTE_CONTROL_STATE_REPLY((byte) 0x23, "查询远程控制状态"),
|
||||||
|
STREAM_PUSH((byte) 0x32, "视频流推送"),
|
||||||
|
;
|
||||||
|
|
||||||
|
private final byte code;
|
||||||
|
private final String info;
|
||||||
|
|
||||||
|
GcsFrameEnum(byte code, String info) {
|
||||||
|
this.code = code;
|
||||||
|
this.info = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getInfo() {
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GcsFrameEnum getByCode(byte frameCode) {
|
||||||
|
for (GcsFrameEnum enums : GcsFrameEnum.values()) {
|
||||||
|
if (enums.code == frameCode) {
|
||||||
|
return enums;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClientTypeEnum getClientEnum() {
|
||||||
|
return ClientTypeEnum.GCS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,41 @@
|
|||||||
|
package com.platform.info.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author : shiyi
|
||||||
|
* @Date : 2024/2/17 16:36
|
||||||
|
* @Description : 地面站类型枚举
|
||||||
|
*/
|
||||||
|
public enum GcsTypeEnum {
|
||||||
|
// 地面站类型枚举
|
||||||
|
REMOTE_GCS(0, "远程地面站"),
|
||||||
|
BOX_GCS(1, "箱式地面站"),
|
||||||
|
HANDHELD_GCS(2, "手持地面站"),
|
||||||
|
CARBIN_GCS(3, "方舱地面站"),
|
||||||
|
AIRPORT_GCS(4,"机场型地面站"),
|
||||||
|
;
|
||||||
|
|
||||||
|
private final int code;
|
||||||
|
private final String info;
|
||||||
|
|
||||||
|
GcsTypeEnum(int code, String info) {
|
||||||
|
this.code = code;
|
||||||
|
this.info = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getInfo() {
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GcsTypeEnum getTypeByCode(Integer code) {
|
||||||
|
for (GcsTypeEnum enums : GcsTypeEnum.values()) {
|
||||||
|
if (enums.getCode() == code) {
|
||||||
|
return enums;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.platform.info.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author : shiyi
|
||||||
|
* @Date : 2023/12/28 12:02
|
||||||
|
* @Description :
|
||||||
|
*/
|
||||||
|
public interface IClientFrameEnum {
|
||||||
|
public ClientTypeEnum getClientEnum();
|
||||||
|
}
|
@ -0,0 +1,71 @@
|
|||||||
|
package com.platform.info.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author : shiyi
|
||||||
|
* @Date : 2024/1/2 13:46
|
||||||
|
* @Description : 运管和中心指控帧类型枚举
|
||||||
|
*/
|
||||||
|
|
||||||
|
public enum RemoteFrameEnum {
|
||||||
|
// 运管
|
||||||
|
GCS_AUTH_CAC_REQUEST((byte) 0x01, "地面站接入数据路由认证请求"),
|
||||||
|
GCS_AUTH_CAC_RESPONSE((byte)0x02, "地面站接入数据路由认证响应"),
|
||||||
|
HEART_BEAT_REQUEST((byte) 0x03, "心跳请求"),
|
||||||
|
HEART_BEAT_RESPONSE((byte) 0x04, "心跳响应"),
|
||||||
|
FLIGHT_PLAN_REPLY_REQUEST((byte) 0x05, "飞行计划审批结果通知"),
|
||||||
|
FLIGHT_PLAN_REPLY_RESPONSE((byte) 0x06, "飞行计划审批结果响应"),
|
||||||
|
FLY_REPLY_REQUEST((byte) 0x07, "放飞申请结果通知"),
|
||||||
|
FLY_REPLY_RESPONSE((byte) 0x08, "放飞申请结果响应"),
|
||||||
|
RECEIVE_ALARM_REQUEST((byte) 0x09, "告警信息"),
|
||||||
|
RECEIVE_ALARM_RESPONSE((byte) 0x0A, "告警信息接收响应"),
|
||||||
|
RECEIVE_ATC_REQUEST( (byte) 0x0B, "管制指令通知"),
|
||||||
|
RECEIVE_ATC_RESPONSE((byte) 0x0C, "管制指令接收响应"),
|
||||||
|
FLIGHT_PLAN_REVOKE_REQUEST((byte) 0x0D, "飞行计划撤销通知"),
|
||||||
|
FLIGHT_PLAN_REVOKE_RESPONSE((byte) 0x0E, "飞行计划撤销响应"),
|
||||||
|
UAV_TELEMETRY_DATA_TRANSFER((byte) 0x0F, "无人机遥测数据透传"),
|
||||||
|
AIRSPACE_REPLY_REQUEST((byte) 0x1A, "空域申请结果通知"),
|
||||||
|
AIRSPACE_REPLY_RESPONSE((byte) 0x1B, "空域申请结果收到响应"),
|
||||||
|
// 中心指控
|
||||||
|
UAV_CONTROL_APPLY((byte) 0x10, "申请无人机控制权"),
|
||||||
|
UAV_CONTROL_REPLY((byte) 0x11, "回复无人机控制权"),
|
||||||
|
UAV_CONTROL_RECEIVE((byte) 0x12, "接收无人机控制权"),
|
||||||
|
UAV_COMMAND_ISSUED((byte) 0x13, "无人机控制指令下发"),
|
||||||
|
UAV_COMMAND_QUERY((byte) 0x14, "无人机控制指令查询"),
|
||||||
|
|
||||||
|
// 自动化机场
|
||||||
|
AIRPORT_COMMAND_ISSUED((byte) 0x15, "机场指令下发"),
|
||||||
|
AIRPORT_COMMAND_QUERY((byte) 0x16, "机场指令查询"),
|
||||||
|
AIRPORT_STATUS_QUERY((byte) 0x17, "机场状态查询"),
|
||||||
|
AIRPORT_STATE_OF_CHARGE_QUERY((byte)0x18, "电格电量查询"),
|
||||||
|
AIRPORT_CONTAINER_STATUS_QUERY((byte)0x19, "货格状态查询"),
|
||||||
|
|
||||||
|
// 推流地址
|
||||||
|
STREAM_PUSH((byte) 0x21, "推流地址");
|
||||||
|
|
||||||
|
;
|
||||||
|
private final byte code;
|
||||||
|
private final String info;
|
||||||
|
public byte getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getInfo() {
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RemoteFrameEnum(byte code, String info) {
|
||||||
|
this.code = code;
|
||||||
|
this.info = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RemoteFrameEnum getByCode(byte frameCode) {
|
||||||
|
for (RemoteFrameEnum enums : RemoteFrameEnum.values()) {
|
||||||
|
if (enums.code == frameCode) {
|
||||||
|
return enums;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
package com.platform.info.enums;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author : shiyi
|
||||||
|
* @Date : 2024/1/9 9:27
|
||||||
|
* @Description : 无人机类型枚举
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public enum UavTypeEnum {
|
||||||
|
//
|
||||||
|
FP981A (0x01, 1,"981A", false),
|
||||||
|
FP981C (0x02, 2,"981C", false),
|
||||||
|
FP98 (0x04, 4,"98", true),
|
||||||
|
FP985 (0x08, 8,"985", true),
|
||||||
|
FP981CS (0x10, 16,"981CS", true),
|
||||||
|
FH981CH (0x20, 32,"981CH", true),
|
||||||
|
// 此后的编码和中心指控编码区分开
|
||||||
|
FH981CH_HYBRID (0x21, 64,"981CH-二代机混动", false),
|
||||||
|
FH981CH_ELECTRIC (0x22, 128,"981CH-二代机电动", false),
|
||||||
|
;
|
||||||
|
private final int gcsCode;
|
||||||
|
private final int remoteCode;
|
||||||
|
private final String info;
|
||||||
|
private final boolean onlyMonitor; // 仅具有监视功能,但不控制
|
||||||
|
|
||||||
|
UavTypeEnum(int code, int remoteCode, String info, boolean onlyMonitor) {
|
||||||
|
this.gcsCode = code;
|
||||||
|
this.remoteCode = remoteCode;
|
||||||
|
this.info = info;
|
||||||
|
this.onlyMonitor = onlyMonitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getGcsCode() {
|
||||||
|
return gcsCode;
|
||||||
|
}
|
||||||
|
public int getRemoteCode() {
|
||||||
|
return remoteCode;
|
||||||
|
}
|
||||||
|
public String getInfo() {
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
public boolean isOnlyMonitor() {
|
||||||
|
return onlyMonitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return this.info;
|
||||||
|
}
|
||||||
|
public static UavTypeEnum getByGcsCode(int code) {
|
||||||
|
for (UavTypeEnum typeEnum : UavTypeEnum.values()) {
|
||||||
|
if (typeEnum.getGcsCode() == code) {
|
||||||
|
return typeEnum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public static UavTypeEnum getByRemoteCode(int code) {
|
||||||
|
for (UavTypeEnum typeEnum : UavTypeEnum.values()) {
|
||||||
|
if (typeEnum.getRemoteCode() == code) {
|
||||||
|
return typeEnum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package com.platform.model;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class DirectControlUavParam {
|
||||||
|
String harborSn;
|
||||||
|
String flightControlSn;
|
||||||
|
String uavId;
|
||||||
|
Integer uavType;
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package com.platform.model;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author : shiyi
|
||||||
|
* @Date : 2024/2/18 9:16
|
||||||
|
* @Description : HTTP统一响应结果
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class Result<T> {
|
||||||
|
boolean success;
|
||||||
|
String message;
|
||||||
|
Integer code;
|
||||||
|
T data;
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
package com.platform.util;
|
||||||
|
|
||||||
|
import org.apache.tomcat.util.codec.binary.Base64;
|
||||||
|
|
||||||
|
import javax.crypto.Mac;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
public class BaseAuthorizationUtils {
|
||||||
|
|
||||||
|
public static void generateAuthAndDateHeader(Map<String, String> header, String method, String gcsId, String token, String uri) {
|
||||||
|
Date sysdate = new Date();
|
||||||
|
SimpleDateFormat df = new SimpleDateFormat("EEE\', \'dd\' \'MMM\' \'yyyy\' \'HH:mm:ss\' \'z", Locale.US);
|
||||||
|
df.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||||
|
String date = df.format(sysdate);
|
||||||
|
header.put("authorization", generateAuth(method, date, gcsId, token, uri));
|
||||||
|
header.put("gcsId", gcsId);
|
||||||
|
header.put("date", date);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String generateAuth(String method, String date, String gcsId, String token, String uri){
|
||||||
|
String string_to_sign = method.toUpperCase() + " " + uri + "\n" + date;
|
||||||
|
String sig = token;
|
||||||
|
String encoding = "";
|
||||||
|
|
||||||
|
try {
|
||||||
|
byte[] signature = getSignature(string_to_sign.getBytes(), sig.getBytes());
|
||||||
|
encoding = new String(Base64.encodeBase64(signature));
|
||||||
|
} catch (Exception var10) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return gcsId + ":" + encoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] getSignature(byte[] data, byte[] key) throws NoSuchAlgorithmException, InvalidKeyException {
|
||||||
|
SecretKeySpec signingKey = new SecretKeySpec(key, "HmacSHA1");
|
||||||
|
Mac mac = Mac.getInstance("HmacSHA1");
|
||||||
|
mac.init(signingKey);
|
||||||
|
byte[] rawHmac = mac.doFinal(data);
|
||||||
|
return rawHmac;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue