Hi Luiz, ma, 2025-04-28 kello 10:49 -0400, Luiz Augusto von Dentz kirjoitti: > 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. There does not appear to be ETHTOOL_SET_TS_INFO or equivalent for netdev, the information comes from drivers where it is hardcoded. So if we want that, it would be a new API. Designing new APIs, one might want instead to take another shot at the NO_POLL_ERRQUEUE thing, but maybe lower in the netdev core stack. > > +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 > > > > > -- Pauli Virtanen