Universal Application + Bluetooth + SPP - c#

I am currently trying to build a library for using the Serial Port Profile (SPP) on an Universal App.
As far as I have discovered, SPP runs on top of RFCOMM. The basics for RFCOMM are outlined in the MSDN which is fine. I was also able to "find" my device and "connect" to it. I was also able to create a StreamReader and StreamWriter for the RFCOMM.
Now the troubles arise. I understand that RFCOMM provides some kind of channels for various features/tasks, one of them being probably SPP (I know the device features SPP and it even works when done via a "normal" serial connection).
I would like to know if there was an example which bytes I have to send through that channel to get a single byte output on the other side. Is there some kind of connection setup required (bi-directional exchange)? Are there examples for these data packets, what are their names and is there a specific specification for it. I think I would be happy even with some of the correct terms to search for.

Alright, what I assumed was basically wrong. Here is the minimalistic code for a very simple (no error handling, no tasks, ...) communication.
This goes into the Package.appxmanifest:
<Capabilities>
<m2:DeviceCapability Name="bluetooth.rfcomm">
<m2:Device Id="any">
<m2:Function Type="name:serialPort" />
</m2:Device>
</m2:DeviceCapability>
</Capabilities>
And this to a method of your choice (make sure your Bluetooth device has been paired, my device has the name "HC-06").
// Find the device
var bluetoothDevicesSpp = await DeviceInformation.FindAllAsync(RfcommDeviceService.GetDeviceSelector(RfcommServiceId.SerialPort));
var bluetoothDeviceHc06 = bluetoothDevicesSpp.SingleOrDefault(d => d.Name == "HC-06");
var serviceRfcomm = await RfcommDeviceService.FromIdAsync(bluetoothDeviceHc06.Id);
StreamSocket socket = new StreamSocket();
await socket.ConnectAsync(serviceRfcomm.ConnectionHostName, serviceRfcomm.ConnectionServiceName, SocketProtectionLevel.BluetoothEncryptionAllowNullAuthentication);
DataWriter writer = new DataWriter(socket.OutputStream);
DataReader reader = new DataReader(socket.InputStream);
To read, use this:
await reader.LoadAsync(1);
byte b = reader.ReadByte();
Debug.WriteLine((char)b);
To write, use this:
writer.WriteString("MaM\r\n");
writer.StoreAsync();
The bytes will be transferred as they are, no additional protocol or similar is necessary. Enjoy.

Related

Read data via bluetooth using c#

I am using Lecia Disto e7100i which basically measures distance and area using laser. This device has bluetooth and can be paired with windows.
I am trying to develop an wpf app that reads the mesaured data using c#
There is no sdk that comes along with the device.
I have tried to use 32feet.Net but since there is no proper documentation I don't know where to start.
Is there any way that I can do to solve my problem?
This is not a full response, instead its more of a guideline on how to resolve your issue:
Pair the device with your Computer
Run the included software that displays the data somehow
Use WireShark to analyze the traffic
see if it is a standard protocol type or something custom
understand the protocol and reimplement it using c# and BluetoothSockets
To get started, you can try:
var client = new BluetoothClient();
// Select the bluetooth device
var dlg = new SelectBluetoothDeviceDialog();
DialogResult result = dlg.ShowDialog(this);
if (result != DialogResult.OK)
{
return;
}
BluetoothDeviceInfo device = dlg.SelectedDevice;
BluetoothAddress addr = device.DeviceAddress;
Console.WriteLine(device.DeviceName);
BluetoothSecurity.PairRequest(addr, "PIN"); // set the pin here or take user input
device.SetServiceState(BluetoothService.HumanInterfaceDevice, true);
Thread.Sleep(100); // Precautionary
if (device.InstalledServices.Length == 0)
{
// handle appropriately
}
client.Connect(addr, BluetoothService.HumanInterfaceDevice);
Also make sure that
Device appears in "Bluetooth devices" in the "Control panel".
Device is HID or change code accordingly.
Hope it helps. Cheers!
Try this demo project, and the following articles after that one.
Try to follow this tutorial
Here you can see a direct answer by the mantainer of 32feet, with which you can get in touch
Check also this answer

C# wpf how to stream webcam to ip address (possibly with Vlc)

I need to stream a webcam to an ip address.
After days of googling I decided that the easiest way was to embed Vlc.
That said I am also still open to other solutions.
Step1 - OK!: I can see my webcam in a form by using that code:
vlcPlayer.MediaPlayer.VlcLibDirectory = new DirectoryInfo(#"c:\Program Files (x86)\VideoLAN\VLC\");
vlcPlayer.MediaPlayer.EndInit();
vlcPlayer.MediaPlayer.Play(new Uri(#"dshow://");
Step2 - OK!: Now trying to make a step forward and using this tutorial I can send a video locally 127.0.0.1:5004 using 2 instances of Vlc: one to transmit and one to receive.
Step 3 - NOT OK: it should seem simple to configure vlc for changing the source from file to webcam and to transmit it via ip.
So what I do is to operate as before only changing the source:
1. Menu "Media" --> Stream. That opens the "open media" window.
Here I click the tab capture device --> video device name --> I choose "integrated webcam"
Then all the rest is as before. But nothing happens. The receiver is black with nothing inside. Also If I try to save the flow from the receiver I only get a few bytes.
The afore mentioned settings for the transmitter are the following:
Capture device tab --> integrated webcam. Then the stream button --> the window opens correctly with dshow:\ --> next --> new destination RTP,MPEG transport stream ---> add button --> address = 127.0.0.1 port = 5004 StreamNAme=test
So the strange is that when I stream a file with whatever name from the transmitter, it immediately is recognized by the receiver. Instead try as I might, nothing happens when the webcam is the source.
That being said the problem above is not crucial to the solution.
What I care for is not how to use vlc stand alone but how to use it from my wpf application in order to send the webcam stream.
Thanks for any help
Patrick
I believe this sample should help you achieve your goal:
static void Main()
{
var currentDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
// Default installation path of VideoLAN.LibVLC.Windows
var libDirectory =
new DirectoryInfo(Path.Combine(currentDirectory, "libvlc", IntPtr.Size == 4 ? "win-x86" : "win-x64"));
using (var mediaPlayer = new Vlc.DotNet.Core.VlcMediaPlayer(libDirectory))
{
var mediaOptions = new[]
{
":sout=#rtp{sdp=rtsp://127.0.0.1:554/}",
":sout-keep"
};
mediaPlayer.SetMedia(new Uri("http://hls1.addictradio.net/addictrock_aac_hls/playlist.m3u8"),
mediaOptions);
mediaPlayer.Play();
Console.WriteLine("Streaming on rtsp://127.0.0.1:554/");
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
}
You will need 2 nuget packages: Vlc.DotNet (C# wrapper) and VideoLAN.LibVLC.Windows (LibVLC library for Windows).

Which bluetooth functions should I use in my UWP app to read in characterstics from my BLE Device

I am trying to read temperature characterstic from my BLE device(Blue gecko bgm13p22)
I have tried in the C# Windows BLE code
this
GattReadResult result = await selectedCharacteristic.ReadValueAsync(BluetoothCacheMode.Uncached);//ReadValueAsync-->Performs a Characteristic Value read from the value cache maintained by Windows or retrieve from Windows
and this
GattReadResult result = await selectedCharacteristic.ReadValueAsync();//ReadValueAsync-->Performs a Characteristic Value read from the value cache maintained by Windows or retrieve from Windows
and in package.appxmanifest
I added this
<DeviceCapability Name="bluetooth.genericAttributeProfile">
<Device Id="any">
<Function Type="name:healthThermometer" />
</Device>
</DeviceCapability>
</Capabilities>
to read temperature value from BLE device but it still cannot read
Any help is appreciated
The Blue Gecko uses the Bluetooth SIG adopted Health Thermometer service.
The documentation of the SIG states the following:
Source: https://www.bluetooth.com/specifications/gatt
Once configured by the Collector, a Thermometer will typically remain
powered off between uses and will only advertise and allow a Collector
to connect when the Thermometer has data to send. In this scenario,
the Thermometer will enter a GAP Connectable Mode and start
advertising when it has data to send to the Collector. The Collector
will typically execute a GAP connection establishment procedure such
that it is scanning for the Thermometer using a white list. When a
connection is established, the Thermometer sends one or more
indications or notifications to the Collector. When the data transfer
is complete the Thermometer typically terminates the connection.
Where collector is your app, and thermometer your Blue Gecko .
For UWP this means: Listen to the device with the AdvertisementWatcher and get the device.
Get the service and connect.
Get the characteristic and set the ClientCharacteristicConfigurationDescriptor to notify.
Implement a Characteristic-value changed method.
This means that the thermometer values are in the notification or you must read the values after the notification has arrived.
If there is no notification there is nothing to read.
I made an example on Github explaining the advertisementwatcher and subscribing tor notifications:https://github.com/GrooverFromHolland/SimpleBleExample_by_Devicename
The example is written for visual studio 2017, but you can read the most important methods and getting an idea
by opening the MainPage.xaml.cs on Github.
You read the temperature in a byte-array, containg a flagsfield(8bits), temperature(4 bytes) and optional timestamp(7 bytes), temptype(8bits)
from https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.temperature_measurement.xml
Your appxmanifest must contain:
<Capabilities>
<Capability Name="internetClient" />
<DeviceCapability Name="bluetooth" />
</Capabilities>
In my example add these lines after:
characteristicFoundMilis = stopwatch.ElapsedMilliseconds;
Debug.WriteLine("Characteristic found in " +
(characteristicFoundMilis - serviceFoundMilis) + " ms");
Lines to add:
GattCharacteristicProperties properties = charac.CharacteristicProperties;
if (properties.HasFlag(GattCharacteristicProperties.Read))
{
Debug.WriteLine("This characteristic supports reading from it.");
}
if (properties.HasFlag(GattCharacteristicProperties.Write))
{
Debug.WriteLine("This characteristic supports writing to it.");
}
if (properties.HasFlag(GattCharacteristicProperties.Notify))
{
Debug.WriteLine("This characteristic supports subscribing to notifications.");
}
if (properties.HasFlag(GattCharacteristicProperties.Indicate))
{
Debug.WriteLine("This characteristic supports subscribing to Indication");
}

Can't connect the Hololens to a Bluetooth Low Energy device

For a project I'm working on, I need to read data from a BluetoothLE module (HM-10). I need to read and use this data from a Unity-application. To connect and read data I'm building a plugin for Unity using Visual Studio 2017. I can get a list of BluetoothLE devices using:
string[] requestedProperties = { "System.Devices.Aep.DeviceAddress", "System.Devices.Aep.IsConnected" };
deviceWatcher =
DeviceInformation.CreateWatcher(
BluetoothLEDevice.GetDeviceSelectorFromPairingState(false),
requestedProperties,
DeviceInformationKind.AssociationEndpoint);
Connecting to a device seems to work as well. I use:
BluetoothLEDevice btDevice = await BluetoothLEDevice.FromIdAsync(device.Id);
Next, I want to read the data that this device is sending. I understand I need to collect the services and characteristics next before I can read this data. But for some reason I can't await the services. I get an error using this:var gattservices = await btDevice.GetGattServicesAsync();
The error reads:
Unable to cast object of type 'Windows.Devices.Bluetooth.BluetoothLEDevice' to type 'Windows.Devices.Bluetooth.IBluetoothLEDevice3'
Am I using the wrong methods to get my results?
Any help will be appreciated!
I have finally found how I can get all services and the characteristics per service. By creating a GattDevice I can get the services with GattDevice.GattServices.
When I found the correct GattDeviceService, I can get the Characteristics with:
GattService s = new GattService(GattDeviceService)
GattCharacteristic.GetCharacteristics(s)

How to read bluetooth data from Windows CE to bluetooth Device

I have a Windows Mobile/CE 6 device that needs to read RFID data from a bluetooth RFID wand in a custom .NET 3.5 CF application. Tried many different solutions and trying to make 32Feet's InTheHand bluetooth library work. I can get the device to pair and connect just fine, but when I send commands to the unit and try to read from the stream, it always results in an exception of "Operation time-out". Any tips or help is much appreciated.
var endpoint = new BluetoothEndPoint(device.DeviceAddress, BluetoothService.SerialPort);
var client = new BluetoothClient();
client.Connect(endpoint); // Connects just fine!
var stream = client.GetStream();
using (var sw = new StreamWriter(stream))
{
sw.Write("l");
}
if (stream.CanRead) // Always False
{
using (var sr = new StreamReader(stream))
{
var exi = sr.Peek();
var p = sr.ReadToEnd();
var pp = sr.ReadLine();
}
}
1.
I would first check, if there is any communication possible using the standard tools. Possibly the RFID does not work as you think.
Connect the BT RFID using the BT applet and add a new outgoing Serial Port also in the BT applet. Then use PocketPuTTY or another serial terminal tool to communicate with the RFID module. If that works, you can go on and start using 32feet.
2.
Will the RFID answer on a simple char or does it need a CR/LF on received data?
3.
Test the communication from a PC following 1. usning a Hyperterminal like app.

Categories