powered-up
powered-up copied to clipboard
BlueZ Bluetooth Stack
#64 non-breaking
still todo:
- [ ] more testing with more devices and examples
- [ ] test with multiple hubs at the same time
- [ ] set samples back to winrt bluetooth
- [X] ~wait for new Tmds.DBus dependency version (new version has some important-ish changes)~
- [X] ~existing devices currently block discovery~
- [X] raspberry pi (4) ~issue: device disconnects on notify enable~ use bluez-firmware package version 1.2-4+rpt8
Any suspicion, when is this missing TMDS update incoming?
Any suspicion, when is this missing TMDS update incoming?
It was released today :)
But during testing I found another issue. I've been developing on my laptop with Linux and everything now works smoothly. Today I also tested the same code on the raspberry pi (4), and the Technic Hub that i'm using for testing disconnects if I enable notifications on the characteristic. It is that specific call to StartNotifyAsync that will make the device disconnect instantly. Now I found similar-ish reports of this issue in several places, some of them in the python lib issues (https://github.com/virantha/bricknil/issues/21) but that's always kind of difficult to determine if their problems originate from their libs/lang use or if it's actually related One user on the raspberry pi forums has a remarkably similar experience: https://www.raspberrypi.org/forums/viewtopic.php?t=287467
I suspect this is an issue in the raspberry pi bluetooth firmware, which would kind of suck.
I did some more testing on the raspberry pi, after stumbling across this issue: https://github.com/RPi-Distro/bluez-firmware/issues/6
It's not exactly the same issue I am facing, but downgrading the bluetooth firmware on the pi did work. It seems to be very reliable when connecting to the device (albeit a bit slow). I'll do more testing maybe this weekend or next week. Hopefully the new firmware for the pi's bluetooth stack will come soon and everything + my code will be stable.
Some good news at last, the bluetooth firmware for the raspberry pi was updated twice since my last comment. I updated the firmware to the latest released version (1.2-4+rpt8) today and everything seems to work, no sudden disconnects. I'm really happy with this. I'll do some more testing and update the PR against the latest master if everything works
@justxi FYI
@tthiery Thanks.
how can I get this pull request in my fork, so I can play with it. I am really interested in the BlueZ implementation because I use a raspberrypi 3B?
This is a pull request from an existing fork owned by @vuurbeving into the upstream repository (which this one is). So when you clone/fork this, you will not get it. However, the source of the pull request is here: https://github.com/vuurbeving/powered-up/tree/issue-64-bluez.
The most easiest solution: clone and pull that fork. However, with some git mastery, clone this, add a second git remote and pull the branch into your local clone. All possible ;)
Maybe you can support @vuurbeving a bit by testing it when you get it running.
I will try. Thanks
Hi @vuurbeving
I downloaded your branch and compiled it on my Raspberry PI 4 after merging it with the latest and greatest. Works for the examples and the CLI (previously reported as failed but debugging server closet to bedroom is not so smart with a wireless device 😀).
Small hints
- Update your source branch/repo to latest. Accept all incoming changes (the conflict above)
- Fix Cli/Examples/TestScript projects by adding BlueZ in the csproj AND the serviceCollection Add ops next to BlueGigaBLE !!!
- Fix the interface implementation (see WinRT variant for very simple shim variant)
- There is a new interface IPoweredUpBluetoothDeviceInfo to be used instead of
PoweredUpBluetoothDeviceInfo
with a default implementationPoweredUpBluetoothDeviceInfoWithMacAddress
- The existing property
ulong BluetoothAddress
is replaced withMacAddressAsUInt64
- See the WinRT implementation. It uses the same objects. Fix by replacing it. Beauty later.
- There is a new interface IPoweredUpBluetoothDeviceInfo to be used instead of
- ~~Compile on Windows regular, on Linux compile using
dotnet build -f net5.0 -p:TargetFrameworks=net5.0
(this suppresses errors due to the multi-targeting) (or await #179)~~ - Run on Linux using
./bin/Debug/net5.0/SharpBrick.PoweredUp.Examples --EnableTrace true --BluetoothAdapter BlueZ
I could create a PR on your PR but that is a bit crazy ;) ... UPDATE: See next comment
This is changes as part of step (2)
commit 016dff317a392ae27e6837679d2d40a32dc38567
Merge: 6febc05 6e4e3dd
Author:
Date: Sat May 8 21:11:01 2021 +0100
Merge branch 'master' into issue-64-bluez
diff --cc examples/SharpBrick.PoweredUp.Examples/SharpBrick.PoweredUp.Examples.csproj
index fc99d6d,33bb82f..a1626a1
--- a/examples/SharpBrick.PoweredUp.Examples/SharpBrick.PoweredUp.Examples.csproj
+++ b/examples/SharpBrick.PoweredUp.Examples/SharpBrick.PoweredUp.Examples.csproj
@@@ -8,15 -8,23 +8,24 @@@
<ItemGroup>
<ProjectReference Include="..\..\src\SharpBrick.PoweredUp\SharpBrick.PoweredUp.csproj" />
- <ProjectReference Include="..\..\src\SharpBrick.PoweredUp.WinRT\SharpBrick.PoweredUp.WinRT.csproj" />
+ </ItemGroup>
+
+ <ItemGroup Condition=" '$(TargetFramework)' == 'net5.0' ">
+ <ProjectReference Include="..\..\src\SharpBrick.PoweredUp.BlueGigaBLE\SharpBrick.PoweredUp.BlueGigaBLE.csproj" />
+ <ProjectReference Include="..\..\src\SharpBrick.PoweredUp.BlueZ\SharpBrick.PoweredUp.BlueZ.csproj" />
</ItemGroup>
+ <ItemGroup Condition=" '$(TargetFramework)' == 'net5.0-windows10.0.19041.0' ">
+ <ProjectReference Include="..\..\src\SharpBrick.PoweredUp.WinRT\SharpBrick.PoweredUp.WinRT.csproj" />
+ <ProjectReference Include="..\..\src\SharpBrick.PoweredUp.BlueGigaBLE\SharpBrick.PoweredUp.BlueGigaBLE.csproj" />
+ </ItemGroup>
+
<ItemGroup>
- <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.4" />
- <PackageReference Include="Microsoft.Extensions.Logging" Version="3.1.4" />
- <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.1.4" />
- <PackageReference Include="Microsoft.Windows.SDK.Contracts" Version="10.0.19041.1" />
+ <PackageReference Include="Microsoft.Extensions.Configuration.CommandLine" Version="5.0.0" />
+ <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="5.0.0" />
+ <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.1" />
+ <PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />
+ <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="5.0.0" />
</ItemGroup>
</Project>
and then (3)
commit 2c11fa2ecec4bc62704216c5c453479803e7c315
Author:
Date: Sat May 8 21:33:56 2021 +0100
Port BlueZ to .NET 5 and multi-targeting
diff --git a/examples/SharpBrick.PoweredUp.Examples/Program.cs b/examples/SharpBrick.PoweredUp.Examples/Program.cs
index 4c68aef..97c8ca9 100644
--- a/examples/SharpBrick.PoweredUp.Examples/Program.cs
+++ b/examples/SharpBrick.PoweredUp.Examples/Program.cs
@@ -81,6 +81,10 @@ namespace SharpBrick.PoweredUp.Examples
#endif
#if NET5_0_OR_GREATER
+ if (bluetoothAdapter == "BlueZ")
+ {
+ serviceCollection.AddBlueZBluetooth();
+ }
if (bluetoothAdapter == "BlueGigaBLE")
{
// config for "COMPortName" and "TraceDebug" (either via command line or poweredup.json)
diff --git a/src/SharpBrick.PoweredUp.BlueZ/BlueZPoweredUpBluetoothAdapter.cs b/src/SharpBrick.PoweredUp.BlueZ/BlueZPoweredUpBluetoothAdapter.cs
index 42e9b21..c48ffea 100644
--- a/src/SharpBrick.PoweredUp.BlueZ/BlueZPoweredUpBluetoothAdapter.cs
+++ b/src/SharpBrick.PoweredUp.BlueZ/BlueZPoweredUpBluetoothAdapter.cs
@@ -75,7 +75,7 @@ namespace SharpBrick.PoweredUp.BlueZ
private async Task<bool> IsLegoWirelessProcotolDevice(IDevice1 device)
=> (await device.GetUUIDsAsync()).NullToEmpty().Any(x => x.ToUpperInvariant() == PoweredUpBluetoothConstants.LegoHubService);
- public async void Discover(Func<PoweredUpBluetoothDeviceInfo, Task> discoveryHandler, CancellationToken cancellationToken = default)
+ public async void Discover(Func<IPoweredUpBluetoothDeviceInfo, Task> discoveryHandler, CancellationToken cancellationToken = default)
{
_adapter ??= await GetAdapterAsync();
@@ -88,7 +88,7 @@ namespace SharpBrick.PoweredUp.BlueZ
var poweredUpDevice = new BlueZPoweredUpBluetoothDevice(device, discoveryHandler);
await poweredUpDevice.Initialize();
- _devices.Add(poweredUpDevice.DeviceInfo.BluetoothAddress, poweredUpDevice);
+ _devices.Add(poweredUpDevice.DeviceInfo.MacAddressAsUInt64, poweredUpDevice);
await poweredUpDevice.TryGetManufacturerDataAsync();
}
@@ -123,14 +123,16 @@ namespace SharpBrick.PoweredUp.BlueZ
await poweredUpDevice.Initialize();
- _devices.Add(poweredUpDevice.DeviceInfo.BluetoothAddress, poweredUpDevice);
+ _devices.Add(poweredUpDevice.DeviceInfo.MacAddressAsUInt64, poweredUpDevice);
await poweredUpDevice.TryGetManufacturerDataAsync();
}
}
- public Task<IPoweredUpBluetoothDevice> GetDeviceAsync(ulong bluetoothAddress)
+ public Task<IPoweredUpBluetoothDevice> GetDeviceAsync(IPoweredUpBluetoothDeviceInfo bluetoothDeviceInfo)
{
+ var bluetoothAddress = (bluetoothDeviceInfo is PoweredUpBluetoothDeviceInfoWithMacAddress local) ? local.MacAddressAsUInt64 : throw new ArgumentException("DeviceInfo not created by adapter", nameof(bluetoothDeviceInfo));
+
if (!_devices.ContainsKey(bluetoothAddress))
{
throw new ArgumentOutOfRangeException("Requested bluetooth device is not available from this adapter");
@@ -138,5 +140,12 @@ namespace SharpBrick.PoweredUp.BlueZ
return Task.FromResult<IPoweredUpBluetoothDevice>(_devices[bluetoothAddress]);
}
+
+ public Task<IPoweredUpBluetoothDeviceInfo> CreateDeviceInfoByKnownStateAsync(object state)
+ => Task.FromResult<IPoweredUpBluetoothDeviceInfo>(state switch
+ {
+ ulong address => new PoweredUpBluetoothDeviceInfoWithMacAddress() { MacAddressAsUInt64 = address },
+ _ => null,
+ });
}
}
diff --git a/src/SharpBrick.PoweredUp.BlueZ/BlueZPoweredUpBluetoothDevice.cs b/src/SharpBrick.PoweredUp.BlueZ/BlueZPoweredUpBluetoothDevice.cs
index 59cf0aa..e964fe9 100644
--- a/src/SharpBrick.PoweredUp.BlueZ/BlueZPoweredUpBluetoothDevice.cs
+++ b/src/SharpBrick.PoweredUp.BlueZ/BlueZPoweredUpBluetoothDevice.cs
@@ -10,14 +10,14 @@ namespace SharpBrick.PoweredUp.BlueZ
{
internal class BlueZPoweredUpBluetoothDevice : IPoweredUpBluetoothDevice
{
- private Func<PoweredUpBluetoothDeviceInfo, Task> _discoveryHandler;
+ private Func<IPoweredUpBluetoothDeviceInfo, Task> _discoveryHandler;
private IDevice1 _device;
- internal PoweredUpBluetoothDeviceInfo DeviceInfo { get; private set; } = new PoweredUpBluetoothDeviceInfo();
+ internal PoweredUpBluetoothDeviceInfoWithMacAddress DeviceInfo { get; private set; } = new PoweredUpBluetoothDeviceInfoWithMacAddress();
internal bool Connected { get; private set; } = false;
internal bool ServicesResolved { get; private set;} = false;
- internal BlueZPoweredUpBluetoothDevice(IDevice1 device, Func<PoweredUpBluetoothDeviceInfo, Task> discoveryHandler = null)
+ internal BlueZPoweredUpBluetoothDevice(IDevice1 device, Func<IPoweredUpBluetoothDeviceInfo, Task> discoveryHandler = null)
{
_discoveryHandler = discoveryHandler;
_device = device;
@@ -82,7 +82,7 @@ namespace SharpBrick.PoweredUp.BlueZ
internal async Task GetSafeDeviceInfoAsync()
{
var btAddress = await _device.GetAddressAsync();
- DeviceInfo.BluetoothAddress = Utilities.BluetoothAddressFormatter.ConvertToInteger(btAddress);
+ DeviceInfo.MacAddressAsUInt64 = Utilities.BluetoothAddressFormatter.ConvertToInteger(btAddress);
DeviceInfo.Name = Name = await _device.GetNameAsync();
}
diff --git a/src/SharpBrick.PoweredUp.BlueZ/SharpBrick.PoweredUp.BlueZ.csproj b/src/SharpBrick.PoweredUp.BlueZ/SharpBrick.PoweredUp.BlueZ.csproj
index adaa183..d05845e 100644
--- a/src/SharpBrick.PoweredUp.BlueZ/SharpBrick.PoweredUp.BlueZ.csproj
+++ b/src/SharpBrick.PoweredUp.BlueZ/SharpBrick.PoweredUp.BlueZ.csproj
@@ -1,13 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
- <TargetFramework>netstandard2.1</TargetFramework>
+ <TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
- <PackageReference Include="Polly" Version="7.2.1" />
+ <PackageReference Include="Polly" Version="7.2.2" />
<PackageReference Include="Tmds.DBus" Version="0.9.1" />
- <PackageReference Include="System.Reactive" Version="4.4.1" />
+ <PackageReference Include="System.Reactive" Version="5.0.0" />
</ItemGroup>
<ItemGroup>
diff --git a/src/SharpBrick.PoweredUp.Cli/Program.cs b/src/SharpBrick.PoweredUp.Cli/Program.cs
index b547ab0..58b9c95 100644
--- a/src/SharpBrick.PoweredUp.Cli/Program.cs
+++ b/src/SharpBrick.PoweredUp.Cli/Program.cs
@@ -260,6 +260,10 @@ namespace SharpBrick.PoweredUp.Cli
#endif
#if NET5_0_OR_GREATER
+ if (bluetoothAdapter == "BlueZ")
+ {
+ serviceCollection.AddBlueZBluetooth();
+ }
if (bluetoothAdapter == "BlueGigaBLE")
{
// config for "COMPortName" and "TraceDebug" (either via command line or poweredup.json)
diff --git a/src/SharpBrick.PoweredUp.Cli/SharpBrick.PoweredUp.Cli.csproj b/src/SharpBrick.PoweredUp.Cli/SharpBrick.PoweredUp.Cli.csproj
index 281d422..b6d448f 100644
--- a/src/SharpBrick.PoweredUp.Cli/SharpBrick.PoweredUp.Cli.csproj
+++ b/src/SharpBrick.PoweredUp.Cli/SharpBrick.PoweredUp.Cli.csproj
@@ -14,6 +14,7 @@
<ItemGroup Condition=" '$(TargetFramework)' == 'net5.0' ">
<ProjectReference Include="..\..\src\SharpBrick.PoweredUp.BlueGigaBLE\SharpBrick.PoweredUp.BlueGigaBLE.csproj" />
+ <ProjectReference Include="..\..\src\SharpBrick.PoweredUp.BlueZ\SharpBrick.PoweredUp.BlueZ.csproj" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net5.0-windows10.0.19041.0' ">
diff --git a/test/SharpBrick.PoweredUp.TestScript/Program.cs b/test/SharpBrick.PoweredUp.TestScript/Program.cs
index a086382..3bdf376 100644
--- a/test/SharpBrick.PoweredUp.TestScript/Program.cs
+++ b/test/SharpBrick.PoweredUp.TestScript/Program.cs
@@ -36,6 +36,10 @@ namespace SharpBrick.PoweredUp.TestScript
#endif
#if NET5_0_OR_GREATER
+ if (bluetoothAdapter == "BlueZ")
+ {
+ serviceCollection.AddBlueZBluetooth();
+ }
if (bluetoothAdapter == "BlueGigaBLE")
{
// config for "COMPortName" and "TraceDebug" (either via command line or poweredup.json)
diff --git a/test/SharpBrick.PoweredUp.TestScript/SharpBrick.PoweredUp.TestScript.csproj b/test/SharpBrick.PoweredUp.TestScript/SharpBrick.PoweredUp.TestScript.csproj
index 56467c2..84eed46 100644
--- a/test/SharpBrick.PoweredUp.TestScript/SharpBrick.PoweredUp.TestScript.csproj
+++ b/test/SharpBrick.PoweredUp.TestScript/SharpBrick.PoweredUp.TestScript.csproj
@@ -13,6 +13,7 @@
<ItemGroup Condition=" '$(TargetFramework)' == 'net5.0' ">
<ProjectReference Include="..\..\src\SharpBrick.PoweredUp.BlueGigaBLE\SharpBrick.PoweredUp.BlueGigaBLE.csproj" />
+ <ProjectReference Include="..\..\src\SharpBrick.PoweredUp.BlueZ\SharpBrick.PoweredUp.BlueZ.csproj" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net5.0-windows10.0.19041.0' ">