Re: [PATCH BlueZ v3 2/2] media: implement SupportedFeatures property

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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





[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux