1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
RIOT/pkg/nimble/rpble/include/nimble_rpble.h
2022-01-27 10:30:30 +01:00

183 lines
6.7 KiB
C

/*
* 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 <hauke.petersen@fu-berlin.de>
*/
#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 */
nimble_phy_t phy_mode; /**< BLE PHY mode to use */
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 */
/** @} */