1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
RIOT/pkg/nimble/scanlist/nimble_scanlist.c
2021-12-02 23:31:33 +01:00

137 lines
3.3 KiB
C

/*
* 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_scanlist
* @{
*
* @file
* @brief Implementation of a list for NimBLE scan results
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*
* @}
*/
#include <assert.h>
#include <limits.h>
#include "ztimer.h"
#include "net/bluetil/ad.h"
#include "nimble_scanlist.h"
#define ENABLE_DEBUG 0
#include "debug.h"
static nimble_scanlist_entry_t _mem[NIMBLE_SCANLIST_SIZE];
static clist_node_t _pool;
static clist_node_t _list;
static int _finder(clist_node_t *node, void *arg)
{
const ble_addr_t *addr = (const ble_addr_t *)arg;
nimble_scanlist_entry_t *e = (nimble_scanlist_entry_t *)node;
if (ble_addr_cmp(&e->addr, addr) == 0) {
return 1;
}
return 0;
}
static nimble_scanlist_entry_t *_find(const ble_addr_t *addr)
{
return (nimble_scanlist_entry_t *)clist_foreach(&_list, _finder,
(void *)addr);
}
void nimble_scanlist_init(void)
{
for (unsigned i = 0; i < ARRAY_SIZE(_mem); i++) {
clist_rpush(&_pool, &_mem[i].node);
}
}
nimble_scanlist_entry_t *nimble_scanlist_get_by_pos(unsigned pos)
{
nimble_scanlist_entry_t *e = nimble_scanlist_get_next(NULL);
for (unsigned i = 0; (i < pos) && e; i++) {
e = nimble_scanlist_get_next(e);
}
return e;
}
void nimble_scanlist_update(uint8_t type, const ble_addr_t *addr,
const nimble_scanner_info_t *info,
const uint8_t *ad, size_t len)
{
assert(addr);
assert(len <= BLE_ADV_PDU_LEN);
uint32_t now = (uint32_t)ztimer_now(ZTIMER_USEC);
nimble_scanlist_entry_t *e = _find(addr);
if (!e) {
e = (nimble_scanlist_entry_t *)clist_lpop(&_pool);
if (!e) {
/* no space available, dropping newly discovered node */
return;
}
memcpy(&e->addr, addr, sizeof(ble_addr_t));
if (ad) {
memcpy(e->ad, ad, len);
}
e->ad_len = len;
e->last_rssi = info->rssi;
e->first_update = now;
e->adv_msg_cnt = 1;
e->type = type;
e->phy_pri = info->phy_pri;
e->phy_sec = info->phy_sec;
clist_rpush(&_list, (clist_node_t *)e);
}
else {
e->adv_msg_cnt++;
}
e->last_update = now;
}
nimble_scanlist_entry_t *nimble_scanlist_get_next(nimble_scanlist_entry_t *e)
{
if (e == NULL) {
return (nimble_scanlist_entry_t *)_list.next;
}
else {
e = (nimble_scanlist_entry_t *)e->node.next;
if (e == (nimble_scanlist_entry_t *)_list.next) {
/* end of list */
return NULL;
}
return e;
}
}
nimble_scanlist_entry_t *nimble_scanlist_get(unsigned pos)
{
nimble_scanlist_entry_t *cur = nimble_scanlist_get_next(NULL);
for (unsigned i = 0; i < pos; i++) {
cur = nimble_scanlist_get_next(cur);
}
return cur;
}
void nimble_scanlist_clear(void)
{
clist_node_t *node = clist_lpop(&_list);
while (node) {
clist_rpush(&_pool, node);
node = clist_lpop(&_list);
}
}