# USB 探頭協議（靜態重構）

> 來源：`UsbProbeManager`、`HUsbProbeInterface`、`HSUsbProbe`（jadx）＋ `libdoppler/libHSocketIf/libh264rtp` 導出符號。純靜態推斷，未經硬件驗證。

## 1. USB 設備層

| 項 | 值 | 證據 |
|---|---|---|
| VID | `0x04B4`（1204） | `HUsbProbeInterface.PROBE_VID` |
| PID | `0x1004`（4100） | `HUsbProbeInterface.PROBE_PID` |
| VID 含義 | **Cypress Semiconductor** | 0x04B4 為 Cypress 註冊 VID → FX2/FX3 系 USB 控制器 |
| 控制傳輸 | EP0，setup 8 B / buffer 64 B | `USB_EP0_BUF_LEN=64`、`USB_SETUPDATA_LEN=8` |
| 數據傳輸 | **EP6 bulk，FIFO 2,048 B** | `USB_EP6_FIFO_SIZE=2048`（Cypress FX3 特徵） |
| 設備枚舉 | 動態掃描（不硬編碼 VID/PID 過濾），分三路 | `ScanHUsbProbe`/`ScanHSUsbProbe`/`ScanHRProbe` |

探頭驅動類譜系（`handprobe.components.usb`）：

```
HUsbProbe (基類)
├── HSUsbProbe ── HSUsbProbeCh16   (FPGA ch16 系列，mProbeType=4)
├── HRUsbProbe                     (R 系列)
├── HRTLUsbProbe                   (Realtek 方案)
└── HCyRTLUsbProbe                 (Cypress/Realtek 組合?)
```

## 2. FPGA 地址空間（影像流讀寫直接定址）

| 常量 | 值 | 用途 |
|---|---|---|
| `FPGA_BIMG_ADDR` | 131,072（0x20000） | B 模式影像 |
| `FPGA_CIMG_ADDR` | 131,072 | C（Color）影像 |
| `FPGA_H264_ADDR` | 262,144（0x40000） | H.264 編碼流 |
| `FPGA_TIMG_ADDR` | 393,216（0x60000） | T/M 模式影像 |

影像幀尺寸：B/C 各 131,072 B（128 KB）；M 8,192 B；PW 2,048 B；T 10,240 B。
RF 採集模式（`mRFGather`）讀 2,097,152 B（2 MB 全緩衝 `mImgBuf`）。

## 3. 讀取循環（USB_ImgReadThread，priority=10）

```
loop:
  CheckImgUpload() → bitmask
    bit0 (1): B 影像就緒
    bit1 (2): M/PW 就緒
    bit2 (4): C 影像就緒
  ConType 3 (WUSB):
    ReadBCImage → HH264PlayerIf.WUsbSignalBCImg   (H.264 流解碼路徑)
  ConType 4 (USB):
    probeType==6: GetImgPack → HH264PlayerIf.RUsbSignalImgReady
    else:
      Read(0x20000, mImgBuf, RF?2MB:128KB)
      mImgBuf[0] < 0  →  HDscClassIf.Reserse(buf, 131072)   ← 方向標記!
      (SIMU 模式: simdat++ 填 ramp 假數據)
  DispMode 分支:
    5  → Read(0x60000, mTImgBuf, 2048)   → PW 隊列 → HH264PlayerIf.PackD
    9  → Read(0x60000, mMImgBufCache, 10240) → 4×2048 分包 → HH264PlayerIf.PackM
    8/55 → Read(0x20000, mCImgBuf, 131072) → 拼入 mImgBuf[131072..262144]
```

### 「EncImg」真相

`jnitojava.WUsbReadImg` → `UsbProbeManager.ReadEncImg` → `mUsbInterface.ReadBCImage()`。
「Enc」= **BC（B+C 合成）影像**的縮寫，**不是加密**。安全結論：USB 影像流為明文位元組流；幀首 byte 最高位是**影像方向（正/反）標記**（負值 → `HDscClassIf.Reserse` 整幀反轉），無加密層。

## 4. 寫入路徑（FPGA 寄存器/參數）

- `Write(addr, data, len)` → 隊列 `UWlanWriteQueueElem{addr,data,len}` → 寫線程：
  - USB（ConType 4）：直接 `mUsbInterface.Write`
  - UWLAN（ConType 5）：`WlanProbe.mICmdHandler.UWriteFPGA(addr,data,len)`；`TCP_PARA` 時走 `UWriteFPGA_TCP`（TCP 通道傳 FPGA 寄存器寫）
- WLAN 讀取：`UReadFPGA(addr, out, len)` / `UReadFPGA_TCP`，1.5 s 信號量超時

## 5. 探頭授權體系（EEPROM 功能位）

`HSUsbProbe` 定義探頭 EEPROM 授權地址表：

| EEPROM 地址 | 內容 |
|---|---|
| 32,764 | 探頭序列號（`EEPROM_SN_ADDR`） |
| 28,160 | 探頭 SN（64 B 讀取） |
| 28,192 | 板卡 SN |
| 28,312 | **OEM ID**（App 側 `CheckOEMId(GetProbeOemId())` 強制匹配） |
| 28,224 | **DICOM 功能授權** |
| 28,240 | **PW 多普勒授權** |
| 28,256 | **Color 授權** |
| 28,288 | **B 模式授權** |
| 28,308 | **人/獸醫模式授權** |

- `VerifyAuth()`：讀 EEPROM SN + 探頭 SN（首 byte 合法性檢查 `!=-1 && !=204`）→ 拼接 `SN-XXXX` 標識 → 授權
- `WriteAuthCode()` / vendor request `VR_USB_SET_AUTH=24` → 寫回授權（廠商售後解鎖通道）
- **`HSUsbProbeCh16.VerifyAuth()` 直接 `return true`**（ch16 探頭無 SN 認證——可能 ch16 系無 EEPROM 或授權移至 App 側）
- `UpdateDicomAuth()`：DICOM 授權經 USB 通道更新

### 商業模式解讀

功能授權（B/C/PW/DICOM/人獸醫）儲存於**探頭硬件 EEPROM**，而非 App：換 App/設備不能解鎖高階功能；廠商經 vendor request 寫碼解鎖。OEM ID 鎖死探頭與白牌 App 的匹配（探頭不能跨品牌用）。

## 6. Wi-Fi 探頭協議（`handprobe.application.wlan`）

- 命令框架：`CmdParser` / `CmdInfo` / `BaseCmdHandler` → `CmdHandler` / `WlanCmdHandler`
- 傳輸：`WlanHost` / `WlanClient` / `WlanProbe`（多主機 `GetMultiHost()`）
- 序列化：`protocol.Tools`（Hex/ASCII 轉換、`StrToHex_r`、`IntToByte_o`——大小端雙向）
- 雙通道：UDP 命令 + 可選 `TCP_PARA`（TCP 參數通道）
- `JsonParam` 標籤：`Tag_probe_id` 等 JSON 配置項

## 7. 未解（需硬件/動態）

1. `CheckImgUpload` 的具體實現（寄存器 or EP 中斷）
2. H.264 流格式（`WUsbSignalBCImg` 輸入的碼流封裝）
3. vendor request 完整碼表（除 24/81 外）
4. WLAN 命令碼錶（`CmdInfo` 枚舉值）
