首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >蓝牙LE:将特征设置为字节数组发送错误的值

蓝牙LE:将特征设置为字节数组发送错误的值
EN

Stack Overflow用户
提问于 2019-07-07 16:21:16
回答 1查看 1K关注 0票数 0

我正在使用Bluetoothleapis.h与自定义蓝牙低能设备进行通信。

设备的设置方式如下:

  • 海关关贸总协定服务
  • Characteristic#1读/写(期望3个字节)
  • Characteristic#2读取/通知(返回1字节)

我可以从characteristic#2中得到适当的值,但是当我试图向characteristic#1发送数据时,设备会接收到奇怪的数据。

该特性负责一个真实物体的3个参数(想象一个光的强度,颜色,等等)。(0,0,0)应该响应“关灯”,但是如果我发送(0,0,0),我可以看到设备接收到了其他东西(我不知道确切的是什么,但它没有关闭)。无论我发送什么值,状态似乎都不会改变。

我尝试过在写和写-无响应之间交替,两者产生相同的结果。

有趣的是,GetCharacteristicValue返回8的charValueDataSize,尽管已知特征只接受3个字节。巧合的是,由于某种原因,1字节只读特性的大小为9 .

我尝试将WriteValue的大小限制为3个字节,但在这种情况下,我得到了一个无效的参数错误。StackOverflow上其他地方的答案表明,我需要使用从GetCharacteristicValue获得的答案,并将我的数据传输到那里。

考虑到无论发送哪个值,实际对象的状态都不会改变,我怀疑问题出在我设置字节数组以传输数据的方法上。

此外,即使在设置GetCharacteristicValue之后,调用它也会返回一个空数组。

我不知道实际发送的是什么值,并且我缺乏通过Wireshark跟踪它们的硬件。

代码语言:javascript
复制
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应用程序时,读写功能都很好。

更新1

@Shubham指出,这可能是一个无聊的问题,因此我试图用memcpy代替以下内容:

代码语言:javascript
复制
int j = 0;
int i = charValueDataSize - 1;
while (j < bufferSize)
{
    pWriteValue->Data[i] = writeBuffer[j];
    --i;
    ++j;
}

然而,一切都没有改变。

更新2

我已经按照emil's suggestion合并了这些更改,并且它起了作用!发布完整的代码,以防其他人遇到同样的问题。

顺便说一句,尽管特征标记为Writable: true,Writable- no-response : false,但我需要将标志设置为no-response,这样才能发送值。

代码语言:javascript
复制
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;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-07-08 14:02:06

我的建议是,首先将charValueDataSize设置为512 +BTH_LE_GATT_CHARACTERISTIC_VALUE(最大可能),并跳过获得大小的初始读取。然后检查pWriteValue->DataSize,以获得读取成功后的实际大小。而且,即使在出错的情况下,也要确保释放你的内存。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56923982

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档