Giter Site home page Giter Site logo

dotnet-bluez's Introduction

DotNet-BlueZ

A quick and dirty library for BlueZ's D-Bus APIs. Primary focus is Bluetooth Low Energy.

DotNetBlueZ NuGet Badge

Uses Tmds.DBus to access D-Bus. Tmds.DBus.Tool was used to generate the D-Bus object interfaces. D-Bus is the preferred interface for Bluetooth in userspace. The Doing Bluetooth Low Energy on Linux presentation says "Use D-Bus API (documentation in doc/) whenever possible".

Requirements

  • Linux
  • A recent release of BlueZ. This package was tested with BlueZ 5.50. You can check which version you're using with bluetoothd -v.

Installation

dotnet add package HashtagChris.DotNetBlueZ

Events

C# events are available for several properties. Events are useful for properly handling disconnects and reconnects.

Usage

Get a Bluetooth adapter

using HashtagChris.DotNetBlueZ;
...

IAdapter1 adapter = (await BlueZManager.GetAdaptersAsync()).FirstOrDefault();

or get a particular adapter:

IAdapter1 adapter = await BlueZManager.GetAdapterAsync(adapterName: "hci0");

Scan for Bluetooth devices

adapter.DeviceFound += adapter_DeviceFoundAsync;

await adapter.StartDiscoveryAsync();
...
await adapter.StopDiscoveryAsync();

Get Devices

adapter.DeviceFound (above) will be called immediately for existing devices, and as new devices show up during scanning; eventArgs.IsStateChange can be used to distinguish between existing and new devices. Alternatively you can can use GetDevicesAsync:

IReadOnlyList<Device> devices = await adapter.GetDevicesAsync();

Connect to a Device

device.Connected += device_ConnectedAsync;
device.Disconnected += device_DisconnectedAsync;
device.ServicesResolved += device_ServicesResolvedAsync;

await device.ConnectAsync();

Alternatively you can wait for "Connected" and "ServicesResolved" to equal true:

TimeSpan timeout = TimeSpan.FromSeconds(15);

await device.ConnectAsync();
await device.WaitForPropertyValueAsync("Connected", value: true, timeout);
await device.WaitForPropertyValueAsync("ServicesResolved", value: true, timeout);

Retrieve a GATT Service and Characteristic

Prerequisite: You must be connected to a device and services must be resolved. You may need to pair with the device in order to use some services.

Example using GATT Device Information Service UUIDs.

string serviceUUID = "0000180a-0000-1000-8000-00805f9b34fb";
string characteristicUUID = "00002a24-0000-1000-8000-00805f9b34fb";

IGattService1 service = await device.GetServiceAsync(serviceUUID);
IGattCharacteristic1 characteristic = await service.GetCharacteristicAsync(characteristicUUID);

Read a GATT Characteristic value

byte[] value = await characteristic.ReadValueAsync(timeout);

string modelName = Encoding.UTF8.GetString(value);

Subscribe to GATT Characteristic Notifications

characteristic.Value += characteristic_Value;
...

private static async Task characteristic_Value(GattCharacteristic characteristic, GattCharacteristicValueEventArgs e)
{
  try
  {
    Console.WriteLine($"Characteristic value (hex): {BitConverter.ToString(e.Value)}");

    Console.WriteLine($"Characteristic value (UTF-8): \"{Encoding.UTF8.GetString(e.Value)}\"");
  }
  catch (Exception ex)
  {
    Console.Error.WriteLine(ex);
  }
}

Tips

It may be necessary to pair with a device for a GATT service to be visible or for reading GATT characteristics to work. To pair, one option is to run bluetoothctl (or sudo bluetoothctl) and then run default agent and agent on within bluetoothctl. Watch bluetoothctl for pairing requests.

See Ubuntu's Introduction to Pairing.

Contributing

See Contributing.

Reference

dotnet-bluez's People

Contributors

corentin-raoult avatar hashtagchris avatar springcard avatar yaakov-h avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dotnet-bluez's Issues

ConnectAsync() is blocking Task

'await device.ConnectAsync();
await device.WaitForPropertyValueAsync("Connected", value: true, timeout);'

Line 2 will never be invocked when device can't connect (because it is out of range, for example).
IN this case the BlueZ stack will throw an exception -> 'org.bluez.Error.Failed: Software caused connection abort', but does not respect the timeout sit in the second line.

Missing Services

Hi,

When running my application that uses this excellent on a standard Ubuntu linux box, I can see all 6 of my BLE services and the characteristics. I can also grab data from them.

When I run the same application on the Raspberry Pi, I can see only one service, and not the ones I need. I have added the 'pi' user to the lp and bluetooth groups.

I'm guessing 'dotnet run' might need to run with sudo but I'm not sure.

Any help is greatly appriciated.

Advertising

Is possible to add the possibility to start an advertising process?
Thanks!

set scan paramaters?

Hi @hashtagchris. it is possible to set the scan parmaters as defined

In BlueZ there is this struct:

https://github.com/pauloborges/bluez/blob/master/lib/hci.h#L1536

typedef struct {
uint8_t type;
uint16_t interval;
uint16_t window;
uint8_t own_bdaddr_type;
uint8_t filter;
} attribute ((packed)) le_set_scan_parameters_cp;

I'm using my program as a beacon scanner and i need a way to scan faster as currently i'm missing a lof of packets with the default scan interval and window on a Pi Zero. I don't need to connect to any devices and i'm looking for a way to set the program to scan as fast as possible, while gaining access to the Manufactuer Data in the Advertising Packet.

ConnectAsync() unhandled exception

I'm trying to connect to ELM327 bluetooth device (serial communication) but I'm getting an error..

Unhandled exception. Tmds.DBus.DBusException: org.bluez.Error.NotAvailable: Operation currently not available
   at Tmds.DBus.DBusConnection.CallMethodAsync(Message msg, Boolean checkConnected, Boolean checkReplyType)
   at Tmds.DBus.Connection.CallMethodAsync(Message message)
   at Tmds.DBus.CodeGen.DBusObjectProxy.SendMethodReturnReaderAsync(String iface, String member, Nullable`1 inSignature, MessageWriter writer)
   at *****.ConnectAsync() in ********************

I have also tried to use ConnectProfileAsync() method with proper service UUID - same exception.
Elevating privileges with sudo also doesn't help.
Equivalent test code in Python3 with PyBluez works without problems.

I'm using Linux Ubuntu 20.04 on VM with USB BT dongle and dotnet sdk 3.1.402.
My test source code looks like this:

IAdapter1 adapter = BlueZManager.GetAdaptersAsync().Result.FirstOrDefault();
IReadOnlyList<Device> devices = adapter.GetDevicesAsync().Result;
device = devices.Single(x => x.ObjectPath.ToString().EndsWith(macAddress.Replace(':', '_')));

TimeSpan timeout = TimeSpan.FromSeconds(15);
await device.ConnectAsync();
await device.WaitForPropertyValueAsync("Connected", value: true, timeout);
await device.WaitForPropertyValueAsync("ServicesResolved", value: true, timeout);

RPi3: working locally but not in Docker

Hello, your scan sample is working on my raspberry Pi perfectly, but not in a Docker container. I can detect the Bluetooth chip with adapter hci0 as seen on below screenshot (so I know I have enough privilege for the container to access the chip), but the cs program doesn't seem to find it (i'm running the app through a dockerfile, in an Azure IoT Edge context).
image

Even when I run GetAdaptersAsync(), with another error:
image

uname -a:
image

Dockerfile:
image

Launch script:
image

Thanks for your help!

RegisterAgent

Do you have a sample of how to use the AgentManager and Agent interfaces?

I can get the AgentManager interface but no matter how I call the RegisterAgentAsync, when I then search for my Agent it is not found.

Can't get Battery Service (180f)

Seems that there is an issue when gathering the services,
the service is available when query using device.GetUUIDsAsync()
but no through device.GetServiceAsync()
Using a GATT explorer I can confirm that the service is available without pairing.

GATT Server example request

Not an issue but a example request.

Would it be possible to give us an example on how to do a simple GATT server using this library? I've tried to match up some Python based D-Bus examples with what your library provides, but could not make any sense.

In the end I'd like to have some Xamarin app access data on a PI via BLE.

It shall be much appreciated.

Report all Advertisements

Does anyone have an idea how to listen to ALL advertisements from all devices, not just the first time it is discovered?

Lib excepts unexpectedly when retrieving adapter.GetDevicesAsync

Hi Guys,

First of all happy new-year and have a healthy and wonderful 2021!

Im using your library in a bluetooth implementation for a dedicated device (running on a raspberry) bluez version 5.50
I'm not supplying an eventhandler before calling Adapter.StartDiscoveryAsync() as I only use the GetDevicesAsync when I want to see devices.

When calling Adapter.GetDevicesAsync my application crashes after been running for a few days with the following exception
Hope someone can fix this!

Unhandled exception. Unhandled exception. Unhandled exception. Unhandled exception. Tmds.DBus.DBusException: org.freedesktop.DBus.Error.LimitsExceeded: Connection ":1.127" is not allowed to add more match rules (increase limits in configuration file if required; max_match_rules_per_connection=512)
at Tmds.DBus.DBusConnection.CallMethodAsync(Message msg, Boolean checkConnected, Boolean checkReplyType)
at Tmds.DBus.DBusConnection.WatchSignalAsync(ObjectPath path, String interface, String signalName, SignalHandler handler)
at Tmds.DBus.Connection.WatchSignalAsync(ObjectPath path, String interface, String signalName, SignalHandler handler)
at Tmds.DBus.CodeGen.DBusObjectProxy.WatchNonVoidSignalAsync[T](String iface, String member, Action1 error, Action1 action, ReadMethodDelegate1 readValue, Boolean isPropertiesChanged) at HashtagChris.DotNetBlueZ.Device.CreateAsync(IDevice1 proxy) at HashtagChris.DotNetBlueZ.Adapter.OnDeviceAdded(ValueTuple2 args)
at System.Threading.Tasks.Task.<>c.b__140_1(Object state)
at System.Threading.QueueUserWorkItemCallbackDefaultContext.Execute()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()Tmds.DBus.DBusException: org.freedesktop.DBus.Error.LimitsExceeded: Connection ":1.127" is not allowed to add more match rules (increase limits in configuration file if required; max_match_rules_per_connection=512)
at Tmds.DBus.DBusConnection.CallMethodAsync(Message msg, Boolean checkConnected, Boolean checkReplyType)
at Tmds.DBus.DBusConnection.WatchSignalAsync(ObjectPath path, String interface, String signalName, SignalHandler handler)
at Tmds.DBus.Connection.WatchSignalAsync(ObjectPath path, String interface, String signalName, SignalHandler handler)
at Tmds.DBus.CodeGen.DBusObjectProxy.WatchNonVoidSignalAsync[T](String iface, String member, Action1 error, Action1 action, ReadMethodDelegate1 readValue, Boolean isPropertiesChanged) at HashtagChris.DotNetBlueZ.Device.CreateAsync(IDevice1 proxy) at HashtagChris.DotNetBlueZ.Adapter.OnDeviceAdded(ValueTuple2 args)
at System.Threading.Tasks.Task.<>c.b__140_1(Object state)
at System.Threading.QueueUserWorkItemCallbackDefaultContext.Execute()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()

Aborted

SetDiscoveryFilterAsync

I want only discovery devices which offers me a specific service.
How can i use the SetDiscoveryFilterAsync method?

How to use the IBattery1 interface?

I see the IBattery1 interface is included in the library to deal with the point of Bluez hiding the battery characteristic, but is there any sample how we can best use it?

Subcribe characteristic

I try to Subcribe characteristic. But when the value changed, doesn't have any event raise from Library

Collaboration with dotnet/iot?

I saw an issue about BLE on the dotnet/iot repository, which made me search and find this repository.

The library looks really useful, and I think it could have a bigger audience and more contributors if there would be collaboration with the people in dotnet/iot. Have you considered this?

Subscribe to GATT Characteristic Notifications not found

Hello guys,

I need make a communication with a fat scale equipment in .Net core, so i need followings:

  • Write in one characterisct with person data (I beleave that its ok for me)
  • And whatch a characterisc with notify.

So, I can't get the notify value. I looked for samples, but I didn't find it.
I beleave that I'm doing anything wrong in code.

Look it:

          private async Task GetNotificationBodyFatScaleAsync()
          {
              var characteristic = await LoadCharacteristic(CHARACTERISTIC_MEASURE);
              characteristic.Value += BodyFatScaleDataReceivedAsync;
          }

        private async Task BodyFatScaleDataReceivedAsync(GattCharacteristic sender, GattCharacteristicValueEventArgs eventArgs)
        {
            try
            {
                Console.Out.WriteLine($"Received event from fat scale {eventArgs.Value}");
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex);
            }
        }

I'm following by this one https://github.com/hashtagchris/DotNet-BlueZ#subscribe-to-gatt-characteristic-notifications

Could you help me? Could you send me an example? Or are there any error in lib?

Set Notify and Indicate

I have manage to use DotnetBluez to connect to BLE peripheral device that has write and notify but could not get more data from peripheral that has write, notify and indicate only options. where can I set those setting? Thank you.

A problem of subscribing to characteristic value.

Hello, i tried to read my bluetooth device in Raspberry pi and i saw this message using subscribeToCharacteristic
message :
Error subscribing to characteristic value: Tmds.DBus.DBusException: org.bluez.Error.NotSupported: Operation is not supported
at Tmds.DBus.DBusConnection.CallMethodAsync(Message msg, Boolean checkConnected, Boolean checkReplyType)
at Tmds.DBus.Connection.CallMethodAsync(Message message)
at Tmds.DBus.CodeGen.DBusObjectProxy.SendMethodReturnReaderAsync(String iface, String member, Nullable`1 inSignature, MessageWriter writer)
at HashtagChris.DotNetBlueZ.GattCharacteristic.Subscribe()

and value = await characteristic.GetValueAsync(); length was 0, so i think characteristic.GetValueAsync(); wasn't working.
what should do i do?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.