From 67bf8f93bc209d3d8873d41662796ecec0d6524c Mon Sep 17 00:00:00 2001 From: Jaikumar Ganesh Date: Thu, 9 Jul 2009 19:05:12 -0700 Subject: Add A2DP_INIT command and state. In bluez4, when a device is unpaired the socket end is freed and so we will get a EPIPE when we write to it, this causes us to call bluetooth_close. On the next write, we don't call bluetooth_init. The logic here is thati, if the state is A2DP_STATE_NONE and we are waiting for BLUETOOTH_START state, we need to call bluetooth_init. The ENODEV case is where the other end, doesn't exist, and we are trying to write repeatedly, which means the problem is elsewhere. When we start initially (i.e the first time) when a2dp_set_sink is called, we used to directly set the command to configure and the a2dp_thread used to call bluetooth_init. This fix makes this a separate state and step. Tested: 1. A2DP music playing, turn BT off. Turn BT open, A2DP should work. 2. A2DP music playing, disconnect. On reconnection, it should work. 3. A2DP music playing, cause a crash in bluetoothd. On restart, it should work. 4. A2DP music playing, remote end powers down. On power up, it should work. 5. A2DP music playing, disconnect and unpair. On repair and reconnect, it should work. Tested with 2 headsets and with the troublesome HBH-DS790. --- audio/liba2dp.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'audio') diff --git a/audio/liba2dp.c b/audio/liba2dp.c index 001a964e..3300ec72 100755 --- a/audio/liba2dp.c +++ b/audio/liba2dp.c @@ -101,6 +101,7 @@ typedef enum { typedef enum { A2DP_CMD_NONE = 0, + A2DP_CMD_INIT, A2DP_CMD_CONFIGURE, A2DP_CMD_START, A2DP_CMD_STOP, @@ -911,7 +912,7 @@ static int wait_for_start(struct bluetooth_data *data, int timeout) while (state != A2DP_STATE_STARTED && !err) { if (state == A2DP_STATE_NONE) - return -ENODEV; + set_command(data, A2DP_CMD_INIT); else if (state == A2DP_STATE_INITIALIZED) set_command(data, A2DP_CMD_CONFIGURE); else if (state == A2DP_STATE_CONFIGURED) @@ -949,10 +950,12 @@ static void* a2dp_thread(void *d) command = data->command; pthread_mutex_unlock(&data->mutex); - if (data->state == A2DP_STATE_NONE && command != A2DP_CMD_QUIT) - bluetooth_init(data); - switch (command) { + case A2DP_CMD_INIT: + if (data->state != A2DP_STATE_NONE) + break; + bluetooth_init(data); + break; case A2DP_CMD_CONFIGURE: if (data->state != A2DP_STATE_INITIALIZED) break; @@ -1032,8 +1035,7 @@ void a2dp_set_sink(a2dpData d, const char* address) struct bluetooth_data* data = (struct bluetooth_data*)d; if (strncmp(data->address, address, 18)) { strncpy(data->address, address, 18); - // force reconfiguration - set_command(data, A2DP_CMD_CONFIGURE); + set_command(data, A2DP_CMD_INIT); } } -- cgit v1.2.3