Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1efa188a authored by Wei Wang's avatar Wei Wang Committed by Android (Google) Code Review
Browse files

Merge "LE batchscan consolidated reports" into lmp-dev

parents ae31a553 889fd4f8
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -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)
@@ -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:
+1 −0
Original line number Diff line number Diff line
@@ -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,
+275 −80
Original line number Diff line number Diff line
@@ -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);


/*******************************************************************************
**
@@ -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
@@ -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
@@ -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)
    {
@@ -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;
@@ -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;
        }
@@ -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
@@ -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;
@@ -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);
@@ -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;
@@ -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;
@@ -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
+16 −0
Original line number Diff line number Diff line
@@ -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,
@@ -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;