Add GS <--> GC interaction analysis
This commit is contained in:
@@ -0,0 +1,281 @@
|
||||
# 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。
|
||||
|
||||
```c
|
||||
// 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)
|
||||
|
||||
```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)
|
||||
|
||||
```java
|
||||
// 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)
|
||||
|
||||
```java
|
||||
bCmds[3] = 0x1D; // OpCode: SEND_PASSWORD
|
||||
bCmds[4] = 0x08; // Length (8 bytes)
|
||||
// bCmds[5-12] = password bytes
|
||||
```
|
||||
|
||||
### 3. 取得事件 (Get InBand Event)
|
||||
|
||||
```java
|
||||
bCmds[0] = 0xFF; // Phase Code
|
||||
bCmds[1] = 0x00; // Request Code
|
||||
bCmds[2] = 0x00; // Controller No
|
||||
bCmds[3] = 0x02; // OpCode: Get Event
|
||||
```
|
||||
|
||||
## 資料傳輸函數
|
||||
|
||||
### GS 端 (cNetWork.c)
|
||||
|
||||
```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 (可選) |
|
||||
|
||||
## 實作重點
|
||||
|
||||
1. **雙向通訊**: GS 同時連接 GC (客戶端) 和 RAID Controller (硬體)
|
||||
2. **協議轉發**: GS 將 GC 的請求轉發給 RAID Controller
|
||||
3. **錯誤回傳**: 錯誤從 RAID Controller → GS → GC
|
||||
4. **長連接**: 使用 TCP keep-alive 維持連線
|
||||
5. **共享記憶體**: GS 與本機 RAID Driver 共享資料
|
||||
Reference in New Issue
Block a user