}
}
}
+
+/*******************************************************************************
+**
+** Function bta_dm_ble_scan
+**
+** Description This function set the preferred connection scan parameters.
+**
+** Parameters:
+**
+*******************************************************************************/
+void bta_dm_ble_scan (tBTA_DM_MSG *p_data)
+{
+ tBTM_STATUS status;
+ if (p_data->ble_scan.start) {
+ /*Save the callback to be called when a scan results are available */
+ bta_dm_search_cb.p_scan_cback = p_data->ble_scan.p_cback;
+
+ if ((status = BTM_BleScan(TRUE, p_data->ble_scan.duration,
+ bta_dm_observe_results_cb, bta_dm_observe_cmpl_cb)) != BTM_CMD_STARTED) {
+ APPL_TRACE_WARNING(" %s start scan failed. status=0x%x\n", __FUNCTION__, status);
+ }
+
+ if (p_data->ble_scan.p_start_scan_cback) {
+ status = (status == BTM_CMD_STARTED ? BTA_SUCCESS : BTA_FAILURE);
+ p_data->ble_scan.p_start_scan_cback(status);
+ }
+ } else {
+ bta_dm_search_cb.p_scan_cback = NULL;
+ status = BTM_BleScan(FALSE, 0, NULL, NULL);
+
+ if (status != BTM_CMD_STARTED){
+ APPL_TRACE_WARNING(" %s stop scan failed, status=0x%x\n", __FUNCTION__, status);
+ }
+
+ if (p_data->ble_scan.p_stop_scan_cback) {
+ status = (status == BTM_CMD_STARTED ? BTA_SUCCESS : BTA_FAILURE);
+ p_data->ble_scan.p_stop_scan_cback(status);
+ }
+ }
+}
+
/*******************************************************************************
**
** Function bta_dm_ble_set_adv_params
}
}
+/*******************************************************************************
+**
+** Function BTA_DmBleScan
+**
+** Description This procedure keep the device listening for advertising
+** events from a broadcast device.
+**
+** Parameters start: start or stop scan.
+**
+** Returns void
+
+**
+** Returns void.
+**
+*******************************************************************************/
+extern void BTA_DmBleScan(BOOLEAN start, UINT32 duration,
+ tBTA_DM_SEARCH_CBACK *p_results_cb,
+ tBTA_START_STOP_SCAN_CMPL_CBACK *p_start_stop_scan_cb)
+{
+ tBTA_DM_API_BLE_SCAN *p_msg;
+
+ APPL_TRACE_API("BTA_DmBleScan:start = %d ", start);
+
+ if ((p_msg = (tBTA_DM_API_BLE_SCAN *) osi_malloc(sizeof(tBTA_DM_API_BLE_SCAN))) != NULL) {
+ memset(p_msg, 0, sizeof(tBTA_DM_API_BLE_SCAN));
+
+ p_msg->hdr.event = BTA_DM_API_BLE_SCAN_EVT;
+ p_msg->start = start;
+ p_msg->duration = duration;
+ p_msg->p_cback = p_results_cb;
+ if (start){
+ p_msg->p_start_scan_cback = p_start_stop_scan_cb;
+ }
+ else {
+ p_msg->p_stop_scan_cback = p_start_stop_scan_cb;
+ }
+
+ bta_sys_sendmsg(p_msg);
+ }
+}
+
/*******************************************************************************
**
** Function BTA_DmBleStopAdvertising
support the scan filter setting for the APP******/
BTA_DM_API_BLE_SCAN_FIL_PARAM_EVT,
BTA_DM_API_BLE_OBSERVE_EVT,
+ BTA_DM_API_BLE_SCAN_EVT,
BTA_DM_API_UPDATE_CONN_PARAM_EVT,
/*******This event added by Yulong at 2016/9/9 to
support the random address setting for the APP******/
tBTA_START_STOP_ADV_CMPL_CBACK *p_stop_adv_cback;
} tBTA_DM_API_BLE_OBSERVE;
+/* Data type for start/stop scan */
+typedef struct {
+ BT_HDR hdr;
+ BOOLEAN start;
+ UINT32 duration;
+ tBTA_DM_SEARCH_CBACK *p_cback;
+ tBTA_START_STOP_SCAN_CMPL_CBACK *p_start_scan_cback;
+ tBTA_START_STOP_SCAN_CMPL_CBACK *p_stop_scan_cback;
+ tBTA_START_STOP_ADV_CMPL_CBACK *p_stop_adv_cback;
+} tBTA_DM_API_BLE_SCAN;
+
typedef struct {
BT_HDR hdr;
BD_ADDR remote_bda;
tBTA_DM_API_BLE_SCAN_PARAMS ble_set_scan_params;
tBTA_DM_API_BLE_SCAN_FILTER_PARAMS ble_set_scan_fil_params;
tBTA_DM_API_BLE_OBSERVE ble_observe;
+ tBTA_DM_API_BLE_SCAN ble_scan;
tBTA_DM_API_ENABLE_PRIVACY ble_remote_privacy;
tBTA_DM_API_LOCAL_PRIVACY ble_local_privacy;
tBTA_DM_API_BLE_ADV_PARAMS ble_set_adv_params;
extern void bta_dm_close_gatt_conn(tBTA_DM_MSG *p_data);
#endif /* ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) && SDP_INCLUDED == TRUE) && (GATTC_INCLUDED == TRUE) */
extern void bta_dm_ble_observe (tBTA_DM_MSG *p_data);
+extern void bta_dm_ble_scan (tBTA_DM_MSG *p_data);
extern void bta_dm_ble_update_conn_params (tBTA_DM_MSG *p_data);
extern void bta_dm_ble_disconnect (tBTA_DM_MSG *p_data);
extern void bta_dm_ble_set_rand_address(tBTA_DM_MSG *p_data);
bta_dm_ble_set_scan_params, /* BTA_DM_API_BLE_SCAN_PARAM_EVT */
bta_dm_ble_set_scan_fil_params, /* BTA_DM_API_BLE_SCAN_FIL_PARAM_EVT */
bta_dm_ble_observe, /* BTA_DM_API_BLE_OBSERVE_EVT*/
+ bta_dm_ble_scan, /* BTA_DM_API_BLE_SCAN_EVT */
bta_dm_ble_update_conn_params, /* BTA_DM_API_UPDATE_CONN_PARAM_EVT */
/* This handler function added by
Yulong at 2016/9/9 to support the
tBTA_DM_SEARCH_CBACK *p_results_cb,
tBTA_START_STOP_SCAN_CMPL_CBACK *p_start_stop_scan_cb);
+/*******************************************************************************
+**
+** Function BTA_DmBleScan
+**
+** Description This procedure keep the device listening for advertising
+** events from a broadcast device.
+**
+** Parameters start: start or stop observe.
+** duration : Duration of the scan. Continuous scan if 0 is passed
+** p_results_cb: Callback to be called with scan results
+**
+** Returns void
+**
+*******************************************************************************/
+extern void BTA_DmBleScan(BOOLEAN start, UINT32 duration,
+ tBTA_DM_SEARCH_CBACK *p_results_cb,
+ tBTA_START_STOP_SCAN_CMPL_CBACK *p_start_stop_scan_cb);
+
extern void BTA_DmBleStopAdvertising(void);
extern void BTA_DmSetRandAddress(BD_ADDR rand_addr);
scan_params->scan_interval,
scan_params->scan_window,
scan_params->scan_type,
- scan_params->own_addr_type,
scan_params->scan_filter_policy,
+ scan_params->own_addr_type,
scan_param_setup_cback);
} else {
btc_scan_params_callback(ESP_DEFAULT_GATT_IF, BTM_ILLEGAL_VALUE);
tBTA_START_STOP_SCAN_CMPL_CBACK *start_scan_cb)
{
if ((results_cb != NULL) && (start_scan_cb != NULL)) {
- ///Start scan the device
- BTA_DmBleObserve(true, duration, results_cb, start_scan_cb);
+ //Start scan the device
+ BTA_DmBleScan(true, duration, results_cb, start_scan_cb);
} else {
- LOG_ERROR("The scan duration or p_results_cb invalid\n");
+ LOG_ERROR("The start_scan_cb or results_cb invalid\n");
}
}
static void btc_ble_stop_scanning(tBTA_START_STOP_SCAN_CMPL_CBACK *stop_scan_cb)
{
uint8_t duration = 0;
- BTA_DmBleObserve(false, duration, NULL, stop_scan_cb);
+ BTA_DmBleScan(false, duration, NULL, stop_scan_cb);
}
tBLE_ADDR_TYPE *p_peer_addr_type,
tBLE_ADDR_TYPE *p_own_addr_type);
static void btm_ble_stop_observe(void);
+static void btm_ble_stop_discover(void);
#define BTM_BLE_INQ_RESULT 0x01
#define BTM_BLE_OBS_RESULT 0x02
#define BTM_BLE_SEL_CONN_RESULT 0x04
+#define BTM_BLE_DISCO_RESULT 0x08
/* LE states combo bit to check */
const UINT8 btm_le_state_combo_tbl[BTM_BLE_STATE_MAX][BTM_BLE_STATE_MAX][2] = {
}
+/*******************************************************************************
+**
+** Function BTM_BleScan
+**
+** Description This procedure keep the device listening for advertising
+** events from a broadcast device.
+**
+** Parameters start: start or stop scan.
+** white_list: use white list in observer mode or not.
+**
+** Returns void
+**
+*******************************************************************************/
+tBTM_STATUS BTM_BleScan(BOOLEAN start, UINT32 duration,
+ tBTM_INQ_RESULTS_CB *p_results_cb, tBTM_CMPL_CB *p_cmpl_cb)
+{
+ tBTM_BLE_INQ_CB *p_inq = &btm_cb.ble_ctr_cb.inq_var;
+ tBTM_STATUS status = BTM_WRONG_MODE;
+
+ if (!controller_get_interface()->supports_ble()) {
+ return BTM_ILLEGAL_VALUE;
+ }
+
+ if (start) {
+ /* shared inquiry database, do not allow scan if any inquiry is active */
+ if (BTM_BLE_IS_DISCO_ACTIVE(btm_cb.ble_ctr_cb.scan_activity)) {
+ BTM_TRACE_ERROR("%s scan already active", __func__);
+ return status;
+ }
+
+ btm_cb.ble_ctr_cb.p_scan_results_cb = p_results_cb;
+ btm_cb.ble_ctr_cb.p_scan_cmpl_cb = p_cmpl_cb;
+ status = BTM_CMD_STARTED;
+
+ /* scan is not started */
+ if (!BTM_BLE_IS_SCAN_ACTIVE(btm_cb.ble_ctr_cb.scan_activity)) {
+ /* assume observe always not using white list */
+#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE)
+ /* enable resolving list */
+ btm_ble_enable_resolving_list_for_platform(BTM_BLE_RL_SCAN);
+#endif
+ // if not set scan params, set defalult scan params
+ if (!p_inq->scan_params_set)
+ {
+ /* allow config of scan type */
+ p_inq->scan_type = BTM_BLE_SCAN_MODE_ACTI;
+ p_inq->scan_interval = BTM_BLE_GAP_DISC_SCAN_INT;
+ p_inq->scan_window = BTM_BLE_GAP_DISC_SCAN_WIN;
+ p_inq->sfp = BTM_BLE_DEFAULT_SFP;
+ p_inq->scan_params_set = TRUE;
+ btsnd_hcic_ble_set_scan_params(p_inq->scan_type, p_inq->scan_interval,
+ p_inq->scan_window,
+ btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type,
+ p_inq->sfp);
+ }
+ p_inq->scan_duplicate_filter = BTM_BLE_DUPLICATE_DISABLE;
+ status = btm_ble_start_scan();
+ }
+
+ if (status == BTM_CMD_STARTED) {
+ btm_cb.ble_ctr_cb.scan_activity |= BTM_LE_DISCOVER_ACTIVE;
+ if (duration != 0)
+ /* start observer timer */
+ {
+ btu_start_timer (&btm_cb.ble_ctr_cb.scan_timer_ent, BTU_TTYPE_BLE_SCAN, duration);
+ }
+ }
+ } else if (BTM_BLE_IS_DISCO_ACTIVE(btm_cb.ble_ctr_cb.scan_activity)) {
+ status = BTM_CMD_STARTED;
+ btm_ble_stop_discover();
+ } else {
+ BTM_TRACE_ERROR("%s scan not active\n", __func__);
+ }
+
+ return status;
+
+}
+
/*******************************************************************************
**
** Function BTM_BleBroadcast
p_cb->scan_interval = scan_interval;
p_cb->scan_window = scan_window;
p_cb->sfp = scan_filter_policy;
+ p_cb->scan_params_set = TRUE;
btsnd_hcic_ble_set_scan_params(p_cb->scan_type, (UINT16)scan_interval,
(UINT16)scan_window,
if (BTM_BLE_IS_OBS_ACTIVE(btm_cb.ble_ctr_cb.scan_activity)) {
rt |= BTM_BLE_OBS_RESULT;
}
+ /* for discover, always "discoverable */
+ if (BTM_BLE_IS_DISCO_ACTIVE(btm_cb.ble_ctr_cb.scan_activity)) {
+ rt |= BTM_BLE_DISCO_RESULT;
+ }
if (BTM_BLE_IS_SEL_CONN_ACTIVE(btm_cb.ble_ctr_cb.scan_activity) &&
(evt_type == BTM_BLE_CONNECT_EVT || evt_type == BTM_BLE_CONNECT_DIR_EVT)) {
*******************************************************************************/
static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt_type, UINT8 *p)
{
+
tINQ_DB_ENT *p_i;
tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
tBTM_INQ_RESULTS_CB *p_inq_results_cb = p_inq->p_inq_results_cb;
tBTM_INQ_RESULTS_CB *p_obs_results_cb = btm_cb.ble_ctr_cb.p_obs_results_cb;
+ tBTM_INQ_RESULTS_CB *p_scan_results_cb = btm_cb.ble_ctr_cb.p_scan_results_cb;
tBTM_BLE_INQ_CB *p_le_inq_cb = &btm_cb.ble_ctr_cb.inq_var;
BOOLEAN update = TRUE;
UINT8 result = 0;
/* scan repsonse to be updated */
(!p_i->scan_rsp))) {
update = TRUE;
- } else if (BTM_BLE_IS_OBS_ACTIVE(btm_cb.ble_ctr_cb.scan_activity)) {
+ } else if (BTM_BLE_IS_DISCO_ACTIVE(btm_cb.ble_ctr_cb.scan_activity)) {
update = FALSE;
} else {
/* if yes, skip it */
if (p_obs_results_cb && (result & BTM_BLE_OBS_RESULT)) {
(p_obs_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results, p_le_inq_cb->adv_data_cache);
}
+ if (p_scan_results_cb && (result & BTM_BLE_DISCO_RESULT)) {
+ (p_scan_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results, p_le_inq_cb->adv_data_cache);
+ }
}
}
(p_obs_cb)((tBTM_INQUIRY_CMPL *) &btm_cb.btm_inq_vars.inq_cmpl_info);
}
}
+
+/*******************************************************************************
+**
+** Function btm_ble_stop_observe
+**
+** Description Stop the BLE Observe.
+**
+** Returns void
+**
+*******************************************************************************/
+static void btm_ble_stop_discover(void)
+{
+ tBTM_BLE_CB *p_ble_cb = & btm_cb.ble_ctr_cb;
+ tBTM_CMPL_CB *p_scan_cb = p_ble_cb->p_scan_cmpl_cb;
+
+ btu_stop_timer (&p_ble_cb->scan_timer_ent);
+
+ p_ble_cb->scan_activity &= ~BTM_LE_DISCOVER_ACTIVE;
+
+ p_ble_cb->p_scan_results_cb = NULL;
+ p_ble_cb->p_scan_cmpl_cb = NULL;
+
+ if (!BTM_BLE_IS_SCAN_ACTIVE(p_ble_cb->scan_activity)) {
+ /* Clear the inquiry callback if set */
+ btm_cb.ble_ctr_cb.inq_var.scan_type = BTM_BLE_SCAN_MODE_NONE;
+ btm_cb.ble_ctr_cb.inq_var.state = BTM_BLE_STOP_SCAN;
+ /* stop discovery now */
+ btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_DISABLE, BTM_BLE_DUPLICATE_ENABLE);
+ }
+
+ if (p_scan_cb) {
+ (p_scan_cb)((tBTM_INQUIRY_CMPL *) &btm_cb.btm_inq_vars.inq_cmpl_info);
+ }
+}
+
/*******************************************************************************
**
** Function btm_ble_adv_states_operation
case BTU_TTYPE_BLE_OBSERVE:
btm_ble_stop_observe();
break;
-
+ case BTU_TTYPE_BLE_SCAN:
+ btm_ble_stop_discover();
+ break;
case BTU_TTYPE_BLE_INQUIRY:
btm_ble_stop_inquiry();
break;
case BTU_TTYPE_BLE_GAP_LIM_DISC:
case BTU_TTYPE_BLE_RANDOM_ADDR:
case BTU_TTYPE_BLE_GAP_FAST_ADV:
+ case BTU_TTYPE_BLE_SCAN:
case BTU_TTYPE_BLE_OBSERVE:
btm_ble_timeout(p_tle);
break;
/* inquiry activity mask */
#define BTM_BR_INQ_ACTIVE_MASK (BTM_GENERAL_INQUIRY_ACTIVE|BTM_LIMITED_INQUIRY_ACTIVE|BTM_PERIODIC_INQUIRY_ACTIVE) /* BR/EDR inquiry activity mask */
-#define BTM_BLE_SCAN_ACTIVE_MASK 0xF0 /* LE scan activity mask */
+#define BTM_BLE_SCAN_ACTIVE_MASK 0x01F0 /* LE scan activity mask */
#define BTM_BLE_INQ_ACTIVE_MASK (BTM_LE_GENERAL_INQUIRY_ACTIVE|BTM_LE_LIMITED_INQUIRY_ACTIVE) /* LE inquiry activity mask*/
#define BTM_INQUIRY_ACTIVE_MASK (BTM_BR_INQ_ACTIVE_MASK | BTM_BLE_INQ_ACTIVE_MASK) /* inquiry activity mask */
tBTM_STATUS BTM_BleObserve(BOOLEAN start, UINT32 duration,
tBTM_INQ_RESULTS_CB *p_results_cb, tBTM_CMPL_CB *p_cmpl_cb);
+/*******************************************************************************
+**
+** Function BTM_BleScan
+**
+** Description This procedure keep the device listening for advertising
+** events from a broadcast device.
+**
+** Parameters start: start or stop scan.
+**
+** Returns void
+**
+*******************************************************************************/
+//extern
+tBTM_STATUS BTM_BleScan(BOOLEAN start, UINT32 duration,
+ tBTM_INQ_RESULTS_CB *p_results_cb, tBTM_CMPL_CB *p_cmpl_cb);
+
/*******************************************************************************
**
#define BTM_BLE_IS_RESOLVE_BDA(x) ((x[0] & BLE_RESOLVE_ADDR_MASK) == BLE_RESOLVE_ADDR_MSB)
/* LE scan activity bit mask, continue with LE inquiry bits */
-#define BTM_LE_SELECT_CONN_ACTIVE 0x40 /* selection connection is in progress */
-#define BTM_LE_OBSERVE_ACTIVE 0x80 /* observe is in progress */
+#define BTM_LE_SELECT_CONN_ACTIVE 0x0040 /* selection connection is in progress */
+#define BTM_LE_OBSERVE_ACTIVE 0x0080 /* observe is in progress */
+#define BTM_LE_DISCOVER_ACTIVE 0x0100 /* scan is in progress */
/* BLE scan activity mask checking */
#define BTM_BLE_IS_SCAN_ACTIVE(x) ((x) & BTM_BLE_SCAN_ACTIVE_MASK)
#define BTM_BLE_IS_INQ_ACTIVE(x) ((x) & BTM_BLE_INQUIRY_MASK)
#define BTM_BLE_IS_OBS_ACTIVE(x) ((x) & BTM_LE_OBSERVE_ACTIVE)
+#define BTM_BLE_IS_DISCO_ACTIVE(x) ((x) & BTM_LE_DISCOVER_ACTIVE)
#define BTM_BLE_IS_SEL_CONN_ACTIVE(x) ((x) & BTM_LE_SELECT_CONN_ACTIVE)
/* BLE ADDR type ID bit */
typedef struct {
UINT16 discoverable_mode;
UINT16 connectable_mode;
+ BOOLEAN scan_params_set;
UINT32 scan_window;
UINT32 scan_interval;
UINT8 scan_type; /* current scan type: active or passive */
/* Define BLE Device Management control structure
*/
typedef struct {
- UINT8 scan_activity; /* LE scan activity mask */
+ UINT16 scan_activity; /* LE scan activity mask */
/*****************************************************
** BLE Inquiry
tBTM_CMPL_CB *p_obs_cmpl_cb;
TIMER_LIST_ENT obs_timer_ent;
+ /* scan callback and timer */
+ tBTM_INQ_RESULTS_CB *p_scan_results_cb;
+ tBTM_CMPL_CB *p_scan_cmpl_cb;
+ TIMER_LIST_ENT scan_timer_ent;
+
/* background connection procedure cb value */
tBTM_BLE_CONN_TYPE bg_conn_type;
UINT32 scan_int;
void btm_ble_stop_scan(void);
void btm_clear_all_pending_le_entry(void);
-void btm_ble_stop_scan();
BOOLEAN btm_ble_send_extended_scan_params(UINT8 scan_type, UINT32 scan_int,
UINT32 scan_win, UINT8 addr_type_own,
UINT8 scan_filter_policy);
#define BTU_TTYPE_BLE_GAP_FAST_ADV 106
#define BTU_TTYPE_BLE_OBSERVE 107
-
#define BTU_TTYPE_UCD_TO 108
-
+#define BTU_TTYPE_BLE_SCAN 109
/* This is the inquiry response information held by BTU, and available