Connecting to a BLE device

Connecting to a BLE device

Postby Jeff Barnes » Tue Feb 13, 2024 10:00 pm

Hi All,

I posted this question a few years ago but never got a workable solution so I'm trying again.

Has anyone ever connected to a Bluetooth Low Energy device?

If so, can you please send me some examples?

I used to connect to Bluetooth using a serial connection but with BLE it's way different.

Any help would be greatly appreciated.
Thanks,
Jeff Barnes

(FWH 16.11, xHarbour 1.2.3, Bcc730)
User avatar
Jeff Barnes
 
Posts: 929
Joined: Sun Oct 09, 2005 1:05 pm
Location: Ontario, Canada

Re: Connecting to a BLE device

Postby Antonio Linares » Tue Feb 13, 2024 11:55 pm

Dear Jeff,

This may help you:
Code: Select all  Expand view
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
#include <windows.h>
#include <bluetoothleapis.h>

// Link with 'BluetoothApis.lib'

int main() {
    BLUETOOTH_DEVICE_INFO deviceInfo;
    HANDLE hRadio = NULL;
    BLUETOOTH_FIND_RADIO_PARAMS btfrp = { sizeof(BLUETOOTH_FIND_RADIO_PARAMS) };
    HBLUETOOTH_RADIO_FIND hFind = BluetoothFindFirstRadio(&btfrp, &hRadio);
    if (hFind == NULL) {
        printf("BluetoothFindFirstRadio failed\n");
        return 1;
    }
   
    BLUETOOTH_RADIO_INFO radioInfo = { sizeof(BLUETOOTH_RADIO_INFO) };
    if (BluetoothGetRadioInfo(hRadio, &radioInfo) != ERROR_SUCCESS) {
        printf("BluetoothGetRadioInfo failed\n");
        CloseHandle(hRadio);
        return 1;
    }
   
    // Initialize the search parameters
    BLUETOOTH_DEVICE_SEARCH_PARAMS searchParams;
    ZeroMemory(&searchParams, sizeof(BLUETOOTH_DEVICE_SEARCH_PARAMS));
    searchParams.dwSize = sizeof(BLUETOOTH_DEVICE_SEARCH_PARAMS);
    searchParams.fReturnAuthenticated = TRUE;
    searchParams.fReturnRemembered = TRUE;
    searchParams.fReturnConnected = TRUE;
    searchParams.fReturnUnknown = TRUE;
    searchParams.fIssueInquiry = TRUE;
    searchParams.cTimeoutMultiplier = 4; // 4 * 1.28s (default HCI inquiry time)

    // Start the device discovery
    HBLUETOOTH_DEVICE_FIND hFindDevice = BluetoothFindFirstDevice(&searchParams, &deviceInfo);
    if (hFindDevice == NULL) {
        printf("BluetoothFindFirstDevice failed\n");
        CloseHandle(hRadio);
        return 1;
    }

    do {
        // Check if the device is a BLE device
        if (deviceInfo.ulClassofDevice & COD_MAJOR_DEVICE_CLASS_MASK == COD_MAJOR_DEVICE_CLASS_PERIPHERAL) {
            // Print information about the discovered BLE device
            wprintf(L"Device name: %s\n", deviceInfo.szName);
            wprintf(L"Device address: %02X:%02X:%02X:%02X:%02X:%02X\n",
                    deviceInfo.Address.rgBytes[5],
                    deviceInfo.Address.rgBytes[4],
                    deviceInfo.Address.rgBytes[3],
                    deviceInfo.Address.rgBytes[2],
                    deviceInfo.Address.rgBytes[1],
                    deviceInfo.Address.rgBytes[0]);
            wprintf(L"Device class: 0x%08x\n", deviceInfo.ulClassofDevice);
            wprintf(L"-----------------------------------------\n");

            // Connect to the BLE device
            HANDLE hDevice = BluetoothOpenDevice(&deviceInfo.Address, NULL);
            if (hDevice == NULL) {
                printf("BluetoothOpenDevice failed\n");
                continue;
            }

            // Send data to the BLE device
            UCHAR sendData[] = { 0x01, 0x02, 0x03 };
            DWORD bytesSent;
            if (!BluetoothWriteFile(hDevice, sendData, sizeof(sendData), &bytesSent, NULL)) {
                printf("BluetoothWriteFile failed\n");
                CloseHandle(hDevice);
                continue;
            }

            // Receive data from the BLE device
            UCHAR recvData[256];
            DWORD bytesRead;
            if (!BluetoothReadFile(hDevice, recvData, sizeof(recvData), &bytesRead, NULL)) {
                printf("BluetoothReadFile failed\n");
                CloseHandle(hDevice);
                continue;
            }

            // Print received data
            printf("Received data from the device: ");
            for (DWORD i = 0; i < bytesRead; i++) {
                printf("%02X ", recvData[i]);
            }
            printf("\n");

            // Close the device handle
            CloseHandle(hDevice);
        }

        // Continue searching for more devices
    } while (BluetoothFindNextDevice(hFindDevice, &deviceInfo));

    // Close the device find handle
    BluetoothFindDeviceClose(hFindDevice);

    // Close the radio handle
    CloseHandle(hRadio);

    return 0;
}
 
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 41314
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Connecting to a BLE device

Postby Jeff Barnes » Wed Feb 14, 2024 2:33 am

Do I need a certain version of FiveWin for this ?
Thanks,
Jeff Barnes

(FWH 16.11, xHarbour 1.2.3, Bcc730)
User avatar
Jeff Barnes
 
Posts: 929
Joined: Sun Oct 09, 2005 1:05 pm
Location: Ontario, Canada

Re: Connecting to a BLE device

Postby Antonio Linares » Wed Feb 14, 2024 8:50 am

Dear Jeff,

Please build and run this test and let me know what you get:
Code: Select all  Expand view
#include "FiveWin.ch"

function Main()

   Test()

return nil

#pragma BEGINDUMP

#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
#include <windows.h>
#include <BluetoothAPIs.h>
#include <hbapi.h>

// Link with 'BluetoothApis.lib'

#define COD_MAJOR_DEVICE_CLASS_MASK       0x1F00
#define COD_MAJOR_DEVICE_CLASS_PERIPHERAL   0x08

HB_FUNC( TEST )
{
    BLUETOOTH_DEVICE_INFO deviceInfo;
    HANDLE hRadio = NULL;
    BLUETOOTH_FIND_RADIO_PARAMS btfrp = { sizeof(BLUETOOTH_FIND_RADIO_PARAMS) };
    HBLUETOOTH_RADIO_FIND hFind = BluetoothFindFirstRadio(&btfrp, &hRadio);
    if (hFind == NULL) {
        MessageBox( 0, "BluetoothFindFirstRadio failed", "error", 0 );
        return;
    }
   
    BLUETOOTH_RADIO_INFO radioInfo = { sizeof(BLUETOOTH_RADIO_INFO) };
    if (BluetoothGetRadioInfo(hRadio, &radioInfo) != ERROR_SUCCESS) {
        MessageBox(0, "BluetoothGetRadioInfo failed", "error", 0 );
        CloseHandle(hRadio);
        return;
    }
   
    // Initialize the search parameters
    BLUETOOTH_DEVICE_SEARCH_PARAMS searchParams;
    ZeroMemory(&searchParams, sizeof(BLUETOOTH_DEVICE_SEARCH_PARAMS));
    searchParams.dwSize = sizeof(BLUETOOTH_DEVICE_SEARCH_PARAMS);
    searchParams.fReturnAuthenticated = TRUE;
    searchParams.fReturnRemembered = TRUE;
    searchParams.fReturnConnected = TRUE;
    searchParams.fReturnUnknown = TRUE;
    searchParams.fIssueInquiry = TRUE;
    searchParams.cTimeoutMultiplier = 4; // 4 * 1.28s (default HCI inquiry time)

    // Start the device discovery
    HBLUETOOTH_DEVICE_FIND hFindDevice = BluetoothFindFirstDevice(&searchParams, &deviceInfo);
    if (hFindDevice == NULL) {
        MessageBox( 0, "BluetoothFindFirstDevice failed", "error", 0 );
        CloseHandle(hRadio);
        return;
    }

    do {
        // Check if the device is a BLE device
        if ( ( deviceInfo.ulClassofDevice & COD_MAJOR_DEVICE_CLASS_MASK ) == COD_MAJOR_DEVICE_CLASS_PERIPHERAL) {
            // Print information about the discovered BLE device
            wprintf(L"Device name: %s\n", deviceInfo.szName);
            wprintf(L"Device address: %02X:%02X:%02X:%02X:%02X:%02X\n",
                    deviceInfo.Address.rgBytes[5],
                    deviceInfo.Address.rgBytes[4],
                    deviceInfo.Address.rgBytes[3],
                    deviceInfo.Address.rgBytes[2],
                    deviceInfo.Address.rgBytes[1],
                    deviceInfo.Address.rgBytes[0]);
            wprintf(L"Device class: 0x%08x\n", deviceInfo.ulClassofDevice);
            wprintf(L"-----------------------------------------\n");

            /*
            // Connect to the BLE device
            HANDLE hDevice = ( HANDLE ) BluetoothOpenDevice(&deviceInfo.Address, NULL);
            if (hDevice == NULL) {
                printf("BluetoothOpenDevice failed\n");
                continue;
            }

            // Send data to the BLE device
            UCHAR sendData[] = { 0x01, 0x02, 0x03 };
            DWORD bytesSent;
            if (!BluetoothWriteFile(hDevice, sendData, sizeof(sendData), &bytesSent, NULL)) {
                printf("BluetoothWriteFile failed\n");
                CloseHandle(hDevice);
                continue;
            }

            // Receive data from the BLE device
            UCHAR recvData[256];
            DWORD bytesRead;
            if (!BluetoothReadFile(hDevice, recvData, sizeof(recvData), &bytesRead, NULL)) {
                printf("BluetoothReadFile failed\n");
                CloseHandle(hDevice);
                continue;
            }

            // Print received data
            printf("Received data from the device: ");
            for (DWORD i = 0; i < bytesRead; i++) {
                printf("%02X ", recvData[i]);
            }
            printf("\n");

            // Close the device handle
            CloseHandle(hDevice);
            */

        }

        // Continue searching for more devices
    } while (BluetoothFindNextDevice(hFindDevice, &deviceInfo));

    // Close the device find handle
    BluetoothFindDeviceClose(hFindDevice);

    // Close the radio handle
    // CloseHandle(hRadio);

    // return 0;
}

#pragma ENDDUMP
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 41314
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Connecting to a BLE device

Postby Jeff Barnes » Tue Feb 27, 2024 9:11 pm

Sorry Antonio,
Threw out my back and have been unable to test until now.

It would not compile. See below:



┌────────────────────────────────────────────────────────────────────────────┐
│ FiveWin for xHarbour 16.10 - Oct. 2016 xHarbour development power │▄
│ (c) FiveTech 1993-2016 for Microsoft Windows 9X/NT/200X/ME/XP/Vista/7/8/10 │█
└────────────────────────────────────────────────────────────────────────────┘█
  ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
Compiling...
xHarbour 1.2.3 Intl. (SimpLex) (Build 20150603)
Copyright 1999-2015, http://www.xharbour.org http://www.harbour-project.org/
Compiling 'testble.prg' and generating preprocessed output to 'testble.ppo'...
Generating C source output to 'testble.c'...
Done.
Lines 9, Functions/Procedures 1, pCodes 13
Embarcadero C++ 7.30 for Win32 Copyright (c) 1993-2017 Embarcadero Technologies, Inc.
testble.c:
Error E2187 c:\bcc730\include\windows\sdk\prsht.h 919: Unexpected end of file in conditional started on line 20
Error E2139 c:\bcc730\include\windows\sdk\commdlg.h 933: Declaration missing ;
Error E2139 c:\bcc730\include\windows\sdk\commdlg.h 934: Declaration missing ;
Error E2139 c:\bcc730\include\windows\sdk\commdlg.h 935: Declaration missing ;
Error E2139 c:\bcc730\include\windows\sdk\commdlg.h 938: Declaration missing ;
Error E2139 c:\bcc730\include\windows\sdk\commdlg.h 939: Declaration missing ;
Error E2139 c:\bcc730\include\windows\sdk\commdlg.h 940: Declaration missing ;
Error E2139 c:\bcc730\include\windows\sdk\commdlg.h 965: Declaration missing ;
Error E2139 c:\bcc730\include\windows\sdk\commdlg.h 966: Declaration missing ;
Error E2139 c:\bcc730\include\windows\sdk\commdlg.h 967: Declaration missing ;
Error E2139 c:\bcc730\include\windows\sdk\commdlg.h 970: Declaration missing ;
Error E2139 c:\bcc730\include\windows\sdk\commdlg.h 971: Declaration missing ;
Error E2139 c:\bcc730\include\windows\sdk\commdlg.h 972: Declaration missing ;
Error E2140 testble.prg 34: Declaration is not allowed here in function HB_FUN_TEST
Error E2140 testble.prg 42: Declaration is not allowed here in function HB_FUN_TEST
Error E2140 testble.prg 53: Declaration is not allowed here in function HB_FUN_TEST
*** 16 errors in Compile ***
c:\temp\BluetoothApis.lib
* Linking errors *
Thanks,
Jeff Barnes

(FWH 16.11, xHarbour 1.2.3, Bcc730)
User avatar
Jeff Barnes
 
Posts: 929
Joined: Sun Oct 09, 2005 1:05 pm
Location: Ontario, Canada

Re: Connecting to a BLE device

Postby Antonio Linares » Wed Feb 28, 2024 6:48 am

Dear Jeff,

Wishing you are feeling better now.

This version properly builds using updated xHarbour bins and BCC 7.70 (you need an updated FWH version):
┌────────────────────────────────────────────────────────────────────────────┐
│ FiveWin for xHarbour 23.10 - Oct. 2023 Harbour development power │▄
│ (c) FiveTech 1993-2023 for Microsoft Windows 9X/NT/200X/ME/XP/Vista/7/8/10 │█
└────────────────────────────────────────────────────────────────────────────┘█
  ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
Compiling...
xHarbour 1.3.1 Intl. (SimpLex) (Build 20240108)
Copyright 1999-2023, http://www.xharbour.org http://www.harbour-project.org/
Compiling 'jeff.prg' and generating preprocessed output to 'jeff.ppo'...
Generating C source output to 'jeff.c'...
Done.
Lines 9, Functions/Procedures 1, pCodes 15
Embarcadero C++ 7.70 for Win32 Copyright (c) 1993-2023 Embarcadero Technologies, Inc.
jeff.c:
Turbo Incremental Link 6.97 Copyright (c) 1997-2022 Embarcadero Technologies, Inc.
* Application successfully built *

jeff.prg
Code: Select all  Expand view
#include "FiveWin.ch"

function Main()

   Test()

return nil

#pragma BEGINDUMP

#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
#include <windows.h>
#include <BluetoothAPIs.h>
#include <hbapi.h>

// Link with 'BluetoothApis.lib'

#define COD_MAJOR_DEVICE_CLASS_MASK       0x1F00
#define COD_MAJOR_DEVICE_CLASS_PERIPHERAL   0x08

HB_FUNC( TEST )
{
    BLUETOOTH_DEVICE_INFO deviceInfo;
    HANDLE hRadio = NULL;
    BLUETOOTH_FIND_RADIO_PARAMS btfrp = { sizeof(BLUETOOTH_FIND_RADIO_PARAMS) };
    HBLUETOOTH_RADIO_FIND hFind = BluetoothFindFirstRadio(&btfrp, &hRadio);
    BLUETOOTH_RADIO_INFO radioInfo = { sizeof(BLUETOOTH_RADIO_INFO) };
    BLUETOOTH_DEVICE_SEARCH_PARAMS searchParams;
    HBLUETOOTH_DEVICE_FIND hFindDevice;

    if (hFind == NULL) {
        MessageBox( 0, "BluetoothFindFirstRadio failed", "error", 0 );
        return;
    }
   
    if (BluetoothGetRadioInfo(hRadio, &radioInfo) != ERROR_SUCCESS) {
        MessageBox(0, "BluetoothGetRadioInfo failed", "error", 0 );
        CloseHandle(hRadio);
        return;
    }
   
    // Initialize the search parameters
    ZeroMemory(&searchParams, sizeof(BLUETOOTH_DEVICE_SEARCH_PARAMS));
    searchParams.dwSize = sizeof(BLUETOOTH_DEVICE_SEARCH_PARAMS);
    searchParams.fReturnAuthenticated = TRUE;
    searchParams.fReturnRemembered = TRUE;
    searchParams.fReturnConnected = TRUE;
    searchParams.fReturnUnknown = TRUE;
    searchParams.fIssueInquiry = TRUE;
    searchParams.cTimeoutMultiplier = 4; // 4 * 1.28s (default HCI inquiry time)

    // Start the device discovery
    hFindDevice = BluetoothFindFirstDevice(&searchParams, &deviceInfo);
    if (hFindDevice == NULL) {
        MessageBox( 0, "BluetoothFindFirstDevice failed", "error", 0 );
        CloseHandle(hRadio);
        return;
    }

    do {
        // Check if the device is a BLE device
        if ( ( deviceInfo.ulClassofDevice & COD_MAJOR_DEVICE_CLASS_MASK ) == COD_MAJOR_DEVICE_CLASS_PERIPHERAL) {
            // Print information about the discovered BLE device
            wprintf(L"Device name: %s\n", deviceInfo.szName);
            wprintf(L"Device address: %02X:%02X:%02X:%02X:%02X:%02X\n",
                    deviceInfo.Address.rgBytes[5],
                    deviceInfo.Address.rgBytes[4],
                    deviceInfo.Address.rgBytes[3],
                    deviceInfo.Address.rgBytes[2],
                    deviceInfo.Address.rgBytes[1],
                    deviceInfo.Address.rgBytes[0]);
            wprintf(L"Device class: 0x%08x\n", deviceInfo.ulClassofDevice);
            wprintf(L"-----------------------------------------\n");

            /*
            // Connect to the BLE device
            HANDLE hDevice = ( HANDLE ) BluetoothOpenDevice(&deviceInfo.Address, NULL);
            if (hDevice == NULL) {
                printf("BluetoothOpenDevice failed\n");
                continue;
            }

            // Send data to the BLE device
            UCHAR sendData[] = { 0x01, 0x02, 0x03 };
            DWORD bytesSent;
            if (!BluetoothWriteFile(hDevice, sendData, sizeof(sendData), &bytesSent, NULL)) {
                printf("BluetoothWriteFile failed\n");
                CloseHandle(hDevice);
                continue;
            }

            // Receive data from the BLE device
            UCHAR recvData[256];
            DWORD bytesRead;
            if (!BluetoothReadFile(hDevice, recvData, sizeof(recvData), &bytesRead, NULL)) {
                printf("BluetoothReadFile failed\n");
                CloseHandle(hDevice);
                continue;
            }

            // Print received data
            printf("Received data from the device: ");
            for (DWORD i = 0; i < bytesRead; i++) {
                printf("%02X ", recvData[i]);
            }
            printf("\n");

            // Close the device handle
            CloseHandle(hDevice);
            */

        }

        // Continue searching for more devices
    } while (BluetoothFindNextDevice(hFindDevice, &deviceInfo));

    // Close the device find handle
    BluetoothFindDeviceClose(hFindDevice);

    // Close the radio handle
    // CloseHandle(hRadio);

    // return 0;
}

#pragma ENDDUMP

It requires a bthprops.dll that I am searching for...
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 41314
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Connecting to a BLE device

Postby Antonio Linares » Wed Feb 28, 2024 7:20 am

https://stackoverflow.com/questions/19436462/loadlibrarybthprops-dll-fails-file-not-found

It seems as we have to locate bthprops.cpl and then copy it as bthprops.dll, but this does not work...

where to find bthprops.dll... ?
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 41314
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Connecting to a BLE device

Postby Marc Venken » Wed Feb 28, 2024 8:16 am

Marc Venken
Using: FWH 23.04 with Harbour
User avatar
Marc Venken
 
Posts: 1343
Joined: Tue Jun 14, 2016 7:51 am
Location: Belgium

Re: Connecting to a BLE device

Postby Antonio Linares » Wed Feb 28, 2024 8:27 am

many thanks Marc, yes, it seems fine :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 41314
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain


Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: Google [Bot] and 57 guests