Hi Pauli, On Sun, Apr 27, 2025 at 12:25 PM Pauli Virtanen <pav@xxxxxx> wrote: > > Add org.bluez.Media.SupportedFeatures. Add feature tx-timestamping. > --- > > Notes: > v3: > - fix #includes > > v2: > - use SIOCETHTOOL to get kernel support > > profiles/audio/media.c | 74 ++++++++++++++++++++++++++++++++++++++++++ > src/adapter.h | 3 ++ > 2 files changed, 77 insertions(+) > > diff --git a/profiles/audio/media.c b/profiles/audio/media.c > index 69c6dc671..07264cfa1 100644 > --- a/profiles/audio/media.c > +++ b/profiles/audio/media.c > @@ -18,6 +18,17 @@ > #include <errno.h> > #include <inttypes.h> > > +#include <time.h> > +#include <stdio.h> > +#include <unistd.h> > +#include <linux/errqueue.h> > +#include <linux/net_tstamp.h> > +#include <linux/ethtool.h> > +#include <linux/sockios.h> > +#include <net/if.h> > +#include <sys/socket.h> > +#include <sys/ioctl.h> > + > #include <glib.h> > > #include "lib/bluetooth.h" > @@ -81,6 +92,7 @@ struct media_adapter { > #ifdef HAVE_AVRCP > GSList *players; /* Players list */ > #endif > + int so_timestamping; > }; > > struct endpoint_request { > @@ -3340,8 +3352,69 @@ static gboolean supported_uuids(const GDBusPropertyTable *property, > return TRUE; > } I would add a comment regarding the assumption that this depends on bluetoothd not threatening the errqueue events as errors, which is why it is important to have this exposed otherwise the clients don't know it can be safely enabled with use of ETHTOOL_GET_TS_INFO. > +static bool probe_tx_timestamping(struct media_adapter *adapter) > +{ > + struct ifreq ifr = {}; > + struct ethtool_ts_info cmd = {}; > + int sk = -1; > + > + if (adapter->so_timestamping != -1) > + goto done; > + > + snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "hci%u", > + btd_adapter_get_index(adapter->btd_adapter)); > + ifr.ifr_data = (void *)&cmd; > + cmd.cmd = ETHTOOL_GET_TS_INFO; I'd probably add a comment here saying that if one does support SIOCETHTOOL over L2CAP then it must be enabled to other MediaTransports, e.g. ISO. > + sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); > + if (sk < 0) > + goto error; > + if (ioctl(sk, SIOCETHTOOL, &ifr)) > + goto error; > + close(sk); > + > + adapter->so_timestamping = cmd.so_timestamping; > + > +done: > + return adapter->so_timestamping & SOF_TIMESTAMPING_TX_SOFTWARE; > + > +error: > + if (sk >= 0) > + close(sk); > + adapter->so_timestamping = 0; > + return false; > +} > + > +static const struct { > + const char *name; > + bool (*probe)(struct media_adapter *adapter); > +} features[] = { > + { "tx-timestamping", probe_tx_timestamping }, > +}; > + > +static gboolean supported_features(const GDBusPropertyTable *property, > + DBusMessageIter *iter, void *data) > +{ > + struct media_adapter *adapter = data; > + DBusMessageIter entry; > + size_t i; > + > + dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, > + DBUS_TYPE_STRING_AS_STRING, &entry); > + > + for (i = 0; i < ARRAY_SIZE(features); ++i) > + if (features[i].probe(adapter)) > + dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, > + &features[i].name); > + > + dbus_message_iter_close_container(iter, &entry); > + > + return TRUE; > +} > + > static const GDBusPropertyTable media_properties[] = { > { "SupportedUUIDs", "as", supported_uuids }, > + { "SupportedFeatures", "as", supported_features }, > { } > }; > > @@ -3383,6 +3456,7 @@ int media_register(struct btd_adapter *btd_adapter) > adapter = g_new0(struct media_adapter, 1); > adapter->btd_adapter = btd_adapter_ref(btd_adapter); > adapter->apps = queue_new(); > + adapter->so_timestamping = -1; > > if (!g_dbus_register_interface(btd_get_dbus_connection(), > adapter_get_path(btd_adapter), > diff --git a/src/adapter.h b/src/adapter.h > index 6b2bc28f6..9371cdefb 100644 > --- a/src/adapter.h > +++ b/src/adapter.h > @@ -262,6 +262,9 @@ bool btd_le_connect_before_pairing(void); > > bool btd_adapter_has_settings(struct btd_adapter *adapter, uint32_t settings); > > +int btd_adapter_get_so_timestamping(struct btd_adapter *adapter, int proto, > + int *so_timestamping); > + > enum experimental_features { > EXP_FEAT_DEBUG = 1 << 0, > EXP_FEAT_LE_SIMULT_ROLES = 1 << 1, > -- > 2.49.0 > > -- Luiz Augusto von Dentz