diff --git a/system/bta/dm/bta_dm_act.c b/system/bta/dm/bta_dm_act.c index 349d6149eded1f948da6146c5c826a29539ee0a6..0dcbab37005f447a5b1feb7e9fa6a2e33aa7ee72 100644 --- a/system/bta/dm/bta_dm_act.c +++ b/system/bta/dm/bta_dm_act.c @@ -5042,7 +5042,6 @@ void bta_dm_ble_passkey_reply (tBTA_DM_MSG *p_data) { if (p_data->pin_reply.accept) { - BTM_BlePasskeyReply(p_data->ble_passkey_reply.bd_addr, BTM_SUCCESS, p_data->ble_passkey_reply.passkey); } else @@ -5327,6 +5326,142 @@ void btm_dm_ble_multi_adv_disable(tBTA_DM_MSG *p_data) #endif } +/******************************************************************************* +** +** Function bta_dm_ble_setup_storage +** +** Description This function configures up the storage parameters for ADV batch scanning +** +** Parameters: +** +*******************************************************************************/ +void bta_dm_ble_setup_storage (tBTA_DM_MSG *p_data) +{ +#if BLE_BATCH_SCAN_INCLUDED == TRUE + tBTM_STATUS btm_status = 0; + + btm_status = BTM_BleSetStorageConfig(p_data->ble_set_storage.batch_scan_full_max, + p_data->ble_set_storage.batch_scan_trunc_max, + p_data->ble_set_storage.batch_scan_notify_threshold, + p_data->ble_set_storage.p_setup_cback, + p_data->ble_set_storage.p_thres_cback, + p_data->ble_set_storage.p_read_rep_cback, + p_data->ble_set_storage.ref_value); + + if(BTM_CMD_STARTED != btm_status) + bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_CFG_STRG_EVT, p_data->ble_set_storage.ref_value, + btm_status); +#endif +} + +/******************************************************************************* +** +** Function bta_dm_ble_enable_batch_scan +** +** Description This function sets up the parameters and enables batch scan +** +** Parameters: +** +*******************************************************************************/ +void bta_dm_ble_enable_batch_scan (tBTA_DM_MSG *p_data) +{ +#if BLE_BATCH_SCAN_INCLUDED == TRUE + tBTM_STATUS btm_status = 0; + + 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.ref_value); + + if(BTM_CMD_STARTED != btm_status) + bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_ENABLE_EVT, p_data->ble_enable_scan.ref_value, + btm_status); + +#endif +} + +/******************************************************************************* +** +** Function bta_dm_ble_disable_batch_scan +** +** Description This function disables the batch scan +** +** Parameters: +** +*******************************************************************************/ +void bta_dm_ble_disable_batch_scan (tBTA_DM_MSG *p_data) +{ + UNUSED(p_data); +#if BLE_BATCH_SCAN_INCLUDED == TRUE + tBTM_STATUS btm_status = 0; + + btm_status = BTM_BleDisableBatchScan(p_data->ble_disable_scan.ref_value); + + if(BTM_CMD_STARTED != btm_status) + bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_DISABLE_EVT, p_data->ble_enable_scan.ref_value, + btm_status); +#endif +} + +/******************************************************************************* +** +** Function bta_dm_ble_read_scan_reports +** +** Description This function reads the batch scan reports +** +** Parameters: +** +*******************************************************************************/ +void bta_dm_ble_read_scan_reports(tBTA_DM_MSG *p_data) +{ +#if BLE_BATCH_SCAN_INCLUDED == TRUE + tBTM_STATUS btm_status = 0; + + btm_status = BTM_BleReadScanReports(p_data->ble_read_reports.scan_type, + p_data->ble_read_reports.ref_value); + + if(BTM_CMD_STARTED != btm_status) + bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_READ_REPTS_EVT, p_data->ble_enable_scan.ref_value, + btm_status); +#endif +} + +/******************************************************************************* +** +** Function bta_ble_scan_setup_cb +** +** Description Handle the setup callback from BTM layer and forward it to app layer +** +** Parameters: +** +*******************************************************************************/ +void bta_ble_scan_setup_cb(tBTM_BLE_BATCH_SCAN_EVT evt, tBTM_BLE_REF_VALUE ref_value, + tBTM_STATUS status) +{ + tBTA_BLE_BATCH_SCAN_EVT bta_evt = 0; + + switch(evt) + { + case BTM_BLE_BATCH_SCAN_ENABLE_EVT: + bta_evt = BTA_BLE_BATCH_SCAN_ENB_EVT; + break; + case BTM_BLE_BATCH_SCAN_CFG_STRG_EVT: + bta_evt = BTA_BLE_BATCH_SCAN_CFG_STRG_EVT; + break; + case BTM_BLE_BATCH_SCAN_DISABLE_EVT: + bta_evt = BTA_BLE_BATCH_SCAN_DIS_EVT; + break; + case BTM_BLE_BATCH_SCAN_PARAM_EVT: + bta_evt = BTA_BLE_BATCH_SCAN_PARAM_EVT; + break; + default: + break; + } + + if(NULL != bta_dm_cb.p_setup_cback) + bta_dm_cb.p_setup_cback(bta_evt, ref_value, status); +} + #if ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE)) #ifndef BTA_DM_GATT_CLOSE_DELAY_TOUT #define BTA_DM_GATT_CLOSE_DELAY_TOUT 1000 @@ -5661,6 +5796,7 @@ static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC *p_data) break; } } + #endif /* BTA_GATT_INCLUDED */ #if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE diff --git a/system/bta/dm/bta_dm_api.c b/system/bta/dm/bta_dm_api.c index 1c5e8e70d5cb3196c7202d1dc35fa0d4f1aa75b2..bf739adee3f6b81c4097c3eda574647a5d34e035 100644 --- a/system/bta/dm/bta_dm_api.c +++ b/system/bta/dm/bta_dm_api.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright (C) 2003-2012 Broadcom Corporation + * Copyright (C) 2003-2014 Broadcom Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -1575,6 +1575,134 @@ BTA_API extern void BTA_DmBleSetScanRsp (tBTA_BLE_AD_MASK data_mask, tBTA_BLE_AD } } +/******************************************************************************* +** +** Function BTA_DmBleSetStorageParams +** +** Description This function is called to override the BTA scan response. +** +** Parameters batch_scan_full_max -Max storage space (in %) allocated to full scanning +** batch_scan_trunc_max -Max storage space (in %) allocated to truncated scanning +** batch_scan_notify_threshold -Setup notification level based on total space +** p_setup_cback - Setup callback pointer +** p_thres_cback - Threshold callback pointer +** p_rep_cback - Reports callback pointer +** ref_value - Ref value +** +** Returns None +** +*******************************************************************************/ +BTA_API extern void BTA_DmBleSetStorageParams(UINT8 batch_scan_full_max, + UINT8 batch_scan_trunc_max, + UINT8 batch_scan_notify_threshold, + tBTA_BLE_SCAN_SETUP_CBACK *p_setup_cback, + tBTA_BLE_SCAN_THRESHOLD_CBACK *p_thres_cback, + tBTA_BLE_SCAN_REP_CBACK* p_rep_cback, + tBTA_DM_BLE_REF_VALUE ref_value) +{ + tBTA_DM_API_SET_STORAGE_CONFIG *p_msg; + bta_dm_cb.p_setup_cback = p_setup_cback; + if ((p_msg = (tBTA_DM_API_SET_STORAGE_CONFIG *) + GKI_getbuf(sizeof(tBTA_DM_API_SET_STORAGE_CONFIG))) != NULL) + { + p_msg->hdr.event = BTA_DM_API_BLE_SETUP_STORAGE_EVT; + p_msg->p_setup_cback=bta_ble_scan_setup_cb; + p_msg->p_thres_cback=p_thres_cback; + p_msg->p_read_rep_cback=p_rep_cback; + p_msg->ref_value = ref_value; + p_msg->batch_scan_full_max = batch_scan_full_max; + p_msg->batch_scan_trunc_max = batch_scan_trunc_max; + p_msg->batch_scan_notify_threshold = batch_scan_notify_threshold; + bta_sys_sendmsg(p_msg); + } +} + +/******************************************************************************* +** +** Function BTA_DmBleEnableBatchScan +** +** Description This function is called to enable the batch scan +** +** Parameters scan_mode -Batch scan mode +** scan_interval - Scan interval +** scan_window - Scan window +** discard_rule -Discard rules +** addr_type - Address type +** +** Returns None +** +*******************************************************************************/ +BTA_API extern void BTA_DmBleEnableBatchScan(tBTA_BLE_SCAN_MODE scan_mode, + UINT32 scan_interval, UINT32 scan_window, + tBTA_BLE_DISCARD_RULE discard_rule, + tBLE_ADDR_TYPE addr_type, + tBTA_DM_BLE_REF_VALUE ref_value) +{ + tBTA_DM_API_ENABLE_SCAN *p_msg; + + if ((p_msg = (tBTA_DM_API_ENABLE_SCAN *) GKI_getbuf(sizeof(tBTA_DM_API_ENABLE_SCAN))) != NULL) + { + p_msg->hdr.event = BTA_DM_API_BLE_ENABLE_BATCH_SCAN_EVT; + p_msg->scan_mode = scan_mode; + p_msg->scan_int = scan_interval; + p_msg->scan_window = scan_window; + p_msg->discard_rule = discard_rule; + p_msg->addr_type = addr_type; + p_msg->ref_value = ref_value; + bta_sys_sendmsg(p_msg); + } +} + +/******************************************************************************* +** +** Function BTA_DmBleDisableBatchScan +** +** Description This function is called to disable the batch scan +** +** Parameters +** +** Returns None +** +*******************************************************************************/ +BTA_API extern void BTA_DmBleDisableBatchScan(tBTA_DM_BLE_REF_VALUE ref_value) +{ + tBTA_DM_API_DISABLE_SCAN *p_msg; + + if ((p_msg = (tBTA_DM_API_DISABLE_SCAN *) + GKI_getbuf(sizeof(tBTA_DM_API_DISABLE_SCAN))) != NULL) + { + p_msg->hdr.event = BTA_DM_API_BLE_DISABLE_BATCH_SCAN_EVT; + p_msg->ref_value = ref_value; + bta_sys_sendmsg(p_msg); + } +} + +/******************************************************************************* +** +** Function BTA_DmBleReadScanReports +** +** Description This function is called to read scan reports +** +** Parameters scan_type -Batch scan mode +** +** Returns None +** +*******************************************************************************/ +BTA_API extern void BTA_DmBleReadScanReports(tBTA_BLE_SCAN_MODE scan_type, + tBTA_DM_BLE_REF_VALUE ref_value) +{ + tBTA_DM_API_READ_SCAN_REPORTS *p_msg; + + if ((p_msg = (tBTA_DM_API_READ_SCAN_REPORTS *) + GKI_getbuf(sizeof(tBTA_DM_API_READ_SCAN_REPORTS))) != NULL) + { + p_msg->hdr.event = BTA_DM_API_BLE_READ_SCAN_REPORTS_EVT; + p_msg->scan_type = scan_type; + p_msg->ref_value = ref_value; + bta_sys_sendmsg(p_msg); + } +} + /******************************************************************************* ** ** Function BTA_DmBleBroadcast diff --git a/system/bta/dm/bta_dm_int.h b/system/bta/dm/bta_dm_int.h index 901450187631091c5c2b71f18b7934530747fdbf..0a1e967b0acb5344d9b315c998e2d426ba9e112f 100644 --- a/system/bta/dm/bta_dm_int.h +++ b/system/bta/dm/bta_dm_int.h @@ -118,6 +118,11 @@ enum BTA_DM_API_BLE_MULTI_ADV_PARAM_UPD_EVT, BTA_DM_API_BLE_MULTI_ADV_DATA_EVT, BTA_DM_API_BLE_MULTI_ADV_DISABLE_EVT, + BTA_DM_API_BLE_SETUP_STORAGE_EVT, + BTA_DM_API_BLE_ENABLE_BATCH_SCAN_EVT, + BTA_DM_API_BLE_DISABLE_BATCH_SCAN_EVT, + BTA_DM_API_BLE_READ_SCAN_REPORTS_EVT, + BTA_DM_API_BLE_TRACK_ADVERTISER_EVT, #endif #if ( BTM_EIR_SERVER_INCLUDED == TRUE )&&( BTA_EIR_CANNED_UUID_LIST != TRUE )&&(BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0) @@ -584,7 +589,6 @@ typedef struct UINT8 inst_id; }tBTA_DM_API_BLE_MULTI_ADV_DISABLE; - typedef struct { BT_HDR hdr; @@ -593,6 +597,51 @@ typedef struct tBTA_SET_ADV_DATA_CMPL_CBACK *p_adv_data_cback; }tBTA_DM_API_SET_ADV_CONFIG; +typedef struct +{ + BT_HDR hdr; + UINT8 batch_scan_full_max; + UINT8 batch_scan_trunc_max; + UINT8 batch_scan_notify_threshold; + tBTA_BLE_SCAN_SETUP_CBACK *p_setup_cback; + tBTA_BLE_SCAN_THRESHOLD_CBACK *p_thres_cback; + tBTA_BLE_SCAN_REP_CBACK *p_read_rep_cback; + tBTA_DM_BLE_REF_VALUE ref_value; +} tBTA_DM_API_SET_STORAGE_CONFIG; + +typedef struct +{ + BT_HDR hdr; + tBTA_BLE_SCAN_MODE scan_mode; + UINT32 scan_int; + UINT32 scan_window; + tBTA_BLE_DISCARD_RULE discard_rule; + tBLE_ADDR_TYPE addr_type; + tBTA_DM_BLE_REF_VALUE ref_value; +} tBTA_DM_API_ENABLE_SCAN; + +typedef struct +{ + BT_HDR hdr; + tBTA_DM_BLE_REF_VALUE ref_value; +} tBTA_DM_API_DISABLE_SCAN; + +typedef struct +{ + BT_HDR hdr; + tBTA_BLE_SCAN_MODE scan_type; + tBTA_DM_BLE_REF_VALUE ref_value; +} tBTA_DM_API_READ_SCAN_REPORTS; + +typedef struct +{ + BT_HDR hdr; + UINT8 track_adv_action; + tBLE_ADDR_TYPE addr_type; + tBLE_BD_ADDR *p_bda; + UINT8 onlost_timeout; +} tBTA_DM_API_TRACK_ADVERTISER; + #endif /* BLE_INCLUDED */ typedef struct @@ -742,6 +791,12 @@ typedef union tBTA_DM_API_BLE_MULTI_ADV_PARAM ble_multi_adv_param; tBTA_DM_API_BLE_MULTI_ADV_DATA ble_multi_adv_data; tBTA_DM_API_BLE_MULTI_ADV_DISABLE ble_multi_adv_disable; + + tBTA_DM_API_SET_STORAGE_CONFIG ble_set_storage; + tBTA_DM_API_ENABLE_SCAN ble_enable_scan; + tBTA_DM_API_READ_SCAN_REPORTS ble_read_reports; + tBTA_DM_API_DISABLE_SCAN ble_disable_scan; + tBTA_DM_API_TRACK_ADVERTISER ble_track_advert; #endif tBTA_DM_API_SET_AFH_CHANNEL_ASSESSMENT set_afh_channel_assessment; @@ -844,6 +899,8 @@ typedef struct BOOLEAN is_bta_dm_active; tBTA_DM_ACTIVE_LINK device_list; tBTA_DM_SEC_CBACK *p_sec_cback; + tBTA_BLE_SCAN_SETUP_CBACK *p_setup_cback; + void *p_ref; TIMER_LIST_ENT signal_strength_timer; tBTA_SIG_STRENGTH_MASK signal_strength_mask; UINT16 state; @@ -1118,6 +1175,10 @@ extern void bta_dm_ble_multi_adv_data(tBTA_DM_MSG *p_data); extern void bta_dm_ble_multi_adv_upd_param(tBTA_DM_MSG *p_data); extern void bta_dm_ble_multi_adv_enb(tBTA_DM_MSG *p_data); +extern void bta_dm_ble_setup_storage(tBTA_DM_MSG *p_data); +extern void bta_dm_ble_enable_batch_scan(tBTA_DM_MSG * p_data); +extern void bta_dm_ble_disable_batch_scan(tBTA_DM_MSG * p_data); +extern void bta_dm_ble_read_scan_reports(tBTA_DM_MSG * p_data); #endif extern void bta_dm_set_encryption(tBTA_DM_MSG *p_data); extern void bta_dm_confirm(tBTA_DM_MSG *p_data); diff --git a/system/bta/dm/bta_dm_main.c b/system/bta/dm/bta_dm_main.c index 250dd28ce66382ba30204e16656fc7665dc768ba..ac0b9308ffab09e954a6ae58c45e19c3753de8ef 100644 --- a/system/bta/dm/bta_dm_main.c +++ b/system/bta/dm/bta_dm_main.c @@ -112,6 +112,10 @@ const tBTA_DM_ACTION bta_dm_action[] = bta_dm_ble_multi_adv_upd_param, /* BTA_DM_API_BLE_MULTI_ADV_PARAM_UPD_EVT */ bta_dm_ble_multi_adv_data, /* BTA_DM_API_BLE_MULTI_ADV_DATA_EVT */ btm_dm_ble_multi_adv_disable, /* BTA_DM_API_BLE_MULTI_ADV_DISABLE_EVT */ + bta_dm_ble_setup_storage, /* BTA_DM_API_BLE_SETUP_STORAGE_EVT */ + bta_dm_ble_enable_batch_scan, /* BTA_DM_API_BLE_ENABLE_BATCH_SCAN_EVT */ + bta_dm_ble_disable_batch_scan, /* BTA_DM_API_BLE_DISABLE_BATCH_SCAN_EVT */ + bta_dm_ble_read_scan_reports, /* BTA_DM_API_BLE_READ_SCAN_REPORTS_EVT */ #endif #if ( BTM_EIR_SERVER_INCLUDED == TRUE )&&( BTA_EIR_CANNED_UUID_LIST != TRUE )&&(BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0) diff --git a/system/bta/include/bta_api.h b/system/bta/include/bta_api.h index 1035bac9450e9c18befdd1bbcb69d379b00d1c2d..af1c31e49642337abb80f20147b584526af1b070 100644 --- a/system/bta/include/bta_api.h +++ b/system/bta/include/bta_api.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright (C) 2003-2012 Broadcom Corporation + * Copyright (C) 2003-2014 Broadcom Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -454,6 +454,41 @@ typedef struct UINT8 *p_remote_name; tBTA_BLE_SERVICE service; } tBTA_BLE_INQ_DATA; + +enum +{ + BTA_BLE_SCAN_MODE_PASS=1, + BTA_BLE_SCAN_MODE_ACTI=2, + BTA_BLE_SCAN_MODE_PASS_ACTI=3 +}; +typedef UINT8 tBTA_BLE_SCAN_MODE; + +enum +{ + BTA_BLE_DISCARD_OLD_ITEMS=0, + BTA_BLE_DISCARD_LOWER_RSSI_ITEMS=1 +}; +typedef UINT8 tBTA_BLE_DISCARD_RULE; + +enum +{ + BTA_BLE_ADV_SEEN_FIRST_TIME=0, + BTA_BLE_ADV_TRACKING_TIMEOUT=1 +}; +typedef UINT8 tBTA_BLE_ADV_CHANGE_REASON; + +enum +{ + BTA_BLE_BATCH_SCAN_ENB_EVT = 1, + BTA_BLE_BATCH_SCAN_CFG_STRG_EVT = 2, + BTA_BLE_BATCH_SCAN_DATA_EVT = 3, + BTA_BLE_BATCH_SCAN_THRES_EVT = 4, + BTA_BLE_BATCH_SCAN_PARAM_EVT = 5, + BTA_BLE_BATCH_SCAN_DIS_EVT = 6 +}; +typedef tBTM_BLE_BATCH_SCAN_EVT tBTA_BLE_BATCH_SCAN_EVT; + +typedef tBTM_BLE_TRACK_ADV_ACTION tBTA_BLE_TRACK_ADV_ACTION; #endif /* BLE customer specific feature function type definitions */ @@ -531,8 +566,8 @@ typedef struct UINT8 data_len; /* <= 20 bytes */ UINT8 *p_pattern; UINT16 company_id_mask; /* UUID value mask */ - UINT8 *p_pattern_mask; /* Manufactuer data matching mask, same length as data pattern, - set to all 0xff, match exact data */ + UINT8 *p_pattern_mask; /* Manufacturer data matching mask, same length + as data pattern, set to all 0xff, match exact data */ }tBTA_DM_BLE_PF_MANU_COND; typedef struct @@ -912,6 +947,7 @@ typedef UINT8 tBTA_BLE_MULTI_ADV_EVT; /* multi adv callback */ typedef void (tBTA_BLE_MULTI_ADV_CBACK)(tBTA_BLE_MULTI_ADV_EVT event, UINT8 inst_id, void *p_ref, tBTA_STATUS status); +typedef UINT8 tBTA_DM_BLE_REF_VALUE; /* Vendor Specific Command Callback */ typedef tBTM_VSC_CMPL_CB tBTA_VENDOR_CMPL_CBACK; @@ -1014,6 +1050,14 @@ typedef void (tBTA_DM_ENCRYPT_CBACK) (BD_ADDR bd_addr, tBTA_TRANSPORT transport, #define BTA_DM_BLE_SEC_NO_MITM BTM_BLE_SEC_ENCRYPT_NO_MITM #define BTA_DM_BLE_SEC_MITM BTM_BLE_SEC_ENCRYPT_MITM typedef tBTM_BLE_SEC_ACT tBTA_DM_BLE_SEC_ACT; + +typedef void (tBTA_BLE_SCAN_THRESHOLD_CBACK)(tBTA_DM_BLE_REF_VALUE ref_value); +typedef void (tBTA_BLE_SCAN_REP_CBACK) (tBTA_DM_BLE_REF_VALUE ref_value, UINT8 report_format, + UINT8 num_records, UINT16 data_len, + UINT8* p_rep_data, tBTA_STATUS status); +typedef void (tBTA_BLE_SCAN_SETUP_CBACK) (tBTA_BLE_BATCH_SCAN_EVT evt, tBTA_DM_BLE_REF_VALUE ref_value, + tBTA_STATUS status); + #else typedef UINT8 tBTA_DM_BLE_SEC_ACT; #endif @@ -2278,6 +2322,81 @@ BTA_API extern tBTA_STATUS BTA_BleDisableAdvInstance(UINT8 inst_id); *******************************************************************************/ BTA_API extern void BTA_DmBleUpdateConnectionParams(BD_ADDR bd_addr, UINT16 min_int, UINT16 max_int, UINT16 latency, UINT16 timeout); + +/******************************************************************************* +** +** Function BTA_DmBleSetStorageParams +** +** Description This function is called to set the storage parameters +** +** Parameters batch_scan_full_max -Max storage space (in %) allocated to full scanning +** batch_scan_trunc_max -Max storage space (in %) allocated to truncated scanning +** batch_scan_notify_threshold - Setup notification level based on total space +** consumed by both pools. Setting it to 0 will disable threshold notification +** p_setup_cback - Setup callback +** p_thres_cback - Threshold callback +** p_rep_cback - Reports callback +** p_ref - Ref pointer +** +** Returns None +** +*******************************************************************************/ +BTA_API extern void BTA_DmBleSetStorageParams(UINT8 batch_scan_full_max, + UINT8 batch_scan_trunc_max, + UINT8 batch_scan_notify_threshold, + tBTA_BLE_SCAN_SETUP_CBACK *p_setup_cback, + tBTA_BLE_SCAN_THRESHOLD_CBACK *p_thres_cback, + tBTA_BLE_SCAN_REP_CBACK* p_rep_cback, + tBTA_DM_BLE_REF_VALUE ref_value); + +/******************************************************************************* +** +** Function BTA_DmBleEnableBatchScan +** +** Description This function is called to enable the batch scan +** +** Parameters scan_mode -Batch scan mode +** scan_interval - Scan interval +** scan_window - Scan window +** discard_rule -Discard rules +** addr_type - Address type +** +** Returns None +** +*******************************************************************************/ +BTA_API extern void BTA_DmBleEnableBatchScan(tBTA_BLE_SCAN_MODE scan_mode, + UINT32 scan_interval, UINT32 scan_window, + tBTA_BLE_DISCARD_RULE discard_rule, + tBLE_ADDR_TYPE addr_type, + tBTA_DM_BLE_REF_VALUE ref_value); + +/******************************************************************************* +** +** Function BTA_DmBleReadScanReports +** +** Description This function is called to read the batch scan reports +** +** Parameters scan_mode -Batch scan mode +** +** Returns None +** +*******************************************************************************/ +BTA_API extern void BTA_DmBleReadScanReports(tBTA_BLE_SCAN_MODE scan_type, + tBTA_DM_BLE_REF_VALUE ref_value); + +/******************************************************************************* +** +** Function BTA_DmBleDisableBatchScan +** +** Description This function is called to disable the batch scanning +** +** Parameters None +** +** Returns None +** +*******************************************************************************/ +BTA_API extern void BTA_DmBleDisableBatchScan(tBTA_DM_BLE_REF_VALUE ref_value); + #endif #ifdef __cplusplus diff --git a/system/bta/include/bta_gatt_api.h b/system/bta/include/bta_gatt_api.h index 49af1912d7211b80866da3816eeed2d6b4141d47..3de755815bec24a5ae6d33accbba6e6b9663f25d 100644 --- a/system/bta/include/bta_gatt_api.h +++ b/system/bta/include/bta_gatt_api.h @@ -135,6 +135,12 @@ typedef UINT8 tBTA_GATT_STATUS; #define BTA_GATTC_MULT_ADV_DATA_EVT 22 /* Multi ADV data event */ #define BTA_GATTC_MULT_ADV_DIS_EVT 23 /* Disable Multi ADV event */ #define BTA_GATTC_CONGEST_EVT 24 /* Congestion event */ +#define BTA_GATTC_BTH_SCAN_ENB_EVT 25 /* Enable batch scan event */ +#define BTA_GATTC_BTH_SCAN_CFG_EVT 26 /* Config storage event */ +#define BTA_GATTC_BTH_SCAN_RD_EVT 27 /* Batch scan reports read event */ +#define BTA_GATTC_BTH_SCAN_THR_EVT 28 /* Batch scan threshold event */ +#define BTA_GATTC_BTH_SCAN_PARAM_EVT 29 /* Batch scan param event */ +#define BTA_GATTC_BTH_SCAN_DIS_EVT 30 /* Disable batch scan event */ typedef UINT8 tBTA_GATTC_EVT; diff --git a/system/btif/src/btif_gatt_client.c b/system/btif/src/btif_gatt_client.c index 3df5070e6a598d310773224b9fd6cf64ec516c12..1f8962ca187866f0059a32b3109d288461730387 100644 --- a/system/btif/src/btif_gatt_client.c +++ b/system/btif/src/btif_gatt_client.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright (C) 2009-2013 Broadcom Corporation + * Copyright (C) 2009-2014 Broadcom Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -100,7 +100,11 @@ typedef enum { BTIF_GATTC_ADV_INSTANCE_ENABLE, BTIF_GATTC_ADV_INSTANCE_UPDATE, BTIF_GATTC_ADV_INSTANCE_SET_DATA, - BTIF_GATTC_ADV_INSTANCE_DISABLE + BTIF_GATTC_ADV_INSTANCE_DISABLE, + BTIF_GATTC_CONFIG_STORAGE_PARAMS, + BTIF_GATTC_ENABLE_BATCH_SCAN, + BTIF_GATTC_READ_BATCH_SCAN_REPORTS, + BTIF_GATTC_DISABLE_BATCH_SCAN } btif_gattc_event_t; #define BTIF_GATT_MAX_OBSERVED_DEV 40 @@ -109,9 +113,34 @@ typedef enum { #define BTIF_GATTC_RSSI_EVT 0x1001 #define BTIF_GATTC_SCAN_FILTER_EVT 0x1003 +#define ENABLE_BATCH_SCAN 1 +#define DISABLE_BATCH_SCAN 0 + /******************************************************************************* ** Local type definitions ********************************************************************************/ +typedef struct +{ + uint8_t report_format; + uint16_t data_len; + uint8_t num_records; + uint8_t *p_rep_data; +} btgatt_batch_reports; + +typedef struct +{ + uint8_t status; + uint8_t client_if; + uint8_t batch_scan_full_max; + uint8_t batch_scan_trunc_max; + uint8_t batch_scan_notify_threshold; + tBTA_BLE_SCAN_MODE scan_mode; + uint32_t scan_interval; + uint32_t scan_window; + tBTA_BLE_DISCARD_RULE discard_rule; + tBLE_ADDR_TYPE addr_type; + btgatt_batch_reports read_reports; +} btgatt_batch_track_cb_t; typedef struct { @@ -254,6 +283,7 @@ static void btif_gattc_init_dev_cb(void) { memset(p_dev_cb, 0, sizeof(btif_gattc_dev_cb_t)); } + static void btif_gattc_add_remote_bdaddr (BD_ADDR p_bda, uint8_t addr_type) { BOOLEAN found=FALSE; @@ -616,6 +646,61 @@ static void btif_gattc_upstreams_evt(uint16_t event, char* p_param) ); break; + case BTA_GATTC_BTH_SCAN_CFG_EVT: + { + btgatt_batch_track_cb_t *p_data = (btgatt_batch_track_cb_t*)p_param; + HAL_CBACK(bt_gatt_callbacks, client->batchscan_cfg_storage_cb + , p_data->client_if + , p_data->status + ); + break; + } + + case BTA_GATTC_BTH_SCAN_ENB_EVT: + { + btgatt_batch_track_cb_t *p_data = (btgatt_batch_track_cb_t*)p_param; + HAL_CBACK(bt_gatt_callbacks, client->batchscan_enb_disable_cb + , ENABLE_BATCH_SCAN + , p_data->client_if + , p_data->status); + break; + } + + case BTA_GATTC_BTH_SCAN_DIS_EVT: + { + btgatt_batch_track_cb_t *p_data = (btgatt_batch_track_cb_t*)p_param; + HAL_CBACK(bt_gatt_callbacks, client->batchscan_enb_disable_cb + , DISABLE_BATCH_SCAN + , p_data->client_if + , p_data->status); + break; + } + + case BTA_GATTC_BTH_SCAN_THR_EVT: + { + btgatt_batch_track_cb_t *p_data = (btgatt_batch_track_cb_t*)p_param; + HAL_CBACK(bt_gatt_callbacks, client->batchscan_threshold_cb + , p_data->client_if); + break; + } + + case BTA_GATTC_BTH_SCAN_RD_EVT: + { + btgatt_batch_track_cb_t *p_data = (btgatt_batch_track_cb_t*)p_param; + uint8_t *p_rep_data = NULL; + + if(p_data->read_reports.data_len > 0) + { + p_rep_data = GKI_getbuf(p_data->read_reports.data_len); + memcpy(p_rep_data, p_data->read_reports.p_rep_data, p_data->read_reports.data_len); + } + + HAL_CBACK(bt_gatt_callbacks, client->batchscan_reports_cb + , p_data->client_if, p_data->status, p_data->read_reports.report_format + , p_data->read_reports.num_records, p_data->read_reports.data_len, p_rep_data); + break; + } + default: BTIF_TRACE_ERROR("%s: Unhandled event (%d)!", __FUNCTION__, event); break; @@ -650,15 +735,14 @@ static void bta_gattc_multi_adv_cback(tBTA_BLE_MULTI_ADV_EVT event, UINT8 inst_i btif_cb.status = call_status; btif_cb.client_if = client_if; + // Store the inst_id obtained from stack layer now btif_cb.inst_id = inst_id; switch(event) { case BTA_BLE_MULTI_ADV_ENB_EVT: - { upevt = BTA_GATTC_MULT_ADV_ENB_EVT; break; - } case BTA_BLE_MULTI_ADV_DISABLE_EVT: upevt = BTA_GATTC_MULT_ADV_DIS_EVT; @@ -691,6 +775,98 @@ static void bta_gattc_set_adv_data_cback(tBTA_STATUS call_status) (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL); } +static void bta_batch_scan_setup_cb (tBTA_BLE_BATCH_SCAN_EVT evt, + tBTA_DM_BLE_REF_VALUE ref_value, tBTA_STATUS status) +{ + UINT8 upevt = 0; + btgatt_batch_track_cb_t btif_scan_track_cb; + + btif_scan_track_cb.status = status; + btif_scan_track_cb.client_if = ref_value; + BTIF_TRACE_DEBUG3("bta_batch_scan_setup_cb-Status:%x, client_if:%d, evt=%d", + status, ref_value, evt); + + switch(evt) + { + case BTA_BLE_BATCH_SCAN_ENB_EVT: + { + upevt = BTA_GATTC_BTH_SCAN_ENB_EVT; + break; + } + + case BTA_BLE_BATCH_SCAN_DIS_EVT: + { + upevt = BTA_GATTC_BTH_SCAN_DIS_EVT; + break; + } + + case BTA_BLE_BATCH_SCAN_CFG_STRG_EVT: + { + upevt = BTA_GATTC_BTH_SCAN_CFG_EVT; + break; + } + + case BTA_BLE_BATCH_SCAN_DATA_EVT: + { + upevt = BTA_GATTC_BTH_SCAN_RD_EVT; + break; + } + + case BTA_BLE_BATCH_SCAN_THRES_EVT: + { + upevt = BTA_GATTC_BTH_SCAN_THR_EVT; + break; + } + + default: + return; + } + + btif_transfer_context(btif_gattc_upstreams_evt, upevt,(char*) &btif_scan_track_cb, + sizeof(btgatt_batch_track_cb_t), NULL); + +} + +static void bta_batch_scan_threshold_cb(tBTA_DM_BLE_REF_VALUE ref_value) +{ + btgatt_batch_track_cb_t btif_scan_track_cb; + btif_scan_track_cb.status = 0; + btif_scan_track_cb.client_if = ref_value; + + BTIF_TRACE_DEBUG2("%s - client_if:%d",__FUNCTION__, ref_value); + + btif_transfer_context(btif_gattc_upstreams_evt, BTA_GATTC_BTH_SCAN_THR_EVT, + (char*) &btif_scan_track_cb, sizeof(btif_gattc_cb_t), NULL); +} + +static void bta_batch_scan_reports_cb(tBTA_DM_BLE_REF_VALUE ref_value, UINT8 report_format, + UINT8 num_records, UINT16 data_len, + UINT8* p_rep_data, tBTA_STATUS status) +{ + btgatt_batch_track_cb_t btif_scan_track_cb; + BTIF_TRACE_DEBUG5("%s - client_if:%d, %d, %d, %d",__FUNCTION__, ref_value, status, num_records, + data_len); + + btif_scan_track_cb.status = status; + + btif_scan_track_cb.client_if = ref_value; + btif_scan_track_cb.read_reports.report_format = report_format; + btif_scan_track_cb.read_reports.data_len = data_len; + btif_scan_track_cb.read_reports.num_records = num_records; + + if(data_len > 0) + { + 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); + } + + btif_transfer_context(btif_gattc_upstreams_evt, BTA_GATTC_BTH_SCAN_RD_EVT, + (char*) &btif_scan_track_cb, sizeof(btgatt_batch_track_cb_t), NULL); + + if(data_len > 0) + GKI_freebuf(btif_scan_track_cb.read_reports.p_rep_data); +} + static void bta_scan_results_cb (tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data) { btif_gattc_cb_t btif_cb; @@ -771,6 +947,7 @@ static void btgattc_handle_event(uint16_t event, char* p_param) btif_gattc_cb_t* p_cb = NULL; btif_adv_data_t *p_adv_data = NULL; btgatt_multi_adv_inst_cb *p_inst_cb = NULL; + btgatt_batch_track_cb_t *p_scan_track_cb = NULL; if(BTIF_GATTC_ADV_INSTANCE_ENABLE == event || BTIF_GATTC_ADV_INSTANCE_DISABLE == event || BTIF_GATTC_ADV_INSTANCE_UPDATE == event) @@ -781,11 +958,15 @@ static void btgattc_handle_event(uint16_t event, char* p_param) { if(BTIF_GATTC_ADV_INSTANCE_SET_DATA == event || BTIF_GATTC_SET_ADV_DATA == event) p_adv_data = (btif_adv_data_t*)p_param; + else + if(BTIF_GATTC_CONFIG_STORAGE_PARAMS == event || BTIF_GATTC_ENABLE_BATCH_SCAN == event + || BTIF_GATTC_READ_BATCH_SCAN_REPORTS == event || BTIF_GATTC_DISABLE_BATCH_SCAN == event) + p_scan_track_cb = (btgatt_batch_track_cb_t *) p_param; else p_cb = (btif_gattc_cb_t*)p_param; } - if (!p_cb && !p_adv_data && !p_inst_cb) return; + if (!p_cb && !p_adv_data && !p_inst_cb && !p_scan_track_cb) return; BTIF_TRACE_EVENT("%s: Event %d", __FUNCTION__, event); @@ -1266,6 +1447,35 @@ static void btgattc_handle_event(uint16_t event, char* p_param) BTM_BleSetScanParams(p_cb->scan_interval, p_cb->scan_window, BTM_BLE_SCAN_MODE_ACTI); break; + case BTIF_GATTC_CONFIG_STORAGE_PARAMS: + { + BTA_DmBleSetStorageParams(p_scan_track_cb->batch_scan_full_max, + p_scan_track_cb->batch_scan_trunc_max, p_scan_track_cb->batch_scan_notify_threshold, + bta_batch_scan_setup_cb, bta_batch_scan_threshold_cb, bta_batch_scan_reports_cb, + (tBTA_DM_BLE_REF_VALUE)p_scan_track_cb->client_if); + break; + } + + case BTIF_GATTC_ENABLE_BATCH_SCAN: + { + BTA_DmBleEnableBatchScan(p_scan_track_cb->scan_mode, p_scan_track_cb->scan_interval, + p_scan_track_cb->scan_window, p_scan_track_cb->discard_rule, + p_scan_track_cb->addr_type, p_scan_track_cb->client_if); + break; + } + + case BTIF_GATTC_DISABLE_BATCH_SCAN: + { + BTA_DmBleDisableBatchScan(p_scan_track_cb->client_if); + break; + } + + case BTIF_GATTC_READ_BATCH_SCAN_REPORTS: + { + BTA_DmBleReadScanReports(p_scan_track_cb->scan_mode, p_scan_track_cb->client_if); + break; + } + default: BTIF_TRACE_ERROR("%s: Unknown event (%d)!", __FUNCTION__, event); break; @@ -1712,6 +1922,53 @@ static bt_status_t btif_gattc_multi_adv_disable(int client_if) (char*) &adv_cb, sizeof(btgatt_multi_adv_inst_cb), NULL); } +static bt_status_t btif_gattc_cfg_storage(int client_if,int batch_scan_full_max, + int batch_scan_trunc_max, int batch_scan_notify_threshold) +{ + CHECK_BTGATT_INIT(); + btgatt_batch_track_cb_t bt_scan_cb; + bt_scan_cb.client_if = (uint8_t) client_if; + bt_scan_cb.batch_scan_full_max = batch_scan_full_max; + bt_scan_cb.batch_scan_trunc_max = batch_scan_trunc_max; + bt_scan_cb.batch_scan_notify_threshold = batch_scan_notify_threshold; + return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_CONFIG_STORAGE_PARAMS, + (char*) &bt_scan_cb, sizeof(btgatt_batch_track_cb_t), NULL); +} + +static bt_status_t btif_gattc_enb_batch_scan(int client_if,int scan_mode, int scan_interval, + int scan_window, int addr_type, int discard_rule) +{ + CHECK_BTGATT_INIT(); + btgatt_batch_track_cb_t bt_scan_cb; + bt_scan_cb.client_if = (uint8_t) client_if; + bt_scan_cb.scan_mode = scan_mode; + bt_scan_cb.scan_interval = scan_interval; + bt_scan_cb.scan_window = scan_window; + bt_scan_cb.discard_rule = discard_rule; + bt_scan_cb.addr_type = addr_type; + return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_ENABLE_BATCH_SCAN, + (char*) &bt_scan_cb, sizeof(btgatt_batch_track_cb_t), NULL); +} + +static bt_status_t btif_gattc_dis_batch_scan(int client_if) +{ + CHECK_BTGATT_INIT(); + btgatt_batch_track_cb_t bt_scan_cb; + bt_scan_cb.client_if = (uint8_t) client_if; + return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_DISABLE_BATCH_SCAN, + (char*) &bt_scan_cb, sizeof(btgatt_batch_track_cb_t), NULL); +} + +static bt_status_t btif_gattc_read_batch_scan_reports(int client_if, int scan_mode) +{ + CHECK_BTGATT_INIT(); + btgatt_batch_track_cb_t bt_scan_cb; + bt_scan_cb.client_if = (uint8_t) client_if; + bt_scan_cb.scan_mode = scan_mode; + return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_READ_BATCH_SCAN_REPORTS, + (char*) &bt_scan_cb, sizeof(btgatt_batch_track_cb_t), NULL); +} + extern bt_status_t btif_gattc_test_command_impl(int command, btgatt_test_params_t* params); static bt_status_t btif_gattc_test_command(int command, btgatt_test_params_t* params) @@ -1751,6 +2008,10 @@ const btgatt_client_interface_t btgattClientInterface = { btif_gattc_multi_adv_update, btif_gattc_multi_adv_setdata, btif_gattc_multi_adv_disable, + btif_gattc_cfg_storage, + btif_gattc_enb_batch_scan, + btif_gattc_dis_batch_scan, + btif_gattc_read_batch_scan_reports, btif_gattc_test_command }; diff --git a/system/include/bt_target.h b/system/include/bt_target.h index 25f4349cb0f9304bf75ee3ade936fcec08b52e52..ec7399949fc160dab289374bf2968d3afd3a8987 100644 --- a/system/include/bt_target.h +++ b/system/include/bt_target.h @@ -1318,6 +1318,10 @@ and USER_HW_DISABLE_API macros */ #define BLE_VND_INCLUDED TRUE #endif +#ifndef BLE_BATCH_SCAN_INCLUDED +#define BLE_BATCH_SCAN_INCLUDED TRUE +#endif + /****************************************************************************** ** ** ATT/GATT Protocol/Profile Settings diff --git a/system/stack/Android.mk b/system/stack/Android.mk index fd76ed8b9a55f0f91a1ee34d0fb46344ccd0fa78..404d3d8a2ce8a61374f3b2d471d47ca95167d43a 100644 --- a/system/stack/Android.mk +++ b/system/stack/Android.mk @@ -66,6 +66,7 @@ LOCAL_SRC_FILES:= \ ./btm/btm_dev.c \ ./btm/btm_ble_gap.c \ ./btm/btm_ble_multi_adv.c \ + ./btm/btm_ble_batchscan.c \ ./btm/btm_acl.c \ ./btm/btm_sco.c \ ./btm/btm_pm.c \ diff --git a/system/stack/btm/btm_ble_batchscan.c b/system/stack/btm/btm_ble_batchscan.c new file mode 100644 index 0000000000000000000000000000000000000000..015284fd1ad3081781515929281dda5111cd9ae1 --- /dev/null +++ b/system/stack/btm/btm_ble_batchscan.c @@ -0,0 +1,655 @@ +/****************************************************************************** + * + * Copyright (C) 2014 Broadcom Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ +#include <string.h> +#include <stdio.h> +#include <stddef.h> +#include "bt_target.h" + +#include "btm_ble_api.h" +#include "bt_types.h" +#include "bt_utils.h" +#include "btu.h" +#include "btm_int.h" +#include "hcimsgs.h" + +#if (BLE_INCLUDED == TRUE && BLE_BATCH_SCAN_INCLUDED == TRUE) + +tBTM_BLE_BATCH_SCAN_CB ble_batchscan_cb; + + +/* length of each batch scan command */ +#define BTM_BLE_BATCH_SCAN_STORAGE_CFG_LEN 4 +#define BTM_BLE_BATCH_SCAN_PARAM_CONFIG_LEN 12 +#define BTM_BLE_BATCH_SCAN_ENB_DISB_LEN 2 +#define BTM_BLE_BATCH_SCAN_READ_RESULTS_LEN 2 + +#define BTM_BLE_BATCH_SCAN_CB_EVT_MASK 0xF0 +#define BTM_BLE_BATCH_SCAN_SUBCODE_MASK 0x0F + +/******************************************************************************* +** Local functions +*******************************************************************************/ + +/******************************************************************************* +** +** Function btm_ble_batchscan_filter_track_adv_vse_cback +** +** Description VSE callback for batch scan, filter, and tracking events. +** +** Returns None +** +*******************************************************************************/ +void btm_ble_batchscan_filter_track_adv_vse_cback(UINT8 len, UINT8 *p) +{ + UINT8 sub_event; + UINT8 reason; + + STREAM_TO_UINT8(sub_event, p); + + BTM_TRACE_EVENT("btm_ble_batchscan_filter_track_adv_vse_cback called with event:%x", sub_event); + if (HCI_VSE_SUBCODE_BLE_THRESHOLD_SUB_EVT == sub_event && + NULL != ble_batchscan_cb.p_thres_cback) + { + ble_batchscan_cb.p_thres_cback(ble_batchscan_cb.ref_value); + } +} + +/******************************************************************************* +** +** Function btm_ble_batchscan_enq_op_q +** +** Description enqueue a batchscan operation in q to check command complete +** status +** +** Returns void +** +*******************************************************************************/ +void btm_ble_batchscan_enq_op_q(UINT8 opcode, tBTM_BLE_BATCH_SCAN_STATE cur_state, + UINT8 cb_evt, tBTM_BLE_REF_VALUE ref_value) +{ + ble_batchscan_cb.op_q.sub_code[ble_batchscan_cb.op_q.next_idx] = (opcode |(cb_evt << 4)); + ble_batchscan_cb.op_q.cur_state[ble_batchscan_cb.op_q.next_idx] = cur_state; + ble_batchscan_cb.op_q.ref_value[ble_batchscan_cb.op_q.next_idx] = ref_value; + BTM_TRACE_DEBUG("btm_ble_batchscan_enq_op_q: subcode:%d, Cur_state:%d, ref_value:%d", + ble_batchscan_cb.op_q.sub_code[ble_batchscan_cb.op_q.next_idx], + ble_batchscan_cb.op_q.cur_state[ble_batchscan_cb.op_q.next_idx], + ble_batchscan_cb.op_q.ref_value[ble_batchscan_cb.op_q.next_idx]); + ble_batchscan_cb.op_q.next_idx = (ble_batchscan_cb.op_q.next_idx + 1) + % BTM_BLE_BATCH_SCAN_MAX; +} + +/******************************************************************************* +** +** Function btm_ble_batchscan_deq_op_q +** +** Description dequeue a batch scan operation from q when command complete +** is received +** +** Returns void +** +*******************************************************************************/ +void btm_ble_batchscan_deq_op_q(UINT8 *p_opcode,tBTM_BLE_BATCH_SCAN_STATE *cur_state, + UINT8 *p_cb_evt, tBTM_BLE_REF_VALUE *p_ref) +{ + *p_cb_evt = (ble_batchscan_cb.op_q.sub_code[ble_batchscan_cb.op_q.pending_idx] >> 4); + *p_opcode = (ble_batchscan_cb.op_q.sub_code[ble_batchscan_cb.op_q.pending_idx] + & BTM_BLE_BATCH_SCAN_SUBCODE_MASK); + *p_ref = ble_batchscan_cb.op_q.ref_value[ble_batchscan_cb.op_q.pending_idx]; + *cur_state = (ble_batchscan_cb.op_q.cur_state[ble_batchscan_cb.op_q.pending_idx]); + ble_batchscan_cb.op_q.pending_idx = (ble_batchscan_cb.op_q.pending_idx + 1) + % BTM_BLE_BATCH_SCAN_MAX; +} + +/******************************************************************************* +** +** Function btm_ble_batchscan_vsc_cmpl_cback +** +** Description Batch scan VSC complete callback +** +** Parameters p_params - VSC completed callback parameters +** +** Returns void +** +*******************************************************************************/ +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; + + UINT8 status = 0, subcode = 0, opcode = 0; + UINT8 report_format = 0, num_records = 0, cb_evt = 0; + tBTM_BLE_BATCH_SCAN_STATE cur_state = 0; + + if (len < 2) + { + BTM_TRACE_ERROR("wrong length for btm_ble_batch_scan_vsc_cmpl_cback"); + btm_ble_batchscan_deq_op_q(&opcode, &cur_state, &cb_evt, &ref_value); + return; + } + + STREAM_TO_UINT8(status, p); + STREAM_TO_UINT8(subcode, p); + + btm_ble_batchscan_deq_op_q(&opcode, &cur_state, &cb_evt, &ref_value); + + BTM_TRACE_DEBUG("btm_ble_batchscan op_code = %02x state = %02x cb_evt = %02x,ref_value=%d", + opcode, cur_state, cb_evt, ref_value); + + if (opcode != subcode) + { + BTM_TRACE_ERROR("Got unexpected VSC cmpl, expected: %d got: %d",subcode,opcode); + return; + } + + switch (subcode) + { + case BTM_BLE_BATCH_SCAN_ENB_DISAB_CUST_FEATURE: + { + if(BTM_SUCCESS == status && BTM_BLE_SCAN_ENABLE_CALLED == cur_state) + ble_batchscan_cb.cur_state = BTM_BLE_SCAN_ENABLED_STATE; + else + if(BTM_BLE_SCAN_ENABLE_CALLED == cur_state) + { + BTM_TRACE_ERROR("SCAN_ENB_DISAB_CUST_FEATURE - Invalid state after enb"); + ble_batchscan_cb.cur_state = BTM_BLE_SCAN_INVALID_STATE; + } + + if(BTM_SUCCESS == status && BTM_BLE_SCAN_DISABLE_CALLED == cur_state) + ble_batchscan_cb.cur_state = BTM_BLE_SCAN_DISABLED_STATE; + else + if(BTM_BLE_SCAN_DISABLE_CALLED == cur_state) + { + BTM_TRACE_ERROR("SCAN_ENB_DISAB_CUST_FEATURE - Invalid state after disabled"); + ble_batchscan_cb.cur_state = BTM_BLE_SCAN_INVALID_STATE; + } + 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); + + if(cb_evt != 0 && NULL != ble_batchscan_cb.p_setup_cback) + ble_batchscan_cb.p_setup_cback(cb_evt, ref_value, status); + break; + } + + case BTM_BLE_BATCH_SCAN_SET_STORAGE_PARAM: + { + BTM_TRACE_DEBUG("BTM_BLE_BATCH_SCAN_SET_STORAGE_PARAM status = %d, evt=%d", + status, cb_evt); + if(cb_evt != 0 && NULL != ble_batchscan_cb.p_setup_cback) + ble_batchscan_cb.p_setup_cback(cb_evt, ref_value, status); + break; + } + + case BTM_BLE_BATCH_SCAN_SET_PARAMS: + { + BTM_TRACE_DEBUG("BTM_BLE_BATCH_SCAN_SET_PARAMS status = %d,evt=%d", status, cb_evt); + if(cb_evt != 0 && NULL != ble_batchscan_cb.p_setup_cback) + ble_batchscan_cb.p_setup_cback(cb_evt, ref_value, status); + break; + } + + case BTM_BLE_BATCH_SCAN_READ_RESULTS: + { + if(cb_evt != 0 && NULL != ble_batchscan_cb.p_scan_rep_cback) + { + STREAM_TO_UINT8(report_format,p); + STREAM_TO_UINT8(num_records, p); + 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); + ble_batchscan_cb.p_scan_rep_cback(ref_value,report_format, + num_records,(len-4),p,status); + } + break; + } + + default: + break; + } + + return; +} + +/******************************************************************************* +** +** Function btm_ble_set_storage_config +** +** Description This function writes the storage configuration in controller +** +** Parameters batch_scan_full_max -Max storage space (in %) allocated to full scanning +** batch_scan_trunc_max -Max storage space (in %) allocated to truncated scanning +** batch_scan_notify_threshold - Setup notification level based on total space +** +** Returns status +** +*******************************************************************************/ +tBTM_STATUS btm_ble_set_storage_config(UINT8 batch_scan_full_max, UINT8 batch_scan_trunc_max, + UINT8 batch_scan_notify_threshold) +{ + tBTM_STATUS status = BTM_NO_RESOURCES; + UINT8 param[BTM_BLE_BATCH_SCAN_STORAGE_CFG_LEN], *pp; + + pp = param; + memset(param, 0, BTM_BLE_BATCH_SCAN_STORAGE_CFG_LEN); + + UINT8_TO_STREAM (pp, BTM_BLE_BATCH_SCAN_SET_STORAGE_PARAM); + UINT8_TO_STREAM (pp, batch_scan_full_max); + UINT8_TO_STREAM (pp, batch_scan_trunc_max); + UINT8_TO_STREAM (pp, batch_scan_notify_threshold); + + if ((status = BTM_VendorSpecificCommand (HCI_BLE_BATCH_SCAN_OCF, + BTM_BLE_BATCH_SCAN_STORAGE_CFG_LEN, param, + btm_ble_batchscan_vsc_cmpl_cback))!= BTM_CMD_STARTED) + { + BTM_TRACE_ERROR("btm_ble_set_storage_config %d", status); + return BTM_ILLEGAL_VALUE; + } + + return status; +} + +/******************************************************************************* +** +** Function btm_ble_set_batchscan_param +** +** Description This function writes the batch scan params in controller +** +** Parameters scan_mode -Batch scan mode +** scan_interval - Scan interval +** scan_window - Scan window +** discard_rule -Discard rules +** addr_type - Address type +** +** Returns status +** +*******************************************************************************/ +tBTM_STATUS btm_ble_set_batchscan_param(tBTM_BLE_BATCH_SCAN_MODE scan_mode, + UINT32 scan_interval, UINT32 scan_window, tBLE_ADDR_TYPE addr_type, + tBTM_BLE_DISCARD_RULE discard_rule) +{ + tBTM_STATUS status = BTM_NO_RESOURCES; + UINT8 scan_param[BTM_BLE_BATCH_SCAN_PARAM_CONFIG_LEN], *pp_scan; + + pp_scan = scan_param; + memset(scan_param, 0, BTM_BLE_BATCH_SCAN_PARAM_CONFIG_LEN); + + UINT8_TO_STREAM (pp_scan, BTM_BLE_BATCH_SCAN_SET_PARAMS); + UINT8_TO_STREAM (pp_scan, scan_mode); + UINT32_TO_STREAM (pp_scan, scan_interval); + UINT32_TO_STREAM (pp_scan, scan_window); + UINT8_TO_STREAM (pp_scan, addr_type); + UINT8_TO_STREAM (pp_scan, discard_rule); + + if ((status = BTM_VendorSpecificCommand (HCI_BLE_BATCH_SCAN_OCF, + BTM_BLE_BATCH_SCAN_PARAM_CONFIG_LEN, + scan_param, btm_ble_batchscan_vsc_cmpl_cback))!= BTM_CMD_STARTED) + { + BTM_TRACE_ERROR("btm_ble_set_batchscan_param %d", status); + return BTM_ILLEGAL_VALUE; + } + + return status; +} + +/******************************************************************************* +** +** Function btm_ble_enable_disable_batchscan +** +** Description This function enables the customer specific feature in controller +** +** Parameters enable_disable: true - enable, false - disable +** +** Returns status +** +*******************************************************************************/ +tBTM_STATUS btm_ble_enable_disable_batchscan(BOOLEAN enable_disable) +{ + tBTM_STATUS status = BTM_NO_RESOURCES; + UINT8 enb_disble = 0x01; + UINT8 enable_param[BTM_BLE_BATCH_SCAN_ENB_DISB_LEN], *pp_enable; + + if(!enable_disable) + enb_disble = 0x00; + + pp_enable = enable_param; + memset(enable_param, 0, BTM_BLE_BATCH_SCAN_ENB_DISB_LEN); + + UINT8_TO_STREAM (pp_enable, BTM_BLE_BATCH_SCAN_ENB_DISAB_CUST_FEATURE); + UINT8_TO_STREAM (pp_enable, enb_disble); + + if ((status = BTM_VendorSpecificCommand (HCI_BLE_BATCH_SCAN_OCF, + BTM_BLE_BATCH_SCAN_ENB_DISB_LEN, enable_param, + btm_ble_batchscan_vsc_cmpl_cback))!= BTM_CMD_STARTED) + { + status = BTM_MODE_UNSUPPORTED; + BTM_TRACE_ERROR("btm_ble_enable_disable_batchscan %d", status); + return BTM_ILLEGAL_VALUE; + } + + if(enable_disable) + ble_batchscan_cb.cur_state = BTM_BLE_SCAN_ENABLE_CALLED; + else + ble_batchscan_cb.cur_state = BTM_BLE_SCAN_DISABLE_CALLED; + 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 +** +** Description This function is called to write storage config params. +** +** Parameters: batch_scan_full_max - Max storage space (in %) allocated to full style +** batch_scan_trunc_max - Max storage space (in %) allocated to trunc style +** batch_scan_notify_threshold - Setup notification level based on total space +** p_setup_cback - Setup callback pointer +** p_thres_cback - Threshold callback pointer +** p_rep_cback - Reports callback pointer +** ref_value - Reference value +** +** Returns tBTM_STATUS +** +*******************************************************************************/ +tBTM_STATUS BTM_BleSetStorageConfig(UINT8 batch_scan_full_max, UINT8 batch_scan_trunc_max, + UINT8 batch_scan_notify_threshold, + tBTM_BLE_SCAN_SETUP_CBACK *p_setup_cback, + tBTM_BLE_SCAN_THRESHOLD_CBACK *p_thres_cback, + tBTM_BLE_SCAN_REP_CBACK* p_rep_cback, + tBTM_BLE_REF_VALUE ref_value) +{ + 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); + + if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1])) + return BTM_ILLEGAL_VALUE; + + BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb); + + if (0 == cmn_ble_vsc_cb.tot_scan_results_strg) + { + BTM_TRACE_ERROR("Controller does not support batch scan"); + return BTM_ERR_PROCESSING; + } + + ble_batchscan_cb.p_setup_cback = p_setup_cback; + ble_batchscan_cb.p_thres_cback = p_thres_cback; + ble_batchscan_cb.p_scan_rep_cback = p_rep_cback; + ble_batchscan_cb.ref_value = ref_value; + + if (batch_scan_full_max > BTM_BLE_ADV_SCAN_FULL_MAX || + batch_scan_trunc_max > BTM_BLE_ADV_SCAN_TRUNC_MAX || + batch_scan_notify_threshold > BTM_BLE_ADV_SCAN_THR_MAX) + { + BTM_TRACE_ERROR("Illegal set storage config params"); + 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 || + BTM_BLE_SCAN_DISABLE_CALLED == ble_batchscan_cb.cur_state) + { + status = btm_ble_enable_disable_batchscan(TRUE); + if(BTM_CMD_STARTED != status) + return status; + ble_batchscan_cb.cur_state = BTM_BLE_SCAN_ENABLE_CALLED; + btm_ble_batchscan_enq_op_q(BTM_BLE_BATCH_SCAN_ENB_DISAB_CUST_FEATURE, + BTM_BLE_SCAN_ENABLE_CALLED, 0, ref_value); + } + + status = btm_ble_set_storage_config(batch_scan_full_max, batch_scan_trunc_max, + batch_scan_notify_threshold); + if(BTM_CMD_STARTED != status) + return status; + /* The user needs to be provided scan config storage event */ + btm_ble_batchscan_enq_op_q(BTM_BLE_BATCH_SCAN_SET_STORAGE_PARAM, ble_batchscan_cb.cur_state, + BTM_BLE_BATCH_SCAN_CFG_STRG_EVT, ref_value); + + return status; +} + + +/******************************************************************************* +** +** Function BTM_BleEnableBatchScan +** +** Description This function is called to configure and enable batch scanning +** +** Parameters: scan_mode -Batch scan mode +** scan_interval - Scan interval value +** scan_window - Scan window value +** discard_rule - Data discard rule +** ref_value - Reference value +** +** Returns tBTM_STATUS +** +*******************************************************************************/ +tBTM_STATUS BTM_BleEnableBatchScan(tBTM_BLE_BATCH_SCAN_MODE scan_mode, + UINT32 scan_interval, UINT32 scan_window, tBLE_ADDR_TYPE addr_type, + tBTM_BLE_DISCARD_RULE discard_rule, tBTM_BLE_REF_VALUE ref_value) +{ + tBTM_STATUS status = BTM_NO_RESOURCES; + tBTM_BLE_VSC_CB cmn_ble_vsc_cb; + BTM_TRACE_EVENT (" BTM_BleEnableBatchScan"); + + if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1])) + return BTM_ILLEGAL_VALUE; + + BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb); + + if (0 == cmn_ble_vsc_cb.tot_scan_results_strg) + { + BTM_TRACE_ERROR("Controller does not support batch scan"); + return BTM_ERR_PROCESSING; + } + + BTM_TRACE_DEBUG("BTM_BleEnableBatchScan: %d, %x, %x, %d, %d", scan_mode, scan_interval, + scan_window, discard_rule, ble_batchscan_cb.cur_state); + + /* Only 16 bits will be used for scan interval and scan window as per agreement with Google */ + /* So the standard LE range would suffice for scan interval and scan window */ + if ((BTM_BLE_VALID_PRAM(scan_interval, BTM_BLE_SCAN_INT_MIN, BTM_BLE_SCAN_INT_MAX) || + BTM_BLE_VALID_PRAM(scan_window, BTM_BLE_SCAN_WIN_MIN, BTM_BLE_SCAN_WIN_MAX)) + && (BTM_BLE_BATCH_SCAN_MODE_PASS == scan_mode || BTM_BLE_BATCH_SCAN_MODE_ACTI == scan_mode + || BTM_BLE_BATCH_SCAN_MODE_PASS_ACTI == scan_mode) + && (BTM_BLE_DISCARD_OLD_ITEMS == discard_rule || + BTM_BLE_DISCARD_LOWER_RSSI_ITEMS == discard_rule)) + { + 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); + if(BTM_CMD_STARTED != status) + return status; + btm_ble_batchscan_enq_op_q(BTM_BLE_BATCH_SCAN_ENB_DISAB_CUST_FEATURE, + BTM_BLE_SCAN_ENABLE_CALLED, 0, ref_value); + } + + ble_batchscan_cb.scan_mode = scan_mode; + /* This command starts batch scanning, if enabled */ + status = btm_ble_set_batchscan_param(scan_mode, scan_interval, scan_window, addr_type, + discard_rule); + if(BTM_CMD_STARTED != status) + return status; + + /* The user needs to be provided scan enable event */ + btm_ble_batchscan_enq_op_q(BTM_BLE_BATCH_SCAN_SET_PARAMS, ble_batchscan_cb.cur_state, + BTM_BLE_BATCH_SCAN_ENABLE_EVT, ref_value); + } + else + { + BTM_TRACE_ERROR("Illegal enable scan params"); + return BTM_ILLEGAL_VALUE; + } + return status; +} + +/******************************************************************************* +** +** Function BTM_BleDisableBatchScan +** +** Description This function is called to disable batch scanning +** +** Parameters: ref_value - Reference value +** +** Returns tBTM_STATUS +** +*******************************************************************************/ +tBTM_STATUS BTM_BleDisableBatchScan(tBTM_BLE_REF_VALUE ref_value) +{ + tBTM_STATUS status = BTM_NO_RESOURCES; + tBTM_BLE_VSC_CB cmn_ble_vsc_cb; + BTM_TRACE_EVENT (" BTM_BleDisableBatchScan"); + + if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1])) + return BTM_ILLEGAL_VALUE; + + BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb); + + if (0 == cmn_ble_vsc_cb.tot_scan_results_strg) + { + BTM_TRACE_ERROR("Controller does not support batch scan"); + return BTM_ERR_PROCESSING; + } + + status = btm_ble_enable_disable_batchscan(FALSE); + if(BTM_CMD_STARTED == status) + { + /* The user needs to be provided scan disable event */ + btm_ble_batchscan_enq_op_q(BTM_BLE_BATCH_SCAN_ENB_DISAB_CUST_FEATURE, + BTM_BLE_SCAN_DISABLE_CALLED, BTM_BLE_BATCH_SCAN_DISABLE_EVT, + ref_value); + } + + return status; +} + +/******************************************************************************* +** +** Function BTM_BleReadScanReports +** +** Description This function is called to start reading batch scan reports +** +** Parameters: scan_mode - Batch scan mode +** ref_value - Reference value +** +** Returns tBTM_STATUS +** +*******************************************************************************/ +tBTM_STATUS BTM_BleReadScanReports(tBTM_BLE_BATCH_SCAN_MODE scan_mode, + tBTM_BLE_REF_VALUE ref_value) +{ + tBTM_STATUS status = BTM_NO_RESOURCES; + tBTM_BLE_VSC_CB cmn_ble_vsc_cb; + UINT8 read_scan_mode = 0; + + BTM_TRACE_EVENT (" BTM_BleReadScanReports"); + + if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1])) + return BTM_ILLEGAL_VALUE; + + BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb); + + if (0 == cmn_ble_vsc_cb.tot_scan_results_strg) + { + BTM_TRACE_ERROR("Controller does not support batch scan"); + return BTM_ERR_PROCESSING; + } + + /* Check if the requested scan mode has already been setup by the user */ + read_scan_mode = ble_batchscan_cb.scan_mode & BTM_BLE_BATCH_SCAN_MODE_ACTI; + if(0 == read_scan_mode) + read_scan_mode = ble_batchscan_cb.scan_mode & BTM_BLE_BATCH_SCAN_MODE_PASS; + + if(read_scan_mode > 0 && (BTM_BLE_BATCH_SCAN_MODE_PASS == scan_mode || + BTM_BLE_BATCH_SCAN_MODE_ACTI == 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) + { + /* 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); + } + } + else + { + BTM_TRACE_ERROR("Illegal read scan params: %d, %d, %d", read_scan_mode, scan_mode, + ble_batchscan_cb.cur_state); + return BTM_ILLEGAL_VALUE; + } + return status; +} + + +/******************************************************************************* +** +** Function btm_ble_batchscan_init +** +** Description This function initialize the batch scan control block. +** +** Parameters None +** +** Returns status +** +*******************************************************************************/ +void btm_ble_batchscan_init(void) +{ + BTM_TRACE_EVENT (" btm_ble_batchscan_init"); + memset(&ble_batchscan_cb, 0, sizeof(tBTM_BLE_BATCH_SCAN_CB)); + BTM_RegisterForVSEvents(btm_ble_batchscan_filter_track_adv_vse_cback, TRUE); +} + +#endif diff --git a/system/stack/btm/btm_ble_gap.c b/system/stack/btm/btm_ble_gap.c index 477bd33cdd84008c5b5c297d098a80203c33a677..2b64705fcb1136b70bc6778c226d16e6ea1f0172 100644 --- a/system/stack/btm/btm_ble_gap.c +++ b/system/stack/btm/btm_ble_gap.c @@ -52,10 +52,9 @@ #define BTM_EXT_BLE_RMT_NAME_TIMEOUT 30 #define MIN_ADV_LENGTH 2 -extern tBTM_BLE_MULTI_ADV_CB btm_multi_adv_cb; +static tBTM_BLE_VSC_CB cmn_ble_vsc_cb; static tBTM_BLE_CTRL_FEATURES_CBACK *p_ctrl_le_feature_rd_cmpl_cback = NULL; - /******************************************************************************* ** Local functions *******************************************************************************/ @@ -434,6 +433,7 @@ tBTM_STATUS BTM_BleBroadcast(BOOLEAN start) *******************************************************************************/ static void btm_ble_vendor_capability_vsc_cmpl_cback (tBTM_VSC_CMPL *p_vcs_cplt_params) { +#if BLE_VND_INCLUDED == TRUE UINT8 status = 0xFF, *p; UINT8 rpa_offloading, max_irk_list_sz, filtering_support, max_filter; UINT16 scan_result_storage; @@ -459,13 +459,17 @@ static void btm_ble_vendor_capability_vsc_cmpl_cback (tBTM_VSC_CMPL *p_vcs_cplt_ STREAM_TO_UINT8 (btm_cb.cmn_ble_vsc_cb.filter_support, p); STREAM_TO_UINT8 (btm_cb.cmn_ble_vsc_cb.max_filter, p); } + p_vcb->irk_avail_size = max_irk_list_sz; if (p_ctrl_le_feature_rd_cmpl_cback != NULL) p_ctrl_le_feature_rd_cmpl_cback(status); - btm_multi_adv_cb.adv_inst_max = btm_cb.cmn_ble_vsc_cb.adv_inst_max; - BTM_TRACE_DEBUG("btm_ble_vendor_capability_vsc_cmpl_cback:%d, status=%d, max_irk_size=%d", - btm_multi_adv_cb.adv_inst_max, status,btm_ble_vendor_cb.irk_avail_size); + + BTM_TRACE_DEBUG("btm_ble_vendor_capability_vsc_cmpl_cback: status=%d, max_irk_size=%d", + status, btm_ble_vendor_cb.irk_avail_size); +#else + UNUSED(p_vcs_cplt_params); +#endif } /******************************************************************************* @@ -502,6 +506,7 @@ BTM_API extern void BTM_BleGetVendorCapabilities(tBTM_BLE_VSC_CB *p_cmn_vsc_cb) *******************************************************************************/ BTM_API extern void BTM_BleReadControllerFeatures(tBTM_BLE_CTRL_FEATURES_CBACK *p_vsc_cback) { +#if BLE_VND_INCLUDED == TRUE BTM_TRACE_DEBUG("BTM_BleReadControllerFeatures"); memset(&btm_ble_vendor_cb, 0, sizeof(tBTM_BLE_VENDOR_CB)); @@ -515,6 +520,9 @@ BTM_API extern void BTM_BleReadControllerFeatures(tBTM_BLE_CTRL_FEATURES_CBACK { BTM_TRACE_ERROR("LE Get_Vendor Capabilities Command Failed."); } +#else + UNUSED(p_vsc_cback); +#endif return ; } @@ -2844,7 +2852,7 @@ void btm_ble_update_mode_operation(UINT8 link_role, BD_ADDR bd_addr, BOOLEAN con } } - if (btm_multi_adv_cb.adv_inst_max == 0 && + if (btm_cb.cmn_ble_vsc_cb.adv_inst_max == 0 && btm_cb.ble_ctr_cb.inq_var.connectable_mode == BTM_BLE_CONNECTABLE) { btm_ble_set_connectability ( btm_cb.ble_ctr_cb.inq_var.connectable_mode ); @@ -3040,6 +3048,7 @@ void btm_ble_init (void) BTM_TRACE_EVENT ("btm_ble_init "); memset(p_cb, 0, sizeof(tBTM_BLE_CB)); + memset(&btm_cb.cmn_ble_vsc_cb, 0 , sizeof(tBTM_BLE_VSC_CB)); p_cb->cur_states = 0; p_cb->inq_var.adv_mode = BTM_BLE_ADV_DISABLE; @@ -3057,6 +3066,11 @@ void btm_ble_init (void) #if BLE_MULTI_ADV_INCLUDED == TRUE btm_ble_multi_adv_init(); #endif + +#if BLE_BATCH_SCAN_INCLUDED == TRUE + btm_ble_batchscan_init(); +#endif + } /******************************************************************************* diff --git a/system/stack/btm/btm_ble_int.h b/system/stack/btm/btm_ble_int.h index 52be674c614ddaf38c0d2c8644f1b5e1f97ef520..76dc9e38b3d36398271a2ea5c1f05ac06809abf2 100644 --- a/system/stack/btm/btm_ble_int.h +++ b/system/stack/btm/btm_ble_int.h @@ -338,7 +338,6 @@ extern tBTM_STATUS btm_ble_stop_adv(void); extern tBTM_STATUS btm_ble_start_scan (UINT8 filter_enb); - /* LE security function from btm_sec.c */ #if SMP_INCLUDED == TRUE extern void btm_ble_link_sec_check(BD_ADDR bd_addr, tBTM_LE_AUTH_REQ auth_req, tBTM_BLE_SEC_REQ_ACT *p_sec_req_act); @@ -396,6 +395,7 @@ extern void btm_gen_resolve_paddr_low(tBTM_RAND_ENC *p); extern void btm_ble_multi_adv_configure_rpa (tBTM_BLE_MULTI_ADV_INST *p_inst); extern void btm_ble_multi_adv_init(void); +extern void btm_ble_batchscan_init(void); extern void btm_ble_multi_adv_reenable(UINT8 inst_id); extern void btm_ble_multi_adv_enb_privacy(BOOLEAN enable); extern BOOLEAN btm_ble_topology_check(tBTM_BLE_STATE_MASK request); diff --git a/system/stack/btm/btm_ble_multi_adv.c b/system/stack/btm/btm_ble_multi_adv.c index 9cdf741cb952567d4d7f002b6d075f6ecb68dbe0..572e7c132b6ddfa20cb2248ba2cf01f5ba08c0d4 100644 --- a/system/stack/btm/btm_ble_multi_adv.c +++ b/system/stack/btm/btm_ble_multi_adv.c @@ -546,10 +546,14 @@ tBTM_STATUS BTM_BleEnableAdvInstance (tBTM_BLE_ADV_PARAMS *p_params, UINT8 i; tBTM_STATUS rt = BTM_NO_RESOURCES; tBTM_BLE_MULTI_ADV_INST *p_inst = &btm_multi_adv_cb.adv_inst[0]; + tBTM_BLE_VSC_CB cmn_ble_vsc_cb; + BTM_TRACE_EVENT("BTM_BleEnableAdvInstance called"); - if (btm_multi_adv_cb.adv_inst_max == 0) + BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb); + + if (0 == cmn_ble_vsc_cb.adv_inst_max) { BTM_TRACE_ERROR("Controller does not support Multi ADV"); return BTM_ERR_PROCESSING; @@ -602,10 +606,13 @@ tBTM_STATUS BTM_BleUpdateAdvInstParam (UINT8 inst_id, tBTM_BLE_ADV_PARAMS *p_par { tBTM_STATUS rt = BTM_ILLEGAL_VALUE; tBTM_BLE_MULTI_ADV_INST *p_inst = &btm_multi_adv_cb.adv_inst[inst_id - 1]; + tBTM_BLE_VSC_CB cmn_ble_vsc_cb; BTM_TRACE_EVENT("BTM_BleUpdateAdvInstParam called with inst_id:%d", inst_id); - if (btm_multi_adv_cb.adv_inst_max == 0) + BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb); + + if (0 == cmn_ble_vsc_cb.adv_inst_max) { BTM_TRACE_ERROR("Controller does not support Multi ADV"); return BTM_ERR_PROCESSING; @@ -655,8 +662,10 @@ tBTM_STATUS BTM_BleCfgAdvInstData (UINT8 inst_id, BOOLEAN is_scan_rsp, UINT8 *p_len; tBTM_STATUS rt; UINT8 *pp_temp = (UINT8*)(param + BTM_BLE_MULTI_ADV_WRITE_DATA_LEN -1); + tBTM_BLE_VSC_CB cmn_ble_vsc_cb; - if (btm_multi_adv_cb.adv_inst_max == 0) + BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb); + if (0 == cmn_ble_vsc_cb.adv_inst_max) { BTM_TRACE_ERROR("Controller does not support Multi ADV"); return BTM_ERR_PROCESSING; @@ -699,10 +708,13 @@ tBTM_STATUS BTM_BleCfgAdvInstData (UINT8 inst_id, BOOLEAN is_scan_rsp, tBTM_STATUS BTM_BleDisableAdvInstance (UINT8 inst_id) { tBTM_STATUS rt = BTM_ILLEGAL_VALUE; + tBTM_BLE_VSC_CB cmn_ble_vsc_cb; BTM_TRACE_EVENT("BTM_BleDisableAdvInstance with inst_id:%d", inst_id); - if (btm_multi_adv_cb.adv_inst_max == 0) + BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb); + + if (0 == cmn_ble_vsc_cb.adv_inst_max) { BTM_TRACE_ERROR("Controller does not support Multi ADV"); return BTM_ERR_PROCESSING; diff --git a/system/stack/btm/btm_devctl.c b/system/stack/btm/btm_devctl.c index c837c1656151779104ea7ecb1c30be8264ae7175..980cac1a871bc477b3d072d8a291101d571f5c4c 100644 --- a/system/stack/btm/btm_devctl.c +++ b/system/stack/btm/btm_devctl.c @@ -671,7 +671,9 @@ void btm_reset_complete (void) btm_cb.ble_ctr_cb.p_select_cback = NULL; memset(&btm_cb.ble_ctr_cb.bg_dev_list, 0, (sizeof(tBTM_LE_BG_CONN_DEV)*BTM_BLE_MAX_BG_CONN_DEV_NUM)); gatt_reset_bgdev_list(); +#if BLE_MULTI_ADV_INCLUDED == TRUE btm_ble_multi_adv_init(); +#endif #endif } } diff --git a/system/stack/include/btm_ble_api.h b/system/stack/include/btm_ble_api.h index 8bdc6d1d3da9594ed1cdda22f2fd830416766151..ddf831b2fd91c8ad8f296ae431c0468348d03c86 100644 --- a/system/stack/include/btm_ble_api.h +++ b/system/stack/include/btm_ble_api.h @@ -46,11 +46,19 @@ typedef UINT8 tBTM_BLE_CHNL_MAP[CHNL_MAP_LEN]; #define BTM_BLE_UNKNOWN_EVT 0xff +typedef UINT8 tBTM_BLE_REF_VALUE; + #define BTM_BLE_SCAN_MODE_PASS 0 #define BTM_BLE_SCAN_MODE_ACTI 1 #define BTM_BLE_SCAN_MODE_NONE 0xff typedef UINT8 tBTM_BLE_SCAN_MODE; +#define BTM_BLE_BATCH_SCAN_MODE_PASS 1 +#define BTM_BLE_BATCH_SCAN_MODE_ACTI 2 +#define BTM_BLE_BATCH_SCAN_MODE_PASS_ACTI 3 + +typedef UINT8 tBTM_BLE_BATCH_SCAN_MODE; + /* advertising channel map */ #define BTM_BLE_ADV_CHNL_37 (0x01 << 0) #define BTM_BLE_ADV_CHNL_38 (0x01 << 1) @@ -88,6 +96,18 @@ typedef UINT8 tBTM_BLE_SFP; #define BTM_BLE_ADV_INT_MIN 0x0020 #define BTM_BLE_ADV_INT_MAX 0x4000 +/* Full scan boundary values */ +#define BTM_BLE_ADV_SCAN_FULL_MIN 0x00 +#define BTM_BLE_ADV_SCAN_FULL_MAX 0x64 + +/* Partial scan boundary values */ +#define BTM_BLE_ADV_SCAN_TRUNC_MIN BTM_BLE_ADV_SCAN_FULL_MIN +#define BTM_BLE_ADV_SCAN_TRUNC_MAX BTM_BLE_ADV_SCAN_FULL_MAX + +/* Threshold values */ +#define BTM_BLE_ADV_SCAN_THR_MIN BTM_BLE_ADV_SCAN_FULL_MIN +#define BTM_BLE_ADV_SCAN_THR_MAX BTM_BLE_ADV_SCAN_FULL_MAX + /* connection parameter boundary values */ #define BTM_BLE_SCAN_INT_MIN 0x0004 #define BTM_BLE_SCAN_INT_MAX 0x4000 @@ -439,9 +459,46 @@ typedef struct { tBTM_BLE_MULTI_ADV_INST adv_inst[BTM_BLE_MULTI_ADV_MAX]; tBTM_BLE_MULTI_ADV_OPQ op_q; - UINT8 adv_inst_max; /* max adv instance supported in controller */ }tBTM_BLE_MULTI_ADV_CB; +typedef void (tBTM_BLE_SCAN_THRESHOLD_CBACK)(tBTM_BLE_REF_VALUE ref_value); +typedef void (tBTM_BLE_SCAN_REP_CBACK)(tBTM_BLE_REF_VALUE ref_value, UINT8 report_format, + UINT8 num_records, UINT16 total_len, + UINT8* p_rep_data, UINT8 status); +typedef void (tBTM_BLE_SCAN_SETUP_CBACK)(UINT8 evt, tBTM_BLE_REF_VALUE ref_value, UINT8 status); + +#ifndef BTM_BLE_BATCH_SCAN_MAX +#define BTM_BLE_BATCH_SCAN_MAX 5 +#endif + +typedef enum +{ + BTM_BLE_SCAN_INVALID_STATE=0, + BTM_BLE_SCAN_ENABLE_CALLED=1, + BTM_BLE_SCAN_ENABLED_STATE=2, + BTM_BLE_SCAN_DISABLE_CALLED=3, + BTM_BLE_SCAN_DISABLED_STATE=4 +}tBTM_BLE_BATCH_SCAN_STATE; + +typedef struct +{ + UINT8 sub_code[BTM_BLE_BATCH_SCAN_MAX]; + tBTM_BLE_BATCH_SCAN_STATE cur_state[BTM_BLE_BATCH_SCAN_MAX]; + tBTM_BLE_REF_VALUE ref_value[BTM_BLE_BATCH_SCAN_MAX]; + UINT8 pending_idx; + UINT8 next_idx; +}tBTM_BLE_BATCH_SCAN_OPQ; + +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_SCAN_SETUP_CBACK *p_setup_cback; + tBTM_BLE_SCAN_THRESHOLD_CBACK *p_thres_cback; + tBTM_BLE_SCAN_REP_CBACK *p_scan_rep_cback; + tBTM_BLE_REF_VALUE ref_value; +}tBTM_BLE_BATCH_SCAN_CB; /* These are the fields returned in each device adv packet. It ** is returned in the results callback if registered. @@ -465,6 +522,33 @@ enum }; typedef UINT8 tBTM_BLE_CONN_TYPE; +enum +{ + BTM_BLE_DISCARD_OLD_ITEMS, + BTM_BLE_DISCARD_LOWER_RSSI_ITEMS +}; +typedef UINT8 tBTM_BLE_DISCARD_RULE; + +enum +{ + BTM_BLE_TRACK_ADV_ADD, + BTM_BLE_TRACK_ADV_REMOVE +}; + +typedef UINT8 tBTM_BLE_TRACK_ADV_ACTION; + +#define BTM_BLE_MULTI_ADV_INVALID 0 + +#define BTM_BLE_BATCH_SCAN_ENABLE_EVT 1 +#define BTM_BLE_BATCH_SCAN_CFG_STRG_EVT 2 +#define BTM_BLE_BATCH_SCAN_READ_REPTS_EVT 3 +#define BTM_BLE_BATCH_SCAN_THR_EVT 4 +#define BTM_BLE_BATCH_SCAN_PARAM_EVT 5 +#define BTM_BLE_BATCH_SCAN_DISABLE_EVT 6 + +typedef UINT8 tBTM_BLE_BATCH_SCAN_EVT; + + typedef BOOLEAN (tBTM_BLE_SEL_CBACK)(BD_ADDR random_bda, UINT8 *p_remote_name); typedef void (tBTM_BLE_CTRL_FEATURES_CBACK)(tBTM_STATUS status); @@ -476,6 +560,8 @@ typedef void (tBTM_BLE_RANDOM_SET_CBACK) (BD_ADDR random_bda); typedef void (tBTM_BLE_SCAN_REQ_CBACK)(BD_ADDR remote_bda, tBLE_ADDR_TYPE addr_type, UINT8 adv_evt); +tBTM_BLE_SCAN_SETUP_CBACK bta_ble_scan_setup_cb; + /***************************************************************************** ** EXTERNAL FUNCTION DECLARATIONS *****************************************************************************/ @@ -564,6 +650,18 @@ BTM_API extern tBTM_STATUS BTM_BleWriteAdvData(tBTM_BLE_AD_MASK data_mask, BTM_API extern void BTM_BleReadAdvParams (UINT16 *adv_int_min, UINT16 *adv_int_max, tBLE_BD_ADDR *p_dir_bda, tBTM_BLE_ADV_CHNL_MAP *p_chnl_map); +/******************************************************************************* +** +** Function BTM_BleObtainVendorCapabilities +** +** Description This function is called to obatin vendor capabilties +** +** Parameters p_cmn_vsc_cb - Returns the vednor capabilities +** +** Returns void +** +*******************************************************************************/ +extern void BTM_BleObtainVendorCapabilities(tBTM_BLE_VSC_CB *p_cmn_vsc_cb); /******************************************************************************* ** @@ -592,6 +690,96 @@ BTM_API extern void BTM_BleSetScanParams(UINT16 scan_interval, UINT16 scan_windo ** *******************************************************************************/ BTM_API extern void BTM_BleGetVendorCapabilities(tBTM_BLE_VSC_CB *p_cmn_vsc_cb); +/******************************************************************************* +** +** Function BTM_BleSetStorageConfig +** +** Description This function is called to setup storage configuration and setup callbacks. +** +** Parameters UINT8 batch_scan_full_max -Batch scan full maximum + UINT8 batch_scan_trunc_max - Batch scan truncated value maximum + UINT8 batch_scan_notify_threshold - Threshold value + tBTM_BLE_SCAN_SETUP_CBACK *p_setup_cback - Setup callback + tBTM_BLE_SCAN_THRESHOLD_CBACK *p_thres_cback -Threshold callback + void *p_ref - Reference value +** +** Returns tBTM_STATUS +** +*******************************************************************************/ +BTM_API extern tBTM_STATUS BTM_BleSetStorageConfig(UINT8 batch_scan_full_max, + UINT8 batch_scan_trunc_max, + UINT8 batch_scan_notify_threshold, + tBTM_BLE_SCAN_SETUP_CBACK *p_setup_cback, + tBTM_BLE_SCAN_THRESHOLD_CBACK *p_thres_cback, + tBTM_BLE_SCAN_REP_CBACK* p_cback, + tBTM_BLE_REF_VALUE ref_value); + +/******************************************************************************* +** +** Function BTM_BleEnableBatchScan +** +** Description This function is called to enable batch scan +** +** Parameters tBTM_BLE_BATCH_SCAN_MODE scan_mode - Batch scan mode + UINT32 scan_interval -Scan interval + UINT32 scan_window - Scan window value + tBLE_ADDR_TYPE addr_type - Address type + tBTM_BLE_DISCARD_RULE discard_rule - Data discard rules +** +** Returns tBTM_STATUS +** +*******************************************************************************/ +BTM_API extern tBTM_STATUS BTM_BleEnableBatchScan(tBTM_BLE_BATCH_SCAN_MODE scan_mode, + UINT32 scan_interval, UINT32 scan_window, + tBTM_BLE_DISCARD_RULE discard_rule, + tBLE_ADDR_TYPE addr_type, + tBTM_BLE_REF_VALUE ref_value); + +/******************************************************************************* +** +** Function BTM_BleDisableBatchScan +** +** Description This function is called to disable batch scanning +** +** Parameters void +** +** Returns void +** +*******************************************************************************/ +BTM_API extern tBTM_STATUS BTM_BleDisableBatchScan(tBTM_BLE_REF_VALUE ref_value); + +/******************************************************************************* +** +** Function BTM_BleReadScanReports +** +** Description This function is called to read batch scan reports +** +** Parameters tBTM_BLE_SCAN_MODE scan_mode - Scan mode report to be read out + tBTM_BLE_SCAN_REP_CBACK* p_cback - Reports callback +** +** Returns tBTM_STATUS +** +*******************************************************************************/ +BTM_API extern tBTM_STATUS BTM_BleReadScanReports(tBTM_BLE_SCAN_MODE scan_mode, + tBTM_BLE_REF_VALUE ref_value); + +/******************************************************************************* +** +** Function BTM_BleTrackAdvertiser +** +** Description This function is called to read batch scan reports +** +** Parameters track_adv_action - Track advertiser action + addr_type - address type + p_bda - BD address + onlost_timeout - Timeout for onlost event +** +** Returns tBTM_STATUS +** +*******************************************************************************/ +BTM_API extern tBTM_STATUS BTM_BleTrackAdvertiser(tBTM_BLE_TRACK_ADV_ACTION track_adv_action, + tBLE_BD_ADDR *p_bda, UINT8 onlost_timeout); + /******************************************************************************* ** ** Function BTM_BleWriteScanRsp diff --git a/system/stack/include/hcidefs.h b/system/stack/include/hcidefs.h index 4c0b604f0dd39525035d98d3c610f012a37cdb17..07aacad0e38dece227ba950bdefe87fcd2499e24 100644 --- a/system/stack/include/hcidefs.h +++ b/system/stack/include/hcidefs.h @@ -340,6 +340,12 @@ /* Multi adv OCF */ #define HCI_BLE_MULTI_ADV_OCF (0x0154 | HCI_GRP_VENDOR_SPECIFIC) +/* Batch scan OCF */ +#define HCI_BLE_BATCH_SCAN_OCF (0x0156 | HCI_GRP_VENDOR_SPECIFIC) + +/* Tracking OCF */ +#define HCI_BLE_TRACK_ADV_OCF (0x0158 | HCI_GRP_VENDOR_SPECIFIC) + /* subcode for multi adv feature */ #define BTM_BLE_MULTI_ADV_SET_PARAM 0x01 #define BTM_BLE_MULTI_ADV_WRITE_ADV_DATA 0x02 @@ -350,6 +356,18 @@ /* multi adv VSE subcode */ #define HCI_VSE_SUBCODE_BLE_MULTI_ADV_ST_CHG 0x55 /* multi adv instance state change */ +/* subcode for batch scan feature */ +#define BTM_BLE_BATCH_SCAN_ENB_DISAB_CUST_FEATURE 0x01 +#define BTM_BLE_BATCH_SCAN_SET_STORAGE_PARAM 0x02 +#define BTM_BLE_BATCH_SCAN_SET_PARAMS 0x03 +#define BTM_BLE_BATCH_SCAN_READ_RESULTS 0x04 + +/* batch scan VSE subcode */ +#define HCI_VSE_SUBCODE_BLE_THRESHOLD_SUB_EVT 0x54 /* Threshold event */ + +/* tracking sub event */ +#define HCI_VSE_SUBCODE_BLE_TRACKING_SUB_EVT 0x56 /* Tracking event */ + /* LE supported states definition */ #define HCI_LE_ADV_STATE 0x00000001 #define HCI_LE_SCAN_STATE 0x00000002