diff --git a/pkg/nimble/netif/include/nimble_netif.h b/pkg/nimble/netif/include/nimble_netif.h index fd4b7927fd..b7acbf0fd1 100644 --- a/pkg/nimble/netif/include/nimble_netif.h +++ b/pkg/nimble/netif/include/nimble_netif.h @@ -253,6 +253,22 @@ int nimble_netif_close(int handle); int nimble_netif_accept(const uint8_t *ad, size_t ad_len, const struct ble_gap_adv_params *adv_params); +/** + * @brief Wait for an incoming connection from a specific peer, sending + * directed advertisements (IND_DIR) + * + * @param[in] addr BLE address of the target peer + * @param[in] timeout_ms stop advertising after this time (in ms), set to + * BLE_HS_FOREVER to disable timeout + * @param[in] adv_params advertising (timing) parameters to use + * + * @return NIMBLE_NETIF_OK on success + * @return NIMBLE_NETIF_BUSY if already advertising + * @return NIMBLE_NETIF_NOMEM on insufficient connection memory + */ +int nimble_netif_accept_direct(const ble_addr_t *addr, uint32_t timeout_ms, + const struct ble_gap_adv_params *adv_params); + /** * @brief Stop accepting incoming connections (stop advertising) * * diff --git a/pkg/nimble/netif/nimble_netif.c b/pkg/nimble/netif/nimble_netif.c index 0a2b70a82a..9d4e56959a 100644 --- a/pkg/nimble/netif/nimble_netif.c +++ b/pkg/nimble/netif/nimble_netif.c @@ -531,6 +531,11 @@ static int _on_gap_slave_evt(struct ble_gap_event *event, void *arg) case BLE_GAP_EVENT_CONN_UPDATE_REQ: /* nothing to do here */ break; + case BLE_GAP_EVENT_ADV_COMPLETE: { + uint8_t addr[BLE_ADDR_LEN]; + nimble_netif_conn_free(handle, addr); + _notify(handle, NIMBLE_NETIF_ACCEPT_STOP, addr); + } default: break; } @@ -634,10 +639,10 @@ int nimble_netif_close(int handle) return NIMBLE_NETIF_OK; } -int nimble_netif_accept(const uint8_t *ad, size_t ad_len, - const struct ble_gap_adv_params *adv_params) +static int _accept(const uint8_t *ad, size_t ad_len, const ble_addr_t *addr, + uint32_t timeout, + const struct ble_gap_adv_params *adv_params) { - assert(ad); assert(adv_params); int handle; @@ -651,10 +656,18 @@ int nimble_netif_accept(const uint8_t *ad, size_t ad_len, } /* set advertisement data */ - res = ble_gap_adv_set_data(ad, (int)ad_len); - assert(res == 0); + if (ad != NULL) { + res = ble_gap_adv_set_data(ad, (int)ad_len); + assert(res == 0); + } + /* remember address if applicable */ + if (addr) { + nimble_netif_conn_t *conn = nimble_netif_conn_get(handle); + bluetil_addr_swapped_cp(addr->val, conn->addr); + } + /* remember context and start advertising */ - res = ble_gap_adv_start(nimble_riot_own_addr_type, NULL, BLE_HS_FOREVER, + res = ble_gap_adv_start(nimble_riot_own_addr_type, addr, timeout, adv_params, _on_gap_slave_evt, (void *)handle); assert(res == 0); @@ -663,6 +676,20 @@ int nimble_netif_accept(const uint8_t *ad, size_t ad_len, return NIMBLE_NETIF_OK; } +int nimble_netif_accept(const uint8_t *ad, size_t ad_len, + const struct ble_gap_adv_params *adv_params) +{ + assert(ad != NULL); + assert(ad_len > 0); + return _accept(ad, ad_len, NULL, BLE_HS_FOREVER, adv_params); +} + +int nimble_netif_accept_direct(const ble_addr_t *addr, uint32_t timeout, + const struct ble_gap_adv_params *adv_params) +{ + return _accept(NULL, 0, addr, timeout, adv_params); +} + int nimble_netif_accept_stop(void) { int handle = nimble_netif_conn_get_adv();