| /** @file |
| @brief RPL data handler |
| |
| This is not to be included by the application. |
| */ |
| |
| /* |
| * Copyright (c) 2016 Intel Corporation |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #ifndef __RPL_H |
| #define __RPL_H |
| |
| #include <kernel.h> |
| #include <stdbool.h> |
| |
| #include <net/net_ip.h> |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| #if defined(CONFIG_NET_RPL) |
| |
| #include "route.h" |
| |
| #define NET_ICMPV6_RPL 155 /* RPL Control Message */ |
| |
| #define NET_RPL_DODAG_SOLICIT 0x00 |
| #define NET_RPL_DODAG_INFO_OBJ 0x01 |
| #define NET_RPL_DEST_ADV_OBJ 0x02 |
| #define NET_RPL_DEST_ADV_OBJ_ACK 0x03 |
| #define NET_RPL_SEC_DODAG_SOLICIT 0x80 |
| #define NET_RPL_SEC_DODAG_INFO_OBJ 0x81 |
| #define NET_RPL_SEC_DEST_ADV_OBJ 0x82 |
| #define NET_RPL_SEC_DEST_ADV_OBJ_ACK 0x83 |
| #define NET_RPL_CONSISTENCY_CHECK 0x8A |
| |
| /* Routing Metric/Constraint Type, RFC 6551 ch 6.1 */ |
| #define NET_RPL_MC_NONE 0 /* Local identifier for empty MC */ |
| #define NET_RPL_MC_NSA 1 /* Node State and Attributes */ |
| #define NET_RPL_MC_ENERGY 2 /* Node Energy */ |
| #define NET_RPL_MC_HOPCOUNT 3 /* Hop Count */ |
| #define NET_RPL_MC_THROUGHPUT 4 /* Throughput */ |
| #define NET_RPL_MC_LATENCY 5 /* Latency */ |
| #define NET_RPL_MC_LQL 6 /* Link Quality Level */ |
| #define NET_RPL_MC_ETX 7 /* Expected Transmission Count */ |
| #define NET_RPL_MC_LC 8 /* Link Color */ |
| |
| /* Routing Metric/Constraint Common Header Flag Field, RFC 6551, ch 6.3 */ |
| #define NET_RPL_MC_FLAG_P BIT(5) |
| #define NET_RPL_MC_FLAG_C BIT(6) |
| #define NET_RPL_MC_FLAG_O BIT(7) |
| #define NET_RPL_MC_FLAG_R BIT(8) |
| |
| /* Routing Metric/Constraint Common Header A Field, RFC 6551, ch 6.4 */ |
| #define NET_RPL_MC_A_ADDITIVE 0 |
| #define NET_RPL_MC_A_MAXIMUM 1 |
| #define NET_RPL_MC_A_MINIMUM 2 |
| #define NET_RPL_MC_A_MULTIPLICATIVE 3 |
| |
| /* Node type field, RFC 6551, ch 6.7 */ |
| #define NET_RPL_MC_NODE_TYPE_MAINS 0 |
| #define NET_RPL_MC_NODE_TYPE_BATTERY 1 |
| #define NET_RPL_MC_NODE_TYPE_SCAVENGING 2 |
| |
| /* The bit index within the flags field of the RPL metric object energy |
| * structure. |
| */ |
| #define NET_RPL_MC_ENERGY_INCLUDED 3 |
| #define NET_RPL_MC_ENERGY_TYPE 1 |
| #define NET_RPL_MC_ENERGY_ESTIMATION 0 |
| |
| /* RPL control message options. */ |
| #define NET_RPL_OPTION_PAD1 0 |
| #define NET_RPL_OPTION_PADN 1 |
| #define NET_RPL_OPTION_DAG_METRIC_CONTAINER 2 |
| #define NET_RPL_OPTION_ROUTE_INFO 3 |
| #define NET_RPL_OPTION_DAG_CONF 4 |
| #define NET_RPL_OPTION_TARGET 5 |
| #define NET_RPL_OPTION_TRANSIT 6 |
| #define NET_RPL_OPTION_SOLICITED_INFO 7 |
| #define NET_RPL_OPTION_PREFIX_INFO 8 |
| #define NET_RPL_OPTION_TARGET_DESC 9 |
| |
| #define NET_RPL_MAX_RANK_INC (7 * CONFIG_NET_RPL_MIN_HOP_RANK_INC) |
| #define NET_RPL_INFINITE_RANK 0xffff |
| |
| /* Rank of a root node. */ |
| #define NET_RPL_ROOT_RANK(instance) ((instance)->min_hop_rank_inc) |
| |
| #define NET_RPL_DAG_RANK(rank, instance) ((rank) / \ |
| (instance)->min_hop_rank_inc) |
| |
| /* |
| * The ETX in the metric container is expressed as a fixed-point value |
| * whose integer part can be obtained by dividing the value by |
| * NET_RPL_MC_ETX_DIVISOR. |
| */ |
| #define NET_RPL_MC_ETX_DIVISOR 256 |
| |
| /* DAG Mode of Operation */ |
| #define NET_RPL_MOP_NO_DOWNWARD_ROUTES 0 |
| #define NET_RPL_MOP_NON_STORING 1 |
| #define NET_RPL_MOP_STORING_NO_MULTICAST 2 |
| #define NET_RPL_MOP_STORING_MULTICAST 3 |
| |
| #if defined(CONFIG_NET_RPL_DEFAULT_INSTANCE) |
| #define NET_RPL_DEFAULT_INSTANCE CONFIG_NET_RPL_DEFAULT_INSTANCE |
| #else |
| #define NET_RPL_DEFAULT_INSTANCE 0x1e |
| #endif |
| |
| #define NET_RPL_PARENT_FLAG_UPDATED 0x1 |
| #define NET_RPL_PARENT_FLAG_LINK_METRIC_VALID 0x2 |
| |
| /* RPL IPv6 extension header option. */ |
| #define NET_RPL_HDR_OPT_LEN 4 |
| #define NET_RPL_HOP_BY_HOP_LEN (NET_RPL_HDR_OPT_LEN + 2 + 2) |
| #define NET_RPL_HDR_OPT_DOWN 0x80 |
| #define NET_RPL_HDR_OPT_DOWN_SHIFT 7 |
| #define NET_RPL_HDR_OPT_RANK_ERR 0x40 |
| #define NET_RPL_HDR_OPT_RANK_ERR_SHIFT 6 |
| #define NET_RPL_HDR_OPT_FWD_ERR 0x20 |
| #define NET_RPL_HDR_OPT_FWD_ERR_SHIFT 5 |
| |
| /** |
| * RPL modes |
| * |
| * The RPL module can be in either of three modes: mesh mode |
| * (NET_RPL_MODE_MESH), feather mode (NET_RPL_MODE_FEATHER), and leaf mode |
| * (NET_RPL_MODE_LEAF). In mesh mode, nodes forward data for other nodes, |
| * and are reachable by others. In feather mode, nodes can forward |
| * data for other nodes, but are not reachable themselves. In leaf |
| * mode, nodes do not forward data for others, but are reachable by |
| * others. |
| */ |
| enum net_rpl_mode { |
| NET_RPL_MODE_MESH, |
| NET_RPL_MODE_FEATHER, |
| NET_RPL_MODE_LEAF, |
| }; |
| |
| /** |
| * Flag values in DAO message. |
| */ |
| #define NET_RPL_DAO_K_FLAG 0x80 /* DAO ACK requested */ |
| #define NET_RPL_DAO_D_FLAG 0x40 /* DODAG ID present */ |
| |
| #define NET_RPL_LOLLIPOP_MAX_VALUE 255 |
| #define NET_RPL_LOLLIPOP_CIRCULAR_REGION 127 |
| #define NET_RPL_LOLLIPOP_SEQUENCE_WINDOWS 16 |
| |
| static inline u8_t net_rpl_lollipop_init(void) |
| { |
| return NET_RPL_LOLLIPOP_MAX_VALUE - |
| NET_RPL_LOLLIPOP_SEQUENCE_WINDOWS + 1; |
| } |
| |
| static inline void net_rpl_lollipop_increment(u8_t *counter) |
| { |
| if (*counter > NET_RPL_LOLLIPOP_CIRCULAR_REGION) { |
| *counter = (*counter + 1) & NET_RPL_LOLLIPOP_MAX_VALUE; |
| } else { |
| *counter = (*counter + 1) & NET_RPL_LOLLIPOP_CIRCULAR_REGION; |
| } |
| } |
| |
| static inline bool net_rpl_lollipop_is_init(u8_t counter) |
| { |
| return counter > NET_RPL_LOLLIPOP_CIRCULAR_REGION; |
| } |
| |
| struct net_rpl_instance; |
| struct net_rpl_dag; |
| |
| /** |
| * @brief DIO prefix suboption. |
| */ |
| struct net_rpl_prefix { |
| /** IPv6 address prefix */ |
| struct in6_addr prefix; |
| |
| /** Lifetime of the prefix */ |
| u32_t lifetime; |
| |
| /** Length of the prefix */ |
| u8_t length; |
| |
| /** Prefix flags */ |
| u8_t flags; |
| }; |
| |
| /** |
| * @brief Node energy object, RFC 6551, ch 3.2 |
| */ |
| struct net_rpl_node_energy_object { |
| /** Energy node flags */ |
| u8_t flags; |
| |
| /** Energy estimation */ |
| u8_t estimation; |
| }; |
| |
| /** |
| * @brief DAG Metric Container. RFC 6551, ch 2.1 |
| */ |
| struct net_rpl_metric_container { |
| /** Type of the container */ |
| u8_t type; |
| |
| /** Container flags */ |
| u8_t flags; |
| |
| /** Aggregated value (A field) */ |
| u8_t aggregated; |
| |
| /** |
| * Precedence of this Routing Metric/Constraint object relative |
| * to other objects in the container. |
| */ |
| u8_t precedence; |
| |
| /** Length of the object body */ |
| u8_t length; |
| |
| /** Metric container information */ |
| union metric_object { |
| struct net_rpl_node_energy_object energy; |
| u16_t etx; |
| } obj; |
| }; |
| |
| /** |
| * @brief Parent information. |
| */ |
| struct net_rpl_parent { |
| /** Used DAG */ |
| struct net_rpl_dag *dag; |
| |
| /** Used metric container */ |
| struct net_rpl_metric_container mc; |
| |
| /** When last transmit happened */ |
| u32_t last_tx_time; |
| |
| /** Rank of the parent */ |
| u16_t rank; |
| |
| /** Destination Advertisement Trigger Sequence Number */ |
| u8_t dtsn; |
| |
| /** Parent flags */ |
| u8_t flags; |
| }; |
| |
| /** |
| * @brief Directed Acyclic Graph (DAG) |
| */ |
| struct net_rpl_dag { |
| /** DAG id */ |
| struct in6_addr dag_id; |
| |
| /** What is the preferred parent. */ |
| struct net_rpl_parent *preferred_parent; |
| |
| /** IPv6 prefix information */ |
| struct net_rpl_prefix prefix_info; |
| |
| /** Used RPL instance */ |
| struct net_rpl_instance *instance; |
| |
| /** Minimum rank */ |
| u16_t min_rank; |
| |
| /** DAG rank */ |
| u16_t rank; |
| |
| /** DAG version. */ |
| u8_t version; |
| |
| /** DODAG preference. */ |
| u8_t preference : 3; |
| |
| /** Is this DAG used or not. */ |
| u8_t is_used : 1; |
| |
| /** Is DAG grounded or floating. */ |
| u8_t is_grounded : 1; |
| |
| /** Is DAG joined or not. */ |
| u8_t is_joined : 1; |
| |
| u8_t _unused : 2; |
| }; |
| |
| /** |
| * @brief Get related neighbor information from parent pointer. |
| * |
| * @param data Pointer to parent. |
| * |
| * @return Neighbor pointer if found, NULL if neighbor is not found. |
| */ |
| struct net_nbr *net_rpl_get_nbr(struct net_rpl_parent *data); |
| |
| /** |
| * @brief Get related neighbor data from parent pointer. |
| * |
| * @param data Pointer to parent. |
| * |
| * @return Neighbor data pointer if found, NULL if neighbor is not found. |
| */ |
| struct net_ipv6_nbr_data * |
| net_rpl_get_ipv6_nbr_data(struct net_rpl_parent *parent); |
| |
| /** |
| * @brief RPL object function (OF) reset. |
| * |
| * @details Reset the OF state for a specific DAG. This function is called when |
| * doing a global repair on the DAG. |
| * |
| * @param dag Pointer to DAG object |
| */ |
| extern void net_rpl_of_reset(struct net_rpl_dag *dag); |
| |
| /** |
| * @brief RPL object function (OF) neighbor link callback. |
| * |
| * @details Receives link-layer neighbor information. The etx parameter |
| * specifies the current ETX(estimated transmissions) for the neighbor. |
| * |
| * @param iface Network interface |
| * @param parent Parent of the neighbor |
| * @param status Transmission status |
| * @param ext Estimated transmissions value |
| * |
| * @return 0 if ok, < 0 if error |
| */ |
| extern int net_rpl_of_neighbor_link_cb(struct net_if *iface, |
| struct net_rpl_parent *parent, |
| int status, int etx); |
| |
| /** |
| * @brief RPL object function (OF) get best parent. |
| * |
| * @details Compares two parents and returns the best one. |
| * |
| * @param iface Network interface. |
| * @param parentA First parent. |
| * @param parentB Second parent. |
| * |
| * @return Best parent is returned. |
| */ |
| extern struct net_rpl_parent * |
| net_rpl_of_best_parent(struct net_if *iface, |
| struct net_rpl_parent *parentA, |
| struct net_rpl_parent *parentB); |
| |
| /** |
| * @brief RPL object function (OF) get best DAG. |
| * |
| * @details Compares two DAGs and returns the best one. |
| * |
| * @param dagA First DAG. |
| * @param dagB Second DAG. |
| * |
| * @return Best DAG. |
| */ |
| extern struct net_rpl_dag *net_rpl_of_best_dag(struct net_rpl_dag *dagA, |
| struct net_rpl_dag *dagB); |
| |
| /** |
| * @brief RPL object function (OF) calculate rank. |
| * |
| * @details Calculates a rank value using the parent rank and a base rank. |
| * If parent is not set, the OF selects a default increment that is |
| * added to the base rank. Otherwise, the OF uses information known |
| * about parent to select an increment to the base rank. |
| */ |
| extern u16_t net_rpl_of_calc_rank(struct net_rpl_parent *parent, |
| u16_t rank); |
| |
| /** |
| * @brief RPL object function (OF) update metric container. |
| * |
| * @details Updates the metric container for outgoing DIOs in a certain DAG. |
| * If the OF of the DAG does not use metric containers, the function |
| * should set the object type to NET_RPL_MC_NONE. |
| * |
| * @param instance Pointer to RPL instance. |
| */ |
| extern int net_rpl_of_update_mc(struct net_rpl_instance *instance); |
| |
| /** |
| * @brief RPL object function (OF) objective code point used. |
| * |
| * @details Check if we support desired objective function. |
| * |
| * @param ocp Objective Code Point value |
| * |
| * @return true if OF is supported, false otherwise. |
| */ |
| extern bool net_rpl_of_find(u16_t ocp); |
| |
| /** |
| * @brief Return RPL object function (OF) objective code point used. |
| * |
| * @return OCP (Objective Code Point) value used. |
| */ |
| extern u16_t net_rpl_of_get(void); |
| |
| /** |
| * @brief RPL instance structure |
| * |
| * Describe RPL instance. |
| */ |
| struct net_rpl_instance { |
| /** Routing metric information */ |
| struct net_rpl_metric_container mc; |
| |
| /** All the DAGs for this RPL instance */ |
| struct net_rpl_dag dags[CONFIG_NET_RPL_MAX_DAG_PER_INSTANCE]; |
| |
| #if defined(CONFIG_NET_RPL_PROBING) |
| /** When next probe message will be sent. */ |
| struct k_delayed_work probing_timer; |
| #endif /* CONFIG_NET_RPL_PROBING */ |
| |
| /** DODAG Information Object timer. */ |
| struct k_delayed_work dio_timer; |
| |
| /** Destination Advertisement Object timer. */ |
| struct k_delayed_work dao_timer; |
| |
| /** DAO lifetime timer. */ |
| struct k_delayed_work dao_lifetime_timer; |
| |
| #if defined(CONFIG_NET_RPL_DAO_ACK) |
| /** DAO retransmit timer */ |
| struct k_delayed_work dao_retransmit_timer; |
| |
| /** DAO number of retransmissions */ |
| u8_t dao_transmissions; |
| #endif |
| |
| /** Network interface to send DAO */ |
| struct net_if *iface; |
| |
| /** Current DAG in use */ |
| struct net_rpl_dag *current_dag; |
| |
| /** Current default router information */ |
| struct net_if_router *default_route; |
| |
| /** Amount of time for completion of dio interval */ |
| u32_t dio_next_delay; |
| |
| /** Objective Code Point (Used objective function) */ |
| u16_t ocp; |
| |
| /** MaxRankIncrease, RFC 6550, ch 6.7.6 */ |
| u16_t max_rank_inc; |
| |
| /** MinHopRankIncrease, RFC 6550, ch 6.7.6 */ |
| u16_t min_hop_rank_inc; |
| |
| /** |
| * Provides the unit in seconds that is used to express route |
| * lifetimes in RPL. For very stable networks, it can be hours |
| * to days. RFC 6550, ch 6.7.6 |
| */ |
| u16_t lifetime_unit; |
| |
| #if defined(CONFIG_NET_STATISTICS_RPL) |
| /** Number of DIO intervals for this RPL instance. */ |
| u16_t dio_intervals; |
| |
| /** Number of DIOs sent for this RPL instance. */ |
| u16_t dio_send_pkt; |
| |
| /** Number of DIOs received for this RPL instance. */ |
| u16_t dio_recv_pkt; |
| #endif /* CONFIG_NET_STATISTICS_RPL */ |
| |
| /** |
| * This is the lifetime that is used as default for all RPL routes. |
| * It is expressed in units of Lifetime Units, e.g., the default |
| * lifetime in seconds is (Default Lifetime) * (Lifetime Unit) |
| * RFC 6550, ch 6.7.6 |
| */ |
| u8_t default_lifetime; |
| |
| /** Instance ID of this RPL instance */ |
| u8_t instance_id; |
| |
| /** Destination Advertisement Trigger Sequence Number */ |
| u8_t dtsn; |
| |
| /** Mode of operation */ |
| u8_t mop; |
| |
| /** DIOIntervalDoublings, RFC 6550, ch 6.7.6 */ |
| u8_t dio_interval_doublings; |
| |
| /** DIOIntervalMin, RFC 6550, ch 6.7.6 */ |
| u8_t dio_interval_min; |
| |
| /** Current DIO interval */ |
| u8_t dio_interval_current; |
| |
| /** DIORedundancyConstant, ch 6.7.6 */ |
| u8_t dio_redundancy; |
| |
| /** Current number of DIOs received (temp var) */ |
| u8_t dio_counter; |
| |
| /** Keep track of whether we can send DIOs or not (true if we can send) |
| */ |
| bool dio_send; |
| |
| /** Is this RPL instance used or not */ |
| bool is_used; |
| |
| /** Is DAO timer active or not. */ |
| bool dao_timer_active; |
| |
| /** Is DAO lifetime timer active or not. */ |
| bool dao_lifetime_timer_active; |
| }; |
| |
| /** |
| * @brief RPL DIO structure |
| * |
| * Describe RPL DAG Information Object. |
| */ |
| struct net_rpl_dio { |
| /** Routing metric information */ |
| struct net_rpl_metric_container mc; |
| |
| /** DAG id */ |
| struct in6_addr dag_id; |
| |
| /** IPv6 prefix information */ |
| struct net_rpl_prefix prefix_info; |
| |
| /** IPv6 destination prefix */ |
| struct net_rpl_prefix destination_prefix; |
| |
| /** Objective Code Point (OF being used) */ |
| u16_t ocp; |
| |
| /** Current rank */ |
| u16_t rank; |
| |
| /** MaxRankIncrease, RFC 6550, ch 6.7.6 */ |
| u16_t max_rank_inc; |
| |
| /** MinHopRankIncrease, RFC 6550, ch 6.7.6 */ |
| u16_t min_hop_rank_inc; |
| /** |
| * Provides the unit in seconds that is used to express route |
| * lifetimes in RPL. For very stable networks, it can be hours |
| * to days. RFC 6550, ch 6.7.6 |
| */ |
| u16_t lifetime_unit; |
| |
| /** |
| * This is the lifetime that is used as default for all RPL routes. |
| * It is expressed in units of Lifetime Units, e.g., the default |
| * lifetime in seconds is (Default Lifetime) * (Lifetime Unit) |
| * RFC 6550, ch 6.7.6 |
| */ |
| u8_t default_lifetime; |
| |
| /** Instance ID of this RPL instance */ |
| u8_t instance_id; |
| |
| /** Destination Advertisement Trigger Sequence Number */ |
| u8_t dtsn; |
| |
| /** Mode of operation */ |
| u8_t mop; |
| |
| /** DAG interval doublings */ |
| u8_t dag_interval_doublings; |
| |
| /** DAG interval min */ |
| u8_t dag_interval_min; |
| |
| /** DAG interval */ |
| u8_t dag_interval_current; |
| |
| /** DAG redundancy constant */ |
| u8_t dag_redundancy; |
| |
| /** Is this DAG grounded or floating */ |
| u8_t grounded; |
| |
| /** DODAG preference */ |
| u8_t preference; |
| |
| /** DODAG version number */ |
| u8_t version; |
| }; |
| |
| /** |
| * @brief RPL route information source |
| */ |
| enum net_rpl_route_source { |
| NET_RPL_ROUTE_INTERNAL, |
| NET_RPL_ROUTE_UNICAST_DAO, |
| NET_RPL_ROUTE_MULTICAST_DAO, |
| NET_RPL_ROUTE_DIO, |
| }; |
| |
| /** |
| * @brief RPL route entry |
| * |
| * Stores extra information for RPL route. |
| */ |
| struct net_rpl_route_entry { |
| /** Dag info for this route */ |
| struct net_rpl_dag *dag; |
| |
| /** Lifetime for this route entry (in seconds) */ |
| u32_t lifetime; |
| |
| /** Where this route came from */ |
| enum net_rpl_route_source route_source; |
| |
| /** No-Path target option with lifetime 0 received (true) or (false) */ |
| bool no_path_received; |
| }; |
| |
| /** |
| * The extra data size is used in route.h to determine how much extra |
| * space to allocate for RPL specific data. |
| */ |
| #define NET_ROUTE_EXTRA_DATA_SIZE sizeof(struct net_rpl_route_entry) |
| |
| /** |
| * @brief Check if the IPv6 address is a RPL multicast address. |
| * |
| * @param addr IPv6 address |
| * |
| * @return True if address is RPL multicast address, False otherwise. |
| */ |
| static inline bool net_rpl_is_ipv6_addr_mcast(const struct in6_addr *addr) |
| { |
| return UNALIGNED_GET(&addr->s6_addr32[0]) == htonl(0xff020000) && |
| UNALIGNED_GET(&addr->s6_addr32[1]) == 0x00000000 && |
| UNALIGNED_GET(&addr->s6_addr32[2]) == 0x00000000 && |
| UNALIGNED_GET(&addr->s6_addr32[3]) == htonl(0x0000001a); |
| } |
| |
| /** |
| * @brief Create RPL IPv6 multicast address FF02::1a |
| * |
| * @param addr IPv6 address. |
| * |
| * @return Pointer to given IPv6 address. |
| */ |
| static inline |
| struct in6_addr *net_rpl_create_mcast_address(struct in6_addr *addr) |
| { |
| addr->s6_addr[0] = 0xFF; |
| addr->s6_addr[1] = 0x02; |
| UNALIGNED_PUT(0, &addr->s6_addr16[1]); |
| UNALIGNED_PUT(0, &addr->s6_addr16[2]); |
| UNALIGNED_PUT(0, &addr->s6_addr16[3]); |
| UNALIGNED_PUT(0, &addr->s6_addr16[4]); |
| UNALIGNED_PUT(0, &addr->s6_addr16[5]); |
| UNALIGNED_PUT(0, &addr->s6_addr16[6]); |
| addr->s6_addr[14] = 0; |
| addr->s6_addr[15] = 0x1a; |
| |
| return addr; |
| } |
| |
| /** |
| * @brief Return information whether the DAG is in use right now. |
| * |
| * @param dag Pointer to DAG. |
| * |
| * @return true if in use, false otherwise |
| */ |
| static inline bool net_rpl_dag_is_used(struct net_rpl_dag *dag) |
| { |
| NET_ASSERT(dag); |
| |
| return !!dag->is_used; |
| } |
| |
| /** |
| * @brief Set the DAG as not in use. |
| * |
| * @param dag Pointer to DAG. |
| */ |
| static inline void net_rpl_dag_set_not_used(struct net_rpl_dag *dag) |
| { |
| NET_ASSERT(dag); |
| |
| dag->is_used = 0; |
| } |
| |
| /** |
| * @brief Set the DAG as in use. |
| * |
| * @param dag Pointer to DAG. |
| */ |
| static inline void net_rpl_dag_set_used(struct net_rpl_dag *dag) |
| { |
| NET_ASSERT(dag); |
| |
| dag->is_used = 1; |
| } |
| |
| /** |
| * @brief Return information whether the DAG is grounded or floating. |
| * |
| * @param dag Pointer to DAG. |
| * |
| * @return true if grounded, false if floating |
| */ |
| static inline bool net_rpl_dag_is_grounded(struct net_rpl_dag *dag) |
| { |
| NET_ASSERT(dag); |
| |
| return !!dag->is_grounded; |
| } |
| |
| /** |
| * @brief Set DAG information whether it is grounded or floating. |
| * |
| * @param dag Pointer to DAG. |
| */ |
| static inline void net_rpl_dag_set_grounded_status(struct net_rpl_dag *dag, |
| bool grounded) |
| { |
| NET_ASSERT(dag); |
| |
| dag->is_grounded = grounded; |
| } |
| |
| /** |
| * @brief Return information whether the DAG is joined or not. |
| * |
| * @param dag Pointer to DAG. |
| * |
| * @return true if joined, false otherwise |
| */ |
| static inline bool net_rpl_dag_is_joined(struct net_rpl_dag *dag) |
| { |
| NET_ASSERT(dag); |
| |
| return !!dag->is_joined; |
| } |
| |
| /** |
| * @brief Mark DAG as joined. |
| * |
| * @param dag Pointer to DAG. |
| */ |
| static inline void net_rpl_dag_join(struct net_rpl_dag *dag) |
| { |
| NET_ASSERT(dag); |
| |
| dag->is_joined = 1; |
| } |
| |
| /** |
| * @brief Mark DAG as joined. |
| * |
| * @param dag Pointer to DAG. |
| */ |
| static inline void net_rpl_dag_unjoin(struct net_rpl_dag *dag) |
| { |
| NET_ASSERT(dag); |
| |
| dag->is_joined = 0; |
| } |
| |
| /** |
| * @brief Get preference for this DAG. |
| * |
| * @details This function returns the preference of the dag. |
| * |
| * @param dag Pointer to DAG. |
| * |
| * @return preference value |
| */ |
| static inline |
| u8_t net_rpl_dag_get_preference(struct net_rpl_dag *dag) |
| { |
| NET_ASSERT(dag); |
| |
| return dag->preference; |
| } |
| |
| /** |
| * @brief Set preference for this DAG. |
| * |
| * @details This function sets the preference of the dag. |
| * |
| * @param dag Pointer to DAG. |
| * @param preference New preference value. |
| */ |
| static inline |
| void net_rpl_dag_set_preference(struct net_rpl_dag *dag, |
| u8_t preference) |
| { |
| NET_ASSERT(dag && preference <= 8); |
| |
| dag->preference = preference; |
| } |
| |
| /** |
| * @typedef net_rpl_join_callback_t |
| * @brief Callback for evaluating if this is a network to join or not. |
| * @param dio Pointer to DIO. |
| * @return True if the network is to be joined, false otherwise. |
| */ |
| typedef bool (*net_rpl_join_callback_t)(struct net_rpl_dio *dio); |
| |
| /** |
| * @brief Register a callback that determines if the network is to be |
| * joined or not. |
| * |
| * @param cb Callback function |
| */ |
| void net_rpl_set_join_callback(net_rpl_join_callback_t cb); |
| |
| /** |
| * @brief Send a DODAG Information Solicitation message. |
| * |
| * @param dst Destination IPv6 address. |
| * @param iface Interface to send the message to. |
| * |
| * @return 0 message was sent ok, <0 otherwise |
| */ |
| int net_rpl_dis_send(struct in6_addr *dst, struct net_if *iface); |
| |
| /** |
| * @brief Send a Destination Advertisement Object message. |
| * |
| * @param iface Network interface to use, this can be set to NULL in which |
| * case the function can try to figure it out itself. |
| * @param parent Pointer to parent information. |
| * @param prefix IPv6 address |
| * @param lifetime Lifetime of the advertisement. |
| * |
| * @return 0 message was sent ok, <0 otherwise |
| */ |
| int net_rpl_dao_send(struct net_if *iface, |
| struct net_rpl_parent *parent, |
| struct in6_addr *prefix, |
| u8_t lifetime); |
| |
| /** |
| * @brief Send a DODAG Information Object message. |
| * |
| * @param iface Network interface to use, this can be set to NULL in which |
| * case the function can try to figure it out itself. |
| * @param instance Pointer to instance object. |
| * @param src IPv6 source address. |
| * @param dst IPv6 destination address. |
| * |
| * @return 0 message was sent ok, <0 otherwise |
| */ |
| int net_rpl_dio_send(struct net_if *iface, |
| struct net_rpl_instance *instance, |
| struct in6_addr *src, |
| struct in6_addr *dst); |
| |
| /** |
| * @brief Set the root DAG. |
| * |
| * @param iface Network interface to use. |
| * @param instance Pointer to instance object. |
| * @param dag_id IPv6 address of the DAG. |
| * |
| * @return DAG object or NULL if creation failed. |
| */ |
| struct net_rpl_dag *net_rpl_set_root(struct net_if *iface, |
| u8_t instance_id, |
| struct in6_addr *dag_id); |
| |
| /** |
| * @brief Set the root DAG with version. |
| * |
| * @param iface Network interface to use. |
| * @param instance Pointer to instance object. |
| * @param dag_id IPv6 address of the DAG. |
| * @param version Version number to use. |
| * |
| * @return DAG object or NULL if creation failed. |
| */ |
| struct net_rpl_dag *net_rpl_set_root_with_version(struct net_if *iface, |
| u8_t instance_id, |
| struct in6_addr *dag_id, |
| u8_t version); |
| |
| /** |
| * @brief Get first available DAG. |
| * |
| * @return First available DAG or NULL if none found. |
| */ |
| struct net_rpl_dag *net_rpl_get_any_dag(void); |
| |
| /** |
| * @brief Set IPv6 prefix we are using. |
| * |
| * @param iface Network interface in use. |
| * @param dag DAG in use. |
| * @param prefix IPv6 prefix we are using. |
| * @param prefix_len IPv6 prefix length. |
| * |
| * @return True if prefix could be set, false otherwise. |
| */ |
| bool net_rpl_set_prefix(struct net_if *iface, |
| struct net_rpl_dag *dag, |
| struct in6_addr *prefix, |
| u8_t prefix_len); |
| |
| /** |
| * @brief Do global repair for this route. |
| * |
| * @param route IPv6 route entry. |
| */ |
| void net_rpl_global_repair(struct net_route_entry *route); |
| |
| /** |
| * @brief Do global repair for this instance. |
| * |
| * @param instance RPL instance id. |
| */ |
| bool net_rpl_repair_root(u8_t instance_id); |
| |
| /** |
| * @brief Update RPL headers in IPv6 packet. |
| * |
| * @param pkt Network packet. |
| * @param addr IPv6 address of next hop host. |
| * |
| * @return 0 if ok, < 0 if error |
| */ |
| int net_rpl_update_header(struct net_pkt *pkt, struct in6_addr *addr); |
| |
| /** |
| * @brief Verify RPL header in IPv6 packet. |
| * |
| * @param pkt Network packet fragment list. |
| * @param frag Current network buffer fragment. |
| * @param offset Where the RPL header starts in the packet |
| * @param pos How long the RPL header was, this is returned to the caller. |
| * @param out result True if ok, false if error |
| * |
| * @return frag Returns the fragment where this call finished reading. |
| */ |
| struct net_buf *net_rpl_verify_header(struct net_pkt *pkt, struct net_buf *frag, |
| u16_t offset, u16_t *pos, |
| bool *result); |
| |
| /** |
| * @brief Insert RPL extension header to IPv6 packet. |
| * |
| * @param pkt Network packet. |
| * |
| * @return 0 if ok, <0 if error. |
| */ |
| int net_rpl_insert_header(struct net_pkt *pkt); |
| |
| /** |
| * @brief Revert RPL extension header to IPv6 packet. |
| * Revert flags, instance ID and sender rank in the packet. |
| * |
| * @param pkt Network packet. |
| * @param offset Where the HBH header starts in the packet |
| * @param pos How long the RPL header was, this is returned to the caller. |
| * |
| * @return 0 if ok, <0 if error. |
| */ |
| int net_rpl_revert_header(struct net_pkt *pkt, u16_t offset, u16_t *pos); |
| |
| /** |
| * @brief Get parent IPv6 address. |
| * |
| * @param iface Network interface |
| * @param parent Parent pointer |
| * |
| * @return Parent IPv6 address, or NULL if no such parent. |
| */ |
| struct in6_addr *net_rpl_get_parent_addr(struct net_if *iface, |
| struct net_rpl_parent *parent); |
| |
| typedef void (*net_rpl_parent_cb_t)(struct net_rpl_parent *parent, |
| void *user_data); |
| |
| /** |
| * @brief Go through all the parents entries and call callback |
| * for each entry that is in use. |
| * |
| * @param cb User supplied callback function to call. |
| * @param user_data User specified data. |
| * |
| * @return Total number of parents found. |
| */ |
| int net_rpl_foreach_parent(net_rpl_parent_cb_t cb, void *user_data); |
| |
| /** |
| * @brief Set the RPL mode (mesh or leaf) of this node. |
| * |
| * @param new_mode New RPL mode. Value is either NET_RPL_MODE_MESH, |
| * NET_RPL_MODE_FEATHER or NET_RPL_MODE_LEAF. The NET_RPL_MODE_MESH is |
| * the default mode. |
| */ |
| void net_rpl_set_mode(enum net_rpl_mode new_mode); |
| |
| /** |
| * @brief Get the RPL mode (mesh or leaf) of this node. |
| * |
| * @return Current RPL mode. |
| */ |
| enum net_rpl_mode net_rpl_get_mode(void); |
| |
| /** |
| * @brief Get the default RPL instance. |
| * |
| * @return Current default RPL instance. |
| */ |
| struct net_rpl_instance *net_rpl_get_default_instance(void); |
| |
| void net_rpl_init(void); |
| #else |
| #define net_rpl_init(...) |
| #define net_rpl_global_repair(...) |
| #define net_rpl_update_header(...) 0 |
| #endif /* CONFIG_NET_RPL */ |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| #endif /* __RPL_H */ |