Re: [PATCH BlueZ v3 5/9] obexd: Add BIP client for AVRCP cover art download

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

 



Hi Frédéric,

On Mon, Sep 16, 2024 at 9:28 AM Frédéric Danis
<frederic.danis@xxxxxxxxxxxxx> wrote:
>
> The cover art image handle is available in the metadata of the track
> when the OBEX BIP session is connected to the PSM port provided
> in AVRCP SDP record and available as org.bluez.MediaPlayer property.
>
> This service allows to get the thumbnail.
> ---
>  Makefile.obexd         |   1 +
>  obexd/client/bip.c     | 171 +++++++++++++++++++++++++++++++++++++++++
>  obexd/client/bip.h     |  12 +++
>  obexd/client/manager.c |   2 +
>  4 files changed, 186 insertions(+)
>  create mode 100644 obexd/client/bip.c
>  create mode 100644 obexd/client/bip.h
>
> diff --git a/Makefile.obexd b/Makefile.obexd
> index 4cdce73af..866147dd1 100644
> --- a/Makefile.obexd
> +++ b/Makefile.obexd
> @@ -81,6 +81,7 @@ obexd_src_obexd_SOURCES = $(btio_sources) $(gobex_sources) \
>                         obexd/client/ftp.h obexd/client/ftp.c \
>                         obexd/client/opp.h obexd/client/opp.c \
>                         obexd/client/map.h obexd/client/map.c \
> +                       obexd/client/bip.h obexd/client/bip.c \
>                         obexd/client/map-event.h obexd/client/map-event.c \
>                         obexd/client/transfer.h obexd/client/transfer.c \
>                         obexd/client/transport.h obexd/client/transport.c \
> diff --git a/obexd/client/bip.c b/obexd/client/bip.c
> new file mode 100644
> index 000000000..f4af2834b
> --- /dev/null
> +++ b/obexd/client/bip.c
> @@ -0,0 +1,171 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + *
> + *  OBEX Client
> + *
> + *  Copyright (C) 2024  Collabora Ltd.
> + *
> + *
> + */
> +
> +#define _GNU_SOURCE
> +#include <errno.h>
> +#include <stdlib.h>
> +#include <string.h>
> +
> +#include "gdbus/gdbus.h"
> +#include "gobex/gobex.h"
> +
> +#include "obexd/src/log.h"
> +#include "transfer.h"
> +#include "session.h"
> +#include "driver.h"
> +#include "bip.h"
> +
> +#define OBEX_BIP_AVRCP_UUID \
> +       "\x71\x63\xDD\x54\x4A\x7E\x11\xE2\xB4\x7C\x00\x50\xC2\x49\x00\x48"
> +#define OBEX_BIP_AVRCP_UUID_LEN 16
> +
> +#define BIP_AVRCP_INTERFACE "org.bluez.obex.BipAvrcp1"

I'd go with org.bluez.obex.Image and then work the details of BIP vs
BIP-AVRCP internally.

> +#define ERROR_INTERFACE "org.bluez.obex.Error"
> +#define BIP_AVRCP_UUID "0000111A-0000-1000-8000-00805f9b34fb"
> +
> +#define IMG_HANDLE_TAG  0x30
> +
> +static DBusConnection *conn;
> +
> +struct bip_avrcp_data {
> +       struct obc_session *session;
> +};
> +
> +static DBusMessage *get_image_thumbnail(DBusConnection *connection,
> +                                       DBusMessage *message, void *user_data)
> +{
> +       struct bip_avrcp_data *bip_avrcp = user_data;
> +       const char *handle = NULL, *image_path = NULL;
> +       struct obc_transfer *transfer;
> +       GObexHeader *header;
> +       DBusMessage *reply = NULL;
> +       GError *err = NULL;
> +
> +       DBG("");
> +
> +       if (dbus_message_get_args(message, NULL,
> +                               DBUS_TYPE_STRING, &image_path,
> +                               DBUS_TYPE_STRING, &handle,
> +                               DBUS_TYPE_INVALID) == FALSE) {
> +               reply = g_dbus_create_error(message,
> +                               ERROR_INTERFACE ".InvalidArguments", NULL);
> +               return reply;
> +       }
> +
> +       transfer = obc_transfer_get("x-bt/img-thm", NULL, image_path, &err);
> +       if (transfer == NULL)
> +               goto fail;
> +
> +       header = g_obex_header_new_unicode(IMG_HANDLE_TAG, handle);
> +       obc_transfer_add_header(transfer, header);
> +
> +       if (!obc_session_queue(bip_avrcp->session, transfer, NULL, NULL, &err))
> +               goto fail;
> +
> +       return obc_transfer_create_dbus_reply(transfer, message);
> +
> +fail:
> +       reply = g_dbus_create_error(message, ERROR_INTERFACE ".Failed", "%s",
> +                                                               err->message);
> +       g_error_free(err);
> +       return reply;
> +}
> +
> +static const GDBusMethodTable bip_avrcp_methods[] = {
> +       { GDBUS_ASYNC_METHOD("GetImageThumbnail",

If we rename the interface to Image then this can be just "GetThumbnail".

> +               GDBUS_ARGS({ "file", "s" }, { "handle", "s"}),
> +               GDBUS_ARGS({ "transfer", "o" }, { "properties", "a{sv}" }),
> +               get_image_thumbnail) },
> +       { }
> +};
> +
> +static void bip_avrcp_free(void *data)
> +{
> +       struct bip_avrcp_data *bip_avrcp = data;
> +
> +       obc_session_unref(bip_avrcp->session);
> +       g_free(bip_avrcp);
> +}
> +
> +static int bip_avrcp_probe(struct obc_session *session)
> +{
> +       struct bip_avrcp_data *bip_avrcp;
> +       const char *path;
> +
> +       path = obc_session_get_path(session);
> +
> +       DBG("%s", path);
> +
> +       bip_avrcp = g_try_new0(struct bip_avrcp_data, 1);
> +       if (!bip_avrcp)
> +               return -ENOMEM;
> +
> +       bip_avrcp->session = obc_session_ref(session);
> +
> +       if (!g_dbus_register_interface(conn, path, BIP_AVRCP_INTERFACE,
> +                                       bip_avrcp_methods,
> +                                       NULL, NULL,
> +                                       bip_avrcp, bip_avrcp_free)) {
> +               bip_avrcp_free(bip_avrcp);
> +               return -ENOMEM;
> +       }
> +
> +       return 0;
> +}
> +
> +static void bip_avrcp_remove(struct obc_session *session)
> +{
> +       const char *path = obc_session_get_path(session);
> +
> +       DBG("%s", path);
> +
> +       g_dbus_unregister_interface(conn, path, BIP_AVRCP_INTERFACE);
> +}
> +
> +static struct obc_driver bip_avrcp = {
> +       .service = "BIP-AVRCP",
> +       .uuid = BIP_AVRCP_UUID,
> +       .target = OBEX_BIP_AVRCP_UUID,
> +       .target_len = OBEX_BIP_AVRCP_UUID_LEN,
> +       .probe = bip_avrcp_probe,
> +       .remove = bip_avrcp_remove
> +};
> +
> +int bip_init(void)
> +{
> +       int err;
> +
> +       DBG("");
> +
> +       conn = dbus_bus_get(DBUS_BUS_SESSION, NULL);
> +       if (!conn)
> +               return -EIO;
> +
> +       err = obc_driver_register(&bip_avrcp);
> +       if (err < 0)
> +               goto failed;
> +
> +       return 0;
> +
> +failed:
> +       dbus_connection_unref(conn);
> +       conn = NULL;
> +       return err;
> +}
> +
> +void bip_exit(void)
> +{
> +       DBG("");
> +
> +       dbus_connection_unref(conn);
> +       conn = NULL;
> +
> +       obc_driver_unregister(&bip_avrcp);
> +}
> diff --git a/obexd/client/bip.h b/obexd/client/bip.h
> new file mode 100644
> index 000000000..18e3360f3
> --- /dev/null
> +++ b/obexd/client/bip.h
> @@ -0,0 +1,12 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + *
> + *  OBEX Client
> + *
> + *  Copyright (C) 2024  Collabora Ltd.
> + *
> + *
> + */
> +
> +int bip_init(void);
> +void bip_exit(void);
> diff --git a/obexd/client/manager.c b/obexd/client/manager.c
> index 52c00fb0c..52f4d0179 100644
> --- a/obexd/client/manager.c
> +++ b/obexd/client/manager.c
> @@ -32,6 +32,7 @@
>  #include "pbap.h"
>  #include "sync.h"
>  #include "map.h"
> +#include "bip.h"
>  #include "manager.h"
>
>  #define CLIENT_INTERFACE       "org.bluez.obex.Client1"
> @@ -258,6 +259,7 @@ static const struct obc_module {
>         { "pbap", pbap_init, pbap_exit },
>         { "sync", sync_init, sync_exit },
>         { "map", map_init, map_exit },
> +       { "bip", bip_init, bip_exit },
>         { }
>  };
>
> --
> 2.34.1
>
>


-- 
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