162 lines
4.8 KiB
Markdown
162 lines
4.8 KiB
Markdown
# 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()
|
|
```
|