Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 1 addition & 59 deletions apps/bttester/src/btp_gap.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,6 @@ static struct os_callout connected_ev_co;
static struct btp_gap_device_connected_ev connected_ev;
#define CONNECTED_EV_DELAY_MS(itvl) 8 * BLE_HCI_CONN_ITVL * itvl / 1000
static int connection_attempts;
#if MYNEWT_VAL(BTTESTER_PRIVACY_MODE) && MYNEWT_VAL(BTTESTER_USE_NRPA)
static int64_t advertising_start;
static struct os_callout bttester_nrpa_rotate_timer;
#endif

static const struct ble_gap_conn_params dflt_conn_params = {
.scan_itvl = 0x0010,
Expand Down Expand Up @@ -235,49 +231,6 @@ static struct ble_gap_adv_params adv_params = {

static uint8_t ad_flags = BLE_HS_ADV_F_BREDR_UNSUP;

#if MYNEWT_VAL(BTTESTER_PRIVACY_MODE) && MYNEWT_VAL(BTTESTER_USE_NRPA)
static void rotate_nrpa_cb(struct os_event *ev)
{
int rc;
ble_addr_t addr;
int32_t duration_ms = BLE_HS_FOREVER;
int32_t remaining_time;
os_time_t remaining_ticks;

if (current_settings & BIT(BTP_GAP_SETTINGS_DISCOVERABLE)) {
if (ad_flags & BLE_HS_ADV_F_DISC_LTD) {
duration_ms = MYNEWT_VAL(BTTESTER_LTD_ADV_TIMEOUT);
}
}

#if MYNEWT_VAL(BLE_EXT_ADV)
ble_gap_ext_adv_stop(0);
#else
ble_gap_adv_stop();
#endif

rc = ble_hs_id_gen_rnd(1, &addr);
assert(rc == 0);
rc = ble_hs_id_set_rnd(addr.val);
assert(rc == 0);

#if MYNEWT_VAL(BLE_EXT_ADV)
ble_gap_ext_adv_start(0, duration_ms / 10, 0);
#else
ble_gap_adv_start(own_addr_type, NULL, duration_ms,
&adv_params, gap_event_cb, NULL);
#endif

remaining_time = os_get_uptime_usec() - advertising_start;
if (remaining_time > 0) {
advertising_start = os_get_uptime_usec();
os_time_ms_to_ticks(remaining_time, &remaining_ticks);
os_callout_reset(&bttester_nrpa_rotate_timer,
remaining_ticks);
}
}
#endif

static uint8_t
set_connectable(const void *cmd, uint16_t cmd_len,
void *rsp, uint16_t *rsp_len)
Expand Down Expand Up @@ -556,14 +509,6 @@ start_advertising(const void *cmd, uint16_t cmd_len,
return BTP_STATUS_FAILED;
}

#if MYNEWT_VAL(BTTESTER_PRIVACY_MODE) && MYNEWT_VAL(BTTESTER_USE_NRPA)
if (MYNEWT_VAL(BTTESTER_NRPA_TIMEOUT) < duration_ms / 1000) {
advertising_start = os_get_uptime_usec();
os_callout_reset(&bttester_nrpa_rotate_timer,
OS_TICKS_PER_SEC * MYNEWT_VAL(BTTESTER_NRPA_TIMEOUT));
}
#endif

#if MYNEWT_VAL(BLE_EXT_ADV)
err = ble_gap_ext_adv_start(0, duration_ms / 10, 0);
#else
Expand Down Expand Up @@ -2475,10 +2420,7 @@ tester_init_gap(void)
return BTP_STATUS_FAILED;
}
#endif
#if MYNEWT_VAL(BTTESTER_PRIVACY_MODE) && MYNEWT_VAL(BTTESTER_USE_NRPA)
os_callout_init(&bttester_nrpa_rotate_timer, os_eventq_dflt_get(),
rotate_nrpa_cb, NULL);
#endif

adv_buf = os_msys_get(ADV_BUF_LEN, 0);
assert(adv_buf);

Expand Down
158 changes: 158 additions & 0 deletions nimble/host/src/ble_gap.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,11 +186,16 @@ struct ble_gap_slave_state {
unsigned int high_duty_directed:1;
unsigned int legacy_pdu:1;
unsigned int rnd_addr_set:1;
unsigned int nrpa_exp_set : 1;
#if MYNEWT_VAL(BLE_PERIODIC_ADV)
unsigned int periodic_configured:1;
uint8_t periodic_op;
#endif
uint8_t rnd_addr[6];
ble_npl_time_t nrpa_exp_os_ticks;
ble_npl_time_t adv_start_time;
uint16_t adv_duration;
uint8_t adv_max_events;
#else
/* timer is used only with legacy advertising */
unsigned int exp_set:1;
Expand All @@ -202,10 +207,141 @@ struct ble_gap_slave_state {
};

static bssnz_t struct ble_gap_slave_state ble_gap_slave[BLE_ADV_INSTANCES];
#if MYNEWT_VAL(BLE_EXT_ADV)
static int ble_gap_ext_adv_set_addr_no_lock(uint8_t instance, const uint8_t *addr);
static int ble_gap_ext_adv_stop_no_lock(uint8_t instance);
int ble_gap_ext_adv_start(uint8_t instance, int duration, int max_events);
#endif

#if NIMBLE_BLE_ADVERTISE
#if MYNEWT_VAL(BLE_EXT_ADV)
static bool ext_adv_legacy_configured = false;

static bool
ble_gap_ext_adv_rnd_addr_is_nrpa(const uint8_t *addr)
{
return (addr[5] & 0xc0) == 0;
}

static uint16_t
ble_gap_ext_adv_remaining_duration(uint8_t instance)
{
ble_npl_time_t elapsed_ticks;
uint32_t elapsed_ms;
uint32_t elapsed_units;

if (ble_gap_slave[instance].adv_duration == 0) {
return 0;
}

elapsed_ticks = ble_npl_time_get() - ble_gap_slave[instance].adv_start_time;
elapsed_ms = ble_npl_time_ticks_to_ms32(elapsed_ticks);
elapsed_units = elapsed_ms / 10;

if (elapsed_units >= ble_gap_slave[instance].adv_duration) {
return 1;
}

return ble_gap_slave[instance].adv_duration - elapsed_units;
}

static int
ble_gap_ext_adv_nrpa_rotate(uint8_t instance, const uint8_t *addr)
{
uint16_t duration;
uint8_t max_events;
int rc;

duration = ble_gap_ext_adv_remaining_duration(instance);
max_events = ble_gap_slave[instance].adv_max_events;

rc = ble_gap_ext_adv_stop_no_lock(instance);
if (rc != 0) {
return rc;
}

rc = ble_gap_ext_adv_set_addr_no_lock(instance, addr);
if (rc != 0) {
return rc;
}

rc = ble_gap_ext_adv_start(instance, duration, max_events);
if (rc != 0) {
return rc;
}

return 0;
}

static void
ble_gap_ext_adv_nrpa_set_exp(uint8_t instance)
{
ble_npl_time_t timeout_ticks;
uint32_t timeout_ms;
int rc;

timeout_ms = MYNEWT_VAL(BLE_RPA_TIMEOUT) * 1000UL;

rc = ble_npl_time_ms_to_ticks(timeout_ms, &timeout_ticks);
BLE_HS_DBG_ASSERT_EVAL(rc == 0);

ble_gap_slave[instance].nrpa_exp_os_ticks = ble_npl_time_get() + timeout_ticks;
ble_gap_slave[instance].nrpa_exp_set = 1;
ble_hs_timer_resched();
}

static void
ble_gap_ext_adv_nrpa_clear_exp(uint8_t instance)
{
ble_gap_slave[instance].nrpa_exp_set = 0;
ble_hs_timer_resched();
}

static uint32_t
ble_gap_ext_adv_nrpa_timer(void)
{
ble_npl_stime_t ticks;
uint32_t min_ticks;
ble_addr_t addr;
int rc;
int i;

min_ticks = BLE_HS_FOREVER;

for (i = 0; i < BLE_ADV_INSTANCES; i++) {
if (ble_gap_slave[i].op != BLE_GAP_OP_S_ADV ||
!ble_gap_slave[i].rnd_addr_set || !ble_gap_slave[i].nrpa_exp_set ||
!ble_gap_ext_adv_rnd_addr_is_nrpa(ble_gap_slave[i].rnd_addr)) {
continue;
}

ticks = ble_gap_slave[i].nrpa_exp_os_ticks - ble_npl_time_get();
if (ticks > 0) {
min_ticks = min(min_ticks, ticks);
continue;
}

rc = ble_hs_id_gen_rnd(1, &addr);
if (rc != 0) {
min_ticks = min(min_ticks, ble_npl_time_ms_to_ticks32(
BLE_GAP_CANCEL_RETRY_TIMEOUT_MS));
continue;
}

rc = ble_gap_ext_adv_nrpa_rotate(i, addr.val);
if (rc != 0) {
min_ticks = min(min_ticks, ble_npl_time_ms_to_ticks32(
BLE_GAP_CANCEL_RETRY_TIMEOUT_MS));
continue;
}

ble_gap_ext_adv_nrpa_set_exp(i);
ticks = ble_gap_slave[i].nrpa_exp_os_ticks - ble_npl_time_get();
min_ticks = min(min_ticks, ticks);
}

return min_ticks;
}
#endif
#endif

Expand Down Expand Up @@ -2385,6 +2521,10 @@ ble_gap_timer(void)
min_ticks = min(min_ticks, ble_gap_slave_timer());
#endif

#if NIMBLE_BLE_ADVERTISE && MYNEWT_VAL(BLE_EXT_ADV)
min_ticks = min(min_ticks, ble_gap_ext_adv_nrpa_timer());
#endif

return min_ticks;
}

Expand Down Expand Up @@ -3427,6 +3567,13 @@ ble_gap_ext_adv_set_addr_no_lock(uint8_t instance, const uint8_t *addr)
ble_gap_slave[instance].rnd_addr_set = 1;
memcpy(ble_gap_slave[instance].rnd_addr, addr, 6);

if (ble_gap_ext_adv_rnd_addr_is_nrpa(addr) &&
ble_gap_slave[instance].op == BLE_GAP_OP_S_ADV) {
ble_gap_ext_adv_nrpa_set_exp(instance);
} else if (!ble_gap_ext_adv_rnd_addr_is_nrpa(addr)) {
ble_gap_ext_adv_nrpa_clear_exp(instance);
}

return 0;
}

Expand Down Expand Up @@ -3548,8 +3695,18 @@ ble_gap_ext_adv_start(uint8_t instance, int duration, int max_events)
}

ble_gap_slave[instance].op = BLE_GAP_OP_S_ADV;
ble_gap_slave[instance].adv_start_time = ble_npl_time_get();
ble_gap_slave[instance].adv_duration = duration;
ble_gap_slave[instance].adv_max_events = max_events;

if (ble_gap_slave[instance].rnd_addr_set &&
ble_gap_ext_adv_rnd_addr_is_nrpa(ble_gap_slave[instance].rnd_addr)) {
ble_gap_ext_adv_nrpa_set_exp(instance);
} else {
ble_gap_ext_adv_nrpa_clear_exp(instance);
}
ble_hs_unlock();

return 0;
}

Expand Down Expand Up @@ -3584,6 +3741,7 @@ ble_gap_ext_adv_stop_no_lock(uint8_t instance)
}

ble_gap_slave[instance].op = BLE_GAP_OP_NULL;
ble_gap_ext_adv_nrpa_clear_exp(instance);

if (!active) {
return BLE_HS_EALREADY;
Expand Down
Loading