diff --git a/jsowell-common/src/main/java/com/jsowell/common/YouDianUtils.java b/jsowell-common/src/main/java/com/jsowell/common/YouDianUtils.java index 0093e7238..fd12d8f6b 100644 --- a/jsowell-common/src/main/java/com/jsowell/common/YouDianUtils.java +++ b/jsowell-common/src/main/java/com/jsowell/common/YouDianUtils.java @@ -35,4 +35,26 @@ public class YouDianUtils { log.info("计算的校验值:{}, 接收到的校验值:{}", calculatedChecksum, receivedChecksum); return calculatedChecksum == receivedChecksum; } + + /** + * 计算校验字段 + */ + public static int calculateCheckField(byte[] bytes) { + // 计算累加和 + int sum = 0; + for (int i = 0; i < bytes.length - 2; i++) { + sum += (bytes[i] & 0xFF); // 将每个字节视为无符号值进行累加 + } + + // 取累加和的低 2 字节(16 位) + return sum & 0xFFFF; + } + + /** + * 获取校验字段byte数组 + */ + public static byte[] getCheckFieldBytes(byte[] bytes) { + int calculatedChecksum = calculateCheckField(bytes); + return BytesUtil.intToBytesLittle(calculatedChecksum); + } } diff --git a/jsowell-common/src/main/java/com/jsowell/common/core/domain/ebike/EBikeDataProtocol.java b/jsowell-common/src/main/java/com/jsowell/common/core/domain/ebike/EBikeDataProtocol.java index 38062174c..43bd8e2ac 100644 --- a/jsowell-common/src/main/java/com/jsowell/common/core/domain/ebike/EBikeDataProtocol.java +++ b/jsowell-common/src/main/java/com/jsowell/common/core/domain/ebike/EBikeDataProtocol.java @@ -67,7 +67,10 @@ public class EBikeDataProtocol { * @return 报文 */ public String getHEXString() { - byte[] bytes = Bytes.concat(this.head, this.length, this.physicalId, this.messageId, this.command, this.msgBody, this.checksum); - return BytesUtil.binary(bytes, 16); + return BytesUtil.binary(this.getBytes(), 16); + } + + public byte[] getBytes() { + return Bytes.concat(this.head, this.length, this.physicalId, this.messageId, this.command, this.msgBody, this.checksum); } } diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/AbstractEBikeHandler.java b/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/AbstractEBikeHandler.java index d0c8ce70f..99d505eb3 100644 --- a/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/AbstractEBikeHandler.java +++ b/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/AbstractEBikeHandler.java @@ -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); } /** diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/GetServerTimeHandler.java b/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/GetServerTimeHandler.java index 1edddd2c4..88e7f7d07 100644 --- a/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/GetServerTimeHandler.java +++ b/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/GetServerTimeHandler.java @@ -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); } } diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/HeartbeatHandler.java b/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/HeartbeatHandler.java index 2fef34e72..afd7547a7 100644 --- a/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/HeartbeatHandler.java +++ b/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/HeartbeatHandler.java @@ -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]; } } diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/RegistrationHandler.java b/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/RegistrationHandler.java index 730fa8c4f..d39052923 100644 --- a/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/RegistrationHandler.java +++ b/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/RegistrationHandler.java @@ -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]; } } diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/SettlementUploadHandler.java b/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/SettlementUploadHandler.java index 8c5ad68bf..fd9825a8e 100644 --- a/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/SettlementUploadHandler.java +++ b/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/SettlementUploadHandler.java @@ -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; } diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/handler/yunkuaichong/TimeCheckSettingHandler.java b/jsowell-netty/src/main/java/com/jsowell/netty/handler/yunkuaichong/TimeCheckSettingHandler.java index 1e7751c4c..854abf3df 100644 --- a/jsowell-netty/src/main/java/com/jsowell/netty/handler/yunkuaichong/TimeCheckSettingHandler.java +++ b/jsowell-netty/src/main/java/com/jsowell/netty/handler/yunkuaichong/TimeCheckSettingHandler.java @@ -12,7 +12,7 @@ import org.springframework.stereotype.Component; * 对时设置 * * 运营平台同步充电桩时钟,以保证充电桩与运营平台的时钟一致 - * + * @deprecated * @author JS-ZZA * @date 2022/9/19 15:11 */ diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/server/electricbicycles/ElectricBicyclesServerHandler.java b/jsowell-netty/src/main/java/com/jsowell/netty/server/electricbicycles/ElectricBicyclesServerHandler.java index d41825c99..0877f53b5 100644 --- a/jsowell-netty/src/main/java/com/jsowell/netty/server/electricbicycles/ElectricBicyclesServerHandler.java +++ b/jsowell-netty/src/main/java/com/jsowell/netty/server/electricbicycles/ElectricBicyclesServerHandler.java @@ -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 statusList = Lists.newArrayList(); for (byte statusByte : statusBytes) { int status = BytesUtil.bytesToIntLittle(new byte[]{statusByte});