diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c
index 50c0f43..177f653 100644
--- a/profiles/audio/a2dp.c
+++ b/profiles/audio/a2dp.c
return NULL;
}
-int a2dp_register(const bdaddr_t *src, GKeyFile *config)
+static struct a2dp_server *a2dp_server_register(const bdaddr_t *src,
+ GKeyFile *config)
{
- gboolean source = TRUE, sink = FALSE;
- char *str;
- GError *err = NULL;
struct a2dp_server *server;
+ int av_err;
- if (!config)
- goto proceed;
+ server = g_new0(struct a2dp_server, 1);
- str = g_key_file_get_string(config, "General", "Enable", &err);
-
- if (err) {
- DBG("audio.conf: %s", err->message);
- g_clear_error(&err);
- } else {
- if (strstr(str, "Sink"))
- source = TRUE;
- if (strstr(str, "Source"))
- sink = TRUE;
- g_free(str);
+ av_err = avdtp_init(src, config);
+ if (av_err < 0) {
+ DBG("AVDTP not registered");
+ g_free(server);
+ return NULL;
}
- str = g_key_file_get_string(config, "General", "Disable", &err);
+ bacpy(&server->src, src);
+ servers = g_slist_append(servers, server);
- if (err) {
- DBG("audio.conf: %s", err->message);
- g_clear_error(&err);
- } else {
- if (strstr(str, "Sink"))
- source = FALSE;
- if (strstr(str, "Source"))
- sink = FALSE;
- g_free(str);
- }
+ return server;
+}
-proceed:
+int a2dp_source_register(const bdaddr_t *src, GKeyFile *config)
+{
+ struct a2dp_server *server;
server = find_server(servers, src);
- if (!server) {
- int av_err;
+ if (server != NULL)
+ goto done;
- server = g_new0(struct a2dp_server, 1);
+ server = a2dp_server_register(src, config);
+ if (server == NULL)
+ return -EPROTONOSUPPORT;
- av_err = avdtp_init(src, config);
- if (av_err < 0) {
- g_free(server);
- return av_err;
- }
+done:
+ server->source_enabled = TRUE;
- bacpy(&server->src, src);
- servers = g_slist_append(servers, server);
- }
+ return 0;
+}
- server->source_enabled = source;
+int a2dp_sink_register(const bdaddr_t *src, GKeyFile *config)
+{
+ struct a2dp_server *server;
- server->sink_enabled = sink;
+ server = find_server(servers, src);
+ if (server != NULL)
+ goto done;
+
+ server = a2dp_server_register(src, config);
+ if (server == NULL)
+ return -EPROTONOSUPPORT;
+
+done:
+ server->sink_enabled = TRUE;
return 0;
}
diff --git a/profiles/audio/a2dp.h b/profiles/audio/a2dp.h
index 736bc66..ded1060 100644
--- a/profiles/audio/a2dp.h
+++ b/profiles/audio/a2dp.h
struct avdtp_error *err,
void *user_data);
-int a2dp_register(const bdaddr_t *src, GKeyFile *config);
+int a2dp_source_register(const bdaddr_t *src, GKeyFile *config);
+int a2dp_sink_register(const bdaddr_t *src, GKeyFile *config);
void a2dp_unregister(const bdaddr_t *src);
struct a2dp_sep *a2dp_add_sep(const bdaddr_t *src, uint8_t type,
diff --git a/profiles/audio/manager.c b/profiles/audio/manager.c
index e453e26..2f36efd 100644
--- a/profiles/audio/manager.c
+++ b/profiles/audio/manager.c
audio_device_unregister(dev);
}
-static int a2dp_probe(struct btd_profile *p, struct btd_device *device,
+static int a2dp_source_probe(struct btd_profile *p, struct btd_device *device,
GSList *uuids)
{
struct audio_device *audio_dev;
return -1;
}
- if (g_slist_find_custom(uuids, A2DP_SINK_UUID, bt_uuid_strcmp) &&
- audio_dev->sink == NULL)
- audio_dev->sink = sink_init(audio_dev);
+ audio_dev->source = source_init(audio_dev);
- if (g_slist_find_custom(uuids, A2DP_SOURCE_UUID, bt_uuid_strcmp) &&
- audio_dev->source == NULL)
- audio_dev->source = source_init(audio_dev);
+ return 0;
+}
+
+static int a2dp_sink_probe(struct btd_profile *p, struct btd_device *device,
+ GSList *uuids)
+{
+ struct audio_device *audio_dev;
+
+ audio_dev = get_audio_dev(device);
+ if (!audio_dev) {
+ DBG("unable to get a device object");
+ return -1;
+ }
+
+ audio_dev->sink = sink_init(audio_dev);
return 0;
}
return adp;
}
-static int a2dp_server_probe(struct btd_profile *p,
+static int a2dp_source_server_probe(struct btd_profile *p,
struct btd_adapter *adapter)
{
struct audio_adapter *adp;
const gchar *path = adapter_get_path(adapter);
- int err;
DBG("path %s", path);
if (!adp)
return -EINVAL;
- err = a2dp_register(adapter_get_address(adapter), config);
- if (err < 0)
- audio_adapter_unref(adp);
+ audio_adapter_unref(adp); /* Referenced by a2dp server */
- return err;
+ return a2dp_source_register(adapter_get_address(adapter), config);
}
-static void a2dp_server_remove(struct btd_profile *p,
+static int a2dp_sink_server_probe(struct btd_profile *p,
struct btd_adapter *adapter)
{
struct audio_adapter *adp;
DBG("path %s", path);
- adp = find_adapter(adapters, adapter);
+ adp = audio_adapter_get(adapter);
if (!adp)
- return;
+ return -EINVAL;
- a2dp_unregister(adapter_get_address(adapter));
- audio_adapter_unref(adp);
+ audio_adapter_unref(adp); /* Referenced by a2dp server */
+
+ return a2dp_sink_register(adapter_get_address(adapter), config);
}
static int avrcp_server_probe(struct btd_profile *p,
audio_adapter_unref(adp);
}
-static struct btd_profile a2dp_profile = {
- .name = "audio-a2dp",
+static struct btd_profile a2dp_source_profile = {
+ .name = "audio-source",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
- .remote_uuids = BTD_UUIDS(A2DP_SOURCE_UUID, A2DP_SINK_UUID,
- ADVANCED_AUDIO_UUID),
- .device_probe = a2dp_probe,
+ .remote_uuids = BTD_UUIDS(A2DP_SOURCE_UUID),
+ .device_probe = a2dp_source_probe,
.device_remove = audio_remove,
- .adapter_probe = a2dp_server_probe,
- .adapter_remove = a2dp_server_remove,
+ .adapter_probe = a2dp_source_server_probe,
+};
+
+static struct btd_profile a2dp_sink_profile = {
+ .name = "audio-sink",
+ .priority = BTD_PROFILE_PRIORITY_MEDIUM,
+
+ .remote_uuids = BTD_UUIDS(A2DP_SINK_UUID),
+ .device_probe = a2dp_sink_probe,
+ .device_remove = audio_remove,
+
+ .adapter_probe = a2dp_sink_server_probe,
};
static struct btd_profile avrcp_profile = {
max_connected_headsets = i;
proceed:
- if (enabled.source || enabled.sink)
- btd_profile_register(&a2dp_profile);
+ if (enabled.source)
+ btd_profile_register(&a2dp_source_profile);
+
+ if (enabled.sink)
+ btd_profile_register(&a2dp_sink_profile);
if (enabled.control)
btd_profile_register(&avrcp_profile);
config = NULL;
}
- if (enabled.source || enabled.sink)
- btd_profile_unregister(&a2dp_profile);
+ if (enabled.source)
+ btd_profile_unregister(&a2dp_source_profile);
+
+ if (enabled.sink)
+ btd_profile_unregister(&a2dp_sink_profile);
if (enabled.control)
btd_profile_unregister(&avrcp_profile);