sys/nimble_autoadv: add new module
module for automated bluetooth advertising
This commit is contained in:
parent
54e8069110
commit
fe4f0a69ee
@ -77,6 +77,9 @@ nimble_drivers_nrf5x:
|
||||
nimble_addr:
|
||||
"$(MAKE)" -C $(TDIR)/addr/
|
||||
|
||||
nimble_autoadv:
|
||||
"$(MAKE)" -C $(TDIR)/autoadv
|
||||
|
||||
nimble_autoconn:
|
||||
"$(MAKE)" -C $(TDIR)/autoconn
|
||||
|
||||
|
||||
@ -39,6 +39,10 @@ ifneq (,$(filter nimble_addr,$(USEMODULE)))
|
||||
USEMODULE += bluetil_addr
|
||||
endif
|
||||
|
||||
ifneq (,$(filter nimble_autoadv,$(USEMODULE)))
|
||||
USEMODULE += bluetil_ad
|
||||
endif
|
||||
|
||||
ifneq (,$(filter nimble_autoconn_%,$(USEMODULE)))
|
||||
USEMODULE += nimble_autoconn
|
||||
endif
|
||||
|
||||
@ -76,6 +76,9 @@ endif
|
||||
ifneq (,$(filter nimble_addr,$(USEMODULE)))
|
||||
INCLUDES += -I$(RIOTPKG)/nimble/addr/include
|
||||
endif
|
||||
ifneq (,$(filter nimble_autoadv,$(USEMODULE)))
|
||||
INCLUDES += -I$(RIOTPKG)/nimble/autoadv/include
|
||||
endif
|
||||
ifneq (,$(filter nimble_autoconn,$(USEMODULE)))
|
||||
INCLUDES += -I$(RIOTPKG)/nimble/autoconn/include
|
||||
endif
|
||||
|
||||
3
pkg/nimble/autoadv/Makefile
Normal file
3
pkg/nimble/autoadv/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
MODULE = nimble_autoadv
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
28
pkg/nimble/autoadv/README.md
Normal file
28
pkg/nimble/autoadv/README.md
Normal file
@ -0,0 +1,28 @@
|
||||
# NimBLE automated advertisements
|
||||
|
||||
Module for automated bluetooth advertising. Advertising is restarted on
|
||||
disconnect events automatically. Defaults to the following characteristics:
|
||||
- General discoverable mode (BLE_GAP_DISC_MODE_GEN)
|
||||
- Undirected connectable mode (BLE_GAP_CONN_MODE_UND)
|
||||
- No expiration (BLE_HS_FOREVER)
|
||||
- No name
|
||||
|
||||
It can be enabled by adding
|
||||
```
|
||||
USEMODULE += nimble_autoadv
|
||||
```
|
||||
to your makefile.
|
||||
|
||||
If your application is calling functions from nimble, e.g.
|
||||
ble_svc_gap_device_name_set(), NIMBLE_AUTOADV_START_MANUALLY should be set to 1
|
||||
with the following line in your Makefile:
|
||||
```
|
||||
CFLAGS += -DNIMBLE_AUTOADV_START_MANUALLY=1
|
||||
```
|
||||
Then the application should call nimble_autoadv_adv_start() after all of its
|
||||
nimble calls to prevent errors like BLE_HS_EBUSY.
|
||||
|
||||
To specify a device name add the following line to your Makefile:
|
||||
```
|
||||
CFLAGS += -DNIMBLE_AUTOADV_DEVICE_NAME='"Riot OS device"'
|
||||
```
|
||||
142
pkg/nimble/autoadv/include/nimble_autoadv.h
Normal file
142
pkg/nimble/autoadv/include/nimble_autoadv.h
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Freie Universität Berlin
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup pkg_nimble_autoadv Automated advertising
|
||||
* @ingroup pkg_nimble
|
||||
*
|
||||
* @brief Module for automated bluetooth advertising. Advertising is
|
||||
* restarted on disconnect events automatically. Defaults to the
|
||||
* following characteristics:
|
||||
* - General discoverable mode (BLE_GAP_DISC_MODE_GEN)
|
||||
* - Undirected connectable mode (BLE_GAP_CONN_MODE_UND)
|
||||
* - No expiration (BLE_HS_FOREVER)
|
||||
* - No name
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
*
|
||||
* @author Hendrik van Essen <hendrik.ve@fu-berlin.de>
|
||||
*/
|
||||
|
||||
#ifndef NIMBLE_AUTOADV_H
|
||||
#define NIMBLE_AUTOADV_H
|
||||
|
||||
#include "host/ble_gap.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Name of the device for the advertising procedure. If this is not
|
||||
* defined, it will be defined as NULL, resulting in not configuring
|
||||
* a name at all.
|
||||
*/
|
||||
#ifndef NIMBLE_AUTOADV_DEVICE_NAME
|
||||
#define NIMBLE_AUTOADV_DEVICE_NAME NULL
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief If an application is calling functions from nimble, e.g.
|
||||
* ble_svc_gap_device_name_set(), NIMBLE_AUTOADV_START_MANUALLY should
|
||||
* be set to 1 and then the application should call
|
||||
* nimble_autoadv_start() after all of its nimble calls to prevent
|
||||
* errors like BLE_HS_EBUSY.
|
||||
*
|
||||
* Defined as 0 by default.
|
||||
*/
|
||||
#ifndef NIMBLE_AUTOADV_START_MANUALLY
|
||||
#define NIMBLE_AUTOADV_START_MANUALLY 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Initialize autoadv module.
|
||||
*/
|
||||
void nimble_autoadv_init(void);
|
||||
|
||||
/**
|
||||
* @brief Set struct for additional arguments specifying the particulars of
|
||||
* the advertising procedure. Uses memcpy internally.
|
||||
*
|
||||
* If there is an active advertising process, it will be restarted.
|
||||
*
|
||||
* @param[in] params struct with customized additional arguments
|
||||
*/
|
||||
void nimble_autoadv_set_ble_gap_adv_params(struct ble_gap_adv_params *params);
|
||||
|
||||
/**
|
||||
* @brief Add a new field to the given advertising data.
|
||||
*
|
||||
* If there is an active advertising process, it will be restarted.
|
||||
*
|
||||
* @param[in] type field type to add
|
||||
* @param[in] data payload for the field
|
||||
* @param[in] data_len length of the payload in bytes
|
||||
*
|
||||
* @return BLUETIL_AD_OK if the new field was added
|
||||
* @return BLUETIL_AD_NOMEM if there is not enough space to write add field
|
||||
*/
|
||||
int nimble_autoadv_add_field(uint8_t type, const void *data, size_t data_len);
|
||||
|
||||
/**
|
||||
* @brief Set the duration for the advertising procedure.
|
||||
*
|
||||
* If there is an active advertising process, it will be restarted.
|
||||
*
|
||||
* @param[in] duration_ms duration of advertising procedure in ms
|
||||
*/
|
||||
void nimble_auto_adv_set_adv_duration(int32_t duration_ms);
|
||||
|
||||
/**
|
||||
* @brief Set the callback for gap events. Callback is used for the logic when
|
||||
* to start the advertising procedure.
|
||||
*
|
||||
* If there is an active advertising process, it will be restarted.
|
||||
*
|
||||
* @param[in] cb The callback to associate with this advertising
|
||||
* procedure. If advertising ends, the event is reported
|
||||
* through this callback. If advertising results in a
|
||||
* connection, the connection inherits this callback as its
|
||||
* event-reporting mechanism.
|
||||
*
|
||||
* @param[in] cb_arg The optional argument to pass to the callback function.
|
||||
*/
|
||||
void nimble_auto_adv_set_gap_cb(ble_gap_event_fn *cb, void *cb_arg);
|
||||
|
||||
/**
|
||||
* @brief Start the automated advertising procedure.
|
||||
*
|
||||
* Needs to be called manually when NIMBLE_AUTOADV_START_MANUALLY was
|
||||
* set to true and after every call of nimble_autoadv_stop() to start
|
||||
* advertising again.
|
||||
*/
|
||||
void nimble_autoadv_start(void);
|
||||
|
||||
/**
|
||||
* @brief Stop the automated advertising procedure. After calling this, you
|
||||
* have to call nimble_autoadv_start() manually to restart the process.
|
||||
*/
|
||||
void nimble_autoadv_stop(void);
|
||||
|
||||
/**
|
||||
* @brief Reset all data regarding the advertising process.
|
||||
* Following characteristics will be applied:
|
||||
* - General discoverable mode (BLE_GAP_DISC_MODE_GEN)
|
||||
* - Undirected connectable mode (BLE_GAP_CONN_MODE_UND)
|
||||
* - No expiration (BLE_HS_FOREVER)
|
||||
* - No name
|
||||
*/
|
||||
void nimble_autoadv_reset(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/** @} */
|
||||
#endif /* NIMBLE_AUTOADV_H */
|
||||
174
pkg/nimble/autoadv/nimble_autoadv.c
Normal file
174
pkg/nimble/autoadv/nimble_autoadv.c
Normal file
@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Freie Universität Berlin
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup pkg_nimble_autoadv
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
*
|
||||
* @author Hendrik van Essen <hendrik.ve@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "nimble_riot.h"
|
||||
|
||||
#include "host/ble_hs.h"
|
||||
#include "host/ble_gap.h"
|
||||
#include "net/bluetil/ad.h"
|
||||
|
||||
#include "nimble_autoadv.h"
|
||||
|
||||
/* settings for advertising procedure */
|
||||
static struct ble_gap_adv_params _advp;
|
||||
|
||||
/* duration of the advertisement procedure */
|
||||
static int32_t _adv_duration;
|
||||
|
||||
/* buffer for _ad */
|
||||
static uint8_t buf[BLE_HS_ADV_MAX_SZ];
|
||||
|
||||
/* advertising data struct */
|
||||
static bluetil_ad_t _ad;
|
||||
|
||||
/* GAP callback function */
|
||||
static ble_gap_event_fn *_gap_cb;
|
||||
|
||||
/* arguments for GAP callback function */
|
||||
static void *_gap_cb_arg;
|
||||
|
||||
void nimble_autoadv_start(void);
|
||||
|
||||
static int _gap_event_cb(struct ble_gap_event *event, void *arg)
|
||||
{
|
||||
(void) arg;
|
||||
|
||||
switch (event->type) {
|
||||
|
||||
case BLE_GAP_EVENT_CONNECT:
|
||||
if (event->connect.status != 0) {
|
||||
// failed, ensure advertising is restarted
|
||||
nimble_autoadv_start();
|
||||
}
|
||||
break;
|
||||
|
||||
case BLE_GAP_EVENT_DISCONNECT:
|
||||
nimble_autoadv_start();
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void nimble_autoadv_init(void)
|
||||
{
|
||||
nimble_autoadv_reset();
|
||||
|
||||
if (!NIMBLE_AUTOADV_START_MANUALLY) {
|
||||
nimble_autoadv_start();
|
||||
}
|
||||
}
|
||||
|
||||
int nimble_autoadv_add_field(uint8_t type, const void *data, size_t data_len)
|
||||
{
|
||||
int rc = bluetil_ad_add(&_ad, type, data, data_len);
|
||||
|
||||
if (rc != BLUETIL_AD_OK) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (ble_gap_adv_active()) {
|
||||
nimble_autoadv_start();
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void nimble_autoadv_set_ble_gap_adv_params(struct ble_gap_adv_params *params)
|
||||
{
|
||||
memcpy(&_advp, params, sizeof(struct ble_gap_adv_params));
|
||||
|
||||
if (ble_gap_adv_active()) {
|
||||
nimble_autoadv_start();
|
||||
}
|
||||
}
|
||||
|
||||
void nimble_auto_adv_set_adv_duration(int32_t duration_ms)
|
||||
{
|
||||
_adv_duration = duration_ms;
|
||||
|
||||
if (ble_gap_adv_active()) {
|
||||
nimble_autoadv_start();
|
||||
}
|
||||
}
|
||||
|
||||
void nimble_auto_adv_set_gap_cb(ble_gap_event_fn *cb, void *cb_arg)
|
||||
{
|
||||
_gap_cb = cb;
|
||||
_gap_cb_arg = cb_arg;
|
||||
|
||||
if (ble_gap_adv_active()) {
|
||||
nimble_autoadv_start();
|
||||
}
|
||||
}
|
||||
|
||||
void nimble_autoadv_start(void)
|
||||
{
|
||||
int rc;
|
||||
(void) rc;
|
||||
|
||||
rc = ble_gap_adv_stop();
|
||||
assert(rc == BLE_HS_EALREADY || rc == 0);
|
||||
|
||||
rc = ble_gap_adv_set_data(_ad.buf, _ad.pos);
|
||||
assert(rc == 0);
|
||||
|
||||
rc = ble_gap_adv_start(nimble_riot_own_addr_type, NULL, _adv_duration, &_advp, _gap_cb, _gap_cb_arg);
|
||||
assert(rc == 0);
|
||||
}
|
||||
|
||||
void nimble_autoadv_stop(void)
|
||||
{
|
||||
int rc;
|
||||
(void) rc;
|
||||
|
||||
rc = ble_gap_adv_stop();
|
||||
assert(rc == BLE_HS_EALREADY || rc == 0);
|
||||
}
|
||||
|
||||
void nimble_autoadv_reset(void)
|
||||
{
|
||||
_gap_cb = &_gap_event_cb;
|
||||
_gap_cb_arg = NULL;
|
||||
|
||||
_adv_duration = BLE_HS_FOREVER;
|
||||
|
||||
memset(&_advp, 0, sizeof _advp);
|
||||
_advp.conn_mode = BLE_GAP_CONN_MODE_UND;
|
||||
_advp.disc_mode = BLE_GAP_DISC_MODE_GEN;
|
||||
|
||||
int rc = 0;
|
||||
(void) rc;
|
||||
|
||||
rc = bluetil_ad_init_with_flags(&_ad, buf, sizeof(buf), BLUETIL_AD_FLAGS_DEFAULT);
|
||||
assert(rc == BLUETIL_AD_OK);
|
||||
|
||||
if (NIMBLE_AUTOADV_DEVICE_NAME != NULL) {
|
||||
rc = bluetil_ad_add_name(&_ad, NIMBLE_AUTOADV_DEVICE_NAME);
|
||||
assert(rc == BLUETIL_AD_OK);
|
||||
}
|
||||
|
||||
if (ble_gap_adv_active()) {
|
||||
nimble_autoadv_start();
|
||||
}
|
||||
}
|
||||
@ -145,4 +145,9 @@ void nimble_riot_init(void)
|
||||
assert(res == NIMBLE_AUTOCONN_OK);
|
||||
nimble_autoconn_enable();
|
||||
#endif
|
||||
|
||||
#ifdef MODULE_NIMBLE_AUTOADV
|
||||
extern void nimble_autoadv_init(void);
|
||||
nimble_autoadv_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user