blob: e0adb6eb6f8c012e0235889f0deff0eab4eac04d [file] [log] [blame]
/** @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 */