summaryrefslogtreecommitdiffstats
path: root/btif
diff options
context:
space:
mode:
authorMattias Agren <magren@broadcom.com>2012-05-31 15:52:45 +0200
committerMatthew Xie <mattx@google.com>2012-07-14 11:19:22 -0700
commitf476c7d052409d27d60cbe8d17c9ed14c663518e (patch)
tree0ded62e77efe929e37935f7ed9588bebd1b5c50f /btif
parent00f5bc43b14beb053a462b48e100378d34b75e19 (diff)
downloadexternal_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.h6
-rwxr-xr-xbtif/src/btif_av.c84
-rwxr-xr-xbtif/src/btif_media_task.c18
-rwxr-xr-xbtif/src/btif_storage.c31
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);
}