11 KiB
11 KiB
GS (DtrGuiSrv) <--> GC (GUI Client) 互動分析
系統架構
┌─────────────────────────────────────────────────────────────────────┐
│ RAIDGuard X 系統架構 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ GC (GUI) │ │ GS (Server) │ │
│ │ RAIDGuard X │◄────────►│ DtrGuiSrv │ │
│ │ (Java Swing) │ Port │ (C Program) │ │
│ │ │ 8922 │ │ │
│ └─────────────────┘ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ In-Band API │ │
│ │ (RAID Controller)│ │
│ │ Port 8922 │ │
│ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
通訊流程
1. 連線建立
GC (Client) GS (Server)
│ │
│──── connect(8922) ─────────────────►│
│◄──── accept() ─────────────────────│
│ │
│──── Phase1: Length ────────────────►│
│◄──── Phase1: Ack ───────────────────│
│ │
│──── Phase2: Data ──────────────────►│
│◄──── Phase2: Response ──────────────│
│ │
│ ... (重複) ... │
│ │
│──── close() ───────────────────────►│
2. 傳輸協議 (TCP Port 8922)
GS 作為 TCP Server,監聽 Port 8922。
// cNetWork.c
#define DTR_GUI_PORT 8922
SHORT InitialSrvSocket(ULONG SerPortNum, ULONG ClientConnectionAllow) {
server_sockfd = socket(AF_INET, SOCK_STREAM, 0x00);
bind(server_sockfd, ...);
listen(server_sockfd, ClientConnectionAllow);
return server_sockfd;
}
請求類型
| Request Type | 值 | 說明 |
|---|---|---|
| REQ_INBAND_COMMAND | 0x01 | In-Band 命令 (轉發到 RAID 控制器) |
| REQ_SERVER_CONFIG | 0x02 | 伺服器設定 (SMTP, Email 等) |
Request 格式
┌─────────────────────────────────────────────────────────────┐
│ Request Package │
├─────────────────────────────────────────────────────────────┤
│ Byte 0 │ Byte 1 │ Byte 2-3 │ Byte 4+ │
├─────────────────────────────────────────────────────────────┤
│ Req Type │ Phase Code │ Length │ Data │
│ (0x01/0x02)│ │ (LE) │ │
└─────────────────────────────────────────────────────────────┘
Response 格式
┌─────────────────────────────────────────────────────────────┐
│ Response Package │
├─────────────────────────────────────────────────────────────┤
│ Byte 0 │ Byte 1 │ Byte 2 │ Byte 3+ │
├─────────────────────────────────────────────────────────────┤
│ Phase Code │ Req Code │ Ctrl No │ Data / Error Code │
│ 0x50 │ │ │ │
└─────────────────────────────────────────────────────────────┘
處理流程
GS 端處理 (cNetWork.c)
// 主迴圈
while(1) {
client_sockfd = accept(server_sockfd, ...);
// 接收請求
GUITrans(client_sockfd, pInBuffer, ...); // Phase 1
GUITrans(client_sockfd, pInBuffer, ...); // Phase 2
// 解析請求類型
switch(pInBuffer[0]) {
case REQ_INBAND_COMMAND: // 0x01
// 取得 Controller ID
iCtlrID = SNtoCtlrID(sSN);
// 轉發到 RAID 控制器
bStatus = HandleInBandReq(&ReqPackage, iCtlrID, &usInBandErrCode);
break;
case REQ_SERVER_CONFIG: // 0x02
// 處理伺服器設定
bStatus = HandleSrvConfigReq(&ReqPackage);
break;
}
// 發送回應
ServerGUITrans(&ReqPackage);
}
GC 端請求範例
1. 取得頁面資料 (GET_PAGE)
// InBandAPI/SendCmd.java
// 組建命令
byte[] bCmds = new byte[...];
bCmds[0] = 0x00; // Phase Code
bCmds[1] = 0x00; // Request Code
bCmds[2] = 0x00; // Controller No
bCmds[3] = 0x01; // OpCode: GET_PAGE
bCmds[4] = 0x03; // Length
bCmds[5] = pageCode; // Page Code (0x00, 0x01, 0x07, etc.)
2. 發送密碼 (SEND_PASSWORD)
bCmds[3] = 0x1D; // OpCode: SEND_PASSWORD
bCmds[4] = 0x08; // Length (8 bytes)
// bCmds[5-12] = password bytes
3. 取得事件 (Get InBand Event)
bCmds[0] = 0xFF; // Phase Code
bCmds[1] = 0x00; // Request Code
bCmds[2] = 0x00; // Controller No
bCmds[3] = 0x02; // OpCode: Get Event
資料傳輸函數
GS 端 (cNetWork.c)
UCHAR GUITrans(SHORT sd, PUCHAR pInBuffer, ULONG InBufferLength, SHORT flg_trans) {
while(LastByte) {
if(flg_trans == SERVER_READ) {
ByteSend = recv(sd, pBaseAddr, LastByte, 0x00);
} else if(flg_trans == SERVER_WRITE) {
ByteSend = send(sd, pBaseAddr, LastByte, 0x00);
}
LastByte -= ByteSend;
pBaseAddr += ByteSend;
}
return SYSOK;
}
UCHAR ServerGUITrans(PNET_REQ_PACKAGE pReqPackage) {
// Phase 1: 傳輸長度
if(pReqPackage->direction == SERVER_READ) {
// 接收長度
} else {
// 發送長度
Phase1Buf[0] = TRANS_PHASE1;
Phase1Buf[1] = (Length & 0xFF);
Phase1Buf[2] = ((Length >> 8) & 0xFF);
}
// Phase 2: 傳輸資料
pReqPackage->pOutBuffer[0] = TRANS_PHASE2;
GUITrans(..., SERVER_WRITE);
return SYSOK;
}
錯誤處理
錯誤回應格式
Byte 0: Phase Code
Byte 1: Request Code
Byte 2: Controller Number
Byte 3: Error Code
Byte 4-5: InBand Error Code (LSB ~ MSB)
常見錯誤碼
| 錯誤碼 | 說明 |
|---|---|
| 0x50 | 成功 (Success) |
| 0x4x | 失敗 (Fail) |
| SYSFAIL_SERSVE_RESEND_FAIL | 傳輸失敗 |
| SYSFAIL_INBAND_SN_NOT_MATCH | SN 不匹配 |
關鍵檔案對應
GS 端 (C)
| 檔案 | 功能 |
|---|---|
| cNetWork.c | TCP 網路通訊 |
| cInBand.c | In-Band API 處理 |
| cPollingEvent.c | 事件輪詢 |
| cMail.c | Email 發送 |
| cShareMem.c | 共享記憶體 |
GC 端 (Java)
| 檔案 | 功能 |
|---|---|
| SendCmd.java | TCP 通訊封裝 |
| CmdQueue.java | 命令排程 |
| PageDataDB.java | 資料儲存 |
| frmMain.java | 主介面 |
通訊序列圖
GC GS RAID Controller
│ │ │
│── TCP Connect(8922) ──►│ │
│◄── Accept ─────────────│ │
│ │ │
│── REQ_INBAND_COMMAND ─►│ │
│ (GET_PAGE) │ │
│ │── InBand Protocol ───────►│
│ │◄── Page Data ───────────│
│◄─ Page Data ──────────│ │
│ │ │
│── REQ_INBAND_COMMAND ─►│ │
│ (SEND_PASSWORD) │ │
│ │── InBand Protocol ───────►│
│ │◄── Status ──────────────│
│◄─ Status ─────────────│ │
│ │ │
│── TCP Close ──────────│ │
連接埠
| Port | 用途 |
|---|---|
| 8922 | GC ↔ GS 主要通訊 |
| 8922 | GS ↔ RAID Controller |
| 162 | SNMP Trap (可選) |
實作重點
- 雙向通訊: GS 同時連接 GC (客戶端) 和 RAID Controller (硬體)
- 協議轉發: GS 將 GC 的請求轉發給 RAID Controller
- 錯誤回傳: 錯誤從 RAID Controller → GS → GC
- 長連接: 使用 TCP keep-alive 維持連線
- 共享記憶體: GS 與本機 RAID Driver 共享資料