mirror of https://github.com/ARMmbed/mbed-os.git
214 lines
11 KiB
C
214 lines
11 KiB
C
/*
|
|
* Copyright (c) 2015-2018, Arm Limited and affiliates.
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#ifndef RPL_STRUCTURES_H_
|
|
#define RPL_STRUCTURES_H_
|
|
|
|
/* RPLstructures are public only for the core processing (rpl_upward,
|
|
* rpl_downward, and objective function implementations). This file should
|
|
* not be included by rpl_control, rpl_objective or rpl_policy, or any
|
|
* external user.
|
|
*/
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
|
|
#include "Service_Libs/Trickle/trickle.h"
|
|
|
|
struct rpl_objective;
|
|
|
|
/* Descriptor for a RPL neighbour within a DODAG
|
|
*
|
|
* Note that global address is only needed with downward routes, but I don't
|
|
* think it's worth optimising for an "upward-only" build. (Unless to be a RPL
|
|
* leaf?)
|
|
*
|
|
* DODAG parents are identified by the dodag_parent flag, and they are sorted
|
|
* first in the instance candidate_neighbour list, in order of preference.
|
|
*/
|
|
struct rpl_neighbour {
|
|
rpl_dodag_version_t *dodag_version; // Back pointer to DODAG Version
|
|
uint8_t ll_address[16]; // Link-local address (source of DIO)
|
|
uint8_t global_address[16]; // Global address (from DIO RIO)
|
|
bool dodag_parent: 1; // This is a DODAG parent (if true, dodag_version may not be NULL)
|
|
bool was_dodag_parent: 1; // Was a DODAG parent (used only during parent selection)
|
|
bool have_global_address: 1; // Global address known
|
|
bool considered: 1; // Have considered at least once for parent selection
|
|
bool confirmed: 1; // Confirmed
|
|
unsigned dodag_pref: 4; // Preference indication for DODAG parents (0=best)
|
|
uint8_t dao_path_control; // Path control bit assignments for DAO parent
|
|
uint8_t old_dao_path_control;
|
|
uint8_t addr_reg_failures; // Address registration failure count (missing ACK)
|
|
int8_t interface_id;
|
|
uint8_t g_mop_prf;
|
|
uint8_t dtsn;
|
|
uint16_t rank;
|
|
uint32_t dio_timestamp; // Timestamp of last received DIO message
|
|
/* Need link quality indication */
|
|
ns_list_link_t candidate_neighbour_link;
|
|
};
|
|
|
|
typedef NS_LIST_HEAD(rpl_neighbour_t, candidate_neighbour_link) rpl_neighbour_list_t;
|
|
|
|
/* Descriptor for a DODAG Version, identified by (RPLInstanceID, DODAGID, DODAGVersionNumber) */
|
|
struct rpl_dodag_version {
|
|
rpl_dodag_t *dodag; /* Back pointer to DODAG */
|
|
uint8_t number; /* Version Number */
|
|
uint16_t lowest_advertised_rank;
|
|
uint16_t last_advertised_rank;
|
|
uint16_t hard_rank_limit; /* Hard rank limit by DAGMaxRankIncrease */
|
|
uint16_t greediness_rank_limit; /* Rank limit for greediness */
|
|
ns_list_link_t link;
|
|
};
|
|
|
|
/* Descriptor for a DODAG. A DODAG is identified by a (RPLInstanceID, DODAGID) tuple */
|
|
struct rpl_dodag {
|
|
rpl_instance_t *instance; /* Back pointer to instance */
|
|
uint32_t timestamp; /* How long since we heard a DIO */
|
|
uint8_t id[16]; /* Root identifier */
|
|
uint8_t g_mop_prf; /* Grounded, Mode, Preference */
|
|
rpl_dodag_conf_t config; /* Configuration from DIO */
|
|
uint8_t info_version; /* Version for g_mop_prf and config */
|
|
bool root: 1; /* We are the root of this DODAG */
|
|
bool was_root: 1; /* If we have ever been a root in this DODAG */
|
|
bool leaf: 1; /* We are a leaf in this DODAG (by policy) */
|
|
bool have_config: 1; /* We have the config */
|
|
bool used: 1; /* We have ever been a member of this DODAG? */
|
|
uint8_t new_config_advertisment_count; /* We have advertiment new config at multicasti DIO max updated value is 0xfe*/
|
|
NS_LIST_HEAD(rpl_dodag_version_t, link) versions; /* List of DODAG versions (newest first) */
|
|
prefix_list_t prefixes; /* Prefixes advertised in DIO PIOs */
|
|
rpl_dio_route_list_t routes; /* Routes advertised in DIO RIOs*/
|
|
trickle_params_t dio_timer_params; /* Trickle parameters */
|
|
ns_list_link_t link;
|
|
};
|
|
|
|
typedef struct rpl_dao_target rpl_dao_target_t;
|
|
|
|
/* List of transits for a DAO target in a non-storing root */
|
|
typedef struct rpl_dao_root_transit {
|
|
uint8_t transit[16];
|
|
rpl_dao_target_t *parent; /* Current parent matched by transit. NULL if DODAG root, the original target if no match */
|
|
rpl_dao_target_t *target;
|
|
uint8_t path_control;
|
|
uint16_t cost;
|
|
ns_list_link_t parent_link;
|
|
ns_list_link_t target_link;
|
|
} rpl_dao_root_transit_t;
|
|
|
|
typedef NS_LIST_HEAD(rpl_dao_root_transit_t, target_link) rpl_dao_root_transit_list_t;
|
|
typedef NS_LIST_HEAD(rpl_dao_root_transit_t, parent_link) rpl_dao_root_transit_children_list_t;
|
|
|
|
/* Information held for a DAO target in a non-storing root */
|
|
typedef struct rpl_dao_root {
|
|
uint32_t cost; /* Routing cost - (used as number of incoming graph edges during topo sort) */
|
|
rpl_dao_root_transit_children_list_t children; /* Child list - only valid after routing cost computation */
|
|
rpl_dao_root_transit_list_t transits;
|
|
} rpl_dao_root_t;
|
|
|
|
/* Information held for a DAO target in other nodes */
|
|
typedef struct rpl_dao_non_root {
|
|
uint8_t path_lifetime; /* Does this count down? 0 means "not set yet" on published targets - we don't hold "No-Path" entries */
|
|
uint8_t pc_assigning; /* Bitfield of Path Control being assigned by in-flight DAO */
|
|
uint8_t pc_assigned; /* Bitfield of Path Control successfully assigned */
|
|
uint8_t pc_to_retry; /* Bitfield of Path Control assignment to be retried */
|
|
uint32_t refresh_timer; /* Refresh timer (seconds) - 0xFFFFFFFF = infinite, 0 = not yet set */
|
|
} rpl_dao_non_root_t;
|
|
|
|
|
|
/* Descriptor for a RPL DAO target */
|
|
struct rpl_dao_target {
|
|
rpl_instance_t *instance;
|
|
uint8_t prefix[16];
|
|
uint8_t prefix_len;
|
|
uint8_t path_sequence;
|
|
uint8_t path_control;
|
|
uint8_t response_wait_time;
|
|
int8_t interface_id;
|
|
uint32_t lifetime; /* Seconds */
|
|
uint32_t descriptor; /* Target descriptor */
|
|
bool external: 1; /* RPL 'E' flag */
|
|
bool root: 1; /* This is a "root" structure - root member of info active */
|
|
bool published: 1; /* Are we publishing, or did we get it from a DAO? (non-root) */
|
|
bool own: 1; /* Is this our own address, or are we publishing for an attached host? (non-root) */
|
|
bool descriptor_present: 1; /* Target descriptor specified */
|
|
bool need_seq_inc: 1;
|
|
bool connected: 1; /* We know this target has a path to the root */
|
|
bool trig_confirmation_state: 1; /* Enable confirmation to parent's */
|
|
bool active_confirmation_state: 1;
|
|
union {
|
|
#ifdef HAVE_RPL_ROOT
|
|
rpl_dao_root_t root; /* Info specific to a non-storing root */
|
|
#endif
|
|
rpl_dao_non_root_t non_root; /* Info for other nodes (any in storing, non-root in non-storing) */
|
|
} info;
|
|
ns_list_link_t link;
|
|
};
|
|
|
|
typedef NS_LIST_HEAD(rpl_dao_target_t, link) rpl_dao_target_list_t;
|
|
|
|
/* Descriptor for a RPL Instance. An instance can have multiple DODAGs.
|
|
*
|
|
* If top bit of instance_id is set then it's a local DODAG, and the dodags
|
|
* list must have exactly one member, whose dodag_id disambiguates the
|
|
* instance_id.
|
|
*/
|
|
struct rpl_instance {
|
|
ns_list_link_t link;
|
|
rpl_domain_t *domain; /* Back pointer to domain */
|
|
uint8_t id; /* RPLInstanceID */
|
|
uint8_t dtsn; /* Our DTSN for this instance */
|
|
bool neighbours_changed: 1;
|
|
bool local_repair: 1;
|
|
bool root_topo_sort_valid: 1;
|
|
bool root_paths_valid: 1;
|
|
bool dio_not_consistent: 1; /* Something changed - not consistent this period */
|
|
bool dao_in_transit: 1; /* If we have a DAO in transit */
|
|
bool requested_dao_ack: 1; /* If we requested an ACK (so we retry if no ACK, rather than assuming success) */
|
|
bool pending_neighbour_confirmation: 1; /* if we have not finished address registration state to parent */
|
|
bool parent_was_selected: 1;
|
|
bool advertised_dodag_membership_since_last_repair: 1; /* advertised dodag membership since last repair */
|
|
uint8_t poison_count;
|
|
uint8_t repair_dis_count;
|
|
uint16_t repair_dis_timer;
|
|
uint32_t last_dao_trigger_time;
|
|
uint16_t srh_error_count; /* SRH errors since last DAO trigger */
|
|
NS_LIST_HEAD(rpl_dodag_t, link) dodags; /* List of DODAGs */
|
|
rpl_neighbour_t *wait_response;
|
|
rpl_neighbour_list_t candidate_neighbours; /* Candidate neighbour set */
|
|
// rpl_neighbour_list_t old_neighbours; /* Old neighbours (without a live DODAG version) */
|
|
rpl_dodag_version_t *current_dodag_version; /* Pointer to DODAG version we are a member of (if any) */
|
|
uint16_t current_rank; /* Current rank in current DODAG Version */
|
|
uint16_t parent_selection_timer;
|
|
|
|
trickle_t dio_timer; /* Trickle timer for DIO transmission */
|
|
rpl_dao_root_transit_children_list_t root_children;
|
|
rpl_dao_target_list_t dao_targets; /* List of DAO targets */
|
|
uint8_t dao_sequence; /* Next DAO sequence to use */
|
|
uint8_t dao_sequence_in_transit; /* DAO sequence in transit (if dao_in_transit) */
|
|
uint16_t delay_dao_timer;
|
|
uint16_t dao_retry_timer;
|
|
uint8_t dao_attempt;
|
|
struct rpl_objective *of; /* Objective function pointer */
|
|
};
|
|
|
|
/* rpl_control.h uses NS_LIST_HEAD_INCOMPLETE */
|
|
NS_STATIC_ASSERT(offsetof(struct rpl_instance, link) == 0, "Link must be first in struct rpl_instance")
|
|
|
|
|
|
|
|
#endif /* RPL_STRUCTURES_H_ */
|