# Dump Controller Log 實現分析 ## 流程架構 ``` ┌─────────────────────────────────────────────────────────────┐ │ frmMain.jmDumpEventLog_actionPerformed() │ │ (根據型號選擇使用 dlgDumpLog 或 dlgDumpLog2) │ └──────────────────────────┬──────────────────────────────────┘ │ ┌───────────────┴───────────────┐ ▼ ▼ ┌──────────────┐ ┌──────────────┐ │ dlgDumpLog │ │ dlgDumpLog2 │ │ (舊型號) │ │ (新型號) │ └──────────────┘ └──────────────┘ │ │ └───────────┬───────────────────┘ ▼ ┌──────────────────────────┐ │ dumpEventLog() │ │ TCP 連線 Port 8922 │ └───────────┬──────────────┘ ▼ ┌──────────────────────────┐ │ OpCode: 0x01 │ │ SubOp: 0x03 │ │ Page: 0x60 ~ 0x64 │ └───────────┬──────────────┘ ▼ ┌──────────────────────────┐ │ 寫入 ./Log 目錄 │ │ 壓縮為 ZIP 檔 │ └──────────────────────────┘ ``` ## 通訊協定 ### Request ``` Head: [0x01, 0x17, 0x00, 0x00, 0x00] (23 bytes) Data: [0x02, 0x01, SN(16 bytes), CDB(5 bytes)] ``` ### CDB 結構 | Offset | 值 | 說明 | |--------|-----|------| | 0 | 0x01 | OpCode - GET_PAGE | | 1 | 0x03 | SubOp | | 2 | 0x60-0x64 | Page Code (Log Type) | | 3 | LSB | Block Index | | 4 | MSB | Block Index | ### Log Types | Page | 說明 | |------|------| | 0x60 | System Log | | 0x61 | Event Log | | 0x62 | I/O Error Log | | 0x63 | Dump Log | | 0x64 | Reserved | ## 實現細節 ### dlgDumpLog.java ```java // 1. 連線到控制器 theSocket.connect(new InetSocketAddress(PageDataDB.GuiSrvIpAddr, Port), 10000); // 2. 發送请求 (OpCode 0x01, SubOp 0x03) Cdb[0] = 0x01; // GET_PAGE Cdb[1] = 0x03; // SubOp Cdb[2] = 0x60; // Log type (0x60-0x64) Cdb[3] = BlockIndexLSB; Cdb[4] = BlockIndexMSB; // 3. 解析回應 arg[0] = reply[9]; // Status (0x50 = Success) arg[1] = reply[12]; // Page code arg[2] = startBlock; arg[3] = totalBlocks; // 4. 寫入檔案 (./Log 目錄) File file = getFile((byte)arg[1]); fileOut.write(reply, 15, 512); // 寫入 512 bytes // 5. 壓縮成 ZIP compressLog(); // 打包成 Log_YYYYMMDD_HHMMSS.zip ``` ### 迴圈邏輯 ```java // 遍历 5 種 log 類型 for (byte i = 0x60; i <= 0x64; i++) { // 取得該類型的 log 總量 arg1 = dumpEventLog(Cdb); // 遍历每個 block for (int j = arg1[2]; j < arg1[3]; j++) { Cdb[3] = (byte)(j & 0xFF); // LSB Cdb[4] = (byte)((j >> 8) & 0xFF); // MSB arg2 = dumpEventLog(Cdb); // 寫入單個 block fileOut.write(reply, 15, 512); } } ``` ## 輸出檔案 - **目錄**: `./Log/` - **格式**: `Log_YYYYMMDD_HHMMSS.zip` - **內容**: 5 個 log 類型的原始資料 (各 512 bytes/block) ## 關鍵類 | 類別 | 檔案 | 功能 | |------|------|------| | `frmMain` | frmMain.java:4136 | 入口,選擇 dialog 版本 | | `dlgDumpLog` | dlgDumpLog.java | 舊型號使用 (單一控制器) | | `dlgDumpLog2` | dlgDumpLog2.java | 新型號使用 (支援多控制器) | | `SendCmd` | InBandAPI/SendCmd.java | TCP 通訊底層 | ## Code Flow ### 1. Menu 點擊 ``` frmMain.jmDumpControllerLog (MenuItem) → frmMain.jmDumpEventLog_actionPerformed() → 檢查型號選擇 dlgDumpLog 或 dlgDumpLog2 ``` ### 2. Dump 執行 ``` dlgDumpLog.run() → for (0x60 ~ 0x64) { dumpEventLog() 取得總量 for (每個 block) { dumpEventLog() 取得資料 寫入檔案 } } → compressLog() 壓縮 → dispose() ``` ### 3. Socket 通訊 ``` dumpEventLog(Cdb) → connect(Port 8922) → send(Head + SN + CDB) → read(reply) → parse status & data → close() ```