1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

sys/net: add l2scan list module

This commit is contained in:
Fabian Hüßler 2023-03-14 10:30:15 +01:00 committed by Fabian Hüßler
parent b482a713a3
commit dd52f5fedd
5 changed files with 176 additions and 0 deletions

View File

@ -101,6 +101,9 @@ endif
ifneq (,$(filter l2filter,$(USEMODULE)))
DIRS += net/link_layer/l2filter
endif
ifneq (,$(filter l2scan_list,$(USEMODULE)))
DIRS += net/link_layer/l2scan_list
endif
ifneq (,$(filter l2util,$(USEMODULE)))
DIRS += net/link_layer/l2util
endif

View File

@ -0,0 +1,73 @@
/*
* Copyright (C) 2023 ML!PA Consulting Gmbh
*
* 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 net_l2scanlist Scan List - List of wireless access points
* @ingroup net
* @brief Internal list data structure of scanned access points
* @ref NETOPT_SCAN
* @{
*
* @file
* @brief L2 Scan list API
*
* @author Fabian Hüßler <fabian.huessler@ml-pa.com>
*/
#ifndef NET_L2SCAN_LIST_H
#define NET_L2SCAN_LIST_H
#include <stdlib.h>
#include "list.h"
#include "net/netopt.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Type of a Link Layer scan list
*/
typedef struct l2scan_list {
list_node_t *head; /**< Pointer to the list head node */
/* items */
} l2scan_list_t;
/**
* @brief Empty the list to start a new scan
*
* @param[in, out] list Pointer to list
* @param[in, out] nodes Pointer to nodes array
* @param[in] nodes_numof Number of nodes in the array
* @param[in] node_size Size of one node element in the array
*/
void l2scan_list_empty(l2scan_list_t *list,
list_node_t *nodes, unsigned nodes_numof,
size_t node_size);
/**
* @brief Insert a new scan result into the list
*
* @param[in, out] list Pointer to list
* @param[in, out] nodes Pointer to nodes array
* @param[in] nodes_numof Number of nodes in the array
* @param[in] node_size Size of one node element in the array
* @param[in] result New result to insert
*/
void l2scan_list_insert(l2scan_list_t *list,
list_node_t *nodes, unsigned nodes_numof,
size_t node_size,
const netopt_scan_result_t *result);
#ifdef __cplusplus
}
#endif
#endif /* NET_L2SCAN_LIST_H */
/** @} */

View File

@ -0,0 +1,9 @@
# Copyright (c) 2023 ML!PA Consulting Gmbh
#
# 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.
#
config MODULE_L2SCAN_LIST
bool "List of scanned Link Layer access points"

View File

@ -0,0 +1 @@
include $(RIOTBASE)/Makefile.base

View File

@ -0,0 +1,90 @@
/*
* Copyright (C) 2023 ML!PA Consulting Gmbh
*
* 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 net_l2scan_list
* @{
*
* @file
* @brief List to store the result of a network scan
*
* @author Fabian Hüßler <fabian.huessler@ml-pa.com>
*
* @}
*/
#include <string.h>
#include "list.h"
#include "net/netopt.h"
#include "net/l2scan_list.h"
#define SCAN_LIST_NODE_AT(array, pos, size) ((void *)(((uint8_t *)(array)) + ((pos) * (size))))
/**
* @brief Basic type of a scan result in a list
*/
typedef struct scan_list_node {
list_node_t node; /* Basic node */
netopt_scan_result_t result; /* Basic scan result */
} scan_list_node_t;
static scan_list_node_t *_scan_list_get_insert(l2scan_list_t *list,
list_node_t *array, unsigned array_numof,
size_t item_size)
{
scan_list_node_t *lowest = (scan_list_node_t *)array;
for (unsigned i = 0; i < array_numof; i++) {
/* look for free slot or lowest element */
scan_list_node_t *result = SCAN_LIST_NODE_AT(array, i, item_size);
if (!result->result.strength) {
return result; /* free slot */
}
if (result->result.strength < lowest->result.strength) {
lowest = result; /* override lowest element */
}
}
list_node_t l = { .next = list->head };
list_remove(&l, &lowest->node);
return lowest;
}
void l2scan_list_empty(l2scan_list_t *list,
list_node_t *nodes, unsigned nodes_numof,
size_t node_size)
{
list->head = NULL;
memset(nodes, 0, nodes_numof * node_size);
}
void l2scan_list_insert(l2scan_list_t *list,
list_node_t *nodes, unsigned nodes_numof,
size_t node_size,
const netopt_scan_result_t *result)
{
scan_list_node_t *insert = _scan_list_get_insert(list, nodes,
nodes_numof, node_size);
*insert = (scan_list_node_t) { .node = { .next = NULL }, };
memcpy(&insert->result, result, node_size - sizeof(list_node_t));
if (!list->head) {
list->head = &insert->node;
}
else if (((scan_list_node_t *)list->head)->result.strength < result->strength) {
insert->node.next = list->head;
list->head = &insert->node;
}
else {
scan_list_node_t *next, *before = (scan_list_node_t *)list->head;
while ((next = (scan_list_node_t *)before->node.next) &&
next->result.strength > result->strength) {
before = (scan_list_node_t *)before->node.next;
}
list_add(&before->node, &insert->node);
}
}