[v0.0.1] 将哈勃原有逻辑和线上版本对齐(不处理地面站的在控无人机更新信息,直接转发数据);哈勃客户端类管理;CacClient channel隐藏并暴露静态channel引用以供哈勃客户端转发数据
parent
e1467baf2b
commit
46bf0a6363
@ -1,65 +0,0 @@
|
||||
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,34 @@
|
||||
package com.platform.service;
|
||||
|
||||
import com.platform.info.enums.ClientTypeEnum;
|
||||
import com.platform.service.clientmanage.BaseClient;
|
||||
import com.platform.service.clientmanage.ClientManager;
|
||||
import com.platform.service.clientmanage.HaborClient;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufUtil;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @Author : shiyi
|
||||
* @Date : 2025/1/15 16:19
|
||||
* @Description : 向中心指控转发遥控遥测
|
||||
*/
|
||||
@ChannelHandler.Sharable @Component @Slf4j
|
||||
public class CacDataRouterHandler extends SimpleChannelInboundHandler<ByteBuf> {
|
||||
@Override
|
||||
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
|
||||
BaseClient client = ClientManager.getClient(ctx.channel());
|
||||
if (client == null || client.getClientType() != ClientTypeEnum.HABOR) {
|
||||
return;
|
||||
}
|
||||
HaborClient haborClient = (HaborClient) client;
|
||||
haborClient.sendToCac(msg);
|
||||
|
||||
log.info("数据({}bytes): {}", msg.readableBytes(), ByteBufUtil.hexDump(msg));
|
||||
// ctx.writeAndFlush(msg);
|
||||
}
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
package com.platform.service.clientmanage;
|
||||
|
||||
|
||||
import com.platform.info.enums.ClientTypeEnum;
|
||||
import io.netty.channel.Channel;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @Author : shiyi
|
||||
* @Date : 2023/12/18 14:51
|
||||
* @Description : 客户端类
|
||||
*/
|
||||
@Slf4j @Getter
|
||||
public abstract class BaseClient {
|
||||
protected Channel channel;
|
||||
protected String sn; // 客户端唯一编号
|
||||
|
||||
protected String ip;
|
||||
protected String port;
|
||||
protected String serverPort;
|
||||
// protected boolean online = false;
|
||||
public BaseClient(String sn, Channel channel) {
|
||||
this.sn = sn;
|
||||
this.channel = channel;
|
||||
InetSocketAddress remoteAddress = (InetSocketAddress) channel.remoteAddress();
|
||||
InetSocketAddress localAddress = (InetSocketAddress) channel.localAddress();
|
||||
ip = remoteAddress.getHostString();
|
||||
port = String.valueOf(remoteAddress.getPort());
|
||||
serverPort = String.valueOf(localAddress.getPort());
|
||||
}
|
||||
|
||||
/**
|
||||
* 报告客户端上线
|
||||
*/
|
||||
public abstract boolean online();
|
||||
|
||||
/**
|
||||
* 报告客户端下线
|
||||
*/
|
||||
public abstract boolean offline();
|
||||
|
||||
|
||||
// public ChannelFuture sendMessage(byte frameType, byte[] data) {
|
||||
// return ClientManager.send(getClientType(), channel, frameType, data);
|
||||
// }
|
||||
|
||||
public abstract ClientTypeEnum getClientType();
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BaseClient{" +
|
||||
"channel=" + channel.id() +
|
||||
", sn='" + sn + '\'' +
|
||||
", ip='" + ip + '\'' +
|
||||
", port=" + port +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
BaseClient that = (BaseClient) o;
|
||||
return Objects.equals(sn, that.sn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(sn);
|
||||
}
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
package com.platform.service.clientmanage;
|
||||
|
||||
|
||||
import com.platform.cac.CacHpApi;
|
||||
import com.platform.info.enums.ClientTypeEnum;
|
||||
import com.platform.info.enums.UavTypeEnum;
|
||||
import com.platform.model.DirectControlUavParam;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.Channel;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
/**
|
||||
* @Author : shiyi
|
||||
* @Date : 2024/9/18 10:38
|
||||
* @Description : 飞控客户端
|
||||
*/
|
||||
@Slf4j @Getter
|
||||
public class HaborClient extends BaseClient{
|
||||
// static HashSet<String> fkSnSet = new HashSet<>();
|
||||
private UavTypeEnum uavType;
|
||||
private byte fkId;
|
||||
private String uavId;
|
||||
|
||||
public HaborClient(String sn, Channel channel) {
|
||||
super(sn, channel);
|
||||
// channel绑定客户端
|
||||
channel.attr(ClientManager.CLIENT_ATTRIBUTE_KEY).setIfAbsent(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean online() {
|
||||
return CacHpApi.uavMasterControlNotify(uavId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean offline() {
|
||||
return CacHpApi.uavPowerOff(uavId);
|
||||
}
|
||||
// @Override
|
||||
// public ChannelFuture sendMessage(byte frameType, byte[] data) {
|
||||
// return channel.writeAndFlush(Unpooled.wrappedBuffer(data));
|
||||
// }
|
||||
|
||||
@Override
|
||||
public ClientTypeEnum getClientType() {
|
||||
return ClientTypeEnum.HABOR;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 发送飞控数据到中心指控
|
||||
* @param srcBuf 原始ByteBuf
|
||||
*/
|
||||
public void sendToCac(ByteBuf srcBuf) {
|
||||
|
||||
}
|
||||
|
||||
private void buildFrameToCac(ByteBuf srcBuf, ByteBuf dstBuf) {
|
||||
// TODO: 2024/9/18: 构建飞控数据帧到中心指控
|
||||
}
|
||||
|
||||
private void queryCacDirectControlUavInfo() {
|
||||
DirectControlUavParam directControlUavParam = CacHpApi.queryCacDirectControlUav(sn);
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue