@@ -54,7 +54,13 @@
#define CSIS_UUID_STR "00001846-0000-1000-8000-00805f9b34fb"
+struct csis_data {
+ struct btd_adapter *adapter;
+ struct bt_csip *csip;
+};
+
struct csip_data {
+ struct btd_adapter *adapter;
struct btd_device *device;
struct btd_service *service;
struct bt_csip *csip;
@@ -62,6 +68,7 @@ struct csip_data {
};
static struct queue *sessions;
+static struct queue *servers;
static void csip_debug(const char *str, void *user_data)
{
@@ -78,12 +85,6 @@ static struct csip_data *csip_data_new(struct btd_device *device)
return data;
}
-static bool csip_ltk_read(struct bt_csip *csip, uint8_t k[16], void *user_data)
-{
- /* TODO: Retrieve LTK using device object */
- return false;
-}
-
static void csip_data_add(struct csip_data *data)
{
DBG("data %p", data);
@@ -95,10 +96,6 @@ static void csip_data_add(struct csip_data *data)
bt_csip_set_debug(data->csip, csip_debug, NULL, NULL);
- bt_csip_set_sirk(data->csip, btd_opts.csis.encrypt, btd_opts.csis.sirk,
- btd_opts.csis.size, btd_opts.csis.rank,
- csip_ltk_read, data);
-
if (!sessions)
sessions = queue_new();
@@ -201,25 +198,6 @@ static void csip_attached(struct bt_csip *csip, void *user_data)
data->csip = csip;
csip_data_add(data);
-
-}
-
-static int csip_server_probe(struct btd_profile *p,
- struct btd_adapter *adapter)
-{
- struct btd_gatt_database *database = btd_adapter_get_database(adapter);
-
- DBG("CSIP path %s", adapter_get_path(adapter));
-
- bt_csip_add_db(btd_gatt_database_get_db(database));
-
- return 0;
-}
-
-static void csip_server_remove(struct btd_profile *p,
- struct btd_adapter *adapter)
-{
- DBG("CSIP remove Adapter");
}
static int csip_accept(struct btd_service *service)
@@ -332,9 +310,114 @@ static struct btd_profile csip_profile = {
.accept = csip_accept,
.disconnect = csip_disconnect,
- .adapter_probe = csip_server_probe,
- .adapter_remove = csip_server_remove,
+ .experimental = true,
+};
+static bool csis_ltk_read(struct bt_csip *csip, uint8_t k[16], void *user_data)
+{
+ /* TODO: Retrieve LTK using device object */
+ return false;
+}
+
+static void csis_data_add(struct csis_data *data)
+{
+ DBG("data %p", data);
+
+ if (queue_find(servers, NULL, data)) {
+ error("data %p already added", data);
+ return;
+ }
+
+ bt_csip_set_debug(data->csip, csip_debug, NULL, NULL);
+
+ bt_csip_set_sirk(data->csip, btd_opts.csis.encrypt, btd_opts.csis.sirk,
+ btd_opts.csis.size, btd_opts.csis.rank,
+ csis_ltk_read, data);
+
+ if (!servers)
+ servers = queue_new();
+
+ queue_push_tail(servers, data);
+}
+
+static struct csis_data *csis_data_new(struct btd_adapter *adapter)
+{
+ struct csis_data *data;
+
+ data = new0(struct csis_data, 1);
+ data->adapter = adapter;
+
+ return data;
+}
+
+static int csis_server_probe(struct btd_profile *p, struct btd_adapter *adapter)
+{
+ struct btd_gatt_database *database = btd_adapter_get_database(adapter);
+ struct csis_data *data;
+
+ DBG("path %s", adapter_get_path(adapter));
+
+ data = csis_data_new(adapter);
+
+ data->csip = bt_csip_new(btd_gatt_database_get_db(database), NULL);
+ if (!data->csip) {
+ error("Unable to create CSIP instance");
+ free(data);
+ return -EINVAL;
+ }
+
+ csis_data_add(data);
+
+ return 0;
+}
+
+static bool match_csis(const void *data, const void *match_data)
+{
+ const struct csis_data *csis = data;
+ const struct btd_adapter *adapter = match_data;
+
+ return csis->adapter == adapter;
+}
+
+static void csis_data_free(struct csis_data *data)
+{
+ bt_csip_unref(data->csip);
+ free(data);
+}
+
+static void csis_data_remove(struct csis_data *data)
+{
+ DBG("data %p", data);
+
+ csis_data_free(data);
+
+ if (queue_isempty(servers)) {
+ queue_destroy(servers, NULL);
+ servers = NULL;
+ }
+}
+
+static void csis_server_remove(struct btd_profile *p,
+ struct btd_adapter *adapter)
+{
+ struct csis_data *data;
+
+ DBG("path %s", adapter_get_path(adapter));
+
+ data = queue_remove_if(servers, match_csis, adapter);
+ if (!data)
+ return;
+
+ csis_data_remove(data);
+}
+
+static struct btd_profile csis_profile = {
+ .name = "csis",
+ .priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .local_uuid = CSIS_UUID_STR,
+
+ .adapter_probe = csis_server_probe,
+ .adapter_remove = csis_server_remove,
.experimental = true,
};
@@ -344,6 +427,10 @@ static int csip_init(void)
{
int err;
+ err = btd_profile_register(&csis_profile);
+ if (err)
+ return err;
+
err = btd_profile_register(&csip_profile);
if (err)
return err;
@@ -355,6 +442,7 @@ static int csip_init(void)
static void csip_exit(void)
{
+ btd_profile_unregister(&csis_profile);
btd_profile_unregister(&csip_profile);
bt_csip_unregister(csip_id);
}
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> adapter_probe callback shall register service the plugin wants to expose which was not the case for csip since it depended on a device to register the bt_csip instance which is then responsible to register its attributes, so this change it so there is a dedicated driver for CSIS which takes care of creating the necessary attributes and associate it with the adapter so it can be cleanup properly. --- profiles/audio/csip.c | 150 +++++++++++++++++++++++++++++++++--------- 1 file changed, 119 insertions(+), 31 deletions(-)