Share files between 2 computers via bluetooth from terminal
First, you need to apt install bluez-tools obexpushd
.
To send and receive files, you need to set up and pair the devices first.
SETUP
from Arch Wiki - bluetooth:
Bluetoothctl
Start the bluetoothctl
interactive command. There one can input help
to get a list of available commands.
- Turn the power to the controller on by entering
power on
. It is off by default. - Enter
devices
to get the MAC Address of the device with which to pair. - Enter device discovery mode with
scan on
command if device is not yet on the list. - Turn the agent on with
agent on
. - Enter
pair MAC Address
to do the pairing (tab completion works). - If using a device without a PIN, one may need to manually trust the
device before it can reconnect successfully. Enter
trust MAC Address
to do so. - Finally, use
connect MAC_address
to establish a connection.
The last two bullet points are not necessary for the send part of a file transfer, but you need the connect
later for the receive part.
An example session may look this way:
# bluetoothctl
[NEW] Controller 00:10:20:30:40:50 pi [default]
[bluetooth]# agent KeyboardOnly
Agent registered
[bluetooth]# default-agent
Default agent request successful
[bluetooth]# scan on
Discovery started
[CHG] Controller 00:10:20:30:40:50 Discovering: yes
[NEW] Device 00:12:34:56:78:90 myLino
[CHG] Device 00:12:34:56:78:90 LegacyPairing: yes
[bluetooth]# pair 00:12:34:56:78:90
Attempting to pair with 00:12:34:56:78:90
[CHG] Device 00:12:34:56:78:90 Connected: yes
[CHG] Device 00:12:34:56:78:90 Connected: no
[CHG] Device 00:12:34:56:78:90 Connected: yes
Request PIN code
[agent] Enter PIN code: 1234
[CHG] Device 00:12:34:56:78:90 Paired: yes
Pairing successful
[CHG] Device 00:12:34:56:78:90 Connected: no
[bluetooth]# connect 00:12:34:56:78:90
Attempting to connect to 00:12:34:56:78:90
[CHG] Device 00:12:34:56:78:90 Connected: yes
Connection successful
To make changes permanent and in order to have the device active after a reboot, a udev
rule is needed:
/etc/udev/rules.d/10-local.rules
# Set bluetooth power up
ACTION=="add", KERNEL=="hci0", RUN+="/usr/bin/hciconfig %k up"
Tip: Replace KERNEL=="hci0"
with KERNEL=="hci[0-9]*"
to match all BT interfaces.
After a suspend/resume-cycle, the device can be powered on automatically using a custom systemd service:
/etc/systemd/system/[email protected]
[Unit]
Description=Bluetooth auto power on
After=bluetooth.service sys-subsystem-bluetooth-devices-%i.device suspend.target
[Service]
Type=oneshot
ExecStart=/usr/bin/hciconfig %i up
[Install]
WantedBy=suspend.target
Enable an instance of the unit using your bluetooth device name, for example [email protected]
.
Now your devices are paired. Check that you can see the other with bt-device -l
.
SEND
Next, you have to send up your systemd
infrastructure for the send to work, otherwise you get the following error:
Acquiring proxy failed: Error calling StartServiceByName for org.bluez.obex: GDBus.Error:org.freedesktop.systemd1.LoadFailed: Unit dbus-org.bluez.obex.service failed to load: No such file or directory.
Make the necessary systemd
changes with
systemctl --user start obex
sudo systemctl --global enable obex
This makes sure you can send files. A sudo
also in the first line will fail!
You can send files now by bluetooth-sendto --device=12:34:56:78:9A:BC filename filename2
. If a transfer hangs at 100%, a ctrlc finalizes it (or aborts earlier).
To know your device name (12:34:56:78:9A:BC), you can issue bt-device -l
.
RECEIVE
from Raspberry Pi forum:
We want to set up a OBEX push server, this is why obexpushd
was needed.
The compatibility flag on the Bluetooth daemon is needed, you have to edit /etc/systemd/system/dbus-org.bluez.service
with the editor of your choice by adding the -C
flag to the end of the ExecStart=
line. It should look like this:
ExecStart=/usr/lib/bluetooth/bluetoothd -C
Reboot or restart the service with sudo systemctl daemon-reload
after editing. Choose a specific directory where received files are placed, for example by sudo mkdir /bluetooth
.
Start the server with sudo obexpushd -B -o /bluetooth -n
, it should respond with:
obexpushd 0.11.2 Copyright (C) 2006-2010 Hendrik Sattler
This software comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions.
Listening on bluetooth/[00:00:00:00:00:00]:9
If that's not working, and you get:
obexpushd 0.11.2 Copyright (C) 2006-2010 Hendrik Sattler
This software comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions.
BtOBEX_ServerRegister: Address already in use
net_init() failed
it could be because you have another daemon or program running which occupies the rfcomm channel 9 that obexpushd
uses by default. In this case, change the channel to 23 like this:
sudo obexpushd -B23 -o /bluetooth -n
to use channel 23.
Once you get obexpushd
running, open a second terminal window. You can verify that the OBEX service is registered with
sudo sdptool browse local
It should list (at channel 23 in this case), among others, this:
Service Name: OBEX Object Push
Service Description: a free OBEX server
Service Provider: obexpushd
Service RecHandle: 0x10005
Service Class ID List:
"OBEX Object Push" (0x1105)
Protocol Descriptor List:
"L2CAP" (0x0100)
"RFCOMM" (0x0003)
Channel: 23
"OBEX" (0x0008)
Profile Descriptor List:
"OBEX Object Push" (0x1105)
Version: 0x0100
In that window, while obexpushd
is still running, use bluetoothctl
to set discoverable on
. Now pair from your other device. Pairing MUST be done while obexpushd
is running, or the other device wont recognize the service is available. If the phone is already paired, remove it from your other device, use bluetoothctl
to remove it from the Ubuntu computer, and re-pair.
After you connect (the last bullet point from the above list), you should be able to receive files. They will appear in the /bluetooth
directory. Notice that they will be owned by root, so you'll need sudo to access them. Or you can do a chmod 0777 /bluetooth
for a public exchange directory, since the bluetooth authentification is device-based and not user-based anyway.
In order to automate the obexpushd command, create the file /etc/systemd/system/obexpush.service
[Unit]
Description=OBEX Push service
After=bluetooth.service
Requires=bluetooth.service
[Service]
ExecStart=/usr/bin/obexpushd -B23 -o /bluetooth -n
[Install]
WantedBy=multi-user.target
Then, set that to autostart with
sudo systemctl enable obexpush
After a reboot or restart of the service with sudo systemctl daemon-reload
, you should be able to send and receive files in both directions now.
Don't forget to connect the devices when trying to receive files.