Getting BLE Beacons in C++ Windows 10 Desktop Application

1

Has someone already figured out how to get BLE Beacons into a c++ desktop apps?

I have some code from the following websites to get it done in c#:
msdn sozial site
and
codefest.at post. Sorry, it's in german but the code is code

but that'for C# and not c++

I also have the example from MS (msdn.microsoft.com/en-us/library/hh973459.aspx) how to use the WinRL

For now I have the following code:

#include "stdafx.h"

#include <iostream>
#include <Windows.Foundation.h>
#include <wrl\wrappers\corewrappers.h>
#include <wrl\client.h>
#include <stdio.h>
#include <../winrt/windows.devices.bluetooth.h>
#include <../winrt/windows.devices.bluetooth.advertisement.h>

using namespace std;
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
using namespace ABI::Windows::Foundation;
using namespace ABI::Windows::Devices::Bluetooth::Advertisement;

/* http://www.codefest.at/post/2015/09/07/Bluetooth-Beacons-Windows-10.aspx
private async void WatcherOnReceived(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs eventArgs)
{
_beaconManager.ReceivedAdvertisement(eventArgs);
}

var watcher = new BluetoothLEAdvertisementWatcher { ScanningMode = BluetoothLEScanningMode.Active };
watcher.Received += WatcherOnReceived;
watcher.Stopped += WatcherOnStopped;
watcher.Start();
*/

// Prints an error string for the provided source code line and HRESULT
// value and returns the HRESULT value as an int.
int PrintError(unsigned int line, HRESULT hr)
{
    wprintf_s(L"ERROR: Line:%d HRESULT: 0x%X\n", line, hr);
    return hr;
}

EventRegistrationToken watcherToken;

int main()
{

    // Initialize the Windows Runtime.
    RoInitializeWrapper initialize(RO_INIT_MULTITHREADED);
    if (FAILED(initialize))
    {
        return PrintError(__LINE__, initialize);
    }

    // Get the activation factory for the IBluetoothLEAdvertisementWatcherFactory interface.
    ComPtr<IBluetoothLEAdvertisementWatcherFactory> bleAdvWatcherFactory;
    HRESULT hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_Devices_Bluetooth_Advertisement_BluetoothLEAdvertisementWatcher).Get(), &bleAdvWatcherFactory);
    if (FAILED(hr))
    {
        return PrintError(__LINE__, hr);
    }

    IBluetoothLEAdvertisementWatcher* bleWatcher;
    IBluetoothLEAdvertisementFilter* bleFilter;

    hr = bleAdvWatcherFactory->Create(bleFilter, &bleWatcher);

    if (bleWatcher == NULL)
    {
        cout << "bleWatcher is NULL, err is " << hex << hr;
    }
    else
    {
        bleWatcher->Start();

        while (1)
            Sleep(1000);
    }


    return 0;
    }

my problem is that the Watcher Factory complains ( hr = E_INVALIDARG "One or more arguments are not valid" 0x80070057) that one of the variables is not valid (I suspect the filter because it has no valid content).

And even on the same level of severity, I have no idea how to register the event handler for the incoming beacons.

msdn.microsoft.com/en-us/library/windows/apps/windows.devices.bluetooth.advertisement.bluetoothleadvertisementwatcher.received?cs-save-lang=1&cs-lang=cpp is telling me something about the Received event. But I don't have it in my autocomplete from VS and also not by manually looking into the header file. The next best thing I have is the "add_Received" but I can't find any documentation about it how to use. And I don't get that much wiser from the header file.

Thanks in advance for tips and tricks or even a working solution.
Markus

c++
bluetooth
windows-runtime
uwp
bluetooth-lowenergy
asked on Stack Overflow Oct 6, 2016 by Markus F • edited Oct 11, 2016 by Rita Han

1 Answer

1

You have few problems in your code. First of all All I* classes should be wrapped around ComPtr<I*>

ComPtr<IBluetoothLEAdvertisementWatcher> bleWatcher;
ComPtr<IBluetoothLEAdvertisementFilter> bleFilter;

In function bleAdvWatcherFactory->Create(bleFilter, &bleWatcher); parameter bleFilter is undefined and it will lead to undefined behaviour (In Debug version it might be initialized as nullptr).

You can create it by using: Wrappers::HStringReference

Wrappers::HStringReference class_id_filter(RuntimeClass_Windows_Devices_Bluetooth_Advertisement_BluetoothLEAdvertisementFilter);
hr = RoActivateInstance(class_id_filter.Get(), reinterpret_cast<IInspectable**>(bleFilter.GetAddressOf()));

Then you are allowed to call:

hr = bleAdvWatcherFactory->Create(bleFilter.Get(), &bleWatcher.GetAddressOf());
answered on Stack Overflow Jan 26, 2017 by Lukasz S

User contributions licensed under CC BY-SA 3.0