1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 20 #ifndef H_BLE_LL_SCAN_ 21 #define H_BLE_LL_SCAN_ 22 23 #include "controller/ble_ll_sched.h" 24 #include "hal/hal_timer.h" 25 #include "syscfg/syscfg.h" 26 #include "nimble/nimble_npl.h" 27 28 #ifdef __cplusplus 29 extern "C" { 30 #endif 31 32 /* 33 * SCAN_REQ 34 * -> ScanA (6 bytes) 35 * -> AdvA (6 bytes) 36 * 37 * ScanA is the scanners public (TxAdd=0) or random (TxAdd = 1) address 38 * AdvaA is the advertisers public (RxAdd=0) or random (RxAdd=1) address. 39 * 40 * Sent by the LL in the Scanning state; received by the LL in the advertising 41 * state. The advertising address is the intended recipient of this frame. 42 */ 43 #define BLE_SCAN_REQ_LEN (12) 44 45 /* 46 * SCAN_RSP 47 * -> AdvA (6 bytes) 48 * -> ScanRspData (0 - 31 bytes) 49 * 50 * AdvaA is the advertisers public (TxAdd=0) or random (TxAdd=1) address. 51 * ScanRspData may contain any data from the advertisers host. 52 * 53 * Sent by the LL in the advertising state; received by the LL in the 54 * scanning state. 55 */ 56 #define BLE_SCAN_RSP_LEGACY_DATA_MAX_LEN (31) 57 #define BLE_SCAN_LEGACY_MAX_PKT_LEN (37) 58 59 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) 60 #define BLE_SCAN_RSP_DATA_MAX_LEN MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE) 61 62 /* For Bluetooth 5.0 we need state machine for two PHYs*/ 63 #define BLE_LL_SCAN_PHY_NUMBER (2) 64 #else 65 #define BLE_LL_SCAN_PHY_NUMBER (1) 66 #define BLE_SCAN_RSP_DATA_MAX_LEN BLE_SCAN_RSP_LEGACY_DATA_MAX_LEN 67 #endif 68 69 #define PHY_UNCODED (0) 70 #define PHY_CODED (1) 71 #define PHY_NOT_CONFIGURED (0xFF) 72 73 #define BLE_LL_EXT_ADV_MODE_NON_CONN (0x00) 74 #define BLE_LL_EXT_ADV_MODE_CONN (0x01) 75 #define BLE_LL_EXT_ADV_MODE_SCAN (0x02) 76 77 struct ble_ll_scan_params 78 { 79 uint8_t phy; 80 uint8_t own_addr_type; 81 uint8_t scan_filt_policy; 82 uint8_t configured; 83 uint8_t scan_type; 84 uint8_t scan_chan; 85 uint16_t scan_itvl; 86 uint16_t scan_window; 87 uint32_t scan_win_start_time; 88 uint32_t next_event_start; 89 }; 90 91 #define BLE_LL_AUX_CHAIN_BIT 0x01 92 #define BLE_LL_AUX_INCOMPLETE_BIT 0x02 93 #define BLE_LL_AUX_INCOMPLETE_ERR_BIT 0x04 94 #define BLE_LL_AUX_HAS_ADDRA 0x08 95 #define BLE_LL_AUX_IGNORE_BIT 0x10 96 #define BLE_LL_AUX_HAS_DIR_ADDRA 0x20 97 #define BLE_LL_AUX_TRUNCATED_SENT 0x40 98 #define BLE_LL_AUX_HAS_ADI 0x80 99 100 #define BLE_LL_SET_AUX_FLAG(aux_data, flag) ((aux_data)->flags |= flag) 101 #define BLE_LL_CHECK_AUX_FLAG(aux_data, flag) (!!((aux_data)->flags & flag)) 102 103 struct ble_ll_aux_data { 104 uint8_t ref_cnt; 105 uint8_t chan; 106 uint8_t aux_phy; 107 uint8_t aux_primary_phy; 108 uint8_t mode; 109 uint8_t scanning; 110 uint8_t flags; 111 uint16_t adi; 112 uint32_t offset; 113 uint8_t offset_units; 114 uint8_t addr[6]; 115 uint8_t addr_type; 116 uint8_t dir_addr[6]; 117 uint8_t dir_addr_type; 118 uint8_t evt_type; 119 struct ble_ll_sched_item sch; 120 struct ble_ll_ext_adv_report *evt; 121 }; 122 123 struct ble_ll_scan_sm 124 { 125 uint8_t scan_enabled; 126 uint8_t own_addr_type; 127 uint8_t scan_filt_dups; 128 uint8_t scan_rsp_pending; 129 uint8_t scan_rsp_cons_fails; 130 uint8_t scan_rsp_cons_ok; 131 int8_t scan_rpa_index; 132 uint8_t scan_peer_rpa[BLE_DEV_ADDR_LEN]; 133 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1) 134 ble_npl_time_t scan_nrpa_timer; 135 uint8_t scan_nrpa[BLE_DEV_ADDR_LEN]; 136 #endif 137 138 /* XXX: Shall we count backoff per phy? */ 139 uint16_t upper_limit; 140 uint16_t backoff_count; 141 uint32_t scan_win_start_time; 142 struct os_mbuf *scan_req_pdu; 143 struct ble_npl_event scan_sched_ev; 144 struct hal_timer scan_timer; 145 146 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) 147 struct hal_timer duration_timer; 148 struct hal_timer period_timer; 149 uint32_t duration_ticks; 150 uint32_t period_ticks; 151 uint8_t ext_scanning; 152 #endif 153 154 uint8_t cur_phy; 155 uint8_t next_phy; 156 uint8_t restart_timer_needed; 157 struct ble_ll_aux_data *cur_aux_data; 158 struct ble_ll_scan_params phy_data[BLE_LL_SCAN_PHY_NUMBER]; 159 }; 160 161 /* Scan types */ 162 #define BLE_SCAN_TYPE_PASSIVE (BLE_HCI_SCAN_TYPE_PASSIVE) 163 #define BLE_SCAN_TYPE_ACTIVE (BLE_HCI_SCAN_TYPE_ACTIVE) 164 #define BLE_SCAN_TYPE_INITIATE (2) 165 166 /*---- HCI ----*/ 167 /* Set scanning parameters */ 168 int ble_ll_scan_set_scan_params(uint8_t *cmd); 169 170 /* Turn scanning on/off */ 171 int ble_ll_scan_set_enable(uint8_t *cmd, uint8_t ext); 172 173 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) 174 int ble_ll_set_ext_scan_params(uint8_t *cmd, uint8_t cmdlen); 175 #endif 176 177 /*--- Controller Internal API ---*/ 178 /* Initialize the scanner */ 179 void ble_ll_scan_init(void); 180 181 /* Reset the scanner */ 182 void ble_ll_scan_reset(void); 183 184 /* Called when Link Layer starts to receive a PDU and is in scanning state */ 185 int ble_ll_scan_rx_isr_start(uint8_t pdu_type, uint16_t *rxflags); 186 187 /* Called when Link Layer has finished receiving a PDU while scanning */ 188 int ble_ll_scan_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok); 189 190 /* Process a scan response PDU */ 191 void ble_ll_scan_rx_pkt_in(uint8_t pdu_type, struct os_mbuf *om, 192 struct ble_mbuf_hdr *hdr); 193 194 /* Boolean function denoting whether or not the whitelist can be changed */ 195 int ble_ll_scan_can_chg_whitelist(void); 196 197 /* Boolean function returning true if scanning enabled */ 198 int ble_ll_scan_enabled(void); 199 200 /* Boolean function returns true if whitelist is enabled for scanning */ 201 int ble_ll_scan_whitelist_enabled(void); 202 203 /* Initialize the scanner when we start initiating */ 204 struct hci_create_conn; 205 int ble_ll_scan_initiator_start(struct hci_create_conn *hcc, 206 struct ble_ll_scan_sm **sm); 207 208 /* Returns the PDU allocated by the scanner */ 209 struct os_mbuf *ble_ll_scan_get_pdu(void); 210 211 /* Called to set the resolvable private address of the last connected peer */ 212 void ble_ll_scan_set_peer_rpa(uint8_t *rpa); 213 214 /* Returns peer RPA of last connection made */ 215 uint8_t *ble_ll_scan_get_peer_rpa(void); 216 217 /* Returns the local RPA used by the scanner/initiator */ 218 uint8_t *ble_ll_scan_get_local_rpa(void); 219 220 /* Stop the scanning state machine */ 221 void ble_ll_scan_sm_stop(int chk_disable); 222 223 /* Resume scanning */ 224 void ble_ll_scan_chk_resume(void); 225 226 /* Called when wait for response timer expires in scanning mode */ 227 void ble_ll_scan_wfr_timer_exp(void); 228 229 int ble_ll_scan_adv_decode_addr(uint8_t pdu_type, uint8_t *rxbuf, 230 struct ble_mbuf_hdr *ble_hdr, 231 uint8_t **addr, uint8_t *addr_type, 232 uint8_t **inita, uint8_t *init_addr_type, 233 int *ext_mode); 234 235 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) 236 /* Get aux ptr from ext advertising */ 237 int ble_ll_scan_get_aux_data(struct ble_mbuf_hdr *ble_hdr, uint8_t *rxbuf); 238 239 /* Initialize the extended scanner when we start initiating */ 240 struct hci_ext_create_conn; 241 int ble_ll_scan_ext_initiator_start(struct hci_ext_create_conn *hcc, 242 struct ble_ll_scan_sm **sm); 243 244 /* Called to parse extended advertising*/ 245 struct ble_ll_ext_adv_report; 246 int ble_ll_scan_parse_ext_hdr(struct os_mbuf *om, 247 uint8_t *adva, uint8_t adva_type, 248 uint8_t *inita, uint8_t inita_type, 249 struct ble_mbuf_hdr *ble_hdr, 250 struct ble_ll_ext_adv_report *parsed_evt); 251 252 void ble_ll_scan_aux_data_ref(struct ble_ll_aux_data *aux_scan); 253 int ble_ll_scan_aux_data_unref(struct ble_ll_aux_data *aux_scan); 254 #endif 255 256 /* Called to clean up current aux data */ 257 void ble_ll_scan_clean_cur_aux_data(void); 258 void ble_ll_scan_end_adv_evt(struct ble_ll_aux_data *aux_data); 259 260 #ifdef __cplusplus 261 } 262 #endif 263 264 #endif /* H_BLE_LL_SCAN_ */ 265