[pulseaudio-discuss] [PATCH next v0 04/11] bluetooth: Use array to store profile states
Mikel Astiz
mikel.astiz.oss at gmail.com
Thu Dec 6 06:55:29 PST 2012
From: Mikel Astiz <mikel.astiz at bmw-carit.de>
Refactor the code to use an array of states instead of independent
member fields, avoiding duplicated code and improving readability.
---
src/modules/bluetooth/bluetooth-util.c | 81 ++++++++++++++-----------
src/modules/bluetooth/bluetooth-util.h | 13 +---
src/modules/bluetooth/module-bluetooth-device.c | 59 +++++-------------
3 files changed, 62 insertions(+), 91 deletions(-)
diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c
index 6f784d1..4986501 100644
--- a/src/modules/bluetooth/bluetooth-util.c
+++ b/src/modules/bluetooth/bluetooth-util.c
@@ -93,6 +93,24 @@ pa_bt_audio_state_t pa_bt_audio_state_from_string(const char* value) {
return PA_BT_AUDIO_STATE_INVALID;
}
+static bool pa_bt_audio_profile_from_interface(const char *interface, enum profile *p) {
+ if (pa_streq(interface, "org.bluez.AudioSink")) {
+ *p = PROFILE_A2DP;
+ return true;
+ } else if (pa_streq(interface, "org.bluez.AudioSource")) {
+ *p = PROFILE_A2DP_SOURCE;
+ return true;
+ } else if (pa_streq(interface, "org.bluez.Headset")) {
+ *p = PROFILE_HSP;
+ return true;
+ } else if (pa_streq(interface, "org.bluez.HandsfreeGateway")) {
+ *p = PROFILE_HFGW;
+ return true;
+ }
+
+ return false;
+}
+
static pa_bluetooth_uuid *uuid_new(const char *uuid) {
pa_bluetooth_uuid *u;
@@ -112,6 +130,7 @@ static void uuid_free(pa_bluetooth_uuid *u) {
static pa_bluetooth_device* device_new(pa_bluetooth_discovery *discovery, const char *path) {
pa_bluetooth_device *d;
+ unsigned i;
pa_assert(discovery);
pa_assert(path);
@@ -133,10 +152,9 @@ static pa_bluetooth_device* device_new(pa_bluetooth_discovery *discovery, const
d->trusted = -1;
d->audio_state = PA_BT_AUDIO_STATE_INVALID;
- d->audio_sink_state = PA_BT_AUDIO_STATE_INVALID;
- d->audio_source_state = PA_BT_AUDIO_STATE_INVALID;
- d->headset_state = PA_BT_AUDIO_STATE_INVALID;
- d->hfgw_state = PA_BT_AUDIO_STATE_INVALID;
+
+ for (i = 0; i < PA_BLUETOOTH_PROFILE_COUNT; i++)
+ d->profile_state[i] = PA_BT_AUDIO_STATE_INVALID;
return d;
}
@@ -185,14 +203,18 @@ static void device_free(pa_bluetooth_device *d) {
}
static pa_bool_t device_is_audio_ready(const pa_bluetooth_device *d) {
+ unsigned i;
+
pa_assert(d);
- return
- d->device_info_valid && d->audio_state != PA_BT_AUDIO_STATE_INVALID &&
- (d->audio_sink_state != PA_BT_AUDIO_STATE_INVALID ||
- d->audio_source_state != PA_BT_AUDIO_STATE_INVALID ||
- d->headset_state != PA_BT_AUDIO_STATE_INVALID ||
- d->hfgw_state != PA_BT_AUDIO_STATE_INVALID);
+ if (!d->device_info_valid || d->audio_state == PA_BT_AUDIO_STATE_INVALID)
+ return FALSE;
+
+ for (i = 0; i < PA_BLUETOOTH_PROFILE_COUNT; i++)
+ if (d->profile_state[i] != PA_BT_AUDIO_STATE_INVALID)
+ return TRUE;
+
+ return FALSE;
}
static const char *check_variant_property(DBusMessageIter *i) {
@@ -570,6 +592,7 @@ static void get_properties_reply(DBusPendingCall *pending, void *userdata) {
if (dbus_message_iter_get_arg_type(&element_i) == DBUS_TYPE_DICT_ENTRY) {
DBusMessageIter dict_i;
+ enum profile profile;
dbus_message_iter_recurse(&element_i, &dict_i);
@@ -589,22 +612,13 @@ static void get_properties_reply(DBusPendingCall *pending, void *userdata) {
if (parse_audio_property(y, &d->audio_state, &dict_i) < 0)
goto finish;
- } else if (dbus_message_has_interface(p->message, "org.bluez.Headset")) {
- if (parse_audio_property(y, &d->headset_state, &dict_i) < 0)
- goto finish;
-
- } else if (dbus_message_has_interface(p->message, "org.bluez.AudioSink")) {
- if (parse_audio_property(y, &d->audio_sink_state, &dict_i) < 0)
- goto finish;
+ } else if (pa_bt_audio_profile_from_interface(dbus_message_get_interface(p->message), &profile)) {
+ pa_bt_audio_state_t state;
- } else if (dbus_message_has_interface(p->message, "org.bluez.AudioSource")) {
- if (parse_audio_property(y, &d->audio_source_state, &dict_i) < 0)
- goto finish;
-
- } else if (dbus_message_has_interface(p->message, "org.bluez.HandsfreeGateway")) {
- if (parse_audio_property(y, &d->hfgw_state, &dict_i) < 0)
+ if (parse_audio_property(y, &state, &dict_i) < 0)
goto finish;
+ d->profile_state[profile] = state;
}
}
@@ -846,6 +860,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us
if ((d = pa_hashmap_get(y->devices, dbus_message_get_path(m)))) {
DBusMessageIter arg_i;
+ enum profile profile;
bool old_any_connected = pa_bluetooth_device_any_audio_connected(d);
if (!dbus_message_iter_init(m, &arg_i)) {
@@ -861,21 +876,13 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us
if (parse_audio_property(y, &d->audio_state, &arg_i) < 0)
goto fail;
- } else if (dbus_message_has_interface(m, "org.bluez.Headset")) {
- if (parse_audio_property(y, &d->headset_state, &arg_i) < 0)
- goto fail;
+ } else if (pa_bt_audio_profile_from_interface(dbus_message_get_interface(m), &profile)) {
+ pa_bt_audio_state_t state;
- } else if (dbus_message_has_interface(m, "org.bluez.AudioSink")) {
- if (parse_audio_property(y, &d->audio_sink_state, &arg_i) < 0)
+ if (parse_audio_property(y, &state, &arg_i) < 0)
goto fail;
- } else if (dbus_message_has_interface(m, "org.bluez.AudioSource")) {
- if (parse_audio_property(y, &d->audio_source_state, &arg_i) < 0)
- goto fail;
-
- } else if (dbus_message_has_interface(m, "org.bluez.HandsfreeGateway")) {
- if (parse_audio_property(y, &d->hfgw_state, &arg_i) < 0)
- goto fail;
+ d->profile_state[profile] = state;
}
if (old_any_connected != pa_bluetooth_device_any_audio_connected(d))
@@ -989,8 +996,8 @@ bool pa_bluetooth_device_any_audio_connected(const pa_bluetooth_device *d) {
* loaded. */
return
d->audio_state >= PA_BT_AUDIO_STATE_CONNECTED ||
- d->audio_source_state >= PA_BT_AUDIO_STATE_CONNECTED ||
- d->hfgw_state >= PA_BT_AUDIO_STATE_CONNECTED;
+ d->profile_state[PROFILE_A2DP_SOURCE] >= PA_BT_AUDIO_STATE_CONNECTED ||
+ d->profile_state[PROFILE_HFGW] >= PA_BT_AUDIO_STATE_CONNECTED;
}
int pa_bluetooth_transport_acquire(pa_bluetooth_transport *t, const char *accesstype, size_t *imtu, size_t *omtu) {
diff --git a/src/modules/bluetooth/bluetooth-util.h b/src/modules/bluetooth/bluetooth-util.h
index ecc663c..35f91df 100644
--- a/src/modules/bluetooth/bluetooth-util.h
+++ b/src/modules/bluetooth/bluetooth-util.h
@@ -126,17 +126,8 @@ struct pa_bluetooth_device {
/* Audio state */
pa_bt_audio_state_t audio_state;
- /* AudioSink state */
- pa_bt_audio_state_t audio_sink_state;
-
- /* AudioSource state */
- pa_bt_audio_state_t audio_source_state;
-
- /* Headset state */
- pa_bt_audio_state_t headset_state;
-
- /* HandsfreeGateway state */
- pa_bt_audio_state_t hfgw_state;
+ /* AudioSink, AudioSource, Headset and HandsfreeGateway states */
+ pa_bt_audio_state_t profile_state[PA_BLUETOOTH_PROFILE_COUNT];
};
pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *core);
diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c
index 649e73f..83b18f3 100644
--- a/src/modules/bluetooth/module-bluetooth-device.c
+++ b/src/modules/bluetooth/module-bluetooth-device.c
@@ -366,23 +366,6 @@ static void bt_transport_release(struct userdata *u) {
teardown_stream(u);
}
-static pa_bt_audio_state_t get_profile_audio_state(const struct userdata *u, const pa_bluetooth_device *d) {
- switch(u->profile) {
- case PROFILE_HSP:
- return d->headset_state;
- case PROFILE_A2DP:
- return d->audio_sink_state;
- case PROFILE_A2DP_SOURCE:
- return d->audio_source_state;
- case PROFILE_HFGW:
- return d->hfgw_state;
- case PROFILE_OFF:
- break;
- }
-
- pa_assert_not_reached();
-}
-
static int bt_transport_acquire(struct userdata *u, pa_bool_t start) {
const char *accesstype = "rw";
@@ -404,7 +387,7 @@ static int bt_transport_acquire(struct userdata *u, pa_bool_t start) {
suspended in the meantime, so we can't really guarantee that the
stream will not be requested until BlueZ's API supports this
atomically. */
- if (get_profile_audio_state(u, u->device) < PA_BT_AUDIO_STATE_PLAYING) {
+ if (u->device->profile_state[u->profile] < PA_BT_AUDIO_STATE_PLAYING) {
pa_log_info("Failed optional acquire of transport %s", u->transport->path);
return -1;
}
@@ -1368,7 +1351,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us
if (pa_hashmap_get(u->card->profiles, "a2dp") == NULL)
available = audio_state_to_availability(state);
else
- available = audio_state_to_availability_merged(state, u->device->audio_sink_state);
+ available = audio_state_to_availability_merged(state, u->device->profile_state[PROFILE_A2DP]);
pa_assert_se(port = pa_hashmap_get(u->card->ports, "bluetooth-output"));
pa_device_port_set_available(port, available);
@@ -1402,7 +1385,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us
if (pa_hashmap_get(u->card->profiles, "hsp") == NULL)
available = audio_state_to_availability(state);
else
- available = audio_state_to_availability_merged(state, u->device->headset_state);
+ available = audio_state_to_availability_merged(state, u->device->profile_state[PROFILE_HSP]);
pa_assert_se(port = pa_hashmap_get(u->card->ports, "bluetooth-output"));
pa_device_port_set_available(port, available);
@@ -2207,17 +2190,8 @@ static int card_set_profile(pa_card *c, pa_card_profile *new_profile) {
if (*d != PROFILE_OFF) {
const pa_bluetooth_device *device = u->device;
- if (device->headset_state < PA_BT_AUDIO_STATE_CONNECTED && *d == PROFILE_HSP) {
- pa_log_warn("HSP is not connected, refused to switch profile");
- return -PA_ERR_IO;
- } else if (device->audio_sink_state < PA_BT_AUDIO_STATE_CONNECTED && *d == PROFILE_A2DP) {
- pa_log_warn("A2DP Sink is not connected, refused to switch profile");
- return -PA_ERR_IO;
- } else if (device->audio_source_state < PA_BT_AUDIO_STATE_CONNECTED && *d == PROFILE_A2DP_SOURCE) {
- pa_log_warn("A2DP Source is not connected, refused to switch profile");
- return -PA_ERR_IO;
- } else if (device->hfgw_state < PA_BT_AUDIO_STATE_CONNECTED && *d == PROFILE_HFGW) {
- pa_log_warn("HandsfreeGateway is not connected, refused to switch profile");
+ if (device->profile_state[*d] < PA_BT_AUDIO_STATE_CONNECTED) {
+ pa_log_warn("Profile not connected, refused to switch profile to %s", new_profile->name);
return -PA_ERR_IO;
}
}
@@ -2262,7 +2236,8 @@ static void create_ports_for_profile(struct userdata *u, pa_hashmap *ports, pa_c
case PROFILE_A2DP:
if ((port = pa_hashmap_get(ports, "bluetooth-output")) != NULL) {
port->priority = PA_MAX(port->priority, profile->priority * 100);
- port->available = audio_state_to_availability_merged(device->headset_state, device->audio_sink_state);
+ port->available = audio_state_to_availability_merged(device->profile_state[PROFILE_HSP],
+ device->profile_state[PROFILE_A2DP]);
pa_hashmap_put(port->profiles, profile->name, profile);
} else {
pa_assert_se(port = pa_device_port_new(u->core, "bluetooth-output", _("Bluetooth Output"), 0));
@@ -2270,7 +2245,7 @@ static void create_ports_for_profile(struct userdata *u, pa_hashmap *ports, pa_c
port->is_output = 1;
port->is_input = 0;
port->priority = profile->priority * 100;
- port->available = audio_state_to_availability(device->audio_sink_state);
+ port->available = audio_state_to_availability(device->profile_state[*d]);
pa_hashmap_put(port->profiles, profile->name, profile);
}
@@ -2282,14 +2257,15 @@ static void create_ports_for_profile(struct userdata *u, pa_hashmap *ports, pa_c
port->is_output = 0;
port->is_input = 1;
port->priority = profile->priority * 100;
- port->available = audio_state_to_availability(device->audio_source_state);
+ port->available = audio_state_to_availability(device->profile_state[*d]);
pa_hashmap_put(port->profiles, profile->name, profile);
break;
case PROFILE_HSP:
if ((port = pa_hashmap_get(ports, "bluetooth-output")) != NULL) {
port->priority = PA_MAX(port->priority, profile->priority * 100);
- port->available = audio_state_to_availability_merged(device->headset_state, device->audio_sink_state);
+ port->available = audio_state_to_availability_merged(device->profile_state[PROFILE_HSP],
+ device->profile_state[PROFILE_A2DP]);
pa_hashmap_put(port->profiles, profile->name, profile);
} else {
pa_assert_se(port = pa_device_port_new(u->core, "bluetooth-output", _("Bluetooth Output"), 0));
@@ -2297,7 +2273,7 @@ static void create_ports_for_profile(struct userdata *u, pa_hashmap *ports, pa_c
port->is_output = 1;
port->is_input = 0;
port->priority = profile->priority * 100;
- port->available = audio_state_to_availability(device->headset_state);
+ port->available = audio_state_to_availability(device->profile_state[*d]);
pa_hashmap_put(port->profiles, profile->name, profile);
}
@@ -2306,7 +2282,7 @@ static void create_ports_for_profile(struct userdata *u, pa_hashmap *ports, pa_c
port->is_output = 0;
port->is_input = 1;
port->priority = profile->priority * 100;
- port->available = audio_state_to_availability(device->headset_state);
+ port->available = audio_state_to_availability(device->profile_state[*d]);
pa_hashmap_put(port->profiles, profile->name, profile);
break;
@@ -2316,7 +2292,7 @@ static void create_ports_for_profile(struct userdata *u, pa_hashmap *ports, pa_c
port->is_output = 1;
port->is_input = 0;
port->priority = profile->priority * 100;
- port->available = audio_state_to_availability(device->hfgw_state);
+ port->available = audio_state_to_availability(device->profile_state[*d]);
pa_hashmap_put(port->profiles, profile->name, profile);
pa_assert_se(port = pa_device_port_new(u->core, "hfgw-input", _("Bluetooth Handsfree Gateway"), 0));
@@ -2324,7 +2300,7 @@ static void create_ports_for_profile(struct userdata *u, pa_hashmap *ports, pa_c
port->is_output = 0;
port->is_input = 1;
port->priority = profile->priority * 100;
- port->available = audio_state_to_availability(device->hfgw_state);
+ port->available = audio_state_to_availability(device->profile_state[*d]);
pa_hashmap_put(port->profiles, profile->name, profile);
break;
@@ -2466,10 +2442,7 @@ static int add_card(struct userdata *u) {
d = PA_CARD_PROFILE_DATA(u->card->active_profile);
- if ((device->headset_state < PA_BT_AUDIO_STATE_CONNECTED && *d == PROFILE_HSP) ||
- (device->audio_sink_state < PA_BT_AUDIO_STATE_CONNECTED && *d == PROFILE_A2DP) ||
- (device->audio_source_state < PA_BT_AUDIO_STATE_CONNECTED && *d == PROFILE_A2DP_SOURCE) ||
- (device->hfgw_state < PA_BT_AUDIO_STATE_CONNECTED && *d == PROFILE_HFGW)) {
+ if (*d != PROFILE_OFF && (device->profile_state[*d] < PA_BT_AUDIO_STATE_CONNECTED)) {
pa_log_warn("Default profile not connected, selecting off profile");
u->card->active_profile = pa_hashmap_get(u->card->profiles, "off");
u->card->save_profile = FALSE;
--
1.7.11.7
More information about the pulseaudio-discuss
mailing list