How to scan Bluetooth Low energy (BLE) devices which are available/present? - windows-10-mobile

I am working on a windows phone app that can scan BLE devices. I have implemented the logic which is showing the desired devices.
But the problem is that if I remove those devices or switch them off, even then my application returns their names in scan result. I think it is returning cached result. How I can make sure it will show only those devices which are available/present.
I have tried using the additional properties i.e. System.Devices.Aep.IsPresent etc in scan but they are coming as null in result no matter ble devices available or not.
Here is code snippet I am using -
string[] requestedProperties = new string[] { "System.Devices.Aep.IsPresent"
, "System.Devices.Present"
, "System.Devices.Connected"
, "System.Devices.Paired"
, "System.Devices.Aep.IsConnected"
, "System.Devices.AepContainer.IsPresent"
};
diCollection = await DeviceInformation.FindAllAsync(GattDeviceService.GetDeviceSelectorFromUuid(serviceUuid)
, requestedProperties
);
foreach (var diItem in diCollection)
{
Debug.WriteLine("Discovered Device name - " + diItem.Name);
Debug.WriteLine("Discovered Device Additional Properties Below");
foreach (var item in diItem.Properties)
{
Debug.WriteLine("Key-{0} Value-{1}", item.Key, item.Value);
}
}
Here is the Package.appxmanifest capabilities used -
<Capabilities>
<Capability Name="internetClientServer" />
<DeviceCapability Name="bluetooth" />
</Capabilities>
Please help me resolve this small issue. Am I missing something trivial here?
Thanks in advance.
-Jitender

I tried every single one of the properties below with 2 PCs, where both were paired to the Handheld and only one was turned on and a Windows Handheld 8.1.
https://learn.microsoft.com/en-us/windows/uwp/devices-sensors/device-information-properties
The ones needed were AssociationEndpoint related properties, none of which are supported in windows phone 8.1 (even the enumeration is not available) - so basically the api does not provide any way for us to be able to query the connections from cache for whether they are presently available or not.
I tested with every combinations and they do not provide sufficient information (the PC that is turned on is indistinguishable from the one that was not).
The only workaround was to connect to every paired computer on the cache and see if each connection was successful to add this to the list displayed if succeeeded. Every failed connection takes ~4-5 seconds. So this can take some significant amount of delay in showing the list if there are multiple paired computers via in the past. Yet I could not find any other feasible way of checking this, at least this resolves the issue.

Related

Why is my USB device sometimes creating another entry in the windows (7&10) registry?

What can cause a USB device to have double entries for the same device in the registry?
How are the numbers following the "9&" derived (see below), i.e., 3406C40F and 2D6B958A, in case this is a hint to what is causing this problem.
My guess is that possibly the device reports itself differently during enumeration, possibly a different configuration and/or device descriptor.
Details of the test that causes this problem:
I am running a USB plug/unplug enumeration test where every time I plug in the device I verify various things to make sure that the enumeration is correct. This cycle is repeated 1000's of times. This a development test.
Upon enumeration, the test uses devcon.exe to verify some things about the collections. For some unknown reason, after some number of enumerations, the numbers associated with the collections is changing. Further investigation shows what appears to be two entries in the registry for the same device with these same numbers.
\9&3406C40F is the number at the beginning of the test associated with each collection
and some time later after several hundred enumerations it changes, in this case to
\9&2D6B958A
initial enumeration
2020-09-18 16:09:22,066 main INFO =========> devcon.exe "find HID"\vid_047F* <=========
HID\VID_047F&PID_015D&MI_03&COL05\9&3406C40F&0&0004 : HID-compliant device
HID\VID_047F&PID_015D&MI_03&COL01\9&3406C40F&0&0000 : HID-compliant device
HID\VID_047F&PID_015D&MI_03&COL02\9&3406C40F&0&0001 : HID-compliant device
HID\VID_047F&PID_015D&MI_03&COL03\9&3406C40F&0&0002 : HID-compliant consumer control device
HID\VID_047F&PID_015D&MI_03&COL04\9&3406C40F&0&0003 : HID-compliant device
several hundred enumerations later,
HID\VID_047F&PID_015D&MI_03&COL01\9&2D6B958A&0&0000 :HID-compliant device
HID\VID_047F&PID_015D&MI_03&COL02\9&2D6B958A&0&0001 :HID-compliant device
HID\VID_047F&PID_015D&MI_03&COL03\9&2D6B958A&0&0002 :HID-compliant consumer control device
HID\VID_047F&PID_015D&MI_03&COL04\9&2D6B958A&0&0003 :HID-compliant device
HID\VID_047F&PID_015D&MI_03&COL05\9&2D6B958A&0&0004 :HID-compliant device
I've run this test for millions of cycles on other devices but I have never seen this problem before. It is happening on win7 and win10.
Any help would be very appreciated! thx!
It's a device bug. The device is intermittently not reporting it's serial number so the OS creates a new entry with a different LUID (locally unique ID).

What is the correct usage of FrameTiming and FrameTimingManager

I'm trying to log the time the GPU takes to render a frame. To do this I found that Unity implemented a struct FrameTiming, and a class named FrameTimingManager
The FrameTiming struct has a property gpuFrameTime which sounds like exactly what I need, however the value is never set, and the documentation on it doesn't provide much help either
public double gpuFrameTime;
Description
The GPU time for a given frame, in ms.
Looking further I found the FrameTimingManager class which contains a static method for GetGpuTimerFrequency(), which has the not so helpful documentation stating only:
Returns ulong GPU timer frequency for current platform.
Description
This returns the frequency of GPU timer on the current platform, used to interpret timing results. If the platform does not support returning this value it will return 0.
Calling this method in an update loop only ever yields 0 (on both Window 10 running Unity 2019.3 and Android phone running Android 10).
private void OnEnable()
{
frameTiming = new FrameTiming();
}
private void Update()
{
FrameTimingManager.CaptureFrameTimings();
var result = FrameTimingManager.GetGpuTimerFrequency();
Debug.LogFormat("result: {0}", result); //logs 0
var gpuFrameTime = frameTiming.gpuFrameTime;
Debug.LogFormat("gpuFrameTime: {0}", gpuFrameTime); //logs 0
}
So what's the deal here, am I using the FrameTimeManager incorrectly, or are Windows and Android not supported (Unity mentions in the docs that not all platforms are supported, but nowhere do they give a list of supported devices..)?
While grabbing documentation links for the question I stumbled across some forum posts that shed light on the issue, so leaving it here for future reference.
The FrameTimingManager is indeed not supported for Windows, and only has limited support for Android devices, more specifically only for Android Vulkan devices. As explained by jwtan_Unity on the forums here (emphasis mine):
FrameTimingManager was introduced to support Dynamic Resolution. Thus, it is only supported on platforms that support Dynamic Resolution. These platforms are currently Xbox One, PS4, Nintendo Switch, iOS, macOS and tvOS (Metal only), Android (Vulkan only), Windows Standalone and UWP (DirectX 12 only).
Now to be able to use the FrameTimingManager.GetGpuTimerFrequency() we need to do something else first. We need to take a snapshot of the current timings using FrameTimingManager.CaptureFrameTimings first (this needs to be done every frame). From the docs:
This function triggers the FrameTimingManager to capture a snapshot of FrameTiming's data, that can then be accessed by the user.
The FrameTimingManager tries to capture as many frames as the platform allows but will only capture complete timings from finished and valid frames so the number of frames it captures may vary. This will also capture platform specific extended frame timing data if the platform supports more in depth data specifically available to it.
As explained by Timothyh_Unity on the forums hereenter link description here
CaptureFrameTimings() - This should be called once per frame(presuming you want timing data that frame). Basically this function captures a user facing collection of timing data.
So the total code to get the GPU frequency (on a supported device) would be
private void Update()
{
FrameTimingManager.CaptureFrameTimings();
var result = FrameTimingManager.GetGpuTimerFrequency();
Debug.LogFormat("result: {0}", result);
}
Note that all FrameTimingManager methods are static, and do not require you to instantiate a manager first
Why none of this is properly documented by Unity beats me...

A driver has enumerated two child PDO's that returned identical Device ID's

I have a kmdf bus driver PCI\VEN_XXXX&DEV_XXXX that creates two statically enumerated PDOs with serial numbers: 217 and 218; one for each Ethernet port. The PDO hardware id is ROOT\MY_NIC_PORT so I can install a NDIS Miniport driver on them.
The bus driver passes SDV and Verifier; but, on reboot two more PDOs get enumerated. On the next reboot I get a duplicate pdo crash.
The toaster example used the device class guid as part of the hardware id. When I tried that my NIC ports no longer showed up in device manager.
Any debug suggestion or work around idea would be appreciated?
pnpCaps.LockSupported = WdfFalse;
pnpCaps.EjectSupported = WdfTrue;
pnpCaps.Removable = WdfTrue;
pnpCaps.DockDevice = WdfFalse;
pnpCaps.UniqueID = WdfTrue;
pnpCaps.SilentInstall = WdfTrue;
pnpCaps.SurpriseRemovalOK = WdfTrue;
pnpCaps.HardwareDisabled = WdfFalse;
pnpCaps.NoDisplayInUI = WdfFalse;
pnpCaps.Address = SerialNo;
pnpCaps.UINumber = SerialNo;
************************************************************
Driver Verifier detected violation:
A driver has enumerated two child PDO's that returned identical Device
ID's.
CulpritAddress = FFFFF8025ED309C4, DeviceObject1 = FFFFE3882FB2F300,
DeviceObject2 = FFFFE3882EBF88D0.
************************************************************
There are a few versions of the toaster bus sample -- assuming you started with this one, then note that it saves its list of child PDOs in the registry. My guess is that your driver is both loading PDOs from the registry, and trying to dynamically create some too.
Set a breakpoint on your driver's version of Bus_PlugInDevice, and see how often it's getting called. Make sure it's never getting called 2x with the same Instance ID.
To clear up a bit of the naming thing: a device setup class is a GUID that is totally unrelated to its hardware ID. For NICs that want to interoperate with the OS's networking stack, you must use the NET setup class, {4d36e972-e325-11ce-bfc1-08002be10318}. You can put anything you want into your hardware ID. I don't really encourage you to put "ROOT\" in there, since that could be confused with a root-enumerated device (which your devices are not). Instead, you can use "yourcompany_yourdevice\port1" as a hardware ID.
While you're thinking about naming things, there are a few things to note about hardware IDs:
Once you assign a HWID, it's rather difficult to change it in a future driver update, without breaking customers who had already installed your device. So get it right the first time.
Once you assign an Instance ID, don't change or reuse it for the lifetime of the device. Otherwise you'll cause this bugcheck, or cause IP addresses to bounce around / get reset. The OS ultimately uses the Instance ID to figure out which NIC port to bind an IP address to.
Think about what happens if someone plugs 2 of your device into a system. Make sure your Instance ID is unique across all ports. You can do this by encoding into the Instance ID the PCI device serial number (if it has one) or by falling back to the PCI bus:device:function.
Don't lump together different types of hardware under the same hardware ID. For example, if the deluxe version of your device supports checksum offload, but the regular version does not -- you should use 2 different hardware IDs for these two different devices. Otherwise it gets difficult to write a single INF that has keywords for both.

Getting unique device ID in Win8 app

I need to get an unique device identifier in Windows 8 application. I have few applications and I need to determine device ID that have one or more apps installed (e.g. a bonus for a gamer installing other game in the series). Using following methods provides me with per-app IDs which won't tell me that device have some other apps installed.
I've tried three different approaches but they all return different UDIDs on the same PC.
1) This was used before, since I needed unique id per app, now I need UDID, so it's predictably doesn't work for me:
GUID g;
std::string ret;
CoCreateGuid(&g);
Platform::Guid pg(g);
std::string udid = WStringToUTF8(pg.ToString()->Data());
2) I've tried EasClienDeviceInformation, which was suggested as a sure thing, but got different results for 2 apps on the same PC:
EasClientDeviceInformation^ info = ref new EasClientDeviceInformation;
ret = WStringToUTF8(info->Id.ToString()->Data());
3) And I've tried the commonly used way to get ASHWID, without any hope and it obviously shown different UDIDs:
auto token = Windows::System::Profile::HardwareIdentification::GetPackageSpecificToken(nullptr);
ret = WStringToUTF8(Windows::Security::Cryptography::CryptographicBuffer::EncodeToBase64String(token->Id)->Data());
_RPT1(_CRT_WARN, "TOKEN UDID IS %s \n", ret.c_str());
I know only about one option and it's to use MAC-address, but I'm not sure if it's a valid option. Users can have a PC where MAC-address could be changed or duplicated (I've heard of batches of chinese network adapters having the same address), or have a device without a network whatsoever (e.g. use a PC without a network adapter and connect to the internet using USB dongles).
So the questions are:
Did I do everything right, or I made a mistake that caused my examples to return wrong UDIDs?
Am I right to assume that MAC-address is the only viable way to get a trutfully unique per-device identifier? I could've been inattentive and missed some obvious way.
Am I wrong in my assumptions of MAC-address identification insecurities like those I've described above?
UPD: I also would like to know the right way for WP8, while we're on it.

Why does EnumDisplayDevices ignore my second gpu?

I've got a call like this:
while(EnumDisplayDevices(NULL, index, &displayDevice, 0)) {
// do stuff
}
My understanding is that this is supposed to report all graphics devices as displayDevice but it only reports one, multiple times. I've got an Intel card as my primary adapter and and NVidia card as secondary -- I'm hoping to be able to not only get the names and info of both cards but also to determine which the app is run with (ie the app defaults to the Intel but I can change the default in the NVidia control panel or even with the context menu in Windows Explorer). However, the call always reports three devices... and all three are the Intel. It reports Intel as \.\DISPLAY1, \.\DISPLAY2 and \.\DISPLAY3.
I can confirm that my code runs with the correct graphics card by looking at the DLLs that it uses. (Indeed, I needed to connect a second monitor to get it to use the NVidia card at all -- otherwise, the app would launch on the Intel no matter what card I chose. Either way, the Intel card always comes back as DISPLAY_DEVICE_ACTIVE.
This is because flag in DISPLAY_DEVICE structure, DISPLAY_DEVICE_PRIMARY_DEVICE --The primary desktop is on the device. For a system with a single display card, this is always set. For a system with multiple display cards, only one device can have this set.
To fetch active display devices from second GPU use following flag condition
while (EnumDisplayDevices(NULL, index, &dd, 0))
{
if(((dd.StateFlags & DISPLAY_DEVICE_ACTIVE) && ((dd.StateFlags & DISPLAY_DEVICE_ACTIVE) || (!(dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE))) &&(!(dd.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER))))
{
activeDispCount++;
}
index++;
}

Resources