Component/bt: fix get error adv packet sometimes

This commit is contained in:
zhiweijian 2018-08-17 11:54:45 +08:00 committed by bot
parent c7f4fae8d0
commit 1ca5b70803
3 changed files with 106 additions and 6 deletions

View file

@ -1439,7 +1439,8 @@ void BTM_BleSetScanFilterParams(tGATT_IF client_if, UINT32 scan_interval, UINT32
if (BTM_BLE_ISVALID_PARAM(scan_interval, BTM_BLE_SCAN_INT_MIN, max_scan_interval) && if (BTM_BLE_ISVALID_PARAM(scan_interval, BTM_BLE_SCAN_INT_MIN, max_scan_interval) &&
BTM_BLE_ISVALID_PARAM(scan_window, BTM_BLE_SCAN_WIN_MIN, max_scan_window) && BTM_BLE_ISVALID_PARAM(scan_window, BTM_BLE_SCAN_WIN_MIN, max_scan_window) &&
(scan_mode == BTM_BLE_SCAN_MODE_ACTI || scan_mode == BTM_BLE_SCAN_MODE_PASS)) { (scan_mode == BTM_BLE_SCAN_MODE_ACTI || scan_mode == BTM_BLE_SCAN_MODE_PASS) &&
(scan_duplicate_filter < BTM_BLE_SCAN_DUPLICATE_MAX)) {
p_cb->scan_type = scan_mode; p_cb->scan_type = scan_mode;
p_cb->scan_interval = scan_interval; p_cb->scan_interval = scan_interval;
p_cb->scan_window = scan_window; p_cb->scan_window = scan_window;
@ -2637,7 +2638,7 @@ static void btm_ble_parse_adv_data(tBTM_INQ_INFO *p_info, UINT8 *p_data,
** Returns void ** Returns void
** **
*******************************************************************************/ *******************************************************************************/
void btm_ble_cache_adv_data(tBTM_INQ_RESULTS *p_cur, UINT8 data_len, UINT8 *p, UINT8 evt_type) void btm_ble_cache_adv_data(BD_ADDR bda, tBTM_INQ_RESULTS *p_cur, UINT8 data_len, UINT8 *p, UINT8 evt_type)
{ {
tBTM_BLE_INQ_CB *p_le_inq_cb = &btm_cb.ble_ctr_cb.inq_var; tBTM_BLE_INQ_CB *p_le_inq_cb = &btm_cb.ble_ctr_cb.inq_var;
UINT8 *p_cache; UINT8 *p_cache;
@ -2651,6 +2652,15 @@ void btm_ble_cache_adv_data(tBTM_INQ_RESULTS *p_cur, UINT8 data_len, UINT8 *p, U
p_cur->scan_rsp_len = 0; p_cur->scan_rsp_len = 0;
} }
//Clear the adv cache if the addresses are not equal
if(memcmp(bda, p_le_inq_cb->adv_addr, BD_ADDR_LEN) != 0) {
p_le_inq_cb->adv_len = 0;
memcpy(p_le_inq_cb->adv_addr, bda, BD_ADDR_LEN);
memset(p_le_inq_cb->adv_data_cache, 0, BTM_BLE_CACHE_ADV_DATA_MAX);
p_cur->adv_data_len = 0;
p_cur->scan_rsp_len = 0;
}
if (data_len > 0) { if (data_len > 0) {
p_cache = &p_le_inq_cb->adv_data_cache[p_le_inq_cb->adv_len]; p_cache = &p_le_inq_cb->adv_data_cache[p_le_inq_cb->adv_len];
STREAM_TO_UINT8(length, p); STREAM_TO_UINT8(length, p);
@ -2878,7 +2888,7 @@ static void btm_ble_appearance_to_cod(UINT16 appearance, UINT8 *dev_class)
** Returns void ** Returns void
** **
*******************************************************************************/ *******************************************************************************/
BOOLEAN btm_ble_update_inq_result(tINQ_DB_ENT *p_i, UINT8 addr_type, UINT8 evt_type, UINT8 *p) BOOLEAN btm_ble_update_inq_result(BD_ADDR bda, tINQ_DB_ENT *p_i, UINT8 addr_type, UINT8 evt_type, UINT8 *p)
{ {
BOOLEAN to_report = TRUE; BOOLEAN to_report = TRUE;
tBTM_INQ_RESULTS *p_cur = &p_i->inq_info.results; tBTM_INQ_RESULTS *p_cur = &p_i->inq_info.results;
@ -2896,7 +2906,7 @@ BOOLEAN btm_ble_update_inq_result(tINQ_DB_ENT *p_i, UINT8 addr_type, UINT8 evt_t
BTM_TRACE_WARNING("EIR data too long %d. discard", data_len); BTM_TRACE_WARNING("EIR data too long %d. discard", data_len);
return FALSE; return FALSE;
} }
btm_ble_cache_adv_data(p_cur, data_len, p, evt_type); btm_ble_cache_adv_data(bda, p_cur, data_len, p, evt_type);
p1 = (p + data_len); p1 = (p + data_len);
STREAM_TO_UINT8 (rssi, p1); STREAM_TO_UINT8 (rssi, p1);
@ -3120,6 +3130,71 @@ void btm_ble_process_adv_pkt (UINT8 *p_data)
} }
} }
/*******************************************************************************
**
** Function btm_ble_process_last_adv_pkt
**
** Description This function is called to report last adv packet
**
** Parameters
**
** Returns void
**
*******************************************************************************/
static void btm_ble_process_last_adv_pkt(void)
{
UINT8 result = 0;
UINT8 null_bda[6] = {0};
tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
tBTM_INQ_RESULTS_CB *p_inq_results_cb = p_inq->p_inq_results_cb;
tBTM_INQ_RESULTS_CB *p_obs_results_cb = btm_cb.ble_ctr_cb.p_obs_results_cb;
tBTM_INQ_RESULTS_CB *p_scan_results_cb = btm_cb.ble_ctr_cb.p_scan_results_cb;
tBTM_BLE_INQ_CB *p_le_inq_cb = &btm_cb.ble_ctr_cb.inq_var;
tINQ_DB_ENT *p_i = btm_inq_db_find (p_le_inq_cb->adv_addr);
if(memcmp(null_bda, p_le_inq_cb->adv_addr, BD_ADDR_LEN) == 0) {
return;
}
if(p_i == NULL) {
BTM_TRACE_DEBUG("no last adv");
return;
}
if ((result = btm_ble_is_discoverable(p_le_inq_cb->adv_addr, p_i->inq_info.results.ble_evt_type, NULL)) == 0) {
BTM_TRACE_WARNING("%s device is no longer discoverable so discarding advertising packet pkt",
__func__);
return;
}
/* background connection in selective connection mode */
if (btm_cb.ble_ctr_cb.bg_conn_type == BTM_BLE_CONN_SELECTIVE) {
//do nothing
} else {
if (p_inq_results_cb && (result & BTM_BLE_INQ_RESULT)) {
(p_inq_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results, p_le_inq_cb->adv_data_cache);
p_le_inq_cb->adv_len = 0;
memset(p_le_inq_cb->adv_addr, 0, BD_ADDR_LEN);
p_i->inq_info.results.adv_data_len = 0;
p_i->inq_info.results.scan_rsp_len = 0;
}
if (p_obs_results_cb && (result & BTM_BLE_OBS_RESULT)) {
(p_obs_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results, p_le_inq_cb->adv_data_cache);
p_le_inq_cb->adv_len = 0;
memset(p_le_inq_cb->adv_addr, 0, BD_ADDR_LEN);
p_i->inq_info.results.adv_data_len = 0;
p_i->inq_info.results.scan_rsp_len = 0;
}
if (p_scan_results_cb && (result & BTM_BLE_DISCO_RESULT)) {
(p_scan_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results, p_le_inq_cb->adv_data_cache);
p_le_inq_cb->adv_len = 0;
memset(p_le_inq_cb->adv_addr, 0, BD_ADDR_LEN);
p_i->inq_info.results.adv_data_len = 0;
p_i->inq_info.results.scan_rsp_len = 0;
}
}
}
/******************************************************************************* /*******************************************************************************
** **
** Function btm_ble_process_adv_pkt_cont ** Function btm_ble_process_adv_pkt_cont
@ -3144,6 +3219,13 @@ static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt
BOOLEAN update = TRUE; BOOLEAN update = TRUE;
UINT8 result = 0; UINT8 result = 0;
//if scan duplicate is enabled, the adv packet without scan response is allowed to report to higgher layer
if(p_le_inq_cb->scan_duplicate_filter == BTM_BLE_SCAN_DUPLICATE_ENABLE) {
if(memcmp(bda, p_le_inq_cb->adv_addr, BD_ADDR_LEN) != 0) {
btm_ble_process_last_adv_pkt();
}
}
p_i = btm_inq_db_find (bda); p_i = btm_inq_db_find (bda);
/* Check if this address has already been processed for this inquiry */ /* Check if this address has already been processed for this inquiry */
@ -3172,7 +3254,7 @@ static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt
p_inq->inq_cmpl_info.num_resp++; p_inq->inq_cmpl_info.num_resp++;
} }
/* update the LE device information in inquiry database */ /* update the LE device information in inquiry database */
if (!btm_ble_update_inq_result(p_i, addr_type, evt_type, p)) { if (!btm_ble_update_inq_result(bda, p_i, addr_type, evt_type, p)) {
return; return;
} }
@ -3216,12 +3298,24 @@ static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt
} else { } else {
if (p_inq_results_cb && (result & BTM_BLE_INQ_RESULT)) { if (p_inq_results_cb && (result & BTM_BLE_INQ_RESULT)) {
(p_inq_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results, p_le_inq_cb->adv_data_cache); (p_inq_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results, p_le_inq_cb->adv_data_cache);
p_le_inq_cb->adv_len = 0;
memset(p_le_inq_cb->adv_addr, 0, BD_ADDR_LEN);
p_i->inq_info.results.adv_data_len = 0;
p_i->inq_info.results.scan_rsp_len = 0;
} }
if (p_obs_results_cb && (result & BTM_BLE_OBS_RESULT)) { if (p_obs_results_cb && (result & BTM_BLE_OBS_RESULT)) {
(p_obs_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results, p_le_inq_cb->adv_data_cache); (p_obs_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results, p_le_inq_cb->adv_data_cache);
p_le_inq_cb->adv_len = 0;
memset(p_le_inq_cb->adv_addr, 0, BD_ADDR_LEN);
p_i->inq_info.results.adv_data_len = 0;
p_i->inq_info.results.scan_rsp_len = 0;
} }
if (p_scan_results_cb && (result & BTM_BLE_DISCO_RESULT)) { if (p_scan_results_cb && (result & BTM_BLE_DISCO_RESULT)) {
(p_scan_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results, p_le_inq_cb->adv_data_cache); (p_scan_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results, p_le_inq_cb->adv_data_cache);
p_le_inq_cb->adv_len = 0;
memset(p_le_inq_cb->adv_addr, 0, BD_ADDR_LEN);
p_i->inq_info.results.adv_data_len = 0;
p_i->inq_info.results.scan_rsp_len = 0;
} }
} }
} }

View file

@ -162,7 +162,7 @@ typedef struct {
UINT8 adv_len; UINT8 adv_len;
UINT8 adv_data_cache[BTM_BLE_CACHE_ADV_DATA_MAX]; UINT8 adv_data_cache[BTM_BLE_CACHE_ADV_DATA_MAX];
BD_ADDR adv_addr;
/* inquiry BD addr database */ /* inquiry BD addr database */
UINT8 num_bd_entries; UINT8 num_bd_entries;
UINT8 max_bd_entries; UINT8 max_bd_entries;

View file

@ -582,6 +582,12 @@ typedef struct {
tBTM_BLE_REF_VALUE ref_value; tBTM_BLE_REF_VALUE ref_value;
} tBTM_BLE_BATCH_SCAN_CB; } tBTM_BLE_BATCH_SCAN_CB;
/// Ble scan duplicate type
enum {
BTM_BLE_SCAN_DUPLICATE_DISABLE = 0x0, /*!< the Link Layer should generate advertising reports to the host for each packet received */
BTM_BLE_SCAN_DUPLICATE_ENABLE = 0x1, /*!< the Link Layer should filter out duplicate advertising reports to the Host */
BTM_BLE_SCAN_DUPLICATE_MAX = 0x2, /*!< 0x02 0xFF, Reserved for future use */
};
/* filter selection bit index */ /* filter selection bit index */
#define BTM_BLE_PF_ADDR_FILTER 0 #define BTM_BLE_PF_ADDR_FILTER 0
#define BTM_BLE_PF_SRVC_DATA 1 #define BTM_BLE_PF_SRVC_DATA 1