shjung 11 months ago
parent
commit
a00fdf9eed

+ 0 - 12
src/main/java/com/sig/comm/server/dto/SignalMapInfo.java

@@ -1,12 +0,0 @@
-package com.sig.comm.server.dto;
-
-public class SignalMapInfo {
-
-    public static final int ESIGMAP_LC_TYPE_NONE = 0;
-    public static final int ESIGMAP_LC_TYPE_2004 = 1;                   /* 2004년 protocol */
-    public static final int ESIGMAP_LC_TYPE_2010 = 2;                   /* 2010년 protocol */
-
-    public static final int MAX_SIGMAP_LSU = 16;      /* 최대 lcu 갯수 */
-    public static final int MAX_SIGMAP_STEP = 32;      /* 최대 step 갯수 */
-
-}

+ 1 - 0
src/main/java/com/sig/comm/server/xnet/server/SigCommServerInitializer.java

@@ -7,6 +7,7 @@ import com.sig.comm.server.dto.RegionCenter;
 import com.sig.comm.server.repository.ApplicationRepository;
 import com.sig.comm.server.xnet.server.codec.SigSendByteBufMessageEncoder;
 import com.sig.comm.server.xnet.server.handler.SigCommServerInboundMessageHandler;
+import com.sig.comm.server.xnet.server.process.protocol.SigProtocolConst;
 import io.netty.channel.Channel;
 import io.netty.channel.ChannelInitializer;
 import io.netty.channel.ChannelPipeline;

+ 1 - 1
src/main/java/com/sig/comm/server/xnet/server/process/protocol/SigCommPacket.java

@@ -46,7 +46,7 @@ public class SigCommPacket implements Serializable {
         this.buffer = new byte[this.packetLength];
         byteBuf.getBytes(byteBuf.readerIndex(), this.buffer);
 
-        if (this.packetLength >= (SigProtocolConst.SIG_HEAD_SIZE + SigProtocolConst.SIG_TAIL_SIZE)) {
+        if (this.packetLength < (SigProtocolConst.SIG_HEAD_SIZE + SigProtocolConst.SIG_TAIL_SIZE)) {
             this.stx        = SigProtocolConst.SIG_NULL;
             this.opCode     = SigProtocolConst.SIG_NULL;
             this.year       = 0;

+ 204 - 0
src/main/java/com/sig/comm/server/xnet/server/process/protocol/SigMapCompress.java

@@ -0,0 +1,204 @@
+package com.sig.comm.server.xnet.server.process.protocol;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class SigMapCompress {
+
+    public static final int MAXMAPDATASIZE = 608;
+    public static final int MAX_VAR_CNT = 40;
+
+    public static final int SP_SIZE = 19;
+    public static final int SP_MIN = 16;
+    public static final int SP_MAX = 17;
+    public static final int SP_EOP = 18;
+
+    public static final byte CODE_PED_GREEN = (byte)0x10;
+    public static final byte CODE_PED_FLASH = (byte)0x20;
+    public static final byte CODE_CAR_GREEN = (byte)0x01;
+    public static final byte CODE_PED_GINX  = (byte)0x00; /* 0b00000000 */
+    public static final byte CODE_PED_FINX  = (byte)0x01; /* 0b00000001 */
+    public static final byte CODE_CAR_GINX  = (byte)0x02; /* 0b00000010 */
+    public static final byte CODE_USER_INX  = (byte)0x03; /* 0b00000011 */
+
+    /*
+     * 2010 protocol
+     */
+    public static final int MAX_COLUM = 16;      /* 16 LSU */
+    public static final int MAX_STEP = 32;
+    public static final byte MIN_EOP3SEC = (byte)0x03;
+    public static final byte MIN_3SEC = (byte)0x02;
+    public static final byte MIN_VAR = (byte)0x01;
+    public static final byte MAX_VAR = (byte)0x00;
+
+    public static final byte DELIMITER = (byte)0xFF;
+
+    public static short gen16LRC(byte[] s, int size) {
+        int sLrc = 0;
+        for (int ii = 0; ii < size; ii++) {
+            sLrc += (ii + 1) * (s[ii] & 0xFF); // Ensure unsigned value
+        }
+
+        byte lrc0 = (byte) (sLrc / 256);
+        byte lrc1 = (byte) (sLrc % 256);
+
+        return (short) ((lrc0 << 8) | (lrc1 & 0xFF));
+    }
+
+    public static int signalMapDecompress(byte[] compData, int start, int length, byte[] deCompData) {
+        int dp = 0;
+        int cop, cp, up;
+        int ep = length;
+        int sp = 77;
+        int inx;
+        int data;
+
+        /* find the first delimiter 0xFF */
+        data = compData[sp];
+        if (data != DELIMITER || sp >= ep) {
+            sp = 0;
+            while (sp <= ep) {
+                data = compData[sp];
+                if (data == DELIMITER) {
+                    break;
+                }
+                sp++;
+            }
+            data = compData[sp];
+            if (data != DELIMITER || sp >= ep) {
+                return 0;
+            }
+        }
+        sp++;
+        cop = cp = sp;
+
+        /* find the second delimiter 0xFF to backward */
+        sp = ep;
+        while (sp > cp) {
+            data = compData[sp];
+            if (data == DELIMITER) {
+                break;
+            }
+            sp--;
+        }
+        data = compData[sp];
+        if (data != DELIMITER || sp <= cp) {
+            return 0;
+        }
+
+        sp++;
+        up = sp;
+        sp = 0;
+        int inxCount = 0;
+        int byteCount = 0;
+        while(sp < cop-1) {
+            for (int bitCount = 0; bitCount < 8; bitCount++) {
+                data = compData[sp];
+                if ((data & (0x01 << bitCount)) > 0) {
+                    inx = compData[cp];
+                    inx = (inx & (0x03 << inxCount) ) >> inxCount;
+                    switch(inx)
+                    {
+                        case CODE_PED_GINX: deCompData[dp] = CODE_PED_GREEN; break;
+                        case CODE_PED_FINX: deCompData[dp] = CODE_PED_FLASH; break;
+                        case CODE_CAR_GINX: deCompData[dp] = CODE_CAR_GREEN; break;
+                        case CODE_USER_INX:
+                            deCompData[dp] = compData[up++];
+                            if (deCompData[up] == 0x00) {
+                                return byteCount+1;
+                            }
+                            break;
+                    }
+                    inxCount += 2;
+                    if ((inxCount % 8) == 0) {
+                        inxCount = 0;
+                        cp++;
+                    }
+                    dp++;
+                }
+                else {
+                    deCompData[dp++] = (byte)0x00;
+                }
+                if (dp >= MAXMAPDATASIZE) {
+                    return MAXMAPDATASIZE; /* PREVENT OVERRANGE */
+                }
+                byteCount++;
+            }
+            if (sp >= ep) {
+                break;
+            }
+            sp++;
+        }
+        return byteCount + 1;
+    }
+
+    public static int signalMapDecompress2010(byte[] compData, int start, int length, byte[] deCompData) {
+        int dp = 0;
+        int cop, cp, up;
+        int ep = length;
+        int sp = 0;
+        int col = 0;
+        int tCnt = 0;
+        int inx;
+        int data;
+
+        data = compData[sp];
+        while ((sp < ep) && (data > 0)) {
+            /* LSU 코드 값이 없으면 while 문이 종료됨 */
+        }
+
+        data = compData[sp++];
+        if (data > 0) {
+            return 0;
+        }
+
+        int value;
+        int varAttr, attr;
+        varAttr = attr = sp;
+        while (varAttr < ep && compData[varAttr++] != 0x00) {
+            ;   /*3초아닌 스텝시간 영역으로 이동*/
+        }
+        if (varAttr >= ep) {
+            return 0;
+        }
+
+        int stepIdx;
+        for (int step = 0; step < MAX_STEP; step++) {
+            if ((step > 0) && (step % 4 != 0)) {
+                attr++;
+                if (compData[attr] == 0x00) {
+                    break;
+                }
+            }
+            value = (((compData[attr]) >> ((step%4)*2)) & 0x03);
+            stepIdx = step*SP_SIZE;
+            switch(value)
+            {
+                case MIN_EOP3SEC:
+                    deCompData[stepIdx+SP_MIN] = 3;
+                    deCompData[stepIdx+SP_EOP] = 1;
+                    break; /*3초인 EOP 스텝인 경우 */
+                case MIN_3SEC:
+                    deCompData[stepIdx+SP_MIN] = 3;
+                    break;
+                case MAX_VAR:
+                    deCompData[stepIdx+SP_MAX] = compData[varAttr++];
+                    if (deCompData[stepIdx+SP_MAX] == (byte) 0x01) {
+                        if ((compData[varAttr] & 0x80) > 0) {
+                            deCompData[stepIdx+SP_EOP] = 1;
+                        }
+                        deCompData[stepIdx+SP_MIN] = (byte)(compData[varAttr++] & (byte) 0x7F);
+                        deCompData[stepIdx+SP_MAX] = compData[varAttr++];
+                    }
+                    break;
+                case MIN_VAR:
+                    deCompData[stepIdx+SP_MIN] = (byte)(compData[varAttr] & (byte) 0x7F);
+                    if ((compData[varAttr++] & 0x80) > 0) {
+                        deCompData[stepIdx+SP_EOP] = 1;
+                    }
+                    break;
+            }
+        }
+        return MAXMAPDATASIZE;
+    }
+}

+ 61 - 0
src/main/java/com/sig/comm/server/xnet/server/process/protocol/SigMapData.java

@@ -0,0 +1,61 @@
+package com.sig.comm.server.xnet.server.process.protocol;
+
+import lombok.Data;
+import lombok.Getter;
+
+@Data
+public class SigMapData {
+
+    public static final int ESIGMAP_LC_TYPE_NONE = 0;
+    public static final int ESIGMAP_LC_TYPE_2004 = 1;                   /* 2004년 protocol */
+    public static final int ESIGMAP_LC_TYPE_2010 = 2;                   /* 2010년 protocol */
+
+    public static final int MAX_COMPRESS_DATA_SIZE = 255;
+    public static final int MAX_DECOMPRESS_DATA_SIZE = (16+3)*32;   // 608
+
+    public static final int MAX_SIGMAP_LSU = 16;      /* 최대 lcu 갯수 */
+    public static final int MAX_SIGMAP_STEP = 32;      /* 최대 step 갯수 */
+
+
+    private SigMapInfo[] step; // signal map data - step1 ~ step32
+
+    private byte[] data;
+    @Getter
+    public static class SigMapInfo {
+        private byte[] lsu; // 4색등화기 또는 3색등화기에 해당하는 lsu 배열
+        private byte minTm; // 고정시간값
+        private byte maxTm; // 가변시간값
+        private byte eop; // 현시종료
+
+        public SigMapInfo() {
+            this.lsu = new byte[MAX_SIGMAP_LSU];
+            this.minTm = (byte)0x00;
+            this.maxTm = (byte)0x00;
+            this.eop = (byte)0x00;
+        }
+        public void init() {
+            for (int ii = 0; ii < MAX_SIGMAP_LSU; ii++) {
+                this.lsu[ii] = (byte)0x00;
+            }
+            this.minTm = (byte)0x00;
+            this.maxTm = (byte)0x00;
+            this.eop = (byte)0x00;
+        }
+    }
+
+    public SigMapData() {
+        this.data = new byte[MAX_DECOMPRESS_DATA_SIZE];
+        this.step = new SigMapInfo[MAX_SIGMAP_STEP];
+    }
+
+    public void init() {
+        int ii;
+        for (ii = 0; ii < this.data.length; ii++) {
+            this.data[ii] = (byte)0x00;
+        }
+        for (ii = 0; ii < MAX_SIGMAP_STEP; ii++) {
+            this.step[ii].init();
+        }
+    }
+
+}

+ 1 - 0
src/main/java/com/sig/comm/server/xnet/server/process/request/SigCommRequest.java

@@ -1,5 +1,6 @@
 package com.sig.comm.server.xnet.server.process.request;
 
+import com.sig.comm.server.xnet.server.process.protocol.SigProtocolConst;
 import com.sig.comm.server.xnet.server.process.protocol.eSigOpCode;
 import lombok.Getter;
 import org.jetbrains.annotations.NotNull;

+ 66 - 7
src/main/java/com/sig/comm/server/xnet/server/process/response/SigSignalMap.java

@@ -1,8 +1,10 @@
 package com.sig.comm.server.xnet.server.process.response;
 
-import com.sig.comm.server.dto.SignalMapInfo;
+import com.sig.comm.server.dto.IntDto;
 import com.sig.comm.server.process.dbms.DbmsData;
 import com.sig.comm.server.process.dbms.DbmsDataProcess;
+import com.sig.comm.server.xnet.server.process.protocol.SigMapCompress;
+import com.sig.comm.server.xnet.server.process.protocol.SigMapData;
 import com.sig.comm.server.xnet.server.process.protocol.SigProtocolConst;
 import lombok.extern.slf4j.Slf4j;
 import org.slf4j.MDC;
@@ -48,7 +50,8 @@ public class SigSignalMap implements SigCommResponse {
 //                byte compData[MAX_COMPRESSDATA_SIZE];   /* 압축된 signal map data */
 //            } pkt_signalmap, *pkt_signalmapp; /* 2 + 1+1+1+1+1 + 255 bytes = 262 */
 
-
+            int res;
+            SigMapData mapData = new SigMapData();
             List<HashMap<String, Object>> typeLists = new ArrayList<>();
             List<HashMap<String, Object>> lists = new ArrayList<>();
             String regionCd = packet.getCenter().getRegionCd();
@@ -57,19 +60,75 @@ public class SigSignalMap implements SigCommResponse {
             byte[] buffer = packet.getPacket().getBuffer();
             for (int ii = 0; ii < packet.getPacket().getCount(); ii++) {
                 int intNo = ((buffer[idx++] & 0xFF) << 8) | (buffer[idx++] & 0xFF);
-                int lcType = (buffer[idx++] & 0xFF);    /* SIGNAL Controller protocol type, ESIGMAP_LC_TYPE_2004 or  ESIGMAP_LC_TYPE_2010 */
-                int ringNo = (buffer[idx++] & 0xFF);    /* ring no, 0: Aring, 1: Bring */
-                int lampTp = (buffer[idx++] & 0xFF);    /* 등화기 유형 */
+                int lcType = (buffer[idx++] & 0xFF);    /* 제어기유형(1:2004년형, 2:2010년형) */
+                int ringNo = (buffer[idx++] & 0xFF);    /* 링번호(0:A링,1:B링) */
+                int lampTp = (buffer[idx++] & 0xFF);    /* 등화기유형(3:3색등화기, 4:4색등화기) */
                 int planTp = (buffer[idx++] & 0xFF);    /* map 계획구분, 0:일반제, 1~5:시차제, 6:보행맵 */
                 int compSize = (buffer[idx++] & 0xFF);
 
-                if (lcType == SignalMapInfo.ESIGMAP_LC_TYPE_2004) {
+                byte[] compData = new byte[SigMapData.MAX_COMPRESS_DATA_SIZE];
+                byte[] deCompData = new byte[SigMapData.MAX_DECOMPRESS_DATA_SIZE];
+                System.arraycopy(buffer, idx, compData, 0, compData.length);
+
+                mapData.init();
 
+                if (lcType == SigMapData.ESIGMAP_LC_TYPE_2004) {
+                    res = SigMapCompress.signalMapDecompress(compData, idx, compSize, deCompData);
                 }
                 else {
+                    res = SigMapCompress.signalMapDecompress2010(compData, idx, compSize, deCompData);
+                }
+                idx = idx + SigMapData.MAX_COMPRESS_DATA_SIZE;
+
+                if (res == 0) {
+                    log.error("[{}], SigSignalMap.response: Decompress Error. INT_NO: {}, LC_TYPE: {}", packet.getCenter().getLogKey(), intNo, lcType);
+                    continue;
+                }
+
+                IntDto intDto = packet.getCenter().getIntMap().get(intNo);
+                if (intDto != null) {
+                    if (intDto.getIntLcType() != lcType || intDto.getIntLampType() != lampTp) {
+                        HashMap<String, Object> intParam = new HashMap<>();
+                        intParam.put("REGION_CD",     regionCd);
+                        intParam.put("INT_NO",        intNo);
+                        intParam.put("INT_LCTYPE",    lcType);
+                        intParam.put("INT_LAMP-TYPE", lampTp);
+                        typeLists.add(intParam);
+                    }
+                }
+
+                for (int jj = 0; jj < SigMapData.MAX_SIGMAP_STEP; jj++) {
+                    HashMap<String, Object> param = new HashMap<>();
+
+                    SigMapData.SigMapInfo mapInfo = mapData.getStep()[jj];
+                    param.put("REGION_CD",  regionCd);                  /*지역센터코드 */
+                    param.put("INT_NO",     intNo);                     /*교차로 번호 */
+                    param.put("RING_NO",    ringNo);                    /*링번호(0:A링,1:B링) */
+                    param.put("PLAN_TP",    planTp);                    /*계획구분(0:일반제, 1:시차제, 2:시차제, 3:시차제, 4:시차제, 5:시차제, 6:보행맵) */
+                    param.put("STEP_NO",    jj+1);                      /*스텝번호(1~32) */
+
+                    param.put("CAR1",   mapInfo.getLsu()[ 0] & 0xFF);   /*차량등 1 (2004-LSU1) */
+                    param.put("PED1",   mapInfo.getLsu()[ 1] & 0xFF);   /*보행등 1 (2004-LSU2) */
+                    param.put("CAR2",   mapInfo.getLsu()[ 2] & 0xFF);
+                    param.put("PED2",   mapInfo.getLsu()[ 3] & 0xFF);
+                    param.put("CAR3",   mapInfo.getLsu()[ 4] & 0xFF);
+                    param.put("PED3",   mapInfo.getLsu()[ 5] & 0xFF);
+                    param.put("CAR4",   mapInfo.getLsu()[ 6] & 0xFF);
+                    param.put("PED4",   mapInfo.getLsu()[ 7] & 0xFF);
+                    param.put("CAR5",   mapInfo.getLsu()[ 8] & 0xFF);
+                    param.put("PED5",   mapInfo.getLsu()[ 9] & 0xFF);
+                    param.put("CAR6",   mapInfo.getLsu()[10] & 0xFF);
+                    param.put("PED6",   mapInfo.getLsu()[11] & 0xFF);
+                    param.put("CAR7",   mapInfo.getLsu()[12] & 0xFF);
+                    param.put("PED7",   mapInfo.getLsu()[13] & 0xFF);
+                    param.put("CAR8",   mapInfo.getLsu()[14] & 0xFF);   /*차량등 8 (2004-LSU15) */
+                    param.put("PED8",   mapInfo.getLsu()[15] & 0xFF);   /*보행등 8 (2004-LSU16) */
+                    param.put("MIN_TM", mapInfo.getMinTm()   & 0xFF);   /*최소시간 */
+                    param.put("MAX_TM", mapInfo.getMaxTm()   & 0xFF);   /*최대시간 */
+                    param.put("EOP",    mapInfo.getEop()     & 0xFF);   /*현시종료여부(1:종료) */
 
+                    lists.add(param);
                 }
-                idx = idx + 255;
             }
             this.dbmsDataProcess.add(new DbmsData(DbmsData.DBMS_DATA_INT_SIGNALMAP, packet.getCenter(), false, lists));
             if (!typeLists.isEmpty()) {

+ 1 - 1
src/main/java/com/sig/comm/server/xnet/server/process/response/SigTodPlan.java

@@ -58,7 +58,7 @@ public class SigTodPlan implements SigCommResponse {
             int idx = SigProtocolConst.SIG_HEAD_SIZE;
             byte[] buffer = packet.getPacket().getBuffer();
             for (int ii = 0; ii < packet.getPacket().getCount(); ii++) {
-                 int intNo = ((buffer[idx++] & 0xFF) << 8) | (buffer[idx++] & 0xFF);
+                int intNo = ((buffer[idx++] & 0xFF) << 8) | (buffer[idx++] & 0xFF);
                 int planNo = (buffer[idx++] & 0xFF);
 
                 for (int jj = 0; jj < 16; jj++) {