update 电单车协议

This commit is contained in:
Guoqs
2024-08-26 15:48:22 +08:00
parent c091b6dea7
commit 8d278745b4
11 changed files with 126 additions and 26 deletions

View File

@@ -1,14 +1,13 @@
package com.jsowell.netty.handler.electricbicycles;
import com.google.common.primitives.Bytes;
import com.jsowell.common.YouDianUtils;
import com.jsowell.common.constant.CacheConstants;
import com.jsowell.common.core.domain.ebike.EBikeDataProtocol;
import com.jsowell.common.core.domain.ykc.YKCDataProtocol;
import com.jsowell.common.core.domain.ykc.YKCFrameTypeCode;
import com.jsowell.common.core.redis.RedisCache;
import com.jsowell.common.enums.ykc.PileChannelEntity;
import com.jsowell.common.util.BytesUtil;
import com.jsowell.common.util.CRC16Util;
import com.jsowell.common.util.DateUtils;
import io.netty.channel.ChannelHandlerContext;
import org.springframework.beans.factory.InitializingBean;
@@ -39,20 +38,22 @@ public abstract class AbstractEBikeHandler implements InitializingBean {
protected byte[] getResult(EBikeDataProtocol dataProtocol, byte[] messageBody) {
// 起始标志
byte[] head = dataProtocol.getHead();
// 序列号域
byte[] serialNumber = dataProtocol.getPhysicalId();
// 加密标志
byte[] encryptFlag = dataProtocol.getMessageId();
// 请求帧类型
byte[] requestFrameType = dataProtocol.getCommand();
// 应答帧类型
byte[] responseFrameType = YKCFrameTypeCode.PlatformAnswersRelation.getResponseFrameTypeBytes(requestFrameType);
// 数据域 值为“序列号域+加密标志+帧类型标志+消息体”字节数之和
byte[] dataFields = Bytes.concat(serialNumber, encryptFlag, responseFrameType, messageBody);
// 计算crc 从序列号域到数据域的 CRC 校验
int crc16 = CRC16Util.calcCrc16(dataFields);
return Bytes.concat(head, BytesUtil.intToBytes(dataFields.length, 1), dataFields, BytesUtil.intToBytes(crc16));
// 长度 = 物理ID(4) + 消息ID(2) + 命令(1) + 数据(n) + 校验(2)每包最多256字节
byte[] length = BytesUtil.intToBytes(9 + messageBody.length);
// 物理id
byte[] physicalId = dataProtocol.getPhysicalId();
// 加密标志
byte[] messageId = dataProtocol.getMessageId();
// 请求帧类型
byte[] command = dataProtocol.getCommand();
// 整个数据包中的每个字节(不包括校验字段本身)
byte[] dataFields = Bytes.concat(head, length, physicalId, messageId, command, messageBody);
byte[] checkFieldBytes = YouDianUtils.getCheckFieldBytes(dataFields);
return Bytes.concat(dataFields, checkFieldBytes);
}
/**

View File

@@ -1,14 +1,18 @@
package com.jsowell.netty.handler.electricbicycles;
import com.alibaba.fastjson2.JSON;
import com.jsowell.common.core.domain.ebike.EBikeDataProtocol;
import com.jsowell.common.util.BytesUtil;
import com.jsowell.netty.factory.EBikeOperateFactory;
import com.jsowell.pile.domain.ebike.AbsEBikeMessage;
import com.jsowell.pile.domain.ebike.EBikeCommandEnum;
import com.jsowell.pile.domain.ebike.deviceupload.EBikeMessageCmd22;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* 设备心跳包
* 设备获取服务器时间
*/
@Slf4j
@Component
@@ -24,11 +28,18 @@ public class GetServerTimeHandler extends AbstractEBikeHandler {
* 执行逻辑
* 有应答
*
* @param msg
* @param dataProtocol
* @param ctx
*/
@Override
public byte[] supplyProcess(EBikeDataProtocol dataProtocol, ChannelHandlerContext ctx) {
return new byte[0];
// 解析字节数组
EBikeMessageCmd22 message = (EBikeMessageCmd22) AbsEBikeMessage.parseMessage(dataProtocol.getBytes());
log.info("设备获取服务器时间:{}", JSON.toJSONString(message));
// 获取当前服务器10位时间戳
byte[] timeBytes = BytesUtil.getIntBytes((int) (System.currentTimeMillis() / 1000));
System.out.println("data: " + BytesUtil.bytesToIntLittle(timeBytes));
return getResult(dataProtocol, timeBytes);
}
}

View File

@@ -1,8 +1,11 @@
package com.jsowell.netty.handler.electricbicycles;
import com.alibaba.fastjson2.JSON;
import com.jsowell.common.core.domain.ebike.EBikeDataProtocol;
import com.jsowell.netty.factory.EBikeOperateFactory;
import com.jsowell.pile.domain.ebike.AbsEBikeMessage;
import com.jsowell.pile.domain.ebike.EBikeCommandEnum;
import com.jsowell.pile.domain.ebike.deviceupload.EBikeMessageCmd21;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@@ -29,6 +32,10 @@ public class HeartbeatHandler extends AbstractEBikeHandler {
*/
@Override
public byte[] supplyProcess(EBikeDataProtocol dataProtocol, ChannelHandlerContext ctx) {
// 解析字节数组
EBikeMessageCmd21 message = (EBikeMessageCmd21) AbsEBikeMessage.parseMessage(dataProtocol.getBytes());
EBikeMessageCmd21.DeviceHeartbeat deviceHeartbeat = message.getDeviceHeartbeat();
log.info("设备心跳包:{}", JSON.toJSONString(message));
return new byte[0];
}
}

View File

@@ -1,14 +1,17 @@
package com.jsowell.netty.handler.electricbicycles;
import com.alibaba.fastjson2.JSON;
import com.jsowell.common.core.domain.ebike.EBikeDataProtocol;
import com.jsowell.netty.factory.EBikeOperateFactory;
import com.jsowell.pile.domain.ebike.AbsEBikeMessage;
import com.jsowell.pile.domain.ebike.EBikeCommandEnum;
import com.jsowell.pile.domain.ebike.deviceupload.EBikeMessageCmd20;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* 设备心跳
* 设备注册
*/
@Slf4j
@Component
@@ -24,11 +27,15 @@ public class RegistrationHandler extends AbstractEBikeHandler {
* 执行逻辑
* 有应答
*
* @param msg
* @param dataProtocol
* @param ctx
*/
@Override
public byte[] supplyProcess(EBikeDataProtocol dataProtocol, ChannelHandlerContext ctx) {
// 解析字节数组
EBikeMessageCmd20 message = (EBikeMessageCmd20) AbsEBikeMessage.parseMessage(dataProtocol.getBytes());
EBikeMessageCmd20.DeviceRegister deviceRegister = message.getDeviceRegister();
log.info("设备注册包:{}", JSON.toJSONString(message));
return new byte[0];
}
}

View File

@@ -1,14 +1,17 @@
package com.jsowell.netty.handler.electricbicycles;
import com.alibaba.fastjson2.JSON;
import com.jsowell.common.core.domain.ebike.EBikeDataProtocol;
import com.jsowell.netty.factory.EBikeOperateFactory;
import com.jsowell.pile.domain.ebike.AbsEBikeMessage;
import com.jsowell.pile.domain.ebike.EBikeCommandEnum;
import com.jsowell.pile.domain.ebike.deviceupload.EBikeMessageCmd03;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* 设备心跳包
* 结算消费信息上传
*/
@Slf4j
@Component
@@ -29,6 +32,10 @@ public class SettlementUploadHandler extends AbstractEBikeHandler {
*/
@Override
public byte[] supplyProcess(EBikeDataProtocol dataProtocol, ChannelHandlerContext ctx) {
// 解析字节数组
EBikeMessageCmd03 message = (EBikeMessageCmd03) AbsEBikeMessage.parseMessage(dataProtocol.getBytes());
EBikeMessageCmd03.SettlementInfo settlementInfo = message.getSettlementInfo();
log.info("结算消费信息上传:{}", JSON.toJSONString(message));
return null;
}

View File

@@ -12,7 +12,7 @@ import org.springframework.stereotype.Component;
* 对时设置
*
* 运营平台同步充电桩时钟,以保证充电桩与运营平台的时钟一致
*
* @deprecated
* @author JS-ZZA
* @date 2022/9/19 15:11
*/

View File

@@ -2,6 +2,7 @@ package com.jsowell.netty.server.electricbicycles;
import com.alibaba.fastjson2.JSON;
import com.google.common.collect.Lists;
import com.jsowell.common.util.BytesUtil;
import com.jsowell.netty.service.electricbicycles.EBikeBusinessService;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
@@ -40,6 +41,7 @@ public class ElectricBicyclesServerHandler extends SimpleChannelInboundHandler<O
// 处理数据
byte[] response = eBikeService.process(msg, ctx);
if (Objects.nonNull(response)) {
log.info("响应数据:{}", BytesUtil.binary(response, 16));
// 响应客户端
ByteBuf buffer = ctx.alloc().buffer().writeBytes(response);
// this.channelWrite(channel.id(), buffer);