我正在使用Bluetoothleapis.h与自定义的Bluetooth Low Energy设备进行通信。
通过以下方式设置设备:
我能够从特征2中获得正确的值。但是,当我尝试将数据发送到特征1时,设备会收到奇怪的数据。
该特征负责现实对象的3个参数(想象具有强度,颜色等的光)。 (0,0,0)应该响应“灯”熄灭,但是如果我发送(0,0,0),我可以看到设备收到了其他东西(我不能确切说出什么,但不是)关闭)。无论我发送什么值,状态都不会改变。
我尝试在写响应和无写响应之间切换,两者都产生相同的结果。
有趣的是,GetCharacteristicValue返回的charValueDataSize为8,即使已知该特征仅接受3个字节也是如此。巧合的是,出于某种原因,1字节只读特征的大小为9。
我尝试将WriteValue的大小限制为仅3个字节,但是在这种情况下,我得到了无效的参数错误。关于StackOverflow的其他答案表明,我需要使用从GetCharacteristicValue获得的数据,然后将数据传输到那里。
鉴于实际对象的状态无论发送哪个值都不会改变,我怀疑问题出在我设置字节数组以传输数据的方式上。
此外,即使设置了GetCharacteristicValue,它也会返回一个空数组。
我不确定实际发送的是什么值,并且我缺少通过Wireshark跟踪它们的硬件。
DWORD WriteValueToCharacteristic(__in const HANDLE deviceHandle,
__in const CharacteristicData* pCharData,
__in const UCHAR* writeBuffer,
__in const USHORT bufferSize,
__in const BOOL noResponse )
{
HRESULT hr;
PBTH_LE_GATT_CHARACTERISTIC pCharacteristic = pCharData->pCharacteristic;
USHORT charValueDataSize;
hr = BluetoothGATTGetCharacteristicValue
(
deviceHandle,
pCharacteristic,
0,
NULL,
&charValueDataSize,
BLUETOOTH_GATT_FLAG_NONE
);
if (hr != HRESULT_FROM_WIN32(ERROR_MORE_DATA))
{
Log(L"BluetoothGATTSetCharacteristicValue returned error %d", hr);
FormatBluetoothError(hr);
return -1;
}
PBTH_LE_GATT_CHARACTERISTIC_VALUE pWriteValue = (PBTH_LE_GATT_CHARACTERISTIC_VALUE)HeapAlloc
(
GetProcessHeap(), HEAP_ZERO_MEMORY, charValueDataSize + sizeof(BTH_LE_GATT_CHARACTERISTIC_VALUE)
);
if (pWriteValue == NULL)
{
Log(L"Out of memory.");
return -1;
}
hr = BluetoothGATTGetCharacteristicValue
(
deviceHandle,
pCharacteristic,
charValueDataSize,
pWriteValue,
NULL,
BLUETOOTH_GATT_FLAG_FORCE_READ_FROM_DEVICE
);
memcpy(pWriteValue->Data, writeBuffer, bufferSize);
ULONG flags = noResponse == TRUE ? BLUETOOTH_GATT_FLAG_WRITE_WITHOUT_RESPONSE : 0;
hr = BluetoothGATTSetCharacteristicValue
(
deviceHandle,
pCharacteristic,
pWriteValue,
NULL,
flags
);
if (hr != S_OK)
{
Log(L"BluetoothGATTSetCharacteristicValue returned error %d", hr);
FormatBluetoothError(hr);
return -1;
}
HeapFree(GetProcessHeap(), 0, pWriteValue);
return ERROR_SUCCESS;
}
SetCharacteristicValue返回S_OK,不产生任何错误。
在Android上使用BLE应用程序时,对特征的读写都可以正常工作。
@Shubham指出这可能是字节顺序问题,因此我尝试将memcpy替换为以下内容:
int j = 0;
int i = charValueDataSize - 1;
while (j < bufferSize)
{
pWriteValue->Data[i] = writeBuffer[j];
--i;
++j;
}
但是,什么都没有改变。
我已经按照emil's suggestion合并了更改,并且有效!发布完整的代码,以防其他人遇到相同的问题。
偶然地,即使特征被标记为可写:true,可写无响应:false,我也需要将标志设置为无响应才能发送值。
DWORD WriteValueToCharacteristic(__in const HANDLE deviceHandle, __in const CharacteristicData* pCharData, __in const UCHAR* writeBuffer, __in const USHORT bufferSize, __in const BOOL noResponse)
{
HRESULT hr;
PBTH_LE_GATT_CHARACTERISTIC pCharacteristic = pCharData->pCharacteristic;
USHORT charValueDataSize = 512;
PBTH_LE_GATT_CHARACTERISTIC_VALUE pWriteValue = (PBTH_LE_GATT_CHARACTERISTIC_VALUE)HeapAlloc
(
GetProcessHeap(), HEAP_ZERO_MEMORY, charValueDataSize + sizeof(BTH_LE_GATT_CHARACTERISTIC_VALUE)
);
if (pWriteValue == NULL)
{
Log(L"Out of memory.");
return -1;
}
hr = BluetoothGATTGetCharacteristicValue
(
deviceHandle,
pCharacteristic,
(ULONG)charValueDataSize,
pWriteValue,
NULL,
BLUETOOTH_GATT_FLAG_FORCE_READ_FROM_DEVICE
);
if (bufferSize > pWriteValue->DataSize)
{
if(pWriteValue->DataSize == 0)
{
pWriteValue->DataSize = bufferSize;
}
}
// after the first write, DataSize stays as 3
//pWriteValue->DataSize here is 3, as expected
//buffer size is also 3
memcpy(pWriteValue->Data, writeBuffer, bufferSize);
ULONG flags = noResponse == TRUE ? BLUETOOTH_GATT_FLAG_WRITE_WITHOUT_RESPONSE : 0;
hr = BluetoothGATTSetCharacteristicValue
(
deviceHandle,
pCharacteristic,
pWriteValue,
NULL,
flags
);
if (hr != S_OK)
{
Log(L"BluetoothGATTSetCharacteristicValue returned error %d", hr);
FormatBluetoothError(hr);
HeapFree(GetProcessHeap(), 0, pWriteValue);
return -1;
}
HeapFree(GetProcessHeap(), 0, pWriteValue);
return ERROR_SUCCESS;
}
答案 0 :(得分:0)
我的建议是,首先将charValueDataSize设置为512 + sizeof(BTH_LE_GATT_CHARACTERISTIC_VALUE)(最大可能),然后跳过将获得该大小的初始读取。然后,在成功读取后检查pWriteValue-> DataSize以获得实际大小。另外,即使出现错误,也请确保释放内存。