1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
RIOT/pkg/nimble/netif/nimble_netif_conn.c
2019-12-18 17:05:48 +01:00

206 lines
4.9 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.
*/
/**
* @ingroup pkg_nimble_netif_conn
* @{
*
* @file
* @brief Connection context handling for NimBLE netif
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*
* @}
*/
#include "nimble_netif_conn.h"
#define ENABLE_DEBUG (0)
#include "debug.h"
#define CONN_CNT (NIMBLE_NETIF_MAX_CONN)
static mutex_t _lock = MUTEX_INIT;
static nimble_netif_conn_t _conn[CONN_CNT];
static int _find_by_state(uint16_t filter)
{
for (unsigned i = 0; i < CONN_CNT; i++) {
if (_conn[i].state & filter) {
return (int)i;
}
}
return NIMBLE_NETIF_CONN_INVALID;
}
void nimble_netif_conn_init(void)
{
DEBUG("conn_init\n");
memset(_conn, 0, sizeof(_conn));
for (unsigned i = 0; i < CONN_CNT; i++) {
_conn[i].state = NIMBLE_NETIF_UNUSED;
}
}
nimble_netif_conn_t *nimble_netif_conn_get(int handle)
{
if ((handle < 0) || (handle >= CONN_CNT)) {
return NULL;
}
return &_conn[handle];
}
int nimble_netif_conn_get_adv(void)
{
int handle;
DEBUG("nimble_netif_conn_get_adv\n");
mutex_lock(&_lock);
handle = _find_by_state(NIMBLE_NETIF_ADV);
mutex_unlock(&_lock);
return handle;
}
int nimble_netif_conn_get_connecting(void)
{
int handle;
DEBUG("nimble_netif_conn_get_connecting\n");
mutex_lock(&_lock);
handle = _find_by_state(NIMBLE_NETIF_CONNECTING);
mutex_unlock(&_lock);
DEBUG("nimble_netif_conn_get_connecting - handle %i\n", handle);
return handle;
}
int nimble_netif_conn_get_by_addr(const uint8_t *addr)
{
assert(addr);
int handle = NIMBLE_NETIF_CONN_INVALID;
DEBUG("nimble_netif_conn_get_by_addr %02x\n", (int)addr[0]);
mutex_lock(&_lock);
for (unsigned i = 0; i < CONN_CNT; i++) {
if ((_conn[i].state & NIMBLE_NETIF_L2CAP_CONNECTED) &&
memcmp(_conn[i].addr, addr, BLE_ADDR_LEN) == 0) {
handle = (int)i;
break;
}
}
mutex_unlock(&_lock);
DEBUG("nimble_netif_conn_get_by_addr - found handle: %i\n", handle);
return handle;
}
int nimble_netif_conn_get_by_gaphandle(uint16_t gaphandle)
{
int handle = NIMBLE_NETIF_CONN_INVALID;
DEBUG("nimble_netif_conn_get_by_gaphandle %i\n", (int)gaphandle);
mutex_lock(&_lock);
for (unsigned i = 0; i < CONN_CNT; i++) {
if (_conn[i].gaphandle == gaphandle) {
handle = (int)i;
break;
}
}
mutex_unlock(&_lock);
DEBUG("nimble_netif_conn_get_by_gaphandle - found %i\n", handle);
return handle;
}
int nimble_netif_conn_start_connection(const uint8_t *addr)
{
int handle;
DEBUG("nimble_netif_conn_start_connection, addr %02x\n", (int)addr[0]);
mutex_lock(&_lock);
handle = _find_by_state(NIMBLE_NETIF_UNUSED);
if (handle != NIMBLE_NETIF_CONN_INVALID) {
_conn[handle].state = NIMBLE_NETIF_CONNECTING;
memcpy(_conn[handle].addr, addr, BLE_ADDR_LEN);
}
mutex_unlock(&_lock);
return handle;
}
int nimble_netif_conn_start_adv(void)
{
int handle;
DEBUG("nimble_netif_conn_start_adv\n");
mutex_lock(&_lock);
handle = _find_by_state(NIMBLE_NETIF_ADV);
if (handle != NIMBLE_NETIF_CONN_INVALID) {
handle = NIMBLE_NETIF_BUSY;
}
else {
handle = _find_by_state(NIMBLE_NETIF_UNUSED);
if (handle != NIMBLE_NETIF_CONN_INVALID) {
_conn[handle].state = NIMBLE_NETIF_ADV;
}
else {
handle = NIMBLE_NETIF_NOMEM;
}
}
mutex_unlock(&_lock);
return handle;
}
void nimble_netif_conn_free(int handle, uint8_t *addr)
{
assert((handle >= 0) && (handle < CONN_CNT));
DEBUG("nimble_netif_conn_free, handle %i\n", handle);
mutex_lock(&_lock);
if (addr) {
memcpy(addr, _conn[handle].addr, BLE_ADDR_LEN);
}
memset(&_conn[handle], 0, sizeof(nimble_netif_conn_t));
_conn[handle].state = NIMBLE_NETIF_UNUSED;
mutex_unlock(&_lock);
}
void nimble_netif_conn_foreach(uint16_t filter,
nimble_netif_conn_iter_t cb, void *arg)
{
assert(cb);
DEBUG("nimble_netif_conn_foreach 0x%04x\n", (int)filter);
mutex_lock(&_lock);
for (unsigned i = 0; i < CONN_CNT; i++) {
if (_conn[i].state & filter) {
int res = cb(&_conn[i], (int)i, arg);
if (res != 0) {
break;
}
}
}
mutex_unlock(&_lock);
}
unsigned nimble_netif_conn_count(uint16_t filter)
{
unsigned cnt = 0;
DEBUG("nimble_netif_conn_count, filter 0x%04x\n", (int)filter);
mutex_lock(&_lock);
for (unsigned i = 0; i < CONN_CNT; i++) {
if (_conn[i].state & filter) {
++cnt;
}
}
mutex_unlock(&_lock);
return cnt;
}