Browse Source

fix(协议解析):协议解析中基本信息解析超出下标、处理粘包过程中长度判断错误;无发送车牌信息时发送假车牌号,使得流程可往下走;解析不到枪号,不往下处理

Zhenghanjv 7 months ago
parent
commit
f1f198099c

+ 4 - 0
ai-fueling/src/main/java/com/tokheim/aifueling/communication/BaseAnalyzer.java

@@ -23,6 +23,7 @@ public abstract class BaseAnalyzer {
         int dataType = data[0];     //数据类型
 
         BaseInfo baseInfo = getBaseInfo(ip,data); //获取基础信息
+        if (baseInfo.getNozzleNum() == 0) return; //如果获取不到枪号就不发送
         BaseInfo allInfo = getOtherInfo(baseInfo, ByteArrayUtils.slipt(data,2,data.length)); //获取完整信息
         InterfaceUtils.sendDataToInternal(dataType,allInfo);
     }
@@ -64,6 +65,9 @@ public abstract class BaseAnalyzer {
         byte[] slipBytes = ByteArrayUtils.slipt(data,2,data.length);//截掉命令字和加油点
         int index = 0;
         while (index < slipBytes.length) {
+            //如果基本信息已经获取到,就不再往下解析
+            if (baseInfo.getEventType() != null && baseInfo.getCardType() != null && baseInfo.getOilCode() !=null
+            && baseInfo.getNozzleNum() != null) break;
             switch (slipBytes[index]) {
                 case 0x21:
                     baseInfo.setEventType((int) slipBytes[index+1]);

+ 36 - 1
ai-fueling/src/main/java/com/tokheim/aifueling/communication/toInternalInterface/InterfaceUtils.java

@@ -3,6 +3,7 @@ package com.tokheim.aifueling.communication.toInternalInterface;
 import cn.hutool.core.convert.Convert;
 import com.google.gson.Gson;
 import com.tokheim.aifueling.communication.entitys.BaseInfo;
+import com.tokheim.aifueling.communication.entitys.CardStatus;
 import com.tokheim.aifueling.communication.toInternalInterface.entity.FuelResponse;
 import com.tokheim.aifueling.communication.toMachine.MachineWriter;
 import com.tokheim.aifueling.utils.BeanUtils;
@@ -10,11 +11,18 @@ import lombok.extern.slf4j.Slf4j;
 
 import java.io.IOException;
 import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 @Slf4j
 public class InterfaceUtils {
     private static final InterfaceApi interfaceApi = BeanUtils.getBean(InterfaceApi.class);
 
+    //存储卡指令
+    private static Map<Integer, BaseInfo> cardCommMap = new HashMap<>();
+
     /**
      * 发送数据到内部接口
      * @param dataType 数据类型,用于确定 baseInfo 可转换的子类
@@ -22,12 +30,26 @@ public class InterfaceUtils {
      */
     public static void sendDataToInternal(Integer dataType, BaseInfo baseInfo) {
         try {
+            sortCardComm(dataType, baseInfo);
+            if (dataType == 1 && baseInfo.getEventType() == 3) log.info("无密码确认");
+
+            if (dataType == 1 && baseInfo.getEventType() == 7) return;
+
             String response = interfaceApi.sendData(dataType, baseInfo);
             log.info("收到内部接口响应:{}",response);
 
+            //如果发了车牌匹配结果,把缓存的 卡最大可加金额 发出去
+            if (dataType == 6) {
+                response = interfaceApi.sendData(1, cardCommMap.get(baseInfo.getNozzleNum()));
+                log.info("发送卡最大可加金额,收到内部接口响应:{}",response);
+            }
+
             FuelResponse fuelResponse = new Gson().fromJson(response, FuelResponse.class);
             FuelResponse.Data data = fuelResponse.getData();
-            if (data == null) return;
+            if (data == null){
+                if (dataType == 1 && baseInfo.getEventType() == 3) MachineWriter.sendCarNumber(baseInfo.getIp(),baseInfo.getFuelPoint(), baseInfo.getInternalNum(), "0");
+                return;
+            }
 
             //若车牌号不为空
             if (data.getLicensePlate() != null && !data.getLicensePlate().isEmpty()) {
@@ -63,4 +85,17 @@ public class InterfaceUtils {
 
         return true;
     }
+
+    /**
+     * 整理卡命令顺序
+     */
+    private static void sortCardComm(Integer dataType, BaseInfo baseInfo) {
+        //如果是发送卡无密码或者卡有密码,表示是一把枪卡加油过程的一个起始,把缓存删除
+        if (dataType == 1 && (baseInfo.getEventType() == 1 || baseInfo.getEventType() == 2)){
+            cardCommMap.remove(baseInfo.getNozzleNum());
+        }
+
+        //卡最大可加金额指令信息加入缓存
+        if (dataType == 1 && baseInfo.getEventType() == 7) cardCommMap.put(baseInfo.getNozzleNum(), baseInfo);
+    }
 }

+ 1 - 1
ai-fueling/src/main/java/com/tokheim/aifueling/netty/handler/UnpackHandler.java

@@ -85,7 +85,7 @@ public class UnpackHandler extends ChannelInboundHandlerAdapter {
 
 
         //数据长度不够
-        if (cacheData.length <= dataLen) return;
+        if (cacheData.length <= headIndex + 8 + dataLen) return;
 
         //将加密截取(命令字+实际数据)发送到下一个 handler
         byte[] dataBytes = ByteArrayUtils.slipt(cacheData, headIndex + 8, headIndex + 8 + dataLen);

+ 2 - 2
ai-fueling/src/main/resources/application-prod.yml

@@ -32,7 +32,7 @@ spring:
   datasource:
     url: jdbc:mariadb://localhost:3306/ai-fueling?characterEncoding=utf-8
     username: root
-    password: 123456
+    password: TKhs@123
     driver-class-name: org.mariadb.jdbc.Driver
   # jpa 配置
   jpa:
@@ -46,7 +46,7 @@ spring:
 # 内部接口配置
 internalInterface:
   baseUrl: http://localhost
-  port: 5169
+  port: 5000
   sendData: ${internalInterface.baseUrl}:${internalInterface.port}/FCC
 
 # 跨域相关

+ 1 - 1
ai-fueling/src/test/java/com/tokheim/aifueling/AiFuelingApplicationTests.java

@@ -60,7 +60,7 @@ class AiFuelingApplicationTests {
     void testSplit() {
 //        byte[] source = {0x02,0x01,0x01,0x00,0x00,0x62,0x00,0x0c,0x05,0x21,0x22,0x01,0x23,0x02,0x10, (byte) 0x90,0x24,0x01,0x30,0x01,0x02,0x01,0x01,0x00,0x02,0x60,0x00,0x0b,0x01,0x00, (byte) 0xff,0x07,0x20,0x24,0x08,0x15,0x17,0x06,0x54,0x03,0x00,0x02,0x52,0x03,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x02,0x01,0x01,0x00,0x02,0x60,0x00,0x0b,0x01,0x00, (byte) 0xff,0x07,0x20,0x24,0x08,0x15,0x17,0x06,0x56,0x03,0x00,0x02,0x52,0x03,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x03,0x00,0x00,0x00};
         byte[] test = {0x12,0x11};
-        byte[] slipt = ByteArrayUtils.slipt(test, 1, 5);
+        byte[] slipt = ByteArrayUtils.slipt(test, 0, 2);
         System.out.println(ByteArrayUtils.bytesToHexString(slipt));
     }