Raspberry Pi Asked by Amon Green on November 15, 2021
I don’t often post on forums like this, but when I do, there’s always someone in the comments telling me I violated some practice of forum posting and I never get a legitimate answer, so I figured I’d explain my situation carefully before I get started:
With that out of the way, here’s what I’m trying to do and some requirements:
I’ve followed about five or six solutions thoroughly, but it seems that most are just for bridging other devices to a WiFi network the pi is on. What I’m looking for is a solution to bridge the devices to the loopback of the pi where the server is hosted. I’ve tried bridge_ports lo
in the /etc/network/interfaces
file for the bridge, but apparently that doesn’t work. I’m clearly no expert in this, so could someone help me out? Sorry if I’m sounding blunt, I don’t post often on forums like this and want to make sure I’m clear about what I’m looking for and don’t want to break some community code or whatever.
Edit: Sorry, should have mentioned: this is a pi 3B on Buster 2019-09-26
It seems that you have had no response to this so I thought I would have a try to see how far I got. These are my notes from the journey. This was not a successful journey for me but I'm hoping by sharing my failure it will help someone build on it.
From searching around it is clear that how to configure Bluetooth Personal Area Networks with BlueZ has changed dramatically over the last few years. Most of the tutorials I found used tools that have since been deprecated.
As I could not find a good tutorial I went and looked at more formal documentation.
The Bluetooth SIG has a document on the PAN profile at: https://www.bluetooth.com/specifications/profiles-overview/
and the PAN Profile overview on the Symbian Developer Library I found helpful: From: https://docs.huihoo.com/symbian/s60-5th-edition-cpp-developers-library-v2.1/GUID-35228542-8C95-4849-A73F-2B4F082F0C44/sdk/doc_source/guide/Short-Link-Services-subsystem-guide/ShortLinkServices/BluetoothProfiles/BluetoothPAN/BTPANProfileOverview.html
It appears there are three main variations on a PAN. This is backed up when looking in the BlueZ Network DBus API. However, the BlueZ API seems to have client/server of either GN, NAP or PANU whereas the above documents talk about the PANU always being the client. I did some drawnings of how I think it is in BlueZ:
In the BlueZ readme it suggests the networking profiles are enabled by default. https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/README#n188
The networking API is documentated at: https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/network-api.txt
They have an example/test Python script for this client functionality at: https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/test/test-network
And for a PAN Network server: https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/test/test-nap
There is a thread about using this on the developer mailing list. https://marc.info/?l=linux-bluetooth&m=145504188107174&w=2 There seems to be good information in the thread but (spoiler alert) they didn't get it working but that was a few years ago.
However, I did find a follow-up that is disconnected from the main thread:
https://marc.info/?l=linux-bluetooth&m=149129232432090&w=2
Not a conclusive answer but there was a reply from one of the main developers suggesting it should work.
This last thread talked about running a test-gn
script which I could not find.
For the server, the NetworkServer1
Register
method is called from the adapter device object path. Using bluetoothctl show
before and after this Register
command will show that a PAN UUID has been added.
For the client, the Network1
Connect
method is called from the remote device object path. For this path to be there, the client and server device need to have been paired.
I have been using bluetoothctl
to do the pairing.
I edited /etc/dbus-1/system.d/bluetooth.conf
to include permission for the Network1
and NetworkServer1
interfaces. I did this on both my test Raspberry Pi's
<policy user="root">
<allow own="org.bluez"/>
<allow send_destination="org.bluez"/>
<allow send_interface="org.bluez.Agent1"/>
<allow send_interface="org.bluez.MediaEndpoint1"/>
<allow send_interface="org.bluez.MediaPlayer1"/>
<allow send_interface="org.bluez.Profile1"/>
<allow send_interface="org.bluez.GattCharacteristic1"/>
<allow send_interface="org.bluez.GattDescriptor1"/>
<allow send_interface="org.bluez.LEAdvertisement1"/>
<allow send_interface="org.bluez.Network1"/>
<allow send_interface="org.bluez.NetworkServer1"/>
<allow send_interface="org.freedesktop.DBus.ObjectManager"/>
<allow send_interface="org.freedesktop.DBus.Properties"/>
</policy>
I tested tethering to my phone as this just required me to get the client working. This worked well. I enabled Bluetooth tethering on my Android phone. Then on the Raspberry Pi, using bluetoothctl, scanned, paired, and trusted before using the following commandline to connect:
busctl call org.bluez /org/bluez/hci0/dev_xx_xx_xx_xx_xx_xx org.bluez.Network1 Connect s pan_type
[xx_xx_xx_xx_xx_xx being the BD_ADDR of my phone with : replaced with _]
[pan_type is one of gn, panu, or nap]
I have been using a python script to do the same [network_client.py
]:
import argparse
from signal import pause
import pydbus
parser = argparse.ArgumentParser()
parser.add_argument('d', help='BD_ADDR of network server')
parser.add_argument('u', help='Server type to connect to [gn, panu, nap]')
args = parser.parse_args()
device = args.d
device_path = f"/org/bluez/hci0/dev_{device.replace(':', '_')}"
bus = pydbus.SystemBus()
network = bus.get('org.bluez', device_path)['org.bluez.Network1']
print(f'Connecting to {args.d} as a {args.u}')
network.Connect(args.u)
try:
print('Press CTRL-C to disconnect')
pause()
except KeyboardInterrupt:
print('Disconnecting from network')
network.Disconnect()
Using the command line:
python3 network_client.py xx:xx:xx:xx:xx:xx nap
These instructions remain valid for the different client types you may want to connect to whether that is on a phone or a Raspberry Pi.
I have found this to be the more difficult part because of my lack of knowledge on setting up network bridges and understanding what BlueZ is doing for me and what I need to do. I have found the following documents useful references for creating network bridge on the Bluetooth PAN server. :
Iproute2 tutorial https://www.howtogeek.com/657911/how-to-use-the-ip-command-on-linux/
Iproute2 examples https://baturin.org/docs/iproute2/
As I don't have this fully worked out I am using iproute2 on the command line so settings aren't saved. This means when I make errors, a reboot resets things to a working state
/etc/dbus-1/system.d/bluetooth.conf
to include Network1
and NetworkServer1
interfaces (same as client setup)trust
in bluetoothctl to ensure the server and client trust each otherservice bluetooth status
service bluetooth status
[server]Bridge specified in Register command does not exist
BNEP server cannot be added
bnep: Can't add bnep0 to the bridge
Connection from client without server registered (0x1116 = NAP, 0x1117 = GN etc) or permissions in /etc/dbus-1/system.d/bluetooth.conf
Server error, bridge not initialized: (0x1116)
Jul 26 10:43:11 raspberrypi bluetoothd[581]: BNEP server cannot be added
PAN type not registered on Server
gi.repository.GLib.Error: g-io-error-quark: GDBus.Error:org.bluez.Error.Failed: Input/output error (36)
Starting a client for a PAN type that hasn't been paired with on specified server or permissions in /etc/dbus-1/system.d/bluetooth.conf
hasn't been set.
gi.repository.GLib.Error: g-io-error-quark: GDBus.Error:org.bluez.Error.NotSupported: Operation is not supported (36)
This can be done on the commandline with one of the DBus tools. e.g.:
busctl call org.bluez/ org/bluez/hci0 org.bluez.NetworkServer1 Register ss pan_type bridge_name
Or I have been using a Python script [network_server.py
]:
import argparse
import pydbus
from gi.repository import GLib
bus = pydbus.SystemBus()
server = bus.get('org.bluez', '/org/bluez/hci0')['org.bluez.NetworkServer1']
parser = argparse.ArgumentParser()
parser.add_argument('u', help='Server role [gn, panu, nap]')
args = parser.parse_args()
if args.u == 'gn':
bridge = 'bluez_gn'
elif args.u == 'panu':
bridge = 'bluez_panu'
else:
bridge = 'bluez_nap'
server.Register(args.u, bridge)
print(f'Service {args.u} is registered with bridge {bridge}')
mainloop = GLib.MainLoop()
print('Press CTRL-C to disconnect')
try:
mainloop.run()
except KeyboardInterrupt:
mainloop.quit()
The server needs to be started before the client
Care needs to be taken when pairing two Raspberry Pi's together for PAN to ensure things are done in the correct order
On server:
server: Define bridge for PAN type
server: start server script so PAN UUID is in list of services
server[bluetoothctl]: `default-agent`
server[bluetoothctl]: `discoverable on` <leave bluetoothctl running>
On client
client[bluetoothctl]: `default-agent`
client[bluetoothctl]: `scan on`
client[bluetoothctl]: `scan off`
client[bluetoothctl]: `pair xx:xx:xx:xx:xx:xx` <need to type yes on both machines>
client[bluetoothctl]: `trust xx:xx:xx:xx:xx:xx`
On Server
server[bluetoothctl]: `trust yy:yy:yy:yy:yy:yy`
On Client
client: start client script
panu
]Work In Progress
gn
]sudo ip link add name bluez_gn type bridge
sudo ip link set bluez_gn up
python3 network_server.py gn
I then use the pairing process outlined above before starting the client. After ~30 seconds I can use ip addr show
to see that client bnep0
has an ip address and I can ping it. However, I can't ping the server from the client. I suspect this is because I have created the bridge incorrectly.
nap
]On the server RPi, I have wired internet on eth0
so this is how I setup the bridge and start the server
sudo ip link add name bluez_nap type bridge
sudo ip link set bluez_nap up
sudo ip link set dev eth0 master bluez_nap
python3 network_server.py nap
I then use the pairing process outlined above before starting the client. This give my PAN client access to the internet over bluetooth. However, I do loose network access to the PAN server. I suspect this means my bridge setup is not not complete.
Commands I've been using to check on status etc are:
service bluetooth status
sudo btmon -t
ip address show
ip route show
ip link show
dmesg -w
If anyone understands why BNEP server is not being created then please let me know.
Answered by ukBaz on November 15, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP