WXK
2024-12-20 51135221cd73a2b3a6ce4b5ec906396d5a33b4c7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */
 
#ifndef H_BLE_LL_SCAN_
#define H_BLE_LL_SCAN_
 
#include "controller/ble_ll_sched.h"
#include "controller/ble_ll_tmr.h"
#include "nimble_syscfg.h"
#include "nimble/nimble_npl.h"
 
#ifdef __cplusplus
extern "C" {
#endif
 
/*
 * SCAN_REQ
 *      -> ScanA    (6 bytes)
 *      -> AdvA     (6 bytes)
 *
 *  ScanA is the scanners public (TxAdd=0) or random (TxAdd = 1) address
 *  AdvaA is the advertisers public (RxAdd=0) or random (RxAdd=1) address.
 *
 * Sent by the LL in the Scanning state; received by the LL in the advertising
 * state. The advertising address is the intended recipient of this frame.
 */
#define BLE_SCAN_REQ_LEN                (12)
 
/*
 * SCAN_RSP
 *      -> AdvA         (6 bytes)
 *      -> ScanRspData  (0 - 31 bytes)
 *
 *  AdvaA is the advertisers public (TxAdd=0) or random (TxAdd=1) address.
 *  ScanRspData may contain any data from the advertisers host.
 *
 * Sent by the LL in the advertising state; received by the LL in the
 * scanning state.
 */
#define BLE_SCAN_RSP_LEGACY_DATA_MAX_LEN       (31)
#define BLE_SCAN_LEGACY_MAX_PKT_LEN            (37)
 
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
#define BLE_SCAN_RSP_DATA_MAX_LEN       MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE)
 
/* For Bluetooth 5.0 we need state machine for two PHYs*/
#define BLE_LL_SCAN_PHY_NUMBER          (2)
#else
#define BLE_LL_SCAN_PHY_NUMBER          (1)
#define BLE_SCAN_RSP_DATA_MAX_LEN       BLE_SCAN_RSP_LEGACY_DATA_MAX_LEN
#endif
 
#define PHY_UNCODED                    (0)
#define PHY_CODED                      (1)
 
#define BLE_LL_EXT_ADV_MODE_NON_CONN    (0x00)
#define BLE_LL_EXT_ADV_MODE_CONN        (0x01)
#define BLE_LL_EXT_ADV_MODE_SCAN        (0x02)
 
/* All values are stored as ticks */
struct ble_ll_scan_timing {
    uint32_t interval;
    uint32_t window;
    uint32_t start_time;
};
 
struct ble_ll_scan_phy
{
    uint8_t phy;
    uint8_t configured;
    uint8_t scan_type;
    uint8_t scan_chan;
    struct ble_ll_scan_timing timing;
};
 
struct ble_ll_scan_pdu_data {
    uint8_t hdr_byte;
    /* ScanA for SCAN_REQ and InitA for CONNECT_IND */
    union {
        uint8_t scana[BLE_DEV_ADDR_LEN];
        uint8_t inita[BLE_DEV_ADDR_LEN];
    };
    uint8_t adva[BLE_DEV_ADDR_LEN];
};
 
struct ble_ll_scan_addr_data {
    uint8_t *adva;
    uint8_t *targeta;
    uint8_t *adv_addr;
    uint8_t adva_type : 1;
    uint8_t targeta_type : 1;
    uint8_t adv_addr_type : 1;
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
    uint8_t adva_resolved : 1;
    uint8_t targeta_resolved : 1;
    int8_t rpa_index;
#endif
};
 
struct ble_ll_scan_sm
{
    uint8_t scan_enabled;
 
    uint8_t own_addr_type;
    uint8_t scan_filt_policy;
    uint8_t scan_filt_dups;
    uint8_t scan_rsp_pending;
    uint8_t scan_rsp_cons_fails;
    uint8_t scan_rsp_cons_ok;
    uint8_t scan_peer_rpa[BLE_DEV_ADDR_LEN];
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
    ble_npl_time_t scan_nrpa_timer;
    uint8_t scan_nrpa[BLE_DEV_ADDR_LEN];
#endif
    struct ble_ll_scan_pdu_data pdu_data;
 
    /* XXX: Shall we count backoff per phy? */
    uint16_t upper_limit;
    uint16_t backoff_count;
    uint32_t scan_win_start_time;
    struct ble_npl_event scan_sched_ev;
    struct ble_ll_tmr scan_timer;
    struct ble_npl_event scan_interrupted_ev;
 
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
    struct ble_npl_callout duration_timer;
    struct ble_npl_callout period_timer;
    ble_npl_time_t duration_ticks;
    ble_npl_time_t period_ticks;
    uint8_t ext_scanning;
#endif
 
    uint8_t restart_timer_needed;
 
    struct ble_ll_scan_phy *scanp;
    struct ble_ll_scan_phy *scanp_next;
    struct ble_ll_scan_phy scan_phys[BLE_LL_SCAN_PHY_NUMBER];
 
#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL)
    /* Connection sm for initiator scan */
    struct ble_ll_conn_sm *connsm;
#endif
};
 
/* Scan types */
#define BLE_SCAN_TYPE_PASSIVE   (BLE_HCI_SCAN_TYPE_PASSIVE)
#define BLE_SCAN_TYPE_ACTIVE    (BLE_HCI_SCAN_TYPE_ACTIVE)
#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL)
#define BLE_SCAN_TYPE_INITIATE  (2)
#endif
 
/*---- HCI ----*/
/* Set scanning parameters */
int ble_ll_scan_hci_set_params(const uint8_t *cmdbuf, uint8_t len);
 
/* Turn scanning on/off */
int ble_ll_scan_hci_set_enable(const uint8_t *cmdbuf, uint8_t len);
int ble_ll_scan_hci_set_ext_enable(const uint8_t *cmdbuf, uint8_t len);
 
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
int ble_ll_scan_hci_set_ext_params(const uint8_t *cmdbuf, uint8_t len);
#endif
 
/*--- Controller Internal API ---*/
/* Initialize the scanner */
void ble_ll_scan_init(void);
 
/* Reset the scanner */
void ble_ll_scan_reset(void);
 
/* Called when Link Layer starts to receive a PDU and is in scanning state */
int ble_ll_scan_rx_isr_start(uint8_t pdu_type, uint16_t *rxflags);
 
/* Called when Link Layer has finished receiving a PDU while scanning */
int ble_ll_scan_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok);
 
/* Process a scan response PDU */
void ble_ll_scan_rx_pkt_in(uint8_t pdu_type, struct os_mbuf *om,
                           struct ble_mbuf_hdr *hdr);
 
/* Boolean function denoting whether or not the whitelist can be changed */
int ble_ll_scan_can_chg_whitelist(void);
 
/* Boolean function returning true if scanning enabled */
int ble_ll_scan_enabled(void);
 
/* Initialize the scanner when we start initiating */
struct ble_ll_conn_create_scan;
struct ble_ll_conn_create_params;
int
ble_ll_scan_initiator_start(struct ble_ll_conn_sm *connsm, uint8_t ext,
                            struct ble_ll_conn_create_scan *cc_scan);
 
/* Returns storage for PDU data (for SCAN_REQ or CONNECT_IND) */
struct ble_ll_scan_pdu_data *ble_ll_scan_get_pdu_data(void);
 
/* Called to set the resolvable private address of the last connected peer */
void ble_ll_scan_set_peer_rpa(uint8_t *rpa);
 
/* Returns peer RPA of last connection made */
uint8_t *ble_ll_scan_get_peer_rpa(void);
 
/* Returns the local RPA used by the scanner/initiator */
uint8_t *ble_ll_scan_get_local_rpa(void);
 
/* Stop the scanning state machine */
void ble_ll_scan_sm_stop(int chk_disable);
 
/* Resume scanning */
#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER)
void ble_ll_scan_chk_resume(void);
#else
static inline void ble_ll_scan_chk_resume(void) { };
#endif
 
/* Called when wait for response timer expires in scanning mode */
void ble_ll_scan_wfr_timer_exp(void);
 
/* Called when scan could be interrupted  */
void ble_ll_scan_interrupted(struct ble_ll_scan_sm *scansm);
 
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
/* Called to parse extended advertising*/
void ble_ll_scan_end_adv_evt(struct ble_ll_aux_data *aux_data);
#endif
 
/* Called to halt currently running scan */
void ble_ll_scan_halt(void);
 
uint8_t *ble_ll_get_scan_nrpa(void);
uint8_t ble_ll_scan_get_own_addr_type(void);
uint8_t ble_ll_scan_get_filt_policy(void);
uint8_t ble_ll_scan_get_filt_dups(void);
uint8_t ble_ll_scan_backoff_kick(void);
void ble_ll_scan_backoff_update(int success);
 
int ble_ll_scan_dup_check_ext(uint8_t addr_type, uint8_t *addr, bool has_aux,
                              uint16_t adi);
int ble_ll_scan_dup_update_ext(uint8_t addr_type, uint8_t *addr, bool has_aux,
                               uint16_t adi);
int ble_ll_scan_have_rxd_scan_rsp(uint8_t *addr, uint8_t txadd, uint8_t ext_adv,
                                  uint16_t adi);
void ble_ll_scan_add_scan_rsp_adv(uint8_t *addr, uint8_t txadd, uint8_t ext_adv,
                                  uint16_t adi);
 
int
ble_ll_scan_rx_filter(uint8_t own_addr_type, uint8_t scan_filt_policy,
                      struct ble_ll_scan_addr_data *addrd, uint8_t *scan_ok);
int ble_ll_scan_rx_check_init(struct ble_ll_scan_addr_data *addrd);
 
#ifdef __cplusplus
}
#endif
 
#endif /* H_BLE_LL_SCAN_ */