diff options
author | Mattias Agren <magren@broadcom.com> | 2012-05-31 15:52:45 +0200 |
---|---|---|
committer | Matthew Xie <mattx@google.com> | 2012-07-14 11:19:22 -0700 |
commit | f476c7d052409d27d60cbe8d17c9ed14c663518e (patch) | |
tree | 0ded62e77efe929e37935f7ed9588bebd1b5c50f /btif | |
parent | 00f5bc43b14beb053a462b48e100378d34b75e19 (diff) | |
download | external_bluetooth_bluedroid-f476c7d052409d27d60cbe8d17c9ed14c663518e.zip external_bluetooth_bluedroid-f476c7d052409d27d60cbe8d17c9ed14c663518e.tar.gz external_bluetooth_bluedroid-f476c7d052409d27d60cbe8d17c9ed14c663518e.tar.bz2 |
Ensure we ack back suspend request if we are not ready for it
Block audioflinger/a2dp hal from trying to restart stream while
we are remotely suspended.
Change-Id: I17577306f1be248857a8484a22a8a14cb956ec19
Diffstat (limited to 'btif')
-rwxr-xr-x[-rw-r--r--] | btif/include/btif_av.h | 6 | ||||
-rwxr-xr-x | btif/src/btif_av.c | 84 | ||||
-rwxr-xr-x | btif/src/btif_media_task.c | 18 | ||||
-rwxr-xr-x | btif/src/btif_storage.c | 31 |
4 files changed, 98 insertions, 41 deletions
diff --git a/btif/include/btif_av.h b/btif/include/btif_av.h index e481459..2c08a99 100644..100755 --- a/btif/include/btif_av.h +++ b/btif/include/btif_av.h @@ -128,15 +128,15 @@ BOOLEAN btif_av_stream_ready(void); /******************************************************************************* ** -** Function btif_av_stream_started +** Function btif_av_stream_started_ready ** -** Description Checks whether AV is already started (remotely) +** Description Checks whether AV ready for media start in streaming state ** ** Returns None ** *******************************************************************************/ -BOOLEAN btif_av_stream_started(void); +BOOLEAN btif_av_stream_started_ready(void); /******************************************************************************* ** diff --git a/btif/src/btif_av.c b/btif/src/btif_av.c index b2b1378..3096629 100755 --- a/btif/src/btif_av.c +++ b/btif/src/btif_av.c @@ -84,21 +84,31 @@ typedef enum { BTIF_AV_STATE_CLOSING } btif_av_state_t; +/* Should not need dedicated suspend state as actual actions are no + different than open state. Suspend flags are needed however to prevent + media task from trying to restart stream during remote suspend or while + we are in the process of a local suspend */ + +#define BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING 0x1 +#define BTIF_AV_FLAG_REMOTE_SUSPEND 0x2 + /***************************************************************************** ** Local type definitions ******************************************************************************/ + typedef struct { tBTA_AV_HNDL bta_handle; bt_bdaddr_t peer_bda; btif_sm_handle_t sm_handle; + UINT8 flags; } btif_av_cb_t; + /***************************************************************************** ** Static variables ******************************************************************************/ static btav_callbacks_t *bt_av_callbacks = NULL; static btif_av_cb_t btif_av_cb; - static TIMER_LIST_ENT tle_av_open_on_rc; /* both interface and media task needs to be ready to alloc incoming request */ @@ -246,13 +256,15 @@ static void btif_initiate_av_open_tmr_hdlr(TIMER_LIST_ENT *tle) static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *p_data) { - BTIF_TRACE_DEBUG2("%s event:%s", __FUNCTION__, dump_av_sm_event_name(event)); + BTIF_TRACE_DEBUG3("%s event:%s flags %x", __FUNCTION__, + dump_av_sm_event_name(event), btif_av_cb.flags); switch (event) { case BTIF_SM_ENTER_EVT: /* clear the peer_bda */ memset(&btif_av_cb.peer_bda, 0, sizeof(bt_bdaddr_t)); + btif_av_cb.flags = 0; btif_a2dp_on_idle(); break; @@ -337,7 +349,8 @@ static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *p_data) static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *p_data) { - BTIF_TRACE_DEBUG2("%s event:%s", __FUNCTION__, dump_av_sm_event_name(event)); + BTIF_TRACE_DEBUG3("%s event:%s flags %x", __FUNCTION__, + dump_av_sm_event_name(event), btif_av_cb.flags); switch (event) { @@ -406,7 +419,8 @@ static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *p_data static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *p_data) { - BTIF_TRACE_DEBUG2("%s event:%s", __FUNCTION__, dump_av_sm_event_name(event)); + BTIF_TRACE_DEBUG3("%s event:%s flags %x", __FUNCTION__, + dump_av_sm_event_name(event), btif_av_cb.flags); switch (event) { @@ -461,7 +475,8 @@ static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *p_data) { tBTA_AV *p_av = (tBTA_AV*)p_data; - BTIF_TRACE_DEBUG2("%s event:%s", __FUNCTION__, dump_av_sm_event_name(event)); + BTIF_TRACE_DEBUG3("%s event:%s flags %x", __FUNCTION__, + dump_av_sm_event_name(event), btif_av_cb.flags); switch (event) { @@ -537,11 +552,16 @@ static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *p_data { tBTA_AV *p_av = (tBTA_AV*)p_data; - BTIF_TRACE_DEBUG2("%s event:%s", __FUNCTION__, dump_av_sm_event_name(event)); + BTIF_TRACE_DEBUG3("%s event:%s flags %x", __FUNCTION__, + dump_av_sm_event_name(event), btif_av_cb.flags); switch (event) { case BTIF_SM_ENTER_EVT: + + /* we are again in started state, clear any remote suspend flags */ + btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND; + HAL_CBACK(bt_av_callbacks, audio_state_cb, BTAV_AUDIO_STATE_STARTED, &(btif_av_cb.peer_bda)); break; @@ -549,16 +569,19 @@ static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *p_data case BTIF_SM_EXIT_EVT: break; + /* fixme -- use suspend = true always to work around issue with BTA AV */ case BTIF_AV_STOP_STREAM_REQ_EVT: - /* immediately flush any pending tx frames while suspend is pending */ - btif_a2dp_set_tx_flush(TRUE); + case BTIF_AV_SUSPEND_STREAM_REQ_EVT: - BTA_AvStop(TRUE); - break; + /* set pending flag to ensure btif task is not trying to restart + stream while suspend is in progress */ + btif_av_cb.flags |= BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING; - case BTIF_AV_SUSPEND_STREAM_REQ_EVT: + /* if we were remotely suspended but suspend locally, local suspend + always overrides */ + btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND; - /* immediately stop transmission of frames whiel suspend is pending */ + /* immediately stop transmission of frames while suspend is pending */ btif_a2dp_set_tx_flush(TRUE); BTA_AvStop(TRUE); @@ -588,6 +611,8 @@ static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *p_data /* if not successful, remain in current state */ if (p_av->suspend.status != BTA_AV_SUCCESS) { + btif_av_cb.flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING; + /* suspend failed, reset back tx flush state */ btif_a2dp_set_tx_flush(FALSE); return FALSE; @@ -598,6 +623,11 @@ static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *p_data /* remote suspend, notify HAL and await audioflinger to suspend/stop stream */ + /* set remote suspend flag to block media task from restarting + stream only if we did not already initiate a local suspend */ + if ((btif_av_cb.flags & BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING) == 0) + btif_av_cb.flags |= BTIF_AV_FLAG_REMOTE_SUSPEND; + HAL_CBACK(bt_av_callbacks, audio_state_cb, BTAV_AUDIO_STATE_REMOTE_SUSPEND, &(btif_av_cb.peer_bda)); } @@ -606,7 +636,11 @@ static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *p_data HAL_CBACK(bt_av_callbacks, audio_state_cb, BTAV_AUDIO_STATE_STOPPED, &(btif_av_cb.peer_bda)); } + btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENED); + + /* suspend completed and state changed, clear pending status */ + btif_av_cb.flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING; break; case BTA_AV_STOP_EVT: @@ -831,8 +865,8 @@ BOOLEAN btif_av_stream_ready(void) { btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle); - BTIF_TRACE_EVENT2("btif_av_stream_ready : sm hdl %d, state %d", - btif_av_cb.sm_handle, state); + BTIF_TRACE_DEBUG3("btif_av_stream_ready : sm hdl %d, state %d, flags %x", + btif_av_cb.sm_handle, state, btif_av_cb.flags); /* also make sure main adapter is enabled */ if (btif_is_enabled() == 0) @@ -840,24 +874,36 @@ BOOLEAN btif_av_stream_ready(void) BTIF_TRACE_EVENT0("main adapter not enabled"); return FALSE; } + + /* check if we are remotely suspended */ + if (btif_av_cb.flags & BTIF_AV_FLAG_REMOTE_SUSPEND) + return FALSE; + return (state == BTIF_AV_STATE_OPENED); } /******************************************************************************* ** -** Function btif_av_stream_started +** Function btif_av_stream_started_ready ** -** Description Checks whether AV is already started (remotely) +** Description Checks whether AV ready for media start in streaming state ** ** Returns None ** *******************************************************************************/ -BOOLEAN btif_av_stream_started(void) +BOOLEAN btif_av_stream_started_ready(void) { btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle); - BTIF_TRACE_EVENT2("btif_av_stream_started : sm hdl %d, state %d", - btif_av_cb.sm_handle, state); + + BTIF_TRACE_DEBUG3("btif_av_stream_started : sm hdl %d, state %d, flags %x", + btif_av_cb.sm_handle, state, btif_av_cb.flags); + + /* don't allow media task to start if we are suspending or + remotely suspended (not yet changed state) */ + if (btif_av_cb.flags & (BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING | BTIF_AV_FLAG_REMOTE_SUSPEND)) + return FALSE; + return (state == BTIF_AV_STATE_STARTED); } diff --git a/btif/src/btif_media_task.c b/btif/src/btif_media_task.c index a821fb8..9de74d5 100755 --- a/btif/src/btif_media_task.c +++ b/btif/src/btif_media_task.c @@ -490,7 +490,7 @@ static void btif_recv_ctrl_data(void) } /* check whether av is ready to setup a2dp datapath */ - if ((btif_av_stream_ready() == TRUE) || (btif_av_stream_started() == TRUE)) + if ((btif_av_stream_ready() == TRUE) || (btif_av_stream_started_ready() == TRUE)) { a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS); } @@ -510,7 +510,7 @@ static void btif_recv_ctrl_data(void) /* post start event and wait for audio path to open */ btif_dispatch_sm_event(BTIF_AV_START_STREAM_REQ_EVT, NULL, 0); } - else if (btif_av_stream_started()) + else if (btif_av_stream_started_ready()) { /* already started, setup audio data channel listener and ack back immediately */ @@ -539,7 +539,17 @@ static void btif_recv_ctrl_data(void) case A2DP_CTRL_CMD_SUSPEND: /* local suspend */ - btif_dispatch_sm_event(BTIF_AV_SUSPEND_STREAM_REQ_EVT, NULL, 0); + if (btif_av_stream_started_ready()) + { + btif_dispatch_sm_event(BTIF_AV_SUSPEND_STREAM_REQ_EVT, NULL, 0); + } + else + { + /* if we are not in started state, just ack back ok and let + audioflinger close the channel. This can happen if we are + remotely suspended */ + a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS); + } break; default: @@ -1053,7 +1063,7 @@ static void ra_update(UINT32 bytes_processed) /* converts adjusted frame count to adjusted pcmtime equivalent */ btif_media_cb.ra.ra_adjust_pcmtime += (btif_media_cb.ra.ra_adjust_cnt)*pcmtime_equivalent; - APPL_TRACE_EVENT2("ra adjust %d %d", btif_media_cb.ra.ra_adjust_cnt, btif_media_cb.ra.ra_adjust_pcmtime); + VERBOSE("ra adjust %d %d", btif_media_cb.ra.ra_adjust_cnt, btif_media_cb.ra.ra_adjust_pcmtime); /* check pcmtime adjustments every stats interval */ if (ra_stats_update > (RA_STATS_INTERVAL*1000000L)) diff --git a/btif/src/btif_storage.c b/btif/src/btif_storage.c index 2ff415c..abb224c 100755 --- a/btif/src/btif_storage.c +++ b/btif/src/btif_storage.c @@ -139,11 +139,11 @@ #define BTIF_AUTO_PAIR_CONF_FILE "/etc/bluetooth/auto_pair_devlist.conf" #define BTIF_STORAGE_PATH_AUTOPAIR_BLACKLIST "auto_pair_blacklist" -#define BTIF_STORAGE_KEY_AUTOPAIR_BLIACKLIST_ADDR "AddressBlacklist" -#define BTIF_STORAGE_KEY_AUTOPAIR_BLIACKLIST_EXACTNAME "ExactNameBlacklist" -#define BTIF_STORAGE_KEY_AUTOPAIR_BLIACKLIST_PARTIALNAME "PartialNameBlacklist" +#define BTIF_STORAGE_KEY_AUTOPAIR_BLACKLIST_ADDR "AddressBlacklist" +#define BTIF_STORAGE_KEY_AUTOPAIR_BLACKLIST_EXACTNAME "ExactNameBlacklist" +#define BTIF_STORAGE_KEY_AUTOPAIR_BLACKLIST_PARTIALNAME "PartialNameBlacklist" #define BTIF_STORAGE_KEY_AUTOPAIR_FIXPIN_KBLIST "FixedPinZerosKeyboardBlacklist" -#define BTIF_STORAGE_KEY_AUTOPAIR_DYNAMIC_BLIACKLIST_ADDR "DynamicAddressBlacklist" +#define BTIF_STORAGE_KEY_AUTOPAIR_DYNAMIC_BLACKLIST_ADDR "DynamicAddressBlacklist" #define BTIF_AUTO_PAIR_CONF_VALUE_SEPERATOR "," #define BTIF_AUTO_PAIR_CONF_SPACE ' ' @@ -1717,6 +1717,7 @@ bt_status_t btif_storage_write_hl_mdl_data(UINT8 app_idx, char *value, int value ** BT_STATUS_FAIL otherwise ** *******************************************************************************/ + bt_status_t btif_storage_load_autopair_device_list() { char *fname, *key_name, *key_value; @@ -1733,7 +1734,7 @@ bt_status_t btif_storage_load_autopair_device_list() return BT_STATUS_FAIL; } - key_value = unv_read_key(fname,BTIF_STORAGE_KEY_AUTOPAIR_BLIACKLIST_ADDR,linebuf, BTIF_STORAGE_MAX_LINE_SZ); + key_value = unv_read_key(fname,BTIF_STORAGE_KEY_AUTOPAIR_BLACKLIST_ADDR,linebuf, BTIF_STORAGE_MAX_LINE_SZ); if (key_value == NULL) { @@ -1773,11 +1774,11 @@ bt_status_t btif_storage_load_autopair_device_list() if (key_name == NULL) continue; - else if((strcmp(key_name, BTIF_STORAGE_KEY_AUTOPAIR_BLIACKLIST_ADDR) == 0) || - (strcmp(key_name, BTIF_STORAGE_KEY_AUTOPAIR_BLIACKLIST_EXACTNAME) ==0) || + else if((strcmp(key_name, BTIF_STORAGE_KEY_AUTOPAIR_BLACKLIST_ADDR) == 0) || + (strcmp(key_name, BTIF_STORAGE_KEY_AUTOPAIR_BLACKLIST_EXACTNAME) ==0) || (strcmp(key_name, BTIF_STORAGE_KEY_AUTOPAIR_FIXPIN_KBLIST) ==0 ) || - (strcmp(key_name, BTIF_STORAGE_KEY_AUTOPAIR_BLIACKLIST_PARTIALNAME) == 0) || - (strcmp(key_name, BTIF_STORAGE_KEY_AUTOPAIR_DYNAMIC_BLIACKLIST_ADDR) == 0)) + (strcmp(key_name, BTIF_STORAGE_KEY_AUTOPAIR_BLACKLIST_PARTIALNAME) == 0) || + (strcmp(key_name, BTIF_STORAGE_KEY_AUTOPAIR_DYNAMIC_BLACKLIST_ADDR) == 0)) { key_value = strtok(NULL, BTIF_AUTO_PAIR_CONF_KEY_VAL_DELIMETER); unv_write_key (fname, key_name, key_value); @@ -1823,7 +1824,7 @@ BOOLEAN btif_storage_is_device_autopair_blacklisted(bt_bdaddr_t *remote_dev_add /* check if this device address LAP is same as one of the auto pair blackliseted LAP */ value = unv_read_key( fname, - BTIF_STORAGE_KEY_AUTOPAIR_BLIACKLIST_ADDR, + BTIF_STORAGE_KEY_AUTOPAIR_BLACKLIST_ADDR, linebuf, BTIF_STORAGE_MAX_LINE_SZ); if (value != NULL) { @@ -1836,7 +1837,7 @@ BOOLEAN btif_storage_is_device_autopair_blacklisted(bt_bdaddr_t *remote_dev_add if (dev_name_str != NULL) { value = unv_read_key( fname, - BTIF_STORAGE_KEY_AUTOPAIR_BLIACKLIST_EXACTNAME, + BTIF_STORAGE_KEY_AUTOPAIR_BLACKLIST_EXACTNAME, linebuf, BTIF_STORAGE_MAX_LINE_SZ); if (value != NULL) { @@ -1845,7 +1846,7 @@ BOOLEAN btif_storage_is_device_autopair_blacklisted(bt_bdaddr_t *remote_dev_add } value = unv_read_key( fname, - BTIF_STORAGE_KEY_AUTOPAIR_BLIACKLIST_PARTIALNAME, + BTIF_STORAGE_KEY_AUTOPAIR_BLACKLIST_PARTIALNAME, linebuf, BTIF_STORAGE_MAX_LINE_SZ); if (value != NULL) { @@ -1861,7 +1862,7 @@ BOOLEAN btif_storage_is_device_autopair_blacklisted(bt_bdaddr_t *remote_dev_add } value = unv_read_key( fname, - BTIF_STORAGE_KEY_AUTOPAIR_DYNAMIC_BLIACKLIST_ADDR, + BTIF_STORAGE_KEY_AUTOPAIR_DYNAMIC_BLACKLIST_ADDR, linebuf, BTIF_STORAGE_MAX_LINE_SZ); if (value != NULL) { @@ -1903,7 +1904,7 @@ bt_status_t btif_storage_add_device_to_autopair_blacklist(bt_bdaddr_t *remote_de } value = unv_read_key( fname, - BTIF_STORAGE_KEY_AUTOPAIR_DYNAMIC_BLIACKLIST_ADDR, + BTIF_STORAGE_KEY_AUTOPAIR_DYNAMIC_BLACKLIST_ADDR, linebuf, BTIF_STORAGE_MAX_LINE_SZ); if (value != NULL) { @@ -1916,7 +1917,7 @@ bt_status_t btif_storage_add_device_to_autopair_blacklist(bt_bdaddr_t *remote_de } /* Write back the key value */ - ret = unv_write_key (fname, BTIF_STORAGE_KEY_AUTOPAIR_DYNAMIC_BLIACKLIST_ADDR,( const char *)linebuf); + ret = unv_write_key (fname, BTIF_STORAGE_KEY_AUTOPAIR_DYNAMIC_BLACKLIST_ADDR,( const char *)linebuf); return (ret == 0 ? BT_STATUS_SUCCESS:BT_STATUS_FAIL); } |