# 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()` | 同步安全关闭硬件流程并关闭串口 | | `CloseAsync()` | 异步安全关闭硬件流程并关闭串口 | | `StopFaceOperationAsync()` | 停止当前人脸流程,优先关闭自动验证 | | `StartAutoVerifyAsync(byte timeout)` | 开启自动验证,返回开关命令结果 | | `StopAutoVerifyAsync(byte timeout = 1)` | 关闭自动验证,返回开关命令结果 | | `WaitReadyAsync(int timeoutMs = 5000)` | 等待 READY NOTE | | `ProbeReadyByStatusAsync()` | 主动查询状态并标记 READY | | `SendRawBytes(byte[] bytes)` | 发送原始协议 bytes | | `RefreshStatus()` | 异步刷新 `CurrentStatus` | 真实串口运行前会自动校验 SDK 授权。授权文件默认路径: ```text Assets/StreamingAssets/si-m1_face.dat ``` ### 事件 | 事件 | 说明 | |---|---| | `OnReady` | 首次 READY | | `OnStatusChanged(FaceModuleStatus)` | 当前状态变化 | | `OnReplyReceived(FaceReply)` | 收到 REPLY 包 | | `OnNoteReceived(FaceNote)` | 收到 NOTE 包 | | `OnFaceStateUpdated(FaceFaceStateNote)` | 收到人脸状态 NOTE | | `OnAutoVerifyResult(FaceAutoVerifyResult)` | 收到自动验证识别结果 NOTE | | `OnQrCodeReceived(string)` | 收到二维码 NOTE | | `OnFeatureReceived(byte[])` | 收到读取特征数据包 | | `OnDataPacketReceived(FacePacket)` | 收到 ImageOrTemplate 数据包 | | `OnError(FaceResultCode, string)` | 错误上报 | | `OnRawLog(string)` | 原始 TX / RX 日志 | ## 3. 基础服务 FaceBasicService 访问路径: ```csharp manager.Basic ``` | 方法 | 返回 | 说明 | |---|---|---| | `ResetAsync()` | `Task` | 复位模组 | | `FaceResetAsync()` | `Task` | 取消当前人脸流程 | | `GetStatusAsync()` | `Task` | 获取模组状态 | | `GetVersionAsync()` | `Task` | 获取固件版本 | | `GetSnAsync()` | `Task` | 获取设备序列号 | | `SetDemoModeAsync(bool enable)` | `Task` | 设置 Demo Mode | | `UpgradeFirmwareAsync()` | `Task` | 启动固件升级命令 | ## 4. 验证服务 FaceVerifyService 访问路径: ```csharp manager.Verify ``` | 方法 | 返回 | 说明 | |---|---|---| | `VerifyAsync(byte timeout, byte maxRecognitionTimes = 30)` | `Task` | 单次人脸验证 | | `AutoVerifyAsync(bool enable, byte timeout)` | `Task` | 底层自动验证开关命令,只表示开关命令 ACK | 推荐业务层使用 `FaceModuleManager.StartAutoVerifyAsync()` 和 `FaceModuleManager.StopAutoVerifyAsync()` 控制自动验证,识别结果通过 `OnAutoVerifyResult` 获取。 ```csharp var control = await manager.StartAutoVerifyAsync(10); if (control.Success) { manager.OnAutoVerifyResult += result => { Debug.Log("自动验证结果: " + result.ResultCode); }; } ``` `StartAutoVerifyAsync()` / `StopAutoVerifyAsync()` 的返回值是 `FaceAutoVerifyControlResult`,表示开启或关闭命令是否成功,不表示识别结果。 ## 5. 录入服务 FaceEnrollmentService 访问路径: ```csharp manager.Enrollment ``` | 方法 | 返回 | 说明 | |---|---|---| | `EnrollAsync(bool admin, string userName, FaceDirection direction, byte timeout)` | `Task` | 交互式多方向录入 | | `EnrollSingleAsync(bool admin, string userName, byte timeout)` | `Task` | 单帧录入 | | `EnrollIntegratedAsync(bool admin, string userName, FaceDirection direction, byte timeout, bool singleFrame = false, bool duplicateCheck = true)` | `Task` | 集成式录入 | | `EnrollSnapFaceImageAsync(bool admin, string userName)` | `Task` | 抓拍人脸后注册 | ## 6. 用户服务 FaceUserService 访问路径: ```csharp manager.Users ``` | 方法 | 返回 | 说明 | |---|---|---| | `DeleteUserAsync(int userId)` | `Task` | 删除指定用户 | | `DeleteAllAsync()` | `Task` | 删除全部用户 | | `GetUserInfoAsync(int userId)` | `Task` | 查询用户信息 | | `GetAllUserIdsAsync()` | `Task>` | 查询用户 ID 列表 | | `GetAllUserIds2Async()` | `Task>` | 使用扩展命令查询用户 ID 列表 | | `GetAllUserInfosAsync()` | `Task>` | 查询全部用户详情 | | `GetAllUserInfos2Async()` | `Task>` | 使用扩展命令查询全部用户详情 | ## 7. 二维码服务 FaceQrCodeService 访问路径: ```csharp manager.QrCode ``` | 方法 | 返回 | 说明 | |---|---|---| | `ScanQrCodeAsync(byte timeout)` | `Task` | 扫描二维码并返回内容 | ## 8. 图片服务 FaceImageService 访问路径: ```csharp manager.Images ``` | 方法 | 返回 | 说明 | |---|---|---| | `SnapUploadImageAsync()` | `Task` | 抓拍普通图片 | | `SnapUploadFaceImageAsync()` | `Task` | 抓拍人脸图片 | | `SnapUploadLargeImageAsync(ImageDpi dpi)` | `Task` | 抓拍大图 | | `EnrollWithPhotoAsync(byte[] photoBytes, BioType type, string userName = null, bool duplicateCheck = true, Action onProgress = null)` | `Task` | 照片注册 | | `EnrollWithPhotoAndIdAsync(int userId, byte[] photoBytes, BioType type, string userName = null, bool duplicateCheck = true, Action onProgress = null)` | `Task` | 指定用户 ID 照片注册 | ## 9. 特征服务 FaceFeatureService 访问路径: ```csharp manager.Features ``` | 方法 | 返回 | 说明 | |---|---|---| | `ReadFeatureAsync(int userId, FeatureType type)` | `Task` | 读取指定用户特征 | | `WriteFeatureAsync(byte[] featureBytes, FeatureType type, string userName = null, Action onProgress = null)` | `Task` | 写入特征并注册 | ## 10. UVC 和高级参数 FaceUvcService 访问路径: ```csharp manager.Uvc ``` | 方法 | 返回 | 说明 | |---|---|---| | `ReadUsbUvcParametersAsync()` | `Task` | 读取 USB / UVC 参数 | | `SetUsbUvcParametersAsync(UsbUvcParameters parameters)` | `Task` | 设置 USB / UVC 参数 | | `SetFaceLocationDisplayAsync(bool visible)` | `Task` | 设置人脸框显示 | | `SetRgbLevelAsync(byte level)` | `Task` | 设置 RGB 阈值 | | `SetDuplicateCheckAsync(bool enableCheck)` | `Task` | 设置查重 | | `ReadDuplicateCheckAsync()` | `Task` | 读取查重状态 | ## 11. 加密服务 FaceEncryptionService 访问路径: ```csharp manager.Encryption ``` | 方法 | 返回 | 说明 | |---|---|---| | `SetReleaseEncryptionKeyAsync(byte[] key16)` | `Task` | 设置 Release 加密密钥 | | `SetDebugEncryptionKeyAsync(byte[] key16)` | `Task` | 设置 Debug 加密密钥 | | `InitEncryptionAsync(byte[] seed4, byte mode)` | `Task` | 初始化加密流程 | | `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` | 验证结果、用户信息、开锁状态 | | `FaceAutoVerifyResult` | 自动验证识别结果 | | `FaceAutoVerifyControlResult` | 自动验证开启/关闭命令结果 | | `FaceEnrollResult` | 录入结果、用户 ID、方向 | | `FaceImageResult` | 图片 bytes、Texture2D、用户 ID | | `UsbUvcParameters` | USB / UVC 参数 | | `FaceCommandException` | 底层命令 REPLY 非成功时抛出的异常 | 高层业务 Result 类型统一使用 `Success` 和 `ResultCode`。`FaceReply` 是底层 REPLY 模型,也统一只暴露 `Success` 和 `ResultCode`。 ### 13.1 常用模型字段 | 类型 | 字段 | 说明 | |---|---|---| | `FaceReply` | `Mid` | 对应的命令 ID | | `FaceReply` | `Success` | `ResultCode == FaceResultCode.Success` | | `FaceReply` | `ResultCode` | 模组返回结果码 | | `FaceReply` | `Data` | REPLY 业务数据,不包含命令 ID 和结果码 | | `FaceNote` | `Nid` | NOTE 类型 | | `FaceNote` | `Data` | NOTE 业务数据,不包含 NOTE ID | | `FaceFaceStateNote` | `State` | 人脸状态码 | | `FaceFaceStateNote` | `Left` / `Top` / `Right` / `Bottom` | 人脸框坐标 | | `FaceFaceStateNote` | `Yaw` / `Pitch` / `Roll` | 人脸姿态角 | | `FaceUserInfo` | `UserId` | 用户 ID | | `FaceUserInfo` | `UserName` | 用户名 | | `FaceUserInfo` | `IsAdmin` | 是否管理员 | | `FaceVerifyResult` | `Success` / `ResultCode` | 验证是否成功及结果码 | | `FaceVerifyResult` | `UserId` / `UserName` / `IsAdmin` | 验证成功时的用户信息 | | `FaceVerifyResult` | `UnlockStatus` | 模组返回的开锁状态 | | `FaceAutoVerifyResult` | `Success` / `ResultCode` | 自动验证 NOTE 的识别结果 | | `FaceAutoVerifyResult` | `VerifyResult` | 成功时解析出的验证结果详情 | | `FaceAutoVerifyControlResult` | `Success` / `ResultCode` | 自动验证开关命令结果 | | `FaceAutoVerifyControlResult` | `Enabled` | 本次命令目标状态 | | `FaceAutoVerifyControlResult` | `Reply` | 底层开关命令 REPLY | | `FaceEnrollResult` | `Success` / `ResultCode` | 录入是否成功及结果码 | | `FaceEnrollResult` | `UserId` | 录入成功后分配或写入的用户 ID | | `FaceEnrollResult` | `Direction` | 录入方向 | | `FaceImageResult` | `Success` / `ResultCode` | 图片命令是否成功及结果码 | | `FaceImageResult` | `UserId` | 照片注册相关用户 ID | | `FaceImageResult` | `Bytes` | 图片原始 bytes | | `FaceImageResult` | `Texture` | Unity `Texture2D` | | `UsbUvcParameters` | `UsbType` | USB 输出类型 | | `UsbUvcParameters` | `BitrateMbps` | 码率,单位 Mbps | | `UsbUvcParameters` | `MjpgQuality` | MJPG 质量 | | `UsbUvcParameters` | `Mirror` | 是否镜像 | | `UsbUvcParameters` | `Rotate180` | 是否旋转 180 度 | ### 13.2 FaceResultCode 结果码 `FaceResultCode` 会出现在 `FaceReply.ResultCode`、高层业务 Result、`OnError`、`FaceCommandException.ResultCode` 中。可使用 `FaceProtocolEncoding.ResultMessage(code)` 获取中文提示。 | 值 | 名称 | 说明 | |---:|---|---| | 0 | `Success` | 成功 | | 1 | `Rejected` | 模组拒绝命令 | | 2 | `Aborted` | 操作已终止 | | 4 | `CameraOpenFailed` | 相机打开失败 | | 5 | `UnknownReason` | 未知错误 | | 6 | `InvalidParam` | 参数无效 | | 7 | `NoMemory` | 内存不足 | | 8 | `UnknownUser` | 未找到用户或没有已录入用户 | | 9 | `MaxUser` | 超过最大用户数量 | | 10 | `FaceEnrolled` | 人脸已录入 | | 12 | `LivenessCheckFailed` | 活体检测失败 | | 13 | `Timeout` | 操作超时 | | 14 | `AuthorizationFailed` | 模组侧授权失败 | | 19 | `ReadFileFailed` | 读文件失败 | | 20 | `WriteFileFailed` | 写文件失败 | | 21 | `NoEncrypt` | 通信未加密 | | 23 | `NoRgbImage` | RGB 图像未就绪 | | 24 | `JpgPhotoTooLarge` | JPG 照片过大 | | 25 | `JpgPhotoTooSmall` | JPG 照片过小 | | 26 | `DetectQr` | 识别过程中检测到二维码 | ### 13.3 FaceStateCode 人脸状态码 `FaceStateCode` 来自 `OnFaceStateUpdated(FaceFaceStateNote)`,主要用于录入、检测和 UI 引导。可使用 `FaceProtocolEncoding.FaceStateMessage(code)` 获取中文提示。 | 值 | 名称 | 说明 | |---:|---|---| | 0 | `Normal` | 人脸正常 | | 1 | `NoFace` | 未检测到人脸 | | 2 | `TooUp` | 人脸太靠上 | | 3 | `TooDown` | 人脸太靠下 | | 4 | `TooLeft` | 人脸太靠左 | | 5 | `TooRight` | 人脸太靠右 | | 6 | `Far` | 距离太远 | | 7 | `Close` | 距离太近 | | 8 | `EyebrowOcclusion` | 眉毛遮挡 | | 9 | `EyeOcclusion` | 眼睛遮挡 | | 10 | `FaceOcclusion` | 脸部遮挡 | | 11 | `DirectionError` | 录入方向错误 | | 12 | `EyeCloseStatusOpenEye` | 闭眼检测中发现睁眼 | | 13 | `EyeCloseStatus` | 当前为闭眼状态 | | 14 | `EyeCloseUnknownStatus` | 无法判定睁闭眼状态 | | 128 | `PalmDetected` | 检测到手掌信息 | ### 13.4 业务常用枚举 | 枚举 | 值 | 说明 | |---|---|---| | `FaceModuleStatus` | `Standby = 0` | 模组待机 | | `FaceModuleStatus` | `Busy = 1` | 模组忙碌 | | `FaceModuleStatus` | `Error = 2` | 模组错误 | | `FaceModuleStatus` | `Invalid = 3` | SDK 未知或无效状态 | | `FaceDirection` | `Undefined = 0x00` | 未定义方向 | | `FaceDirection` | `Middle = 0x01` | 正脸 | | `FaceDirection` | `Right = 0x02` | 向右 | | `FaceDirection` | `Left = 0x04` | 向左 | | `FaceDirection` | `Down = 0x08` | 向下 | | `FaceDirection` | `Up = 0x10` | 向上 | | `BioType` | `NormalPhoto = 0` | 普通照片 | | `BioType` | `EncryptedPhoto = 1` | 加密照片 | | `BioType` | `NormalFeature = 2` | 普通特征 | | `BioType` | `CompressedFeature = 3` | 压缩特征 | | `FeatureType` | `ColorFace = 1` | 彩色人脸特征 | | `FeatureType` | `ColorAndIrFace = 2` | 彩色加红外人脸特征 | | `FeatureType` | `Palm = 3` | 手掌特征 | | `ImageDpi` | `Dpi480x640 = 0` | 480x640 大图 | | `ImageDpi` | `Dpi600x800 = 1` | 600x800 大图 | | `ImageDpi` | `Dpi1200x1600 = 2` | 1200x1600 大图 | ### 13.5 配置枚举 | 枚举 | 值 | 说明 | |---|---|---| | `FaceTransportMode` | `Auto = 0` | 默认通信模式,当前串口实现下等价于串口,Editor 可按 Mock 配置切换 | | `FaceTransportMode` | `SerialPort = 1` | 强制使用串口通信 | | `FaceTransportMode` | `Mock = 3` | 使用 Mock 模组 | | `FaceExclusiveCommandPolicy` | `RejectWhenAutoVerifyEnabled = 0` | 自动验证开启时拒绝独占命令 | | `FaceExclusiveCommandPolicy` | `StopAutoVerify = 1` | 独占命令前自动关闭自动验证 | | `FaceExclusiveCommandPolicy` | `Ignore = 2` | 不处理自动验证状态,由业务自行保证不冲突 | ## 14. 协议和通信底层 业务层通常不需要直接使用底层 API。需要协议调试或自定义通信时可使用: | 类型 | 说明 | |---|---| | `FacePacketBuilder` | 封包 | | `FacePacketParser` | 拆包 | | `FaceProtocolEncoding` | 用户名、ID、结果文本等编码工具 | | `IFaceModuleTransport` | 通信接口 | | `SerialPortTransport` | 串口实现 | | `MockFaceModuleTransport` | Mock 实现 | ## 15. 授权 API 命名空间: ```csharp using Aisu.SIM1.Face.Core; ``` | 类型 | 说明 | |---|---| | `FaceLicenseManager` | 加载、验证授权 token,查询授权状态 | | `FaceLicensePayload` | 授权 payload 数据 | | `FaceLicenseStatus` | 授权状态枚举 | | `FaceLicenseException` | 授权异常 | | `FaceLicenseFeatures` | 功能授权常量 | | `FaceUnityRuntimeBinding` | 读取 `identifier`、`companyName`、`productName`、`version`、`unityVersion` | 常用方法: | 方法 | 说明 | |---|---| | `FaceLicenseManager.LoadAndVerify()` | 读取默认授权文件并验签 | | `FaceLicenseManager.VerifyOrThrow()` | 授权无效时抛出异常 | | `FaceLicenseManager.VerifyFeatureOrThrow(string feature)` | 功能未授权时抛出异常 | | `FaceLicenseManager.IsFeatureEnabled(string feature)` | 查询功能是否授权 | | `FaceLicenseVerifier.VerifyToken(string token)` | 验签并校验授权 payload | | `FaceLicenseVerifier.ValidatePayload(FaceLicensePayload payload)` | 校验 payload 字段、有效期、功能和 Unity 绑定 | | `FaceLicenseVerifier.GetBeijingNow()` | 获取 SDK 授权使用的当前北京时间 | | `FaceLicenseVerifier.FormatBeijingTime(DateTimeOffset value)` | 格式化授权北京时间字符串 | | `FaceLicenseVerifier.GetRemainingDays(FaceLicensePayload payload)` | 计算授权剩余天数 | ### 15.1 FaceLicenseStatus | 值 | 名称 | 说明 | |---:|---|---| | 0 | `Unknown` | 尚未验证或状态未知 | | 1 | `Valid` | 授权有效 | | 2 | `MissingFile` | 授权文件不存在 | | 3 | `InvalidFormat` | 授权格式无效 | | 4 | `InvalidSignature` | 授权签名无效 | | 5 | `ProductMismatch` | 产品 ID 不匹配 | | 6 | `BindingMismatch` | Unity 绑定参数不匹配 | | 7 | `Expired` | 授权已过期 | | 8 | `FeatureDenied` | 功能未授权 | | 9 | `PublicKeyInvalid` | SDK 公钥无效 | | 10 | `ReadFailed` | 授权读取失败 | | 11 | `NotYetValid` | 授权尚未生效 | ### 15.2 FaceLicenseFeatures | 名称 | 说明 | |---|---| | `SerialRuntime` | 串口运行时 | | `Basic` | 基础命令 | | `Verify` | 人脸验证和自动验证 | | `Enroll` | 人脸录入 | | `UserManage` | 用户管理 | | `QrCode` | 二维码 | | `Image` | 图片抓拍、照片注册 | | `Feature` | 特征读写 | | `Uvc` | UVC 和高级参数 | | `Encryption` | 加密通信 | | `Firmware` | 固件升级 | Runtime 不提供 token 签发 API,也不提供公钥覆盖 API。授权签发只应存在于内部 Editor DLL 或独立授权工具中。