UWP Unpaired Paired Bluetooth devices - bluetooth

I am developing in Visual Studio 2015 in C# for
a Raspberry PI 2 device running Windows IoT Core.
For my application I need to pair and unpair Bluetooth devices.
Can I get a list with paired / unpaired / all Bluetooth devices?
Like what can be seen on the Bluetooth page of the
built-in management website (http://[deviceip]:8080/bluetooth.htm)
I found a example (https://github.com/Microsoft/Windows-universal-samples),
but this is to much for me!
For now I just want to get a list with paired / unpaired Bluetooth devices

In order to find devices (Bluetooth or otherwise) you need a selector
which can be used to tell the DeviceWatcher the type of device to search for.
These selectors are basically strings identifying the type of device,
and the UWP framework provides some of them through methods on various classes.
//Gets all paired Bluetooth devices
var selector = BluetoothDevice.GetDeviceSelector();
//Gets all paired Bluetooth devices (same as above as far as I can tell)
var selector = BluetoothDevice.GetDeviceSelectorFromPairingState(true);
//Gets all unpaired Bluetooth devices
var selector = BluetoothDevice.GetDeviceSelectorFromPairingState(false);
From the samples on GitHub:
Currently Bluetooth APIs don't provide a selector to get ALL devices
that are both paired and non-paired. Typically you wouldn't need this
for common scenarios, but it's convenient to demonstrate the
various sample scenarios.
Why we wouldn't typically need this is beyond me, but they do provide
a selector which can be used to find both paired and unpaired devices:
var selector =
"System.Devices.Aep.ProtocolId:=\"{e0cbf06c-cd8b-4647-bb8a-263b43f0f974}\"";
Once you have this selector you need to create an instance
of the DeviceWatcher class using a method on the DeviceInformation class:
var deviceWatcher = DeviceInformation.CreateWatcher(selector,
null, DeviceInformationKind.AssociationEndpoint);
Finally you have to hook up the events so you get notified of changes:
deviceWatcher.Added += (s, i) => { //Handle the new device };
deviceWatcher.Updated += (s, i) => { //Handle the updated device };
deviceWatcher.Removed += (s, i) => { //Handle the removed device };
deviceWatcher.Completed += (s, a) => { s.Stop(); };
deviceWatcher.Stopped += (s, a) => { //Handle here };
Notice that in the Completed handler I stopped the DeviceWatcher
so it enters the Stopped state and can be started again.
Once you have the DeviceInformation you can pair as follows:
var pairingResult =
await i.Pairing.PairAsync(DevicePairingProtectionLevel.Encryption);
As for unpairing, you need to make sure your project targets Build 10586
or any later version in the project properties windows:
Then you'll be able to call UnPairAsync:
await i.Pairing.UnpairAsync();
Older builds do not support UnpairAsync.

Related

Web Bluetooth - Show extra info on scanning dialog

I'm trying to support web-bluetooth to connect to my devices and perform a simple task (such as playing LED).
However, the device information showed on the scanning dialog when calling navigator.bluetooth.requestDevice is not so clear. It only shows the device name and a random (?) hex string.
The problem here is all my devices have the same name (AWESOME_LED), thus it's not easy for the user to select the correct LED if all scanning items show the same device name info. As far as I know, we can not custom to add more info showing on the scanning dialog.
I come up with a new solution that is changing the device name to unique for each LED with the format AWESOME_LED + [uniqueid] e.g AWESOME_LED1, AWESOME_LED2, AWESOME_LED3 so that the user can distinguish one from the others.
My question are:
Is there any alternative solution without making the device name unique?
If not, is there any problem / rejection / limitation from Apple or Google for my current app on App Store / Google Play by not using the same device name for all devices? I have been investigating it at Apple forums / Accessory Design Guidelines and looks like there are no problems, just to make sure if anyone has faced trouble from Apple / Google.
Thanks for your help.
Scanning dialog
My question are:
Is there any alternative solution without making the device name unique?
The browser prompt is not customisable yet. One solution you highlighted already is to make your LED device name unique. If you're able to control the device, why not having one AWESOME_DEVICE name and a GATT characteristic you can write to that controls individual LED colors. Maybe something like:
const device = await navigator.bluetooth.requestDevice({
filters: [{ name: "AWESOME_DEVICE" }],
});
const server = await device.gatt.connect();
const service = await server.getPrimaryService(0x1234); // Your service UUID
const characteristic = await service.getCharacteristic(0x5678); // Your characteristic UUID
// Set LED #1 to red color.
await characteristic.writeValue(
new Uint8Array(/*ledIndex=*/ 1, /*r=*/ 255, /*g=*/ 0, /*b=*/ 0)
);
If not, is there any problem / rejection / limitation from Apple or Google for my current app on App Store / Google Play by not using the
same device name for all devices? I have been investigating it at
[Apple forums][1] / [Accessory Design Guidelines][2] and looks like
there are no problems, just to make sure if anyone has faced trouble
from Apple / Google.
None that I'm aware of.

How do you detect whether your Mixed Reality app is running on HoloLens 1, HoloLens 2 or an immersive headset?

Mixed Reality apps can soon run on three kinds of devices: HoloLens 1, Hololens 2 and Immersive (VR) headsets. Some behavior will likely be different depending on the type of device you run the app on. How can I ask the SDK what kind of device my app is running currently on?
If you are using MRTK (I noticed you might based on your tag), then the best way to do this is by using platform capabilities utility, since that will work as new devices come out, and across platforms. For example, instead of checking "am on on HoloLens 2" you can check "does my device support articulated hands?". That will then work on other platforms that support articulated hands. For an example, chekc out MixedRealityToolkit.Examples/Demos/Utilities/Scenes/MixedRealityCapabilityDemo.unity in MRTK examples.
If you need a temporary solution for now to differentiate WMR from HL1 from HL2, you can use the following code. Note it's windows-only:
using Windows.Security.ExchangeActiveSyncProvisioning;
EasClientDeviceInformation CurrentInfo = new EasClientDeviceInformation();
string sku = CurrentInfo.SystemSku;
HoloLens 1, HoloLens 2, and Immersive headsets should all return different strings.
Edit 6/5/2020:
It's also possible to check the runtime platform as follows:
if (Application.platform == RuntimePlatform.WSAPlayerARM)
{
// Running HoloLens 2, most likely.
}
HolographicDisplay.GetDefault().IsOpaque is true for Immersive VR headsets and false for AR devices like HoloLens.
For HoloLens you don't need to detect a precise device family. Instead you should check the feature support via Universal Contract Version like
bool checkUniversalApiContract(int contractNumber)
{
return winrt::Windows::Foundation::Metadata::ApiInformation::IsApiContractPresent(L"Windows.Foundation.UniversalApiContract", contractNumber);
}
bool supportsHandTracking = checkUniversalApiContract(8);
To check whether it is opaque (VR) or not (AR):
#if UNITY_2017_2_OR_NEWER
bool isOpaque = UnityEngine.XR.WSA.HolographicSettings.IsDisplayOpaque;
#else
bool isOpaque = UnityEngine.VR.VRDevice.isPresent;
#endif
To check whether it is HL1 or HL2, this is a simple solution, not requiring other dlls:
#if UNITY_WSA || UNITY_WSA_10_0
// Get vertical field of view in degrees
// HL1 == 17.5, HL2 == 29
bool isHL1 = (Camera.main.fieldOfView < 23f);
#endif

How can I connect a EV3 mindstorms via bluotooth to a unity game using unityscript?

I am making a race game in Unity with Unityscript and I made a steer with the lego mindstorms EV3 robot. I let te robot send information by bluetooth to the game, but I can't find how I can do that.
I already have the code for the bluetooth running and working a C#, but know I need to know how to translate it to unityscript.
I already tried to find it on google, but I only seem to get some software to hack the robot, but not to make code in unityscript for connecting the steer.
Under here stands the C# code:
// EV3: The EV3Messenger is used to communicate with the Lego EV3.
private EV3Messenger ev3Messenger;
// EV3: Create an EV3Messenger object which you can use to talk to the EV3.
ev3Messenger = new EV3Messenger();
// EV3: Connect to the EV3 serial port over Bluetooth.
// If the program 'hangs' on a call to ev3Messenger.Connect,
// then your EV3 is not paired with your PC yet/anymore.
// To pair: Remove the EV3 from the Windows Bluetooth device list and add it again.
ev3Messenger.Connect("COM3"); // Hardcoded serial port: put the serial port
// of the Bluetooth connection to your EV3 here!
}
/// <summary>
/// UnloadContent will be called once per game and is the place to unload
/// all content.
/// </summary>
protected override void UnloadContent()
{
// Unload any non ContentManager content here
// EV3: Disconnect
if (ev3Messenger.IsConnected)
{
ev3Messenger.Disconnect();
}
}
// EV3: send Brake message to mailbox with name "MakeNoise"
if (ev3Messenger.IsConnected)
{
ev3Messenger.SendMessage("MakeNoise", "Brake");
}
// Game can be controlled by both the arrow keys and the Steer, gas and brake paddle of the connected EV3
UpdatePaddlePositionUsingKeys();
UpdatePaddlePositionUsingEV3();
base.Update(gameTime);
}
///Steer update
private void UpdatePaddlePositionUsingEV3()
{
if (ev3Messenger.IsConnected)
{
// EV3: Receive a new command from mailbox "COMMAND" of the EV3
// and use it to change the direction of the paddle or to exit the game.
EV3Message message = ev3Messenger.ReadMessage();
if (message != null
&& message.MailboxTitle == "Command")
{
if (message.ValueAsText == "")
{
}
{
ev3Messenger.Disconnect();
Exit();
}
}
}
}
I hope that you know where I can find how I can do this or even help me further.
If you want the original code for a small pong game where I got my inspiration from, just comment it.
I hope you can help me.
Here are some useful links with documentation on the EV3 firmware :
Firmware Documentation
LMS2012 Documentation
HDK/SDK
In particular, you need to learn how to send direct commands and then use that to read and write bluetooth mailboxes.
For communicating with the COM port itself using javascript, just do a little searching. For example, I found this SO question which has quite a few different ideas.
As part of c4ev3, We open-sourced our EV3 uploader, which can also be used to send connection-agnostic commands to the device.
Here is how you would move the motors in Perl (Complete version):
use IPC::Open2;
print open2(\*EV3OUT, \*EV3IN, "ev3 tunnel") or die "couldn't find: %!";
print EV3IN "0900xxxx8000 00 A3 00 09 00\n";
print EV3IN "0C00xxxx8000 00 A4 00 09 50 A6 00 09\n";
This would probe for an EV3 accessible over USB, Bluetooth or WiFi and connect to it, then send the direct messages associated with turning the motors. For more information on the direct commands protocol check out LEGO's Communication Developer Manual and David Lechner's answer.
Alternatively, you can write a C program for the EV3 with c4ev3 and communicate with that. That way you got a nicer looking C-API you can use.

Connect to LightBlue peripheral mode

I used LightBlue app on an IOS Devices (iPhone 4s, iOS 6.1.3) in peripheral mode and another IOS device (iPhone 4s, iOS 6.1.3) in a central mode.
I'm using BTLE Transfer example code from Apple, it's working properly on these two devices. However, It does not work on LightBlue. As I just want to develop a simple app that read data from Blood Pressure Device, I've just changed the following service and characteristic UUID in Transfer.h file
define TRANSFER_SERVICE_UUID #"1810"
define TRANSFER_CHARACTERISTIC_UUID #"2A49" // just read value
My plan is going to clone a real device structure on LightBlue and then develop a central app to connect with LightBlue peripheral (I think it then will work with real devices because I donot have any real device at the moment). I set a device as a peripheral and the second one will install modified app (from apple sample) as a central or client.
The following delegate method provided by Apple:
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
// Reject any where the value is above reasonable range
if (RSSI.integerValue > -15) {
return;
}
// Reject if the signal strength is too low to be close enough (Close is around -22dB)
if (RSSI.integerValue < -35) {
return;
}
NSLog(#"Discovered %# at %#", peripheral.name, RSSI);
// Ok, it's in range - have we already seen it?
if (self.discoveredPeripheral != peripheral) {
// Save a local copy of the peripheral, so CoreBluetooth doesn't get rid of it
self.discoveredPeripheral = peripheral;
// And connect
NSLog(#"Connecting to peripheral %#", peripheral);
[self.centralManager connectPeripheral:peripheral options:nil];
self.connectingPeripheral=peripheral; // this line of code I have added as recommended from a member
}
}
And the problem is, this delegate method have been fired and log panel display "Discovered LightBlue at -32".It likely cannot connect to the Lightblue peripheral as I cannot see the output of the line of code NSLog(#"Connecting to peripheral %#", peripheral);
All suggestion are welcome and highly appreciated.

How can I select an audio output device in directshow

I was wondering how I can select the output device for audio in directshow. I am able to get available audio output devices in directshow. But how can I make one of these to be audio output device. Its always going for the default audio device. I want to be able to output audio on my choice of device. I have been struggling through google but couldn't find anything useful. All I could get was this link but it doesn't really solve my problem.
Any help will be really helpful for me.
First off, if you're not using DirectShow .NET (DirectShowLib), get that here: It serves as a (very complete) interface between unmanaged DirectShow and C#
What follows is a pretty simple example of how to play an audio file, to the desired audio device
using DirectShowLib;
private IGraphBuilder m_objFilterGraph = null;
private IBasicAudio m_objBasicAudio = null;
private IMediaControl m_objMediaControl = null;
private void playAudioToDevice(string fName, int devIndex)
{
object source = null;
DsDevice[] devices;
devices = DsDevice.GetDevicesOfCat(FilterCategory.AudioRendererCategory);
DsDevice device = (DsDevice)devices[devIndex];
Guid iid = typeof(IBaseFilter).GUID;
device.Mon.BindToObject(null, null, ref iid, out source);
m_objFilterGraph = (IGraphBuilder)new FilterGraph();
m_objFilterGraph.AddFilter((IBaseFilter)source, "Audio Render");
m_objFilterGraph.RenderFile(fName, "");
m_objBasicAudio = m_objFilterGraph as IBasicAudio;
m_objMediaControl = m_objFilterGraph as IMediaControl;
m_objMediaControl.Run();
}
It is up to user to manage audio devices and choose a primary device (such as via Control Panel applet). You can find ways to switch devices programmatically in Windows XP, however in Vista+ it is impossible without interactive user action by design.
See also Larry's answer here: How to change default sound playback device programmatically?
UPDATE: The mentioned above refers to modifying system configuration trying to alter default audio output device. An application is however not limited to default device only. Instead, it can enumerate available devices (see Using the System Device Enumerator + CLSID_AudioRendererCategory) and then create an instance of renderer for specific device with BindToObject call. From there on, it is a regular filter, just bound internally to device of interest.

Resources