[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