src/modules/bluetooth/bluetooth-util.c | 78 +++++++++++++++----- src/modules/bluetooth/bluetooth-util.h | 16 +++- src/modules/bluetooth/module-bluetooth-device.c | 92 +++++++++++++++++++++--- 3 files changed, 156 insertions(+), 30 deletions(-)
New commits: commit 135afa28e7d4f34aec776fe4d225e21b76fc461c Author: David Henningsson <david.hennings...@canonical.com> Date: Fri Mar 8 18:23:41 2013 +0100 bluetooth: Never allow microphone output ports If we find a microphone output port, it is probably something else than a microphone. Therefore label it "Bluetooth output" instead of "Microphone". Same goes for Headphones and Speakers, but in the other direction. Signed-off-by: David Henningsson <david.hennings...@canonical.com> diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index b19362f..c877df2 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -2094,17 +2094,17 @@ static void create_card_ports(struct userdata *u, pa_hashmap *ports) { case PA_BT_FORM_FACTOR_MICROPHONE: name_prefix = "microphone"; - input_description = output_description = _("Microphone"); + input_description = _("Microphone"); break; case PA_BT_FORM_FACTOR_SPEAKER: name_prefix = "speaker"; - input_description = output_description = _("Speaker"); + output_description = _("Speaker"); break; case PA_BT_FORM_FACTOR_HEADPHONE: name_prefix = "headphone"; - input_description = output_description = _("Headphone"); + output_description = _("Headphone"); break; case PA_BT_FORM_FACTOR_PORTABLE: commit 0a280ceed74079fa8864a519c5deaa02bce306f9 Author: Mikel Astiz <mikel.as...@bmw-carit.de> Date: Thu Mar 7 11:32:23 2013 +0100 bluetooth: Use form factor to set port name and description Use the information provided by the form factor to decide which name and description should be used during port creation. diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index 9dc0cb3..b19362f 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -152,6 +152,9 @@ struct userdata { pa_bluetooth_discovery *discovery; bool auto_connect; + char *output_port_name; + char *input_port_name; + pa_card *card; pa_sink *sink; pa_source *source; @@ -1269,10 +1272,10 @@ static void handle_transport_state_change(struct userdata *u, struct pa_bluetoot pa_card_profile_set_available(cp, transport_state_to_availability(state)); /* Update port availability */ - pa_assert_se(port = pa_hashmap_get(u->card->ports, "bluetooth-output")); + pa_assert_se(port = pa_hashmap_get(u->card->ports, u->output_port_name)); pa_device_port_set_available(port, get_port_availability(u, PA_DIRECTION_OUTPUT)); - pa_assert_se(port = pa_hashmap_get(u->card->ports, "bluetooth-input")); + pa_assert_se(port = pa_hashmap_get(u->card->ports, u->input_port_name)); pa_device_port_set_available(port, get_port_availability(u, PA_DIRECTION_INPUT)); /* Acquire or release transport as needed */ @@ -1516,13 +1519,13 @@ static void connect_ports(struct userdata *u, void *sink_or_source_new_data, pa_ if (direction == PA_DIRECTION_OUTPUT) { pa_sink_new_data *sink_new_data = sink_or_source_new_data; - pa_assert_se(port = pa_hashmap_get(u->card->ports, "bluetooth-output")); + 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 = sink_or_source_new_data; - pa_assert_se(port = pa_hashmap_get(u->card->ports, "bluetooth-input")); + 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); } @@ -2067,17 +2070,83 @@ off: /* Run from main thread */ static void create_card_ports(struct userdata *u, pa_hashmap *ports) { pa_device_port *port; + const char *name_prefix = NULL; + const char *input_description = NULL; + const char *output_description = NULL; pa_assert(u); pa_assert(ports); + pa_assert(u->device); + + switch (pa_bluetooth_get_form_factor(u->device->class)) { + case PA_BT_FORM_FACTOR_UNKNOWN: + break; + + case PA_BT_FORM_FACTOR_HEADSET: + name_prefix = "headset"; + input_description = output_description = _("Headset"); + break; + + case PA_BT_FORM_FACTOR_HANDSFREE: + name_prefix = "handsfree"; + input_description = output_description = _("Handsfree"); + break; + + case PA_BT_FORM_FACTOR_MICROPHONE: + name_prefix = "microphone"; + input_description = output_description = _("Microphone"); + break; + + case PA_BT_FORM_FACTOR_SPEAKER: + name_prefix = "speaker"; + input_description = output_description = _("Speaker"); + break; + + case PA_BT_FORM_FACTOR_HEADPHONE: + name_prefix = "headphone"; + input_description = output_description = _("Headphone"); + break; - pa_assert_se(port = pa_device_port_new(u->core, "bluetooth-output", _("Bluetooth Output"), 0)); + case PA_BT_FORM_FACTOR_PORTABLE: + name_prefix = "portable"; + input_description = output_description = _("Portable"); + break; + + case PA_BT_FORM_FACTOR_CAR: + name_prefix = "car"; + input_description = output_description = _("Car"); + break; + + case PA_BT_FORM_FACTOR_HIFI: + name_prefix = "hifi"; + input_description = output_description = _("HiFi"); + break; + + case PA_BT_FORM_FACTOR_PHONE: + name_prefix = "phone"; + input_description = output_description = _("Phone"); + break; + } + + if (!name_prefix) + name_prefix = "unknown"; + + if (!output_description) + output_description = _("Bluetooth Output"); + + if (!input_description) + input_description = _("Bluetooth Input"); + + u->output_port_name = pa_sprintf_malloc("%s-output", name_prefix); + u->input_port_name = pa_sprintf_malloc("%s-input", name_prefix); + + pa_assert_se(port = pa_device_port_new(u->core, u->output_port_name, output_description, 0)); pa_assert_se(pa_hashmap_put(ports, port->name, port) >= 0); port->is_output = 1; port->is_input = 0; port->available = get_port_availability(u, PA_DIRECTION_OUTPUT); - pa_assert_se(port = pa_device_port_new(u->core, "bluetooth-input", _("Bluetooth Input"), 0)); + pa_assert_se(port = pa_device_port_new(u->core, u->input_port_name, input_description, 0)); pa_assert_se(pa_hashmap_put(ports, port->name, port) >= 0); port->is_output = 0; port->is_input = 1; @@ -2521,6 +2590,9 @@ void pa__done(pa_module *m) { if (u->modargs) pa_modargs_free(u->modargs); + pa_xfree(u->output_port_name); + pa_xfree(u->input_port_name); + pa_xfree(u->address); pa_xfree(u->path); commit b394743fb3a81e3528dc171a282cdb0a5786b545 Author: Mikel Astiz <mikel.as...@bmw-carit.de> Date: Thu Mar 7 11:32:22 2013 +0100 bluetooth: Add specific form factor for phones When a phone is paired, use PA_BT_FORM_FACTOR_PHONE to properly specify its form factor. diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 5d5dfc4..5e4b77b 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -1801,7 +1801,7 @@ pa_hook* pa_bluetooth_discovery_hook(pa_bluetooth_discovery *y, pa_bluetooth_hoo } pa_bt_form_factor_t pa_bluetooth_get_form_factor(uint32_t class) { - unsigned i; + unsigned major, minor; pa_bt_form_factor_t r; static const pa_bt_form_factor_t table[] = { @@ -1815,16 +1815,27 @@ pa_bt_form_factor_t pa_bluetooth_get_form_factor(uint32_t class) { [10] = PA_BT_FORM_FACTOR_HIFI }; - if (((class >> 8) & 31) != 4) - return PA_BT_FORM_FACTOR_UNKNOWN; + /* + * See Bluetooth Assigned Numbers: + * https://www.bluetooth.org/Technical/AssignedNumbers/baseband.htm + */ + major = (class >> 8) & 0x1F; + minor = (class >> 2) & 0x3F; + + switch (major) { + case 2: + return PA_BT_FORM_FACTOR_PHONE; + case 4: + break; + default: + pa_log_debug("Unknown Bluetooth major device class %u", major); + return PA_BT_FORM_FACTOR_UNKNOWN; + } - if ((i = (class >> 2) & 63) >= PA_ELEMENTSOF(table)) - r = PA_BT_FORM_FACTOR_UNKNOWN; - else - r = table[i]; + r = minor < PA_ELEMENTSOF(table) ? table[minor] : PA_BT_FORM_FACTOR_UNKNOWN; if (!r) - pa_log_debug("Unknown Bluetooth minor device class %u", i); + pa_log_debug("Unknown Bluetooth minor device class %u", minor); return r; } @@ -1849,6 +1860,8 @@ const char *pa_bt_form_factor_to_string(pa_bt_form_factor_t ff) { return "car"; case PA_BT_FORM_FACTOR_HIFI: return "hifi"; + case PA_BT_FORM_FACTOR_PHONE: + return "phone"; } pa_assert_not_reached(); diff --git a/src/modules/bluetooth/bluetooth-util.h b/src/modules/bluetooth/bluetooth-util.h index b59255e..3361b0f 100644 --- a/src/modules/bluetooth/bluetooth-util.h +++ b/src/modules/bluetooth/bluetooth-util.h @@ -164,6 +164,7 @@ typedef enum pa_bt_form_factor { PA_BT_FORM_FACTOR_PORTABLE, PA_BT_FORM_FACTOR_CAR, PA_BT_FORM_FACTOR_HIFI, + PA_BT_FORM_FACTOR_PHONE, } pa_bt_form_factor_t; pa_bt_form_factor_t pa_bluetooth_get_form_factor(uint32_t class); commit 11d7a2d1978fcd259402761af5f7dcaf064c98c1 Author: Mikel Astiz <mikel.as...@bmw-carit.de> Date: Thu Mar 7 11:32:21 2013 +0100 bluetooth: Use enum to represent form factors Avoid using strings only to represent form factors in the bluetooth-util API and instead use a new dedicated enum type: pa_bt_form_factor_t. diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 0fd8b85..5d5dfc4 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -1800,26 +1800,26 @@ pa_hook* pa_bluetooth_discovery_hook(pa_bluetooth_discovery *y, pa_bluetooth_hoo return &y->hooks[hook]; } -const char*pa_bluetooth_get_form_factor(uint32_t class) { +pa_bt_form_factor_t pa_bluetooth_get_form_factor(uint32_t class) { unsigned i; - const char *r; - - static const char * const table[] = { - [1] = "headset", - [2] = "hands-free", - [4] = "microphone", - [5] = "speaker", - [6] = "headphone", - [7] = "portable", - [8] = "car", - [10] = "hifi" + pa_bt_form_factor_t r; + + static const pa_bt_form_factor_t table[] = { + [1] = PA_BT_FORM_FACTOR_HEADSET, + [2] = PA_BT_FORM_FACTOR_HANDSFREE, + [4] = PA_BT_FORM_FACTOR_MICROPHONE, + [5] = PA_BT_FORM_FACTOR_SPEAKER, + [6] = PA_BT_FORM_FACTOR_HEADPHONE, + [7] = PA_BT_FORM_FACTOR_PORTABLE, + [8] = PA_BT_FORM_FACTOR_CAR, + [10] = PA_BT_FORM_FACTOR_HIFI }; if (((class >> 8) & 31) != 4) - return NULL; + return PA_BT_FORM_FACTOR_UNKNOWN; if ((i = (class >> 2) & 63) >= PA_ELEMENTSOF(table)) - r = NULL; + r = PA_BT_FORM_FACTOR_UNKNOWN; else r = table[i]; @@ -1829,6 +1829,31 @@ const char*pa_bluetooth_get_form_factor(uint32_t class) { return r; } +const char *pa_bt_form_factor_to_string(pa_bt_form_factor_t ff) { + switch (ff) { + case PA_BT_FORM_FACTOR_UNKNOWN: + return "unknown"; + case PA_BT_FORM_FACTOR_HEADSET: + return "headset"; + case PA_BT_FORM_FACTOR_HANDSFREE: + return "hands-free"; + case PA_BT_FORM_FACTOR_MICROPHONE: + return "microphone"; + case PA_BT_FORM_FACTOR_SPEAKER: + return "speaker"; + case PA_BT_FORM_FACTOR_HEADPHONE: + return "headphone"; + case PA_BT_FORM_FACTOR_PORTABLE: + return "portable"; + case PA_BT_FORM_FACTOR_CAR: + return "car"; + case PA_BT_FORM_FACTOR_HIFI: + return "hifi"; + } + + pa_assert_not_reached(); +} + char *pa_bluetooth_cleanup_name(const char *name) { char *t, *s, *d; bool space = false; diff --git a/src/modules/bluetooth/bluetooth-util.h b/src/modules/bluetooth/bluetooth-util.h index 6423f88..b59255e 100644 --- a/src/modules/bluetooth/bluetooth-util.h +++ b/src/modules/bluetooth/bluetooth-util.h @@ -154,7 +154,20 @@ void pa_bluetooth_transport_set_speaker_gain(pa_bluetooth_transport *t, uint16_t pa_hook* pa_bluetooth_discovery_hook(pa_bluetooth_discovery *y, pa_bluetooth_hook_t hook); -const char* pa_bluetooth_get_form_factor(uint32_t class); +typedef enum pa_bt_form_factor { + PA_BT_FORM_FACTOR_UNKNOWN, + PA_BT_FORM_FACTOR_HEADSET, + PA_BT_FORM_FACTOR_HANDSFREE, + PA_BT_FORM_FACTOR_MICROPHONE, + PA_BT_FORM_FACTOR_SPEAKER, + PA_BT_FORM_FACTOR_HEADPHONE, + PA_BT_FORM_FACTOR_PORTABLE, + PA_BT_FORM_FACTOR_CAR, + PA_BT_FORM_FACTOR_HIFI, +} pa_bt_form_factor_t; + +pa_bt_form_factor_t pa_bluetooth_get_form_factor(uint32_t class); +const char *pa_bt_form_factor_to_string(pa_bt_form_factor_t ff); char *pa_bluetooth_cleanup_name(const char *name); diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index e04780b..9dc0cb3 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -2147,7 +2147,7 @@ static int add_card(struct userdata *u) { bool b; pa_card_profile *p; enum profile *d; - const char *ff; + pa_bt_form_factor_t ff; char *n; const char *default_profile; const pa_bluetooth_device *device = u->device; @@ -2167,8 +2167,10 @@ static int add_card(struct userdata *u) { pa_proplist_sets(data.proplist, PA_PROP_DEVICE_API, "bluez"); pa_proplist_sets(data.proplist, PA_PROP_DEVICE_CLASS, "sound"); pa_proplist_sets(data.proplist, PA_PROP_DEVICE_BUS, "bluetooth"); - if ((ff = pa_bluetooth_get_form_factor(device->class))) - pa_proplist_sets(data.proplist, PA_PROP_DEVICE_FORM_FACTOR, ff); + + if ((ff = pa_bluetooth_get_form_factor(device->class)) != PA_BT_FORM_FACTOR_UNKNOWN) + pa_proplist_sets(data.proplist, PA_PROP_DEVICE_FORM_FACTOR, pa_bt_form_factor_to_string(ff)); + pa_proplist_sets(data.proplist, "bluez.path", device->path); pa_proplist_setf(data.proplist, "bluez.class", "0x%06x", (unsigned) device->class); pa_proplist_sets(data.proplist, "bluez.name", device->name); _______________________________________________ pulseaudio-commits mailing list pulseaudio-commits@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-commits