Search for devices in range of bluetooth UWP - c#

Is it possible to scan for devices in range of bluetooth? I tried FindAll method but it returns all paired devices. Also tried deviceWatcher with the same result.

Is it possible to scan for devices in range of bluetooth?
This is possible, we can use either DeviceInformation.FindAllAsync method or DeviceWatcher class. But to get all Bluetooth devices, we need to note that currently Bluetooth APIs don't provide a selector to get ALL devices that are both paired and non-paired. BluetoothDevice.GetDeviceSelector method actually returns the same value as BluetoothDevice.GetDeviceSelectorFromPairingState(true). So when you use this selector (Advanced Query Syntax (AQS) string), you will always get all paired devices.
To get all devices, we can use this selector get paired devices first and then use BluetoothDevice.GetDeviceSelectorFromPairingState(false) to get the rest unpaired devices.
Or we can just specify the AQS string like following:
//The AQS string for getting all Bluetooth devices
var BluetoothDeviceSelector = "System.Devices.DevObjectType:=5 AND System.Devices.Aep.ProtocolId:=\"{E0CBF06C-CD8B-4647-BB8A-263B43F0F974}\"";
//Using DeviceInformation.FindAllAsync method
var deviceInfoCollection = await DeviceInformation.FindAllAsync(BluetoothDeviceSelector);
//Using DeviceWatcher class
var deviceWatcher = DeviceInformation.CreateWatcher(BluetoothDeviceSelector);
PS: FindAllAsync method is more often used to look through the devices that are currently connected to or paired with the system. To get both paired and non-paired devices, it better to use DeviceWatcher class.
For more info about how to use FindAllAsync method or DeviceWatcher class, please see Enumerate devices and official Device enumeration and pairing sample.
Besides Bluetooth devices, there are also Bluetooth LE devices you might want to get. And for Bluetooth LE devices, the AQS string would be System.Devices.DevObjectType:=5 AND System.Devices.Aep.ProtocolId:="{BB7BB05E-5972-42B5-94FC-76EAA7084D49}".

GetDeviceSelector and friends return strings containing AQS queries. Have you ever looked at them?
Paired
System.Devices.DevObjectType:=5
AND System.Devices.Aep.ProtocolId:="{E0CBF06C-CD8B-4647-BB8A-263B43F0F974}"
AND (
System.Devices.Aep.IsPaired:=System.StructuredQueryType.Boolean#True
OR System.Devices.Aep.Bluetooth.IssueInquiry:=System.StructuredQueryType.Boolean#False
)
Unpaired
System.Devices.DevObjectType:=5
AND System.Devices.Aep.ProtocolId:="{E0CBF06C-CD8B-4647-BB8A-263B43F0F974}"
AND (
System.Devices.Aep.IsPaired:=System.StructuredQueryType.Boolean#False
OR System.Devices.Aep.Bluetooth.IssueInquiry:=System.StructuredQueryType.Boolean#True
)
What do you think is tested by the expression in parentheses?
What do you think might happen if you omit this clause from the string you supply to CreateWatcher?
Something less obvious that you may find helpful is the fact that there are two Bluetooth protocol identifiers. The one shown above is for classic Bluetooth and the query does not match BLE (Bluetooth Low Energy) devices.
The selector I suggest you use is
System.Devices.DevObjectType:=5
AND (
System.Devices.Aep.ProtocolId:="{BB7BB05E-5972-42B5-94FC-76EAA7084D49}"
OR System.Devices.Aep.ProtocolId:="{E0CBF06C-CD8B-4647-BB8A-263B43F0F974}#"
)
I have put line breaks in all these queries to help you read them. Don't include them in your code. For convenience here's some code from one of my projects.
string BleSelector = "System.Devices.DevObjectType:=5 AND (System.Devices.Aep.ProtocolId:=\"{BB7BB05E-5972-42B5-94FC-76EAA7084D49}\" OR System.Devices.Aep.ProtocolId:=\"{E0CBF06C-CD8B-4647-BB8A-263B43F0F974}\")";
string[] requestedProperties = { "System.Devices.Aep.DeviceAddress", "System.Devices.Aep.IsConnected", "System.Devices.Aep.ProtocolId" };
deviceWatcher = DeviceInformation.CreateWatcher(BleSelector, requestedProperties, DeviceInformationKind.AssociationEndpoint);
Using a watcher has the advantage that the list becomes available progressively. FindAllAsync may be asynchronous but it takes ages to return.

I provide BluetoothLE Device Selector string in the following code. It works for me.
DeviceWatcher dWatcher = null;
var BluetoothDeviceSelector = "System.Devices.DevObjectType:=5 AND System.Devices.Aep.ProtocolId:=\"{BB7BB05E-5972-42B5-94FC-76EAA7084D49}\" AND ((System.Devices.Aep.IsPaired:=System.StructuredQueryType.Boolean#True OR System.Devices.Aep.IsPaired:=System.StructuredQueryType.Boolean#False) OR System.Devices.Aep.Bluetooth.IssueInquiry:=System.StructuredQueryType.Boolean#False)";
dWatcher = DeviceInformation.CreateWatcher(BluetoothDeviceSelector);
dWatcher.Added += DeviceAdded;
dWatcher.Updated += DeviceUpdated;
dWatcher.Start();

Related

C# - Bluetooth LE DevicePicker with Custom Filter

I'm trying to add a custom filter to my DevicePicker using System.ItemNameDisplay
I've been searching the internet, finding examples, and testing different implementations but nothing has worked
I can use any of the built in DeviceSelectors from the BluetoothLEDevice class and they work fine but for my specific application I need the DevicePicker to only show devices whose name starts with a certain string [ProductNameStart] where [ProductNameStart] is a hard-coded string representing the starting characters of the devices I want to include on the DevicePicker
I've looked through this example (specifically Scenario 6) and it claims that the AQS can be used in the DevicePicker but doesn't show how.
I also created another project using DeviceWatcher and that works exactly like I intended using this constructor
string deviceFilter = "System.ItemNameDisplay:~<\"[ProductNameStart]\"";
string[] rp = { };DeviceWatcher deviceWatcher = DeviceInformation.CreateWatcher(deviceFilter,rp,DeviceInformationKind.AssociationEndpoint);
I've tried the following implementations for DevicePicker with no luck
DevicePicker devicePicker = new DevicePicker();
//devicePicker.RequestedProperties.Add("System.ItemNameDisplay"); // Doesn't help anything
//devicePicker.Filter.SupportedDeviceSelectors.Add("System.ItemNameDisplay:~<\"[ProductNameStart]\""); // Doesn't Work
//devicePicker.Filter.SupportedDeviceSelectors.Add(BluetoothLEDevice.GetDeviceSelectorFromDeviceName("System.ItemNameDisplay:~<\"[ProductNameStart]\"")); // Doesn't Work
//devicePicker.Filter.SupportedDeviceSelectors.Add(BluetoothLEDevice.GetDeviceSelectorFromDeviceName("[ProductNameStart]")); // Doesn't Work
//devicePicker.Filter.SupportedDeviceSelectors.Add(BluetoothLEDevice.GetDeviceSelectorFromDeviceName(":~<\"[ProductNameStart]\"")); // Doesn't Work
//devicePicker.Filter.SupportedDeviceSelectors.Add(BluetoothLEDevice.GetDeviceSelectorFromDeviceName("~<\"[ProductNameStart]\"")); // Doesn't Work
//devicePicker.Filter.SupportedDeviceSelectors.Add(BluetoothLEDevice.GetDeviceSelectorFromDeviceName("\"[ProductNameStart]\"")); // Doesn't Work
Resources:
SO Posts:
Bluetooth LE Enumeration with DevicePicker issue
AQS syntax when providing a filter for BLE scanning in UWP
Other Posts:
Displaying the device picker in a UWP application
Build a device selector
Using Advanced Query Syntax Programmatically
UWP: Working with Bluetooth devices (part 1)

How to find USB HID DevicePath?

I've been working on USB HID Device in embedded system and C# for a while. I decided to use USBHid library in C#. I got the ideal result with this library. But I have a problem. While defining the USB in the USBHid library, the following code is sufficient in the project of the library that I found on the internet.
public UsbHidDevice Device;
Device = new UsbHidDevice(vvvv,pppp);
However, when I use the same library, it asks me for an expression in the following format.
public UsbHidDevice Device; string vidandpid =
"\\hid#vid_0000&pid_0000&mi_00#a&0&000000000&1&0000#{eeof37d0-1963-47k4-aa41-74476db7uf49}";
Device = new UsbHidDevice(vidandpid);
I adapted this format for my own HID device, but without success. How should this string expression be? I am open to your views. Thank you from now.
How to find USB HID DevicePath?
I gave up on USBHID library and found solution with HidLibrary library. As far as I understand, HidLibrary falls short on some issues.
Here I am sharing the C# code that I linked with HidLibrary. Thank you for all the replies.
device = HidDevices.Enumerate(VendorID, ProductID).FirstOrDefault();
if (device != null)
{
device.OpenDevice();
device.Inserted += DeviceAttachedHandler;
device.Removed += DeviceRemovedHandler;
device.MonitorDeviceEvents = true;
device.ReadReport(myfunction);
}
else { RtBox_Feedback.AppendText("NOT DEVICE!"); }
\\hid#vid_0000&pid_0000&mi_00#a&0&000000000&1&0000#{eeof37d0-1963-47k4-aa41-74476db7uf49} - is a device interface for the {eeof37d0-1963-47k4-aa41-74476db7uf49} interface. It is almost always unique and semi-random for each device. It also may change if yore put device in another USB slot. This string may be used as path to open this "file" with CreateFile Win32 API and talk with device by means of interface-specific IOCTLs. More info here.
For HID devices Windows have another device interface GUID - GUID_DEVINTERFACE_HID - {4D1E55B2-F16F-11CF-88CB-001111000030}
You can use CM_Get_Device_Interface_ListW or SetupDiGetClassDevs/SetupDiEnumDeviceInterfaces/SetupDiGetDeviceInterfaceDetail APIs to enumerate device interfaces by interface GUID or by device Instance ID.
Mentioned "USBHid library in C#" may already have code that doing such enumeration and filtering by HID deivce VID/PID but I cannot say it for sure since you haven't added link to the code of this library. :)

Detect barcode scanner with PointOfService on Windows 10

I would like to use a barcode scanner with Windows 10 (Build 15063) via the Windows.Devices.PointOfService namespace. The scanner is a Datalogic Quickscan QD2430 and I tried with all RS-232 and Keyboard mode.
I used the official sample application https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/BarcodeScanner with no luck. It can detect a device but it's definitely the in-built webcam (HP laptop).
I tried to modify the source, the DeviceHelpers's GetFirstDeviceAsync function https://github.com/Microsoft/Windows-universal-samples/blob/master/SharedContent/cs/DeviceHelpers.cs.
The DeviceInformation.FindAllAsync also returns only the camera's info as result.
string selector = BarcodeScanner.GetDeviceSelector(PosConnectionTypes.All);
DeviceInformation.FindAllAsync(selector);
It returns nothing.
DeviceInformation.FindAllAsync(DeviceClass.ImageScanner);
It returns every connected and I think the previously connected but currently offline devices too. I tried to filter the scanner by name. There was a lot filterd result too, but the convertAsync function returned null for all excepts one, it thrown an Exception "A device attached to the system is not functioning. (Exception from HRESULT: 0x8007001F)".
DeviceInformationCollection infos = await DeviceInformation.FindAllAsync(DeviceClass.All);
foreach(DeviceInformation info in infos)
{
if (info.Name.ToUpper().Contains("BARCODE"))
{
T scanner = await convertAsync(info.Id);
if (scanner != null)
{
return scanner;
}
}
}
Datalogic Quickscan QD2430 is not in the list of devices supported by Windows.Devices.PointOfService.
Ask Datalogic to provide a device driver that supports Windows.Devices.PointOfService, or change the scanner to the one described in the supported list.
Alternatively, create your own device driver according to the Point of Service (POS) of Windows Driver Kit.

Get MAC address of device

I'm writing a Windows Phone 8.1 Application that discovers nearby Bluetooth Low Energy devices.
foreach (DeviceInformation device in devices)
{
BluetoothLEDevice bleDevice = await BluetoothLEDevice.FromIdAsync(device.Id);
}
Everything works fine, but the bleDevice.BluetoothAddress property contains a ulong type, while I need a string type, formatted like a Mac Address.
Example:
bleDevice.BluetoothAddress: 254682828386071 (ulong)
Desired Mac Address: D1:B4:EC:14:29:A8 (string) (that's an example of how I need it, not the actual Mac Address of the device)
Is there a way to convert the long to a Mac Address? Or is there another way to directly discover the Mac Address without conversions? I know there's a tool named In The HAnd - 32feet that could help me, but as of now Windows Phone 8.1 is not supported.
There are numerous topics you can find through Google and here on StackOverflow. Anyway, here's one way to do it:
ulong input = 254682828386071;
var tempMac = input.ToString("X");
//tempMac is now 'E7A1F7842F17'
var regex = "(.{2})(.{2})(.{2})(.{2})(.{2})(.{2})";
var replace = "$1:$2:$3:$4:$5:$6";
var macAddress = Regex.Replace(tempMac, regex, replace);
//macAddress is now 'E7:A1:F7:84:2F:17'

How can I check for 3G, wifi, EDGE, Cellular Networks in Windows Phone 7?

How can I check for 3G, wifi, EDGE, Cellular Networks in Windows Phone 7 using C#?
If you can use the Mango (7.1) SDK, and if your scenario involves using sockets, there's a trivial way to get the NetworkInterfaceType/SubType information for the connection you just made:
NetworkInterfaceInfo netInterfaceInfo = socket.GetCurrentNetworkInterface();
var type = netInterfaceInfo.InterfaceType;
var subType = netInterfaceInfo.InterfaceSubtype;
No need to use the NetworkInterface.NetworkInterfaceType property (which notoriously takes up to 30sec to return); no need to trigger a hostname resolution just to determine the network type; no need to listen to network change events.
Of course, this works best in conjunction with DeviceNetworkInformation.IsNetworkAvailable or NetworkInterface.GetIsNetworkAvailable() - those calls return immediately whether you're on a network or not. If you are, you connect the socket first and ask questions when it's connected :-)
A final note: beware of Mango's DeviceNetworkInformation.IsWiFiEnabled - I thought it would return whether I was on a wifi network, but instead it returns whether wifi is turned on or off in the phone settings... not super useful.
take a look at phoney tools, they have class PhoneNetworking for this:
http://wildermuth.com/2011/03/05/Phoney_Tools_Updated_(WP7_Open_Source_Library)
its open source you can check the source code
As of the Mango release (beta 2 and RC), this information is now available but it requires you to actually make a connection, presumably because it doesn't check until something needs it.
You can either perform a DNS resolution (see below) or use the GetCurrentNetworkInterface WebRequest extension method, which will throw an InvalidOperationException if the request hasn't connected yet.
There are also some events to follow in the Microsoft.Phone.Net.NetworkInformation namespace, but I wouldn't be surprised if those events didn't fire until a connection was made.
Interestingly, it seems you can also prefer or require on a per-connection basis using the SetNetworkPreference and SetNetworkRequirement extension methods, though it doesn't go beyond wifi vs cellular.
DeviceNetworkInformation.ResolveHostNameAsync(
new DnsEndPoint("microsoft.com", 80),
new NameResolutionCallback(nrr =>
{
var info = nrr.NetworkInterface;
var type = info.InterfaceType;
var subType = info.InterfaceSubtype;
}), null);
The enumeration values for NetworkInterfaceType (wifi/gsm) and NetworkInterfaceSubType (edge/3g) are available on MSDN.
Without socket:
var currentList = new NetworkInterfaceList().Where(i => i.InterfaceState == ConnectState.Connected).Select(i => i.InterfaceSubtype);
if (currentList.Contains(NetworkInterfaceSubType.WiFi))
Debug.WriteLine("WiFi");
if (currentList.Intersect(new NetworkInterfaceSubType[]
{
NetworkInterfaceSubType.Cellular_EVDO,
NetworkInterfaceSubType.Cellular_3G,
NetworkInterfaceSubType.Cellular_HSPA,
NetworkInterfaceSubType.Cellular_EVDV,
}).Any())
Debug.WriteLine("3G");
if (currentList.Intersect(new NetworkInterfaceSubType[]
{
NetworkInterfaceSubType.Cellular_GPRS,
NetworkInterfaceSubType.Cellular_1XRTT,
NetworkInterfaceSubType.Cellular_EDGE,
}).Any())
Debug.WriteLine("2G");
Unfortunately the api's don't provide very limited information about the kind of network connection you have. You can tell if you are on 3G, Cellular or Ethernet (i.e. USB connection to PC) but that is all the information you get.
Check out this for more info Better way to check for an network connection on WP7
To get Network Data for windows phone app i.e it is connected to a ethernet, wifi or cellular network also getting the subtype i.e 2G or 3g network following program can be used.
Using Microsoft.Phone.Net.NetworkInformation
Using Microsoft.Phone.net.NetworkInfromation
var Newlist = new NetworkInterfaceList();
foreach (NetworkInterfaceInfo x in Newlist)
{
if(x.InterfaceState==ConnectState.Connected)
{
if(x.InterfaceSubtype.Equals(NetworkInterfaceSubType.WiFi))
{
Interface = x.InterfaceType.ToString();
SubInterface = x.InterfaceSubtype.ToString();
break;
}
else if(x.InterfaceSubtype.Equals(NetworkInterfaceSubType.Cellular_EVDO) || x.InterfaceSubtype.Equals(NetworkInterfaceSubType.Cellular_3G) || x.InterfaceSubtype.Equals(NetworkInterfaceSubType.Cellular_HSPA) || x.InterfaceSubtype.Equals(NetworkInterfaceSubType.Cellular_EVDV))
{
Interface = x.InterfaceType.ToString();
SubInterface= “3G Network”;
break;
}
else if(x.InterfaceSubtype.Equals(NetworkInterfaceSubType.Cellular_GPRS) || x.InterfaceSubtype.Equals(NetworkInterfaceSubType.Cellular_1XRTT) || x.InterfaceSubtype.Equals(NetworkInterfaceSubType.Cellular_EDGE))
{
Interface = x.InterfaceType.ToString();
SubInterface= “2G Network”;
break;
}
else
{
Interface = “Ethernet”;
SubInterface= “Unknown” ;
break;
}
}
else
{
Interface=”not connected”;
SubInterface=”unknown”;
}
Here, Interface and SubInterface gives the network information.

Categories

Resources