本文档以 Unity PC 工程 smart-bow-pc 为主,说明应用侧何时发起 0x5A 授权轮询、如何写特征、如何解析 Notify。
7 字节组包、累加和与加解密算法在 BluetoothDecryptor 中实现(源码位于同仓库 smart-bow-sdk-dll,PC 端通过程序集或同步脚本引用同一逻辑)。
有。 在 PC 端当 CommonConfig.EnableDecryption 与 NeedDecryption 同时为真时,连接成功后会启动 PollingCoroutine,约每秒调用 SendEncrypt → WriteByteData,向外设下发 0x5A~0x5D 的 7 字节授权请求;收到首字节为 0x5a 的 Notify 后走 AUTHOR_Decrypt,成功后 StopEncrypt() 并 InitWhenConenct() 进入业务数据。
InitWhenConenct(),不发送授权帧。0x5A + 4 字节密文 + 校验 + 0x5D)。0x5A + 4 字节明文 + 校验 + 0x5D),算法与规范附件 1、2 一致。PC 校验通过后停止轮询,进入后续业务;失败时按 BluetoothAim 内逻辑可能重连。
sequenceDiagram
participant PC as PC 用户端 Unity
participant D as 蓝牙外设
PC->>D: BLE 连接成功
alt EnableDecryption && NeedDecryption
loop 约每秒,直至授权成功
PC->>D: Write 7 字节授权请求
end
D->>PC: Notify 7 字节应答
PC->>PC: StopEncrypt,InitWhenConenct
else 未开启授权
PC->>PC: 直接 InitWhenConenct
end
| 职责 | PC 工程内路径 |
|---|---|
| 连接成功是否进入授权 | Assets/BowArrow/Scripts/Bluetooth/BluetoothAim.cs:OnConnected(约 399~404 行)、OnConnected_windows1(约 1595~1600 行)、OnCMDBLEReady(约 1970~1974 行) |
| 每秒轮询与下发 | 同上:PollingCoroutine、SendEncrypt、StopEncrypt |
| 收到 Notify 后校验授权 | 同上:OnCharacteristicChanged(约 1625~1659 行),首字节 0x5a 时调用 BluetoothDecryptor.AUTHOR_Decrypt |
| Win 单路 BLE 回调绑定 | 同上:firstBluetoothWindows.OnConnected = OnConnected_windows1 等(搜索 OnConnected_windows1) |
| SmartBow CMD 通道 Notify | 同上:OnCMDBLENotify → OnCharacteristicChanged |
入口:连接成功后启动轮询(通用 BluetoothHelper)
if (CommonConfig.EnableDecryption && NeedDecryption)
{
// 这里验证指令,开始请求授权
// 启动轮询协程
StartCoroutine(PollingCoroutine());
}
入口:Windows 单路 BLE 连接成功
if (CommonConfig.EnableDecryption && NeedDecryption)
{
// 这里验证指令,开始请求授权
// 启动轮询协程
StartCoroutine(PollingCoroutine());
}
入口:SmartBow CMD BLE 特征就绪
if (CommonConfig.EnableDecryption && NeedDecryption)
{
// 这里验证指令,开始请求授权
// 启动轮询协程
StartCoroutine(PollingCoroutine());
}
轮询与写入写特征
private IEnumerator PollingCoroutine()
{
// 发送请求
// SendEncrypt();
// 设置轮询标志
isPolling = true;
PollingCoroutineCount = 4;
uint systemTick = (uint)DateTime.Now.Ticks;
while (isPolling)
{
// 等待一秒
yield return new WaitForSeconds(1f);
SendEncrypt(systemTick);
PollingCoroutineCount--;
}
}
/// <summary>
/// 1、加密字节由系统生成的随机码加密而成;
/// 2、蓝牙每次断开并重新连接后,会重新生成随机加密值;
/// 3、当设备未发送正确的解密信息时,APP会每秒发送1次请求,直到解密成功。
/// </summary>
/// <param name="systemTick"></param>
private void SendEncrypt(uint systemTick)
{
byte[] sendByte = BluetoothDecryptor.AUTHOR_SendReq(systemTick);
Debug.Log("请求sendByte:" + BitConverter.ToString(sendByte));
WriteByteData(sendByte);
}
Notify:授权未通过时只处理 0x5a 帧
if (CommonConfig.EnableDecryption && NeedDecryption)
{
//Pc 版本先走校验流程
if (!BluetoothDecryptor.AUTHOR_IsDecrypt())
{
if (value[0] == 0x5a)
{
// 从硬件读取数据
if (value != null && value.Length > 0)
{
Debug.Log("接收到数据:" + BitConverter.ToString(value));
BluetoothDecryptor.AUTHOR_Decrypt(value);
if (BluetoothDecryptor.AUTHOR_IsDecrypt())
{
Debug.Log("解密成功!");
//解密成功后
StopEncrypt();
//开始连接其他信息
InitWhenConenct();
}
else
{
Debug.Log("解密失败!");
//SideTipView.ShowTip("设备通信失败,断开连接", Color.yellow);
//断开连接等操作
if (PollingCoroutineCount <= 0)
{
StopEncrypt();
DoConnect();
}
}
}
}
return;
}
}
PC 端仅调用 BluetoothDecryptor.AUTHOR_SendReq / AUTHOR_Decrypt / AUTHOR_IsDecrypt,具体算法与 7 字节布局见:
smart-bow-sdk-dll/SmartBowSDK/BluetoothDecryptor.cs(AUTHOR_SendReq、AUTHOR_Decrypt、CheckSum、AUTHOR_ImprovedEncrypt、AUTHOR_ImprovedDecrypt)。
详细帧格式与附件 1、2 以《蓝牙 BLE 外设设计与通信规范》为准;本文档路径:smart-bow-pc/docs/0x5A与BLE规范对照说明.md。