[RFCv3 31/43] bluetooth: Create sink for BlueZ 5 cards

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

 



From: Jo?o Paulo Rechi Vita <jprvita@xxxxxxxxxxxxx>

---
 src/modules/bluetooth/module-bluez5-device.c | 65 +++++++++++++++++++++++++++-
 1 file changed, 64 insertions(+), 1 deletion(-)

diff --git a/src/modules/bluetooth/module-bluez5-device.c b/src/modules/bluetooth/module-bluez5-device.c
index 9375be4..21f557b 100644
--- a/src/modules/bluetooth/module-bluez5-device.c
+++ b/src/modules/bluetooth/module-bluez5-device.c
@@ -72,6 +72,7 @@ struct userdata {
     bool transport_acquired;
 
     pa_card *card;
+    pa_sink *sink;
     pa_bluetooth_profile_t profile;
     char *output_port_name;
     char *input_port_name;
@@ -167,6 +168,25 @@ static const char *form_factor_to_string(pa_bluetooth_form_factor_t ff) {
     pa_assert_not_reached();
 }
 
+/* Run from main thread */
+static void connect_ports(struct userdata *u, void *new_data, pa_direction_t direction) {
+    pa_device_port *port;
+
+    if (direction == PA_DIRECTION_OUTPUT) {
+        pa_sink_new_data *sink_new_data = new_data;
+
+        pa_assert_se(port = pa_hashmap_get(u->card->ports, u->output_port_name));
+        pa_assert_se(pa_hashmap_put(sink_new_data->ports, port->name, port) >= 0);
+        pa_device_port_ref(port);
+    } else {
+        pa_source_new_data *source_new_data = new_data;
+
+        pa_assert_se(port = pa_hashmap_get(u->card->ports, u->input_port_name));
+        pa_assert_se(pa_hashmap_put(source_new_data->ports, port->name, port) >= 0);
+        pa_device_port_ref(port);
+    }
+}
+
 static int transport_acquire(struct userdata *u, bool optional) {
     pa_assert(u->transport);
 
@@ -186,6 +206,45 @@ static int transport_acquire(struct userdata *u, bool optional) {
 }
 
 /* Run from main thread */
+static int add_sink(struct userdata *u) {
+    pa_sink_new_data data;
+
+    pa_assert(u->transport);
+
+    pa_sink_new_data_init(&data);
+    data.module = u->module;
+    data.card = u->card;
+    data.driver = __FILE__;
+    data.name = pa_sprintf_malloc("bluez_sink.%s", u->device->address);
+    data.namereg_fail = false;
+    pa_proplist_sets(data.proplist, "bluetooth.protocol", pa_bluetooth_profile_to_string(u->profile));
+    pa_sink_new_data_set_sample_spec(&data, &u->sample_spec);
+
+    connect_ports(u, &data, PA_DIRECTION_OUTPUT);
+
+    if (!u->transport_acquired)
+        switch (u->profile) {
+            case PA_BLUETOOTH_PROFILE_A2DP_SINK:
+                /* Profile switch should have failed */
+            case PA_BLUETOOTH_PROFILE_A2DP_SOURCE:
+            case PA_BLUETOOTH_PROFILE_OFF:
+                pa_assert_not_reached();
+                break;
+        }
+
+    u->sink = pa_sink_new(u->core, &data, PA_SINK_HARDWARE|PA_SINK_LATENCY);
+    pa_sink_new_data_done(&data);
+    if (!u->sink) {
+        pa_log_error("Failed to create sink");
+        return -1;
+    }
+
+    u->sink->userdata = u;
+
+    return 0;
+}
+
+/* Run from main thread */
 static void transport_config(struct userdata *u) {
     sbc_info_t *sbc_info = &u->sbc_info;
     a2dp_sbc_t *config;
@@ -332,7 +391,11 @@ static int init_profile(struct userdata *u) {
 
     pa_assert(u->transport);
 
-    /* TODO: add sink/source */
+    if (u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK)
+        if (add_sink(u) < 0)
+            r = -1;
+
+    /* TODO: add source */
 
     return r;
 }
-- 
1.8.3.1



[Index of Archives]     [Linux Audio Users]     [AMD Graphics]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux