问题描述
在我的设备配置 gatt.xml 中,我添加了一个带有自定义 UUID 的自定义 GATT 特性并启用了读写属性。配对后使用 Windows 蓝牙 API,当我尝试从 GATT 特征读取时,它工作正常,但写入 GATT 特征不起作用。我一直被拒绝访问,但出现异常。下面我添加了示例 gatt.xml、bgs 和 C# 代码。我正在使用 bluegiga v1.3.1_API。当前设置适用于 USB 加密狗,但我正在尝试将其替换为 Windows 蓝牙 API。
gatt.xml
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<service uuid="180A">
<description>Device information</description>
<characteristic uuid="2a29">
<properties read="true" const="true" />
<value>company name</value>
<description>Manufacturer Name String</description>
</characteristic>
<characteristic uuid="2a24">
<properties read="true" const="true" />
<value>device name</value>
<description>Model Number String</description>
</characteristic>
<characteristic uuid="2a27">
<properties read="true" const="true"/>
<value>2.0</value>
<description>Hardware Revision String</description>
</characteristic>
<characteristic uuid="95551f84-7562-4c30-9455-be0750914ac2" id="xgatt_Params">
<properties read="true" write="true"/>
<value type="user" length="5"/>
<description>Params</description>
</characteristic>
</service>
</configuration>
来自 bgs 脚本的attributes_value 事件
event attributes_value(connection,reason,handle,offset,value_len,value_data)
if handle = xgatt_Params then
if value_len = 2 then
if value_data(0:2) = $0115 then
memcpy(addrPaired(0),addrConnected(0),6)
updatePairing=1
call attributes_user_write_response(connection,0)
else
call attributes_user_write_response(connection,$80)
end if
else
if value_len >= numParams then
memcpy(params(0),value_data(0),numParams)
call updateParams()
call attributes_user_write_response(connection,$80)
end if
end if
end if
end
C# 代码
if (properties.HasFlag(GattCharacteristicProperties.Write))
{
try
{
var writer = new DataWriter();
writer.WriteByte(01);
writer.WriteByte(15);
var result = await characteristic.WriteValueAsync(writer.DetachBuffer(),GattWriteOption.WriteWithResponse);
if (result == GattCommunicationStatus.Success)
{
Console.Write("\n Success");
}
else if (result == GattCommunicationStatus.AccessDenied)
{
Console.Write("\n Access Denied");
}
else if (result == GattCommunicationStatus.Unreachable)
{
Console.Write("\n Unreachable");
}
else if (result == GattCommunicationStatus.ProtocolError)
{
Console.Write("\n ProtocolError");
}
}
catch (Exception ex) when ((uint)ex.HResult == 0x80650003 || (uint)ex.HResult ==
0x80070005)
{
Console.Write("\n " + ex.Message);
}
}
解决方法
Windows 不允许写入 GAP 服务。所以我所做的是使用如下所示的自定义 UUID 制作具有特征的服务,现在它可以工作了。
<service uuid="97b6682c-ca92-11eb-b8bc-0242ac130003">
<description>meso service</description>
<!-- custom write-only characteristic -->
<characteristic uuid="97b66a7a-ca92-11eb-b8bc-0242ac130003" id="xgatt_params_windows">
<description>Data</description>
<properties write="true" />
<value type="user" length="5"/>
</characteristic>
</service>
要记住的另一件事是您需要以相反的顺序从 Windows 写入十六进制值。例如,在我的 BGScript 中,它的期望值为 0115,因此您应该从窗口中反向写入该值。这完全取决于您使用的系统,例如 BigEndian(MSB 优先,例如:Motorola 处理器), 或 LittleEndian(LSB 优先,例如:Intel 处理器)。
var writer = new DataWriter();
writer.WriteByte(15);
writer.WriteByte(01);