Commit dcb9ce75 authored by p x's avatar p x
Browse files

first

parent 009a6d77
Pipeline #3092 canceled with stages
package com.cusc.adas.v2x.dto;
import com.cusc.adas.v2x.utils.Order;
//轨迹点
public class TracePointDto {
//期望经度
@Order(1)
private double expLongitude;
//期望纬度
@Order(2)
private double expLatitude;
//期望速度
@Order(3)
private float expSpeed;
//期望加速度
@Order(4)
private float expAcceleration;
//期望航向角
@Order(5)
private double expHeading;
}
package com.cusc.adas.v2x.dto;
public class VehicleBodyDto {
private VehicleInfoDto vehicleInfo;
}
package com.cusc.adas.v2x.dto;
import java.util.List;
import com.cusc.adas.v2x.utils.FieldDef;
import com.cusc.adas.v2x.utils.NumFlag;
import com.cusc.adas.v2x.utils.Order;
import com.cusc.adas.v2x.utils.RefNumFlag;
/**
* 车辆基础信息
* @author huangml
*
*/
public class VehicleInfoDto {
//车辆编号
@Order(1)
@FieldDef(type="BYTE",isArray=true,length=8)
private String vehicleId;
//消息编号
@Order(2)
@FieldDef(type="BYTE",isArray=true,length=8)
private long messageId;
//GNSS 时间戳
@Order(3)
@FieldDef(type="TIMESTAMP",isArray=false,length=8)
private long timestampGNSS;
//GNSS 速度
@Order(4)
private float velocityGNSS;
//位置
@Order(5)
private PositionDto position;
//航向角
@Order(6)
private double heading;
//档位
@Order(7)
private short tapPos ;
//方向盘转角
@Order(8)
private double steeringAngle;
//当前车速
@Order(9)
private float velocity;
//纵向加速度
@Order(10)
private float accelerationLon;
//横向加速度
@Order(11)
private float accelerationLat;
//垂向加速度
@Order(12)
private float accelerationVer;
//横摆角速度
@Order(13)
private float yawRate;
//油门开度
@Order(14)
private float accelPos;
//发动机输出转速
@Order(15)
private float engineSpeed;
//发动机扭矩
@Order(16)
private double engineTorque;
//制动踏板开关
@Order(17)
private short brakeFlag;
//制动踏板开度
@Order(18)
private float brakePos;
//制动主缸压力
@Order(19)
private int brakePressure;
//油耗
@Order(20)
private float fuelConsumption;
//车辆驾驶模式
@Order(21)
private short driveMode;
//目的地位置
@Order(22)
private Position2DDto destLocation;
//途经点数量
@Order(23)
@NumFlag
private short passPointsNum;
//途经点
@Order(24)
@RefNumFlag(value="passPointsNum")
private List<Position2DDto> passPoints;
}
package com.cusc.adas.v2x.server;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
public class NettyUdpServer {
private final int port;
public NettyUdpServer(int port) {
this.port = port; // server port
}
public void start() throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 128)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new NettyUdpServerHandler()); // channel to handler
}
});
ChannelFuture f = b.bind(port).sync();
System.out.println("Server started on port " + port);
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
public static void main(String[] args) throws Exception {
int port = 8082;
NettyUdpServer server = new NettyUdpServer(port);
server.start();
}
}
package com.cusc.adas.v2x.server;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;
public class NettyUdpServerHandler extends ChannelInboundHandlerAdapter {
/**
* 读取数据实际(这里我们可以读取客户端发送的消息)
* @param ctx 上下文对象
* @param msg 客户端发送的数据
* @throws Exception
*/
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println("server ctx =" + ctx);
Channel channel = ctx.channel();
// 将 msg 转成一个 ByteBuf
// ByteBuf 是 Netty 提供的,不是 NIO 的 ByteBuffer.
ByteBuf buf = (ByteBuf) msg;
System.out.println("客户端发送的消息是: " + buf.toString(CharsetUtil.UTF_8));
System.out.println("客户端地址: " + channel.remoteAddress());
}
/**
* 读取完毕,回复
* @param ctx
* @throws Exception
*/
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
// writeAndFlush 是 write + flush 将数据写入到缓存,并刷新
ctx.writeAndFlush(Unpooled.copiedBuffer("Hello, Client!", CharsetUtil.UTF_8));
}
/**
* 处理异常, 一般是需要关闭通道
* @param ctx
* @param cause
* @throws Exception
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.close();
}
}
package com.cusc.adas.v2x.server;
import java.net.InetSocketAddress;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.DatagramChannel;
import io.netty.channel.socket.nio.NioDatagramChannel;
public class UdpServer {
private final int port;
public UdpServer(int port) {
this.port = port;
}
// public void start() throws Exception {
// EventLoopGroup group = new NioEventLoopGroup();
//
// try {
// Bootstrap b = new Bootstrap();
// b.group(group)
// .channel(NioDatagramChannel.class)
// .handler(new ChannelInitializer<DatagramChannel>() {
// @Override
// protected void initChannel(DatagramChannel ch) throws Exception {
// ch.pipeline().addLast(null);
// }
// });
//
// ChannelFuture f = b.bind(port).sync();
// System.out.println("Server started on port " + port);
// f.channel().closeFuture().sync();
// } finally {
// group.shutdownGracefully();
// }
// }
public void run() throws Exception {
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group)
.channel(NioDatagramChannel.class)
.option(ChannelOption.SO_BROADCAST, true)
.localAddress(new InetSocketAddress(port))
.handler(new ChannelInitializer<DatagramChannel>() {
// @Override
// protected void initChannel(DatagramChannel ch) {
// ch.pipeline().addLast(new SimpleChannelInboundHandler<DatagramPacket>() {
// @Override
// protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) {
// byte[] data = new byte[msg.readableBytes()];
// msg.readBytes(data);
// String received = new String(data).trim();
// System.out.println("Server received: " + received);
// ByteBuf response = Unpooled.copiedBuffer("Echo: " + received, CharsetUtil.UTF_8);
// ctx.writeAndFlush(response); // Echo the received message back to the client
// }
// });
// }
@Override
protected void initChannel(DatagramChannel ch) {
ch.pipeline().addLast(new UdpServerHandler());
}
});
ChannelFuture f = b .bind().sync(); // Bind and start to accept incoming connections.
System.out.println("UDP server started on port " + port);
f.channel().closeFuture().await(); // Wait until the server socket is closed.
} finally {
group.shutdownGracefully(); // Shut down all event loops to terminate all threads and release all resources.
}
}
public static void main(String[] args) throws Exception {
new UdpServer(8082).run(); // Start the server on port 8080
}
}
package com.cusc.adas.v2x.server;
import com.cusc.adas.v2x.dto.VehicleBodyDto;
import com.cusc.adas.v2x.utils.Parse;
import com.cusc.adas.v2x.vo.VehicleMessage;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket;
import io.netty.util.CharsetUtil;
public class UdpServerHandler extends SimpleChannelInboundHandler<DatagramPacket> {
//public static final Logger log = Logger.getLogger(UdpServerHandler.class);
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
//log.info("UDP通道已经连接");
System.out.println("UDP通道已经连接");
super.channelActive(ctx);
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception {
// 处理接收到的数据包,例如打印消息内容或回复客户端等。
// ByteBuf buf = (ByteBuf) msg;
// String message = packet.content().toString();
// byte[] req = new byte[buf.readableBytes()];
ByteBuf buf = (ByteBuf) packet.copy().content();
byte[] req = new byte[buf.readableBytes()];
buf.readBytes(req);
String body = new String(req, CharsetUtil.UTF_8);
String hexString = Parse.byteToHexString(req);
// byte[] bytes = HexStringToByteArray.hexStringToByteArray(body);
if(hexString.substring(10,12).equals("15")) {
ByteBuf byteBuf = Unpooled.wrappedBuffer(req);
VehicleMessage vehicleMessage = Parse.parse(byteBuf,new VehicleMessage());
System.out.println("Received message: " + vehicleMessage);
VehicleBodyDto vehicleBodyDto = new VehicleBodyDto();
Parse.convoterBean(vehicleMessage.getVehicleMessageBody(), vehicleBodyDto);
System.out.println("Received message: " + vehicleBodyDto);
}
// 回复客户端消息(可选)
// ctx.writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer("Response", io.netty.util.CharsetUtil.UTF_8), packet.sender()));
}
}
package com.cusc.adas.v2x.utils;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME) // 注解在运行时可用
@Target(ElementType.FIELD) // 注解只能用于字段(属性)
public @interface FieldDef {
int length() default 1;
String type();
boolean isArray()default false;
boolean isAutoLength() default false ;
}
package com.cusc.adas.v2x.utils;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
public class GenericTypeUtil {
public static Class<?> getListGenericType(Class<?> clazz, String fieldName)
throws NoSuchFieldException {
Field field = clazz.getDeclaredField(fieldName);
Type genericType = field.getGenericType();
if (genericType instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) genericType;
Type[] actualTypes = pt.getActualTypeArguments();
if (actualTypes.length > 0) {
return (Class<?>) actualTypes[0];
}
}
return Object.class;
}
}
package com.cusc.adas.v2x.utils;
public class HexStringToByteArray {
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i + 1), 16));
}
return data;
}
}
package com.cusc.adas.v2x.utils;
import java.net.URISyntaxException;
import java.util.UUID;
import org.fusesource.hawtbuf.Buffer;
import org.fusesource.mqtt.client.Future;
import org.fusesource.mqtt.client.FutureConnection;
import org.fusesource.mqtt.client.MQTT;
import org.fusesource.mqtt.client.Message;
import org.fusesource.mqtt.client.QoS;
import org.fusesource.mqtt.client.Topic;
import com.alibaba.fastjson.JSONObject;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
public class MQTTFutureClient {
private final static String CONNECTION_STRING = "tcp://172.29.128.39:32024";// MQTT服务器主机地址
private final static boolean CLEAN_START = true;
private final static short KEEP_ALIVE = 30;// 低耗网络,但是又需要及时获取数据,心跳30s
public final static long RECONNECTION_ATTEMPT_MAX = 6;
public final static long RECONNECTION_DELAY = 2000;
public final static int SEND_BUFFER_SIZE = 2 * 1024 * 1024;// 发送最大缓冲为2M
public String MQTTFutureClientPublic(JSONObject jsBodyParameter) {
// 定义变量
String jsonStr = "";
// 创建MQTT对象
MQTT mqtt = new MQTT();
try {
String CLIENT_ID = UUID.randomUUID().toString().replace("-", "");// 自动生成的MQTT Client Id
// 设置mqtt broker的ip和端口
mqtt.setHost(CONNECTION_STRING);
// 连接前清空会话信息
mqtt.setCleanSession(CLEAN_START);
// 设置重新连接的次数
mqtt.setReconnectAttemptsMax(RECONNECTION_ATTEMPT_MAX);
// 设置重连的间隔时间
mqtt.setReconnectDelay(RECONNECTION_DELAY);
// 设置心跳时间
mqtt.setKeepAlive(KEEP_ALIVE);
// 设置缓冲的大小
mqtt.setSendBufferSize(SEND_BUFFER_SIZE);
// 设置客户端id、用户名和密码
mqtt.setClientId(CLIENT_ID);
mqtt.setUserName("admin");
mqtt.setPassword("password");
// 获取mqtt的连接对象BlockingConnection
final FutureConnection connection = mqtt.futureConnection();
connection.connect();
Topic[] subscribeTopics = { new Topic("mqtt/face/1376464/Ack", QoS.AT_LEAST_ONCE) };// 订阅主题
connection.subscribe(subscribeTopics);
String publishTopic = "mqtt/face/1376464";// 发布主题
connection.publish(publishTopic, jsBodyParameter.toString().getBytes("UTF-8"), QoS.AT_LEAST_ONCE, false);
Future<Message> futrueMessage = connection.receive();
Message message = futrueMessage.await();
byte[] bs = message.getPayload();
Buffer buffer = message.getPayloadBuffer();
ByteBuf wrappedBuf = Unpooled.wrappedBuffer(bs);
System.out.println(message.getPayloadBuffer());// 打印订阅的消息
String msg = String.valueOf(message.getPayloadBuffer());
jsonStr = msg;
} catch (URISyntaxException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
}
return jsonStr;
}
/*
* service层调用函数,jsBodyParameter为传入的需要发布的参数
*/
public static String writeToMqttMessageFuture(JSONObject jsBodyParameter) throws Exception {
MQTTFutureClient mqttFutureClient = new MQTTFutureClient();
String messageJosn = mqttFutureClient.MQTTFutureClientPublic(jsBodyParameter);
return messageJosn;
}
public static void main(String[] args) throws Exception {
JSONObject jsBodyParameter = new JSONObject();// 定义发布参数变量
jsBodyParameter.put("keyId", "你好!");// 设置参数值
String response = writeToMqttMessageFuture(jsBodyParameter);
System.out.println(response);// 打印订阅的消息
}
}
package com.cusc.adas.v2x.utils;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
public class MqttSubscriber {
private static final String BROKER = "tcp://172.29.128.39:31883";
private static final String CLIENT_ID = "JavaSubscriber";
private static final String TOPIC = "vehicle/{vehicleId}/status";
public static void main(String[] args) {
try {
MqttClient client = new MqttClient(BROKER, CLIENT_ID);
MqttConnectOptions options = new MqttConnectOptions();
options.setCleanSession(true);
client.connect(options);
System.out.println("Connected to broker: " + BROKER);
client.subscribe(TOPIC, (topic, message) -> {
System.out.println("Received message: " + new String(message.getPayload()) + " from topic: " + topic);
});
} catch (MqttException e) {
e.printStackTrace();
}
}
}
package com.cusc.adas.v2x.utils;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME) // 注解在运行时可用
@Target(ElementType.FIELD) // 注解只能用于字段(属性)
public @interface NumFlag {
// 定义注解的属性
String value() default ""; // 默认值
}
package com.cusc.adas.v2x.utils;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME) // 注解在运行时可用
@Target(ElementType.FIELD) // 注解只能用于字段(属性)
public @interface OffsetDef {
double value() default 1;
int type() default 1; //1:除法 2:乘法;
int minValidLength() default 0;
}
package com.cusc.adas.v2x.utils;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME) // 注解在运行时可用
@Target(ElementType.FIELD) // 注解只能用于字段(属性)
public @interface Order {
int value(); // 定义一个名为value的属性,用于存储序号
}
package com.cusc.adas.v2x.utils;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
public class Parse {
public static <T> T parse(ByteBuf data, T t) throws InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException, ClassNotFoundException {
Field [] fields = t.getClass().getDeclaredFields();
List<Field> fList = new ArrayList<>();
SortedMap<Integer,Field> rstMap = new TreeMap<>();
for(Field field : fields) {
field.setAccessible(true);
if (field.isAnnotationPresent(Order.class)) {
String fieldName = field.getName();
Order order = field.getAnnotation(Order.class);
int num = order.value();
//基础数据类型 且 不是数组
if(field.getType().isPrimitive() && !field.getType().isArray() ) {
// data.re
// field.set(fList, rstMap);
readBuf(t,field,data);
}else if(field.getClass().isPrimitive() && field.getType().isArray()){
// 基础数据类型 且 是数组
}else if(List.class.isAssignableFrom(field.getType())) {
// 集合类型
//读取属性的注解是否引用其他字段的长度
if( field.isAnnotationPresent(RefNumFlag.class)) {
RefNumFlag refNumFlag = field.getAnnotation(RefNumFlag.class);
String refField = refNumFlag.value();
Class<?> clazz1 = t.getClass();
Field nameField = clazz1.getDeclaredField(refField);
Type genericType = nameField.getGenericType();
nameField.setAccessible(true);
if (genericType instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) genericType;
Type[] actualTypes = pt.getActualTypeArguments();
if (actualTypes.length > 0) {
actualTypes[0].getClass();
int len= (int) nameField.get(t);
for(int i=0;i<len;i++) {
actualTypes[0].getClass();
}
}
}
}
}else if(field.getType()==String.class) {
//类型为字符串
readBuf(t,field,data);
}else {
//其他对象类型
Class<?> cls = Class.forName(field.getType().getName());
Object obj = cls.newInstance();
parse(data, obj);
field.set(t, obj);
}
rstMap.put(num,field);
}
}
return t;
}
/**
* 读取字节流
* @param t
* @param field
* @param data
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
public static void readBuf(Object t, Field field,ByteBuf data ) throws IllegalArgumentException, IllegalAccessException {
if(data.readerIndex()==data.maxCapacity() )
return ;
FieldDef fieldDef =null;
if(field.isAnnotationPresent(FieldDef.class)) {
fieldDef = field.getAnnotation(FieldDef.class);
}
Class<?> type = field.getType();
if(type==String.class && fieldDef!=null &&fieldDef.type().equals("BYTE")) {
byte[]by = new byte[fieldDef.length()];
data.readBytes(by);
String str = new String(by, StandardCharsets.UTF_8);
field.set(t, str);
}else if(type==short.class) {
field.set(t, data.readUnsignedByte());
}else if(type==int.class) {
field.set(t, data.readUnsignedShort());
}else if(type==long.class && fieldDef==null ) {
field.set(t, data.readUnsignedInt());
}else if(type==long.class && fieldDef!=null &&fieldDef.type().equals("TIMESTAMP") && fieldDef.length()==8 ) {
field.set(t, data.readLong());
}else if(type==long.class && fieldDef!=null &&fieldDef.type().equals("BYTE") ) {
field.set(t, data.readLong());
}
}
public static byte[] longToBytes(long value) {
ByteBuffer buffer = ByteBuffer.allocate(8);
buffer.order(ByteOrder.BIG_ENDIAN); // 指定小端模式
buffer.putLong(value); // 将long值存入buffer
return buffer.array(); // 获取byte数组
}
public static byte[] longToBytes1(long value) {
ByteBuffer buffer = ByteBuffer.allocate(4);
buffer.order(ByteOrder.BIG_ENDIAN); // 指定小端模式
buffer.putLong(value); // 将long值存入buffer
return buffer.array(); // 获取byte数组
}
public static byte[] intToBytes(int value) {
ByteBuffer buffer = ByteBuffer.allocate(4);
buffer.order(ByteOrder.BIG_ENDIAN); // 指定小端模式
buffer.putLong(value); // 将long值存入buffer
return buffer.array(); // 获取byte数组
}
public static String byteToHexString(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02x", b));
}
return sb.toString();
//return null;
// ByteBuffer buffer = ByteBuffer.allocate(8);
// buffer.order(ByteOrder.LITTLE_ENDIAN); // 指定小端模式
// buffer.putLong(value); // 将long值存入buffer
// return buffer.array(); // 获取byte数组
}
public static String long2Hex(long num, int len) {
String hex = Long.toHexString(num);
int padLength = len * 2;
if (hex.length() >= padLength) {
return hex.substring(hex.length() - padLength); // 超长时截断
}
return String.format("%0" + padLength + "d", 0).replace("0", "0") + hex; // 或直接格式化
}
public static void main(String [] args) throws InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException, ClassNotFoundException {
String hexString = "F20000000015018cb864640000000000";
byte[] bytes = HexStringToByteArray.hexStringToByteArray(hexString);
ByteBuf byteBuf = Unpooled.buffer(16);
long l = 500000;
//3600000000
// 1164916946
// byte [] bs = Long.toHexString(l);
String s = long2Hex(l,4);
//longToBytes1(l);
int i = 990;
String hex = Integer.toHexString(i);
String vid = "T1023459";
byte[] by1 = vid.getBytes();
s = byteToHexString(by1);
System.out.println(s);
//
//
// List<Byte> byteList = new ArrayList<Byte>();
//
// Byte[] bytes = byteList.toArray(new Byte[byteList.size()]);
//byte[] bs = convoter(bytes);
//byteBuf.writeBytes(bytes);
//VehicleMessage vehicleMessage = parse(byteBuf,new VehicleMessage());
//System.out.print(vehicleMessage);
}
public static void convoterBean( Object source , Object target) throws IllegalArgumentException, IllegalAccessException, ClassNotFoundException, InstantiationException, NoSuchFieldException, SecurityException {
Field [] fields = source.getClass().getDeclaredFields();
List<Field> fList = new ArrayList<>();
SortedMap<Integer,Field> rstMap = new TreeMap<>();
for(Field field : fields) {
field.setAccessible(true);
Object o= field.get(source);
if(o==null) {
continue;
}
OffsetDef offsetDef =null;
if(field.isAnnotationPresent(OffsetDef.class)) {
offsetDef = field.getAnnotation(OffsetDef.class);
}
//获取目标对象指定的属性
Field tField = target.getClass().getDeclaredField(field.getName());
tField.setAccessible(true);
if (field.isAnnotationPresent(Order.class)) {
if(field.getType().isPrimitive() && !field.getType().isArray() ) {
//如果属性添加了自定义注解 offset
Class<?> type = field.getType();
if(offsetDef!=null) {
double offset =offsetDef.value();
int type1 =offsetDef.type();
int minValidLength =offsetDef.minValidLength();
//startindex
if(type==byte.class) {
tField.set(target, o);
}else if(type==short.class) {
if(minValidLength>0 ) {
int len = String.valueOf((Short)o).length();
if(len<minValidLength) {
int subtract = minValidLength-len;
double f =(Short)o*Math.pow(10, subtract)*offset;
tField.set(target, (float)f);
}else {
double f =(Short)o*offset;
tField.set(target, (float)f);
}
}else {
double f =(Short)o*offset;
tField.set(target, (float)f);
}
}else if(type==int.class) {
if(minValidLength>0 ) {
int len = String.valueOf((Integer)o).length();
if(len<minValidLength) {
int subtract = minValidLength-len;
double f =(Integer)o*Math.pow(10, subtract)*offset;
tField.set(target, (float)f);
}else {
double f =(Integer)o*offset;
tField.set(target, (float)f);
}
}else {
double f =(Integer)o*offset;
tField.set(target, (float)f);
}
}else if(type==long.class) {
if(minValidLength>0 ) {
int len = String.valueOf((Long)o).length();
if(len<minValidLength) {
int subtract = minValidLength-len;
double f =(Long)o*Math.pow(10, subtract)*offset;
tField.set(target, (float)f);
}else {
double f =(Long)o*offset;
tField.set(target, (float)f);
}
}else {
double d =(Long)o*offset;
tField.set(target, d);
}
}
}else {
tField.set(target, o);
}
}else if(field.getClass().isPrimitive() && field.getType().isArray()){
// 基础数据类型 且 是数组
}else if(List.class.isAssignableFrom(field.getType())) {
// 集合类型
//读取属性的注解是否引用其他字段的长度
if( field.isAnnotationPresent(RefNumFlag.class)) {
// RefNumFlag refNumFlag = field.getAnnotation(RefNumFlag.class);
// String refField = refNumFlag.value();
// Class<?> clazz1 = t.getClass();
// Field nameField = clazz1.getDeclaredField(refField);
// Type genericType = nameField.getGenericType();
// nameField.setAccessible(true);
//
// if (genericType instanceof ParameterizedType) {
// ParameterizedType pt = (ParameterizedType) genericType;
// Type[] actualTypes = pt.getActualTypeArguments();
// if (actualTypes.length > 0) {
// actualTypes[0].getClass();
// int len= (int) nameField.get(t);
// for(int i=0;i<len;i++) {
// actualTypes[0].getClass();
// }
// }
// }
}
}else if(field.getType()==String.class) {
//类型为字符串
// try {
// String s = (String)o;
// String s1 = new String(s.getBytes());
tField.set(target, o);
// }catch(Exception e) {
// e.printStackTrace();
// }
}else {
//其他对象类型
Class<?> cls = Class.forName(tField.getType().getName());
Object obj = cls.newInstance();
convoterBean(o, obj);
tField.set(target, obj);
}
}
}
}
public static byte[] convoter(Byte[] bytes) {
byte [] bs = new byte[bytes.length];
int i=0;
for(Byte b :bytes ) {
bs[i++] = b;
}
return bs;
}
}
package com.cusc.adas.v2x.utils;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME) // 注解在运行时可用
@Target(ElementType.FIELD) // 注解只能用于字段(属性)
public @interface RefNumFlag {
String value();
}
package com.cusc.adas.v2x.utils;
import java.nio.charset.StandardCharsets;
import java.security.Security;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class SM4Utils {
private static final String ALGORITHM_NAME = "SM4";
private static final String ALGORITHM_MODE = "SM4/ECB/PKCS5Padding";
static {
Security.addProvider(new BouncyCastleProvider());
}
/**
* ???? SM4 ???
* @return ????? Base64 ?????????
* @throws Exception ??
*/
public static String generateKey() throws Exception {
KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM_NAME, "BC");
kg.init(128);
SecretKey secretKey = kg.generateKey();
return Base64.getEncoder().encodeToString(secretKey.getEncoded());
}
/**
* SM4 ????
* @param plainText ????
* @param key ????? Base64 ?????????
* @return ????? Base64 ?????????
* @throws Exception ??
*/
public static String encrypt(String plainText, String key) throws Exception {
byte[] keyBytes = Base64.getDecoder().decode(key);
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, ALGORITHM_NAME);
Cipher cipher = Cipher.getInstance(ALGORITHM_MODE, "BC");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
byte[] encryptedBytes = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(encryptedBytes);
}
/**
* SM4 ????
* @param cipherText ????? Base64 ?????????
* @param key ????? Base64 ?????????
* @return ????
* @throws Exception ??
*/
public static String decrypt(String cipherText, String key) throws Exception {
byte[] keyBytes = Base64.getDecoder().decode(key);
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, ALGORITHM_NAME);
Cipher cipher = Cipher.getInstance(ALGORITHM_MODE, "BC");
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
byte[] cipherBytes = Base64.getDecoder().decode(cipherText);
byte[] decryptedBytes = cipher.doFinal(cipherBytes);
return new String(decryptedBytes, StandardCharsets.UTF_8);
}
}
package com.cusc.adas.v2x.vo;
import java.util.List;
import com.cusc.adas.v2x.utils.NumFlag;
import com.cusc.adas.v2x.utils.Order;
import com.cusc.adas.v2x.utils.RefNumFlag;
/**
* 车辆自动驾驶信息
* @author huangml
*
*/
public class AutomaticDriveInfo {
//执行云端控制命令编号
@Order(1)
private long cloudMessageId;
//自动驾驶需求加速度
@Order(2)
private int accelCmd;
//自动驾驶需求扭矩
@Order(3)
private long torqueCmd;
//自动驾驶需求速度
@Order(4)
private int velocityCmd;
//规划-位置点轨 迹数量
@Order(5)
@NumFlag
private int planningLocNum;
//规划-位置点轨 迹列表
@Order(6)
@RefNumFlag(value="planningLocNum")
private List<TracePoint> planningLocs;
//决策-换道
@Order(7)
private short decisionLaneChange;
//加减速
@Order(8)
private short decisionAccel;
//决策-转向
@Order(9)
private short decisionTurnSignal;
//决策-车辆状态
@Order(10)
private short decisionVehicleStatus;
//感知目标个数
@Order(11)
@NumFlag
private short detectionLen;
//感知目标数据
@RefNumFlag(value="detectionLen")
@Order(12)
private List<TrajectoryInfo> detectionData;
//自动驾驶系统故障
@Order(13)
private int autoDrivingSysFault;
//电子手刹状态
@Order(14)
private short epbFlag;
//自定义字段长度
@Order(15)
private short userdefinedDataLength;
//自定义字段内容
@Order(16)
private byte[] userdefinedData;
}
package com.cusc.adas.v2x.vo;
public class Cov {
private long cov; // 状态量协方差
public long getCov() {
return cov;
}
public void setCov(long cov) {
this.cov = cov;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment