-
Anjan Chanda authoredAnjan Chanda authored
topology.h 5.85 KiB
/*
* topology.h - topology of easymesh devices
*
* Copyright (C) 2020-2024 IOPSYS Software Solutions AB. All rights reserved.
* Copyright (C) 2025 Genexis AB.
*
* See LICENSE file for source code license information.
*
*/
#ifndef BACKHAUL_TOPOLOGY_H
#define BACKHAUL_TOPOLOGY_H
#include <libubox/list.h>
#include <stdbool.h>
#include <stdint.h>
#include <time.h>
struct tlv_1905neighbor;
struct tlv_device_info;
#define IFACE_MAX_NUM 16
#define NEIGHBORS_MAX_NUM 16
struct local_iface {
uint8_t macaddr[6];
uint16_t media_type;
uint8_t number_of_neighbors;
uint8_t neighbors_al_macs[NEIGHBORS_MAX_NUM][6];
};
/* When populated BH link defined as in TR-181:
* BHDevALMac/BHLocalMac() <-LinkType -< LocalMac
* can be read. Above corresponds to:
* parent/parent_iface <--own_iface->media_type-< own_iface
*/
#define UNKNOWN_TREE_LEVEL -1
struct backhaul_info {
int8_t depth; /** total number of BH links from root node */
uint8_t wifi_hops_from_root; /** number of Wi-Fi BH links from root node */
const struct bh_topology_dev *parent;
const struct local_iface *parent_iface;
const struct local_iface *own_iface;
};
/** Represents single device and its relation to neighbors in BH tree. */
struct bh_topology_dev {
struct list_head list;
struct timespec last_topo_response;
uint8_t al_macaddr[6];
uint8_t number_of_interfaces;
uint8_t num_of_ifaces_with_neighbors;
struct local_iface ifaces[IFACE_MAX_NUM];
struct backhaul_info bh;
};
/** Used to store all discovered EasyMesh devices and model tree topology. */
struct bh_topology_data {
struct list_head dev_list; /* list of struct bh_topology_dev */
uint32_t num_devs;
bool valid;
};
/** Initializes internal structures.
* Has to be called once before any other functions are called.
*/
void init_topology(struct bh_topology_data *topology);
/** Releases all data and internal structures. */
void free_topology(struct bh_topology_data *topology);
/** Returns tree if backhaul topology tree was already build and is still valid.
*
* It's undefined behaviour to read interface, neighbor and backhaul info
* of any bh_topology_dev when this function returns false.
*/
bool is_topology_valid(struct bh_topology_data *topology);
/** Number of devices in backhaul topology tree. */
uint32_t topology_num_devs(struct bh_topology_data *topology);
/** Returns backhaul topology device if exists in the model, NULL otherwise. */
struct bh_topology_dev *topology_find_device(struct bh_topology_data *topology, const uint8_t *al_macaddr);
/** Adds backhaul topology device to the model, invalidates backhaul tree. */
struct bh_topology_dev *topology_add_device(struct bh_topology_data *topology, const uint8_t *al_macaddr);
/** Removes backhaul topology device from the model, invalidates backhaul tree. */
void topology_remove_device(struct bh_topology_data *topology, const uint8_t *al_macaddr);
/** Removes all backhaul topology devices from the model, invalidates backhaul tree. */
void topology_remove_all_devices(struct bh_topology_data *topology);
/**
* Returns true if interface information provided with tlv_device_info differs
* from data already stored in bh_topology_dev (model).
* To reduce time complexity, it's assumed interfaces received in TLV are always ordered
* the same way. Also only number of interfaces and their MAC addresses are compared.
*/
bool has_interface_info_changed(const struct tlv_device_info *tlv_dev_info,
const struct bh_topology_dev *bh_topo_dev);
/**
* Copies interface details from tlv_device_info into bh_topology_dev.
* Invalidates backhaul tree.
*/
void copy_interface_info_from_tlv(struct bh_topology_data *topology,
const struct tlv_device_info *tlv_dev_info,
struct bh_topology_dev *bh_topo_dev);
/**
* Returns true if neighbor information provided with 1905 neighbor TLVs differs
* from data already stored in bh_topology_dev (model).
*/
bool has_neighbor_info_changed(const struct tlv_1905neighbor **neighbor_tlvs,
const uint16_t *tlv_lengths,
uint8_t tlv_number,
const struct bh_topology_dev *bh_topo_dev);
/**
* Copies neighbors details from 1905 neighbor TLVs into bh_topology_dev.
* Invalidates backhaul tree.
*/
void copy_neighbor_info_from_tlvs(struct bh_topology_data *topology,
const struct tlv_1905neighbor **neighbor_tlvs,
const uint16_t *tlv_lengths,
uint8_t tlv_number,
struct bh_topology_dev *bh_topo_dev);
/**
* Shall be called each time device provides topology response.
*/
void set_bh_toplogy_response_timestamp(struct bh_topology_dev *bh_topo_dev);
/**
* Builds backhaul topology tree from unordered list of bh_topology_dev structs
* by setting backhaul_info fields.
*
* Controller is always root node in tree. Edges between tree nodes represent
* BH links, parent nodes provides BH links to child node - each child node
* can have only one parent (be connected over one BH link).
*
* After calling it, is_bh_topology_valid() will return true, until next
* input data change (device add/remove, interface or neighbor info change.)
*/
void topology_build_tree(struct bh_topology_data *topology, const uint8_t *ctrl_al_macaddr);
enum dbg_bh_topo_indent_lvl {
INDENT_LVL_0 = 0,
INDENT_LVL_1 = 1,
INDENT_LVL_2 = 2,
INDENT_LVL_3 = 3,
};
const char *i1905_media_type_to_str(uint16_t media_type);
void dbg_dump_bh_topo_backhaul_info(const struct backhaul_info *bh,
enum dbg_bh_topo_indent_lvl indent_lvl);
void dbg_dump_bh_topo_local_iface(const struct local_iface *local_iface,
enum dbg_bh_topo_indent_lvl indent_lvl);
void dbg_dump_bh_topo_dev(const struct bh_topology_dev *bh_topo_dev,
enum dbg_bh_topo_indent_lvl indent_lvl);
void dbg_dump_bh_topo_devs(const struct list_head *bh_topo_dev_list,
enum dbg_bh_topo_indent_lvl indent_lvl);
void dbg_dump_bh_topo_link(const struct bh_topology_dev *bh_topo_dev,
enum dbg_bh_topo_indent_lvl indent_lvl);
#endif /* BACKHAUL_TOPOLOGY_H */