noble-winrt
noble-winrt copied to clipboard
Binding does not respect list of service ids in DiscoverServices, and instead tells windows to discover all (slow).)
This function simply requests all services from windows, and then filters the list, instead of requesting specific services from windows. For some devices with many services, this is slower than necessary.
bool BLEManager::DiscoverServices(const std::string& uuid,
const std::vector<winrt::guid>& serviceUUIDs)
{
CHECK_DEVICE();
IFDEVICE(device, uuid)
{
auto completed = bind2(this, &BLEManager::OnServicesDiscovered, uuid, serviceUUIDs);
device.GetGattServicesAsync(BluetoothCacheMode::Uncached).Completed(completed);
return true;
}
}
AFAIK the only available method is GetGattServicesForUuidAsync which would only request a single service.
So to implement this we'd have two cases:
- if the
serviceUUIDs
array is empty (which means no filter): useGetGattServicesAsync
as we use now - if the
serviceUUIDs
array not empty: issue aGetGattServicesForUuidAsync
call for each uuid in the array and combine the results
If anyone wants to implement this I can provide further guidance.
It's looking more and more like I am going to need to do this. The same deficiency is in noble_uwp. I could knock this out in JS, but I am going to be bumbling around in C. Ill give it a shot. Any web links on debugging node c modules, and tracking multiple async events are appreciated.
I am assuming we want to hit peripheral_winrt/getService instead of going directly to the device? getService is a callback pattern. Assuming we want to get each service in series, maybe I could do a recursive callback situation?
I get a ton of build errors before making any changes. Can I get some help on how to set my build system to ignore these things? I am assuming I am using tools that are too new or something like that?
C:\Users\Benefit Denial\Documents\GitHub\noble-winrtorig\src\radio_watcher.h(37,21): error C2039: 'function': is not a member of 'std' (compiling source file ..\src\radio_watcher.cc) [C:\Users\Benefit Denial\Documents\GitH
ub\noble-winrtorig\build\noble_winrt.vcxproj]
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\cppwinrt\winrt\Windows.Devices.Radios.h(246): message : see declaration of 'std' (compiling source file ..\src\radio_watcher.cc) [C:\Users\Benefit Denial\Document
s\GitHub\noble-winrtorig\build\noble_winrt.vcxproj]
C:\Users\Benefit Denial\Documents\GitHub\noble-winrtorig\src\radio_watcher.h(37,29): error C2061: syntax error: identifier 'function' (compiling source file ..\src\radio_watcher.cc) [C:\Users\Benefit Denial\Documents\GitHu
b\noble-winrtorig\build\noble_winrt.vcxproj]
C:\Users\Benefit Denial\Documents\GitHub\noble-winrtorig\src\radio_watcher.h(59,10): error C2039: 'function': is not a member of 'std' (compiling source file ..\src\radio_watcher.cc) [C:\Users\Benefit Denial\Documents\GitH
ub\noble-winrtorig\build\noble_winrt.vcxproj]
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\cppwinrt\winrt\Windows.Devices.Radios.h(246): message : see declaration of 'std' (compiling source file ..\src\radio_watcher.cc) [C:\Users\Benefit Denial\Document
s\GitHub\noble-winrtorig\build\noble_winrt.vcxproj]
C:\Users\Benefit Denial\Documents\GitHub\noble-winrtorig\src\radio_watcher.h(59,18): error C7568: argument list missing after assumed function template 'function' (compiling source file ..\src\radio_watcher.cc) [C:\Users\B
enefit Denial\Documents\GitHub\noble-winrtorig\build\noble_winrt.vcxproj]
C:\Users\Benefit Denial\Documents\GitHub\noble-winrtorig\src\radio_watcher.h(59,39): error C2062: type 'unknown-type' unexpected (compiling source file ..\src\radio_watcher.cc) [C:\Users\Benefit Denial\Documents\GitHub\nob
le-winrtorig\build\noble_winrt.vcxproj]
C:\Users\Benefit Denial\Documents\GitHub\noble-winrtorig\src\radio_watcher.h(59,56): error C2238: unexpected token(s) preceding ';' (compiling source file ..\src\radio_watcher.cc) [C:\Users\Benefit Denial\Documents\GitHub\
noble-winrtorig\build\noble_winrt.vcxproj]
C:\Users\Benefit Denial\Documents\GitHub\noble-winrtorig\src\radio_watcher.cc(18,17): error C2039: 'bind': is not a member of 'std' [C:\Users\Benefit Denial\Documents\GitHub\noble-winrtorig\build\noble_winrt.vcxproj]
Nevermind....adding #include <functional>
to radio_watcher.cc fixed it.
This is as far as I have been able to get. It works with one service uuid, but for more than one it just gets all. noble-winrt doesnt seem to have any foundation for emitting an error instead of a list of discovered serviceids.
bool BLEManager::DiscoverServices(const std::string& uuid,
const std::vector<winrt::guid>& serviceUUIDs)
{
CHECK_DEVICE();
IFDEVICE(device, uuid)
{
if (serviceUUIDs.empty() || serviceUUIDs.size() > 1) {
auto completed = bind2(this, &BLEManager::OnServicesDiscovered, uuid, serviceUUIDs);
device.GetGattServicesAsync(BluetoothCacheMode::Uncached).Completed(completed);
return true;
}
if (serviceUUIDs.size() == 1) {
auto& id = serviceUUIDs.at(0);
peripheral.GetService(id, [=](std::optional<GattDeviceService> service) {
if (service)
{
std::vector<std::string> serviceUuids;
serviceUuids.push_back(toStr(id));
mEmit.ServicesDiscovered(uuid, serviceUuids);
}
else
{
LOGE("GetService error");
//need to emit an error here.
}
});
}
}
}
It also appears that device.GetGattServicesAsync does not populate the internal cache of services upon completion?