Bluetooth LE code behaving differently on Windows 8.1 and 10 - bluetooth

I'm using the Bluetooth Low Energy (BLE) API introduced by Microsoft with Windows 8, the BluetoothGATTxxx functions.
My code is working fine on Windows 8.1, but I have observed a difference in the behavior of BluetoothGATTSetDescriptorValue between 8.1 and Windows 10.
The scenario is the following:
Pair the device with the Windows interface.
Find it and enable data notifications with a call to BluetoothGATTSetDescriptorValue to set the field 'IsSubscribeToNotification' of ClientCharacteristicConfiguration to true.
Register a callback to receive the new values (I tried to register the callback first, didn't work well).
The callback gets called every time new data is sent from the device.
All is good. Now, if I turn the device off and on, then repeat steps 2 to 4 it will work fine on Windows 8.1, but not on Windows 10:
BluetoothGATTSetDescriptorValue returns 0x80070572 i.e.
HRESULT_FROM_WIN32(ERROR_NO_USER_SESSION_KEY).
In practice, this means the user has to remove the pairing and redo it every time the device is turned off.
The problem is made worse by the fact that the device has some power management feature and will turn off automatically if it stays idle too long. It seems I need to keep it alive if I don't want the user to delete/redo the pairing every time they want to use the device!
Is anyone else running into this issue too? I tried several searches here and on the net but with no luck. A solution would be to force a new pairing programmatically, and since there is no API for this it would be an ugly hack. I definitely don't want to take that path...

Related

Web-Bluetooth error "GATT operation not authorized" occurs on Windows only

I have been working with web-bluetooth for the past several months on iOS and ChromeOS without any problems. But today, I tried to run some of my examples on Windows for the first time, and to my surprise, most of the things I had implemented didn't work with Windows. I am able to successfully connect to my peripheral, but whenever I try reading or writing anything to a custom service with a custom characteristic, I get the error "GATT operation not authorized". I have tried looking around but there is no information anywhere about this.
I am including below the simplest example I have which is just for turning the LEDs on / off on an nrf52832 board. There is only one custom service and one custom characteristic implemented, the value of which controls the states of the LEDs. This works without any problems on Chromebooks and Macs but does not work on Windows. Here is the link to this simple project including the embedded code and the web-app.
https://github.com/shtarbanov/WebBluetooth-Feather-nRF52832/tree/master/LED%20Control
I have made two implementations of the same thing, one based on promises and another based on async-await located in the folders "WebApp (Async)" and "WebApp (Promises)", respectively. Both of those implementations work fine on Mac and Cromebook, but not on Windows.
It is a known issue that secure characteristics are not accessible using Web Bluetooth on Windows. On other platforms the pairing occurs automatically, but not on Windows. There is an issue tracking this:
https://bugs.chromium.org/p/chromium/issues/detail?id=960258
Stuck with this also and as for workaround i can recommend for windows platform to pair device firstly using windows itself and than to pair it via browser(as a workaround). Not much but hope this helps, at list a little.
P.S. it should be paired via windows only once, so PC will remember device, and than you can pair via browser as long as PC remembers device.

How to detect running on a real device?

I am working on a universal application, and I am trying to detect whether it runs on a desktop computer or on a real IoT device (Raspberry PI 2). Following the recommendation, I am trying to use API contract checks, however this returns true even on the desktop machine:
ApiInformation.IsApiContractPresent( "Windows.Devices.DevicesLowLevelContract", 1, 0 );
Obviously when I try to call GpioController.GetDefault(), it fails on the desktop, but strangely with a FileNotFoundException: "The specified module could not be found."
So what is the right way to detect a real device?
Thanks for your help,
György
Edit:
On some desktops GpioController.GetDefault() returns null, while on other machines it fails with FileNotFoundException.
Edit:
My goal is to ensure that I can safely call any GPIO or IoT Core specific APIs without using try-catch blocks everywhere to handle exceptions when running on a non-IoT device.
You can find the type of device your app is running on by
Windows.System.Profile.AnalyticsInfo.VersionInfo.DeviceFamily
Source:
https://msdn.microsoft.com/en-us/library/windows/apps/windows.system.profile.analyticsversioninfo.aspx
Microsoft does suggest to maximise your reach with universal apps by checking for capabilities instead of just checking the device family.
There's an article about all that here:
https://msdn.microsoft.com/en-us/library/windows/apps/dn894631.aspx
It depends on what aspect of a "real device" you want to check. Using API Contract information is not a good proxy, as you have found (although it should return null, not crash, on desktop -- that's a bug). Using AnalyticsInfo can be a reasonable proxy but you have to be careful about receiving new values over time, plus it actually identifies the OS type rather than the physical hardware. Enumerating hardware devices is the best way to detect hardware, but they can come and go dynamically as the user plugs and unplugs them.
What is it you are looking to do differently based on the answer?

restart via code on windows 10 uwp

We've created a Windows 10 application that runs on tablets in Windows 10 kiosk mode. It works just fine, however, the wifi connection gets lost sometimes since the locations are very remote. We tried fixing the issue from the networking side, but when the devices lose and regain internet access the application will still hang as if it doesn't have internet access displaying a blank page. Where these devices are used, they are bolted into the wall to prevent theft. Which means if we want to reboot its very time consuming as we have to unscrew the cases off the wall and then open the cases to gain access to the power button, and the only way to get the application to run successfully again is to do a reboot on the device.
It was suggested that we have a way to perform a reboot from the application, however, every code example I've tried doesn't work in Windows 10 UWP. Here is the most common one I've found:
System.Diagnostics.Process.Start("restart", "/r");
I have access to the namespace
System.Diagnostics
but the Process class does not exist. Anyone have suggestions on rebooting via code on Win 10 UWP? Or a better solution to our issue? Thanks in advance.
It's also worth mentioning I tried execute a Powershell command too and the dll I need to reference for the Powershell class is not compatible with UWP.
What you require is not possible with the APIs available to UWP apps. This was a security decision. An app distributed through the store shouldn't be able to do things like restart machines.
Based on your scenario though you shouldn't need to go through the store. This means that you could PInvoke native code to do whatever you want. This would still need to be initiated on the actual device.
Yes you can do that!
You should add IoT System Administration in App capability declarations:
<Capabilities><iot:Capability Name="systemManagement"/></Capabilities>
and also You need to have "Windows IoT Extension for UWP" added to your project
using this for Shutdown
Windows.System.ShutdownManager.BeginShutdown(Windows.System.ShutdownKind.Shutdown, TimeSpan.FromSeconds(1)); //Delay is not relevant to shutdown
or for Restart
Windows.System.ShutdownManager.BeginShutdown(Windows.System.ShutdownKind.Restart, TimeSpan.FromSeconds(1)); //Delay before restart after shutdown
You can get more information in this Link

Intermittent Issue with SCAN_Enable error on app load

I acquired a batch of WT0490 wearable pdas with detachable scan head, so converted an application originally made for Windows Mobile (which has been running perfectly for several years) to run on the WT4090s. The devices use these versions:
Windows CE 5.0
EMDK 2.6
ASP.net CF 2.0
Since rollout I've seen some very frustrating behaviour, which seems to start happening after the devices have been operating a few days. Users are reporting the following error:
Unexpected error in application
SCAN_Enable
There doesnt seem to be any noticeable pattern, several devices will be working perfectly for a few days then suddenly this error will show. THen a few days and a few reboots later they work again.
All devices were taken right back to stock settings then our cabs deployed to them. All identical models. We've tried altering memory allocation, swapping scanner headers etc but there is no pattern.
The error seems to occur on load of the first form after login, the login screen displays a list of users in a dropdown with a password box so that part of the app works ok, it seems to be when the scanner is initialised that this failure happens.
I had 40 devices, now 30+ have gone down with this same issue so my gut is telling me its a software issue but as yet ive not been able to find out why.
We've tried warm boots, cold boots, complete reprovisionings as well. We have a couple of dev units that don't show the problem although they are not in regular use so maybe we just haven't seen the problem 'yet'.
I hope someone out there has had this issue and knows how to fix it.
Thanks in advance.
WT4090 was built by Motorola Solution enterprise business, now part of Zebra Technologies. The WT4090 is currently in EOS (End Of Sales) but is still supported by Zebra if you've a maintenance contract.
You can check if you've the latest OS version and fixes installed on the device looking on Zebra Technologies support website.
For question on how to develop for Zebra Technologies devices you can take a look at Launchpad, Zebra's developer community website.
It's Worth noting that these devices have detachable barcode scanners - so if the scanner is not correctly attached, you get a SCAN_Enable error.
If you don't release the scanner, you can also see this error as a previous form could have the scanner blocked.
You may also find you have the ScanWedge app running - this will also block the scanner so you cannot get it enabled. The EMDK needs exclusive access to the scanner to enable it.

Getting node-hid working in Windows

I'm trying to get the node-hid (https://github.com/node-hid/node-hid) module working on Windows 7. I can open a device and write to it, but no data ever arrives.
I've verified the device is sending data. I've dug through the node-hid code (HID.cc) and tried several things to get it working:
Modified the HID::recvAsync function to use an hid_read_timeout in a loop to see if that would return anything.
Set both blocking and non-blocking.
Changed buffer sizes to exactly fit what the device sends.
On Windows 8, with the hid_read_timeout call change, this all works fine. I'm not sure what may have changed between the two systems, but I plan on using this on windows XP as well, so I can't just call it good.
I'm struggling to come up with more ideas as to how to debug this issue. Has anyone successfully done this before? Is there a better option to use Node.js with an HID device?
After some serious debugging, I found that for some reason I have as of yet not been able to determine, the source file, HID.cc for the node module node-hid needed a call to hid_init() within the constructor before the hid_open call. I'm assuming that somehow this is getting hit with multiple threads, making the safety of calling hid_init before hid_open necessary.
I now have this working on both windows 7 and windows 8.
Summary of changes I had to make:
Add hid_init before the hid_open call I'm using.
Change hid_read to hid_read_timeout in a loop. (Since reads won't return on windows XP when shutting down otherwise.)
Once I've cleaned it up, I'll send the author my changes.

Resources