mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
250 lines
9.2 KiB
C
250 lines
9.2 KiB
C
/*
|
|
* Copyright (C) 2018-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.
|
|
*/
|
|
|
|
/**
|
|
* @defgroup pkg_nimble_netif GNRC netif Implementation
|
|
* @ingroup pkg_nimble
|
|
* @brief GNRC netif implementation for NimBLE, enabling the integration
|
|
* of NimBLE into GNRC
|
|
*
|
|
* # About
|
|
* This NimBLE submodule provides a GNRC netif wrapper for integrating NimBLE
|
|
* with GNRC and other network stacks using netif (e.g. CCNlite).
|
|
*
|
|
* # Concept
|
|
* According to the IPv6-over-BLE standards (RFC7668 and IPSP), this module
|
|
* exposes a (configurable) number of point-to-point BLE connections as a single
|
|
* network device to BLE. Unicast traffic is only send using the corresponding
|
|
* BLE connection. Multicast and Broadcast packets are duplicated and send via
|
|
* each open BLE connection.
|
|
*
|
|
* # Structure
|
|
* The netif implementation is able to handle multiple connections
|
|
* simultaneously. The maximum number of concurrent connections is configured
|
|
* during compile time, using NimBLEs MYNEWT_VAL_BLE_MAX_CONNECTIONS option.
|
|
* Dependent on this value, the netif implementation takes care of allocation
|
|
* all the memory needed. The API of this submodule uses simply integer values
|
|
* to reference the used connection context (like file descriptors in linux).
|
|
*
|
|
* Like any other GNRC network device, the NimBLE netif wrapper runs in its own
|
|
* thread. This thread is started and configured by the common netif code. All
|
|
* send and get/set operations are handled by this thread. For efficiency
|
|
* reasons, receiving of data is however handled completely in the NimBLE host
|
|
* thread, from where the received data is directly passed on to the
|
|
* corresponding GNRC thread.
|
|
*
|
|
* Although the wrapper hooks into GNRC using the netif interface, it does need
|
|
* to implement parts of the netdev interface as well. This is done where
|
|
* needed.
|
|
*
|
|
* # Usage
|
|
* This submodule is designed to work fully asynchronous, in the same way as the
|
|
* NimBLE interfaces are designed. All functions in this submodule will only
|
|
* trigger the intended action. Once this action is complete, the module will
|
|
* report the result asynchronously using the configured callback.
|
|
*
|
|
* So before using this module, make sure to register a callback using the
|
|
* @ref nimble_netif_eventcb() function.
|
|
*
|
|
* After this, this module provides functions for managing BLE connections to
|
|
* other devices. Once these connections are established, this module takes care
|
|
* of mapping IP packets to the corresponding connections.
|
|
*
|
|
* @{
|
|
*
|
|
* @file
|
|
* @brief GNRC netif implementation for NimBLE
|
|
*
|
|
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
|
*/
|
|
|
|
#ifndef NIMBLE_NETIF_H
|
|
#define NIMBLE_NETIF_H
|
|
|
|
#include <stdint.h>
|
|
|
|
#include "net/ble.h"
|
|
|
|
#include "host/ble_hs.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/**
|
|
* @brief The maximum number of BLE connections that can be open concurrently
|
|
*
|
|
* @note This value *must* be <= MYNEWT_VAL_BLE_MAX_CONNECTIONS
|
|
*/
|
|
#ifndef NIMBLE_NETIF_MAX_CONN
|
|
#define NIMBLE_NETIF_MAX_CONN (MYNEWT_VAL_BLE_MAX_CONNECTIONS)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Default L2CAP channel ID to use
|
|
*/
|
|
#ifndef NIMBLE_NETIF_CID
|
|
#define NIMBLE_NETIF_CID (BLE_L2CAP_CID_IPSP)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Default MTU size supported by the NimBLE netif wrapper
|
|
*/
|
|
/* NOTE: We do not use the @ref IPV6_MIN_MTU define here, as the iov6.h header
|
|
pulls in some other RIOT headers that clash with NimBLE header (e.g.
|
|
* byteorder.h vs. endian.h) */
|
|
#ifndef NIMBLE_NETIF_MTU
|
|
#define NIMBLE_NETIF_MTU (1280U)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Return codes used by the NimBLE netif module
|
|
*/
|
|
enum {
|
|
NIMBLE_NETIF_OK = 0, /**< everything went fine */
|
|
NIMBLE_NETIF_NOTCONN = -1, /**< not connected */
|
|
NIMBLE_NETIF_DEVERR = -2, /**< internal BLE stack error */
|
|
NIMBLE_NETIF_BUSY = -3, /**< network device is busy */
|
|
NIMBLE_NETIF_NOMEM = -4, /**< insufficient memory */
|
|
NIMBLE_NETIF_NOTADV = -5, /**< not advertising */
|
|
NIMBLE_NETIF_NOTFOUND = -6, /**< no fitting entry found */
|
|
};
|
|
|
|
/**
|
|
* @brief Event types triggered by the NimBLE netif module
|
|
*/
|
|
typedef enum {
|
|
NIMBLE_NETIF_ACCEPTING, /**< accepting incoming connections */
|
|
NIMBLE_NETIF_ACCEPT_STOP, /**< stop accepting incoming connections */
|
|
NIMBLE_NETIF_INIT_MASTER, /**< conn. procedure started (as mater) */
|
|
NIMBLE_NETIF_INIT_SLAVE, /**< conn. procedure started (as slave) */
|
|
NIMBLE_NETIF_CONNECTED_MASTER, /**< connection established as master */
|
|
NIMBLE_NETIF_CONNECTED_SLAVE, /**< connection established as slave */
|
|
NIMBLE_NETIF_CLOSED_MASTER, /**< connection closed (we were master) */
|
|
NIMBLE_NETIF_CLOSED_SLAVE, /**< connection closed (we were slave) */
|
|
NIMBLE_NETIF_ABORT_MASTER, /**< connection est. abort (as master) */
|
|
NIMBLE_NETIF_ABORT_SLAVE, /**< connection est. abort (as slave) */
|
|
NIMBLE_NETIF_CONN_UPDATED, /**< connection parameter update done */
|
|
} nimble_netif_event_t;
|
|
|
|
/**
|
|
* @brief Flags describing the state of a single connection context
|
|
*/
|
|
enum {
|
|
NIMBLE_NETIF_L2CAP_CLIENT = 0x0001, /**< L2CAP client */
|
|
NIMBLE_NETIF_L2CAP_SERVER = 0x0002, /**< L2CAP server */
|
|
NIMBLE_NETIF_L2CAP_CONNECTED = 0x0003, /**< L2CAP is connected */
|
|
NIMBLE_NETIF_GAP_MASTER = 0x0010, /**< GAP master */
|
|
NIMBLE_NETIF_GAP_SLAVE = 0x0020, /**< GAP slave */
|
|
NIMBLE_NETIF_GAP_CONNECTED = 0x0030, /**< GAP is connected */
|
|
NIMBLE_NETIF_ADV = 0x0100, /**< currently advertising */
|
|
NIMBLE_NETIF_CONNECTING = 0x4000, /**< connection in progress */
|
|
NIMBLE_NETIF_UNUSED = 0x8000, /**< context unused */
|
|
NIMBLE_NETIF_ANY = 0xffff, /**< match any state */
|
|
};
|
|
|
|
/**
|
|
* @brief Event callback signature used for asynchronous event signaling
|
|
*
|
|
* @note The event callback is always executed in NimBLE's host thread
|
|
*
|
|
* @param[in] handle handle to the connection that triggered the event
|
|
* @param[in] event type of the event
|
|
* @param[in] addr BLE address of the peer in the effected connection
|
|
*/
|
|
typedef void(*nimble_netif_eventcb_t)(int handle,
|
|
nimble_netif_event_t event,
|
|
const uint8_t *addr);
|
|
|
|
/**
|
|
* @brief Initialize the netif implementation, spawns the netif thread
|
|
*
|
|
* This function is meant to be called once during system initialization, i.e.
|
|
* auto-init.
|
|
*/
|
|
void nimble_netif_init(void);
|
|
|
|
/**
|
|
* @brief Register a global event callback, servicing all NimBLE connections
|
|
*
|
|
* @note The event callback is always executed in NimBLE's host thread
|
|
*
|
|
* @param[in] cb event callback to register, may be NULL
|
|
*/
|
|
void nimble_netif_eventcb(nimble_netif_eventcb_t cb);
|
|
|
|
/**
|
|
* @brief Open a BLE connection as BLE master
|
|
*
|
|
* @param[in] addr address of the advertising BLE slave, in the NimBLE
|
|
* addr format (little endian)
|
|
* @param[in] conn_params connection (timing) parameters
|
|
* @param[in] timeout connect timeout
|
|
*
|
|
* @return the used connection handle on success
|
|
* @return NIMBLE_NETIF_BUSY if already connected to the given address or if
|
|
* a connection setup procedure is in progress
|
|
* @return NIMBLE_NETIF_NOMEM if no connection context memory is available
|
|
*/
|
|
int nimble_netif_connect(const ble_addr_t *addr,
|
|
const struct ble_gap_conn_params *conn_params,
|
|
uint32_t timeout);
|
|
|
|
/**
|
|
* @brief Close the connection with the given handle
|
|
*
|
|
* @param[in] handle handle for the connection to be closed
|
|
*
|
|
* @return NIMBLE_NETIF_OK on success
|
|
* @return NIMBLE_NETIF_NOTFOUND if the handle is invalid
|
|
* @return NIMBLE_NETIF_NOTCONN if context for given handle is not connected
|
|
*/
|
|
int nimble_netif_close(int handle);
|
|
|
|
/**
|
|
* @brief Accept incoming connections by starting to advertise this node
|
|
*
|
|
* @param[in] ad advertising data (in BLE AD format)
|
|
* @param[in] ad_len length of @p ad in bytes
|
|
* @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(const uint8_t *ad, size_t ad_len,
|
|
const struct ble_gap_adv_params *adv_params);
|
|
|
|
/**
|
|
* @brief Stop accepting incoming connections (stop advertising)
|
|
* *
|
|
* @return NIMBLE_NETIF_OK on success
|
|
* @return NIMBLE_NETIF_NOTADV if not currently advertising
|
|
*/
|
|
int nimble_netif_accept_stop(void);
|
|
|
|
/**
|
|
* @brief Update the connection parameters for the given connection
|
|
*
|
|
* @param[in] handle connection handle
|
|
* @param[in] conn_params new connection parameters to apply
|
|
*
|
|
* @return NIMBLE_NETIF_OK on success
|
|
* @return NIMBLE_NETIF_NOTCONN if handle does not point to a connection
|
|
* @return NIMBLE_NETIF_DEVERR if applying the given parameters failed
|
|
*/
|
|
int nimble_netif_update(int handle,
|
|
const struct ble_gap_upd_params *conn_params);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* NIMBLE_NETIF_H */
|
|
/** @} */
|