Release DLL-only UPM package v0.1.2 docs

This commit is contained in:
su 2026-08-04 19:08:10 +08:00
parent daa53abdad
commit 249fe589c7
24 changed files with 887 additions and 1402 deletions

View File

@ -1,4 +1,12 @@
# Changelog
# Changelog
## 0.1.2
- Updated public documentation to use the official Git URL: `https://git.aisu.xin/aisu-sdk/si-m1-face-package.git`.
- Added Chinese counterparts for public entry documents.
- Rewrote the API reference and documented all callback-style APIs.
- Removed public local `file:` install examples from user-facing docs.
- Removed old single-language internal/protocol notes from the public package documentation set.
## 0.1.1

View File

@ -1,4 +1,6 @@
# Demo UI
# Demo UI
中文说明见 [README_UI.zh-CN.md](README_UI.zh-CN.md).
The public DLL-only UPM package does not include Demo UI source files or importable sample scenes.

View File

@ -0,0 +1,13 @@
# Demo UI
English documentation: [README_UI.md](README_UI.md).
公开 DLL-only UPM 包不包含 Demo UI 源码,也不包含可导入的示例场景。
请在自己的 Unity 场景中通过以下菜单创建 `FaceModuleManager`
```text
AISU/SI-M1 Face SDK/Create Manager GameObject
```
如需 Demo UI 源码、示例场景或内部验证测试,请使用私有开发 SDK 仓库。

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 5cb8b30bc471e4c4298b2344b3cbf397
guid: 19c2f555d276460b82d31f7854e4b8f1
TextScriptImporter:
externalObjects: {}
userData:

View File

@ -1,215 +1,181 @@
# SI-M1 Face SDK 接口文档
# SDK API Reference
本文列出 SDK 对业务层推荐使用的公开 API。命名空间统一为 `Aisu.SIM1.Face.*`
中文说明见 [SDK_API_Reference.zh-CN.md](SDK_API_Reference.zh-CN.md).
## 1. 命名空间
This document lists the public business-level API exposed by `xin.aisu.si-m1.face`. The package is DLL-only; source files are not included in the public release.
| 命名空间 | 说明 |
## Namespaces
| Namespace | Description |
|---|---|
| `Aisu.SIM1.Face.Core` | Manager、配置、回调适配、日志、主线程调度 |
| `Aisu.SIM1.Face.Commands` | 业务服务、命令服务、加密接口 |
| `Aisu.SIM1.Face.Protocol` | 协议枚举、封包、拆包、编码工具 |
| `Aisu.SIM1.Face.Transport` | 通信接口、串口、Mock |
| `Aisu.SIM1.Face.Models` | Reply、Note、用户、验证、录入、图片、UVC 等模型 |
| `Aisu.SIM1.Face.Core` | Manager, settings, callback adapter, logging, main-thread dispatch |
| `Aisu.SIM1.Face.Commands` | Business services, command service, encryption adapter |
| `Aisu.SIM1.Face.Protocol` | Protocol enums, packet build/parse helpers, encoding helpers |
| `Aisu.SIM1.Face.Transport` | Transport interface, serial transport, mock transport |
| `Aisu.SIM1.Face.Models` | Reply, note, user, verification, enrollment, image, and UVC models |
## 2. FaceModuleManager
## FaceModuleManager
`FaceModuleManager` 是 SDK 推荐的统一入口。
Use `FaceModuleManager` as the recommended single entry point:
```csharp
using Aisu.SIM1.Face.Core;
```
### 属性
### Properties
| 属性 | 类型 | 说明 |
| Property | Type | Description |
|---|---|---|
| `Basic` | `FaceBasicService` | 基础命令服务 |
| `Verify` | `FaceVerifyService` | 人脸验证服务 |
| `Enrollment` | `FaceEnrollmentService` | 人脸录入服务 |
| `Users` | `FaceUserService` | 用户管理服务 |
| `QrCode` | `FaceQrCodeService` | 二维码服务 |
| `Images` | `FaceImageService` | 图片抓拍与照片注册服务 |
| `Features` | `FaceFeatureService` | 特征读写服务 |
| `Uvc` | `FaceUvcService` | UVC 和高级参数服务 |
| `Encryption` | `FaceEncryptionService` | 加密相关服务 |
| `Callback` | `FaceModuleCallbackAdapter` | 回调式 API 适配 |
| `IsOpen` | `bool` | 通信是否打开 |
| `IsReady` | `bool` | 是否收到 READY |
| `CurrentStatus` | `FaceModuleStatus` | 当前模组状态 |
| `LastError` | `string` | 最近错误文本 |
| `CurrentCommand` | `string` | 当前命令名 |
| `Config` | `FaceModuleConfig` | 当前运行配置 |
| `Settings` | `FaceSdkSettings` | 当前绑定配置资产 |
| `Basic` | `FaceBasicService` | Basic module commands |
| `Verify` | `FaceVerifyService` | Face verification service |
| `Enrollment` | `FaceEnrollmentService` | Face enrollment service |
| `Users` | `FaceUserService` | User management service |
| `QrCode` | `FaceQrCodeService` | QR code service |
| `Images` | `FaceImageService` | Image capture and photo enrollment service |
| `Features` | `FaceFeatureService` | Feature read/write service |
| `Uvc` | `FaceUvcService` | UVC and advanced parameter service |
| `Encryption` | `FaceEncryptionService` | Encryption service |
| `Callback` | `FaceModuleCallbackAdapter` | Callback-style API adapter |
| `IsOpen` | `bool` | Whether the transport is open |
| `IsReady` | `bool` | Whether READY has been received |
| `CurrentStatus` | `FaceModuleStatus` | Current module status |
| `LastError` | `string` | Latest error message |
| `CurrentCommand` | `string` | Current command name |
| `Config` | `FaceModuleConfig` | Current runtime config |
| `Settings` | `FaceSdkSettings` | Bound settings asset |
### 方法
### Methods
| 方法 | 说明 |
| Method | Description |
|---|---|
| `ConfigureTransport(IFaceModuleTransport transport)` | 注入自定义通信层 |
| `Configure(bool useMockInEditor, string portName, int baudRate)` | 兼容旧代码的快速配置入口 |
| `ApplySettings(FaceSdkSettings sdkSettings)` | 应用 ScriptableObject 配置并重建 transport |
| `Open()` | 打开通信 |
| `Close()` | 关闭通信 |
| `WaitReadyAsync(int timeoutMs = 5000)` | 等待 READY NOTE |
| `ProbeReadyByStatusAsync()` | 主动查询状态并标记 READY |
| `SendRawBytes(byte[] bytes)` | 发送原始协议 bytes |
| `RefreshStatus()` | 异步刷新 `CurrentStatus` |
| `ConfigureTransport(IFaceModuleTransport transport)` | Inject a custom transport |
| `Configure(bool useMockInEditor, string portName, int baudRate)` | Quick configuration for legacy code |
| `ApplySettings(FaceSdkSettings sdkSettings)` | Apply ScriptableObject settings and rebuild transport |
| `Open()` | Open transport |
| `Close()` | Close transport |
| `WaitReadyAsync(int timeoutMs = 5000)` | Wait for READY note |
| `ProbeReadyByStatusAsync()` | Query status and mark manager ready |
| `SendRawBytes(byte[] bytes)` | Send raw protocol bytes |
| `RefreshStatus()` | Asynchronously refresh `CurrentStatus` |
### 事件
### Events
| 事件 | 说明 |
| Event | Description |
|---|---|
| `OnReady` | 首次 READY |
| `OnStatusChanged(FaceModuleStatus)` | 当前状态变化 |
| `OnReplyReceived(FaceReply)` | 收到 REPLY 包 |
| `OnNoteReceived(FaceNote)` | 收到 NOTE 包 |
| `OnFaceStateUpdated(FaceFaceStateNote)` | 收到人脸状态 NOTE |
| `OnQrCodeReceived(string)` | 收到二维码 NOTE |
| `OnFeatureReceived(byte[])` | 收到读取特征数据包 |
| `OnDataPacketReceived(FacePacket)` | 收到 ImageOrTemplate 数据包 |
| `OnError(FaceResultCode, string)` | 错误上报 |
| `OnRawLog(string)` | 原始 TX / RX 日志 |
| `OnReady` | First READY event |
| `OnStatusChanged(FaceModuleStatus)` | Module status changed |
| `OnReplyReceived(FaceReply)` | REPLY packet received |
| `OnNoteReceived(FaceNote)` | NOTE packet received |
| `OnFaceStateUpdated(FaceFaceStateNote)` | Face state NOTE received |
| `OnQrCodeReceived(string)` | QR code NOTE received |
| `OnFeatureReceived(byte[])` | Feature data packet received |
| `OnDataPacketReceived(FacePacket)` | Image/template data packet received |
| `OnError(FaceResultCode, string)` | Error reported |
| `OnRawLog(string)` | Raw TX/RX log |
## 3. 基础服务 FaceBasicService
## Async Services
访问路径:
### FaceBasicService
```csharp
manager.Basic
```
Access path: `manager.Basic`
| 方法 | 返回 | 说明 |
| Method | Return | Description |
|---|---|---|
| `ResetAsync()` | `Task<FaceReply>` | 复位模组 |
| `FaceResetAsync()` | `Task<FaceReply>` | 取消当前人脸流程 |
| `GetStatusAsync()` | `Task<FaceModuleStatus>` | 获取模组状态 |
| `GetVersionAsync()` | `Task<string>` | 获取固件版本 |
| `GetSnAsync()` | `Task<string>` | 获取设备序列号 |
| `SetDemoModeAsync(bool enable)` | `Task<FaceReply>` | 设置 Demo Mode |
| `UpgradeFirmwareAsync()` | `Task<FaceReply>` | 启动固件升级命令 |
| `ResetAsync()` | `Task<FaceReply>` | Reset module |
| `FaceResetAsync()` | `Task<FaceReply>` | Cancel current face flow |
| `GetStatusAsync()` | `Task<FaceModuleStatus>` | Get module status |
| `GetVersionAsync()` | `Task<string>` | Get firmware version |
| `GetSnAsync()` | `Task<string>` | Get device serial number |
| `SetDemoModeAsync(bool enable)` | `Task<FaceReply>` | Set Demo Mode |
| `UpgradeFirmwareAsync()` | `Task<FaceReply>` | Start firmware upgrade command |
## 4. 验证服务 FaceVerifyService
### FaceVerifyService
访问路径:
Access path: `manager.Verify`
```csharp
manager.Verify
```
| 方法 | 返回 | 说明 |
| Method | Return | Description |
|---|---|---|
| `VerifyAsync(byte timeout, byte maxRecognitionTimes = 30)` | `Task<FaceVerifyResult>` | 单次人脸验证 |
| `AutoVerifyAsync(bool enable, byte timeout)` | `Task<FaceVerifyResult>` | 启用或关闭自动验证 |
| `VerifyAsync(byte timeout, byte maxRecognitionTimes = 30)` | `Task<FaceVerifyResult>` | Run one face verification |
| `AutoVerifyAsync(bool enable, byte timeout)` | `Task<FaceVerifyResult>` | Enable or disable automatic verification |
## 5. 录入服务 FaceEnrollmentService
### FaceEnrollmentService
访问路径:
Access path: `manager.Enrollment`
```csharp
manager.Enrollment
```
| 方法 | 返回 | 说明 |
| Method | Return | Description |
|---|---|---|
| `EnrollAsync(bool admin, string userName, FaceDirection direction, byte timeout)` | `Task<FaceEnrollResult>` | 交互式多方向录入 |
| `EnrollSingleAsync(bool admin, string userName, byte timeout)` | `Task<FaceEnrollResult>` | 单帧录入 |
| `EnrollIntegratedAsync(bool admin, string userName, FaceDirection direction, byte timeout, bool singleFrame = false, bool duplicateCheck = true)` | `Task<FaceEnrollResult>` | 集成式录入 |
| `EnrollSnapFaceImageAsync(bool admin, string userName)` | `Task<FaceEnrollResult>` | 抓拍人脸后注册 |
| `EnrollAsync(bool admin, string userName, FaceDirection direction, byte timeout)` | `Task<FaceEnrollResult>` | Interactive multi-direction enrollment |
| `EnrollSingleAsync(bool admin, string userName, byte timeout)` | `Task<FaceEnrollResult>` | Single-frame enrollment |
| `EnrollIntegratedAsync(bool admin, string userName, FaceDirection direction, byte timeout, bool singleFrame = false, bool duplicateCheck = true)` | `Task<FaceEnrollResult>` | Integrated enrollment |
| `EnrollSnapFaceImageAsync(bool admin, string userName)` | `Task<FaceEnrollResult>` | Capture face image and enroll |
## 6. 用户服务 FaceUserService
### FaceUserService
访问路径:
Access path: `manager.Users`
```csharp
manager.Users
```
| 方法 | 返回 | 说明 |
| Method | Return | Description |
|---|---|---|
| `DeleteUserAsync(int userId)` | `Task<FaceReply>` | 删除指定用户 |
| `DeleteAllAsync()` | `Task<FaceReply>` | 删除全部用户 |
| `GetUserInfoAsync(int userId)` | `Task<FaceUserInfo>` | 查询用户信息 |
| `GetAllUserIdsAsync()` | `Task<List<int>>` | 查询用户 ID 列表 |
| `GetAllUserIds2Async()` | `Task<List<int>>` | 使用扩展命令查询用户 ID 列表 |
| `GetAllUserInfosAsync()` | `Task<List<FaceUserInfo>>` | 查询全部用户详情 |
| `GetAllUserInfos2Async()` | `Task<List<FaceUserInfo>>` | 使用扩展命令查询全部用户详情 |
| `DeleteUserAsync(int userId)` | `Task<FaceReply>` | Delete a user |
| `DeleteAllAsync()` | `Task<FaceReply>` | Delete all users |
| `GetUserInfoAsync(int userId)` | `Task<FaceUserInfo>` | Query one user |
| `GetAllUserIdsAsync()` | `Task<List<int>>` | Query all user IDs |
| `GetAllUserIds2Async()` | `Task<List<int>>` | Query all user IDs with extended command |
| `GetAllUserInfosAsync()` | `Task<List<FaceUserInfo>>` | Query all user details |
| `GetAllUserInfos2Async()` | `Task<List<FaceUserInfo>>` | Query all user details with extended command |
## 7. 二维码服务 FaceQrCodeService
### FaceQrCodeService
访问路径:
Access path: `manager.QrCode`
```csharp
manager.QrCode
```
| 方法 | 返回 | 说明 |
| Method | Return | Description |
|---|---|---|
| `ScanQrCodeAsync(byte timeout)` | `Task<string>` | 扫描二维码并返回内容 |
| `ScanQrCodeAsync(byte timeout)` | `Task<string>` | Scan QR code and return content |
## 8. 图片服务 FaceImageService
### FaceImageService
访问路径:
Access path: `manager.Images`
```csharp
manager.Images
```
| 方法 | 返回 | 说明 |
| Method | Return | Description |
|---|---|---|
| `SnapUploadImageAsync()` | `Task<FaceImageResult>` | 抓拍普通图片 |
| `SnapUploadFaceImageAsync()` | `Task<FaceImageResult>` | 抓拍人脸图片 |
| `SnapUploadLargeImageAsync(ImageDpi dpi)` | `Task<FaceImageResult>` | 抓拍大图 |
| `EnrollWithPhotoAsync(byte[] photoBytes, BioType type, string userName = null, bool duplicateCheck = true, Action<int, int> onProgress = null)` | `Task<FaceEnrollResult>` | 照片注册 |
| `EnrollWithPhotoAndIdAsync(int userId, byte[] photoBytes, BioType type, string userName = null, bool duplicateCheck = true, Action<int, int> onProgress = null)` | `Task<FaceEnrollResult>` | 指定用户 ID 照片注册 |
| `SnapUploadImageAsync()` | `Task<FaceImageResult>` | Capture normal image |
| `SnapUploadFaceImageAsync()` | `Task<FaceImageResult>` | Capture face image |
| `SnapUploadLargeImageAsync(ImageDpi dpi)` | `Task<FaceImageResult>` | Capture large image |
| `EnrollWithPhotoAsync(byte[] photoBytes, BioType type, string userName = null, bool duplicateCheck = true, Action<int, int> onProgress = null)` | `Task<FaceEnrollResult>` | Enroll with photo |
| `EnrollWithPhotoAndIdAsync(int userId, byte[] photoBytes, BioType type, string userName = null, bool duplicateCheck = true, Action<int, int> onProgress = null)` | `Task<FaceEnrollResult>` | Enroll photo with specified user ID |
## 9. 特征服务 FaceFeatureService
### FaceFeatureService
访问路径:
Access path: `manager.Features`
```csharp
manager.Features
```
| 方法 | 返回 | 说明 |
| Method | Return | Description |
|---|---|---|
| `ReadFeatureAsync(int userId, FeatureType type)` | `Task<byte[]>` | 读取指定用户特征 |
| `WriteFeatureAsync(byte[] featureBytes, FeatureType type, string userName = null, Action<int, int> onProgress = null)` | `Task<FaceEnrollResult>` | 写入特征并注册 |
| `ReadFeatureAsync(int userId, FeatureType type)` | `Task<byte[]>` | Read user feature |
| `WriteFeatureAsync(byte[] featureBytes, FeatureType type, string userName = null, Action<int, int> onProgress = null)` | `Task<FaceEnrollResult>` | Write feature and enroll |
## 10. UVC 和高级参数 FaceUvcService
### FaceUvcService
访问路径:
Access path: `manager.Uvc`
```csharp
manager.Uvc
```
| 方法 | 返回 | 说明 |
| Method | Return | Description |
|---|---|---|
| `ReadUsbUvcParametersAsync()` | `Task<UsbUvcParameters>` | 读取 USB / UVC 参数 |
| `SetUsbUvcParametersAsync(UsbUvcParameters parameters)` | `Task<FaceReply>` | 设置 USB / UVC 参数 |
| `SetFaceLocationDisplayAsync(bool visible)` | `Task<FaceReply>` | 设置人脸框显示 |
| `SetRgbLevelAsync(byte level)` | `Task<FaceReply>` | 设置 RGB 阈值 |
| `SetDuplicateCheckAsync(bool enableCheck)` | `Task<FaceReply>` | 设置查重 |
| `ReadDuplicateCheckAsync()` | `Task<bool>` | 读取查重状态 |
| `ReadUsbUvcParametersAsync()` | `Task<UsbUvcParameters>` | Read USB/UVC parameters |
| `SetUsbUvcParametersAsync(UsbUvcParameters parameters)` | `Task<FaceReply>` | Set USB/UVC parameters |
| `SetFaceLocationDisplayAsync(bool visible)` | `Task<FaceReply>` | Set face rectangle display |
| `SetRgbLevelAsync(byte level)` | `Task<FaceReply>` | Set RGB level |
| `SetDuplicateCheckAsync(bool enableCheck)` | `Task<FaceReply>` | Set duplicate check |
| `ReadDuplicateCheckAsync()` | `Task<bool>` | Read duplicate check state |
## 11. 加密服务 FaceEncryptionService
### FaceEncryptionService
访问路径:
Access path: `manager.Encryption`
```csharp
manager.Encryption
```
| 方法 | 返回 | 说明 |
| Method | Return | Description |
|---|---|---|
| `SetReleaseEncryptionKeyAsync(byte[] key16)` | `Task<FaceReply>` | 设置 Release 加密密钥 |
| `SetDebugEncryptionKeyAsync(byte[] key16)` | `Task<FaceReply>` | 设置 Debug 加密密钥 |
| `InitEncryptionAsync(byte[] seed4, byte mode)` | `Task<FaceReply>` | 初始化加密流程 |
| `EnableEncryption(IFaceModuleCrypto crypto)` | `void` | 设置本地加密算法适配器 |
| `DisableEncryption()` | `void` | 关闭本地加密算法适配器 |
`IFaceModuleCrypto`
| `SetReleaseEncryptionKeyAsync(byte[] key16)` | `Task<FaceReply>` | Set release encryption key |
| `SetDebugEncryptionKeyAsync(byte[] key16)` | `Task<FaceReply>` | Set debug encryption key |
| `InitEncryptionAsync(byte[] seed4, byte mode)` | `Task<FaceReply>` | Initialize encryption |
| `EnableEncryption(IFaceModuleCrypto crypto)` | `void` | Enable local crypto adapter |
| `DisableEncryption()` | `void` | Disable local crypto adapter |
```csharp
public interface IFaceModuleCrypto
@ -220,46 +186,103 @@ public interface IFaceModuleCrypto
}
```
## 12. 回调式 API
## Callback API
`FaceModuleManager.Callback` 适合 Unity Button、旧项目回调风格或不方便使用 `await` 的业务。
`FaceModuleManager.Callback` is useful for Unity UI, button events, legacy callback-style code, or workflows where `await` is inconvenient.
```csharp
manager.Callback.Verify(
timeout: 10,
success: result => Debug.Log(result.UserId),
error: message => Debug.LogError(message));
```
Callbacks use a consistent pattern:
回调特点:
- `success` is invoked on success.
- `error` receives an error message on failure.
- Photo enrollment and feature writing support `progress(current, total)`.
- Callbacks are dispatched back to the Unity main thread through `FaceModuleMainThreadDispatcher`.
- 所有 API 统一使用 `success``error`
- 照片注册、特征写入支持 `progress(current, total)`
- 回调会通过 `FaceModuleMainThreadDispatcher` 回到 Unity 主线程。
### Lifecycle and Transport
## 13. 主要模型
| Method | Success Callback | Description |
|---|---|---|
| `ConfigureTransport(IFaceModuleTransport transport, Action success, Action<string> error)` | `Action` | Inject custom transport |
| `Configure(bool useMockInEditor, string portName, int baudRate, Action success, Action<string> error)` | `Action` | Configure default transport parameters |
| `Open(Action success, Action<string> error)` | `Action` | Open transport |
| `Close(Action success, Action<string> error)` | `Action` | Close transport |
| `SendRawBytes(byte[] bytes, Action success, Action<string> error)` | `Action` | Send raw bytes |
| `WaitReady(int timeoutMs, Action success, Action<string> error)` | `Action` | Wait for READY |
| `ProbeReadyByStatus(Action<FaceModuleStatus> success, Action<string> error)` | `Action<FaceModuleStatus>` | Probe status and mark ready |
| 类型 | 说明 |
### Basic Commands
| Method | Success Callback | Description |
|---|---|---|
| `Reset(Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | Reset module |
| `FaceReset(Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | Cancel current face flow |
| `GetStatus(Action<FaceModuleStatus> success, Action<string> error)` | `Action<FaceModuleStatus>` | Get module status |
| `GetVersion(Action<string> success, Action<string> error)` | `Action<string>` | Get firmware version |
| `GetSn(Action<string> success, Action<string> error)` | `Action<string>` | Get device serial number |
| `SetDemoMode(bool enable, Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | Set Demo Mode |
| `UpgradeFirmware(Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | Start firmware upgrade |
### Verification and Enrollment
| Method | Success Callback | Description |
|---|---|---|
| `Verify(byte timeout, Action<FaceVerifyResult> success, Action<string> error, byte maxRecognitionTimes = 30)` | `Action<FaceVerifyResult>` | Run face verification |
| `AutoVerify(bool enable, byte timeout, Action<FaceVerifyResult> success, Action<string> error)` | `Action<FaceVerifyResult>` | Enable or disable auto verification |
| `Enroll(bool admin, string userName, FaceDirection direction, byte timeout, Action<FaceEnrollResult> success, Action<string> error)` | `Action<FaceEnrollResult>` | Interactive enrollment |
| `EnrollSingle(bool admin, string userName, byte timeout, Action<FaceEnrollResult> success, Action<string> error)` | `Action<FaceEnrollResult>` | Single-frame enrollment |
| `EnrollIntegrated(bool admin, string userName, FaceDirection direction, byte timeout, bool singleFrame, bool duplicateCheck, Action<FaceEnrollResult> success, Action<string> error)` | `Action<FaceEnrollResult>` | Integrated enrollment |
| `EnrollSnapFaceImage(bool admin, string userName, Action<FaceEnrollResult> success, Action<string> error)` | `Action<FaceEnrollResult>` | Capture face image and enroll |
### Users
| Method | Success Callback | Description |
|---|---|---|
| `DeleteUser(int userId, Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | Delete user |
| `DeleteAll(Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | Delete all users |
| `GetUserInfo(int userId, Action<FaceUserInfo> success, Action<string> error)` | `Action<FaceUserInfo>` | Query one user |
| `GetAllUserIds(Action<List<int>> success, Action<string> error)` | `Action<List<int>>` | Query all user IDs |
| `GetAllUserIds2(Action<List<int>> success, Action<string> error)` | `Action<List<int>>` | Query all user IDs with extended command |
| `GetAllUserInfos(Action<List<FaceUserInfo>> success, Action<string> error)` | `Action<List<FaceUserInfo>>` | Query all user details |
| `GetAllUserInfos2(Action<List<FaceUserInfo>> success, Action<string> error)` | `Action<List<FaceUserInfo>>` | Query all user details with extended command |
### QR Code, Images, and Features
| Method | Success Callback | Description |
|---|---|---|
| `ScanQrCode(byte timeout, Action<string> success, Action<string> error)` | `Action<string>` | Scan QR code |
| `SnapUploadImage(Action<FaceImageResult> success, Action<string> error)` | `Action<FaceImageResult>` | Capture normal image |
| `SnapUploadFaceImage(Action<FaceImageResult> success, Action<string> error)` | `Action<FaceImageResult>` | Capture face image |
| `SnapUploadLargeImage(ImageDpi dpi, Action<FaceImageResult> success, Action<string> error)` | `Action<FaceImageResult>` | Capture large image |
| `EnrollWithPhoto(byte[] photoBytes, BioType type, string userName, bool duplicateCheck, Action<FaceEnrollResult> success, Action<string> error, Action<int, int> progress = null)` | `Action<FaceEnrollResult>` | Enroll with photo |
| `EnrollWithPhotoAndId(int userId, byte[] photoBytes, BioType type, string userName, bool duplicateCheck, Action<FaceEnrollResult> success, Action<string> error, Action<int, int> progress = null)` | `Action<FaceEnrollResult>` | Enroll photo with specified user ID |
| `ReadFeature(int userId, FeatureType type, Action<byte[]> success, Action<string> error)` | `Action<byte[]>` | Read user feature |
| `WriteFeature(byte[] featureBytes, FeatureType type, string userName, Action<FaceEnrollResult> success, Action<string> error, Action<int, int> progress = null)` | `Action<FaceEnrollResult>` | Write feature and enroll |
### UVC and Encryption
| Method | Success Callback | Description |
|---|---|---|
| `ReadUsbUvcParameters(Action<UsbUvcParameters> success, Action<string> error)` | `Action<UsbUvcParameters>` | Read USB/UVC parameters |
| `SetUsbUvcParameters(UsbUvcParameters parameters, Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | Set USB/UVC parameters |
| `SetFaceLocationDisplay(bool visible, Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | Set face rectangle display |
| `SetRgbLevel(byte level, Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | Set RGB level |
| `SetDuplicateCheck(bool enableCheck, Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | Set duplicate check |
| `ReadDuplicateCheck(Action<bool> success, Action<string> error)` | `Action<bool>` | Read duplicate check state |
| `SetReleaseEncryptionKey(byte[] key16, Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | Set release encryption key |
| `SetDebugEncryptionKey(byte[] key16, Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | Set debug encryption key |
| `InitEncryption(byte[] seed4, byte mode, Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | Initialize encryption |
| `EnableEncryption(IFaceModuleCrypto crypto, Action success, Action<string> error)` | `Action` | Enable local crypto adapter |
| `DisableEncryption(Action success, Action<string> error)` | `Action` | Disable local crypto adapter |
## Main Models
| Type | Description |
|---|---|
| `FaceReply` | REPLY 包解析结果 |
| `FaceNote` | NOTE 包解析结果 |
| `FaceFaceStateNote` | 人脸状态 NOTE |
| `FaceUserInfo` | 用户 ID、姓名、管理员标记 |
| `FaceVerifyResult` | 验证结果、用户信息、开锁状态 |
| `FaceEnrollResult` | 录入结果、用户 ID、方向 |
| `FaceImageResult` | 图片 bytes、Texture2D、用户 ID |
| `UsbUvcParameters` | USB / UVC 参数 |
| `FaceCommandException` | 命令 REPLY 非成功时抛出的异常 |
## 14. 协议和通信底层
业务层通常不需要直接使用底层 API。需要协议调试或自定义通信时可使用
| 类型 | 说明 |
|---|---|
| `FacePacketBuilder` | 封包 |
| `FacePacketParser` | 拆包 |
| `FaceProtocolEncoding` | 用户名、ID、结果文本等编码工具 |
| `IFaceModuleTransport` | 通信接口 |
| `SerialPortTransport` | 串口实现 |
| `MockFaceModuleTransport` | Mock 实现 |
| `FaceReply` | REPLY packet parse result |
| `FaceNote` | NOTE packet parse result |
| `FaceFaceStateNote` | Face state NOTE |
| `FaceUserInfo` | User ID, name, and admin flag |
| `FaceVerifyResult` | Verification result, user info, unlock status |
| `FaceEnrollResult` | Enrollment result, user ID, direction |
| `FaceImageResult` | Image bytes, `Texture2D`, user ID |
| `UsbUvcParameters` | USB/UVC parameters |
| `FaceCommandException` | Exception thrown for unsuccessful command replies |

View File

@ -0,0 +1,288 @@
# SDK API 参考
English documentation: [SDK_API_Reference.md](SDK_API_Reference.md).
本文列出 `xin.aisu.si-m1.face` 对外公开的业务层 API。公开包为 DLL-only 形式,不包含 SDK 源码。
## 命名空间
| 命名空间 | 说明 |
|---|---|
| `Aisu.SIM1.Face.Core` | Manager、配置、回调适配、日志、主线程调度 |
| `Aisu.SIM1.Face.Commands` | 业务服务、命令服务、加密适配接口 |
| `Aisu.SIM1.Face.Protocol` | 协议枚举、封包/拆包、编码工具 |
| `Aisu.SIM1.Face.Transport` | 通信接口、串口通信、Mock 通信 |
| `Aisu.SIM1.Face.Models` | Reply、Note、用户、验证、录入、图片、UVC 等模型 |
## FaceModuleManager
推荐使用 `FaceModuleManager` 作为统一入口:
```csharp
using Aisu.SIM1.Face.Core;
```
### 属性
| 属性 | 类型 | 说明 |
|---|---|---|
| `Basic` | `FaceBasicService` | 基础命令服务 |
| `Verify` | `FaceVerifyService` | 人脸验证服务 |
| `Enrollment` | `FaceEnrollmentService` | 人脸录入服务 |
| `Users` | `FaceUserService` | 用户管理服务 |
| `QrCode` | `FaceQrCodeService` | 二维码服务 |
| `Images` | `FaceImageService` | 图片抓拍与照片注册服务 |
| `Features` | `FaceFeatureService` | 特征读写服务 |
| `Uvc` | `FaceUvcService` | UVC 和高级参数服务 |
| `Encryption` | `FaceEncryptionService` | 加密服务 |
| `Callback` | `FaceModuleCallbackAdapter` | 回调式 API 适配器 |
| `IsOpen` | `bool` | 通信是否打开 |
| `IsReady` | `bool` | 是否收到 READY |
| `CurrentStatus` | `FaceModuleStatus` | 当前模组状态 |
| `LastError` | `string` | 最近错误信息 |
| `CurrentCommand` | `string` | 当前命令名称 |
| `Config` | `FaceModuleConfig` | 当前运行配置 |
| `Settings` | `FaceSdkSettings` | 当前绑定配置资产 |
### 方法
| 方法 | 说明 |
|---|---|
| `ConfigureTransport(IFaceModuleTransport transport)` | 注入自定义通信层 |
| `Configure(bool useMockInEditor, string portName, int baudRate)` | 兼容旧代码的快速配置入口 |
| `ApplySettings(FaceSdkSettings sdkSettings)` | 应用 ScriptableObject 配置并重建 transport |
| `Open()` | 打开通信 |
| `Close()` | 关闭通信 |
| `WaitReadyAsync(int timeoutMs = 5000)` | 等待 READY NOTE |
| `ProbeReadyByStatusAsync()` | 主动查询状态并标记 READY |
| `SendRawBytes(byte[] bytes)` | 发送原始协议 bytes |
| `RefreshStatus()` | 异步刷新 `CurrentStatus` |
### 事件
| 事件 | 说明 |
|---|---|
| `OnReady` | 首次 READY |
| `OnStatusChanged(FaceModuleStatus)` | 当前状态变化 |
| `OnReplyReceived(FaceReply)` | 收到 REPLY 包 |
| `OnNoteReceived(FaceNote)` | 收到 NOTE 包 |
| `OnFaceStateUpdated(FaceFaceStateNote)` | 收到人脸状态 NOTE |
| `OnQrCodeReceived(string)` | 收到二维码 NOTE |
| `OnFeatureReceived(byte[])` | 收到特征数据包 |
| `OnDataPacketReceived(FacePacket)` | 收到图片或模板数据包 |
| `OnError(FaceResultCode, string)` | 错误上报 |
| `OnRawLog(string)` | 原始 TX/RX 日志 |
## 异步服务 API
### FaceBasicService
访问路径:`manager.Basic`
| 方法 | 返回 | 说明 |
|---|---|---|
| `ResetAsync()` | `Task<FaceReply>` | 复位模组 |
| `FaceResetAsync()` | `Task<FaceReply>` | 取消当前人脸流程 |
| `GetStatusAsync()` | `Task<FaceModuleStatus>` | 获取模组状态 |
| `GetVersionAsync()` | `Task<string>` | 获取固件版本 |
| `GetSnAsync()` | `Task<string>` | 获取设备序列号 |
| `SetDemoModeAsync(bool enable)` | `Task<FaceReply>` | 设置 Demo Mode |
| `UpgradeFirmwareAsync()` | `Task<FaceReply>` | 启动固件升级命令 |
### FaceVerifyService
访问路径:`manager.Verify`
| 方法 | 返回 | 说明 |
|---|---|---|
| `VerifyAsync(byte timeout, byte maxRecognitionTimes = 30)` | `Task<FaceVerifyResult>` | 单次人脸验证 |
| `AutoVerifyAsync(bool enable, byte timeout)` | `Task<FaceVerifyResult>` | 启用或关闭自动验证 |
### FaceEnrollmentService
访问路径:`manager.Enrollment`
| 方法 | 返回 | 说明 |
|---|---|---|
| `EnrollAsync(bool admin, string userName, FaceDirection direction, byte timeout)` | `Task<FaceEnrollResult>` | 交互式多方向录入 |
| `EnrollSingleAsync(bool admin, string userName, byte timeout)` | `Task<FaceEnrollResult>` | 单帧录入 |
| `EnrollIntegratedAsync(bool admin, string userName, FaceDirection direction, byte timeout, bool singleFrame = false, bool duplicateCheck = true)` | `Task<FaceEnrollResult>` | 集成式录入 |
| `EnrollSnapFaceImageAsync(bool admin, string userName)` | `Task<FaceEnrollResult>` | 抓拍人脸后注册 |
### FaceUserService
访问路径:`manager.Users`
| 方法 | 返回 | 说明 |
|---|---|---|
| `DeleteUserAsync(int userId)` | `Task<FaceReply>` | 删除指定用户 |
| `DeleteAllAsync()` | `Task<FaceReply>` | 删除全部用户 |
| `GetUserInfoAsync(int userId)` | `Task<FaceUserInfo>` | 查询指定用户信息 |
| `GetAllUserIdsAsync()` | `Task<List<int>>` | 查询全部用户 ID |
| `GetAllUserIds2Async()` | `Task<List<int>>` | 使用扩展命令查询全部用户 ID |
| `GetAllUserInfosAsync()` | `Task<List<FaceUserInfo>>` | 查询全部用户信息 |
| `GetAllUserInfos2Async()` | `Task<List<FaceUserInfo>>` | 使用扩展命令查询全部用户信息 |
### FaceQrCodeService
访问路径:`manager.QrCode`
| 方法 | 返回 | 说明 |
|---|---|---|
| `ScanQrCodeAsync(byte timeout)` | `Task<string>` | 扫描二维码并返回内容 |
### FaceImageService
访问路径:`manager.Images`
| 方法 | 返回 | 说明 |
|---|---|---|
| `SnapUploadImageAsync()` | `Task<FaceImageResult>` | 抓拍普通图片 |
| `SnapUploadFaceImageAsync()` | `Task<FaceImageResult>` | 抓拍人脸图片 |
| `SnapUploadLargeImageAsync(ImageDpi dpi)` | `Task<FaceImageResult>` | 抓拍大图 |
| `EnrollWithPhotoAsync(byte[] photoBytes, BioType type, string userName = null, bool duplicateCheck = true, Action<int, int> onProgress = null)` | `Task<FaceEnrollResult>` | 照片注册 |
| `EnrollWithPhotoAndIdAsync(int userId, byte[] photoBytes, BioType type, string userName = null, bool duplicateCheck = true, Action<int, int> onProgress = null)` | `Task<FaceEnrollResult>` | 指定用户 ID 照片注册 |
### FaceFeatureService
访问路径:`manager.Features`
| 方法 | 返回 | 说明 |
|---|---|---|
| `ReadFeatureAsync(int userId, FeatureType type)` | `Task<byte[]>` | 读取指定用户特征 |
| `WriteFeatureAsync(byte[] featureBytes, FeatureType type, string userName = null, Action<int, int> onProgress = null)` | `Task<FaceEnrollResult>` | 写入特征并注册 |
### FaceUvcService
访问路径:`manager.Uvc`
| 方法 | 返回 | 说明 |
|---|---|---|
| `ReadUsbUvcParametersAsync()` | `Task<UsbUvcParameters>` | 读取 USB/UVC 参数 |
| `SetUsbUvcParametersAsync(UsbUvcParameters parameters)` | `Task<FaceReply>` | 设置 USB/UVC 参数 |
| `SetFaceLocationDisplayAsync(bool visible)` | `Task<FaceReply>` | 设置人脸框显示 |
| `SetRgbLevelAsync(byte level)` | `Task<FaceReply>` | 设置 RGB 等级 |
| `SetDuplicateCheckAsync(bool enableCheck)` | `Task<FaceReply>` | 设置查重 |
| `ReadDuplicateCheckAsync()` | `Task<bool>` | 读取查重状态 |
### FaceEncryptionService
访问路径:`manager.Encryption`
| 方法 | 返回 | 说明 |
|---|---|---|
| `SetReleaseEncryptionKeyAsync(byte[] key16)` | `Task<FaceReply>` | 设置 Release 加密密钥 |
| `SetDebugEncryptionKeyAsync(byte[] key16)` | `Task<FaceReply>` | 设置 Debug 加密密钥 |
| `InitEncryptionAsync(byte[] seed4, byte mode)` | `Task<FaceReply>` | 初始化加密 |
| `EnableEncryption(IFaceModuleCrypto crypto)` | `void` | 启用本地加密算法适配器 |
| `DisableEncryption()` | `void` | 关闭本地加密算法适配器 |
```csharp
public interface IFaceModuleCrypto
{
byte[] Encrypt(byte[] plainBytes);
byte[] Decrypt(byte[] encryptedBytes);
byte[] GenerateSessionKey(byte[] seed4, byte[] encKey16);
}
```
## 回调式 API
`FaceModuleManager.Callback` 适合 Unity UI、按钮事件、旧项目回调风格或不方便使用 `await` 的业务。
回调规则:
- 成功时调用 `success`
- 失败时调用 `error` 并传入错误信息。
- 照片注册和特征写入支持 `progress(current, total)`
- 回调会通过 `FaceModuleMainThreadDispatcher` 回到 Unity 主线程。
### 生命周期与通信
| 方法 | 成功回调 | 说明 |
|---|---|---|
| `ConfigureTransport(IFaceModuleTransport transport, Action success, Action<string> error)` | `Action` | 注入自定义通信层 |
| `Configure(bool useMockInEditor, string portName, int baudRate, Action success, Action<string> error)` | `Action` | 配置默认通信参数 |
| `Open(Action success, Action<string> error)` | `Action` | 打开通信 |
| `Close(Action success, Action<string> error)` | `Action` | 关闭通信 |
| `SendRawBytes(byte[] bytes, Action success, Action<string> error)` | `Action` | 发送原始 bytes |
| `WaitReady(int timeoutMs, Action success, Action<string> error)` | `Action` | 等待 READY |
| `ProbeReadyByStatus(Action<FaceModuleStatus> success, Action<string> error)` | `Action<FaceModuleStatus>` | 主动探测状态并标记 READY |
### 基础命令
| 方法 | 成功回调 | 说明 |
|---|---|---|
| `Reset(Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | 复位模组 |
| `FaceReset(Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | 取消当前人脸流程 |
| `GetStatus(Action<FaceModuleStatus> success, Action<string> error)` | `Action<FaceModuleStatus>` | 获取模组状态 |
| `GetVersion(Action<string> success, Action<string> error)` | `Action<string>` | 获取固件版本 |
| `GetSn(Action<string> success, Action<string> error)` | `Action<string>` | 获取设备序列号 |
| `SetDemoMode(bool enable, Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | 设置 Demo Mode |
| `UpgradeFirmware(Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | 启动固件升级 |
### 验证与录入
| 方法 | 成功回调 | 说明 |
|---|---|---|
| `Verify(byte timeout, Action<FaceVerifyResult> success, Action<string> error, byte maxRecognitionTimes = 30)` | `Action<FaceVerifyResult>` | 人脸验证 |
| `AutoVerify(bool enable, byte timeout, Action<FaceVerifyResult> success, Action<string> error)` | `Action<FaceVerifyResult>` | 启用或关闭自动验证 |
| `Enroll(bool admin, string userName, FaceDirection direction, byte timeout, Action<FaceEnrollResult> success, Action<string> error)` | `Action<FaceEnrollResult>` | 交互式录入 |
| `EnrollSingle(bool admin, string userName, byte timeout, Action<FaceEnrollResult> success, Action<string> error)` | `Action<FaceEnrollResult>` | 单帧录入 |
| `EnrollIntegrated(bool admin, string userName, FaceDirection direction, byte timeout, bool singleFrame, bool duplicateCheck, Action<FaceEnrollResult> success, Action<string> error)` | `Action<FaceEnrollResult>` | 集成式录入 |
| `EnrollSnapFaceImage(bool admin, string userName, Action<FaceEnrollResult> success, Action<string> error)` | `Action<FaceEnrollResult>` | 抓拍人脸后注册 |
### 用户管理
| 方法 | 成功回调 | 说明 |
|---|---|---|
| `DeleteUser(int userId, Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | 删除指定用户 |
| `DeleteAll(Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | 删除全部用户 |
| `GetUserInfo(int userId, Action<FaceUserInfo> success, Action<string> error)` | `Action<FaceUserInfo>` | 查询指定用户 |
| `GetAllUserIds(Action<List<int>> success, Action<string> error)` | `Action<List<int>>` | 查询全部用户 ID |
| `GetAllUserIds2(Action<List<int>> success, Action<string> error)` | `Action<List<int>>` | 使用扩展命令查询全部用户 ID |
| `GetAllUserInfos(Action<List<FaceUserInfo>> success, Action<string> error)` | `Action<List<FaceUserInfo>>` | 查询全部用户信息 |
| `GetAllUserInfos2(Action<List<FaceUserInfo>> success, Action<string> error)` | `Action<List<FaceUserInfo>>` | 使用扩展命令查询全部用户信息 |
### 二维码、图片与特征
| 方法 | 成功回调 | 说明 |
|---|---|---|
| `ScanQrCode(byte timeout, Action<string> success, Action<string> error)` | `Action<string>` | 扫描二维码 |
| `SnapUploadImage(Action<FaceImageResult> success, Action<string> error)` | `Action<FaceImageResult>` | 抓拍普通图片 |
| `SnapUploadFaceImage(Action<FaceImageResult> success, Action<string> error)` | `Action<FaceImageResult>` | 抓拍人脸图片 |
| `SnapUploadLargeImage(ImageDpi dpi, Action<FaceImageResult> success, Action<string> error)` | `Action<FaceImageResult>` | 抓拍大图 |
| `EnrollWithPhoto(byte[] photoBytes, BioType type, string userName, bool duplicateCheck, Action<FaceEnrollResult> success, Action<string> error, Action<int, int> progress = null)` | `Action<FaceEnrollResult>` | 照片注册 |
| `EnrollWithPhotoAndId(int userId, byte[] photoBytes, BioType type, string userName, bool duplicateCheck, Action<FaceEnrollResult> success, Action<string> error, Action<int, int> progress = null)` | `Action<FaceEnrollResult>` | 指定用户 ID 照片注册 |
| `ReadFeature(int userId, FeatureType type, Action<byte[]> success, Action<string> error)` | `Action<byte[]>` | 读取用户特征 |
| `WriteFeature(byte[] featureBytes, FeatureType type, string userName, Action<FaceEnrollResult> success, Action<string> error, Action<int, int> progress = null)` | `Action<FaceEnrollResult>` | 写入特征并注册 |
### UVC 与加密
| 方法 | 成功回调 | 说明 |
|---|---|---|
| `ReadUsbUvcParameters(Action<UsbUvcParameters> success, Action<string> error)` | `Action<UsbUvcParameters>` | 读取 USB/UVC 参数 |
| `SetUsbUvcParameters(UsbUvcParameters parameters, Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | 设置 USB/UVC 参数 |
| `SetFaceLocationDisplay(bool visible, Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | 设置人脸框显示 |
| `SetRgbLevel(byte level, Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | 设置 RGB 等级 |
| `SetDuplicateCheck(bool enableCheck, Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | 设置查重 |
| `ReadDuplicateCheck(Action<bool> success, Action<string> error)` | `Action<bool>` | 读取查重状态 |
| `SetReleaseEncryptionKey(byte[] key16, Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | 设置 Release 加密密钥 |
| `SetDebugEncryptionKey(byte[] key16, Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | 设置 Debug 加密密钥 |
| `InitEncryption(byte[] seed4, byte mode, Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | 初始化加密 |
| `EnableEncryption(IFaceModuleCrypto crypto, Action success, Action<string> error)` | `Action` | 启用本地加密算法适配器 |
| `DisableEncryption(Action success, Action<string> error)` | `Action` | 关闭本地加密算法适配器 |
## 主要模型
| 类型 | 说明 |
|---|---|
| `FaceReply` | REPLY 包解析结果 |
| `FaceNote` | NOTE 包解析结果 |
| `FaceFaceStateNote` | 人脸状态 NOTE |
| `FaceUserInfo` | 用户 ID、姓名、管理员标记 |
| `FaceVerifyResult` | 验证结果、用户信息、开锁状态 |
| `FaceEnrollResult` | 录入结果、用户 ID、方向 |
| `FaceImageResult` | 图片 bytes、`Texture2D`、用户 ID |
| `UsbUvcParameters` | USB/UVC 参数 |
| `FaceCommandException` | 命令 REPLY 非成功时抛出的异常 |

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 6cd812fde7d86244b82b86344e82770d
guid: 052355b6c0c74dd59f59c9459cf6f2cf
TextScriptImporter:
externalObjects: {}
userData:

View File

@ -1,126 +1,76 @@
# SI-M1 Face SDK 配置与 Editor 工具
# SDK Configuration
SDK 使用 `FaceSdkSettings` 作为推荐配置方式。该配置是 `ScriptableObject`,可在项目中复用,并可同步到场景中的 `FaceModuleManager`
中文说明见 [SDK_Configuration.zh-CN.md](SDK_Configuration.zh-CN.md).
## 1. 默认配置资产
The SDK uses `FaceSdkSettings` as the recommended configuration asset. It is a `ScriptableObject` created inside the importing Unity project and can be synchronized to scene `FaceModuleManager` instances.
默认路径:
## Default Settings Asset
Default path in the importing Unity project:
```text
Assets/AISU/SI-M1 Face SDK/FaceSdkSettings.asset
```
打开菜单 `AISU/SI-M1 Face SDK/Settings`Editor 会加载该路径。若文件不存在,点击 `Load Default` 会创建默认资产。
Open `AISU/SI-M1 Face SDK/Settings` to load or create this asset.
## 2. FaceSdkSettings 字段
## FaceSdkSettings Fields
| 字段 | 类型 | 说明 |
| Field | Type | Description |
|---|---|---|
| `TransportMode` | `FaceTransportMode` | 通信模式:`Auto``SerialPort``Mock` |
| `UseMockInEditor` | `bool` | Editor 下是否强制使用 Mock |
| `PortName` | `string` | Player / 运行时串口号 |
| `BaudRate` | `int` | Player / 运行时波特率 |
| `ReadBufferSize` | `int` | Player / 运行时读取缓冲区 |
| `UseEditorSerialDebugParameters` | `bool` | Editor 下连接真实串口时是否使用单独参数 |
| `EditorPortName` | `string` | Editor 调试串口号 |
| `EditorBaudRate` | `int` | Editor 调试波特率 |
| `EditorReadBufferSize` | `int` | Editor 调试读取缓冲区 |
| `MockResponseDelayFrames` | `int` | Mock 响应延迟帧数 |
| `DebugLogEnabled` | `bool` | 是否启用 SDK Debug 日志 |
| `RawLogEnabled` | `bool` | 是否派发原始 TX / RX 日志 |
| `LogPrefix` | `string` | 日志前缀 |
| `TransportMode` | `FaceTransportMode` | `Auto`, `SerialPort`, or `Mock` |
| `UseMockInEditor` | `bool` | Force mock transport in Unity Editor |
| `PortName` | `string` | Runtime/player serial port |
| `BaudRate` | `int` | Runtime/player baud rate |
| `ReadBufferSize` | `int` | Runtime/player read buffer size |
| `UseEditorSerialDebugParameters` | `bool` | Use separate serial parameters in Editor |
| `EditorPortName` | `string` | Editor debug serial port |
| `EditorBaudRate` | `int` | Editor debug baud rate |
| `EditorReadBufferSize` | `int` | Editor debug read buffer size |
| `MockResponseDelayFrames` | `int` | Mock response delay in frames |
| `DebugLogEnabled` | `bool` | Enable SDK debug logs |
| `RawLogEnabled` | `bool` | Dispatch raw TX/RX logs |
| `LogPrefix` | `string` | Log prefix |
## 3. TransportMode 选择
## TransportMode
| 模式 | 行为 |
| Mode | Behavior |
|---|---|
| `Auto` | Editor 根据 `UseMockInEditor` 选择 Mock 或串口Player 使用串口 |
| `SerialPort` | 使用 `SerialPortTransport` |
| `Mock` | 使用 `MockFaceModuleTransport` |
| `Auto` | Editor chooses mock or serial based on `UseMockInEditor`; Player uses serial |
| `SerialPort` | Use `SerialPortTransport` |
| `Mock` | Use `MockFaceModuleTransport` |
Editor 下有一个额外优先级:
When `UseMockInEditor = true`, the Editor always uses mock transport and does not open a real serial port.
```text
UseMockInEditor = true 时,强制使用 Mock不打开真实串口。
```
## Editor Tools
因此 Editor 中如果需要连接真实串口,必须将 `UseMockInEditor` 设为 `false`
## 4. Editor Serial Debug 参数
Editor 连接真实硬件时,建议开启:
```text
UseEditorSerialDebugParameters = true
```
开启后Editor 中串口使用:
- `EditorPortName`
- `EditorBaudRate`
- `EditorReadBufferSize`
Player 中仍使用:
- `PortName`
- `BaudRate`
- `ReadBufferSize`
这样可以避免 Editor 调试口和发布运行口互相覆盖。
## 5. Editor 工具按钮
配置窗口按钮:
| 按钮 | 行为 |
| Menu | Purpose |
|---|---|
| `Load Default` | 固定加载或创建默认路径的 `FaceSdkSettings.asset` |
| `Save` | 保存当前配置并同步场景中的 Manager |
| `Save and Create/Update Manager` | 保存配置后创建或更新场景 Manager |
| `AISU/SI-M1 Face SDK/Settings` | Open SDK settings window |
| `AISU/SI-M1 Face SDK/Create Manager GameObject` | Create or update one scene `FaceModuleManager` |
| `AISU/SI-M1 Face SDK/Open Diagnostics` | Open diagnostics window |
同步 Manager 时会写入:
The public DLL-only package does not include importable demo samples. Any demo-related menu item should be treated as unavailable in the public release if it appears in the current Editor DLL.
- `m_settings`
- `m_config.TransportMode`
- `m_config.UseMockInEditor`
- 串口参数
- Editor 串口参数
- Mock 延迟
- Raw Log 开关
PlayMode 中同步配置时,会调用 `FaceModuleManager.ApplySettings(settings)`,立即重建当前 transport。
## 6. Manager 配置方式
推荐方式:
## Recommended Usage
```csharp
manager.ApplySettings(settings);
manager.Open();
```
兼容方式:
Legacy quick configuration:
```csharp
manager.Configure(useMockInEditor: true, portName: "COM3", baudRate: 115200);
manager.Open();
```
外部通信层注入:
Custom transport injection:
```csharp
manager.ConfigureTransport(customTransport);
manager.Open();
```
## 7. 场景约束
每个场景建议只保留一个 `FaceModuleManager`
多个 Manager 可能导致:
- 多次打开同一串口。
- 重复接收和派发事件。
- UI 状态不一致。
`Create Manager GameObject` 菜单会校验 Manager 数量,并在存在多个 Manager 时停止创建。
Keep only one `FaceModuleManager` in each scene to avoid duplicate serial connections and duplicated events.

View File

@ -0,0 +1,76 @@
# SDK 配置
English documentation: [SDK_Configuration.md](SDK_Configuration.md).
SDK 推荐使用 `FaceSdkSettings` 作为配置资产。该配置是 `ScriptableObject`,会创建在导入该包的 Unity 项目中,并可同步到场景里的 `FaceModuleManager`
## 默认配置资产
默认路径位于导入该包的 Unity 项目内:
```text
Assets/AISU/SI-M1 Face SDK/FaceSdkSettings.asset
```
打开 `AISU/SI-M1 Face SDK/Settings` 可加载或创建该配置资产。
## FaceSdkSettings 字段
| 字段 | 类型 | 说明 |
|---|---|---|
| `TransportMode` | `FaceTransportMode` | `Auto``SerialPort``Mock` |
| `UseMockInEditor` | `bool` | Unity Editor 中强制使用 Mock 通信 |
| `PortName` | `string` | Runtime/Player 串口号 |
| `BaudRate` | `int` | Runtime/Player 波特率 |
| `ReadBufferSize` | `int` | Runtime/Player 读取缓冲区大小 |
| `UseEditorSerialDebugParameters` | `bool` | Editor 中是否使用单独串口参数 |
| `EditorPortName` | `string` | Editor 调试串口号 |
| `EditorBaudRate` | `int` | Editor 调试波特率 |
| `EditorReadBufferSize` | `int` | Editor 调试读取缓冲区大小 |
| `MockResponseDelayFrames` | `int` | Mock 响应延迟帧数 |
| `DebugLogEnabled` | `bool` | 是否启用 SDK Debug 日志 |
| `RawLogEnabled` | `bool` | 是否派发原始 TX/RX 日志 |
| `LogPrefix` | `string` | 日志前缀 |
## TransportMode
| 模式 | 行为 |
|---|---|
| `Auto` | Editor 根据 `UseMockInEditor` 选择 Mock 或串口Player 使用串口 |
| `SerialPort` | 使用 `SerialPortTransport` |
| `Mock` | 使用 `MockFaceModuleTransport` |
`UseMockInEditor = true`Editor 会始终使用 Mock 通信,不会打开真实串口。
## Editor 工具
| 菜单 | 用途 |
|---|---|
| `AISU/SI-M1 Face SDK/Settings` | 打开 SDK 配置窗口 |
| `AISU/SI-M1 Face SDK/Create Manager GameObject` | 创建或更新场景中的唯一 `FaceModuleManager` |
| `AISU/SI-M1 Face SDK/Open Diagnostics` | 打开诊断窗口 |
公开 DLL-only 包不包含可导入 Demo 示例。如果当前 Editor DLL 中仍出现 Demo 相关菜单,应视为公开版本不可用功能。
## 推荐用法
```csharp
manager.ApplySettings(settings);
manager.Open();
```
兼容式快速配置:
```csharp
manager.Configure(useMockInEditor: true, portName: "COM3", baudRate: 115200);
manager.Open();
```
自定义通信层注入:
```csharp
manager.ConfigureTransport(customTransport);
manager.Open();
```
每个场景建议只保留一个 `FaceModuleManager`,避免重复打开串口和重复派发事件。

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f3143ed1eba09314497d839bc2fb455a
guid: e8f67d1f02034f3b84b7c0a0d635cafe
TextScriptImporter:
externalObjects: {}
userData:

View File

@ -1,4 +1,6 @@
# Mock And Testing
# Mock And Testing
中文说明见 [SDK_Mock_And_Testing.zh-CN.md](SDK_Mock_And_Testing.zh-CN.md).
The public DLL-only package includes runtime mock support inside `Aisu.SIM1.Face.Runtime.dll`, but it does not include EditMode test source files.

View File

@ -0,0 +1,28 @@
# Mock 与测试
English documentation: [SDK_Mock_And_Testing.md](SDK_Mock_And_Testing.md).
公开 DLL-only 包在 `Aisu.SIM1.Face.Runtime.dll` 中包含运行时 Mock 支持,但不包含 EditMode 测试源码。
## Editor Mock
无真实硬件进行 Editor 联调时,在 `FaceSdkSettings` 中启用:
```text
Use Mock In Editor = true
```
启用后SDK 在 Unity Editor 中使用内置 Mock 通信层,不会打开真实串口。
## 真实硬件验证
验证真实 SI-M1 硬件时:
1. 设置 `Use Mock In Editor = false`
2. 配置 `Editor Port Name``Editor Baud Rate``Editor Read Buffer Size`
3. 在场景中创建 `FaceModuleManager`
4. 调用 `Open()`,然后等待 `WaitReadyAsync()` 或处理 `OnReady`
## 自动化测试
内部 EditMode 测试保留在私有开发 SDK 仓库中,不随 DLL-only 公开包发布。

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: b58b6a37fb32dba499120e6cd57a78cf
guid: a617b656891c4bb4b3ffec5f8e3ff611
TextScriptImporter:
externalObjects: {}
userData:

View File

@ -1,19 +1,21 @@
# SDK Quick Start
# SDK Quick Start
This public UPM package is distributed as compiled DLLs and does not include SDK source code, Demo source code, or test source code.
中文说明见 [SDK_QuickStart.zh-CN.md](SDK_QuickStart.zh-CN.md).
This public UPM package is distributed as compiled DLLs and does not include SDK source code, demo source code, test source code, or debug symbols.
## 1. Install
Add the package through Unity Package Manager, or add it to `Packages/manifest.json`:
Add the package through Unity Package Manager:
```json
"xin.aisu.si-m1.face": "https://github.com/your-org/si-m1-face-package.git#v0.1.0"
```text
https://git.aisu.xin/aisu-sdk/si-m1-face-package.git#v0.1.2
```
For local validation:
Or add it to `Packages/manifest.json`:
```json
"xin.aisu.si-m1.face": "file:D:/Workspaces/SDK/si-m1-face-package"
"xin.aisu.si-m1.face": "https://git.aisu.xin/aisu-sdk/si-m1-face-package.git#v0.1.2"
```
## 2. Create Settings
@ -24,7 +26,7 @@ Open Unity menu:
AISU/SI-M1 Face SDK/Settings
```
The tool creates or loads the default settings asset:
The tool creates or loads this settings asset inside the importing Unity project:
```text
Assets/AISU/SI-M1 Face SDK/FaceSdkSettings.asset
@ -67,11 +69,12 @@ public sealed class FaceExample : MonoBehaviour
| Scenario | Recommended Setting |
|---|---|
| Editor UI integration without hardware | `Use Mock In Editor = true` |
| Editor integration without hardware | `Use Mock In Editor = true` |
| Editor with real serial hardware | `Use Mock In Editor = false`, configure editor serial parameters |
| Windows Player | `Transport Mode = SerialPort` or `Auto`, configure runtime serial parameters |
## Notes
- This DLL-only release does not include importable Demo samples.
- Git URL packages may appear as `xin.aisu.si-m1.face@<commit-hash>` in Unity's package cache. This is normal.
- This DLL-only release does not include importable demo samples.
- Demo source and EditMode test source remain in the private development SDK repository.

View File

@ -0,0 +1,80 @@
# SDK 快速开始
English documentation: [SDK_QuickStart.md](SDK_QuickStart.md).
公开 UPM 包以编译后的 DLL 形式发布,不包含 SDK 源码、Demo 源码、测试源码或调试符号。
## 1. 安装
通过 Unity Package Manager 添加 Git URL
```text
https://git.aisu.xin/aisu-sdk/si-m1-face-package.git#v0.1.2
```
或写入 `Packages/manifest.json`
```json
"xin.aisu.si-m1.face": "https://git.aisu.xin/aisu-sdk/si-m1-face-package.git#v0.1.2"
```
## 2. 创建配置
打开 Unity 菜单:
```text
AISU/SI-M1 Face SDK/Settings
```
工具会在导入该包的 Unity 项目中创建或加载配置资产:
```text
Assets/AISU/SI-M1 Face SDK/FaceSdkSettings.asset
```
配置串口号、波特率、Mock 模式和日志选项。
## 3. 创建 Manager
打开 Unity 菜单:
```text
AISU/SI-M1 Face SDK/Create Manager GameObject
```
每个场景建议只保留一个 `FaceModuleManager`,避免重复打开串口和重复派发事件。
## 4. 最小代码
```csharp
using Aisu.SIM1.Face.Core;
using UnityEngine;
public sealed class FaceExample : MonoBehaviour
{
[SerializeField] private FaceModuleManager manager;
private async void Start()
{
manager.Open();
await manager.WaitReadyAsync();
var version = await manager.Basic.GetVersionAsync();
Debug.Log("SI-M1 version: " + version);
}
}
```
## 5. 运行模式
| 场景 | 推荐配置 |
|---|---|
| Editor 中无硬件联调 | `Use Mock In Editor = true` |
| Editor 中连接真实串口硬件 | `Use Mock In Editor = false`,并配置 Editor 串口参数 |
| Windows Player | `Transport Mode = SerialPort``Auto`,并配置运行时串口参数 |
## 注意事项
- Unity 对 Git URL 包可能显示为 `xin.aisu.si-m1.face@<commit-hash>`,这是正常行为。
- DLL-only 公开版本不包含可导入 Demo 示例。
- Demo 源码和 EditMode 测试源码保留在私有开发 SDK 仓库中。

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 7cb4f35138fb4c2aa08cb2ab34c3f37a
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,27 +0,0 @@
# Unity Implementation Notes
This public package provides the SI-M1 Unity integration as compiled DLLs.
## Public Assemblies
| Assembly | Purpose |
|---|---|
| `Aisu.SIM1.Face.Runtime.dll` | Runtime protocol, transports, manager, services, models, mock transport |
| `Aisu.SIM1.Face.Editor.dll` | Editor settings panel, diagnostics, manager creation tools |
## Runtime Areas
- Protocol packet building and parsing.
- Serial and mock transport abstraction.
- Command service and async request/response flow.
- Face enrollment, verification, user, image, feature, QR code, UVC, and encryption services.
- `FaceModuleManager` lifecycle and Unity scene integration.
## Public Release Scope
- SDK source files are not included.
- Demo source files are not included.
- Internal EditMode test source files are not included.
- Debug symbol `.pdb` files are not included.
For private development structure and implementation source, use the internal SDK repository.

View File

@ -1,606 +0,0 @@
# SI-M1 人脸识别算法模组通信协议 V2.63:文档功能总结
> 来源文档:`SI-M1人脸识别算法模组通信协议V2.63.pdf`
> 整理目的:把通信协议、功能命令、返回消息、业务流程整理成可读的功能说明,便于后续 Unity 对接实现。
---
## 1. 文档定位
这份文档不是“人脸识别算法原理说明”,而是 **SI-M1 人脸识别算法模组的主控通信协议说明**
核心关系:
```text
Unity / PC 主控程序 <----串口通信链路----> SI-M1 人脸识别算法模组
```
模组处于 **从属设备** 地位:
- 主控负责发送命令;
- 模组负责执行人脸识别、录入、删除、查询、抓拍、二维码识别、特征读写等动作;
- 模组通过 `REPLY``NOTE``ImageOrTemplate` 三类消息主动/被动返回结果。
---
## 2. 通信消息格式
所有消息统一使用以下帧格式:
| 字段 | 长度 | 说明 |
|---|---:|---|
| SyncWord | 2 bytes | 固定同步头:`0xEF 0xAA` |
| MsgID | 1 byte | 消息 ID / 命令 ID / 返回类型 |
| Size | 2 bytes | Data 长度,高字节在前,单位 byte |
| Data | N bytes | 命令参数或返回数据N 可为 0 |
| ParityCheck | 1 byte | 校验码 |
### 2.1 校验规则
校验码计算方式:
```text
ParityCheck = MsgID ^ SizeHigh ^ SizeLow ^ Data[0] ^ Data[1] ^ ... ^ Data[N-1]
```
注意:
- 不包含 `SyncWord`
- `Size` 是大端模式,即高八位在前;
- Data 为空时,只对 `MsgID + SizeHigh + SizeLow` 做 XOR
- RESET 示例:`EF AA 10 00 00 10`
---
## 3. 主控发送给模组的命令功能
### 3.1 基础控制类
| 功能 | 命令 | Code | Data | 说明 |
|---|---|---:|---|---|
| 复位 / 取消当前任务 | RESET | `0x10` | 无 | 取消录入、验证等正在执行的任务,使模组回到 Standby |
| 获取状态 | GET STATUS | `0x11` | 无 | 获取模组当前状态 |
| 清除录入状态 | FACE RESET | `0x23` | 无 | 终止录入流程并清除录入状态 |
| 获取版本 | GET VERSION | `0x30` | 无 | 获取软件版本信息 |
| 获取设备序列号 | MID_GET_SN | `0x93` | 无 | 获取设备唯一 SN返回 32 bytes前 8 bytes 有效 |
| Demo 模式 | DEMO MODE | `0xFE` | enable 1 byte | 进入演示模式,所有人可解锁,但仍做活体检测 |
---
### 3.2 人脸验证类
| 功能 | 命令 | Code | Data | 说明 |
|---|---|---:|---|---|
| 人脸验证 | VERIFY | `0x12` | `pd_rightaway` + `timeout` + 可选 `Max_Recognition_times` | 启动一次人脸验证 |
| 低功耗自动探测验证 | AUTO_VERIFY | `0x12` | `at_verify` + `timeout` | AI-10 适用,检测到人脸或二维码后自动识别 |
#### VERIFY 参数
| 字段 | 长度 | 说明 |
|---|---:|---|
| pd_rightaway | 1 byte | 文档中作为保留字段,默认 0 |
| timeout | 1 byte | 解锁超时时间,单位秒,最大 255 |
| Max_Recognition_times | 1 byte可选 | 最大识别尝试次数,不发送时默认 30 |
特殊注意:
- 照片注册后,第一次识别成功会补全红外模板并保存到 Flash
- 主控在收到 REPLY 应答或超时后,应延时约 2 秒再断电。
---
### 3.3 人脸录入类
| 功能 | 命令 | Code | Data | 说明 |
|---|---|---:|---|---|
| 交互录入 | ENROLL | `0x13` | admin + user_name + face_dir + timeout | 按指定方向录入人脸 |
| 单帧录入 | ENROLL_SINGLE | `0x1D` | admin + user_name + face_dir + timeout | 只需一张正脸即可注册 |
| 集成录入 | MID_ENROLL_ITG | `0x26` | admin + user_name + face_dir + enroll_type + enable_duplicate + timeout + reserved | ENROLL 的扩展版本,支持交互/单帧和重复录入策略 |
| 抓拍人脸后注册 | ENROLL_SNAPFACEIMAGE | `0x73` | admin + user_name + reserved + reserved | 配合 0x72 未搜索到本地用户时使用,不查重 |
#### ENROLL 参数
| 字段 | 长度 | 说明 |
|---|---:|---|
| admin | 1 byte | 是否管理员1 是0 否 |
| user_name | 32 bytes | 用户姓名 |
| face_dir | 1 byte | 录入方向 |
| timeout | 1 byte | 录入超时时间,单位秒 |
#### 人脸方向定义
| 方向 | Code | 说明 |
|---|---:|---|
| FACE_DIRECTION_UP | `0x10` | 朝上 |
| FACE_DIRECTION_DOWN | `0x08` | 朝下 |
| FACE_DIRECTION_LEFT | `0x04` | 朝左 |
| FACE_DIRECTION_RIGHT | `0x02` | 朝右 |
| FACE_DIRECTION_MIDDLE | `0x01` | 正脸 |
| FACE_DIRECTION_UNDEFINE | `0x00` | 未定义,默认正脸 |
#### 交互录入说明
录入过程中:
1. 主控发送指定方向录入命令;
2. 模组通过 NOTE 返回人脸状态、位置、姿态;
3. Unity 根据 NOTE 信息提示用户调整姿态;
4. 模组通过 REPLY 返回最终录入结果;
5. 录入中可通过 FACE RESET 终止;
6. 录入过程中突然断电,之前录入的人脸不会保存。
#### 录入角度说明
| 方向 | 推荐偏转角度 |
|---|---|
| 正脸 | 正对摄像头 |
| 向上 | 正脸向上偏转 5~55 度 |
| 向下 | 正脸向下偏转 5~55 度 |
| 向右 | 正脸向右偏转 8~60 度 |
| 向左 | 正脸向左偏转 8~60 度 |
不建议使用 Roll 倾斜头部方式录入,应缓慢转头并保持偏转。
---
### 3.4 用户管理类
| 功能 | 命令 | Code | Data | 说明 |
|---|---|---:|---|---|
| 删除指定用户 | DELETE USER | `0x20` | user_id 高字节 + 低字节 | 删除一个已注册用户 |
| 删除全部用户 | DELETE ALL | `0x21` | 无 | 删除所有注册用户 |
| 查询用户信息 | GET USER INFO | `0x22` | user_id 高字节 + 低字节 | 返回用户 ID、姓名、管理员标志 |
| 获取所有用户 ID | MID_GET_ALL_USERID | `0x24` | alluserid_index | 每包最多 100 个用户 ID |
| 获取所有用户 ID 2 | MID_GET_ALL_USERID2 | `0x25` | alluserid_index | AI-10 适用user_counts 为 2 bytes |
---
### 3.5 加密通信类
| 功能 | 命令 | Code | Data | 说明 |
|---|---|---:|---|---|
| 初始化加密 | INIT ENCRYPTION | `0x50` | seed[4] + mode | 主控发送随机数 |
| 设置 Release 加密序列 | MID_SET_RELEASE_ENC_KEY | `0x52` | enc_key_number[16] | 设置正式协议加密序列 |
| 设置 Debug 加密序列 | MID_SET_DEBUG_ENC_KEY | `0x53` | enc_key_number[16] | 设置调试协议加密序列 |
加密流程:
1. 主控给模组上电;
2. 模组发送明文 READY
3. 第一次使用需设置 16 bytes Release 加密序列;
4. 主控生成 4 bytes 随机数发送给模组;
5. 双方基于随机数和私有协议生成 16 bytes 会话密码;
6. 后续通信使用 AES/SMPL 加密;
7. 主控解密设备 ID 并确认设备身份;
8. 后续录入、验证等命令均按加密方式发送和接收。
> 实现注意:文档没有给出完整私有密钥派生算法和 AES/SMPL 细节Unity 侧如需启用加密通信,需要供应商提供 SDK、算法源码或加密协议补充文档。
---
### 3.6 USB / 图像参数类
| 功能 | 命令 | Code | Data | 说明 |
|---|---|---:|---|---|
| 读取 USB UVC 参数 | READ_USB_UVC_PARAMETERS | `0xB0` | 无 | 读取传图参数 |
| 设置 USB UVC 参数 | SET_USB_UVC_PARAMETERS | `0xB1` | USB Type + UVC 码率 + MJPG 质量 + 图像属性 | 设置传图模式、码率、质量、镜像/倒转 |
| 设置人脸框显示 | SET_FACE_LOCATION_DISPLAY | `0xB5` | 0/1 | 设置是否显示人脸框 |
USB Type 示例:
| 值 | 含义 |
|---:|---|
| `0x11` | USB1.1 + Bulk |
| `0x20` | USB2.0 + Bulk |
| `0x91` | USB1.1 + ISOC |
| `0xA0` | USB2.0 + ISOC |
图像属性:
| Bit | 说明 |
|---|---|
| BIT0 | 1 启用镜像 |
| BIT1 | 1 启用 180 度倒转 |
---
### 3.7 二维码识别类
| 功能 | 命令 | Code | Data | 说明 |
|---|---|---:|---|---|
| 扫描二维码 | MID_SCAN_QR_CODE | `0x70` | 0x00 + timeout | 读取二维码信息 |
| 自动探测二维码 | AUTO_VERIFY | `0x12` | at_verify + timeout | AI-10 低功耗自动探测模式下自动识别二维码 |
二维码 NOTE
- `NID_QR_DATA_FLAGS = 15` 表示 QR 数据;
- 可识别二维码不大于 250 bytes ASCII
- 不包含中文。
---
### 3.8 抓拍与图片上传类
| 功能 | 命令 | Code | 数据包规则 | 说明 |
|---|---|---:|---|---|
| 抓拍普通图片 | MID_SNAP&UPLOAD_IMAGE | `0x71` | 每包 1024 bytes最后一包按实际长度 | 240×320 图片 |
| 抓拍人脸图片 | MID_SNAP&UPLOAD_FACEIMAGE | `0x72` | 每包 1024 bytes最后一包按实际长度 | 320×320 人脸图,本地比对后上传 |
| 抓拍全视角大图 | MID_SNAP&UPLOAD_IMAGE_B | `0x74` | 每包 1024 bytes支持 DPI 参数 | 480×640 / 600×800 / 1200×1600 |
0x74 DPI 参数:
| DPI | 分辨率 |
|---:|---|
| 0 | 480×640 |
| 1 | 600×800 |
| 2 | 1200×1600仅 AI-10 有效 |
---
### 3.9 照片 / 特征下发注册类
| 功能 | 命令 | Code | 说明 |
|---|---|---:|---|
| 照片/特征注册,指定 ID | MID_ENROLL_WITH_PHOTO&ID | `0xD7` | 文档建议优先使用 0xF7 |
| 照片/特征注册 | MID_ENROLL_WITH_PHOTO | `0xF7` | 推荐使用 |
| 设置彩色识别阈值 | RGB_LEVEL | `0xD4` | 彩色识别阈值 0~4默认 2 |
#### MID_ENROLL_WITH_PHOTO 0xF7 流程
1. 第一包:`Seq = 0`
2. Data 包含:
- `00`
- `00`
- 照片/特征长度4 bytes大端
- BioType
- 可选姓名长度;
- 可选姓名字符串;
- 可选重复检查标志;
3. 模组返回 Result 和 Seq
4. Result 成功后,主控从 `Seq = 1` 开始发送数据;
5. 每包数据最大 MTU ≤ 246 bytes
6. 最后一包不足 246 bytes 时按实际长度发送;
7. 发送完成后,模组返回最终注册结果和 UserID。
#### BioType 定义
| 值 | 说明 |
|---:|---|
| 0 | 普通照片 |
| 1 | 加密照片 |
| 2 | 普通特征码2048 bytes 彩色,或 4096 bytes 彩色+红外 |
| 3 | 压缩特征码1024 bytes |
特征文件长度:
| 类型 | 文件总长度 | 内容 |
|---|---:|---|
| 彩色+红外特征 | 4100 bytes | 4096 bytes 特征码 + 4 bytes CRC32 |
| 彩色特征 | 2052 bytes | 2048 bytes 特征码 + 4 bytes CRC32 |
| 压缩特征 | 1028 bytes | 1024 bytes 特征码 + 4 bytes CRC32 |
CRC32 初始向量值:`0xFFFFFFFF`
---
### 3.10 特征读写类AI-10
| 功能 | 命令 | Code | 说明 |
|---|---|---:|---|
| 读取特征 | MID_READ_FEATURE | `0xFA` | 按用户 ID 和特征类型读取模板 |
| 写入特征 | MID_WRITE_FEATURE | `0xFB` | 分包写入模板数据 |
Feature Type
| 值 | 说明 |
|---:|---|
| 1 | 彩色人脸模板 |
| 2 | 彩色 + 红外人脸模板 |
| 3 | 掌纹掌静脉模板 |
分包规则:
- 每包 246 bytes
- 从包序号 1 开始递增;
- 最后一包按实际剩余长度;
- 读取特征时先返回特征长度,再按包上传;
- 写入特征时先发送特征类型,再分包写入。
---
### 3.11 查重配置类
| 功能 | 命令 | Code | Data | 说明 |
|---|---|---:|---|---|
| 设置查重 | MID_DUPLICATE_CHECK | `0xFC` | Checkflag | 设置本地注册是否查重 |
| 查询查重状态 | MID_READ_DUPLICATE_CHECK | `0xFC` | 无 | 不带参数时查询当前查重状态 |
Checkflag
| 值 | 文档说明 |
|---:|---|
| 0 | 查重 |
| 1 | 不查重 |
说明:
- 默认查重;
- 设置后立即生效并保存到 Flash
- 重启后仍有效;
- SI-M1 V2.10 以上支持。
---
### 3.12 固件升级类
| 功能 | 命令 | Code | 说明 |
|---|---|---:|---|
| U 盘升级固件 | MID_UPGRADE_FW | `0xF6` | 启动通过 U 盘升级模组固件 |
返回数据中包含升级进度百分比。
---
## 4. 模组返回给主控的消息
模组主要返回三类消息:
| 类型 | MsgID | 说明 |
|---|---:|---|
| REPLY | `0x00` | 命令最终执行结果 |
| NOTE | `0x01` | 模组主动通知,例如 READY、人脸状态、二维码数据 |
| ImageOrTemplate | 业务 mid | 图片或特征模板数据流 |
---
## 5. REPLY 消息
### 5.1 REPLY 格式
```text
SyncWord MsgID=0x00 Size Data Checksum
Data = mid + result + data[n]
```
| 字段 | 说明 |
|---|---|
| mid | 被回复的命令 ID |
| result | 命令执行结果 |
| data | 不同命令对应的返回数据 |
### 5.2 常见 REPLY 返回数据
| mid | Code | 成功时返回 |
|---|---:|---|
| MID_GETSTATUS | `0x11` | status |
| MID_VERIFY | `0x12` | user_id + user_name + admin + unlockStatus |
| MID_ENROLL | `0x13` | user_id + face_direction |
| MID_ENROLL_SINGLE | `0x1D` | user_id + face_direction |
| MID_GETUSERINFO | `0x22` | user_id + user_name + admin |
| MID_GET_ALL_USERID | `0x24` | user_counts + users_id[] |
| MID_GET_VERSION | `0x30` | version data |
| MID_INIT_ENCRYPTION | `0x50` | device_id[20] |
| MID_GET_SN | `0x93` | Device_SN[32],前 8 bytes 有效 |
| MID_SCAN_QR_CODE | `0x70` | QR CODE |
| MID_SNAP_UPLOAD_IMAGE | `0x71` | result + photo_len 或图片数据 |
| MID_SNAP_UPLOAD_FACEIMAGE | `0x72` | result + photo_len + user_id 或图片数据 |
| MID_ENROLL_WITH_PHOTO | `0xF7` | seq + user_id |
| MID_READ_FEATURE | `0xFA` | result + seq + feature_len 或特征数据 |
| MID_WRITE_FEATURE | `0xFB` | result + seq + user_id |
| MID_READ_DUPLICATE_CHECK | `0xFC` | state + duplicate |
---
## 6. Result 结果码
| Code | 名称 | 说明 |
|---:|---|---|
| 0 | MR_SUCCESS | 成功 |
| 1 | MR_REJECTED | 模组拒绝命令 |
| 2 | MR_ABORTED | 录入/验证算法终止 |
| 4 | MR_FAILED4_CAMERA | 相机打开失败 |
| 5 | MR_FAILED4_UNKNOWNREASON | 未知错误 |
| 6 | MR_FAILED4_INVALIDPARAM | 参数无效 |
| 7 | MR_FAILED4_NOMEMORY | 内存不足 |
| 8 | MR_FAILED4_UNKNOWNUSER | 没有已录入用户 |
| 9 | MR_FAILED4_MAXUSER | 超过最大用户数量 |
| 10 | MR_FAILED4_FACEENROLLED | 人脸已录入 |
| 12 | MR_FAILED4_LIVENESSCHECK | 活体检测失败 |
| 13 | MR_FAILED4_TIMEOUT | 录入或解锁超时 |
| 14 | MR_FAILED4_AUTHORIZATION | 加密芯片授权失败 |
| 19 | MR_FAILED4_READ_FILE | 读文件失败 |
| 20 | MR_FAILED4_WRITE_FILE | 写文件失败 |
| 21 | MR_FAILED4_NO_ENCRYPT | 通信协议未加密 |
| 23 | MR_FAILED4_NO_RGBIMAGE | RGB 图像没有 ready |
| 24 | MR_FAILED4_JPGPHOTO_LARGE | JPG 照片过大 |
| 25 | MR_FAILED4_JPGPHOTO_SMALL | JPG 照片过小 |
| 26 | MR_FAILED4_DETECT_QR | 识别过程中扫描并解码了二维码 |
---
## 7. NOTE 消息
### 7.1 NOTE 格式
```text
SyncWord MsgID=0x01 Size Data Checksum
Data = nid + data[n]
```
### 7.2 NID 定义
| NID | Code | 说明 |
|---|---:|---|
| NID_READY | 0 | 模组已准备好 |
| NID_FACE_STATE | 1 | 返回人脸状态、位置、姿态 |
| NID_UNKNOWNERROR | 2 | 未知错误 |
| NID_OTA_DONE | 3 | OTA 完成 |
| NID_EYE_STATE | 4 | 眼睛状态 |
| NID_AUTO_VERIFY | 10 | 自动检测状态 |
| NID_QR_DATA_FLAGS | 15 | 二维码数据 |
---
## 8. NID_FACE_STATE 人脸状态数据
数据结构:
| 字段 | 类型 | 长度 | 说明 |
|---|---|---:|---|
| state | int16 | 2 bytes | 人脸状态 |
| left | int16 | 2 bytes | 人脸框左侧距离 |
| top | int16 | 2 bytes | 人脸框上方距离 |
| right | int16 | 2 bytes | 人脸框右侧距离 |
| bottom | int16 | 2 bytes | 人脸框下方距离 |
| yaw | int16 | 2 bytes | 左右转头角度,负为左转,正为右转 |
| pitch | int16 | 2 bytes | 上下抬头/低头,负为抬头,正为低头 |
| roll | int16 | 2 bytes | 歪头角度,负为右歪,正为左歪 |
### 8.1 Face State Code
| Code | 名称 | 说明 |
|---:|---|---|
| 0 | FACE_STATE_NORMAL | 人脸正常 |
| 1 | FACE_STATE_NOFACE | 未检测到人脸 |
| 2 | FACE_STATE_TOOUP | 太靠近上边沿 |
| 3 | FACE_STATE_TOODOWN | 太靠近下边沿 |
| 4 | FACE_STATE_TOOLEFT | 太靠近左边沿 |
| 5 | FACE_STATE_TOORIGHT | 太靠近右边沿 |
| 6 | FACE_STATE_FAR | 距离太远 |
| 7 | FACE_STATE_CLOSE | 距离太近 |
| 8 | FACE_STATE_EYEBROW_OCCLUSION | 眉毛遮挡 |
| 9 | FACE_STATE_EYE_OCCLUSION | 眼睛遮挡 |
| 10 | FACE_STATE_FACE_OCCLUSION | 脸部遮挡 |
| 11 | FACE_STATE_DIRECTION_ERROR | 录入方向错误 |
| 12 | FACE_STATE_EYE_CLOSE_STATUS_OPEN_EYE | 闭眼模式检测到睁眼 |
| 13 | FACE_STATE_EYE_CLOSE_STATUS | 闭眼状态 |
| 14 | FACE_STATE_EYE_CLOSE_UNKNOWN_STATUS | 无法判定睁闭眼 |
| 128 | PV_STATE_NORMAL | 检测到手掌信息 |
---
## 9. 核心业务流程
### 9.1 主控接收消息流程
```text
串口接收字节流
查找同步头 EF AA
读取 MsgID
读取 Size 高低字节
读取 Data
读取 Checksum 并校验
根据 MsgID 分发:
- 0x00REPLY
- 0x01NOTE
- 其他ImageOrTemplate
```
### 9.2 一般命令处理流程
```text
主控发送命令
模组执行命令
期间可能持续返回 NOTE
最终返回 REPLY
主控根据 result 判断成功/失败
```
如果超时或无结果:
- 主控可发送 GET STATUS 查询状态;
- 如果模组仍 BUSY可等待、取消或 RESET
- 如果出现 ERROR/INVALID应提示异常或重新上电。
### 9.3 上下电流程
```text
主控给模组上电
模组初始化
模组发送 NOTE:READY
主控开始发送业务命令
模组处理并返回结果
主控确认无消息或超时后可断电
```
### 9.4 录入流程
```text
发送 ENROLL / ENROLL_ITG
模组返回 NOTE:FACE_STATE
Unity 提示用户调整距离、方向、姿态
模组返回 REPLY:ENROLL
成功:记录 user_id 和 face_direction
失败:显示 result 对应原因
```
### 9.5 验证流程
```text
发送 VERIFY
模组返回 NOTE:FACE_STATE
Unity 实时显示检测状态
模组返回 REPLY:VERIFY
成功:得到 user_id / user_name / admin
失败:显示错误原因
```
### 9.6 照片下发注册流程
```text
发送 0xF7 第一包Seq=0 + PhotoLen + BioType + 可选扩展参数
模组 ACK
主控 Seq 从 1 开始分包发送照片/特征数据
每包 MTU ≤ 246 bytes
模组逐包 ACK
最后返回 UserID
```
---
## 10. 文档中的关键实现风险
| 风险 | 说明 | 建议 |
|---|---|---|
| 加密协议不完整 | 文档未给出私有密钥派生算法和 AES/SMPL 细节 | 向供应商索取 SDK 或补充协议 |
| 0x12 同时用于 VERIFY 和 AUTO_VERIFY | 同一 MsgID 下 Data 结构不同 | Unity API 层必须区分调用场景 |
| 0x71 / 0x72 / 0x74 返回数据有两阶段 | 第一阶段返回长度,第二阶段返回图片包 | 需要做图片接收状态机 |
| 0xF7 照片注册需要分包 | 每包 ≤246 bytes需等待 ACK 后继续 | 必须实现可靠分包发送队列 |
| 图片包为二进制流 | Unity 需要缓存 byte[] 并转换 Texture2D | 注意主线程 UI 更新 |
| 中文姓名编码未明确 | 文档仅说明 user_name 32 bytes / NameString 长度 | 建议先按 ASCII/UTF-8 测试,最终以供应商确认为准 |
| UVC 视频预览与串口协议是两条链路 | 文档里有 USB UVC 参数,但协议数据只负责控制 | Unity 视频画面需要单独使用 UVC/USB 摄像头方案 |
---
## 11. 一句话总结
这份文档定义了 **主控与 SI-M1 人脸识别模组之间的二进制通信协议**主控通过固定帧格式发送录入、验证、删除、查询、抓拍、二维码、照片注册、特征读写、加密、UVC 参数、升级等命令;模组通过 REPLY 返回最终结果,通过 NOTE 主动上报状态,通过 ImageOrTemplate 分包上传图片或特征模板。

View File

@ -1,437 +0,0 @@
# SI-M1 串口指令测试说明
本文档用于串口助手或底层串口程序直接测试 SI-M1 人脸识别模组协议。Unity 端同样按本文的封包格式发送命令。
## 1. 基础封包格式
主控发送:
```text
EF AA MID SIZE_H SIZE_L DATA... CHECKSUM
```
字段说明:
| 字段 | 长度 | 说明 |
| --- | --- | --- |
| `EF AA` | 2 bytes | 同步头 |
| `MID` | 1 byte | 命令 ID |
| `SIZE_H SIZE_L` | 2 bytes | DATA 长度,大端 |
| `DATA` | N bytes | 命令参数,可为空 |
| `CHECKSUM` | 1 byte | `MID ^ SIZE_H ^ SIZE_L ^ DATA[0] ^ ...` |
模组回复:
```text
EF AA 00 SIZE_H SIZE_L MID RESULT DATA... CHECKSUM
```
主动通知:
```text
EF AA 01 SIZE_H SIZE_L NID DATA... CHECKSUM
```
常见结果码:
| Result | 说明 |
| --- | --- |
| `00` | 成功 |
| `01` | 模组拒绝命令 |
| `02` | 操作终止 |
| `06` | 参数无效 |
| `08` | 未找到用户 |
| `09` | 用户已满 |
| `0A` | 人脸已录入 |
| `0C` | 活体检测失败 |
| `0D` | 超时 |
## 2. 通用测试准备
1. 打开串口:默认 `115200`8N1。
2. 上电后先等模组主动发 READY`EF AA 01 00 01 00 00`
3. 如果没有 READY可发送 `GET STATUS` 确认设备是否在线。
4. 中文用户名使用 UTF-8定长 `user_name[32]` 不足补 `00`
5. 多字节数值均为大端,例如用户 ID `1``00 01`
## 3. 基础接口
| 接口 | MID | DATA | 示例发送 Hex | 成功回复 DATA |
| --- | --- | --- | --- | --- |
| 复位模组 | `10` | 无 | `EF AA 10 00 00 10` | 无 |
| 获取状态 | `11` | 无 | `EF AA 11 00 00 11` | `status` |
| 取消当前人脸流程 | `23` | 无 | `EF AA 23 00 00 23` | 无 |
| 获取版本 | `30` | 无 | `EF AA 30 00 00 30` | 版本字符串 |
| 获取 SN | `93` | 无 | `EF AA 93 00 00 93` | `Device_SN[32]`,前 8 bytes 有效 |
| 固件升级 | `F6` | 无 | `EF AA F6 00 00 F6` | 无,后续等 OTA 通知 |
状态值:
| Status | 说明 |
| --- | --- |
| `00` | Standby 待机 |
| `01` | Busy 忙碌 |
| `02` | Error 错误 |
| `03` | Invalid 无效 |
## 4. 人脸验证接口
### 4.1 普通验证 `VERIFY`
DATA
```text
pd_rightaway timeout max_recognition_times
```
| 字段 | 示例 | 说明 |
| --- | --- | --- |
| `pd_rightaway` | `00` | 普通验证 |
| `timeout` | `0A` | 超时时间,单位秒 |
| `max_recognition_times` | `1E` | 最大识别次数 |
示例发送:
```text
EF AA 12 00 03 00 0A 1E 05
```
成功回复 DATA
```text
user_id[2] user_name[32] admin unlock_status
```
### 4.2 自动验证 `AUTO_VERIFY`
DATA
```text
at_verify timeout
```
| 字段 | 示例 | 说明 |
| --- | --- | --- |
| `at_verify` | `01` | `01` 开启,`00` 关闭 |
| `timeout` | `0A` | 超时时间,单位秒 |
示例发送:
```text
EF AA 12 00 02 01 0A 1B
```
## 5. 人脸录入接口
用户名字段:
```text
user_name[32]
```
例如 `张三` 的 UTF-8 bytes 为:
```text
E5 BC A0 E4 B8 89
```
写入 `user_name[32]` 时格式为:
```text
E5 BC A0 E4 B8 89 00 00 ... 共 32 bytes
```
方向值:
| 值 | 说明 |
| --- | --- |
| `01` | 正脸 |
| `02` | 向右 |
| `04` | 向左 |
| `08` | 向下 |
| `10` | 向上 |
### 5.1 交互录入 `ENROLL`
DATA
```text
admin user_name[32] face_dir timeout
```
示例非管理员、空用户名、正脸、20 秒:
```text
EF AA 13 00 23 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
01 14 25
```
成功回复 DATA
```text
user_id[2] face_direction
```
录入成功后建议立即发送 `GET USER INFO` 确认:
```text
EF AA 22 00 02 00 01 21
```
### 5.2 单帧录入 `ENROLL_SINGLE`
DATA 同 `ENROLL`MID 改为 `1D`
示例非管理员、空用户名、正脸、20 秒:
```text
EF AA 1D 00 23 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
01 14 2B
```
### 5.3 集成录入 `ENROLL_ITG`
Unity 当前 DATA 顺序:
```text
admin user_name[32] face_dir timeout single_frame duplicate_flag reserved
```
| 字段 | 说明 |
| --- | --- |
| `single_frame` | `01` 单帧,`00` 交互 |
| `duplicate_flag` | `00` 查重,`01` 不查重 |
| `reserved` | 固定 `00` |
成功回复 DATA
```text
user_id[2] face_direction
```
### 5.4 抓拍人脸后注册 `ENROLL_SNAPFACEIMAGE`
DATA
```text
admin user_name[32] 00 00
```
成功回复 DATA
```text
user_id[2] face_direction
```
## 6. 用户管理接口
| 接口 | MID | DATA | 示例发送 Hex | 成功回复 DATA |
| --- | --- | --- | --- | --- |
| 删除用户 | `20` | `user_id[2]` | `EF AA 20 00 02 00 01 23` | 无 |
| 删除全部用户 | `21` | 无 | `EF AA 21 00 00 21` | 无 |
| 查询用户信息 | `22` | `user_id[2]` | `EF AA 22 00 02 00 01 21` | `user_id[2] user_name[32] admin` |
| 查询所有用户 ID | `24` | `page_index` | `EF AA 24 00 01 00 25` | `count[1] user_id[]` |
| 查询所有用户 ID 2 | `25` | `page_index` | `EF AA 25 00 01 00 24` | `count[2] user_id[]` |
分页说明:
- `page_index``00` 开始。
- 每页最多 100 个 ID。
- 当返回数量小于 100 时,表示最后一页。
## 7. 二维码接口
DATA
```text
00 timeout
```
示例:扫描 10 秒:
```text
EF AA 70 00 02 00 0A 78
```
成功回复 DATA
```text
QR 字符串 bytes
```
模组也可能通过 NOTE `NID=0F` 主动上报二维码内容。
## 8. 图片抓拍接口
| 接口 | MID | DATA | 示例发送 Hex | 回复说明 |
| --- | --- | --- | --- | --- |
| 普通图片抓拍 | `71` | 无 | `EF AA 71 00 00 71` | 先回复图片长度,再用 MID `71` 分包上传图片 |
| 人脸图片抓拍 | `72` | 无 | `EF AA 72 00 00 72` | 先回复图片长度和用户 ID再用 MID `72` 分包上传图片 |
| 大图抓拍 | `74` | `dpi` | `EF AA 74 00 01 00 75` | 先回复图片长度,再用 MID `74` 分包上传图片 |
大图 DPI
| 值 | 说明 |
| --- | --- |
| `00` | 480x640 |
| `01` | 600x800 |
| `02` | 1200x1600 |
图片 DATA 包由模组发送Unity 按数据总长度拼接。
## 9. 照片注册接口
### 9.1 推荐照片注册 `ENROLL_WITH_PHOTO`
初始化包 DATA
```text
00 00 file_size[4] bio_type name_len name_bytes duplicate_flag
```
| 字段 | 说明 |
| --- | --- |
| `file_size[4]` | 图片或特征文件总长度,大端 |
| `bio_type` | `00` 普通照片,`01` 加密照片,`02` 普通特征,`03` 压缩特征 |
| `name_len` | 用户名 UTF-8 byte 长度 |
| `name_bytes` | 用户名 UTF-8 bytes |
| `duplicate_flag` | `00` 查重,`01` 不查重 |
示例:文件长度 1024普通照片姓名 `张三`,查重:
```text
EF AA F7 00 0F 00 00 00 00 04 00 00 06 E5 BC A0 E4 B8 89 00 D6
```
后续文件分包 DATA
```text
seq[2] file_bytes
```
说明:
- `seq``00 01` 开始。
- 每包最多 246 bytes。
- 每包 MID 仍为 `F7`
- 最后一包发送完成后,成功回复 DATA 通常包含 `user_id[2]`
### 9.2 指定 ID 照片注册 `ENROLL_WITH_PHOTO_AND_ID`
初始化包 DATA
```text
00 00 user_id[2] file_size[4] bio_type name_len name_bytes duplicate_flag
```
后续文件分包规则同 `F7`MID 为 `D7`
## 10. 特征接口
### 10.1 读取特征 `READ_FEATURE`
DATA
```text
00 00 user_id[2] feature_type
```
示例:读取用户 1 的彩色人脸特征:
```text
EF AA FA 00 05 00 00 00 01 01 FF
```
特征类型:
| 值 | 说明 |
| --- | --- |
| `01` | 彩色人脸 |
| `02` | 彩色加红外人脸 |
| `03` | 手掌 |
回复说明:
- 首个 REPLY DATA 返回特征总长度。
- 后续模组用 MID `FA` 分包发送特征 bytes。
### 10.2 写入特征 `WRITE_FEATURE`
初始化包 DATA
```text
00 00 feature_type name_len name_bytes
```
后续特征分包 DATA
```text
seq[2] feature_bytes
```
说明:
- `seq``00 01` 开始。
- 每包最多 246 bytes。
- 每包 MID 仍为 `FB`
- 最后一包成功后回复 `user_id[2]`
## 11. UVC 与高级设置接口
| 接口 | MID | DATA | 示例发送 Hex | 说明 |
| --- | --- | --- | --- | --- |
| 读取 UVC 参数 | `B0` | 无 | `EF AA B0 00 00 B0` | 返回 `usb_type bitrate quality attributes` |
| 设置 UVC 参数 | `B1` | `usb_type bitrate quality attributes` | `EF AA B1 00 04 20 08 50 00 CD` | 示例为 USB2.0、8Mbps、质量 80、无镜像旋转 |
| 设置人脸框显示 | `B5` | `visible` | `EF AA B5 00 01 01 B5` | `01` 显示,`00` 隐藏 |
| 设置 RGB 阈值 | `D4` | `level` | `EF AA D4 00 01 02 D7` | `level` 范围 0 到 4 |
| 设置查重 | `FC` | `check_flag` | `EF AA FC 00 01 00 FD` | `00` 查重,`01` 不查重 |
| 查询查重 | `FC` | 无 | `EF AA FC 00 00 FC` | 返回查重状态 |
| 设置 Demo Mode | `FE` | `enable` | `EF AA FE 00 01 01 FE` | `01` 开启,`00` 关闭 |
UVC `attributes`
| bit | 说明 |
| --- | --- |
| bit0 | 镜像 |
| bit1 | 旋转 180 度 |
## 12. 加密接口
| 接口 | MID | DATA | 示例发送 Hex |
| --- | --- | --- | --- |
| 初始化加密 | `50` | `seed[4] mode` | `EF AA 50 00 05 00 01 02 03 00 55` |
| 设置 Release Key | `52` | `key[16]` | `EF AA 52 00 10 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 42` |
| 设置 Debug Key | `53` | `key[16]` | `EF AA 53 00 10 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 43` |
说明:
- Key 必须为 16 bytes。
- 初始化加密后,后续是否需要加密封包取决于模组固件配置和供应商协议细节。
## 13. 推荐人工测试顺序
1. `GET STATUS`:确认串口可通信。
2. `GET VERSION` / `GET SN`:确认设备信息读取正常。
3. `VERIFY`:无用户时应返回未找到用户或超时。
4. `ENROLL_SINGLE``ENROLL`:录入一个测试用户。
5. `GET ALL USER ID`:确认用户列表出现新 ID。
6. `GET USER INFO`:确认用户名、管理员标记正确,中文姓名不应显示为 `?`
7. `VERIFY`:确认刚录入的人脸可以验证成功。
8. `SNAP_UPLOAD_IMAGE`:确认图片分包可以完整拼接。
9. `READ/WRITE FEATURE`、照片注册、UVC 参数、加密接口按需要继续验证。
## 14. 常见问题
| 现象 | 排查方向 |
| --- | --- |
| 串口打开但无回复 | 确认波特率、TX/RX 线序、供电、GND、是否收到 READY |
| 校验失败 | 重新计算 `CHECKSUM = MID ^ SIZE_H ^ SIZE_L ^ DATA...` |
| 中文姓名变成 `?` | 确认发送端使用 UTF-8不要使用 ASCII |
| 录入成功但列表无用户 | 录入成功后立即发 `GET ALL USER ID``GET USER INFO` 确认 |
| 图片或特征不完整 | 串口助手需要保留二进制原始 bytes不能按文本行读取 |
| 多包命令超时 | 分包 `seq``00 01` 开始,每包最大 246 bytes |

View File

@ -1,16 +0,0 @@
# Interface And Development Notes
This public package is distributed as compiled DLLs and does not include SDK source files, Demo source files, or internal test source files.
Use these public entry points from your Unity project:
- `Aisu.SIM1.Face.Core.FaceModuleManager`
- `Aisu.SIM1.Face.Core.FaceSdkSettings`
- `Aisu.SIM1.Face.Commands.*Service`
- `Aisu.SIM1.Face.Models.*`
- `Aisu.SIM1.Face.Protocol.*`
- `Aisu.SIM1.Face.Transport.IFaceModuleTransport`
For quick setup, see `SDK_QuickStart.md`.
For API details, see `SDK_API_Reference.md`.
For serial command behavior, see `串口指令测试说明.md`.

View File

@ -1,6 +1,8 @@
# AISU SI-M1 Face SDK
# AISU SI-M1 Face SDK
`xin.aisu.si-m1.face` is a Unity UPM package for the AISU SI-M1 face recognition module. This public package is distributed as compiled DLLs and does not include SDK source code.
`xin.aisu.si-m1.face` is a Unity UPM package for the AISU SI-M1 face recognition module. This public package is distributed as compiled DLLs and does not include SDK source code, demo source code, test source code, or debug symbols.
中文说明见 [README.zh-CN.md](README.zh-CN.md).
## Package Info
@ -8,25 +10,28 @@
|---|---|
| Package Name | `xin.aisu.si-m1.face` |
| Display Name | `AISU SI-M1 Face SDK` |
| Version | `0.1.2` |
| Runtime Assembly | `Aisu.SIM1.Face.Runtime.dll` |
| Editor Assembly | `Aisu.SIM1.Face.Editor.dll` |
| Unity Version | `2021.3` or newer |
| Default Settings Path | `Assets/AISU/SI-M1 Face SDK/FaceSdkSettings.asset` |
| User Settings Asset | `Assets/AISU/SI-M1 Face SDK/FaceSdkSettings.asset` in the importing Unity project |
## Install
Add the package through Unity Package Manager using a Git URL, or add it to `Packages/manifest.json`:
Add the package through Unity Package Manager using this Git URL:
```json
"xin.aisu.si-m1.face": "https://github.com/your-org/si-m1-face-package.git#v0.1.0"
```text
https://git.aisu.xin/aisu-sdk/si-m1-face-package.git#v0.1.2
```
For local validation:
Or add it to `Packages/manifest.json`:
```json
"xin.aisu.si-m1.face": "file:D:/Workspaces/SDK/si-m1-face-package"
"xin.aisu.si-m1.face": "https://git.aisu.xin/aisu-sdk/si-m1-face-package.git#v0.1.2"
```
Unity may display Git packages as `xin.aisu.si-m1.face@<commit-hash>` in `Library/PackageCache`. This is expected for Git URL packages; the package version remains defined by `package.json`.
## Quick Start
1. Open `AISU/SI-M1 Face SDK/Settings` and create or load `FaceSdkSettings`.
@ -55,16 +60,18 @@ public sealed class FaceExample : MonoBehaviour
## Documentation
| Document | Description |
| English | Chinese |
|---|---|
| [SDK_QuickStart.md](Documentation~/SDK_QuickStart.md) | Installation, settings, manager creation, minimal call flow |
| [SDK_Configuration.md](Documentation~/SDK_Configuration.md) | `FaceSdkSettings`, editor panel, mock mode, serial parameters |
| [SDK_API_Reference.md](Documentation~/SDK_API_Reference.md) | Public namespaces, manager, events, services, models, callback API |
| [SDK_Mock_And_Testing.md](Documentation~/SDK_Mock_And_Testing.md) | Mock behavior and validation guidance |
| [Quick Start](Documentation~/SDK_QuickStart.md) | [快速开始](Documentation~/SDK_QuickStart.zh-CN.md) |
| [Configuration](Documentation~/SDK_Configuration.md) | [配置说明](Documentation~/SDK_Configuration.zh-CN.md) |
| [API Reference](Documentation~/SDK_API_Reference.md) | [API 参考](Documentation~/SDK_API_Reference.zh-CN.md) |
| [Mock and Testing](Documentation~/SDK_Mock_And_Testing.md) | [Mock 与测试](Documentation~/SDK_Mock_And_Testing.zh-CN.md) |
| [Demo UI Notice](Documentation~/README_UI.md) | [Demo UI 说明](Documentation~/README_UI.zh-CN.md) |
## Public Package Notes
## Public Package Scope
- This package does not include SDK source files.
- This package does not include `.pdb` debug symbols.
- Demo and test source files are not included in this DLL-only release.
- If you need sample source or internal tests, use the private development SDK repository.
- SDK source files are not included.
- `.pdb` debug symbols are not included.
- Demo and test source files are not included.
- Importable `Samples~` are not included in this DLL-only release.
- Sample source and internal validation tests are maintained in the private development SDK repository.

77
README.zh-CN.md Normal file
View File

@ -0,0 +1,77 @@
# AISU SI-M1 Face SDK
`xin.aisu.si-m1.face` 是面向 AISU SI-M1 人脸识别模组的 Unity UPM 包。公开发布包以编译后的 DLL 形式提供,不包含 SDK 源码、Demo 源码、测试源码或调试符号。
English documentation: [README.md](README.md).
## 包信息
| 项目 | 值 |
|---|---|
| Package Name | `xin.aisu.si-m1.face` |
| Display Name | `AISU SI-M1 Face SDK` |
| Version | `0.1.2` |
| Runtime Assembly | `Aisu.SIM1.Face.Runtime.dll` |
| Editor Assembly | `Aisu.SIM1.Face.Editor.dll` |
| Unity Version | `2021.3` 或更高 |
| 用户项目配置资产 | 导入项目中的 `Assets/AISU/SI-M1 Face SDK/FaceSdkSettings.asset` |
## 安装
在 Unity Package Manager 中使用以下 Git URL 导入:
```text
https://git.aisu.xin/aisu-sdk/si-m1-face-package.git#v0.1.2
```
或写入 `Packages/manifest.json`
```json
"xin.aisu.si-m1.face": "https://git.aisu.xin/aisu-sdk/si-m1-face-package.git#v0.1.2"
```
Unity 对 Git URL 包可能会在 `Library/PackageCache` 中显示为 `xin.aisu.si-m1.face@<commit-hash>`。这是 Git 包的正常行为;包版本仍由 `package.json` 中的 `version` 字段定义。
## 快速开始
1. 打开 `AISU/SI-M1 Face SDK/Settings`,创建或加载 `FaceSdkSettings`
2. 配置串口号、波特率、Mock 模式和日志选项。
3. 打开 `AISU/SI-M1 Face SDK/Create Manager GameObject`,在当前场景中创建 `FaceModuleManager`
4. 在业务脚本中引用该 Manager 并调用 SDK 服务。
```csharp
using Aisu.SIM1.Face.Core;
using UnityEngine;
public sealed class FaceExample : MonoBehaviour
{
[SerializeField] private FaceModuleManager manager;
private async void Start()
{
manager.Open();
await manager.WaitReadyAsync();
var version = await manager.Basic.GetVersionAsync();
Debug.Log("SI-M1 version: " + version);
}
}
```
## 文档
| English | 中文 |
|---|---|
| [Quick Start](Documentation~/SDK_QuickStart.md) | [快速开始](Documentation~/SDK_QuickStart.zh-CN.md) |
| [Configuration](Documentation~/SDK_Configuration.md) | [配置说明](Documentation~/SDK_Configuration.zh-CN.md) |
| [API Reference](Documentation~/SDK_API_Reference.md) | [API 参考](Documentation~/SDK_API_Reference.zh-CN.md) |
| [Mock and Testing](Documentation~/SDK_Mock_And_Testing.md) | [Mock 与测试](Documentation~/SDK_Mock_And_Testing.zh-CN.md) |
| [Demo UI Notice](Documentation~/README_UI.md) | [Demo UI 说明](Documentation~/README_UI.zh-CN.md) |
## 公开包范围
- 不包含 SDK 源码。
- 不包含 `.pdb` 调试符号。
- 不包含 Demo 和测试源码。
- DLL-only 公开版本不包含可导入的 `Samples~`
- 示例源码和内部验证测试保留在私有开发 SDK 仓库中。

7
README.zh-CN.md.meta Normal file
View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 5f77a4e01fe647b0a7054dc093177a11
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,7 +1,7 @@
{
"name": "xin.aisu.si-m1.face",
"displayName": "AISU SI-M1 Face SDK",
"version": "0.1.1",
"version": "0.1.2",
"unity": "2021.3",
"description": "Unity UPM package for the AISU SI-M1 face recognition module protocol, transport, command services, and lifecycle manager. Distributed as compiled DLLs without source code.",
"author": {