-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #16364 from haukepetersen/add_nimble_rpble_pr
net/BLE: add support for RPL-over-BLE
- Loading branch information
Showing
14 changed files
with
823 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
MODULE = nimble_rpble | ||
|
||
include $(RIOTBASE)/Makefile.base |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
/* | ||
* Copyright (C) 2019-2021 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_rpble RPL-over-BLE for NimBLE | ||
* @ingroup pkg_nimble | ||
* @brief RPL-over-BLE for Nimble implementation | ||
* | ||
* # About | ||
* This module implements a BLE connection manager the manages BLE connections | ||
* for (multi-hop) IP over BLE networks based on meta data provided by RPL. | ||
* | ||
* | ||
* # Concept | ||
* In their initial state, after power up or reboot, nodes start to scan for | ||
* BLE advertisements containing a specific advertising data (AD) field which | ||
* holds information about RPL DODAGs. For a configured amount of time, the node | ||
* ranks all senders of the received advertising packets based on a given | ||
* metric. After this time, the node selects the best fitting parent based on | ||
* this ranking and tries to connect to that peer. | ||
* | ||
* After a node has successfully opened a connection to its parent node, the | ||
* node starts to advertise its own RPL context data to accept connections | ||
* from potential child nodes. | ||
* | ||
* This approach leads to a BLE network topology that is equal to the IP routing | ||
* topology created by RPL on top. | ||
* | ||
* ## Advertising data structure | ||
* To include RPL context information into (legacy) BLE advertisements, it must | ||
* be encoded into the BLE advertising data format. This implementation uses | ||
* a custom sub-format that is included into the 16-bit UUID Service Data | ||
* (type: 0x16) field (Supplement to Bluetooth Core Specification CSSv8, 1.11). | ||
* The 16-bit UUID in this field is set to the IPSS service ID (0x1820). | ||
* | ||
* The following sub-format is used to encode the RPL context data: | ||
* ``` | ||
* byte 1: instance ID (1b) | ||
* byte 2-17: DODAG ID (16b) | ||
* byte 18: DODAG version (1b) | ||
* byte 19: RPL role (1b) | ||
* byte 20-21: rank (2b) | ||
* byte 22: number of free BLE connection slots (1b) | ||
* ``` | ||
* | ||
* ## Ranking of potential parents | ||
* The currently implemented ranking metric is very simple: the potential parent | ||
* node with the smallest rank is chosen. Additionally, nodes advertise the | ||
* number of free BLE connection slots. In case where multiple nodes advertise | ||
* the same RPL rank, the one with the largest number of open BLE connection | ||
* slots is selected. The idea behind this is to balance the number of BLE | ||
* connections per node, and with that also to balance the RPL DODAG. | ||
* | ||
* | ||
* # Usage | ||
* To use this module, simply include `nimble_rpble` into your build. If nothing | ||
* is explicitly configured, the module will use the default configuration as | ||
* specified in `pkg/nimble/rpble/include/nimble_rpble_params.h`. | ||
* | ||
* Once a node is configured as RPL root (e.g. using the `rpl root ..` shell | ||
* command), it will automatically start to advertise itself. Non-RPL-root nodes | ||
* will automatically scan for potential parent nodes and join the network as | ||
* soon as they find fitting neighbors. | ||
* | ||
* | ||
* ## Implementation status | ||
* In its current state, the implementation only works for environments where a | ||
* single RPL network with a single DODAG are present. The DODAG ID, instance | ||
* ID, and DODAG version are currently pretty much ignored when scanning for | ||
* potential parents. | ||
* | ||
* @{ | ||
* | ||
* @file | ||
* @brief Interface for the nimble_rpble module | ||
* | ||
* @author Hauke Petersen <[email protected]> | ||
*/ | ||
|
||
#ifndef NIMBLE_RPBLE_H | ||
#define NIMBLE_RPBLE_H | ||
|
||
#include "nimble_netif.h" | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
/** | ||
* @brief rpble configuration parameters | ||
*/ | ||
typedef struct { | ||
uint32_t scan_itvl_ms; /**< scan interval when scanning for parents, | ||
* in ms */ | ||
uint32_t scan_win_ms; /**< scan window when scanning for parents, | ||
* in ms */ | ||
uint32_t adv_itvl_ms; /**< advertising interval used when advertising | ||
* RPL context to child nodes, in ms */ | ||
uint32_t conn_scan_itvl_ms; /**< scan interval when connecting to parent, | ||
* in ms */ | ||
uint32_t conn_scan_win_ms; /**< scan window when connecting to parent, in | ||
* ms */ | ||
uint32_t conn_scan_to_ms; /**< timeout when connecting to parent, in ms */ | ||
uint32_t conn_itvl_min_ms; /**< lower bound of connection interval range, | ||
* in ms */ | ||
uint32_t conn_itvl_max_ms; /**< upper bound of connection interval range, | ||
in ms */ | ||
uint16_t conn_latency; /**< used slave latency for parent connection */ | ||
uint32_t conn_super_to_ms; /**< used supervision timeout for parent | ||
* connection, in ms */ | ||
uint32_t eval_itvl_min_ms; /**< amount of time a node searches for | ||
* potential parents, lower bound in ms */ | ||
uint32_t eval_itvl_max_ms; /**< amount of time a node searches for | ||
* potential parents, upper bound in ms */ | ||
} nimble_rpble_cfg_t; | ||
|
||
/** | ||
* @brief RPL DODAG information | ||
*/ | ||
typedef struct { | ||
uint8_t inst_id; /**< instance ID */ | ||
uint8_t dodag_id[16]; /**< DODAG ID */ | ||
uint8_t version; /**< DODAG version */ | ||
uint8_t role; /**< RPL role of the node */ | ||
uint16_t rank; /**< the node's rank in the DODAG */ | ||
} nimble_rpble_ctx_t; | ||
|
||
/** | ||
* @brief Initialize the nimble_rpble module with the given parameters | ||
* | ||
* @note This function must be called only once, typically during system | ||
* initialization | ||
* | ||
* @param[in] cfg configuration parameters | ||
* | ||
* @return 0 on success | ||
*/ | ||
int nimble_rpble_init(const nimble_rpble_cfg_t *cfg); | ||
|
||
/** | ||
* @brief Update the used timing parameters | ||
* | ||
* @param[in] cfg configuration parameters | ||
* | ||
* @return 0 on success | ||
*/ | ||
int nimble_rpble_param_update(const nimble_rpble_cfg_t *cfg); | ||
|
||
/** | ||
* @brief Register a callback that is called on BLE events | ||
* | ||
* The registered callback function is a simple pass-through of nimble_netif | ||
* events. The callback is executed in the context of NimBLE's host thread. | ||
* | ||
* @param[in] cb event callback to register, set to NULL to remove | ||
*/ | ||
int nimble_rpble_eventcb(nimble_netif_eventcb_t cb); | ||
|
||
/** | ||
* @brief Update the current RPL context | ||
* | ||
* @note This function is meant to be called only by the RPL implementation | ||
* | ||
* @param[in] ctx current DODAG state | ||
* @return 0 on success | ||
* @return -EALREADY if the given context did not change | ||
*/ | ||
int nimble_rpble_update(const nimble_rpble_ctx_t *ctx); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif /* NIMBLE_RPBLE_H */ | ||
/** @} */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
/* | ||
* Copyright (C) 2019 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_rpble | ||
* | ||
* @{ | ||
* @file | ||
* @brief Default configuration for the nimble_netif_rpble module | ||
* | ||
* @author Hauke Petersen <[email protected]> | ||
*/ | ||
|
||
#ifndef NIMBLE_RPBLE_PARAMS_H | ||
#define NIMBLE_RPBLE_PARAMS_H | ||
|
||
#include "nimble_rpble.h" | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
/** | ||
* @name Default parameters used for the nimble_netif_rpble module | ||
* @{ | ||
*/ | ||
#ifndef NIMBLE_RPBLE_SCAN_ITVL_MS | ||
#define NIMBLE_RPBLE_SCAN_ITVL_MS 1200U | ||
#endif | ||
#ifndef NIMBLE_RPBLE_SCAN_WIN_MS | ||
#define NIMBLE_RPBLE_SCAN_WIN_MS 120U | ||
#endif | ||
|
||
#ifndef NIMBLE_RPBLE_ADV_ITVL_MS | ||
#define NIMBLE_RPBLE_ADV_ITVL_MS 100U | ||
#endif | ||
|
||
#ifndef NIMBLE_RPBLE_CONN_SCAN_ITVL_MS | ||
#define NIMBLE_RPBLE_CONN_SCAN_ITVL_MS 120U | ||
#endif | ||
#ifndef NIMBLE_RPBLE_CONN_SCAN_WIN_MS | ||
#define NIMBLE_RPBLE_CONN_SCAN_WIN_MS 120U | ||
#endif | ||
#ifndef NIMBLE_RPBLE_CONN_SCAN_TO_MS | ||
#define NIMBLE_RPBLE_CONN_SCAN_TO_MS 360U | ||
#endif | ||
#ifndef NIMBLE_RPBLE_CONN_ITVL_MIN_MS | ||
#define NIMBLE_RPBLE_CONN_ITVL_MIN_MS 90U | ||
#endif | ||
#ifndef NIMBLE_RPBLE_CONN_ITVL_MAX_MS | ||
#define NIMBLE_RPBLE_CONN_ITVL_MAX_MS 110U | ||
#endif | ||
#ifndef NIMBLE_RPBLE_CONN_LATENCY | ||
#define NIMBLE_RPBLE_CONN_LATENCY 0 | ||
#endif | ||
#ifndef NIMBLE_RPBLE_CONN_SUPER_TO_MS | ||
#define NIMBLE_RPBLE_CONN_SUPER_TO_MS 1650U | ||
#endif | ||
|
||
#ifndef NIMBLE_RPBLE_EVAL_ITVL_MIN_MS | ||
#define NIMBLE_RPBLE_EVAL_ITVL_MIN_MS 12000U | ||
#endif | ||
#ifndef NIMBLE_RPBLE_EVAL_ITVL_MAX_MS | ||
#define NIMBLE_RPBLE_EVAL_ITVL_MAX_MS 13000U | ||
#endif | ||
|
||
#ifndef NIMBLE_RPBLE_PARAMS | ||
#define NIMBLE_RPBLE_PARAMS \ | ||
{ .scan_itvl_ms = NIMBLE_RPBLE_SCAN_ITVL_MS, \ | ||
.scan_win_ms = NIMBLE_RPBLE_SCAN_WIN_MS, \ | ||
.adv_itvl_ms = NIMBLE_RPBLE_ADV_ITVL_MS, \ | ||
.conn_scan_itvl_ms = NIMBLE_RPBLE_CONN_SCAN_ITVL_MS, \ | ||
.conn_scan_win_ms = NIMBLE_RPBLE_CONN_SCAN_WIN_MS, \ | ||
.conn_scan_to_ms = NIMBLE_RPBLE_CONN_SCAN_TO_MS, \ | ||
.conn_itvl_min_ms = NIMBLE_RPBLE_CONN_ITVL_MIN_MS, \ | ||
.conn_itvl_max_ms = NIMBLE_RPBLE_CONN_ITVL_MAX_MS, \ | ||
.conn_latency = NIMBLE_RPBLE_CONN_LATENCY, \ | ||
.conn_super_to_ms = NIMBLE_RPBLE_CONN_SUPER_TO_MS, \ | ||
.eval_itvl_min_ms = NIMBLE_RPBLE_EVAL_ITVL_MIN_MS, \ | ||
.eval_itvl_max_ms = NIMBLE_RPBLE_EVAL_ITVL_MAX_MS } | ||
#endif | ||
/**@}*/ | ||
|
||
/** | ||
* @brief nimble_netif_rpble configuration | ||
*/ | ||
static const nimble_rpble_cfg_t nimble_rpble_params = NIMBLE_RPBLE_PARAMS; | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif /* NIMBLE_RPBLE_PARAMS_H */ | ||
/** @} */ |
Oops, something went wrong.