diff --git a/GC_DumpControllerLog.md b/GC_DumpControllerLog.md index 56e437f..8db0469 100644 --- a/GC_DumpControllerLog.md +++ b/GC_DumpControllerLog.md @@ -317,3 +317,186 @@ zout.write(byte[] data); zout.closeEntry(); zout.close(); ``` + +--- + +## .bin 檔案解析 + +### 原始資料格式 + +控制器回傳的資料包含 **Header + Data**: + +``` +┌─────────────────────────────────────────────┐ +│ Controller Response │ +├─────────┬───────────────────────────────────┤ +│ Offset │ Description │ +├─────────┼───────────────────────────────────┤ +│ 0-2 │ Total Length (2 bytes) │ +│ 3 │ (continuation?) │ +│ 4-8 │ Unknown │ +│ 9 │ Status (0x50 = Success) │ +│ 10-11 │ Unknown │ +│ 12 │ Page Code (0x60-0x64) │ +│ 13-14 │ 0xFF 0xFF (flag) │ +│ 15-18 │ Log Count (4 bytes) │ +│ 19-22 │ Start Block (4 bytes) │ +│ 23-26 │ Total Blocks (4 bytes) │ +├─────────┴───────────────────────────────────┤ +│ 15-511 │ Actual Data (496 bytes) │ +└─────────┴───────────────────────────────────┘ +``` + +### 寫入 .bin 檔案的程式碼 + +```java +// 從 reply[15] 開始,寫入 512 bytes +fileOut.write(reply, 15, 512); +``` + +所以 .bin 檔案內容是: +- **每筆 512 bytes** +- **包含 header 資訊** + +### 解析方式 + +#### 1. 解析 Header + +```python +def parse_bin_header(block): + # block 是 512 bytes + status = block[9] # 0x50 = Success + page_code = block[12] # 0x60-0x64 + log_count = int.from_bytes(block[15:19], 'little') + start_block = int.from_bytes(block[19:23], 'little') + total_blocks = int.from_bytes(block[23:27], 'little') + data = block[15:] # 實際資料 + + return { + 'status': status, + 'page_code': page_code, + 'log_count': log_count, + 'start_block': start_block, + 'total_blocks': total_blocks, + 'data': data + } +``` + +#### 2. 解析各類型 Log + +| Page Code | 類型 | 資料格式 | +|-----------|------|----------| +| 0x60 | EventPage.bin | 32 bytes/record | +| 0x61 | DebugPage.bin | 32 bytes/record | +| 0x62 | DiskMetadataPage.bin | 32 bytes/record | +| 0x63 | SpecialLogPage.bin | 48 bytes/record | +| 0x64 | TelMesPages.log | 40 bytes/record (特殊處理) | + +#### 3. Python 解析範例 + +```python +import struct +import datetime + +def parse_event_log(data): + """解析 Event Page (0x60)""" + records = [] + for i in range(0, len(data), 32): + if i + 32 > len(data): + break + record = data[i:i+32] + + # 解析 timestamp (假設格式) + timestamp = struct.unpack(' LogHeader { + LogHeader { + status: block[9], + page_code: block[12], + log_count: u32::from_le_bytes([block[15], block[16], block[17], block[18]]), + start_block: u32::from_le_bytes([block[19], block[20], block[21], block[22]]), + total_blocks: u32::from_le_bytes([block[23], block[24], block[25], block[26]]), + } +} + +fn main() { + let mut file = File::open("EventPage.bin").unwrap(); + let mut buffer = [0u8; 512]; + + let mut block_num = 0; + while file.read(&mut buffer).unwrap() > 0 { + let header = parse_bin_header(&buffer); + println!("Block {}: status={:02x}, page={:02x}", + block_num, header.status, header.page_code); + block_num += 1; + } +} +```