mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-09-15 05:30:03 +00:00
nimble/ll: Decouple aux scanner from main scansm
This change moves handling of scanning aux PDUs to separate unit and thus simplifies code in ble_ll_scan. Basically, once ADV_EXT_IND is scanned by main scansm, scanning aux PDUs is running as a separate LL state and is handled by separate code. Handling on aux PDUs was also refactored a bit, more importantly we no longer need ref/unref for aux_data which caused lots of issues in the past - aux_data is always only allocated in ISR context when ADV_EXT_IND with AuxPtr is received and then can be freed only in LL context if no subsequent scan is scheduled. In addition, some changes were done to filtering routines so that now filtering and address resolution is done only once for each scanned ext advertising event, i.e. either on ADV_EXT_IND or AUX_ADV_IND. There is still some legacy code for aux scanner left since it's used by initiator role. This will be eventually removed once initiator is refactored to use the same code as generic scanner.
This commit is contained in:
@@ -220,6 +220,7 @@ extern STATS_SECT_DECL(ble_ll_stats) ble_ll_stats;
|
||||
#define BLE_LL_STATE_CONNECTION (4)
|
||||
#define BLE_LL_STATE_DTM (5)
|
||||
#define BLE_LL_STATE_SYNC (6)
|
||||
#define BLE_LL_STATE_SCAN_AUX (7)
|
||||
|
||||
/* LL Features */
|
||||
#define BLE_LL_FEAT_LE_ENCRYPTION (0x0000000001)
|
||||
@@ -354,6 +355,7 @@ struct ble_dev_addr
|
||||
#define BLE_LL_EXT_ADV_FLAGS_SIZE (1)
|
||||
#define BLE_LL_EXT_ADV_ADVA_SIZE (6)
|
||||
#define BLE_LL_EXT_ADV_TARGETA_SIZE (6)
|
||||
#define BLE_LL_EXT_ADV_CTE_INFO_SIZE (1)
|
||||
#define BLE_LL_EXT_ADV_DATA_INFO_SIZE (2)
|
||||
#define BLE_LL_EXT_ADV_AUX_PTR_SIZE (3)
|
||||
#define BLE_LL_EXT_ADV_SYNC_INFO_SIZE (18)
|
||||
|
||||
@@ -72,6 +72,12 @@ int ble_ll_resolv_local_addr_rd(const uint8_t *cmdbuf, uint8_t len,
|
||||
struct ble_ll_resolv_entry *
|
||||
ble_ll_resolv_list_find(const uint8_t *addr, uint8_t addr_type);
|
||||
|
||||
static inline int8_t
|
||||
ble_ll_resolv_get_idx(struct ble_ll_resolv_entry *rl)
|
||||
{
|
||||
return rl - g_ble_ll_resolv_list;
|
||||
}
|
||||
|
||||
/* Returns true if address resolution is enabled */
|
||||
uint8_t ble_ll_resolv_enabled(void);
|
||||
|
||||
|
||||
@@ -149,6 +149,20 @@ struct ble_ll_scan_pdu_data {
|
||||
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;
|
||||
@@ -286,6 +300,25 @@ void ble_ll_scan_end_adv_evt(struct ble_ll_aux_data *aux_data);
|
||||
/* 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);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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_AUX_
|
||||
#define H_BLE_LL_SCAN_AUX_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
|
||||
|
||||
struct ble_ll_scan_aux_data;
|
||||
|
||||
void ble_ll_scan_aux_init(void);
|
||||
int ble_ll_scan_aux_sched(struct ble_ll_scan_aux_data *aux, uint32_t pdu_time,
|
||||
uint8_t pdu_time_rem, uint32_t aux_ptr);
|
||||
int ble_ll_scan_aux_rx_isr_start(uint8_t pdu_type, struct ble_mbuf_hdr *rxhdr);
|
||||
int ble_ll_scan_aux_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok);
|
||||
void ble_ll_scan_aux_rx_pkt_in(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *rxhdr);
|
||||
|
||||
void ble_ll_scan_aux_break(struct ble_ll_scan_aux_data *aux);
|
||||
void ble_ll_scan_aux_wfr_timer_exp(void);
|
||||
void ble_ll_scan_aux_halt(void);
|
||||
void ble_ll_scan_aux_sched_remove(struct ble_ll_sched_item *sch);
|
||||
|
||||
int ble_ll_scan_aux_rx_isr_end_on_ext(struct ble_ll_scan_sm *scansm,
|
||||
struct os_mbuf *rxpdu);
|
||||
void ble_ll_scan_aux_pkt_in_on_ext(struct os_mbuf *rxpdu,
|
||||
struct ble_mbuf_hdr *rxhdr);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* H_BLE_LL_SCAN_AUX_ */
|
||||
@@ -71,6 +71,7 @@ extern uint8_t g_ble_ll_sched_offset_ticks;
|
||||
#define BLE_LL_SCHED_TYPE_DTM (5)
|
||||
#define BLE_LL_SCHED_TYPE_PERIODIC (6)
|
||||
#define BLE_LL_SCHED_TYPE_SYNC (7)
|
||||
#define BLE_LL_SCHED_TYPE_SCAN_AUX (8)
|
||||
|
||||
/* Return values for schedule callback. */
|
||||
#define BLE_LL_SCHED_STATE_RUNNING (0)
|
||||
@@ -200,6 +201,9 @@ int ble_ll_sched_aux_scan(struct ble_mbuf_hdr *ble_hdr,
|
||||
struct ble_ll_aux_data *aux_scan);
|
||||
|
||||
int ble_ll_sched_scan_req_over_aux_ptr(uint32_t chan, uint8_t phy_mode);
|
||||
|
||||
int ble_ll_sched_scan_aux(struct ble_ll_sched_item *sch, uint32_t pdu_time,
|
||||
uint8_t pdu_time_rem, uint32_t offset_us);
|
||||
#endif
|
||||
|
||||
/* Stop the scheduler */
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct ble_ll_scan_addr_data;
|
||||
struct ble_ll_sync_sm;
|
||||
|
||||
int ble_ll_sync_create(const uint8_t *cmdbuf, uint8_t len);
|
||||
@@ -48,8 +49,7 @@ void ble_ll_sync_periodic_ind(struct ble_ll_conn_sm *connsm,
|
||||
uint16_t max_skip, uint32_t sync_timeout);
|
||||
void ble_ll_sync_transfer_disconnected(struct ble_ll_conn_sm *connsm);
|
||||
|
||||
void ble_ll_sync_info_event(const uint8_t *addr, uint8_t addr_type,
|
||||
int rpa_index, uint8_t sid,
|
||||
void ble_ll_sync_info_event(struct ble_ll_scan_addr_data *addrd, uint8_t sid,
|
||||
struct ble_mbuf_hdr *rxhdr,
|
||||
const uint8_t *syncinfo);
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "controller/ble_ll_adv.h"
|
||||
#include "controller/ble_ll_sched.h"
|
||||
#include "controller/ble_ll_scan.h"
|
||||
#include "controller/ble_ll_scan_aux.h"
|
||||
#include "controller/ble_ll_hci.h"
|
||||
#include "controller/ble_ll_whitelist.h"
|
||||
#include "controller/ble_ll_resolv.h"
|
||||
@@ -688,6 +689,11 @@ ble_ll_wfr_timer_exp(void *arg)
|
||||
case BLE_LL_STATE_SYNC:
|
||||
ble_ll_sync_wfr_timer_exp();
|
||||
break;
|
||||
#endif
|
||||
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
|
||||
case BLE_LL_STATE_SCAN_AUX:
|
||||
ble_ll_scan_aux_wfr_timer_exp();
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
@@ -848,6 +854,11 @@ ble_ll_rx_pkt_in(void)
|
||||
case BLE_LL_STATE_SYNC:
|
||||
ble_ll_sync_rx_pkt_in(m, ble_hdr);
|
||||
break;
|
||||
#endif
|
||||
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
|
||||
case BLE_LL_STATE_SCAN_AUX:
|
||||
ble_ll_scan_aux_rx_pkt_in(m, ble_hdr);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
/* Any other state should never occur */
|
||||
@@ -984,6 +995,11 @@ ble_ll_rx_start(uint8_t *rxbuf, uint8_t chan, struct ble_mbuf_hdr *rxhdr)
|
||||
case BLE_LL_STATE_SYNC:
|
||||
rc = ble_ll_sync_rx_isr_start(pdu_type, rxhdr);
|
||||
break;
|
||||
#endif
|
||||
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
|
||||
case BLE_LL_STATE_SCAN_AUX:
|
||||
rc = ble_ll_scan_aux_rx_isr_start(pdu_type, rxhdr);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
/* Should not be in this state! */
|
||||
@@ -1109,6 +1125,17 @@ ble_ll_rx_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr)
|
||||
case BLE_LL_STATE_INITIATING:
|
||||
rc = ble_ll_init_rx_isr_end(rxbuf, crcok, rxhdr);
|
||||
break;
|
||||
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
|
||||
case BLE_LL_STATE_SCAN_AUX:
|
||||
if (!badpkt) {
|
||||
rxpdu = ble_ll_rxpdu_alloc(len + BLE_LL_PDU_HDR_LEN);
|
||||
if (rxpdu) {
|
||||
ble_phy_rxpdu_copy(rxbuf, rxpdu);
|
||||
}
|
||||
}
|
||||
rc = ble_ll_scan_aux_rx_isr_end(rxpdu, crcok);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
rc = -1;
|
||||
STATS_INC(ble_ll_stats, bad_ll_state);
|
||||
|
||||
+192
-908
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -28,6 +28,7 @@
|
||||
#include "controller/ble_ll_sched.h"
|
||||
#include "controller/ble_ll_adv.h"
|
||||
#include "controller/ble_ll_scan.h"
|
||||
#include "controller/ble_ll_scan_aux.h"
|
||||
#include "controller/ble_ll_rfmgmt.h"
|
||||
#include "controller/ble_ll_trace.h"
|
||||
#include "controller/ble_ll_sync.h"
|
||||
@@ -244,6 +245,9 @@ ble_ll_sched_conn_reschedule(struct ble_ll_conn_sm *connsm)
|
||||
ble_ll_adv_event_rmvd_from_sched((struct ble_ll_adv_sm *)entry->cb_arg);
|
||||
break;
|
||||
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
|
||||
case BLE_LL_SCHED_TYPE_SCAN_AUX:
|
||||
ble_ll_scan_aux_break(entry->cb_arg);
|
||||
break;
|
||||
case BLE_LL_SCHED_TYPE_AUX_SCAN:
|
||||
ble_ll_scan_end_adv_evt((struct ble_ll_aux_data *)entry->cb_arg);
|
||||
break;
|
||||
@@ -1463,6 +1467,11 @@ ble_ll_sched_execute_item(struct ble_ll_sched_item *sch)
|
||||
} else if (lls == BLE_LL_STATE_SYNC) {
|
||||
STATS_INC(ble_ll_stats, sched_state_sync_errs);
|
||||
ble_ll_sync_halt();
|
||||
#endif
|
||||
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
|
||||
} else if (lls == BLE_LL_STATE_SCAN_AUX) {
|
||||
ble_ll_state_set(BLE_LL_STATE_STANDBY);
|
||||
ble_ll_scan_aux_halt();
|
||||
#endif
|
||||
} else {
|
||||
STATS_INC(ble_ll_stats, sched_state_conn_errs);
|
||||
@@ -1714,6 +1723,65 @@ done:
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
ble_ll_sched_scan_aux(struct ble_ll_sched_item *sch, uint32_t pdu_time,
|
||||
uint8_t pdu_time_rem, uint32_t offset_us)
|
||||
{
|
||||
struct ble_ll_sched_item *entry;
|
||||
uint32_t offset_ticks;
|
||||
os_sr_t sr;
|
||||
int rc;
|
||||
|
||||
offset_us += pdu_time_rem;
|
||||
offset_ticks = os_cputime_usecs_to_ticks(offset_us);
|
||||
|
||||
sch->start_time = pdu_time + offset_ticks - g_ble_ll_sched_offset_ticks;
|
||||
sch->remainder = offset_us - os_cputime_ticks_to_usecs(offset_ticks);
|
||||
/* TODO: make some sane slot reservation */
|
||||
sch->end_time = sch->start_time + os_cputime_usecs_to_ticks(5000);
|
||||
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
|
||||
if (!ble_ll_sched_insert_if_empty(sch)) {
|
||||
/* Scheduler was empty, inserted as 1st element */
|
||||
rc = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
os_cputime_timer_stop(&g_ble_ll_sched_timer);
|
||||
TAILQ_FOREACH(entry, &g_ble_ll_sched_q, link) {
|
||||
if (CPUTIME_LEQ(sch->end_time, entry->start_time)) {
|
||||
TAILQ_INSERT_BEFORE(entry, sch, link);
|
||||
sch->enqueued = 1;
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ble_ll_sched_is_overlap(sch, entry)) {
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!entry) {
|
||||
TAILQ_INSERT_TAIL(&g_ble_ll_sched_q, sch, link);
|
||||
sch->enqueued = 1;
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
done:
|
||||
entry = TAILQ_FIRST(&g_ble_ll_sched_q);
|
||||
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
|
||||
if (entry == sch) {
|
||||
ble_ll_rfmgmt_sched_changed(sch);
|
||||
}
|
||||
os_cputime_timer_start(&g_ble_ll_sched_timer, entry->start_time);
|
||||
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(BLE_LL_DTM)
|
||||
|
||||
@@ -1333,14 +1333,11 @@ ble_ll_sync_event_end(struct ble_npl_event *ev)
|
||||
}
|
||||
|
||||
void
|
||||
ble_ll_sync_info_event(const uint8_t *addr, uint8_t addr_type, int rpa_index,
|
||||
ble_ll_sync_info_event(struct ble_ll_scan_addr_data *addrd,
|
||||
uint8_t sid, struct ble_mbuf_hdr *rxhdr,
|
||||
const uint8_t *syncinfo)
|
||||
{
|
||||
struct ble_ll_sync_sm *sm = NULL;
|
||||
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER)
|
||||
const uint8_t *rpa = NULL;
|
||||
#endif
|
||||
uint16_t max_skip;
|
||||
uint32_t offset;
|
||||
uint32_t usecs;
|
||||
@@ -1365,28 +1362,21 @@ ble_ll_sync_info_event(const uint8_t *addr, uint8_t addr_type, int rpa_index,
|
||||
return;
|
||||
}
|
||||
|
||||
/* check if resolved */
|
||||
if (rpa_index >= 0) {
|
||||
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER)
|
||||
rpa = addr;
|
||||
#endif
|
||||
addr = g_ble_ll_resolv_list[rpa_index].rl_identity_addr;
|
||||
addr_type = g_ble_ll_resolv_list[rpa_index].rl_addr_type;
|
||||
}
|
||||
|
||||
/* check peer */
|
||||
if (g_ble_ll_sync_create_params.options & BLE_HCI_LE_PERIODIC_ADV_CREATE_SYNC_OPT_FILTER) {
|
||||
if (ble_ll_sync_on_list(addr, addr_type, sid) < 0) {
|
||||
if (ble_ll_sync_on_list(addrd->adv_addr,
|
||||
addrd->adv_addr_type, sid) < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* set addr and sid in sm */
|
||||
sm->adv_sid = sid;
|
||||
sm->adv_addr_type = addr_type;
|
||||
memcpy(sm->adv_addr, addr, BLE_DEV_ADDR_LEN);
|
||||
sm->adv_addr_type = addrd->adv_addr_type;
|
||||
memcpy(sm->adv_addr, addrd->adv_addr, BLE_DEV_ADDR_LEN);
|
||||
} else {
|
||||
if ((sm->adv_sid != sid) || (sm->adv_addr_type != addr_type) ||
|
||||
memcmp(sm->adv_addr, addr, BLE_DEV_ADDR_LEN)) {
|
||||
if ((sm->adv_sid != sid) ||
|
||||
(sm->adv_addr_type != addrd->adv_addr_type) ||
|
||||
memcmp(sm->adv_addr, addrd->adv_addr, BLE_DEV_ADDR_LEN)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1406,12 +1396,14 @@ ble_ll_sync_info_event(const uint8_t *addr, uint8_t addr_type, int rpa_index,
|
||||
return;
|
||||
}
|
||||
|
||||
if (rpa_index >= 0) {
|
||||
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
|
||||
if (addrd->adva_resolved) {
|
||||
sm->flags |= BLE_LL_SYNC_SM_FLAG_ADDR_RESOLVED;
|
||||
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER)
|
||||
memcpy(sm->adv_addr_rpa, rpa, BLE_DEV_ADDR_LEN);
|
||||
memcpy(sm->adv_addr_rpa, addrd->adva, BLE_DEV_ADDR_LEN);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/* set params from HCI LE Create Periodic Sync */
|
||||
sm->timeout = g_ble_ll_sync_create_params.timeout;
|
||||
|
||||
@@ -291,6 +291,12 @@ syscfg.defs:
|
||||
restrictions:
|
||||
- 'BLE_LL_CFG_FEAT_LL_ISO if 1'
|
||||
|
||||
BLE_LL_SCAN_AUX_SEGMENT_CNT:
|
||||
description: >
|
||||
Number of auxiliary advertising segments that can be scanned
|
||||
concurrently (Core 5.2, Vol 6, Part B, 4.4.2.2.2).
|
||||
value: 8
|
||||
|
||||
BLE_LL_EXT_ADV_AUX_PTR_CNT:
|
||||
description: >
|
||||
This option configure a max number of scheduled outstanding auxiliary
|
||||
|
||||
Reference in New Issue
Block a user