[pulseaudio-discuss] [RFCv3 28/43] bluetooth: Create BlueZ 5 card ports

jprvita at gmail.com jprvita at gmail.com
Fri Sep 13 16:34:35 PDT 2013


From: João Paulo Rechi Vita <jprvita at openbossa.org>

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

diff --git a/src/modules/bluetooth/module-bluez5-device.c b/src/modules/bluetooth/module-bluez5-device.c
index ecde38c..b10799f 100644
--- a/src/modules/bluetooth/module-bluez5-device.c
+++ b/src/modules/bluetooth/module-bluez5-device.c
@@ -56,6 +56,8 @@ struct userdata {
 
     pa_card *card;
     pa_bluetooth_profile_t profile;
+    char *output_port_name;
+    char *input_port_name;
 };
 
 typedef enum pa_bluetooth_form_factor {
@@ -173,6 +175,143 @@ static char *cleanup_name(const char *name) {
 }
 
 /* Run from main thread */
+static pa_direction_t get_profile_direction(pa_bluetooth_profile_t p) {
+    static const pa_direction_t profile_direction[] = {
+        [PA_BLUETOOTH_PROFILE_A2DP_SINK] = PA_DIRECTION_OUTPUT,
+        [PA_BLUETOOTH_PROFILE_A2DP_SOURCE] = PA_DIRECTION_INPUT,
+        [PA_BLUETOOTH_PROFILE_OFF] = 0
+    };
+
+    return profile_direction[p];
+}
+
+/* Run from main thread */
+static pa_available_t get_port_availability(struct userdata *u, pa_direction_t direction) {
+    pa_available_t result = PA_AVAILABLE_NO;
+    unsigned i;
+
+    pa_assert(u);
+    pa_assert(u->device);
+
+    for (i = 0; i < PA_BLUETOOTH_PROFILE_COUNT; i++) {
+        pa_bluetooth_transport *transport;
+
+        if (!(get_profile_direction(i) & direction))
+            continue;
+
+        if (!(transport = u->device->transports[i]))
+            continue;
+
+        switch(transport->state) {
+            case PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED:
+                continue;
+
+            case PA_BLUETOOTH_TRANSPORT_STATE_IDLE:
+                if (result == PA_AVAILABLE_NO)
+                    result = PA_AVAILABLE_UNKNOWN;
+
+                break;
+
+            case PA_BLUETOOTH_TRANSPORT_STATE_PLAYING:
+                return PA_AVAILABLE_YES;
+        }
+    }
+
+    return result;
+}
+
+/* Run from main thread */
+static void create_card_ports(struct userdata *u, pa_hashmap *ports) {
+    pa_device_port *port;
+    pa_device_port_new_data port_data;
+    const char *name_prefix, *input_description, *output_description;
+
+    pa_assert(u);
+    pa_assert(ports);
+    pa_assert(u->device);
+
+    name_prefix = "unknown";
+    input_description = _("Bluetooth Input");
+    output_description = _("Bluetooth Output");
+
+    switch (form_factor_from_class(u->device->class_of_device)) {
+        case PA_BLUETOOTH_FORM_FACTOR_HEADSET:
+            name_prefix = "headset";
+            input_description = output_description = _("Headset");
+            break;
+
+        case PA_BLUETOOTH_FORM_FACTOR_HANDSFREE:
+            name_prefix = "handsfree";
+            input_description = output_description = _("Handsfree");
+            break;
+
+        case PA_BLUETOOTH_FORM_FACTOR_MICROPHONE:
+            name_prefix = "microphone";
+            input_description = _("Microphone");
+            output_description = _("Bluetooth Output");
+            break;
+
+        case PA_BLUETOOTH_FORM_FACTOR_SPEAKER:
+            name_prefix = "speaker";
+            input_description = _("Bluetooth Input");
+            output_description = _("Speaker");
+            break;
+
+        case PA_BLUETOOTH_FORM_FACTOR_HEADPHONE:
+            name_prefix = "headphone";
+            input_description = _("Bluetooth Input");
+            output_description = _("Headphone");
+            break;
+
+        case PA_BLUETOOTH_FORM_FACTOR_PORTABLE:
+            name_prefix = "portable";
+            input_description = output_description = _("Portable");
+            break;
+
+        case PA_BLUETOOTH_FORM_FACTOR_CAR:
+            name_prefix = "car";
+            input_description = output_description = _("Car");
+            break;
+
+        case PA_BLUETOOTH_FORM_FACTOR_HIFI:
+            name_prefix = "hifi";
+            input_description = output_description = _("HiFi");
+            break;
+
+        case PA_BLUETOOTH_FORM_FACTOR_PHONE:
+            name_prefix = "phone";
+            input_description = output_description = _("Phone");
+            break;
+
+        case PA_BLUETOOTH_FORM_FACTOR_UNKNOWN:
+            name_prefix = "unknown";
+            input_description = _("Bluetooth Input");
+            output_description = _("Bluetooth Output");
+            break;
+    }
+
+    u->output_port_name = pa_sprintf_malloc("%s-output", name_prefix);
+    pa_device_port_new_data_init(&port_data);
+    pa_device_port_new_data_set_name(&port_data, u->output_port_name);
+    pa_device_port_new_data_set_description(&port_data, output_description);
+    pa_device_port_new_data_set_direction(&port_data, PA_DIRECTION_OUTPUT);
+    pa_device_port_new_data_set_available(&port_data, get_port_availability(u, PA_DIRECTION_OUTPUT));
+    pa_assert_se(port = pa_device_port_new(u->core, &port_data, 0));
+    pa_assert_se(pa_hashmap_put(ports, port->name, port) >= 0);
+    pa_device_port_new_data_done(&port_data);
+
+    u->input_port_name = pa_sprintf_malloc("%s-input", name_prefix);
+    pa_device_port_new_data_init(&port_data);
+    pa_device_port_new_data_set_name(&port_data, u->input_port_name);
+    pa_device_port_new_data_set_description(&port_data, input_description);
+    pa_device_port_new_data_set_direction(&port_data, PA_DIRECTION_INPUT);
+    pa_device_port_new_data_set_available(&port_data, get_port_availability(u, PA_DIRECTION_INPUT));
+    pa_assert_se(port = pa_device_port_new(u->core, &port_data, 0));
+    pa_assert_se(pa_hashmap_put(ports, port->name, port) >= 0);
+    pa_device_port_new_data_done(&port_data);
+}
+
+/* Run from main thread */
 static int add_card(struct userdata *u) {
     const pa_bluetooth_device *d;
     pa_card_new_data data;
@@ -208,6 +347,8 @@ static int add_card(struct userdata *u) {
     data.name = pa_sprintf_malloc("bluez_card.%s", d->address);
     data.namereg_fail = false;
 
+    create_card_ports(u, data.ports);
+
     cp = pa_card_profile_new("off", _("Off"), sizeof(pa_bluetooth_profile_t));
     cp->available = PA_AVAILABLE_YES;
     p = PA_CARD_PROFILE_DATA(cp);
@@ -307,5 +448,8 @@ void pa__done(pa_module *m) {
     if (u->discovery)
         pa_bluetooth_discovery_unref(u->discovery);
 
+    pa_xfree(u->output_port_name);
+    pa_xfree(u->input_port_name);
+
     pa_xfree(u);
 }
-- 
1.8.3.1



More information about the pulseaudio-discuss mailing list