Trying to revive 'ubtd' (Bluetooth file transfer)
-
Hello
I'm trying to revive the 'ubtd' app (Bluetooth file transfer) initially written by Michael Zanetti and Ian L., but I've hit a roadblock and I could use some guidance.
I'm currently targetting UT 20.04 on a Pixel 3a.
By default, the OBEX daemon doesn't run on the phone. A 'systemd' unit file is supposed to start it (
/usr/lib/systemd/user/dbus-org.bluez.obex.service), but it is reported as "loaded / inactive (dead)" by 'systemctl' -- I'm not sure why as I was unable to find relevant log entries.I can manually start the OBEX daemon using the following command:
$ systemctl --user start obex.serviceIn this case, the 'obexd' daemon keeps running and uses the same command-line parameters as those specified for the D-Bus related service (
obexd -P ftp,irmc,mas,pcsuite -r /home/phablet).Nonetheless, after pairing the phone with my laptop, when I start my app (the one that is supposed to receive incoming file transfers), I see the following messages in its log:
[03/01/2026 12:25] creating agent on dbus [03/01/2026 12:25] registering agent [03/01/2026 12:25] registering agent on obexd-server [03/01/2026 12:25] Error registering agent for the default adapter: QDBusError("org.freedesktop.DBus.Error.ServiceUnknown", "The name org.bluez.obex was not provided by any .service files")For information, the
obex.serviceunit file does expose "org.bluez.obex" as BusName, not as Name -- not sure how relevant that is.On its side, the OBEX daemon logs the following:
[03/01/2026 12:25] CONNECT(0x0), <unknown>(0xff) [03/01/2026 12:25] CONNECT(0x0), <unknown>(0x0) [03/01/2026 12:25] PUT(0x2), <unknown>(0xff) [03/01/2026 12:25] PUT(0x2), Forbidden(0x43) [03/01/2026 12:25] DISCONNECT(0x1), <unknown>(0xff) [03/01/2026 12:25] DISCONNECT(0x1), Success(0x20) [03/01/2026 12:25] disconnected: Transport got disconnectedSo 'obexd' seems to receive the file sent by the laptop (from the point of view of the laptop, the transfer succeeds), but fails to hand it over to my app, which I guess makes sense as it failed to register itself with the daemon.
Can anyone suggest a fix, further ways to troubleshoot or point me to relevant documentation?
Thanks in advance.
-
@PhAndersson
I guess you already checked if the service is registered to dbus after starting the obexd service:
e.g:busctl list | grep bluez( no idea if it works on 20.04 though)
But maybe that service is supposed to be up only after pairing and with the profile set, in that case maybe bluez is not properly setup on UT for that ?Otherwise idk, i'm on 24.04, and even starting obex fails....
-
@lduboeuf Many thanks for the suggestion. No, I had not checked the output of
busctl list. Here is what it says in the "default" state (i.e. no 'obexd' running, phone not connected to laptop over BT):org.bluez 2170 bluetoothd root :1.40 bluetooth.service - -If I then start 'obexd' manually as explained above, the output remains the same. If I then connect the phone to the laptop over BT, the output is still the same.
For what it's worth, I performed the same test on the laptop (openSUSE Leap 15.6), where 'obexd' is always running and known to be functional, and the
busctl listoutput there also only lists 'bluetoothd', so I'm not sure whether 'obexd' is expected to appear there at all. -
This being said, a further test confirms that when 'obexd' is running, it does register with D-Bus, only not with the expected name:
:1.129 5035 obexd phablet :1.129 user@32011.service - -(the behaviour is the same on the laptop, BTW -- there at least, none of the D-Bus services that are started by a regular user register a name on the bus, even though a 'BusName' parameter is specified in their unit file; only services started as 'root' seem allowed to do that).
-
In Xenial, it was working, when i look at patches on Xenial, it appear there are some related to obexd, that may explain:
https://github.com/ubports/bluez-packaging/tree/xenial/debian/patches -
@lduboeuf That's a very good point -- thanks a lot. I'll have a look at those patches, but most of all you reminded me that I still have a working Xiaomi phone running Xenial, so I'll investigate the way the Bluez/OBEX stack is configured there.
-
OK, first batch of results:
- 'obexd' is started by default on Xenial and runs with the same command-line parameters
- the same two OBEX-related packages are installed, but of course their version differ (5.53 for bluez-obexd, 1.7.1 for libopenobex2)
- the files provided by the 'bluez-obexd' package are the same, except for the
dbus-org.bluez.obex.serviceunit file that is missing on Xenial - the output of
busctl list | grep bluezis quite close to what it is on Focal, except that the corresponding 'systemd' unit file is not shown - the output of
busctl list | grep obexshows something in lieu of a unit file ('session-c1.scope' -- what is it?), but still doesn't advertise any name for the service (see below) - further digging reveals that although 'systemd' is already present on the system, it is not used for user-related processes (i.e. no
systemd --userprocess) -- 'obexd' has been started byupstart --user(based on its PPID)
Maybe the problem on Focal stems from a lack of integration between the OBEX daemon and
systemd --user(which could also explain why the service doesn't start although enabled)?For what it's worth, here is the output of
busctl list | grep obexon Xenial::1.59 4084 obexd phablet :1.59 session-c1.scope c1 - -
@PhAndersson said in Trying to revive 'ubtd' (Bluetooth file transfer):
OK, first batch of results:
- 'obexd' is started by default on Xenial and runs with the same command-line parameters
- the same two OBEX-related packages are installed, but of course their version differ (5.53 for bluez-obexd, 1.7.1 for libopenobex2)
- the files provided by the 'bluez-obexd' package are the same, except for the
dbus-org.bluez.obex.serviceunit file that is missing on Xenial - the output of
busctl list | grep bluezis quite close to what it is on Focal, except that the corresponding 'systemd' unit file is not shown - the output of
busctl list | grep obexshows something in lieu of a unit file ('session-c1.scope' -- what is it?), but still doesn't advertise any name for the service (see below) - further digging reveals that although 'systemd' is already present on the system, it is not used for user-related processes (i.e. no
systemd --userprocess) -- 'obexd' has been started byupstart --user(based on its PPID)
Maybe the problem on Focal stems from a lack of integration between the OBEX daemon and
systemd --user(which could also explain why the service doesn't start although enabled)?For what it's worth, here is the output of
busctl list | grep obexon Xenial::1.59 4084 obexd phablet :1.59 session-c1.scope c1 -Yes indeed, Xenial relies on upstart instead of systemd. Maybe something is missing there.
This discussion could interest core team. @peat_psuwit do you have an idea ? -
Further updates:
The
obex.servicesystemd unit was in fact disabled by default. I enabled it withsystemctl --user enable obex.serviceand then performed a full power-cycle on the phone.After rebooting,
obexdwas still not running.systemdreports the following about the service:â obex.service - Bluetooth OBEX service Loaded: loaded (/usr/lib/systemd/user/obex.service; enabled; vendor preset: enabled) Drop-In: /usr/lib/systemd/user/obex.service.d ââubuntu-touch-session.conf Active: inactive (dead)I didn't find anything in 'journal' that could explain why
systemdfailed to start the unit --obexdlogs its version during startup and even that wasn't present, so I don't believe it's a case of it dying prematurely.Of course, I'm still able to start the service manually with
systemctl --user start obex.service, and in this case, it keeps running until I power-cycle the phone. -
I wonder how the obex service runs at all for you. It does not for me.
On my FP5 running 24.04.1.1, I get:phablet@ubuntu-phablet:~$ systemctl --user cat obex # /usr/lib/systemd/user/obex.service [Unit] Description=Bluetooth OBEX service [Service] Type=dbus BusName=org.bluez.obex ExecStart=/usr/libexec/bluetooth/obexd [Install] Alias=dbus-org.bluez.obex.service # /usr/lib/systemd/user/obex.service.d/ubuntu-touch-session.conf [Service] ExecStart= ExecStart=/usr/lib/bluetooth/obexd -P ftp,irmc,mas,pcsuite -r $HOMEas /usr/lib/bluetooth/obexd does not exist, the service fails to start.
EDIT: after some searching, and finding this github issue, I found the trick to add another override and after setting enable-linger for phablet with loginctl, the obex service is running after a restart.
Not that I can test anything involving Bluetooth for lack of a suitable peripheral

-
@gpatel-fr said in Trying to revive 'ubtd' (Bluetooth file transfer):
I wonder how the obex service runs at all for you. It does not for me.
@lduboeuf already mentioned that
obexdwouldn't start on 24.04. I don't use 24.04 yet myself, so I can't confirm.On my FP5 running 24.04.1.1, I get:
phablet@ubuntu-phablet:~$ systemctl --user cat obex # /usr/lib/systemd/user/obex.service [Unit] Description=Bluetooth OBEX service [Service] Type=dbus BusName=org.bluez.obex ExecStart=/usr/libexec/bluetooth/obexd [Install] Alias=dbus-org.bluez.obex.service # /usr/lib/systemd/user/obex.service.d/ubuntu-touch-session.conf [Service] ExecStart= ExecStart=/usr/lib/bluetooth/obexd -P ftp,irmc,mas,pcsuite -r $HOMEThat content looks identical to what it is on 20.04.
as /usr/lib/bluetooth/obexd does not exist, the service fails to start.
Are you sure
/usr/lib/bluetooth/obexddoes not exist on 24.04? It is normally provided by the same package as the unit file whose content you just showed (packagebluez-obexd).EDIT: after some searching, and finding this github issue, I found the trick to add another override and after setting enable-linger for phablet with loginctl, the obex service is running after a restart.
Thanks a lot for that -- maybe this would the issue on 20.04 as well. I'll try.
Not that I can test anything involving Bluetooth for lack of a suitable peripheral

-
@PhAndersson said in Trying to revive 'ubtd' (Bluetooth file transfer):
Are you sure /usr/lib/bluetooth/obexd does not exist on 24.04
phablet@ubuntu-phablet:~$ ls /usr/lib/bluetooth/obexd
ls: cannot access '/usr/lib/bluetooth/obexd': No such file or directoryWell, that explains it then. When this upgrade from upstart to systemd, UT was still only on focal. When upgrading to 24.04, the path was not upgraded.
On a standard Ubuntu 24.04 (not UT):
apt-file list bluez-obexd
bluez-obexd: /usr/lib/systemd/user/obex.service
bluez-obexd: /usr/libexec/bluetooth/obexd
bluez-obexd: /usr/share/dbus-1/services/org.bluez.obex.service
bluez-obexd: /usr/share/doc/bluez-obexd/changelog.Debian.gz
bluez-obexd: /usr/share/doc/bluez-obexd/copyrightyeah, that's a 24.04 thing. Before Ubuntu was putting the executable under /usr/lib.
I have filed an issue on gitlab.
-
There is progress. I'm happy to report that the D-Bus registration issue that manifested itself through the following error message:
Error registering agent for the default adapter: QDBusError("org.freedesktop.DBus.Error.ServiceUnknown", "The name org.bluez.obex was not provided by any .service files")
is resolved. My mistake. I tried to connect to OBEX over the system bus, when it runs on the session bus.
Still no file transfer, though.
-
@gpatel-fr said in Trying to revive 'ubtd' (Bluetooth file transfer):
@PhAndersson said in Trying to revive 'ubtd' (Bluetooth file transfer):
yeah, that's a 24.04 thing. Before Ubuntu was putting the executable under /usr/lib.I have filed an issue on gitlab.
Splendid! Many thanks.
-
@gpatel-fr said in Trying to revive 'ubtd' (Bluetooth file transfer):
EDIT: after some searching, and finding this github issue, I found the trick to add another override and after setting enable-linger for phablet with loginctl, the obex service is running after a restart.I just tried the
enable-lingertrick on 20.04:$ loginctl enable-lingerthen confirmed that it was set using
$ loginctl user-statusbut after power-cycling the phone, the OBEX daemon still won't start automatically even though its unit file is still enabled.
You mentioned "another override": was there something else to do?
-
the other override is needed because of the specific 24.04 problem, you should not need it.
Maybe all that is needed is to enable again the service.
What's the result of
systemctl --user status obex
also, is there a symbolic link to the service under ~/.config/systemd/user/default.target.wants ?
if not systemd will not start it. -
@gpatel-fr said in Trying to revive 'ubtd' (Bluetooth file transfer):
the other override is needed because of the specific 24.04 problem, you should not need it.
OK -- thanks.
Maybe all that is needed is to enable again the service.
What's the result of
systemctl --user status obex
obex.serviceis still enabled -- here is the requested output:â obex.service - Bluetooth OBEX service Loaded: loaded (/usr/lib/systemd/user/obex.service; enabled; vendor preset: enabled) Drop-In: /usr/lib/systemd/user/obex.service.d ââubuntu-touch-session.conf Active: inactive (dead)also, is there a symbolic link to the service under ~/.config/systemd/user/default.target.wants ?
if not systemd will not start it.Well -- that's a good hint

As it turns out, the folder called
~/.config/systemd/user/default.target.wantsdoes not exist at all. There is a folder calledgraphical-session.target.wantsbut the symlink is not there either. The symlink is created one level above, i.e. in~/.config/systemd/user/. Here is thels -loutput:total 20 lrwxrwxrwx 1 phablet phablet 34 Jan 15 10:50 dbus-org.bluez.obex.service -> /usr/lib/systemd/user/obex.service -rw-rw-r-- 1 phablet phablet 768 Oct 4 16:55 dekkod-notify.service -rw-rw-r-- 1 phablet phablet 716 Oct 4 16:55 dekkod.service drwxr-xr-x 2 phablet phablet 4096 Mar 27 2025 graphical-session.target.wants -rw-rw-r-- 1 phablet phablet 332 Mar 27 2025 osmscout-server.service -rw-rw-r-- 1 phablet phablet 174 Mar 27 2025 osmscout-server.socketBy way of comparison, on my laptop running openSUSE Leap 15.6, the OBEX symlink is created in the exact same place (and
obexdsuccessfully starts when I log in), so I don't know whether or not it's enough to explain why the service fails to start on the phone.This being said, my app is now able to start
obexdby itself if not running already, so that aspect has become less critical. -
@PhAndersson said in Trying to revive 'ubtd' (Bluetooth file transfer):
lrwxrwxrwx 1 phablet phablet 34 Jan 15 10:50 dbus-org.bluez.obex.service -
I have it too; it's a different thing, it's for the dbus part I think.
@PhAndersson said in Trying to revive 'ubtd' (Bluetooth file transfer):
my app is now able to start obexd by itself if not running already,
It may be possible to activate on demand, but I have no idea how.
-
OK, yet more updates.
As already indicated above, my app now successfully registers with D-Bus/OBEX:
[20/01/2026 13:50] Creating a QMirClientScreen now [20/01/2026 13:50] reply QDBusMessage(type=MethodReturn, service=":1.28", signature="", contents=([]) ) [20/01/2026 13:50] creating agent on dbus [20/01/2026 13:50] registering agent [20/01/2026 13:50] discovering obex service [20/01/2026 13:50] OBEX service not found, attempting D-Bus activation [20/01/2026 13:50] OBEX service activated successfully [20/01/2026 13:50] found OBEX service at: "org.bluez.obex" [20/01/2026 13:50] registering agent on obexd-server [20/01/2026 13:50] Agent registered successfully [20/01/2026 13:50] have entries: (".", "..", "HubIncoming", "qmlcache", "qtshadercache-arm64-little_endian-lp64") "/home/phablet/.cache/ratatoskr.philipa" [20/01/2026 13:50] file:///usr/lib/aarch64-linux-gnu/qt5/qml/Lomiri/Components/1.3/Icon.qml:115:5: QML Image: Failed to get image from provider: image://theme/network-cellular-connected [20/01/2026 13:50] QObject::startTimer: Timers cannot be started from another thread [20/01/2026 13:52] file:///usr/lib/aarch64-linux-gnu/qt5/qml/Lomiri/Components/1.3/Icon.qml:115:5: QML Image: Failed to get image from provider: image://theme/network-cellular-connected [20/01/2026 13:52] file:///usr/lib/aarch64-linux-gnu/qt5/qml/Lomiri/Components/1.3/Icon.qml:115:5: QML Image: Failed to get image from provider: image://theme/network-cellular-connected [20/01/2026 13:52] qt.qpa.mirclient: Attempted to deliver an event to a non-existent window, ignoring.But when I start the app and try to push a file from the laptop to the phone over BT,
obexdlogs the following:[20/01/2026 13:50] OBEX daemon 5.64 [20/01/2026 13:50] Excluding pcsuite [20/01/2026 13:50] Excluding ftp [20/01/2026 13:50] Excluding irmc [20/01/2026 13:50] Excluding mas [20/01/2026 13:51] CONNECT(0x0), <unknown>(0xff) [20/01/2026 13:51] CONNECT(0x0), <unknown>(0x0) [20/01/2026 13:51] PUT(0x2), <unknown>(0xff) [20/01/2026 13:51] Agent replied with an error: org.freedesktop.DBus.Error.AccessDenied, An AppArmor policy prevents this sender from sending this message to this recipient; type="method_call", sender=":1.107" (uid=32011 pid=4463 comm="/usr/lib/bluetooth/obexd -P ftp,irmc,mas,pcsuite -" label="unconfined") interface="org.bluez.obex.Agent1" member="AuthorizePush" error name="(unset)" requested_reply="0" destination=":1.106" (uid=32011 pid=4460 comm="ratatoskr " label="ratatoskr.philipa_ratatoskr_260120124119 (enforce)") [20/01/2026 13:51] PUT(0x2), Forbidden(0x43) [20/01/2026 13:51] DISCONNECT(0x1), <unknown>(0xff) [20/01/2026 13:51] DISCONNECT(0x1), Success(0x20) [20/01/2026 13:51] disconnected: Transport got disconnectedLooking in journal, another message is found right before the error reported by
obexd, this one issued bydbus-daemon(here copied from an earlier test run):Jan 15 16:44:14 hatshepsut dbus-daemon[2372]: apparmor="DENIED" operation="dbus_method_call" bus="session" path="/test/agent" interface="org.bluez.obex.Agent1" member="AuthorizePush" name=":1.94" mask="receive" pid=5216 label="ratatoskr.philipa_ratatoskr_260115153557" peer_pid=3539 peer_label="unconfined"Clearly, the IPC between
obexdand the agent registered by my app seems to be blocked by AppArmor. This is the current AA profile for my app:{ "policy_groups": [ "bluetooth", "networking", "content_exchange", "content_exchange_source" ], "policy_version": 20.04 }Can anyone tell me what could be missing?
-
@PhAndersson said in Trying to revive 'ubtd' (Bluetooth file transfer):
AuthorizePush
this is denied; I never dabbled much with Apparmor, and certainly not with UT; I notice with some dismay that there are no apparmor logs and I have no clear idea on the better way to enable them unfortunately.
For now, I have only one positive thing to say: in the application that worked with 16.04, the template was set to 'unconfined'; while this is not generally a great idea, to advance your testing maybe it could be worth a try to add it to the apparmor profile ?