Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 06.11.2013, 14:20   #1
AndreySh
 
Регистрация: 02.07.2013
Сообщений: 7
По умолчанию Как подключиться к Bluetooth low energy устройству?

День добрый!

Пишу программy для планшета под Win 8. Мне нужно подключить внешнее BLE-устройство используя встроенный Bluetooth планшета.
Само устройство уже спарено с Windows и его видно в Диспетчере устройств. А вот как к нему подключиться я никак не могу разобраться.

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

Вот кусок программки, с помощью которого я ищу свое BLE-устройство.
Код:
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;
               }
           }
                       /* Тут проверяю по имени мое устройство или нет */
                       ...
                       /* Тут проверяю по имени мое устройство или нет */
            if (buffer) delete(buffer);
       }
 
 
       if ( GetLastError()!=NO_ERROR &&
            GetLastError()!=ERROR_NO_MORE_ITEMS )
       {
           // Insert error handling here.
           return; //1;
       }
 
       //  Cleanup
       SetupDiDestroyDeviceInfoList(hDevInfo);
 
       return;
AndreySh вне форума Ответить с цитированием
Старый 08.11.2013, 12:43   #2
counter
Участник клуба
 
Регистрация: 18.10.2008
Сообщений: 1,409
По умолчанию

С bluetooth'ом не работал, но могу предположить, что сначала нужно выполнить поиск устройства.

Возможно подойдет для этих целей функция BluetoothFindFirstDevice.
Первым параметром передается структура BLUETOOTH_DEVICE_SEARCH_PARAMS, которая задает параметры поиска.


Цитата:
hRadio
A handle for the radio on which to perform the inquiry. Set to NULL to perform the inquiry on all local Bluetooth radios.
Думаю стоит установить в NULL, чтобы пройтись по всем устройствам

Цитата:
fReturnRemembered
A value that specifies that the search should return remembered Bluetooth devices.
fReturnRemembered = true - все-таки искать нужно запомненное устройство.

Стоит обратить внимание и на параметр fIssueInquiry.

Цитата:
If you specify "fIssueInquiry" to do a search, and it finds a remembered device again, that device won't be returned unless you specify "fReturnRemembered".
counter вне форума Ответить с цитированием
Старый 11.11.2013, 13:05   #3
AndreySh
 
Регистрация: 02.07.2013
Сообщений: 7
По умолчанию

Я уже немного дальше продвинулся, но пока все равно не разобрался до конца.

В случае Bluetooth 4 BluetoothFindFirstDevice не подходит.

На сайте MSDN они предлагают воспользоваться функциями SetupDiEnumDeviceInfo и SetupDiGetDeviceProperty.
http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx

Но они обманывают. На самом деле путь к устройству BLE (bluetooth low energy) удается найти используя функции SetupDiEnumDeviceInterfaces и SetupDiGetDeviceInterfaceDetail. С помощью SetupDiGetDeviceInterfaceDetail я получаю Device Interface path, который можно использовать при вызове CreateFile.

Но дальше опять затыки.
Удается считать из устройства какие оно поддерживает сервисы и характеристики внутри сервисов.
Но при попытке считать значения характеристик получаю ACCESS_DENIED
AndreySh вне форума Ответить с цитированием
Старый 11.11.2013, 13:48   #4
counter
Участник клуба
 
Регистрация: 18.10.2008
Сообщений: 1,409
По умолчанию

А как читаете данные?

Возможно нужно установить таймаут на чтение из девайса...
ReadFile
Цитата:
When reading from a communications device, the behavior of ReadFile is determined by the current communication time-out as set and retrieved by using the SetCommTimeouts and GetCommTimeouts functions. Unpredictable results can occur if you fail to set the time-out values. For more information about communication time-outs, see COMMTIMEOUTS.
counter вне форума Ответить с цитированием
Старый 11.11.2013, 16:37   #5
AndreySh
 
Регистрация: 02.07.2013
Сообщений: 7
По умолчанию

Не, у них новый набор API для Bluetooth Low Energy Functions:
BluetoothGATTGetServices
BluetoothGATTGetCharacteristics
BluetoothGATTGetCharacteristicValue
и т.д.
http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx
Вот первые две функции выполняются нормально и возвращают нужные структуры, а последняя BluetoothGATTGetCharacteristicValue шиш.
AndreySh вне форума Ответить с цитированием
Старый 13.11.2013, 20:58   #6
counter
Участник клуба
 
Регистрация: 18.10.2008
Сообщений: 1,409
По умолчанию

Цитата:
ERROR_ACCESS_DENIED
Returned if both a parent service and a service handle are provided and the service hierarchy does not roll up to the provided parent service handle.
возможно первые два параметра не коррелируют между собой...


Цитата:
hDevice [in]
Handle to the service.
Characteristic [in]
Pointer to the parent characteristic of the characteristic value to be retrieved.

В общем нужно смотреть код. Ну или как-то пытаться понять взаимосвязь сервисов и хэндлов для них.
counter вне форума Ответить с цитированием
Старый 14.11.2013, 17:15   #7
AndreySh
 
Регистрация: 02.07.2013
Сообщений: 7
По умолчанию

Документация у микрософта не супер. :/

Для вот этих 3-х функций:

Код:
1. BluetoothGATTGetServices
2. BluetoothGATTGetCharacteristics
3. BluetoothGATTGetCharacteristicValue
первый параметр HANDLE hDevice

в первом случае они про этот параметр пишут развернуто а потом все меньше и меньше.
Код:
1. Handle to the Bluetooth device from which to obtain the list of primary services.
2. Handle to the Bluetooth device or service.
3. Handle to the service.
Но в своем примере из WDK для Windows 8 они подставляют одну и ту же переменную.

Вот тут есть диаграмма, как связанны сервисы и характеристики.
http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx

К сообщению приложил файл. В нем большая часть содрана как раз из WDK. До 165 строки. До туда все работает.

И вот дальше первый же вызов BluetoothGATTGetCharacteristicValue выдает ошибку.

В общем не понятно, что делать.
Вложения
Тип файла: zip test.zip (1.3 Кб, 54 просмотров)

Последний раз редактировалось AndreySh; 14.11.2013 в 17:55.
AndreySh вне форума Ответить с цитированием
Старый 14.11.2013, 17:40   #8
AndreySh
 
Регистрация: 02.07.2013
Сообщений: 7
По умолчанию

Еще я заметил, что в общем-то не важно работает ли само BLE-устройство или нет. Поведение программы не меняется. Т. е. в обоих случаях я могу считать "структуру" сервисов-характеристик устройства, но не могу считать значение этих характеристик. CreateFile в обоих случаях срабатывает без ошибок и возвращает HANDLE устройства.

И еще, на свой IPhone 4S поставил программку LightBlue она умеет работать с bluetooth 4 LE. Так вот с ее помощью я нормально получаю данные с этого устройства. Т. е. проблема именно в программе под винду, а не в железке.
AndreySh вне форума Ответить с цитированием
Старый 15.11.2013, 12:00   #9
AndreySh
 
Регистрация: 02.07.2013
Сообщений: 7
По умолчанию

Ура, проблема решена! На форуме MSDN наконец-то ответили. Может кому-то пригодится.

Цитата:
To provide isolation between services, windows requires that when reading or writing to the device, that the application opens a handle to the service instance itself.
This can be accomplished by altering BTDeviceInterfaceGUID in your example to be equal to the service UUID (extended to 128 bit using the standard SIG extension if the service uses a 16 bit UUID) of the service you intended to use.
Чтобы расширить 16-битный UUID сервиса до 128 берем Bluetooth_Base_UUID {0000xxxx-0000-1000-8000-00805F9B34FB} и вставляем на место xxxx свой 16-битный.
AndreySh вне форума Ответить с цитированием
Старый 15.11.2013, 12:44   #10
counter
Участник клуба
 
Регистрация: 18.10.2008
Сообщений: 1,409
По умолчанию

Перед выполнением BluetoothGATTGetCharacteristicValue нужно проверить значение hr. Ибо после этого могут быть проблемы:
Код:
 if (numServices != numServicesActual)
        {
            // The returned number of services do not match what we have
            // originally.
            hr = E_FAIL;
        }

Тут еще вопрос такой может быть: откуда пытается читать значение BluetoothGATTGetCharacteristicValue . Это касательно флагов BLUETOOTH_GATT_FLAG_FORCE_READ_FROM _DEVICE и
BLUETOOTH_GATT_FLAG_FORCE_READ_FROM _CACHE.

Так же стоит проверить значение PBTH_LE_GATT_CHARACTERISTIC::IsRead able перед чтением значений.

И что-то мне кажется, что параметр hDevice [in] Handle to the service это не то, что ты туда скармливаешь. Попробуй передавать туда PBTH_LE_GATT_CHARACTERISTIC::Servic eHandle.

А вообще как-то мутно все это описано на MSDN

Цитата:
The parent service must be present in the cache, otherwise the function will fail. The parent service must be a service returned by either BluetoothGATTGetServices or BluetoothGATTGetIncludedServices.
UPD:

Цитата:
Чтобы расширить 16-битный UUID сервиса до 128 берем Bluetooth_Base_UUID {0000xxxx-0000-1000-8000-00805F9B34FB} и вставляем на место xxxx свой 16-битный.
вот оно как оказывается)
counter вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
bluetooth клавиатура как отдельное устройство Mozgunov Общие вопросы Delphi 11 31.03.2013 12:09
FTP как подключиться aank10 C++ Builder 1 13.09.2012 15:49
Как можно обратиться к устройству, которое подключено через USB порт Mikhail Bakurov Общие вопросы Delphi 8 17.11.2008 20:42
Как соединить 2 компьютера через Bluetooth kikoz Операционные системы общие вопросы 6 27.10.2008 23:08
как подключиться к БД из dll? fLytarget Помощь студентам 3 18.08.2008 17:42