Prepare DLL-only UPM package v0.1.0

This commit is contained in:
su 2026-08-04 15:38:28 +08:00
commit c7b8ba0cef
27 changed files with 1818 additions and 0 deletions

17
.gitignore vendored Normal file
View File

@ -0,0 +1,17 @@
# Unity local/generated files
Library/
Temp/
Obj/
Logs/
UserSettings/
.vs/
# Do not publish SDK source or debug symbols in this DLL-only package repo
*.cs
*.asmdef
*.pdb
*.mdb
# OS/editor noise
.DS_Store
Thumbs.db

8
CHANGELOG.md Normal file
View File

@ -0,0 +1,8 @@
# Changelog
## 0.1.0
- Initial UPM package migration for the SI-M1 face module Unity implementation.
- Added Runtime, Editor, Tests, Samples, and Documentation package structure.
- Migrated protocol, transport, command service, manager, tests, and demo sample files from `Assets/App`.
- Limited transport support to serial port and Editor Mock, and removed temporary Android bridge placeholders.

View File

@ -0,0 +1,11 @@
# Demo UI
The public DLL-only UPM package does not include Demo UI source files or importable sample scenes.
Use the SDK from your own Unity scene by creating a `FaceModuleManager` through:
```text
AISU/SI-M1 Face SDK/Create Manager GameObject
```
For Demo UI source, sample scenes, or internal validation tests, use the private development SDK repository.

View File

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

View File

@ -0,0 +1,265 @@
# SI-M1 Face SDK 接口文档
本文列出 SDK 对业务层推荐使用的公开 API。命名空间统一为 `Aisu.SIM1.Face.*`
## 1. 命名空间
| 命名空间 | 说明 |
|---|---|
| `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 等模型 |
## 2. FaceModuleManager
`FaceModuleManager` 是 SDK 推荐的统一入口。
```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)` | 收到 ImageOrTemplate 数据包 |
| `OnError(FaceResultCode, string)` | 错误上报 |
| `OnRawLog(string)` | 原始 TX / RX 日志 |
## 3. 基础服务 FaceBasicService
访问路径:
```csharp
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>` | 启动固件升级命令 |
## 4. 验证服务 FaceVerifyService
访问路径:
```csharp
manager.Verify
```
| 方法 | 返回 | 说明 |
|---|---|---|
| `VerifyAsync(byte timeout, byte maxRecognitionTimes = 30)` | `Task<FaceVerifyResult>` | 单次人脸验证 |
| `AutoVerifyAsync(bool enable, byte timeout)` | `Task<FaceVerifyResult>` | 启用或关闭自动验证 |
## 5. 录入服务 FaceEnrollmentService
访问路径:
```csharp
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>` | 抓拍人脸后注册 |
## 6. 用户服务 FaceUserService
访问路径:
```csharp
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>>` | 使用扩展命令查询全部用户详情 |
## 7. 二维码服务 FaceQrCodeService
访问路径:
```csharp
manager.QrCode
```
| 方法 | 返回 | 说明 |
|---|---|---|
| `ScanQrCodeAsync(byte timeout)` | `Task<string>` | 扫描二维码并返回内容 |
## 8. 图片服务 FaceImageService
访问路径:
```csharp
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 照片注册 |
## 9. 特征服务 FaceFeatureService
访问路径:
```csharp
manager.Features
```
| 方法 | 返回 | 说明 |
|---|---|---|
| `ReadFeatureAsync(int userId, FeatureType type)` | `Task<byte[]>` | 读取指定用户特征 |
| `WriteFeatureAsync(byte[] featureBytes, FeatureType type, string userName = null, Action<int, int> onProgress = null)` | `Task<FaceEnrollResult>` | 写入特征并注册 |
## 10. UVC 和高级参数 FaceUvcService
访问路径:
```csharp
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>` | 读取查重状态 |
## 11. 加密服务 FaceEncryptionService
访问路径:
```csharp
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` | 关闭本地加密算法适配器 |
`IFaceModuleCrypto`
```csharp
public interface IFaceModuleCrypto
{
byte[] Encrypt(byte[] plainBytes);
byte[] Decrypt(byte[] encryptedBytes);
byte[] GenerateSessionKey(byte[] seed4, byte[] encKey16);
}
```
## 12. 回调式 API
`FaceModuleManager.Callback` 适合 Unity Button、旧项目回调风格或不方便使用 `await` 的业务。
```csharp
manager.Callback.Verify(
timeout: 10,
success: result => Debug.Log(result.UserId),
error: message => Debug.LogError(message));
```
回调特点:
- 所有 API 统一使用 `success``error`
- 照片注册、特征写入支持 `progress(current, total)`
- 回调会通过 `FaceModuleMainThreadDispatcher` 回到 Unity 主线程。
## 13. 主要模型
| 类型 | 说明 |
|---|---|
| `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 实现 |

View File

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

View File

@ -0,0 +1,126 @@
# SI-M1 Face SDK 配置与 Editor 工具
SDK 使用 `FaceSdkSettings` 作为推荐配置方式。该配置是 `ScriptableObject`,可在项目中复用,并可同步到场景中的 `FaceModuleManager`
## 1. 默认配置资产
默认路径:
```text
Assets/AISU/SI-M1 Face SDK/FaceSdkSettings.asset
```
打开菜单 `AISU/SI-M1 Face SDK/Settings`Editor 会加载该路径。若文件不存在,点击 `Load Default` 会创建默认资产。
## 2. FaceSdkSettings 字段
| 字段 | 类型 | 说明 |
|---|---|---|
| `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` | 日志前缀 |
## 3. TransportMode 选择
| 模式 | 行为 |
|---|---|
| `Auto` | Editor 根据 `UseMockInEditor` 选择 Mock 或串口Player 使用串口 |
| `SerialPort` | 使用 `SerialPortTransport` |
| `Mock` | 使用 `MockFaceModuleTransport` |
Editor 下有一个额外优先级:
```text
UseMockInEditor = true 时,强制使用 Mock不打开真实串口。
```
因此 Editor 中如果需要连接真实串口,必须将 `UseMockInEditor` 设为 `false`
## 4. Editor Serial Debug 参数
Editor 连接真实硬件时,建议开启:
```text
UseEditorSerialDebugParameters = true
```
开启后Editor 中串口使用:
- `EditorPortName`
- `EditorBaudRate`
- `EditorReadBufferSize`
Player 中仍使用:
- `PortName`
- `BaudRate`
- `ReadBufferSize`
这样可以避免 Editor 调试口和发布运行口互相覆盖。
## 5. Editor 工具按钮
配置窗口按钮:
| 按钮 | 行为 |
|---|---|
| `Load Default` | 固定加载或创建默认路径的 `FaceSdkSettings.asset` |
| `Save` | 保存当前配置并同步场景中的 Manager |
| `Save and Create/Update Manager` | 保存配置后创建或更新场景 Manager |
同步 Manager 时会写入:
- `m_settings`
- `m_config.TransportMode`
- `m_config.UseMockInEditor`
- 串口参数
- Editor 串口参数
- Mock 延迟
- Raw Log 开关
PlayMode 中同步配置时,会调用 `FaceModuleManager.ApplySettings(settings)`,立即重建当前 transport。
## 6. Manager 配置方式
推荐方式:
```csharp
manager.ApplySettings(settings);
manager.Open();
```
兼容方式:
```csharp
manager.Configure(useMockInEditor: true, portName: "COM3", baudRate: 115200);
manager.Open();
```
外部通信层注入:
```csharp
manager.ConfigureTransport(customTransport);
manager.Open();
```
## 7. 场景约束
每个场景建议只保留一个 `FaceModuleManager`
多个 Manager 可能导致:
- 多次打开同一串口。
- 重复接收和派发事件。
- UI 状态不一致。
`Create Manager GameObject` 菜单会校验 Manager 数量,并在存在多个 Manager 时停止创建。

View File

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

View File

@ -0,0 +1,26 @@
# Mock And Testing
The public DLL-only package includes runtime mock support inside `Aisu.SIM1.Face.Runtime.dll`, but it does not include EditMode test source files.
## Editor Mock
For Editor integration without real hardware, enable mock mode in `FaceSdkSettings`:
```text
Use Mock In Editor = true
```
When this option is enabled, the SDK uses the built-in mock transport in the Unity Editor instead of opening a real serial port.
## Hardware Validation
For real SI-M1 hardware validation:
1. Set `Use Mock In Editor = false`.
2. Configure `Editor Port Name`, `Editor Baud Rate`, and `Editor Read Buffer Size`.
3. Create a `FaceModuleManager` in the scene.
4. Call `Open()`, then wait for `WaitReadyAsync()` or handle `OnReady`.
## Automated Tests
Internal EditMode tests are maintained in the private development SDK repository and are not distributed in this DLL-only public package.

View File

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

View File

@ -0,0 +1,77 @@
# 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.
## 1. Install
Add the package through Unity Package Manager, or add it to `Packages/manifest.json`:
```json
"xin.aisu.si-m1.face": "https://github.com/your-org/si-m1-face-package.git#v0.1.0"
```
For local validation:
```json
"xin.aisu.si-m1.face": "file:D:/Workspaces/SDK/si-m1-face-package"
```
## 2. Create Settings
Open Unity menu:
```text
AISU/SI-M1 Face SDK/Settings
```
The tool creates or loads the default settings asset:
```text
Assets/AISU/SI-M1 Face SDK/FaceSdkSettings.asset
```
Configure serial port, baud rate, mock mode, and logging options.
## 3. Create Manager
Open Unity menu:
```text
AISU/SI-M1 Face SDK/Create Manager GameObject
```
Keep one `FaceModuleManager` in the scene to avoid duplicate serial connections and duplicate event dispatch.
## 4. Minimal Code
```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. Runtime Modes
| Scenario | Recommended Setting |
|---|---|
| Editor UI 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.
- Demo source and EditMode test source remain in the private development SDK repository.

View File

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

View File

@ -0,0 +1,27 @@
# 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

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

View File

@ -0,0 +1,606 @@
# 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

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

View File

@ -0,0 +1,437 @@
# 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

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

View File

@ -0,0 +1,16 @@
# 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

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

Binary file not shown.

View File

@ -0,0 +1,23 @@
fileFormatVersion: 2
guid: 1b1f9b3bdf1e4d2c85e46e18dd9b0002
PluginImporter:
serializedVersion: 1
iconMap: {}
executionOrder: {}
isPreloaded: 0
isOverridable: 0
platformData:
Any:
enabled: 0
settings: {}
Editor:
enabled: 1
settings:
DefaultValueInitialized: true
WindowsStoreApps:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

5
LICENSE.md Normal file
View File

@ -0,0 +1,5 @@
# License
Proprietary. Copyright AISU.
Third-party native libraries, vendor SDK files, and device firmware assets retain their original license terms when added to this package.

70
README.md Normal file
View File

@ -0,0 +1,70 @@
# 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.
## Package Info
| Item | Value |
|---|---|
| Package Name | `xin.aisu.si-m1.face` |
| Display Name | `AISU SI-M1 Face SDK` |
| 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` |
## Install
Add the package through Unity Package Manager using a Git URL, or add it to `Packages/manifest.json`:
```json
"xin.aisu.si-m1.face": "https://github.com/your-org/si-m1-face-package.git#v0.1.0"
```
For local validation:
```json
"xin.aisu.si-m1.face": "file:D:/Workspaces/SDK/si-m1-face-package"
```
## Quick Start
1. Open `AISU/SI-M1 Face SDK/Settings` and create or load `FaceSdkSettings`.
2. Set serial port, baud rate, mock mode, and logging options.
3. Open `AISU/SI-M1 Face SDK/Create Manager GameObject` to create a `FaceModuleManager` in the current scene.
4. Reference the manager from your own scripts and call the SDK services.
```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);
}
}
```
## Documentation
| Document | Description |
|---|---|
| [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 |
## Public Package Notes
- 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.

Binary file not shown.

View File

@ -0,0 +1,23 @@
fileFormatVersion: 2
guid: 8cf50efc5a2c44d481a20dd7b5f0b001
PluginImporter:
serializedVersion: 1
iconMap: {}
executionOrder: {}
isPreloaded: 0
isOverridable: 0
platformData:
Any:
enabled: 1
settings: {}
Editor:
enabled: 0
settings:
DefaultValueInitialized: true
WindowsStoreApps:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

18
package.json Normal file
View File

@ -0,0 +1,18 @@
{
"name": "xin.aisu.si-m1.face",
"displayName": "AISU SI-M1 Face SDK",
"version": "0.1.0",
"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": {
"name": "AISU"
},
"keywords": [
"aisu",
"si-m1",
"face",
"recognition",
"serial",
"unity"
]
}