Как подключиться к устройству Bluetooth с низким энергопотреблением

Пишу программу для планшета Win 8. Мне нужно подключить внешнее устройство BLE.
Устройство уже связано с Windows, и я вижу это в диспетчере устройств. Но я не могу понять, как это подключить.

С SetupDiEnumDeviceInfo а также SetupDiGetDeviceProperty Я могу получить некоторую информацию о BLE-устройстве, но выполнить, например, BluetoothGATTGetServices
Ручка устройства обязательна. Я не знаю, где его взять. Возможно, я могу использовать CreateFile, но не понятно, что подставить в качестве первого аргумента lpFileName.

Вот фрагмент кода, с помощью которого я ищу свое устройство.

HDEVINFO hDevInfo;
SP_DEVINFO_DATA DeviceInfoData;
DWORD i;

// Create a HDEVINFO with all present devices.
hDevInfo = SetupDiGetClassDevs(
&BluetoothClassGUID,                     /* GUID_DEVCLASS_BLUETOOTH */
0, 0, DIGCF_PRESENT);

if (hDevInfo == INVALID_HANDLE_VALUE)
{
// Insert error handling here.
return ;//1;
}

// Enumerate through all devices in Set.

DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
for (i=0;SetupDiEnumDeviceInfo(hDevInfo,i,
&DeviceInfoData);i++)
{
DWORD DataT;
LPTSTR buffer = NULL;
DWORD buffersize = 0;

while (!SetupDiGetDeviceRegistryProperty(
hDevInfo,
&DeviceInfoData,
SPDRP_FRIENDLYNAME,
&DataT,
(PBYTE)buffer,
buffersize,
&buffersize))
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER){
// Change the buffer size.
if (buffer) delete(buffer);
// Double the size to avoid problems on
// W2k MBCS systems per KB 888609.
buffer = new wchar_t[buffersize * 2];
}else{
// Insert error handling here.
break;
}
}
/* Here i just compare by name is this my device or not */
...
/* Here i just compare by name is this my device or not */
if (buffer) delete(buffer);
}if ( GetLastError()!=NO_ERROR &&
GetLastError()!=ERROR_NO_MORE_ITEMS )
{
// Insert error handling here.
return; //1;
}

//  Cleanup
SetupDiDestroyDeviceInfoList(hDevInfo);

return;// 0;

Я продвинулся немного дальше, но все еще не могу получить данные с устройства.

  1. Для получения «Device Interface Path» пришлось использовать другие функции:
    SetupDiGetClassDevs, SetupDiEnumDeviceInterfaces а также SetupDiGetDeviceInterfaceDetail.

  2. Далее с CreateFile Я получаю РУЧКУ BLE-устройство.

    hComm = CreateFile (pInterfaceDetailData-> DevicePath, GENERIC_WRITE | GENERIC_READ, NULL, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

  3. Далее с помощью WinAPI BluetoothGATTGetServices а также BluetoothGATTGetCharacteristics Я получаю соответствующие структуры.

Но при попытке получить значение свойства с BluetoothGATTGetCharacteristicsValue, я получил ERROR_ACCESS_DENIED.

И тогда я не знаю что делать. Что может быть не так?

6

Решение

Андрей, я думаю, проблема в том, что ваше устройство не подключено и BluetoothGATTGetCharacteristicsValue не инициирует соединение.

Попробуйте вручную подключить ваше устройство с помощью инструментов Windows. У меня есть следующий поток, который помогает мне: Unpair устройство, Pair device -> Он должен отображаться как подключенный (это работало в моем случае;))

В любом случае, если это не помогает, попробуйте запустить «Как администратор», это помогает в некоторых случаях.

Удачи!!!

0

Другие решения

Примечание. Было бы очень интересно узнать, как получить путь к устройству BTLE для вызова BluetoothGATTGetServices?

gattServiceGUID — это любая длинная форма BLE UUID, поддерживаемая вашим устройством.

"{00001803-0000-1000-8000-00805F9B34FB"} can be used to open a handle to the Link Loss service if supported by the device you are trying to open

HDEVINFO hDevInfo = SetupDiGetClassDevs(&gattServiceGUID, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);

if (hDevInfo != INVALID_HANDLE_VALUE)
{
SP_DEVICE_INTERFACE_DATA interfaceData;
ZeroMemory(&interfaceData,sizeof(SP_DEVICE_INTERFACE_DATA));
interfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

for (DWORD dwDeviceIndex = 0; SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &gattServiceGUID, dwDeviceIndex, &interfaceData); dwDeviceIndex++)
{
dwDeviceCount++;
SetupDiGetDeviceInterfaceDetail(hDevInfo, &interfaceData, NULL, 0, &dwBytesNeeded, NULL);
if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
pInterfaceDetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA) new byte[dwBytesNeeded];

SP_DEVINFO_DATA spDeviceInfoData = { sizeof(SP_DEVINFO_DATA) };

ZeroMemory(pInterfaceDetail, sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA));
pInterfaceDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);

//  grab the interface detail
if (SetupDiGetDeviceInterfaceDetail(hDevInfo, &interfaceData, pInterfaceDetail, dwBytesNeeded, NULL, &spDeviceInfoData) == TRUE)
{
//  request a handle to the GATT service path
m_hGattServiceHandle = CreateFile(pInterfaceDetail->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if (m_hGattServiceHandle != INVALID_HANDLE_VALUE)
{
now you can drill down the characteristics and descriptors with the m_hGattServiceHandle
}
}
}
}
}
0