shjung 2 年之前
父节点
当前提交
abf1b1b153

+ 1 - 0
src/main/java/com/its/vms/config/ApplicationConfig.java

@@ -75,6 +75,7 @@ public class ApplicationConfig {
     private String textTrafGrad3 = "정 체";
     private boolean imageSeqSave = false;
     private float fontSizeRatio = 1.35f;
+    private boolean checkNewForm = true;
 
     @PostConstruct
     private void init() {

+ 2 - 0
src/main/java/com/its/vms/domain/VmsConstants.java

@@ -34,4 +34,6 @@ public class VmsConstants {
     public static int VMS_MAX_CNGS_FORM = 5;
     public static int VMS_MAX_FORM_OBJECTS = 64;        // 최대 VMS 오브젝트 리스트 갯수
 
+    public static int DEFAULT_FORM_ID = 0;
+
 }

+ 141 - 22
src/main/java/com/its/vms/dto/TbVmsCtlrDto.java

@@ -2,6 +2,7 @@ package com.its.vms.dto;
 
 import com.its.app.AppUtils;
 import com.its.app.utils.SysUtils;
+import com.its.vms.config.ApplicationConfig;
 import com.its.vms.domain.*;
 import com.its.vms.domain.enums.eVmsFormType;
 import com.its.vms.entity.TbVmsCtlr;
@@ -12,11 +13,13 @@ import com.its.vms.xnettcp.vms.handler.VmsServerIdleStateHandler;
 import com.its.vms.xnettcp.vms.process.TcpServerSendData;
 import com.its.vms.xnettcp.vms.process.TcpServerSendDataProcess;
 import com.its.vms.xnettcp.vms.protocol.dto.*;
-import com.its.vms.xnettcp.vms.protocol.enums.eControlCommand;
-import com.its.vms.xnettcp.vms.protocol.enums.eControlDeviceId;
+import com.its.vms.xnettcp.vms.protocol.enums.eVmsFileSaveLocation;
 import com.its.vms.xnettcp.vms.protocol.enums.eVmsFormObjectKind;
 import com.its.vms.xnettcp.vms.protocol.enums.eVmsImageType;
+import com.its.vms.xnettcp.vms.protocol.impl.VmsReqBlank;
+import com.its.vms.xnettcp.vms.protocol.impl.VmsReqDataDownload;
 import com.its.vms.xnettcp.vms.protocol.impl.VmsReqDownloadForm;
+import com.its.vms.xnettcp.vms.protocol.impl.VmsReqDownloadFormSchedule;
 import com.its.vms.xnettcp.vms.task.VmsTimeoutTask;
 import io.netty.channel.Channel;
 import io.netty.channel.ChannelFuture;
@@ -129,6 +132,7 @@ public class TbVmsCtlrDto implements Serializable {
     private long              syncTime;
     private VmsFrameSequence  seq;
 
+    private Integer downloadFormId;
     private VmsDownloadFile downloadFile;           // 제어기로 다운로드할 파일정보(TB_VMS_DOWNLOAD)
     private VmsDownloadData downloadData;
     private ConcurrentHashMap<Integer, VmsDownloadForm> downloadFormMap = null;
@@ -327,18 +331,18 @@ public class TbVmsCtlrDto implements Serializable {
     }
 
     public int reset(int devcType, int cntlType, TbVmsCtrlHs ctrlHs) {
-        if (getChannel() == null || getNetState() == NET.CLOSED) {
-            log.error("Reset Request: channel not connected: [{}]", this);
-            return 1;
-        }
-        eControlDeviceId controlDeviceId = eControlDeviceId.getByValue(devcType);
-        eControlCommand commandType = eControlCommand.getByValue(cntlType);
-        if (controlDeviceId == null || commandType == null) {
-            log.error("Reset Request: control type missMatched: [{}], {}, {}", this, controlDeviceId, commandType);
-            return 2;
-        }
-
-        log.warn("[{}] [{},{}], controlDeviceId: {}, commandType: {}", this.vmsCtlrNmbr, devcType, cntlType, controlDeviceId.toString(), commandType.toString());
+//        if (getChannel() == null || getNetState() == NET.CLOSED) {
+//            log.error("Reset Request: channel not connected: [{}]", this);
+//            return 1;
+//        }
+//        eControlDeviceId controlDeviceId = eControlDeviceId.getByValue(devcType);
+//        eControlCommand commandType = eControlCommand.getByValue(cntlType);
+//        if (controlDeviceId == null || commandType == null) {
+//            log.error("Reset Request: control type missMatched: [{}], {}, {}", this, controlDeviceId, commandType);
+//            return 2;
+//        }
+//
+//        log.warn("[{}] [{},{}], controlDeviceId: {}, commandType: {}", this.vmsCtlrNmbr, devcType, cntlType, controlDeviceId.toString(), commandType.toString());
 //		boolean res = ControlDeviceService.getInstance().requestResetCommand(true, this, getChannel());
 //		if (res) {
 //			log.info("RSE REQ CONTROL SEND OK: [{}] [{},{}]", this.RSE_CTLR_NMBR, devcType, cntlType);
@@ -486,11 +490,15 @@ public class TbVmsCtlrDto implements Serializable {
     }
 
     /**
-     * 스케쥴 다운로드 초기화 작업을 수행한다.
+     * 제어기에 메시지를 표출하기 위한 작업.
+     * 1. 제어기에 표출할 폼 정보를 다운로드 한다. - downloadForm
+     * 2. 파일 다운로드(이미지, 심볼) - downloadFile
+     * 3. 폼 스케쥴 다운로드 - downloadFormSchedule
+     * 4. Blank - downloadBlank
      * @param isSchedule
      * @return
      */
-    public boolean downloadScheduleForm(boolean isSchedule) {
+    public boolean downloadForm(boolean isSchedule) {
         VmsFormService formService = (VmsFormService) AppUtils.getBean(VmsFormService.class);
         this.controlMode.setSchedule(isSchedule);
         this.txtOpCode = (byte)0x00;
@@ -574,7 +582,7 @@ public class TbVmsCtlrDto implements Serializable {
             //e_vms_file_download          = 0x82,//    데이터 다운로드                         송신    INI, CFG , Bitmap , Data파일송신            센터 → VMS
             //e_vms_download_schedule_form = 0x96,//    Display Schedule Form                   송신    계획된 Form 표출 요구                       센터 → VMS
             //e_vms_blank                  = 0x9E,//    Blank                                   송신    schedule 표출                               센터 → VMS
-            downloadDefaultSchedule();
+            downloadDefaultFrom();
         }
         else {
             // 스케쥴 모드인 경우(A:자동, F:고정)
@@ -582,21 +590,26 @@ public class TbVmsCtlrDto implements Serializable {
             //e_vms_file_download          = 0x82,//    데이터 다운로드                         송신    INI, CFG , Bitmap , Data파일송신            센터 → VMS
             //e_vms_download_schedule_form = 0x96,//    Display Schedule Form                   송신    계획된 Form 표출 요구                       센터 → VMS
             //e_vms_blank                  = 0x9E,//    Blank                                   송신    schedule 표출                               센터 → VMS
-            downloadDefaultSchedule();
+            downloadAutoFixForm();
         }
 
         return true;
     }
 
-    public boolean downloadDefaultSchedule() {
+    /**
+     * 기본 스케쥴의 폼 정보는 하나의 폼 패킷에 다운로드 해야 여러 폼을 표출할 수 있다.
+     * 제어기에서 FID0000 인 폼이 기본 표출폼 이기 때문이다.
+     * @return
+     */
+    public boolean downloadDefaultFrom() {
         // Download Form  (기본폼은 하나의 폼에 여러폼을 다운로드한다.)
         int formCnt = this.downloadData.getMaxSchedule();
         if (formCnt <= 0) {
-            log.info("VMS {}, Download Schedule Form Count Zero. {} EA.", this.vmsCtlrNmbr, formCnt);
+            log.info("downloadDefaultFrom: VMS {}, Download Schedule Form Count Zero. {} EA.", this.vmsCtlrNmbr, formCnt);
             return true;
         }
 
-        formCnt = 1;
+        //formCnt = 1;
         VmsFormDataDto formData = new VmsFormDataDto(0, formCnt);
         VmsDownloadData.VmsDownloadDataInfo[] units = this.downloadData.getUnits();
         for (int ii = 0; ii < formCnt; ii++) {
@@ -637,9 +650,115 @@ public class TbVmsCtlrDto implements Serializable {
         return sendData(downloadForm.getByteBuffer(), 10, downloadForm.getOpCodeDesc());
     }
 
-    public boolean downloadAutoFixSchedule() {
+    /**
+     * 자동 및 고정 스케쥴인 경우 폼정보 하나를 하나의 패킷으로 전송한다.
+     * @return
+     */
+    public boolean downloadAutoFixForm() {
         // Download Form  (기본폼은 하나의 폼에 하나의 폼만 다운로드한다.)
+        int formCnt = this.downloadData.getMaxSchedule();
+        if (formCnt <= 0) {
+            log.info("downloadAutoFixForm: VMS {}, Download Schedule Form Count Zero. {} EA.", this.vmsCtlrNmbr, formCnt);
+            return true;
+        }
+        return true;
+    }
+
+    /**
+     * 폼 이미지 및 기타 폼에 표출할 심볼 이미지가 다운로드 완료가 된후에 스케쥴 정보를 표출하도록 한다.
+     * @return
+     */
+    public boolean downloadFile() {
+        int formCnt = this.downloadData.getMaxSchedule();
+        if (formCnt <= 0) {
+            log.info(" downloadFile: VMS {}, Download Schedule Form Count Zero. {} EA.", this.vmsCtlrNmbr, formCnt);
+            return true;
+        }
+
+        int downloadCnt = this.downloadData.getDownloadCnt();
+        if (downloadCnt >= formCnt) {
+            // 폼파일이(폼이미지파일) 모두 다운로드 되었으므로 스케쥴 정보를 다운로드 한다.
+            return downloadFormSchedule();  // Display Schedule Form
+        }
+
+        ApplicationConfig config = (ApplicationConfig)AppUtils.getBean(ApplicationConfig.class);
+        boolean endDownload = true;
+        VmsDownloadData.VmsDownloadDataInfo[] units = this.downloadData.getUnits();
+        for (int ii = downloadCnt; ii < formCnt; ii++) {
+            this.downloadData.setDownloadCnt(downloadCnt+1);
+
+            int formId   = units[ii].getFormNo();
+            int bitmapId = units[ii].getBitmapId();
+            int formIdx  = units[ii].getFormIdx();
+            VmsForm pForm = this.formManager.getItem(formIdx);
+            if (config.isCheckNewForm() && units[ii].isDownload()) {
+                // 이미 다운로드 했기 때문에 다시 다운로드 하지 않는다.
+                log.info("downloadFile: VMS {}, IDX {}, FormId {}, BitmapId {}, already download...", this.vmsCtlrNmbr, ii, formId, bitmapId);
+                continue;
+            }
+
+            endDownload = false;
+            this.downloadFormId = units[ii].getVmsFormId();
+
+            log.info("downloadFile: DownloadCnt: VMS {}, IDX {}, FormId {}, BitmapId {}, VMS_FORM_ID: {}", this.vmsCtlrNmbr, ii, formId, bitmapId, this.downloadFormId);
+
+//            int fileNameSize = 11;
+//            int fileSize     = pForm.getImageData().length;
+            String fileName = String.format("BID%04d.BMP", bitmapId);
+            eVmsFileSaveLocation saveLoc = eVmsFileSaveLocation.LOC_DOWNLOAD_PROG_IMAGE;
+
+            VmsReqDataDownload dataDownload = new VmsReqDataDownload(this, saveLoc, fileName, pForm.getImageData());
+            return sendData(dataDownload.getByteBuffer(), 10, dataDownload.getOpCodeDesc());
+        }
+        if (endDownload) {
+            // 폼이미지 정보가 모두 다운로드 되었으므로 스케쥴 정보를 다운로드 한다.
+            return downloadFormSchedule();  // Display Schedule Form
+        }
         return true;
     }
 
+    /**
+     * 제어기에 표출할 폼의 스케쥴 정보를 다운로드 한다.
+     * @return
+     */
+    public boolean downloadFormSchedule() {
+        // 도로공사 표준에 최대 10개의 스케쥴을 사용하도록 되어 있음.
+        int maxSchedule = VmsConstants.VMS_MIN_DOWNLOAD_FORMS;
+        int formCnt = this.downloadData.getMaxSchedule();
+        if (formCnt <= 0) {
+            log.info(" downloadScheduleForm: VMS {}, Download Schedule Form Count Zero. {} EA.", this.vmsCtlrNmbr, formCnt);
+            return true;
+        }
+
+        short[] formId = new short[maxSchedule];
+        byte[] dispSec = new byte[maxSchedule];
+        for (int ii = 0; ii < maxSchedule; ii++) {
+            formId[ii] = 0;
+            dispSec[ii] = 0;
+        }
+
+        if (this.downloadData.isDefault()) {
+            formId[0] = (short)VmsConstants.DEFAULT_FORM_ID;
+            dispSec[0] = 4;
+        }
+        else {
+            for (int ii = 0; ii < formCnt && ii < maxSchedule; ii++) {
+                formId[ii] = (short) this.downloadData.getUnits()[ii].getFormNo();
+                dispSec[ii] = (byte)(this.downloadData.getUnits()[ii].getDisplaySec() & 0xFF);
+            }
+        }
+
+        VmsReqDownloadFormSchedule downloadFormSchedule = new VmsReqDownloadFormSchedule(this, formId, dispSec);
+        return sendData(downloadFormSchedule.getByteBuffer(), 10, downloadFormSchedule.getOpCodeDesc());
+    }
+
+    /**
+     * 스케쥴을 표출하도록 Blank 명령을 전송한다.
+     * @return
+     */
+    public boolean downloadBlank() {
+        VmsReqBlank reqBlank = new VmsReqBlank(this);
+        return sendData(reqBlank.getByteBuffer(), 10, reqBlank.getOpCodeDesc());
+    }
+
 }

+ 1 - 1
src/main/java/com/its/vms/xnettcp/vms/process/response/impl/VmsResParameter.java

@@ -83,7 +83,7 @@ public class VmsResParameter implements VmsResponse {
             // 최초 접속후, 상태정보->파워모듈상태->표출모듈상태->파라미터정보 조회 완료후
             // 네트워크 로그인 상태로 설정하고 스케쥴을 다운로드 하도록 한다.
             this.vmsObj.setNetState(NET.LOGINED);
-            this.vmsObj.downloadScheduleForm(false);
+            this.vmsObj.downloadForm(false);
         }
 
         return true;

+ 0 - 44
src/main/java/com/its/vms/xnettcp/vms/protocol/enums/eControlCommand.java

@@ -1,44 +0,0 @@
-package com.its.vms.xnettcp.vms.protocol.enums;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public enum eControlCommand {
-
-    ControlCommand_Status_Request       (0x00, "ControlCommand_Status_Request"),
-    ControlCommand_Reset                (0x01, "ControlCommand_Reset"),
-    ControlCommand_Push_Broadcast_Delete(0x02, "ControlCommand_Push_Broadcast_Delete"),
-    ControlCommand_Broadcast_Delete     (0x03, "ControlCommand_Broadcast_Delete"),
-    ControlCommand_Wireless_Stop        (0x04, "ControlCommand_Wireless_Stop"),
-    ControlCommand_Wireless_Start       (0x05, "ControlCommand_Wireless_Start");
-
-    private final int value;
-    private final String string;
-
-    private static final Map<Integer, eControlCommand> map;
-    static {
-        map = new HashMap<>();
-        for (eControlCommand e : values()) {
-            map.put(Integer.valueOf(e.value), e);
-        }
-    }
-    public static eControlCommand getByValue(int value) {
-        return map.get(Integer.valueOf(value));
-    }
-    public static eControlCommand getByValue(byte value) {
-        int intValue = (int)(value & 0x0F);
-        return map.get(Integer.valueOf(intValue));
-    }
-
-    eControlCommand(int value, String string) {
-        this.value  = value;
-        this.string = string;
-    }
-
-    public int getValue() {
-        return this.value;
-    }
-    public String toString() {
-        return this.string;
-    }
-}

+ 0 - 43
src/main/java/com/its/vms/xnettcp/vms/protocol/enums/eControlDeviceId.java

@@ -1,43 +0,0 @@
-package com.its.vms.xnettcp.vms.protocol.enums;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public enum eControlDeviceId {
-
-    ControlDeviceId_Controller (0x00, "ControlDeviceId_Controller"),
-    ControlDeviceId_Antena1    (0x01, "ControlDeviceId_Antenna1"),
-    ControlDeviceId_Antena2    (0x02, "ControlDeviceId_Antenna2"),
-    ControlDeviceId_Antena3    (0x03, "ControlDeviceId_Antenna3"),
-    ControlDeviceId_Antena4    (0x04, "ControlDeviceId_Antenna4");
-
-    private final int value;
-    private final String string;
-
-    private static final Map<Integer, eControlDeviceId> map;
-    static {
-        map = new HashMap<>();
-        for (eControlDeviceId e : values()) {
-            map.put(Integer.valueOf(e.value), e);
-        }
-    }
-    public static eControlDeviceId getByValue(int value) {
-        return map.get(Integer.valueOf(value));
-    }
-    public static eControlDeviceId getByValue(byte value) {
-        int intValue = (int)(value & 0x0F);
-        return map.get(Integer.valueOf(intValue));
-    }
-
-    eControlDeviceId(int value, String string) {
-        this.value  = value;
-        this.string = string;
-    }
-
-    public int getValue() {
-        return this.value;
-    }
-    public String toString() {
-        return this.string;
-    }
-}

+ 47 - 0
src/main/java/com/its/vms/xnettcp/vms/protocol/enums/eVmsFileSaveLocation.java

@@ -0,0 +1,47 @@
+package com.its.vms.xnettcp.vms.protocol.enums;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public enum eVmsFileSaveLocation {
+    LOC_DOWNLOAD_FILE         (0x00, "0x00.파일명에 포함"),
+    LOC_DOWNLOAD_PROG         (0x01, "0x01.로컬 프로그램이 속하여 있는 디렉토리에 저장"),
+    LOC_DOWNLOAD_PROG_ROOT    (0x02, "0x02.로컬 프로그램이 설치된 루트 디렉토리에 저장"),
+    LOC_DOWNLOAD_WIN          (0x03, "0x03.윈도우즈 디렉토리에 저장"),
+    LOC_DOWNLOAD_WIN_SYS      (0x04, "0x04.윈도우즈 시스템 디렉토리에 저장"),
+    LOC_DOWNLOAD_PROG_IMAGE   (0x05, "0x05.로컬 프로그램 이미지 디렉토리에 저장"),
+    LOC_DOWNLOAD_PROG_DEFAULT (0x06, "0x06.로컬 프로그램 디폴트 폼 디렉토리에 저장");
+
+    private final int value;
+    private final String string;
+
+    private static final Map<Integer, eVmsFileSaveLocation> map;
+    static {
+        map = new HashMap<>();
+        for (eVmsFileSaveLocation e : values()) {
+            map.put(e.value, e);
+        }
+    }
+
+    public static eVmsFileSaveLocation getValue(int value) {
+        return map.get(value);
+    }
+    public static eVmsFileSaveLocation getValue(byte value) {
+        int intValue = (value & 0x0F);
+        return map.get(intValue);
+    }
+
+    eVmsFileSaveLocation(int value, String string) {
+        this.value  = value;
+        this.string = string;
+    }
+
+    public int getValue() {
+        return this.value;
+    }
+
+    @Override
+    public String toString() {
+        return this.string;
+    }
+}

+ 61 - 0
src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsReqDataDownload.java

@@ -0,0 +1,61 @@
+package com.its.vms.xnettcp.vms.protocol.impl;
+
+import com.its.vms.dto.TbVmsCtlrDto;
+import com.its.vms.xnettcp.vms.protocol.VmsFramePacket;
+import com.its.vms.xnettcp.vms.protocol.VmsReqFramePacket;
+import com.its.vms.xnettcp.vms.protocol.enums.eVmsFileSaveLocation;
+import com.its.vms.xnettcp.vms.protocol.enums.eVmsOpCode;
+import com.its.vms.xnettcp.vms.protocol.impl.dle.VmsDleFramePacket;
+import lombok.extern.slf4j.Slf4j;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/**
+ * Data Download 요청
+ */
+@Slf4j
+public class VmsReqDataDownload implements VmsReqFramePacket {
+
+    private VmsFramePacket framePacket;
+
+    public VmsReqDataDownload(TbVmsCtlrDto vmsObj, eVmsFileSaveLocation saveLoc, String fileName, byte[] data) {
+        if (vmsObj.getProtocolVer() == 0) {
+            this.framePacket = new VmsDleFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getCtlrLocalNo(), (byte)eVmsOpCode.OP_VMS_DATA_DOWNLOAD.getValue());
+        }
+        makeBody(saveLoc, fileName, data);
+    }
+
+    public void makeBody(eVmsFileSaveLocation saveLoc, String fileName, byte[] data) {
+//        Download Data 저장 위치 Code   1
+//        파일명 길이                    1
+//        저장하여야 할 데이터의 크기    4
+//        저장할 파일명                  n
+//        다운로드 데이터                n
+        int fileNameSize = fileName.length();
+        int dataSize = data.length;
+        int bodySize = 6 + fileNameSize + dataSize;
+        log.info("VmsReqDataDownload.makeBody: bodySize {}", bodySize);
+        ByteBuffer byteBuffer = ByteBuffer.allocate(bodySize);
+        byteBuffer.order(ByteOrder.BIG_ENDIAN);
+
+        byteBuffer.put((byte)(saveLoc.getValue() & 0xFF));
+        byteBuffer.put((byte)(fileNameSize & 0xFF));
+        byteBuffer.putInt(dataSize);
+        byteBuffer.put(fileName.getBytes());
+        byteBuffer.put(data);
+
+        this.framePacket.setBody(byteBuffer.array());
+    }
+
+    @Override
+    public ByteBuffer getByteBuffer() {
+        return this.framePacket.getByteBuffer();
+    }
+
+    @Override
+    public String getOpCodeDesc() {
+        return this.framePacket.getOpCodeDesc();
+    }
+
+}

+ 16 - 10
src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsReqDownloadFormSchedule.java

@@ -3,34 +3,40 @@ package com.its.vms.xnettcp.vms.protocol.impl;
 import com.its.vms.dto.TbVmsCtlrDto;
 import com.its.vms.xnettcp.vms.protocol.VmsFramePacket;
 import com.its.vms.xnettcp.vms.protocol.VmsReqFramePacket;
-import com.its.vms.xnettcp.vms.protocol.dto.VmsFormDataDto;
 import com.its.vms.xnettcp.vms.protocol.enums.eVmsOpCode;
 import com.its.vms.xnettcp.vms.protocol.impl.dle.VmsDleFramePacket;
 import lombok.extern.slf4j.Slf4j;
 
 import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
 
 /**
- * Download Schedule Form 요청
+ * Download Form Schedule 요청
  */
 @Slf4j
 public class VmsReqDownloadFormSchedule implements VmsReqFramePacket {
 
     private VmsFramePacket framePacket;
 
-    private VmsFormDataDto formData;
-    private byte[] body;
-    public VmsReqDownloadFormSchedule(TbVmsCtlrDto vmsObj, VmsFormDataDto formData) {
+    public VmsReqDownloadFormSchedule(TbVmsCtlrDto vmsObj, short[] formId, byte[] dispSec) {
         if (vmsObj.getProtocolVer() == 0) {
             this.framePacket = new VmsDleFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getCtlrLocalNo(), (byte)eVmsOpCode.OP_VMS_DOWNLOAD_FORM_SCHEDULE.getValue());
         }
-        this.formData = formData;
+        makeBody(formId, dispSec);
     }
 
-    public void setBody(byte[] schedule) {
-        this.body = new byte[schedule.length];
-        System.arraycopy(schedule, 0, this.body, 0, this.body.length);
-        this.framePacket.setBody(this.body);
+    public void makeBody(short[] formId, byte[] dispSec) {
+        int bodySize = (2 * formId.length) + (dispSec.length);
+        log.info("VmsReqDownloadFormSchedule.makeBody: bodySize {}", bodySize);
+        ByteBuffer byteBuffer = ByteBuffer.allocate(bodySize);
+        byteBuffer.order(ByteOrder.BIG_ENDIAN);
+
+        for (int ii = 0; ii < formId.length; ii++) {
+            byteBuffer.putShort((short)(formId[ii] & 0xFFFF));    // 폼 ID
+            byteBuffer.put((byte)(dispSec[ii] & 0xFF));           // 폼 표출시간
+        }
+
+        this.framePacket.setBody(byteBuffer.array());
     }
 
     @Override

+ 1 - 0
src/main/resources/application.yml

@@ -23,6 +23,7 @@ application:
   text-traf-grad3: 정 체
   image-seq-save: false
   font-size-ratio: 1.35
+  check-new-form: true
 
 communication:
   listen-port: 30200