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; > } One thing that just occurred to me, can ETHTOOL_GET_TS_INFO be written as well? If it can we could make this just an ioctl operation where we attempt to enable so_timestamping field and then the kernel checks if it can be enabled, that way we don't have to introduce another to D-Bus since so_timestamping would only be enabled if bluetoothd had enabled it, that said we need to confirm that would fail with older kernels. > +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; > + > + 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