profiles: Add Support for Metadata, CID and VID
authorMaheta, Abhay <abhay.maheshbhai.maheta@intel.com>
Mon, 23 Jan 2023 23:56:45 +0000 (15:56 -0800)
committerAyush Garg <ayush.garg@samsung.com>
Fri, 5 Jan 2024 10:19:00 +0000 (15:49 +0530)
This adds support for Metadata, Company ID and Vendor Codec ID

profiles/audio/bap.c
profiles/audio/media.c
profiles/audio/transport.c

index f7628a2..421ef71 100644 (file)
@@ -486,6 +486,9 @@ static DBusMessage *set_configuration(DBusConnection *conn, DBusMessage *msg,
        bt_bap_stream_set_user_data(ep->stream, ep->path);
        ep->msg = dbus_message_ref(msg);
 
+       if (ep->metadata && ep->metadata->iov_len)
+               bt_bap_stream_metadata(ep->stream, ep->metadata, NULL, NULL);
+
        return NULL;
 }
 
@@ -635,8 +638,10 @@ static void select_cb(struct bt_bap_pac *pac, int err, struct iovec *caps,
 
        ep->caps = util_iov_dup(caps, 1);
 
-       if (metadata && metadata->iov_base && metadata->iov_len)
+       if (metadata && metadata->iov_base && metadata->iov_len) {
                ep->metadata = util_iov_dup(metadata, 1);
+               bt_bap_stream_metadata(ep->stream, ep->metadata, NULL, NULL);
+       }
 
        ep->qos = *qos;
 
index 4379447..1aea761 100644 (file)
@@ -107,10 +107,14 @@ struct media_endpoint {
        char                    *path;          /* Endpoint object path */
        char                    *uuid;          /* Endpoint property UUID */
        uint8_t                 codec;          /* Endpoint codec */
+       uint16_t                cid;            /* Endpoint company ID */
+       uint16_t                vid;            /* Endpoint vendor codec ID */
        bool                    delay_reporting;/* Endpoint delay_reporting */
        struct bt_bap_pac_qos   qos;            /* Endpoint qos */
        uint8_t                 *capabilities;  /* Endpoint property capabilities */
        size_t                  size;           /* Endpoint capabilities size */
+       uint8_t                 *metadata;      /* Endpoint property metadata */
+       size_t                  metadata_size;  /* Endpoint metadata size */
        guint                   hs_watch;
        guint                   ag_watch;
        guint                   watch;
@@ -217,6 +221,7 @@ static void media_endpoint_destroy(struct media_endpoint *endpoint)
 
        g_dbus_remove_watch(btd_get_dbus_connection(), endpoint->watch);
        g_free(endpoint->capabilities);
+       g_free(endpoint->metadata);
        g_free(endpoint->sender);
        g_free(endpoint->path);
        g_free(endpoint->uuid);
@@ -1319,6 +1324,7 @@ static bool endpoint_init_pac(struct media_endpoint *endpoint, uint8_t type,
        struct btd_gatt_database *database;
        struct gatt_db *db;
        struct iovec data;
+       struct iovec *metadata = NULL;
        char *name;
 
        if (!(g_dbus_get_flags() & G_DBUS_FLAG_ENABLE_EXPERIMENTAL)) {
@@ -1339,23 +1345,36 @@ static bool endpoint_init_pac(struct media_endpoint *endpoint, uint8_t type,
                return false;
        }
 
+       if (!bap_print_cc(endpoint->metadata, endpoint->metadata_size,
+                                       bap_debug, NULL)) {
+               error("Unable to parse endpoint metadata");
+               return false;
+       }
+
        db = btd_gatt_database_get_db(database);
 
        data.iov_base = endpoint->capabilities;
        data.iov_len = endpoint->size;
 
-       /* TODO: Add support for metadata */
-
        if (asprintf(&name, "%s:%s", endpoint->sender, endpoint->path) < 0) {
                error("Could not allocate name for pac %s:%s",
                                endpoint->sender, endpoint->path);
                return false;
        }
 
-       endpoint->pac = bt_bap_add_pac(db, name, type, endpoint->codec,
-                                       &endpoint->qos, &data, NULL);
+       /* TODO: Add support for metadata */
+       if (endpoint->metadata_size) {
+               metadata = g_new0(struct iovec, 1);
+               metadata->iov_base = endpoint->metadata;
+               metadata->iov_len = endpoint->metadata_size;
+       }
+
+       endpoint->pac = bt_bap_add_vendor_pac(db, name, type, endpoint->codec,
+                               endpoint->cid, endpoint->vid, &endpoint->qos,
+                               &data, metadata);
        if (!endpoint->pac) {
                error("Unable to create PAC");
+               free(metadata);
                return false;
        }
 
@@ -1364,6 +1383,7 @@ static bool endpoint_init_pac(struct media_endpoint *endpoint, uint8_t type,
        DBG("PAC %s registered", name);
 
        free(name);
+       free(metadata);
 
        return true;
 }
@@ -1493,9 +1513,13 @@ media_endpoint_create(struct media_adapter *adapter,
                                                const char *uuid,
                                                gboolean delay_reporting,
                                                uint8_t codec,
+                                               uint16_t cid,
+                                               uint16_t vid,
                                                struct bt_bap_pac_qos *qos,
                                                uint8_t *capabilities,
                                                int size,
+                                               uint8_t *metadata,
+                                               int metadata_size,
                                                int *err)
 {
        struct media_endpoint *endpoint;
@@ -1506,6 +1530,8 @@ media_endpoint_create(struct media_adapter *adapter,
        endpoint->path = g_strdup(path);
        endpoint->uuid = g_strdup(uuid);
        endpoint->codec = codec;
+       endpoint->cid = cid;
+       endpoint->vid = vid;
        endpoint->delay_reporting = delay_reporting;
 
        if (qos)
@@ -1517,6 +1543,12 @@ media_endpoint_create(struct media_adapter *adapter,
                endpoint->size = size;
        }
 
+       if (metadata_size > 0) {
+               endpoint->metadata = g_new(uint8_t, metadata_size);
+               memcpy(endpoint->metadata, metadata, metadata_size);
+               endpoint->metadata_size = metadata_size;
+       }
+
        endpoint->adapter = adapter;
 
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
@@ -1594,8 +1626,10 @@ media_endpoint_create(struct media_adapter *adapter,
 
 static int parse_properties(DBusMessageIter *props, const char **uuid,
                                gboolean *delay_reporting, uint8_t *codec,
+                               uint16_t *cid, uint16_t *vid,
                                struct bt_bap_pac_qos *qos,
-                               uint8_t **capabilities, int *size)
+                               uint8_t **capabilities, int *size,
+                               uint8_t **metadata, int *metadata_size)
 {
        gboolean has_uuid = FALSE;
        gboolean has_codec = FALSE;
@@ -1622,6 +1656,15 @@ static int parse_properties(DBusMessageIter *props, const char **uuid,
                                return -EINVAL;
                        dbus_message_iter_get_basic(&value, codec);
                        has_codec = TRUE;
+               } else if (strcasecmp(key, "Vendor") == 0) {
+                       if (var != DBUS_TYPE_UINT16)
+                               return -EINVAL;
+                       dbus_message_iter_get_basic(&value, cid);
+                       dbus_message_iter_next(&value);
+                       var = dbus_message_iter_get_arg_type(&value);
+                       if (var != DBUS_TYPE_UINT16)
+                               return -EINVAL;
+                       dbus_message_iter_get_basic(&value, vid);
                } else if (strcasecmp(key, "DelayReporting") == 0) {
                        if (var != DBUS_TYPE_BOOLEAN)
                                return -EINVAL;
@@ -1635,6 +1678,15 @@ static int parse_properties(DBusMessageIter *props, const char **uuid,
                        dbus_message_iter_recurse(&value, &array);
                        dbus_message_iter_get_fixed_array(&array, capabilities,
                                                        size);
+               } else if (strcasecmp(key, "Metadata") == 0) {
+                       DBusMessageIter array;
+
+                       if (var != DBUS_TYPE_ARRAY)
+                               return -EINVAL;
+
+                       dbus_message_iter_recurse(&value, &array);
+                       dbus_message_iter_get_fixed_array(&array, metadata,
+                                                       metadata_size);
                } else if (strcasecmp(key, "Framing") == 0) {
                        if (var != DBUS_TYPE_BYTE)
                                return -EINVAL;
@@ -1747,9 +1799,13 @@ static DBusMessage *register_endpoint(DBusConnection *conn, DBusMessage *msg,
        const char *sender, *path, *uuid;
        gboolean delay_reporting = FALSE;
        uint8_t codec = 0;
+       uint16_t cid = 0;
+       uint16_t vid = 0;
        struct bt_bap_pac_qos qos = {};
        uint8_t *capabilities = NULL;
+       uint8_t *metadata = NULL;
        int size = 0;
+       int metadata_size = 0;
        int err;
 
        sender = dbus_message_get_sender(msg);
@@ -1766,14 +1822,16 @@ static DBusMessage *register_endpoint(DBusConnection *conn, DBusMessage *msg,
        if (dbus_message_iter_get_arg_type(&props) != DBUS_TYPE_DICT_ENTRY)
                return btd_error_invalid_args(msg);
 
-       if (parse_properties(&props, &uuid, &delay_reporting, &codec, &qos,
-                                               &capabilities, &size) < 0)
+       if (parse_properties(&props, &uuid, &delay_reporting, &codec, &cid,
+                       &vid, &qos, &capabilities, &size, &metadata,
+                       &metadata_size) < 0)
                return btd_error_invalid_args(msg);
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
        current_delay_reporting = delay_reporting;
 #endif
        if (media_endpoint_create(adapter, sender, path, uuid, delay_reporting,
-                               codec, &qos, capabilities, size,
+                                       codec, cid, vid, &qos, capabilities,
+                                       size, metadata, metadata_size,
                                &err) == NULL) {
                if (err == -EPROTONOSUPPORT)
                        return btd_error_not_supported(msg);
@@ -2903,9 +2961,13 @@ static void app_register_endpoint(void *data, void *user_data)
        const char *uuid;
        gboolean delay_reporting = FALSE;
        uint8_t codec;
+       uint16_t cid = 0;
+       uint16_t vid = 0;
        struct bt_bap_pac_qos qos;
        uint8_t *capabilities = NULL;
        int size = 0;
+       uint8_t *metadata = NULL;
+       int metadata_size = 0;
        DBusMessageIter iter, array;
        struct media_endpoint *endpoint;
 
@@ -2932,6 +2994,19 @@ static void app_register_endpoint(void *data, void *user_data)
 
        dbus_message_iter_get_basic(&iter, &codec);
 
+       if (g_dbus_proxy_get_property(proxy, "Vendor", &iter)) {
+               if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT16)
+                       goto fail;
+
+               dbus_message_iter_get_basic(&iter, &cid);
+
+               dbus_message_iter_next(&iter);
+               if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT16)
+                       goto fail;
+
+               dbus_message_iter_get_basic(&iter, &vid);
+       }
+
        /* DelayReporting and Capabilities are considered optional */
        if (g_dbus_proxy_get_property(proxy, "DelayReporting", &iter))  {
                if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_BOOLEAN)
@@ -2948,6 +3023,15 @@ static void app_register_endpoint(void *data, void *user_data)
                dbus_message_iter_get_fixed_array(&array, &capabilities, &size);
        }
 
+       if (g_dbus_proxy_get_property(proxy, "Metadata", &iter)) {
+               if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
+                       goto fail;
+
+               dbus_message_iter_recurse(&iter, &array);
+               dbus_message_iter_get_fixed_array(&array, &metadata,
+                                               &metadata_size);
+       }
+
        /* Parse QoS preferences */
        memset(&qos, 0, sizeof(qos));
        if (g_dbus_proxy_get_property(proxy, "Framing", &iter)) {
@@ -3000,8 +3084,10 @@ static void app_register_endpoint(void *data, void *user_data)
        }
 
        endpoint = media_endpoint_create(app->adapter, app->sender, path, uuid,
-                                               delay_reporting, codec, &qos,
-                                               capabilities, size, &app->err);
+                                               delay_reporting, codec, cid,
+                                               vid, &qos, capabilities,
+                                               size, metadata, metadata_size,
+                                               &app->err);
        if (!endpoint) {
                error("Unable to register endpoint %s:%s: %s", app->sender,
                                                path, strerror(-app->err));
index b40af10..9d7d32d 100644 (file)
@@ -1279,6 +1279,7 @@ static guint resume_bap(struct media_transport *transport,
                                struct media_owner *owner)
 {
        struct bap_transport *bap = transport->data;
+       struct iovec *meta;
        guint id;
 
        if (!bap->stream)
@@ -1296,7 +1297,8 @@ static guint resume_bap(struct media_transport *transport,
                return g_idle_add(resume_complete, transport);
        }
 
-       id = bt_bap_stream_enable(bap->stream, bap->linked, NULL,
+       meta = bt_bap_stream_get_metadata(bap->stream);
+       id = bt_bap_stream_enable(bap->stream, bap->linked, meta,
                                        bap_enable_complete, owner);
        if (!id)
                return 0;