Loading system/bta/dm/bta_dm_act.c +5 −1 Original line number Diff line number Diff line Loading @@ -5371,7 +5371,8 @@ void bta_dm_ble_enable_batch_scan (tBTA_DM_MSG *p_data) btm_status = BTM_BleEnableBatchScan(p_data->ble_enable_scan.scan_mode, p_data->ble_enable_scan.scan_int,p_data->ble_enable_scan.scan_window, p_data->ble_enable_scan.discard_rule, p_data->ble_enable_scan.addr_type, p_data->ble_enable_scan.addr_type, p_data->ble_enable_scan.discard_rule, p_data->ble_enable_scan.ref_value); if(BTM_CMD_STARTED != btm_status) Loading Loading @@ -5456,6 +5457,9 @@ void bta_ble_scan_setup_cb(tBTM_BLE_BATCH_SCAN_EVT evt, tBTM_BLE_REF_VALUE ref_v { tBTA_BLE_BATCH_SCAN_EVT bta_evt = 0; APPL_TRACE_DEBUG("bta_ble_scan_setup_cb : evt: %d, ref_value: %d, status:%d", evt, ref_value, status); switch(evt) { case BTM_BLE_BATCH_SCAN_ENABLE_EVT: Loading system/btif/src/btif_gatt_client.c +1 −0 Original line number Diff line number Diff line Loading @@ -930,6 +930,7 @@ static void bta_batch_scan_reports_cb(tBTA_DM_BLE_REF_VALUE ref_value, UINT8 rep { btif_scan_track_cb.read_reports.p_rep_data = GKI_getbuf(data_len); memcpy(btif_scan_track_cb.read_reports.p_rep_data, p_rep_data, data_len); GKI_freebuf(p_rep_data); } btif_transfer_context(btif_gattc_upstreams_evt, BTA_GATTC_BTH_SCAN_RD_EVT, Loading system/stack/btm/btm_ble_batchscan.c +275 −80 Original line number Diff line number Diff line Loading @@ -47,6 +47,8 @@ tBTM_BLE_ADV_TRACK_CB ble_advtrack_cb; /******************************************************************************* ** Local functions *******************************************************************************/ void btm_ble_batchscan_vsc_cmpl_cback (tBTM_VSC_CMPL *p_params); /******************************************************************************* ** Loading Loading @@ -110,6 +112,132 @@ void btm_ble_batchscan_enq_op_q(UINT8 opcode, tBTM_BLE_BATCH_SCAN_STATE cur_stat % BTM_BLE_BATCH_SCAN_MAX; } /******************************************************************************* ** ** Function btm_ble_batchscan_enq_rep_q ** ** Description enqueue a batchscan report operation in q to check command complete ** status ** ** Returns void ** *******************************************************************************/ tBTM_STATUS btm_ble_batchscan_enq_rep_q(UINT8 report_format, tBTM_BLE_REF_VALUE ref_value) { int i = 0; for (i = 0; i < BTM_BLE_BATCH_REP_MAIN_Q_SIZE; i++) { if (report_format == ble_batchscan_cb.main_rep_q.rep_mode[i]) return BTM_ILLEGAL_VALUE; } ble_batchscan_cb.main_rep_q.rep_mode[ble_batchscan_cb.main_rep_q.next_idx] = report_format; ble_batchscan_cb.main_rep_q.ref_value[ble_batchscan_cb.main_rep_q.next_idx] = ref_value; ble_batchscan_cb.main_rep_q.num_records[ble_batchscan_cb.main_rep_q.next_idx] = 0; ble_batchscan_cb.main_rep_q.data_len[ble_batchscan_cb.main_rep_q.next_idx] = 0; ble_batchscan_cb.main_rep_q.p_data[ble_batchscan_cb.main_rep_q.next_idx] = NULL; BTM_TRACE_DEBUG("btm_ble_batchscan_enq_rep_q: index:%d, rep %d, ref %d", ble_batchscan_cb.main_rep_q.next_idx, report_format, ref_value); ble_batchscan_cb.main_rep_q.next_idx = (ble_batchscan_cb.main_rep_q.next_idx + 1) % BTM_BLE_BATCH_REP_MAIN_Q_SIZE; return BTM_SUCCESS; } /******************************************************************************* ** ** Function btm_ble_batchscan_enq_rep_data ** ** Description setup the data in the main report queue ** ** Returns void ** *******************************************************************************/ void btm_ble_batchscan_enq_rep_data(UINT8 report_format, UINT8 num_records, UINT8 *p_data, UINT8 data_len) { int index = 0, len = 0; UINT8 *p_orig_data = NULL, *p_app_data = NULL; for (index = 0; index < BTM_BLE_BATCH_REP_MAIN_Q_SIZE; index++) { if (report_format == ble_batchscan_cb.main_rep_q.rep_mode[index]) break; } BTM_TRACE_DEBUG("btm_ble_batchscan_enq_rep_data: index:%d, rep %d, num %d len : %d", index, report_format, num_records, data_len); if (index < BTM_BLE_BATCH_REP_MAIN_Q_SIZE && data_len > 0 && num_records > 0) { len = ble_batchscan_cb.main_rep_q.data_len[index]; p_orig_data = ble_batchscan_cb.main_rep_q.p_data[index]; if (NULL != p_orig_data) { p_app_data = GKI_getbuf(len + data_len); memcpy(p_app_data, p_orig_data, len); memcpy(p_app_data+len, p_data, data_len); GKI_freebuf(p_orig_data); ble_batchscan_cb.main_rep_q.p_data[index] = p_app_data; } else { p_app_data = GKI_getbuf(data_len); memcpy(p_app_data, p_data, data_len); ble_batchscan_cb.main_rep_q.p_data[index] = p_app_data; } ble_batchscan_cb.main_rep_q.num_records[index] += num_records; ble_batchscan_cb.main_rep_q.data_len[index] += data_len; } } /******************************************************************************* ** ** Function btm_ble_batchscan_deq_rep_q ** ** Description dequeue a batchscan report in q when command complete ** is received ** ** Returns void ** *******************************************************************************/ void btm_ble_batchscan_deq_rep_data(UINT8 report_format, tBTM_BLE_REF_VALUE *p_ref_value, UINT8 *p_num_records, UINT8 **p_data, UINT16 *p_data_len) { int index = 0; for (index = 0; index < BTM_BLE_BATCH_REP_MAIN_Q_SIZE; index++) { if (report_format == ble_batchscan_cb.main_rep_q.rep_mode[index]) break; } if (BTM_BLE_BATCH_REP_MAIN_Q_SIZE == index) { BTM_TRACE_ERROR("btm_ble_batchscan_deq_rep_data: rep_format:%d not found", report_format); return; } *p_num_records = ble_batchscan_cb.main_rep_q.num_records[index]; *p_ref_value = ble_batchscan_cb.main_rep_q.ref_value[index]; *p_data = ble_batchscan_cb.main_rep_q.p_data[index]; *p_data_len = ble_batchscan_cb.main_rep_q.data_len[index]; ble_batchscan_cb.main_rep_q.p_data[index] = NULL; ble_batchscan_cb.main_rep_q.data_len[index] = 0; ble_batchscan_cb.main_rep_q.rep_mode[index] = 0; ble_batchscan_cb.main_rep_q.ref_value[index] = 0; ble_batchscan_cb.main_rep_q.num_records[index] = 0; BTM_TRACE_DEBUG("btm_ble_batchscan_deq_rep_data: index:%d, rep %d, num %d, data_len %d", index, report_format, *p_num_records, *p_data_len); ble_batchscan_cb.main_rep_q.pending_idx = (ble_batchscan_cb.main_rep_q.pending_idx + 1) % BTM_BLE_BATCH_SCAN_MAX; } /******************************************************************************* ** ** Function btm_ble_batchscan_deq_op_q Loading @@ -132,6 +260,48 @@ void btm_ble_batchscan_deq_op_q(UINT8 *p_opcode,tBTM_BLE_BATCH_SCAN_STATE *cur_s % BTM_BLE_BATCH_SCAN_MAX; } /******************************************************************************* ** ** Function btm_ble_read_batchscan_reports ** ** Description This function reads the reports from controller ** ** Parameters scan_mode - The mode for which the reports are to be read out from the controller ** ref_value - Reference value ** ** Returns status ** *******************************************************************************/ tBTM_STATUS btm_ble_read_batchscan_reports(tBTM_BLE_BATCH_SCAN_MODE scan_mode, tBTM_BLE_REF_VALUE ref_value) { tBTM_STATUS status = BTM_NO_RESOURCES; UINT8 param[BTM_BLE_BATCH_SCAN_READ_RESULTS_LEN], *pp; pp = param; memset(param, 0, BTM_BLE_BATCH_SCAN_READ_RESULTS_LEN); UINT8_TO_STREAM (pp, BTM_BLE_BATCH_SCAN_READ_RESULTS); UINT8_TO_STREAM (pp, scan_mode); if ((status = BTM_VendorSpecificCommand (HCI_BLE_BATCH_SCAN_OCF, BTM_BLE_BATCH_SCAN_READ_RESULTS_LEN, param, btm_ble_batchscan_vsc_cmpl_cback)) != BTM_CMD_STARTED) { BTM_TRACE_ERROR("btm_ble_read_batchscan_reports %d", status); return BTM_ILLEGAL_VALUE; } if (BTM_CMD_STARTED == status) { /* The user needs to be provided scan read reports event */ btm_ble_batchscan_enq_op_q(BTM_BLE_BATCH_SCAN_READ_RESULTS, ble_batchscan_cb.cur_state, BTM_BLE_BATCH_SCAN_READ_REPTS_EVT, ref_value); } return status; } /******************************************************************************* ** ** Function btm_ble_batchscan_vsc_cmpl_cback Loading @@ -148,10 +318,14 @@ void btm_ble_batchscan_vsc_cmpl_cback (tBTM_VSC_CMPL *p_params) UINT8 *p = p_params->p_param_buf; UINT16 len = p_params->param_len; tBTM_BLE_REF_VALUE ref_value = 0; int index = 0; UINT8 status = 0, subcode = 0, opcode = 0; UINT8 report_format = 0, num_records = 0, cb_evt = 0; UINT16 data_len = 0; tBTM_BLE_BATCH_SCAN_STATE cur_state = 0; tBTM_STATUS btm_status = 0; UINT8 *p_data = NULL; if (len < 2) { Loading Loading @@ -198,6 +372,29 @@ void btm_ble_batchscan_vsc_cmpl_cback (tBTM_VSC_CMPL *p_params) BTM_TRACE_DEBUG("BTM_BLE_BATCH_SCAN_ENB_DISAB_CUST_FEAT status = %d, state: %d,evt=%d", status, ble_batchscan_cb.cur_state, cb_evt); /* Clear the queues here */ if(BTM_SUCCESS == status && BTM_BLE_SCAN_DISABLE_CALLED == cur_state) { for (index = 0; index < BTM_BLE_BATCH_REP_MAIN_Q_SIZE; index++) { ble_batchscan_cb.main_rep_q.rep_mode[index] = 0; if (NULL != ble_batchscan_cb.main_rep_q.p_data[index]) GKI_freebuf(ble_batchscan_cb.main_rep_q.p_data[index]); ble_batchscan_cb.main_rep_q.p_data[index] = NULL; ble_batchscan_cb.main_rep_q.ref_value[index] = 0; ble_batchscan_cb.main_rep_q.num_records[index] = 0; } for (index = 0; index < BTM_BLE_BATCH_SCAN_MAX; index++) { ble_batchscan_cb.op_q.sub_code[index] = 0; ble_batchscan_cb.op_q.ref_value[index] = 0; ble_batchscan_cb.op_q.cur_state[index] = 0; } ble_batchscan_cb.op_q.pending_idx = 0; ble_batchscan_cb.op_q.next_idx = 0; } if (cb_evt != 0 && NULL != ble_batchscan_cb.p_setup_cback) ble_batchscan_cb.p_setup_cback(cb_evt, ref_value, status); break; Loading Loading @@ -229,8 +426,33 @@ void btm_ble_batchscan_vsc_cmpl_cback (tBTM_VSC_CMPL *p_params) p = (uint8_t *)(p_params->p_param_buf + 4); BTM_TRACE_DEBUG("BTM_BLE_BATCH_SCAN_READ_RESULTS status=%d,len=%d,rec=%d", status, len-4, num_records); if (0 == num_records) { btm_ble_batchscan_deq_rep_data(report_format, &ref_value, &num_records, &p_data, &data_len); if (NULL != ble_batchscan_cb.p_scan_rep_cback) ble_batchscan_cb.p_scan_rep_cback(ref_value,report_format, num_records, data_len, p_data, status); } else { if ((len-4) > 0) { btm_ble_batchscan_enq_rep_data(report_format, num_records, p, len-4); /* More records could be in the buffer and needs to be pulled out */ btm_status = btm_ble_read_batchscan_reports(report_format, ref_value); if (BTM_CMD_STARTED != btm_status) { btm_ble_batchscan_deq_rep_data(report_format, &ref_value, &num_records, &p_data, &data_len); /* Send whatever is available, in case of a command failure */ if (NULL != ble_batchscan_cb.p_scan_rep_cback && NULL != p_data) ble_batchscan_cb.p_scan_rep_cback(ref_value,report_format, num_records,(len-4),p,status); num_records, data_len, p_data, status); } } } } break; } Loading Loading @@ -365,39 +587,6 @@ tBTM_STATUS btm_ble_enable_disable_batchscan(BOOLEAN enable_disable) return status; } /******************************************************************************* ** ** Function btm_ble_read_batchscan_reports ** ** Description This function reads the reports from controller ** ** Parameters scan_mode - The mode for which the reports are to be read out from the controller ** ** Returns status ** *******************************************************************************/ tBTM_STATUS btm_ble_read_batchscan_reports(tBTM_BLE_BATCH_SCAN_MODE scan_mode) { tBTM_STATUS status = BTM_NO_RESOURCES; UINT8 param[BTM_BLE_BATCH_SCAN_READ_RESULTS_LEN], *pp; pp = param; memset(param, 0, BTM_BLE_BATCH_SCAN_READ_RESULTS_LEN); UINT8_TO_STREAM (pp, BTM_BLE_BATCH_SCAN_READ_RESULTS); UINT8_TO_STREAM (pp, scan_mode); if ((status = BTM_VendorSpecificCommand (HCI_BLE_BATCH_SCAN_OCF, BTM_BLE_BATCH_SCAN_READ_RESULTS_LEN, param, btm_ble_batchscan_vsc_cmpl_cback)) != BTM_CMD_STARTED) { BTM_TRACE_ERROR("btm_ble_read_batchscan_reports %d", status); return BTM_ILLEGAL_VALUE; } return status; } /******************************************************************************* ** ** Function BTM_BleSetStorageConfig Loading Loading @@ -425,7 +614,9 @@ tBTM_STATUS BTM_BleSetStorageConfig(UINT8 batch_scan_full_max, UINT8 batch_scan_ tBTM_STATUS status = BTM_NO_RESOURCES; tBTM_BLE_VSC_CB cmn_ble_vsc_cb; BTM_TRACE_EVENT (" BTM_BleSetStorageConfig: %d", ble_batchscan_cb.cur_state); BTM_TRACE_EVENT (" BTM_BleSetStorageConfig: %d, %d, %d, %d, %d", ble_batchscan_cb.cur_state, ref_value, batch_scan_full_max, batch_scan_trunc_max, batch_scan_notify_threshold); if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1])) return BTM_ILLEGAL_VALUE; Loading @@ -451,8 +642,8 @@ tBTM_STATUS BTM_BleSetStorageConfig(UINT8 batch_scan_full_max, UINT8 batch_scan_ return BTM_ILLEGAL_VALUE; } if (BTM_BLE_SCAN_INVALID_STATE == ble_batchscan_cb.cur_state || BTM_BLE_SCAN_DISABLED_STATE == ble_batchscan_cb.cur_state || if (BTM_BLE_SCAN_INVALID_STATE == ble_batchscan_cb.cur_state || BTM_BLE_SCAN_DISABLED_STATE == ble_batchscan_cb.cur_state || BTM_BLE_SCAN_DISABLE_CALLED == ble_batchscan_cb.cur_state) { status = btm_ble_enable_disable_batchscan(TRUE); Loading Loading @@ -496,7 +687,8 @@ tBTM_STATUS BTM_BleEnableBatchScan(tBTM_BLE_BATCH_SCAN_MODE scan_mode, { tBTM_STATUS status = BTM_NO_RESOURCES; tBTM_BLE_VSC_CB cmn_ble_vsc_cb; BTM_TRACE_EVENT (" BTM_BleEnableBatchScan"); BTM_TRACE_EVENT (" BTM_BleEnableBatchScan: %d, %d, %d, %d, %d, %d", scan_mode, scan_interval, scan_window, addr_type, discard_rule, ref_value); if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1])) return BTM_ILLEGAL_VALUE; Loading Loading @@ -609,8 +801,10 @@ tBTM_STATUS BTM_BleReadScanReports(tBTM_BLE_BATCH_SCAN_MODE scan_mode, tBTM_STATUS status = BTM_NO_RESOURCES; tBTM_BLE_VSC_CB cmn_ble_vsc_cb; UINT8 read_scan_mode = 0; UINT8 *p_data = NULL, report_format = 0, num_records = 0; UINT16 data_len = 0; BTM_TRACE_EVENT (" BTM_BleReadScanReports"); BTM_TRACE_EVENT (" BTM_BleReadScanReports; %d, %d", scan_mode, ref_value); if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1])) return BTM_ILLEGAL_VALUE; Loading @@ -633,12 +827,13 @@ tBTM_STATUS BTM_BleReadScanReports(tBTM_BLE_BATCH_SCAN_MODE scan_mode, && (BTM_BLE_SCAN_ENABLED_STATE == ble_batchscan_cb.cur_state || BTM_BLE_SCAN_ENABLE_CALLED == ble_batchscan_cb.cur_state)) { status = btm_ble_read_batchscan_reports(scan_mode); if(BTM_CMD_STARTED == status) status = btm_ble_batchscan_enq_rep_q(scan_mode, ref_value); if (BTM_SUCCESS == status) { /* The user needs to be provided scan read reports event */ btm_ble_batchscan_enq_op_q(BTM_BLE_BATCH_SCAN_READ_RESULTS, ble_batchscan_cb.cur_state, BTM_BLE_BATCH_SCAN_READ_REPTS_EVT, ref_value); status = btm_ble_read_batchscan_reports(scan_mode, ref_value); if (BTM_CMD_STARTED != status) btm_ble_batchscan_deq_rep_data(scan_mode, &ref_value, &num_records, &p_data, &data_len); } } else Loading system/stack/include/btm_ble_api.h +16 −0 Original line number Diff line number Diff line Loading @@ -474,6 +474,10 @@ typedef void (tBTM_BLE_SCAN_SETUP_CBACK)(UINT8 evt, tBTM_BLE_REF_VALUE ref_value #define BTM_BLE_BATCH_SCAN_MAX 5 #endif #ifndef BTM_BLE_BATCH_REP_MAIN_Q_SIZE #define BTM_BLE_BATCH_REP_MAIN_Q_SIZE 2 #endif typedef enum { BTM_BLE_SCAN_INVALID_STATE=0, Loading @@ -492,11 +496,23 @@ typedef struct UINT8 next_idx; }tBTM_BLE_BATCH_SCAN_OPQ; typedef struct { UINT8 rep_mode[BTM_BLE_BATCH_REP_MAIN_Q_SIZE]; tBTM_BLE_REF_VALUE ref_value[BTM_BLE_BATCH_REP_MAIN_Q_SIZE]; UINT8 num_records[BTM_BLE_BATCH_REP_MAIN_Q_SIZE]; UINT16 data_len[BTM_BLE_BATCH_REP_MAIN_Q_SIZE]; UINT8 *p_data[BTM_BLE_BATCH_REP_MAIN_Q_SIZE]; UINT8 pending_idx; UINT8 next_idx; }tBTM_BLE_BATCH_SCAN_REP_Q; typedef struct { tBTM_BLE_BATCH_SCAN_STATE cur_state; tBTM_BLE_BATCH_SCAN_MODE scan_mode; tBTM_BLE_BATCH_SCAN_OPQ op_q; tBTM_BLE_BATCH_SCAN_REP_Q main_rep_q; tBTM_BLE_SCAN_SETUP_CBACK *p_setup_cback; tBTM_BLE_SCAN_THRESHOLD_CBACK *p_thres_cback; tBTM_BLE_SCAN_REP_CBACK *p_scan_rep_cback; Loading Loading
system/bta/dm/bta_dm_act.c +5 −1 Original line number Diff line number Diff line Loading @@ -5371,7 +5371,8 @@ void bta_dm_ble_enable_batch_scan (tBTA_DM_MSG *p_data) btm_status = BTM_BleEnableBatchScan(p_data->ble_enable_scan.scan_mode, p_data->ble_enable_scan.scan_int,p_data->ble_enable_scan.scan_window, p_data->ble_enable_scan.discard_rule, p_data->ble_enable_scan.addr_type, p_data->ble_enable_scan.addr_type, p_data->ble_enable_scan.discard_rule, p_data->ble_enable_scan.ref_value); if(BTM_CMD_STARTED != btm_status) Loading Loading @@ -5456,6 +5457,9 @@ void bta_ble_scan_setup_cb(tBTM_BLE_BATCH_SCAN_EVT evt, tBTM_BLE_REF_VALUE ref_v { tBTA_BLE_BATCH_SCAN_EVT bta_evt = 0; APPL_TRACE_DEBUG("bta_ble_scan_setup_cb : evt: %d, ref_value: %d, status:%d", evt, ref_value, status); switch(evt) { case BTM_BLE_BATCH_SCAN_ENABLE_EVT: Loading
system/btif/src/btif_gatt_client.c +1 −0 Original line number Diff line number Diff line Loading @@ -930,6 +930,7 @@ static void bta_batch_scan_reports_cb(tBTA_DM_BLE_REF_VALUE ref_value, UINT8 rep { btif_scan_track_cb.read_reports.p_rep_data = GKI_getbuf(data_len); memcpy(btif_scan_track_cb.read_reports.p_rep_data, p_rep_data, data_len); GKI_freebuf(p_rep_data); } btif_transfer_context(btif_gattc_upstreams_evt, BTA_GATTC_BTH_SCAN_RD_EVT, Loading
system/stack/btm/btm_ble_batchscan.c +275 −80 Original line number Diff line number Diff line Loading @@ -47,6 +47,8 @@ tBTM_BLE_ADV_TRACK_CB ble_advtrack_cb; /******************************************************************************* ** Local functions *******************************************************************************/ void btm_ble_batchscan_vsc_cmpl_cback (tBTM_VSC_CMPL *p_params); /******************************************************************************* ** Loading Loading @@ -110,6 +112,132 @@ void btm_ble_batchscan_enq_op_q(UINT8 opcode, tBTM_BLE_BATCH_SCAN_STATE cur_stat % BTM_BLE_BATCH_SCAN_MAX; } /******************************************************************************* ** ** Function btm_ble_batchscan_enq_rep_q ** ** Description enqueue a batchscan report operation in q to check command complete ** status ** ** Returns void ** *******************************************************************************/ tBTM_STATUS btm_ble_batchscan_enq_rep_q(UINT8 report_format, tBTM_BLE_REF_VALUE ref_value) { int i = 0; for (i = 0; i < BTM_BLE_BATCH_REP_MAIN_Q_SIZE; i++) { if (report_format == ble_batchscan_cb.main_rep_q.rep_mode[i]) return BTM_ILLEGAL_VALUE; } ble_batchscan_cb.main_rep_q.rep_mode[ble_batchscan_cb.main_rep_q.next_idx] = report_format; ble_batchscan_cb.main_rep_q.ref_value[ble_batchscan_cb.main_rep_q.next_idx] = ref_value; ble_batchscan_cb.main_rep_q.num_records[ble_batchscan_cb.main_rep_q.next_idx] = 0; ble_batchscan_cb.main_rep_q.data_len[ble_batchscan_cb.main_rep_q.next_idx] = 0; ble_batchscan_cb.main_rep_q.p_data[ble_batchscan_cb.main_rep_q.next_idx] = NULL; BTM_TRACE_DEBUG("btm_ble_batchscan_enq_rep_q: index:%d, rep %d, ref %d", ble_batchscan_cb.main_rep_q.next_idx, report_format, ref_value); ble_batchscan_cb.main_rep_q.next_idx = (ble_batchscan_cb.main_rep_q.next_idx + 1) % BTM_BLE_BATCH_REP_MAIN_Q_SIZE; return BTM_SUCCESS; } /******************************************************************************* ** ** Function btm_ble_batchscan_enq_rep_data ** ** Description setup the data in the main report queue ** ** Returns void ** *******************************************************************************/ void btm_ble_batchscan_enq_rep_data(UINT8 report_format, UINT8 num_records, UINT8 *p_data, UINT8 data_len) { int index = 0, len = 0; UINT8 *p_orig_data = NULL, *p_app_data = NULL; for (index = 0; index < BTM_BLE_BATCH_REP_MAIN_Q_SIZE; index++) { if (report_format == ble_batchscan_cb.main_rep_q.rep_mode[index]) break; } BTM_TRACE_DEBUG("btm_ble_batchscan_enq_rep_data: index:%d, rep %d, num %d len : %d", index, report_format, num_records, data_len); if (index < BTM_BLE_BATCH_REP_MAIN_Q_SIZE && data_len > 0 && num_records > 0) { len = ble_batchscan_cb.main_rep_q.data_len[index]; p_orig_data = ble_batchscan_cb.main_rep_q.p_data[index]; if (NULL != p_orig_data) { p_app_data = GKI_getbuf(len + data_len); memcpy(p_app_data, p_orig_data, len); memcpy(p_app_data+len, p_data, data_len); GKI_freebuf(p_orig_data); ble_batchscan_cb.main_rep_q.p_data[index] = p_app_data; } else { p_app_data = GKI_getbuf(data_len); memcpy(p_app_data, p_data, data_len); ble_batchscan_cb.main_rep_q.p_data[index] = p_app_data; } ble_batchscan_cb.main_rep_q.num_records[index] += num_records; ble_batchscan_cb.main_rep_q.data_len[index] += data_len; } } /******************************************************************************* ** ** Function btm_ble_batchscan_deq_rep_q ** ** Description dequeue a batchscan report in q when command complete ** is received ** ** Returns void ** *******************************************************************************/ void btm_ble_batchscan_deq_rep_data(UINT8 report_format, tBTM_BLE_REF_VALUE *p_ref_value, UINT8 *p_num_records, UINT8 **p_data, UINT16 *p_data_len) { int index = 0; for (index = 0; index < BTM_BLE_BATCH_REP_MAIN_Q_SIZE; index++) { if (report_format == ble_batchscan_cb.main_rep_q.rep_mode[index]) break; } if (BTM_BLE_BATCH_REP_MAIN_Q_SIZE == index) { BTM_TRACE_ERROR("btm_ble_batchscan_deq_rep_data: rep_format:%d not found", report_format); return; } *p_num_records = ble_batchscan_cb.main_rep_q.num_records[index]; *p_ref_value = ble_batchscan_cb.main_rep_q.ref_value[index]; *p_data = ble_batchscan_cb.main_rep_q.p_data[index]; *p_data_len = ble_batchscan_cb.main_rep_q.data_len[index]; ble_batchscan_cb.main_rep_q.p_data[index] = NULL; ble_batchscan_cb.main_rep_q.data_len[index] = 0; ble_batchscan_cb.main_rep_q.rep_mode[index] = 0; ble_batchscan_cb.main_rep_q.ref_value[index] = 0; ble_batchscan_cb.main_rep_q.num_records[index] = 0; BTM_TRACE_DEBUG("btm_ble_batchscan_deq_rep_data: index:%d, rep %d, num %d, data_len %d", index, report_format, *p_num_records, *p_data_len); ble_batchscan_cb.main_rep_q.pending_idx = (ble_batchscan_cb.main_rep_q.pending_idx + 1) % BTM_BLE_BATCH_SCAN_MAX; } /******************************************************************************* ** ** Function btm_ble_batchscan_deq_op_q Loading @@ -132,6 +260,48 @@ void btm_ble_batchscan_deq_op_q(UINT8 *p_opcode,tBTM_BLE_BATCH_SCAN_STATE *cur_s % BTM_BLE_BATCH_SCAN_MAX; } /******************************************************************************* ** ** Function btm_ble_read_batchscan_reports ** ** Description This function reads the reports from controller ** ** Parameters scan_mode - The mode for which the reports are to be read out from the controller ** ref_value - Reference value ** ** Returns status ** *******************************************************************************/ tBTM_STATUS btm_ble_read_batchscan_reports(tBTM_BLE_BATCH_SCAN_MODE scan_mode, tBTM_BLE_REF_VALUE ref_value) { tBTM_STATUS status = BTM_NO_RESOURCES; UINT8 param[BTM_BLE_BATCH_SCAN_READ_RESULTS_LEN], *pp; pp = param; memset(param, 0, BTM_BLE_BATCH_SCAN_READ_RESULTS_LEN); UINT8_TO_STREAM (pp, BTM_BLE_BATCH_SCAN_READ_RESULTS); UINT8_TO_STREAM (pp, scan_mode); if ((status = BTM_VendorSpecificCommand (HCI_BLE_BATCH_SCAN_OCF, BTM_BLE_BATCH_SCAN_READ_RESULTS_LEN, param, btm_ble_batchscan_vsc_cmpl_cback)) != BTM_CMD_STARTED) { BTM_TRACE_ERROR("btm_ble_read_batchscan_reports %d", status); return BTM_ILLEGAL_VALUE; } if (BTM_CMD_STARTED == status) { /* The user needs to be provided scan read reports event */ btm_ble_batchscan_enq_op_q(BTM_BLE_BATCH_SCAN_READ_RESULTS, ble_batchscan_cb.cur_state, BTM_BLE_BATCH_SCAN_READ_REPTS_EVT, ref_value); } return status; } /******************************************************************************* ** ** Function btm_ble_batchscan_vsc_cmpl_cback Loading @@ -148,10 +318,14 @@ void btm_ble_batchscan_vsc_cmpl_cback (tBTM_VSC_CMPL *p_params) UINT8 *p = p_params->p_param_buf; UINT16 len = p_params->param_len; tBTM_BLE_REF_VALUE ref_value = 0; int index = 0; UINT8 status = 0, subcode = 0, opcode = 0; UINT8 report_format = 0, num_records = 0, cb_evt = 0; UINT16 data_len = 0; tBTM_BLE_BATCH_SCAN_STATE cur_state = 0; tBTM_STATUS btm_status = 0; UINT8 *p_data = NULL; if (len < 2) { Loading Loading @@ -198,6 +372,29 @@ void btm_ble_batchscan_vsc_cmpl_cback (tBTM_VSC_CMPL *p_params) BTM_TRACE_DEBUG("BTM_BLE_BATCH_SCAN_ENB_DISAB_CUST_FEAT status = %d, state: %d,evt=%d", status, ble_batchscan_cb.cur_state, cb_evt); /* Clear the queues here */ if(BTM_SUCCESS == status && BTM_BLE_SCAN_DISABLE_CALLED == cur_state) { for (index = 0; index < BTM_BLE_BATCH_REP_MAIN_Q_SIZE; index++) { ble_batchscan_cb.main_rep_q.rep_mode[index] = 0; if (NULL != ble_batchscan_cb.main_rep_q.p_data[index]) GKI_freebuf(ble_batchscan_cb.main_rep_q.p_data[index]); ble_batchscan_cb.main_rep_q.p_data[index] = NULL; ble_batchscan_cb.main_rep_q.ref_value[index] = 0; ble_batchscan_cb.main_rep_q.num_records[index] = 0; } for (index = 0; index < BTM_BLE_BATCH_SCAN_MAX; index++) { ble_batchscan_cb.op_q.sub_code[index] = 0; ble_batchscan_cb.op_q.ref_value[index] = 0; ble_batchscan_cb.op_q.cur_state[index] = 0; } ble_batchscan_cb.op_q.pending_idx = 0; ble_batchscan_cb.op_q.next_idx = 0; } if (cb_evt != 0 && NULL != ble_batchscan_cb.p_setup_cback) ble_batchscan_cb.p_setup_cback(cb_evt, ref_value, status); break; Loading Loading @@ -229,8 +426,33 @@ void btm_ble_batchscan_vsc_cmpl_cback (tBTM_VSC_CMPL *p_params) p = (uint8_t *)(p_params->p_param_buf + 4); BTM_TRACE_DEBUG("BTM_BLE_BATCH_SCAN_READ_RESULTS status=%d,len=%d,rec=%d", status, len-4, num_records); if (0 == num_records) { btm_ble_batchscan_deq_rep_data(report_format, &ref_value, &num_records, &p_data, &data_len); if (NULL != ble_batchscan_cb.p_scan_rep_cback) ble_batchscan_cb.p_scan_rep_cback(ref_value,report_format, num_records, data_len, p_data, status); } else { if ((len-4) > 0) { btm_ble_batchscan_enq_rep_data(report_format, num_records, p, len-4); /* More records could be in the buffer and needs to be pulled out */ btm_status = btm_ble_read_batchscan_reports(report_format, ref_value); if (BTM_CMD_STARTED != btm_status) { btm_ble_batchscan_deq_rep_data(report_format, &ref_value, &num_records, &p_data, &data_len); /* Send whatever is available, in case of a command failure */ if (NULL != ble_batchscan_cb.p_scan_rep_cback && NULL != p_data) ble_batchscan_cb.p_scan_rep_cback(ref_value,report_format, num_records,(len-4),p,status); num_records, data_len, p_data, status); } } } } break; } Loading Loading @@ -365,39 +587,6 @@ tBTM_STATUS btm_ble_enable_disable_batchscan(BOOLEAN enable_disable) return status; } /******************************************************************************* ** ** Function btm_ble_read_batchscan_reports ** ** Description This function reads the reports from controller ** ** Parameters scan_mode - The mode for which the reports are to be read out from the controller ** ** Returns status ** *******************************************************************************/ tBTM_STATUS btm_ble_read_batchscan_reports(tBTM_BLE_BATCH_SCAN_MODE scan_mode) { tBTM_STATUS status = BTM_NO_RESOURCES; UINT8 param[BTM_BLE_BATCH_SCAN_READ_RESULTS_LEN], *pp; pp = param; memset(param, 0, BTM_BLE_BATCH_SCAN_READ_RESULTS_LEN); UINT8_TO_STREAM (pp, BTM_BLE_BATCH_SCAN_READ_RESULTS); UINT8_TO_STREAM (pp, scan_mode); if ((status = BTM_VendorSpecificCommand (HCI_BLE_BATCH_SCAN_OCF, BTM_BLE_BATCH_SCAN_READ_RESULTS_LEN, param, btm_ble_batchscan_vsc_cmpl_cback)) != BTM_CMD_STARTED) { BTM_TRACE_ERROR("btm_ble_read_batchscan_reports %d", status); return BTM_ILLEGAL_VALUE; } return status; } /******************************************************************************* ** ** Function BTM_BleSetStorageConfig Loading Loading @@ -425,7 +614,9 @@ tBTM_STATUS BTM_BleSetStorageConfig(UINT8 batch_scan_full_max, UINT8 batch_scan_ tBTM_STATUS status = BTM_NO_RESOURCES; tBTM_BLE_VSC_CB cmn_ble_vsc_cb; BTM_TRACE_EVENT (" BTM_BleSetStorageConfig: %d", ble_batchscan_cb.cur_state); BTM_TRACE_EVENT (" BTM_BleSetStorageConfig: %d, %d, %d, %d, %d", ble_batchscan_cb.cur_state, ref_value, batch_scan_full_max, batch_scan_trunc_max, batch_scan_notify_threshold); if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1])) return BTM_ILLEGAL_VALUE; Loading @@ -451,8 +642,8 @@ tBTM_STATUS BTM_BleSetStorageConfig(UINT8 batch_scan_full_max, UINT8 batch_scan_ return BTM_ILLEGAL_VALUE; } if (BTM_BLE_SCAN_INVALID_STATE == ble_batchscan_cb.cur_state || BTM_BLE_SCAN_DISABLED_STATE == ble_batchscan_cb.cur_state || if (BTM_BLE_SCAN_INVALID_STATE == ble_batchscan_cb.cur_state || BTM_BLE_SCAN_DISABLED_STATE == ble_batchscan_cb.cur_state || BTM_BLE_SCAN_DISABLE_CALLED == ble_batchscan_cb.cur_state) { status = btm_ble_enable_disable_batchscan(TRUE); Loading Loading @@ -496,7 +687,8 @@ tBTM_STATUS BTM_BleEnableBatchScan(tBTM_BLE_BATCH_SCAN_MODE scan_mode, { tBTM_STATUS status = BTM_NO_RESOURCES; tBTM_BLE_VSC_CB cmn_ble_vsc_cb; BTM_TRACE_EVENT (" BTM_BleEnableBatchScan"); BTM_TRACE_EVENT (" BTM_BleEnableBatchScan: %d, %d, %d, %d, %d, %d", scan_mode, scan_interval, scan_window, addr_type, discard_rule, ref_value); if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1])) return BTM_ILLEGAL_VALUE; Loading Loading @@ -609,8 +801,10 @@ tBTM_STATUS BTM_BleReadScanReports(tBTM_BLE_BATCH_SCAN_MODE scan_mode, tBTM_STATUS status = BTM_NO_RESOURCES; tBTM_BLE_VSC_CB cmn_ble_vsc_cb; UINT8 read_scan_mode = 0; UINT8 *p_data = NULL, report_format = 0, num_records = 0; UINT16 data_len = 0; BTM_TRACE_EVENT (" BTM_BleReadScanReports"); BTM_TRACE_EVENT (" BTM_BleReadScanReports; %d, %d", scan_mode, ref_value); if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1])) return BTM_ILLEGAL_VALUE; Loading @@ -633,12 +827,13 @@ tBTM_STATUS BTM_BleReadScanReports(tBTM_BLE_BATCH_SCAN_MODE scan_mode, && (BTM_BLE_SCAN_ENABLED_STATE == ble_batchscan_cb.cur_state || BTM_BLE_SCAN_ENABLE_CALLED == ble_batchscan_cb.cur_state)) { status = btm_ble_read_batchscan_reports(scan_mode); if(BTM_CMD_STARTED == status) status = btm_ble_batchscan_enq_rep_q(scan_mode, ref_value); if (BTM_SUCCESS == status) { /* The user needs to be provided scan read reports event */ btm_ble_batchscan_enq_op_q(BTM_BLE_BATCH_SCAN_READ_RESULTS, ble_batchscan_cb.cur_state, BTM_BLE_BATCH_SCAN_READ_REPTS_EVT, ref_value); status = btm_ble_read_batchscan_reports(scan_mode, ref_value); if (BTM_CMD_STARTED != status) btm_ble_batchscan_deq_rep_data(scan_mode, &ref_value, &num_records, &p_data, &data_len); } } else Loading
system/stack/include/btm_ble_api.h +16 −0 Original line number Diff line number Diff line Loading @@ -474,6 +474,10 @@ typedef void (tBTM_BLE_SCAN_SETUP_CBACK)(UINT8 evt, tBTM_BLE_REF_VALUE ref_value #define BTM_BLE_BATCH_SCAN_MAX 5 #endif #ifndef BTM_BLE_BATCH_REP_MAIN_Q_SIZE #define BTM_BLE_BATCH_REP_MAIN_Q_SIZE 2 #endif typedef enum { BTM_BLE_SCAN_INVALID_STATE=0, Loading @@ -492,11 +496,23 @@ typedef struct UINT8 next_idx; }tBTM_BLE_BATCH_SCAN_OPQ; typedef struct { UINT8 rep_mode[BTM_BLE_BATCH_REP_MAIN_Q_SIZE]; tBTM_BLE_REF_VALUE ref_value[BTM_BLE_BATCH_REP_MAIN_Q_SIZE]; UINT8 num_records[BTM_BLE_BATCH_REP_MAIN_Q_SIZE]; UINT16 data_len[BTM_BLE_BATCH_REP_MAIN_Q_SIZE]; UINT8 *p_data[BTM_BLE_BATCH_REP_MAIN_Q_SIZE]; UINT8 pending_idx; UINT8 next_idx; }tBTM_BLE_BATCH_SCAN_REP_Q; typedef struct { tBTM_BLE_BATCH_SCAN_STATE cur_state; tBTM_BLE_BATCH_SCAN_MODE scan_mode; tBTM_BLE_BATCH_SCAN_OPQ op_q; tBTM_BLE_BATCH_SCAN_REP_Q main_rep_q; tBTM_BLE_SCAN_SETUP_CBACK *p_setup_cback; tBTM_BLE_SCAN_THRESHOLD_CBACK *p_thres_cback; tBTM_BLE_SCAN_REP_CBACK *p_scan_rep_cback; Loading