How to connect to a low energy bluetooth device

I am writing a program for a Win 8 tablet. I need to connect an external BLE device. The device is already paired with Windows, and I see it in the Device Manager. But I can’t figure out how to connect it.

With SetupDiEnumDeviceInfo and SetupDiGetDeviceProperty . I can get some information about the BLE device, but execute, for example. BluetoothGATTGetServices A handheld device is required. I do not know where to get it. Maybe I can use CreateFile , but it's unclear what to replace it with as the first argument to lpFileName.

Here is the code snippet I'm looking for my device with.

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; 

I moved a little further, but still I can not get data from the device.

  • To get the "Device Interface", you had to use other functions: SetupDiGetClassDevs , SetupDiEnumDeviceInterfaces and SetupDiGetDeviceInterfaceDetail .

  • Next, with CreateFile I get a HANDLE BLE device.

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

  • Then using WinAPI BluetoothGATTGetServices and BluetoothGATTGetCharacteristics I get the corresponding structures.

But when I try to get the property value with BluetoothGATTGetCharacteristicsValue , I get ERROR_ACCESS_DENIED .

And then I do not know what to do. What could be wrong?

+6
source share
3 answers

Andrey, I think the problem is that your device is not connected and BluetoothGATTGetCharacteristicsValue does not start the connection.

Try manually connecting your device using the Windows tools. I have the following thread that helps me: Disconnect the device, Pair device β†’ It should appear as connected (it worked in my case;))

In any case, if this does not help, try running "As Administrator", this helps in some cases.

Good luck !!!

0
source

Note. It would be very interesting to know how to get the device path for a BTLE device to call BluetoothGATTGetServices?

gattServiceGUID is any long form of BLE UUID supported by your device.

 "{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
source

Your problem is c ++. Abomination. Amoeba Abomination!

-1
source

Source: https://habr.com/ru/post/957486/


All Articles