inthehand / 32feet

Personal Area Networking for .NET. Open source and professionally supported
https://inthehand.com/components/32feet/
MIT License
828 stars 209 forks source link

InTheHand.Net.Bluetooth not working for Linux #321

Open MatthiasJentsch opened 1 year ago

MatthiasJentsch commented 1 year ago

Tested with Ubuntu 23.04. Exception in BluetoothClient.Connect.

"System.NullReferenceException" in InTheHand.Net.Bluetooth.dll aufgetreten.: 'Object reference not set to an instance of an object.' bei InTheHand.Net.Sockets.BluetoothClient.Connect(BluetoothEndPoint remoteEP) in /home/default/32feet/InTheHand.Net.Bluetooth/Platforms/Linux/BluetoothClient.linux.cs: Zeile119 bei InTheHand.Net.Sockets.BluetoothClient.PlatformConnect(BluetoothAddress address, Guid service) in /home/default/32feet/InTheHand.Net.Bluetooth/Platforms/Linux/BluetoothClient.linux.cs: Zeile107 bei InTheHand.Net.Sockets.BluetoothClient.Connect(BluetoothAddress address, Guid service) in /home/default/32feet/InTheHand.Net.Bluetooth/BluetoothClient.cs: Zeile72 bei Program.Main(String[] args) in /home/default/32feet/Test/Program.cs: Zeile17

Testprogram:

BluetoothAddress.TryParse("............", out BluetoothAddress bluetoothAddress);
BluetoothClient client = new BluetoothClient();
client.Connect(bluetoothAddress, BluetoothService.SerialPort);

The problem is here in InTheHand.Net.Bluetooth/Platforms/Linux/BluetoothClient.linux.cs method PlatformInitialize. Th line _socket = new Socket(AddressFamilyBluetooth, SocketType.Stream, BluetoothProtocolType.L2Cap); throws a System.Net.Sockets.SocketException with message "Address family not supported by protocol". And so the _socket is null. That causes the NullReferenceException in the Connect method.

I've used the branch linux at commit 10207ba from May 3 2023.

Any idea how to fix this?

peterfoot commented 1 year ago

Linux is not fully implemented yet so the code you see there is a work in progress.

MatthiasJentsch commented 1 year ago

Maybe it would help to solve the creation of the socket. So do you know why I can't create a socket for a bluetooth connection? So basically why it's not possible to create a new Socket(AddressFamilyBluetooth, SocketType.Stream, BluetoothProtocolType.L2Cap)? Why does this throw the Exception "Address family not supported by protocol"?

embeddedmz commented 1 year ago

there's no solution for standard Bluetooth communications in C# under Linux :(

peterfoot commented 1 year ago

InTheHand.Net.Bluetooth 4.1 (released to NuGet today) supports both Windows and Linux when using the net6.0 or net7.0 target platforms. Not all functionality is implemented for Linux yet - you have to connect with a known channel rather than a service UUID but I'm working on adding discovery and SDP features to bring it to parity with Windows.

embeddedmz commented 1 year ago

Hi @peterfoot

I got this exception :

Address Family: Unknown
Address Byte: 31
Size: 10
Unhandled exception. System.Net.Sockets.SocketException (22): Invalid argument
   at InTheHand.Net.Sockets.LinuxSocket.ThrowOnSocketError(Int32 result, Boolean throwOnDisconnected)
   at InTheHand.Net.Sockets.LinuxSocket.Connect(EndPoint remoteEP)
   at InTheHand.Net.Sockets.LinuxBluetoothClient.Connect(BluetoothEndPoint remoteEP)
   at InTheHand.Net.Sockets.LinuxBluetoothClient.Connect(BluetoothAddress address, Guid service)
   at QuickBTTest.Program.Main(String[] args) in D:\DevProjects\Prevo100CSharp\QuickBTTest\Program.cs:line 52
Abandon (core dumped)
peterfoot commented 1 year ago

Currently on Linux you need to use Connect(EndPoint) so that you can specify the channel id because there is no SDP lookup yet.

embeddedmz commented 1 year ago

you can specify the channel id

Can you give me an example ?

I still have an exception if I use BluetoothEndPoint.

peterfoot commented 1 year ago

This is what I've been using to connect to a printer. The service uuid is ignored because it specifies channel 1:-


client.Connect(new BluetoothEndPoint(device.DeviceAddress, BluetoothService.SerialPort, 1));
if (client.Connected)
{
    var stream = client.GetStream();
    StreamWriter writer = new StreamWriter(stream);
    writer.WriteLine("Hello printer");
    writer.Flush();
    writer.Close();
    client.Close();
}
0x57e11a commented 1 year ago

@peterfoot It looks like LinuxBluetoothListener never sets it's Active property in the Start method, causing listeners on linux to throw Not listening. You must call the Start() method before calling this method.

NickBarton commented 2 weeks ago

Peter, got it working superbly on Windows, .NET8. Would like cross-platform to Linux too, but I'm also getting the error:

Address Family: Unknown Address Byte: 31 Size: 10

Currently using 4.1.43, tried to upgrade to 4.1.44 but got downgrade error:

"Severity Code Description Project File Line Suppression State Details Error (active) NU1605 Warning As Error: Detected package downgrade: InTheHand.Net.Bluetooth from 4.1.44 to 4.1.43. Reference the package directly from the project to select a different version. GKDxRCI_Service.Android -> GKDxRCI_Service -> ServiceComms -> InTheHand.Net.Bluetooth (>= 4.1.44) GKDxRCI_Service.Android -> InTheHand.Net.Bluetooth (>= 4.1.43) GKDxRCI_Service.Android C:\GKDTEC\xRCI\GKDxRCI NET8\GKDxRCI_Service.Android\GKDxRCI_Service.Android.csproj 1"

Two questions: Does the latest version include full Linux support? Why am I getting downgrade error in my Android project?