From e44115507121e51fbac4cd9d2b1a419ac246e7c6 Mon Sep 17 00:00:00 2001 From: rabinsahoo Date: Sat, 31 Oct 2020 18:27:45 +0530 Subject: [PATCH 1/4] Added data strcutures for rpl instnace, dodag, parent amd mc --- src/core/rpl_mrhof.h | 24 +++ src/core/rpl_of0.h | 23 +++ src/core/rpl_topology.h | 234 +++++++++++++++++++++++++++ src/core/rpl_types.h | 48 ++++++ src/include/rpl_objective_function.h | 32 ++++ 5 files changed, 361 insertions(+) create mode 100644 src/core/rpl_mrhof.h create mode 100644 src/core/rpl_of0.h create mode 100644 src/core/rpl_topology.h create mode 100644 src/core/rpl_types.h create mode 100644 src/include/rpl_objective_function.h diff --git a/src/core/rpl_mrhof.h b/src/core/rpl_mrhof.h new file mode 100644 index 0000000..b2256e0 --- /dev/null +++ b/src/core/rpl_mrhof.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2020 Authors of Tripple + * + * This file is subject to the terms and conditions. See the file LICENSE in + * the top level directory for more details. + */ + +/** + * @ingroup Include + * @{ + * + * @file + * @brief The Minimum Rank with Hysteresis Objective Function. + * + * @} + */ + + #ifndef _RPL_MRHOF_H_ + #define _RPL_MRHOF_H_ + + + #endif /*_RPL_MRHOF_H_*/ + + diff --git a/src/core/rpl_of0.h b/src/core/rpl_of0.h new file mode 100644 index 0000000..2bfb1e9 --- /dev/null +++ b/src/core/rpl_of0.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2020 Authors of Tripple + * + * This file is subject to the terms and conditions. See the file LICENSE in + * the top level directory for more details. + */ + +/** + * @ingroup Include + * @{ + * + * @file + * @brief Objective Function Zero for RPL. + * + * @} + */ + + #ifndef _RPL_OF0_H_ + #define _RPL_OF0_H_ + + + #endif /*_RPL_OF0_H_*/ + diff --git a/src/core/rpl_topology.h b/src/core/rpl_topology.h new file mode 100644 index 0000000..7eff60e --- /dev/null +++ b/src/core/rpl_topology.h @@ -0,0 +1,234 @@ +/* + * Copyright (C) 2020 Authors of Tripple + * + * This file is subject to the terms and conditions. See the file LICENSE in + * the top level directory for more details. + */ + +/** + * @ingroup UAPI + * @{ + * + * @file + * @brief Tripple Network topology components + * + * @} + */ + +#ifndef _RPL_TOPOLOGY_H_ +#define _RPL_TOPOLOGY_H_ + +#include "rpl_types.h" +#include "rpl_objective_function.h" + +#define RPL_MAX_NUM_THROUGHPUT 5 +#define RPL_MAX_LQL_VALUES 8 + +typedef enum rpl_node_type{ + RPL_NODE_TYPE_LEAF, + RPL_NODE_TYPE_LR, + RPL_NODE_TYPE_BR, + RPL_NODE_TYPE_NONE +}rpl_node_type; + +/* Node Metric or/and constraint Objects*/ +typedef enum rpl_mc_types{ + RPL_MC_TYPE_NSA = 1, /* Won't be supported */ + RPL_MC_TYPE_ENERGY , /* Will support this */ + RPL_MC_TYPE_HOP_COUNT, /* Will Support this */ + RPL_MC_TYPE_THROUGHPUT, /* Will support this */ + RPL_MC_TYPE_LATENCY, /* WIll Support This */ + RPL_MC_TYPE_LINK_RELIABILITY_LQL, /* Will Support This */ + RPL_MC_TYPE_NONE +}rpl_mc_types; + +/* RPL Prefix Information */ +typedef struct _rpl_dodag_prefix{ + uint32_t valid_lifetime; + uint32_t preferred_lifetime; + rpl_ipv6_prefix dodag_prefix; + uint8_t prefix_length; + +#define RPL_DODAG_PREFIX_USE_FOR_ONLINK_DETERMINATION 0x80 +#define RPL_DODAG_PREFIX_USE_FOR_SLAC 0x40 +#define RPL_DODAG_PREFIX_CONTAINS_COMPLETE_ADDRESS 0x20 + uint8_t prefix_flags; + uint8_t reserved[2]; +}rpl_dodag_prefix_t; + + +/* RPL Metrics + Routing Constraints are used to Prune the links and node that + don't satisfy the constraint. + + A routing Metric is a quantitative value that is used to evaluate the + path cost. + + The best path is the path that satisfies all supplied constraints (if any) + and that has the lowest cost with respect to some specified metrics. + + We will support both constraint and metric. + link and node characteristics can be used as constraints and/or metrics +*/ + +typedef struct _rpl_metric_constraint_common{ + uint8_t routing_mc_type; /* It Can be Metric or constrainnts */ + +#define RPL_DAG_MC_RESERVED_FLAGS 0xF800 /* Reserved */ +#define RPL_DAG_MC_METRIC_RECORDING_INFO 0x0400 /* P */ +#define RPL_DAG_MC_USE_AS_CONSTRAINT 0x0200 /* C */ +#define RPL_DAG_MC_CONSTRAINT_IS_OPTIONAL 0x0100 /* O */ +#define RPL_DAG_MC_RECORD_AGGREGATE 0x0080 /* R */ +#define RPL_DAG_MC_TYPE_AGGREGATED_M 0x0070 /* A */ +#define RPL_DAG_MC_PRECEDENCE 0x000F /* A */ + + uint16_t flags; /* P, C , O, R, A, Perc */ +}rpl_metric_constraint_common_t; + +/* Node Metrics */ +typedef struct _rpl_node_energy_object{ + rpl_metric_constraint_common_t stcmnInfo; +#define NE_OBJECT_INCLUSION_VS_EXCLUSION 0x08 +#define NE_OBJECT_NODE_TYPE_MP_BP_ES 0x06 +#define NE_OBJECT_EP_RE 0x01 /*Estimated Percentage Of + Remaining Energy*/ + uint8_t flags; + uint8_t estimated_energy; +}rpl_node_energy_object_t; + + +typedef struct _rpl_hop_count_object{ + rpl_metric_constraint_common_t stcmnInfo; + uint8_t hop_count; +}rpl_hop_count_object_t; + + +/* Link Metrics */ +typedef struct _rpl_throughput_object{ + rpl_metric_constraint_common_t stcmnInfo; + uint32_t throughput; +}rpl_throughput_object; + +/* Link Metrics */ +typedef struct _rpl_latency_object{ + rpl_metric_constraint_common_t stcmnInfo; + uint32_t latency; /* Can be a constraint or Metrics */ +}rpl_latency_object; + +typedef struct _rpl_lql_object{ + rpl_metric_constraint_common_t stcmnInfo; + /* Valid values for lql are from 0 to 7. + 0 - LQL is unknown + 1- Highest LQL. + for each encountered LQL value, only the number of matching links is + reported. */ + uint8_t values[RPL_MAX_LQL_VALUES]; +}rpl_lql_object_t; + +/*The ETX object may be used as a constraint or a path metric.*/ +typedef struct _rpl_etx_object{ + rpl_metric_constraint_common_t stcmnInfo; + uint16_t etx; /* Can be a constraint or Metrics */ +}rpl_etx_object; + + +typedef struct _rpl_link_metric{ + uint16_t etx; /* ETX using ETX_DIVISOR as fixed point divisor */ + int16_t rssi; /* RSSI (received signal strength) */ + uint16_t per_hop_latency; /* Link latency */ +}rpl_link_metric_t; +/* + Metric container can have multiple metrics ans constraints + We need to strore them in the order of their preference +*/ +typedef struct _rpl_dag_metric_container{ + void *metrics_constraints[RPL_NODE_TYPE_NONE]; +}rpl_dag_metric_container_t; + + +/* RPL Parent + An upstream node can be a parent for multiple DODAG belongs to multiple + instnace. + Note: Given an RPL Instance with multiple DODAG, A node can join + one DODAG in that instnace. + Usecase: In home mesh network we can have two DODAG one for the + Baterry operated appliances one for powerline operated + appliances both optimizing different matrics. + + Common Information of a parent across multiple Instnace: + 1- Parent Link Local Address + 2- Parent Link Layer address + 3- Parent Metric information (If all DODAG's of all instances uses + same Metric) + Information Specific to DODAG + 1- Parent Rank + 2- Metric Information if each DODAG have its own metric (Etx, Energy, Hop + Count) + 3- DODAG Specific Globar IP address + 4- DTSN (DAO Trigger Sequence Number) + + */ + +typedef struct _rpl_dag_neighbor{ + /* Neighbor Link Local Address */ + rpl_ipv6_address_t link_local_address; + rpl_link_metric_t link_metric_info; +}rpl_dag_neighbor_t; + +typedef struct _rpl_dag_parent{ + rpl_dag_neighbor_t *nbr_info; + rpl_rank_t rank; + rpl_dag_metric_container_t metric_info; + uint8_t dtsn; + uint8_t flags +}rpl_dag_parent_t; + +typedef struct _rpl_dodag_configs{ + uint16_t max_rank_incr; + uint16_t minhop_rank_incr; + uint16_t lifetime_uint; + uint8_t default_lifetime; + uint8_t dio_inter_doubling; + uint8_t dio_inter_min; + uint8_t dio_redundancy; + uint8_t flag_and_pcs; + uint8_t unused; +}rpl_dodag_configs_t; + +/* + RPL node can belong to one DODAG in a RPL Instance. So Its highly + possible a device can be part of multiple RPL instances. +*/ +typedef struct _rpl_dodag{ + rpl_dodag_configs_t dodag_config; + rpl_ipv6_address_t dodag_id; + rpl_dodag_prefix_t dodag_prefix; + rpl_ipv6_address_t target_address; + rpl_node_type node_role; + rpl_rank_t dodag_rank; + uint8_t dodag_version; + rpl_dag_parent_t *preferred_parent; + rpl_dag_parent_t *parent_list; +}rpl_dodag_t; + + +typedef struct _rpl_instnace{ + struct _rpl_instnace *next; + /* DODAGs Associated with it */ + rpl_dodag_t *dodag; + rpl_objective_function_cb *objfuns; + uint8_t rpl_instance_id; +}rpl_instnace_t; + + +/* A node can be part of multiple Instnace . + An instnace can have multiple DODAG + But a Node can be part of only one DODAG in an RPL instnace */ +typedef struct _rpl_node{ + rpl_instnace_t *rpl_instance_list; + power_type +}rpl_node_t; + + +#endif /*_RPL_TOPOLOGY_H_*/ + diff --git a/src/core/rpl_types.h b/src/core/rpl_types.h new file mode 100644 index 0000000..ade0dc8 --- /dev/null +++ b/src/core/rpl_types.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2020 Authors of Tripple + * + * This file is subject to the terms and conditions. See the file LICENSE in + * the top level directory for more details. + */ + +/** + * @ingroup CORE + * @{ + * + * @file + * @brief data types and constants + * + * @} + */ + +#ifndef _RPL_TYPES_H_ +#define _RPL_TYPES_H_ + +#include + +#define RPL_TRUE 1 +#define RPL_FALSE 0 + +/* Standard Data Types */ +typedef long long_t; +typedef unsigned long ulong_t; +typedef long long int64_t; +typedef unsigned long long uint64_t; +typedef uint8_t bool_t; +typedef uint16_t rpl_rank_t; + + +/* User Defined Data Types */ + +typedef struct _rpl_ipv6_address{ +union{ + uint8_t addr8[16]; + uint16_t addr16[8]; + uint32_t addr32[4]; + }ip6addr; +}rpl_ipv6_address_t; + +typedef rpl_ipv6_address_t rpl_ipv6_prefix; + + + diff --git a/src/include/rpl_objective_function.h b/src/include/rpl_objective_function.h new file mode 100644 index 0000000..d6c90d4 --- /dev/null +++ b/src/include/rpl_objective_function.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2020 Authors of Tripple + * + * This file is subject to the terms and conditions. See the file LICENSE in + * the top level directory for more details. + */ + +/** + * @ingroup Include + * @{ + * + * @file + * @brief RPL objective function interfaces. + * + * @} + */ + +#ifndef _RPL_OBJECTIVE_FUNCTION_ +#define _RPL_OBJECTIVE_FUNCTION_ + +#include + +typedef struct _rpl_objective_function{ + uint16_t (*pf_of_compute_path_cost)(void *rpl_parent); + uint16_t (*pf_of_compute_rank) (void *rpl_parent); + void * (*pf_of_select_preferred_parent)(void *parent_list); + void * (*pf_of_select_n_preferred_parent)(void *parent_list); +}rpl_objective_function_cb; + + +#endif /*_RPL_OBJECTIVE_FUNCTION_*/ + From f2dd034e66451f6522262eac38879052a9ad476d Mon Sep 17 00:00:00 2001 From: rabinsahoo Date: Sat, 5 Jun 2021 22:25:54 +0530 Subject: [PATCH 2/4] Added RPL Message handling --- include/rpl_configurations.h | 112 ++++++ src/core/rpl_ctrl_message.h | 80 +++++ src/core/rpl_instance_dodag.c | 135 ++++++++ src/core/rpl_utils.h | 43 +++ src/core/trickle.c | 63 ++++ src/core/trickle.h | 59 ++++ src/include/rpl_timer_interfaces.h | 52 +++ src/{core => include}/rpl_topology.h | 489 ++++++++++++++------------- 8 files changed, 799 insertions(+), 234 deletions(-) create mode 100644 include/rpl_configurations.h create mode 100644 src/core/rpl_ctrl_message.h create mode 100644 src/core/rpl_instance_dodag.c create mode 100644 src/core/rpl_utils.h create mode 100644 src/core/trickle.c create mode 100644 src/core/trickle.h create mode 100644 src/include/rpl_timer_interfaces.h rename src/{core => include}/rpl_topology.h (88%) diff --git a/include/rpl_configurations.h b/include/rpl_configurations.h new file mode 100644 index 0000000..d5121fc --- /dev/null +++ b/include/rpl_configurations.h @@ -0,0 +1,112 @@ +/** + * @file + * Tripple Configurations + */ + +/* + * Copyright (C) 2020 Authors of Tripple + * + * This file is subject to the terms and conditions. See the file LICENSE in + * the top level directory for more details. + */ + +/** + * @ingroup Include + * @{ + * + * @file + * @brief RPL Configurations + * + * @} + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#define RPL_SUPPORTED_FOR_LWIP 0x01 +#define RPL_SUPPORTED_FOR_UIP 0x02 +#define RPL_SUPPORTED_FOR_RIOT 0x03 + +/* Platform Related Configurations */ +#ifdef RPL_WITH_LWIP +#define RPL_PLATFORM RPL_SUPPORTED_FOR_LWIP +#define TIMER_INCLUDE "lwip_patimer.h" +#endif + +#ifdef RPL_WITH_UIP +#define RPL_PLATFORM RPL_SUPPORTED_FOR_UIP +#endif + +#ifdef RPL_WITH_RIOT +#define RPL_PLATFORM RPL_SUPPORTED_FOR_RIOT +#endif + +/* RPL Protocol Constants as per RFC 6550*/ + +#define DEFAULT_DIO_INTERVAL_MIN 3 +#define DEFAULT_DIO_INTERVAL_DOUBLINGS 20 +#define DEFAULT_DIO_REDUNDANCY_CONSTANT 10 + +#ifndef _RPL_CONFIGURATIONS_H_ +#define _RPL_CONFIGURATIONS_H_ + +#ifndef RPL_CONF_USE_STATIC_ALLOCATION +#define RPL_USE_STATIC_ALLOCATION 1 +#else +#define RPL_USE_STATIC_ALLOCATION RPL_CONF_USE_STATIC_ALLOCATION +#endif + +#if RPL_USE_STATIC_ALLOCATION + +#ifndef RPL_CONF_MAXIMUM_RPL_INSTNACE +#define RPL_MAXIMUM_RPL_INSTNACE 2 +#else +#define RPL_MAXIMUM_RPL_INSTNACE RPL_CONF_MAXIMUM_RPL_INSTNACE +#endif + +#endif + +/* Trickle Related Configurations */ +#ifndef RPL_CONF_DIO_INTERVAL_MIN +#define RPL_DIO_INTERVAL_MIN DEFAULT_DIO_INTERVAL_MIN +#else +#define RPL_DIO_INTERVAL_MIN RPL_CONF_DIO_INTERVAL_MIN +#endif + +#ifndef RPL_CONF_DIO_INTERVAL_DOUBLINGS +#define RPL_DIO_INTERVAL_DOUBLINGS DEFAULT_DIO_INTERVAL_DOUBLINGS +#else +#define RPL_DIO_INTERVAL_DOUBLINGS RPL_CONF_DIO_INTERVAL_DOUBLINGS +#endif + +#ifndef RPL_CONF_DIO_REDUNDANCY_CONSTANT +#define RPL_DIO_REDUNDANCY_CONSTANT DEFAULT_DIO_REDUNDANCY_CONSTANT +#else +#define RPL_DIO_REDUNDANCY_CONSTANT RPL_CONF_DIO_REDUNDANCY_CONSTANT +#endif + +/* Configuration common accross all the RPL instnaces a node + will be part of */ +typedef struct _rpl_node_configurations{ + +}rpl_node_configurations_t; + +/* In a given instnace a node can be part of only one DODAG + so it can have both instnace and DODAG specific configuration */ +typedef struct _rpl_instance_configuration{ + +}rpl_instance_configuration_t; + + +typedef struct _rpl_configurations{ + rpl_node_configurations_t stNodeConfig; + rpl_instance_configuration_t instance_config; +}rpl_configurations_t; + +#ifdef __cplusplus +} +#endif + +#endif /*_RPL_CONFIGURATIONS_H_*/ + \ No newline at end of file diff --git a/src/core/rpl_ctrl_message.h b/src/core/rpl_ctrl_message.h new file mode 100644 index 0000000..41cc48b --- /dev/null +++ b/src/core/rpl_ctrl_message.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2020 Authors of Tripple + * + * This file is subject to the terms and conditions. See the file LICENSE in + * the top level directory for more details. + */ + +/** + * @ingroup UAPI + * @{ + * + * @file + * @brief rpl control messages + * + * @} + */ + +#ifndef _RPL_CTRL_MESSAGE_H_ +#define _RPL_CTRL_MESSAGE_H_ + +#include +#include + +/* RPL Control message option types */ +#define RPL_CTRL_MSG_OPT_PAD1 0x00 +#define RPL_CTRL_MSG_OPT_PADN 0x01 +#define RPL_CTRL_MSG_OPT_DAG_MC 0x02 +#define RPL_CTRL_MSG_OPT_RIO 0x03 +#define RPL_CTRL_MSG_OPT_DODAG_CONFIG 0x04 +#define RPL_CTRL_MSG_OPT_TARGET_IO 0x05 +#define RPL_CTRL_MSG_OPT_TRANSIT_IO 0x06 +#define RPL_CTRL_MSG_OPT_SIO 0x07 +#define RPL_CTRL_MSG_OPT_PIO 0x08 +#define RPL_CTRL_MSG_OPT_TARGET_DO 0x09 + + +typedef struct _rpl_dio_message{ + uint8_t rpl_instnace_id; + uint8_t dodag_version; + rpl_rank_t sender_rank; + bool_t isgrounded; + uint8_t mode_of_op; + uint8_t dodag_preference; + uint8_t dtsn; + rpl_ipv6_address_t dodag_id; + rpl_dag_metric_container_t mc; + rpl_dodag_prefix_t prefix_information; + rpl_dodag_configs_t dodag_config; + rpl_routing_information_t route_information; +}rpl_dio_message_t; + +typedef struct _rpl_dis_message{ + rpl_ipv6_address_t dodag_id; + uint8_t rpl_instance_id; + uint8_t version; +#define RPL_SIO_VER_PREDICATE 0x80 +#define RPL_SIO_INSTANCEID_PREDICATE 0x40 +#define RPL_SIO_DODAGID_PREDICATE 0x20 + uint8_t flags; +}rpl_dis_message_t; + +int rpl_dis_input(rpl_protocol_context rpl_context, + rpl_icmpv6_context_t *rcvd_msg_ctx); +int rpl_dio_input(rpl_protocol_context rpl_context, + rpl_icmpv6_context_t *rcvd_msg_ctx); +int rpl_dao_input(rpl_protocol_context rpl_context, + rpl_icmpv6_context_t *rcvd_msg_ctx); +int rpl_dao_ack_input(rpl_protocol_context rpl_context, + rpl_icmpv6_context_t *rcvd_msg_ctx); +int rpl_dco_input(rpl_protocol_context rpl_context, + rpl_icmpv6_context_t *rcvd_msg_ctx); +int rpl_dco_ack_input(rpl_protocol_context rpl_context, + rpl_icmpv6_context_t *rcvd_msg_ctx); + +int rpl_send_dio(rpl_node_t *rplnode, rpl_instance_t *instance, + rpl_ipv6_address_t *destination); + + +#endif /*_RPL_CTRL_MESSAGE_PARSER_H_*/ + diff --git a/src/core/rpl_instance_dodag.c b/src/core/rpl_instance_dodag.c new file mode 100644 index 0000000..d24ef3f --- /dev/null +++ b/src/core/rpl_instance_dodag.c @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2020 Authors of Tripple + * + * This file is subject to the terms and conditions. See the file LICENSE in + * the top level directory for more details. + */ + +/** + * @ingroup CORE + * @{ + * + * @file + * @brief RPL Instance and DODAG related functions + * + * @} + */ + +#include +#include + +rpl_node_t g_rpl_node; + +#if RPL_USE_STATIC_ALLOCATION +rpl_instance_t g_rpl_instance_pool[RPL_MAXIMUM_RPL_INSTNACE]; +#endif + +rpl_instance_t * rpl_alloc_new_instnace(){ + rpl_instance_t *new_instance = NULL; + +#if RPL_USE_STATIC_ALLOCATION + int i = 0; + + for (; i < RPL_MAXIMUM_RPL_INSTNACE; i++){ + if (!g_rpl_instance_pool[i].is_used){ + memset(&(g_rpl_instance_pool[i]), 0, sizeof(rpl_instnace_t)); + new_instance = &(g_rpl_instance_pool[i]); + new_instance->is_used = RPL_TRUE; + break; + } + } +#else + /* Use Dynamic Memory Allocation */ +#endif + + return new_instance; +} + +rpl_instance_t *rpl_find_instnace(rpl_node_t *rpl_node, uint8_t instance_id){ + rpl_instance_t *cur_instnace = rpl_node->rpl_instance_list; + + while(cur_instnace){ + if (cur_instnace->rpl_instance_id == instance_id){ + break; + } + + cur_instnace = cur_instnace->next; + } + + return cur_instnace; +} + +rpl_protocol_context rpl_init(rpl_node_configurations_t *config){ + memset(&g_rpl_node, 0 , sizeof(rpl_node_t)); + g_rpl_node->node_config = *config; + return &g_rpl_node; +} + +int rpl_add_root_instance(rpl_protocol_context rpl_ctx, + rpl_instance_info_t *instnace_info){ + rpl_node_t *node = (rpl_node_t *)rpl_ctx; + rpl_instance_t *cur_instance = NULL; + rpl_dodag_t *cur_dodag = NULL; + bool_t poision_route = RPL_FALSE; + + if (NULL == rpl_ctx || NULL == instnace_info || + instnace_info->join_as_root == RPL_FALSE){ + return FAILURE; + } + + /* + A node at most will be part of one DODAG in one instnace. + It can be root of the DODAG or a normal node in that instnace. + */ + + cur_instance = rpl_find_instnace(node, instnace_info->instance_id); + if (cur_instance != NULL){ + /* Check if we have already joined a do dag in this instance and its + a root in that DODAG */ + if (cur_instance->dodag && cur_instance->dodag.node_role == + RPL_NODE_TYPE_BR){ + return RPL_ERR_INSTANCE_ROOT_EXISTS; + } + + /* + Node will act as BR in this current DODAG. It need the poision + the routes for which this is the forwarding node + */ + cur_dodag = &(cur_instance->dodag); + poision_route = RPL_TRUE; + } + else{ + cur_instance = rpl_alloc_new_instnace(); + if (NULL == cur_instance){ + return FAILURE; + } + + cur_instance->rpl_instance_id = instnace_info->instance_id; + cur_instance->next = node->rpl_instance_list; + node->rpl_instance_list = cur_instance; + + cur_dodag = &(cur_instance->dodag); + } + + /* Copy the information to DODAG */ + memcpy(cur_dodag->dodag_id.ip6addr.addr8, + instnace_info->dodag_id.ip6addr.addr8); + cur_dodag->dodag_prefix.prefix_length = instnace_info->prefix_length; + memcpy(cur_dodag->dodag_prefix.dodag_prefix.ip6addr.addr8, + instnace_info->prefix.ip6addr.addr8); + cur_dodag->node_role = RPL_NODE_TYPE_BR; + cur_dodag->is_grounded = instnace_info->isGrounded; + + /* RPL_TODO: Handle route poisioning */ + if (poision_route){ + } + + return SUCCESS; +} + + +int rpl_start(rpl_protocol_context rpl_ctx){ + +} + + diff --git a/src/core/rpl_utils.h b/src/core/rpl_utils.h new file mode 100644 index 0000000..ab47e93 --- /dev/null +++ b/src/core/rpl_utils.h @@ -0,0 +1,43 @@ +/** + * @file + * Tripple initialization API + */ + +/* + * Copyright (C) 2020 Authors of Tripple + * + * This file is subject to the terms and conditions. See the file LICENSE in + * the top level directory for more details. + */ + +/** + * @ingroup Core + * @{ + * + * @file + * @brief Common utility functions + * + * @} + */ + +#ifndef _RPL_UTILS_H_ +#define _RPL_UTILS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#define RPL_UTIL_IS_ADDR_MULTICAST(address) \ + (((address)->ip6addr.addr8[0]) == 0xFF) + +rpl_instance_t *rpl_find_instnace(rpl_node_t *rpl_node, uint8_t instance_id); + + +#ifdef __cplusplus +} +#endif + +#endif /*_RPL_UTILS_H_*/ + diff --git a/src/core/trickle.c b/src/core/trickle.c new file mode 100644 index 0000000..f11e8ae --- /dev/null +++ b/src/core/trickle.c @@ -0,0 +1,63 @@ + +#include + +static void rpl_handle_trickle_timeout(void *data) +{ + trickle_timer_t *trickle_timer = (trickle_timer_t *)data; + + /* If the Count is < redundancy constant or supression is disabled + need to perform the task */ + if (trickle_timer->bNeedTsend){ + if (trickle_timer->redundancy_constant == 0 || + trickle_timer->counter < trickle_timer->redundancy_constant){ + trickle_timer->handler(trickle_timer->data); + } + } + else{ + /* Move to Next Interval if we have not yet reached Imax */ + if (trickle_timer->cur_interval < (trickle_timer->interval_min + + trickle_timer->interval_doubling)){ + trickle_timer->cur_interval++; + } + + rpl_start_new_trickle_interval(trickle_timer); + } + + return; +} + + + +int rpl_start_new_trickle_interval(trickle_timer_t *trickle_timer){ + uint32_t interval; + uint32_t duration; + + /* This duration is in milliseconds */ + interval = 1U << trickle_timer->cur_interval; + + /*When an interval begins, Trickle resets c to 0 and sets t to a random point in the + interval, taken from the range [I/2, I)*/ + duration = interval/2; + trickle_timer->remain_delay_interval = interval - duration; + trickle_timer->counter = 0; + + /* Schedule the Time */ + + return SUCCESS; + +} + + +void rpl_reset_trickle_timer(trickle_timer_t *trickle_timer){ + /* If Current Interval 'I' is equal to Imin when Trickle hears an"inconsistent" transmission, + Trickle does nothing.*/ + if (trickle_timer->cur_interval > trickle_timer->interval_min){ + trickle_timer->cur_interval = trickle_timer->interval_min; + trickle_timer->counter = 0; + rpl_start_new_trickle_interval(trickle_timer); + } + + return; +} + + diff --git a/src/core/trickle.h b/src/core/trickle.h new file mode 100644 index 0000000..9627f82 --- /dev/null +++ b/src/core/trickle.h @@ -0,0 +1,59 @@ +/** + * @file + * Tripple initialization API + */ + +/* + * Copyright (C) 2020 Authors of Tripple + * + * This file is subject to the terms and conditions. See the file LICENSE in + * the top level directory for more details. + */ + +/** + * @ingroup Core + * @{ + * + * @file + * @brief Trickle algorithm + * + * @} + */ + +#ifndef _TRICKLE_H_ +#define _TRICKLE_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*pfTrickleTimerTimeoutHandler)(void *); + +typedef struct _trickle_timer{ + /* In the RPL the Trickle Interval MIN is specified in the term of + base 2 log(minumum_interval_size in ms) */ + uint8_t interval_min; + uint8_t interval_doubling; + uint8_t redundancy_constant; + + uint8_t cur_interval; + uint8_t counter; + bool_t bNeedTsend; + uint32_t remain_delay_interval; + pfTrickleTimerTimeoutHandler handler; + void *data; + +}trickle_timer_t; + +void rpl_reset_trickle_timer(trickle_timer_t *trickle_timer); +int rpl_start_new_trickle_interval(trickle_timer_t *trickle_timer); + + +#ifdef __cplusplus +} +#endif + +#endif /* _TRICKLE_H_ */ + diff --git a/src/include/rpl_timer_interfaces.h b/src/include/rpl_timer_interfaces.h new file mode 100644 index 0000000..e806e3c --- /dev/null +++ b/src/include/rpl_timer_interfaces.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2020 Authors of Tripple + * + * This file is subject to the terms and conditions. See the file LICENSE in + * the top level directory for more details. + */ + +/** + * @ingroup PAPI + * @{ + * + * @file + * @brief Timers + * + * @} + */ + +#ifndef _RPL_PAPI_TIMERS_H_ +#define _RPL_PAPI_TIMERS_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +typedef void* rpl_timer_t; +typedef enum _RPL_TIMER_TYPE +{ + RPL_TIMER_TYPE_PERIODIC, + RPL_TIMER_TYPE_ONCE +}RPL_TIMER_TYPE; + +/************************************************************ + Timer Related Interfaces. Each platform need to implement their own + interface. +*************************************************************/ + +/* Timer APIs to be used by the RPL Protocol*/ +/* Create the Timer */ +rpl_timer_t rpl_timer_create_timer_object(void,); + +/*Free the timer object*/ +void rpl_timer_free_timer_object(rpl_timer_t); + +/*Start + + +#ifdef __cplusplus + } +#endif + +#endif /*_RPL_PAPI_TIMERS_H_*/ + diff --git a/src/core/rpl_topology.h b/src/include/rpl_topology.h similarity index 88% rename from src/core/rpl_topology.h rename to src/include/rpl_topology.h index 7eff60e..08f7915 100644 --- a/src/core/rpl_topology.h +++ b/src/include/rpl_topology.h @@ -1,234 +1,255 @@ -/* - * Copyright (C) 2020 Authors of Tripple - * - * This file is subject to the terms and conditions. See the file LICENSE in - * the top level directory for more details. - */ - -/** - * @ingroup UAPI - * @{ - * - * @file - * @brief Tripple Network topology components - * - * @} - */ - -#ifndef _RPL_TOPOLOGY_H_ -#define _RPL_TOPOLOGY_H_ - -#include "rpl_types.h" -#include "rpl_objective_function.h" - -#define RPL_MAX_NUM_THROUGHPUT 5 -#define RPL_MAX_LQL_VALUES 8 - -typedef enum rpl_node_type{ - RPL_NODE_TYPE_LEAF, - RPL_NODE_TYPE_LR, - RPL_NODE_TYPE_BR, - RPL_NODE_TYPE_NONE -}rpl_node_type; - -/* Node Metric or/and constraint Objects*/ -typedef enum rpl_mc_types{ - RPL_MC_TYPE_NSA = 1, /* Won't be supported */ - RPL_MC_TYPE_ENERGY , /* Will support this */ - RPL_MC_TYPE_HOP_COUNT, /* Will Support this */ - RPL_MC_TYPE_THROUGHPUT, /* Will support this */ - RPL_MC_TYPE_LATENCY, /* WIll Support This */ - RPL_MC_TYPE_LINK_RELIABILITY_LQL, /* Will Support This */ - RPL_MC_TYPE_NONE -}rpl_mc_types; - -/* RPL Prefix Information */ -typedef struct _rpl_dodag_prefix{ - uint32_t valid_lifetime; - uint32_t preferred_lifetime; - rpl_ipv6_prefix dodag_prefix; - uint8_t prefix_length; - -#define RPL_DODAG_PREFIX_USE_FOR_ONLINK_DETERMINATION 0x80 -#define RPL_DODAG_PREFIX_USE_FOR_SLAC 0x40 -#define RPL_DODAG_PREFIX_CONTAINS_COMPLETE_ADDRESS 0x20 - uint8_t prefix_flags; - uint8_t reserved[2]; -}rpl_dodag_prefix_t; - - -/* RPL Metrics - Routing Constraints are used to Prune the links and node that - don't satisfy the constraint. - - A routing Metric is a quantitative value that is used to evaluate the - path cost. - - The best path is the path that satisfies all supplied constraints (if any) - and that has the lowest cost with respect to some specified metrics. - - We will support both constraint and metric. - link and node characteristics can be used as constraints and/or metrics -*/ - -typedef struct _rpl_metric_constraint_common{ - uint8_t routing_mc_type; /* It Can be Metric or constrainnts */ - -#define RPL_DAG_MC_RESERVED_FLAGS 0xF800 /* Reserved */ -#define RPL_DAG_MC_METRIC_RECORDING_INFO 0x0400 /* P */ -#define RPL_DAG_MC_USE_AS_CONSTRAINT 0x0200 /* C */ -#define RPL_DAG_MC_CONSTRAINT_IS_OPTIONAL 0x0100 /* O */ -#define RPL_DAG_MC_RECORD_AGGREGATE 0x0080 /* R */ -#define RPL_DAG_MC_TYPE_AGGREGATED_M 0x0070 /* A */ -#define RPL_DAG_MC_PRECEDENCE 0x000F /* A */ - - uint16_t flags; /* P, C , O, R, A, Perc */ -}rpl_metric_constraint_common_t; - -/* Node Metrics */ -typedef struct _rpl_node_energy_object{ - rpl_metric_constraint_common_t stcmnInfo; -#define NE_OBJECT_INCLUSION_VS_EXCLUSION 0x08 -#define NE_OBJECT_NODE_TYPE_MP_BP_ES 0x06 -#define NE_OBJECT_EP_RE 0x01 /*Estimated Percentage Of - Remaining Energy*/ - uint8_t flags; - uint8_t estimated_energy; -}rpl_node_energy_object_t; - - -typedef struct _rpl_hop_count_object{ - rpl_metric_constraint_common_t stcmnInfo; - uint8_t hop_count; -}rpl_hop_count_object_t; - - -/* Link Metrics */ -typedef struct _rpl_throughput_object{ - rpl_metric_constraint_common_t stcmnInfo; - uint32_t throughput; -}rpl_throughput_object; - -/* Link Metrics */ -typedef struct _rpl_latency_object{ - rpl_metric_constraint_common_t stcmnInfo; - uint32_t latency; /* Can be a constraint or Metrics */ -}rpl_latency_object; - -typedef struct _rpl_lql_object{ - rpl_metric_constraint_common_t stcmnInfo; - /* Valid values for lql are from 0 to 7. - 0 - LQL is unknown - 1- Highest LQL. - for each encountered LQL value, only the number of matching links is - reported. */ - uint8_t values[RPL_MAX_LQL_VALUES]; -}rpl_lql_object_t; - -/*The ETX object may be used as a constraint or a path metric.*/ -typedef struct _rpl_etx_object{ - rpl_metric_constraint_common_t stcmnInfo; - uint16_t etx; /* Can be a constraint or Metrics */ -}rpl_etx_object; - - -typedef struct _rpl_link_metric{ - uint16_t etx; /* ETX using ETX_DIVISOR as fixed point divisor */ - int16_t rssi; /* RSSI (received signal strength) */ - uint16_t per_hop_latency; /* Link latency */ -}rpl_link_metric_t; -/* - Metric container can have multiple metrics ans constraints - We need to strore them in the order of their preference -*/ -typedef struct _rpl_dag_metric_container{ - void *metrics_constraints[RPL_NODE_TYPE_NONE]; -}rpl_dag_metric_container_t; - - -/* RPL Parent - An upstream node can be a parent for multiple DODAG belongs to multiple - instnace. - Note: Given an RPL Instance with multiple DODAG, A node can join - one DODAG in that instnace. - Usecase: In home mesh network we can have two DODAG one for the - Baterry operated appliances one for powerline operated - appliances both optimizing different matrics. - - Common Information of a parent across multiple Instnace: - 1- Parent Link Local Address - 2- Parent Link Layer address - 3- Parent Metric information (If all DODAG's of all instances uses - same Metric) - Information Specific to DODAG - 1- Parent Rank - 2- Metric Information if each DODAG have its own metric (Etx, Energy, Hop - Count) - 3- DODAG Specific Globar IP address - 4- DTSN (DAO Trigger Sequence Number) - - */ - -typedef struct _rpl_dag_neighbor{ - /* Neighbor Link Local Address */ - rpl_ipv6_address_t link_local_address; - rpl_link_metric_t link_metric_info; -}rpl_dag_neighbor_t; - -typedef struct _rpl_dag_parent{ - rpl_dag_neighbor_t *nbr_info; - rpl_rank_t rank; - rpl_dag_metric_container_t metric_info; - uint8_t dtsn; - uint8_t flags -}rpl_dag_parent_t; - -typedef struct _rpl_dodag_configs{ - uint16_t max_rank_incr; - uint16_t minhop_rank_incr; - uint16_t lifetime_uint; - uint8_t default_lifetime; - uint8_t dio_inter_doubling; - uint8_t dio_inter_min; - uint8_t dio_redundancy; - uint8_t flag_and_pcs; - uint8_t unused; -}rpl_dodag_configs_t; - -/* - RPL node can belong to one DODAG in a RPL Instance. So Its highly - possible a device can be part of multiple RPL instances. -*/ -typedef struct _rpl_dodag{ - rpl_dodag_configs_t dodag_config; - rpl_ipv6_address_t dodag_id; - rpl_dodag_prefix_t dodag_prefix; - rpl_ipv6_address_t target_address; - rpl_node_type node_role; - rpl_rank_t dodag_rank; - uint8_t dodag_version; - rpl_dag_parent_t *preferred_parent; - rpl_dag_parent_t *parent_list; -}rpl_dodag_t; - - -typedef struct _rpl_instnace{ - struct _rpl_instnace *next; - /* DODAGs Associated with it */ - rpl_dodag_t *dodag; - rpl_objective_function_cb *objfuns; - uint8_t rpl_instance_id; -}rpl_instnace_t; - - -/* A node can be part of multiple Instnace . - An instnace can have multiple DODAG - But a Node can be part of only one DODAG in an RPL instnace */ -typedef struct _rpl_node{ - rpl_instnace_t *rpl_instance_list; - power_type -}rpl_node_t; - - -#endif /*_RPL_TOPOLOGY_H_*/ - +/* + * Copyright (C) 2020 Authors of Tripple + * + * This file is subject to the terms and conditions. See the file LICENSE in + * the top level directory for more details. + */ + +/** + * @ingroup UAPI + * @{ + * + * @file + * @brief Tripple Network topology components + * + * @} + */ + +#ifndef _RPL_TOPOLOGY_H_ +#define _RPL_TOPOLOGY_H_ + +#include "rpl_types.h" +#include "rpl_objective_function.h" +#include "rpl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define RPL_MAX_NUM_THROUGHPUT 5 +#define RPL_MAX_LQL_VALUES 8 + +typedef enum rpl_node_type{ + RPL_NODE_TYPE_LEAF, + RPL_NODE_TYPE_LR, + RPL_NODE_TYPE_BR, + RPL_NODE_TYPE_NONE +}rpl_node_type; + +/* Node Metric or/and constraint Objects*/ +typedef enum rpl_mc_types{ + RPL_MC_TYPE_NSA = 1, /* Won't be supported */ + RPL_MC_TYPE_ENERGY , /* Will support this */ + RPL_MC_TYPE_HOP_COUNT, /* Will Support this */ + RPL_MC_TYPE_THROUGHPUT, /* Will support this */ + RPL_MC_TYPE_LATENCY, /* WIll Support This */ + RPL_MC_TYPE_LINK_RELIABILITY_LQL, /* Will Support This */ + RPL_MC_TYPE_NONE +}rpl_mc_types; + +/* RPL Prefix Information */ +typedef struct _rpl_dodag_prefix{ + uint32_t valid_lifetime; + uint32_t preferred_lifetime; + rpl_ipv6_prefix dodag_prefix; + uint8_t prefix_length; + +#define RPL_DODAG_PREFIX_USE_FOR_ONLINK_DETERMINATION 0x80 +#define RPL_DODAG_PREFIX_USE_FOR_SLAC 0x40 +#define RPL_DODAG_PREFIX_CONTAINS_COMPLETE_ADDRESS 0x20 + uint8_t prefix_flags; + uint8_t reserved[2]; +}rpl_dodag_prefix_t; + + +/* Routing Information */ +typedef struct _rpl_routing_information{ + rpl_ipv6_prefix dodag_prefix; + uint32_t lifetime; + uint8_t prefix_length; + uint8_t preference; +}rpl_routing_information_t; + +/* RPL Metrics + Routing Constraints are used to Prune the links and node that + don't satisfy the constraint. + + A routing Metric is a quantitative value that is used to evaluate the + path cost. + + The best path is the path that satisfies all supplied constraints (if any) + and that has the lowest cost with respect to some specified metrics. + + We will support both constraint and metric. + link and node characteristics can be used as constraints and/or metrics +*/ + +typedef struct _rpl_metric_constraint_common{ + uint8_t routing_mc_type; /* It Can be Metric or constrainnts */ + +#define RPL_DAG_MC_RESERVED_FLAGS 0xF800 /* Reserved */ +#define RPL_DAG_MC_METRIC_RECORDING_INFO 0x0400 /* P */ +#define RPL_DAG_MC_USE_AS_CONSTRAINT 0x0200 /* C */ +#define RPL_DAG_MC_CONSTRAINT_IS_OPTIONAL 0x0100 /* O */ +#define RPL_DAG_MC_RECORD_AGGREGATE 0x0080 /* R */ +#define RPL_DAG_MC_TYPE_AGGREGATED_M 0x0070 /* A */ +#define RPL_DAG_MC_PRECEDENCE 0x000F /* A */ + + uint16_t flags; /* P, C , O, R, A, Perc */ +}rpl_metric_constraint_common_t; + +/* Node Metrics */ +typedef struct _rpl_node_energy_object{ + rpl_metric_constraint_common_t stcmnInfo; +#define NE_OBJECT_INCLUSION_VS_EXCLUSION 0x08 +#define NE_OBJECT_NODE_TYPE_MP_BP_ES 0x06 +#define NE_OBJECT_EP_RE 0x01 /*Estimated Percentage Of + Remaining Energy*/ + uint8_t flags; + uint8_t estimated_energy; +}rpl_node_energy_object_t; + + +typedef struct _rpl_hop_count_object{ + rpl_metric_constraint_common_t stcmnInfo; + uint8_t hop_count; +}rpl_hop_count_object_t; + + +/* Link Metrics */ +typedef struct _rpl_throughput_object{ + rpl_metric_constraint_common_t stcmnInfo; + uint32_t throughput; +}rpl_throughput_object; + +/* Link Metrics */ +typedef struct _rpl_latency_object{ + rpl_metric_constraint_common_t stcmnInfo; + uint32_t latency; /* Can be a constraint or Metrics */ +}rpl_latency_object; + +typedef struct _rpl_lql_object{ + rpl_metric_constraint_common_t stcmnInfo; + /* Valid values for lql are from 0 to 7. + 0 - LQL is unknown + 1- Highest LQL. + for each encountered LQL value, only the number of matching links is + reported. */ + uint8_t values[RPL_MAX_LQL_VALUES]; +}rpl_lql_object_t; + +/*The ETX object may be used as a constraint or a path metric.*/ +typedef struct _rpl_etx_object{ + rpl_metric_constraint_common_t stcmnInfo; + uint16_t etx; /* Can be a constraint or Metrics */ +}rpl_etx_object; + + +typedef struct _rpl_link_metric{ + uint16_t etx; /* ETX using ETX_DIVISOR as fixed point divisor */ + int16_t rssi; /* RSSI (received signal strength) */ + uint16_t per_hop_latency; /* Link latency */ +}rpl_link_metric_t; +/* + Metric container can have multiple metrics ans constraints + We need to strore them in the order of their preference +*/ +typedef struct _rpl_dag_metric_container{ + void *metrics_constraints[RPL_NODE_TYPE_NONE]; +}rpl_dag_metric_container_t; + + +/* RPL Parent + An upstream node can be a parent for multiple DODAG belongs to multiple + instnace. + Note: Given an RPL Instance with multiple DODAG, A node can join + one DODAG in that instnace. + Usecase: In home mesh network we can have two DODAG one for the + Baterry operated appliances one for powerline operated + appliances both optimizing different matrics. + + Common Information of a parent across multiple Instnace: + 1- Parent Link Local Address + 2- Parent Link Layer address + 3- Parent Metric information (If all DODAG's of all instances uses + same Metric) + Information Specific to DODAG + 1- Parent Rank + 2- Metric Information if each DODAG have its own metric (Etx, Energy, Hop + Count) + 3- DODAG Specific Globar IP address + 4- DTSN (DAO Trigger Sequence Number) + + */ + +typedef struct _rpl_dag_neighbor{ + /* Neighbor Link Local Address */ + rpl_ipv6_address_t link_local_address; + rpl_link_metric_t link_metric_info; +}rpl_dag_neighbor_t; + +typedef struct _rpl_dag_parent{ + rpl_dag_neighbor_t *nbr_info; + rpl_rank_t rank; + rpl_dag_metric_container_t metric_info; + uint8_t dtsn; + uint8_t flags +}rpl_dag_parent_t; + +typedef struct _rpl_dodag_configs{ + uint16_t max_rank_incr; + uint16_t minhop_rank_incr; + uint16_t lifetime_uint; + uint8_t default_lifetime; + uint8_t dio_inter_doubling; + uint8_t dio_inter_min; + uint8_t dio_redundancy; + uint8_t flag_and_pcs; + uint8_t unused; +}rpl_dodag_configs_t; + +/* + RPL node can belong to one DODAG in a RPL Instance. So Its highly + possible a device can be part of multiple RPL instances. +*/ +typedef struct _rpl_dodag{ + rpl_dodag_configs_t dodag_config; + rpl_ipv6_address_t dodag_id; + rpl_dodag_prefix_t dodag_prefix; + rpl_ipv6_address_t target_address; + rpl_node_type node_role; + rpl_rank_t dodag_rank; + uint8_t dodag_version; + uint8_t is_grounded; + rpl_dag_parent_t *preferred_parent; + rpl_dag_parent_t *parent_list; + rpl_instnace_t *instnace; +}rpl_dodag_t; + + +typedef struct _rpl_instance{ + struct _rpl_instnace *next; + + /*At most, a RPL node can belong to one DODAG in a RPL Instance */ + rpl_dodag_t dodag; + rpl_objective_function_cb *objfuns; + trickle_timer_t stTrickle; + uint8_t rpl_instance_id; + bool_t is_used; +}rpl_instance_t; + + +/* A node can be part of multiple Instnace . + An instnace can have multiple DODAG + But a Node can be part of only one DODAG in an RPL instnace */ +typedef struct _rpl_node{ + rpl_instance_t *rpl_instance_list; + rpl_configurations_t node_config; +}rpl_node_t; + +#ifdef __cplusplus +} +#endif + +#endif /*_RPL_TOPOLOGY_H_*/ + From ecba9717a68933ee14c364cadfc98f655e0864d4 Mon Sep 17 00:00:00 2001 From: rabinsahoo Date: Thu, 10 Jun 2021 06:14:40 +0530 Subject: [PATCH 3/4] Added memory mangement interfaces --- src/core/rpl_parents.c | 39 +++++++++++++++++ src/include/rpl_memory_mgmt.h | 74 +++++++++++++++++++++++++++++++ src/papi/rpl_memory_mgmt.c | 82 +++++++++++++++++++++++++++++++++++ 3 files changed, 195 insertions(+) create mode 100644 src/core/rpl_parents.c create mode 100644 src/include/rpl_memory_mgmt.h create mode 100644 src/papi/rpl_memory_mgmt.c diff --git a/src/core/rpl_parents.c b/src/core/rpl_parents.c new file mode 100644 index 0000000..8ed4be6 --- /dev/null +++ b/src/core/rpl_parents.c @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 Authors of Tripple + * + * This file is subject to the terms and conditions. See the file LICENSE in + * the top level directory for more details. + */ + +/** + * @ingroup Core + * @{ + * + * @file + * @brief RPL Parent list management + * + * @} + */ + +#include "rpl_topology.h" +#include "rpl_memory_mgmt.h" + +RPL_CREATE_MEMORY_MANAGER(rpl_dag_parent_t, + RPL_MAXIMUM_RPL_PARENT, parent_memory_manager); + + +rpl_dag_parent_t * rpl_add_new_parent() +{ + rpl_dag_parent_t *parent; + parent = rpl_memmgr_memalloc(parent_memory_manager, + sizeof(rpl_dag_parent_t)); + if (NULL == parent){ + return NULL; + } + + return parent; +} + + + + diff --git a/src/include/rpl_memory_mgmt.h b/src/include/rpl_memory_mgmt.h new file mode 100644 index 0000000..f8f9153 --- /dev/null +++ b/src/include/rpl_memory_mgmt.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2020 Authors of Tripple + * + * This file is subject to the terms and conditions. See the file LICENSE in + * the top level directory for more details. + */ + +/** + * @ingroup PAPI + * @{ + * + * @file + * @brief Memory Related Interfaces + * + * @} + */ + +#ifndef _RPL_MEMORY_MGMT_H_ +#define _RPL_MEMORY_MGMT_H_ + +#include "rpl_papi.h" +#include "rpl_topology.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MEMORY_TYPE_STATIC_FLAG 0x80 +#define MEMORY_TYPE_DYNAMIC_FLAG 0x40 + +typedef void rpl_memory_region; + +typedef struct _rpl_memory_manager{ +#if RPL_USE_STATIC_ALLOCATION + int count; + uint8_t *allocation_array; +#endif + uint32_t entry_size; + + /* For malloc based allocation this will be NULL for platform based + memory managers this can be point to the memory manager*/ + rpl_memory_region *memory; + uint8_t flags; +}rpl_memory_manager; + +/* Each Platform MUST implement their own Mmeory Menager if they + don't want to use the static based allocation */ +uint32_t rpl_initialize_memory_manager(rpl_memory_manager *, + uint32_t item_size); + +#if RPL_USE_STATIC_ALLOCATION +#define RPL_CREATE_MEMORY_MANAGER(type, count, name) \ + static type _##name##_mem[count]; \ + static char _##name##_track_alloc[count] = {0}; \ + static rpl_memory_manager name##_manager = {count, \ + _##name##_track_alloc, sizeof(type), \ + _##name##_mem, MEMORY_TYPE_STATIC_FLAG}; \ + static rpl_memory_manager *name = &(name##_manager) +#else +#define RPL_CREATE_MEMORY_MANAGER(type, count, name) \ + static rpl_memory_manager *name = NULL +#endif + +void *rpl_memmgr_memalloc(rpl_memory_manager *, uint32_t); +void rpl_memmgr_memfree(rpl_memory_manager *, void *); + +#define RPL_MEMORY_INIT + +#ifdef __cplusplus +} +#endif + +#endif /*_RPL_MEMORY_MGMT_H_*/ + diff --git a/src/papi/rpl_memory_mgmt.c b/src/papi/rpl_memory_mgmt.c new file mode 100644 index 0000000..15c6dd6 --- /dev/null +++ b/src/papi/rpl_memory_mgmt.c @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2020 Authors of Tripple + * + * This file is subject to the terms and conditions. See the file LICENSE in + * the top level directory for more details. + */ + +/** + * @ingroup PAPI + * @{ + * + * @file + * @brief Memory Related Interfaces + * + * @} + */ + +#include "rpl_memory_mgmt.h" + +static void *rpl_static_memmgr_memalloc(rpl_memory_manager *mem_mgr) +{ +#if RPL_USE_STATIC_ALLOCATION + int i = 0; + + for (; i < mem_mgr->count ; i++){ + if (mem_mgr->allocation_array[i] == 0){ + /* Increase the count to indicate memory is in use */ + mem_mgr->allocation_array[i] = 1; + return (void *)((char *)mem_mgr->memory + (i * mem_mgr->entry_size)); + } + } +#endif + + return NULL; + +} + +static void rpl_static_memmgr_memfree(rpl_memory_manager *mem_mgr, + void *memory) +{ +#if RPL_USE_STATIC_ALLOCATION + int index = 0; + + /* Find the index of the memory that will be freed.*/ + index = ((char *)memory - (char *)mem_mgr->memory)/mem_mgr->entry_size; + if (mem_mgr->allocation_array[index] > 0){ + mem_mgr->allocation_array[index] = 0; + } +#endif + + return; +} + +void *rpl_memmgr_memalloc(rpl_memory_manager *mem_mgr,uint32_t size) +{ + if (NULL == mem_mgr){ + return NULL; + } + + /* For Static Memory just return the next free index */ + if (mem_mgr->flags & MEMORY_TYPE_STATIC_FLAG){ + return rpl_static_memmgr_memalloc(mem_mgr); + } + else{ + return NULL; + } +} +void rpl_memmgr_memfree(rpl_memory_manager *mem_mgr, void *mem) +{ + if (NULL == mem_mgr || mem == NULL){ + return; + } + + /* For Static Memory just return the next free index */ + if (mem_mgr->flags & MEMORY_TYPE_STATIC_FLAG){ + return rpl_static_memmgr_memfree(mem_mgr, mem); + } + else{ + return; + } +} + From 1c95b423229f009f066299c1c2cfceda3bd42879 Mon Sep 17 00:00:00 2001 From: rabinsahoo Date: Thu, 10 Jun 2021 06:16:47 +0530 Subject: [PATCH 4/4] header file chnages --- include/rpl.h | 29 ++- include/rpl_configurations.h | 45 +++-- include/rpl_papi.h | 110 ++++++++--- include/rpl_uapi.h | 9 + src/Filelists.cmake | 24 ++- src/core/msg_handler.c | 264 ++++++++++++++++++++++++++- src/core/rpl_ctrl_message.h | 2 +- src/core/rpl_instance_dodag.c | 20 +- src/core/rpl_mrhof.h | 13 +- src/core/rpl_of0.h | 13 +- src/core/rpl_types.h | 24 +-- src/core/trickle.c | 1 + src/include/init.h | 3 - src/include/init.h.cmake.in | 3 - src/include/rpl_objective_function.h | 7 + src/include/rpl_timer_interfaces.h | 17 +- src/include/rpl_topology.h | 14 +- src/papi/papi_icmp6.c | 53 +++++- src/uapi/uapi_rpl.c | 15 ++ 19 files changed, 572 insertions(+), 94 deletions(-) diff --git a/include/rpl.h b/include/rpl.h index f66b4c0..191cea2 100644 --- a/include/rpl.h +++ b/include/rpl.h @@ -18,11 +18,34 @@ #ifndef _RPL_H_ #define _RPL_H_ +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + enum { - SUCCESS = 0, - FAILURE, - // Add specific return codes here + SUCCESS = 0, + FAILURE, + + // Add specific return codes here + RPL_ERR_INSTANCE_ROOT_EXISTS, }; +typedef struct _rpl_ipv6_address{ +union{ + uint8_t addr8[16]; + uint16_t addr16[8]; + uint32_t addr32[4]; + }ip6addr; +}rpl_ipv6_address_t; + +typedef rpl_ipv6_address_t rpl_ipv6_prefix; + +#ifdef __cplusplus +} +#endif + #endif // _RPL_H_ diff --git a/include/rpl_configurations.h b/include/rpl_configurations.h index d5121fc..2613163 100644 --- a/include/rpl_configurations.h +++ b/include/rpl_configurations.h @@ -20,36 +20,47 @@ * @} */ +#ifndef _RPL_CONFIGURATIONS_H_ +#define _RPL_CONFIGURATIONS_H_ + #ifdef __cplusplus extern "C" { #endif -#define RPL_SUPPORTED_FOR_LWIP 0x01 -#define RPL_SUPPORTED_FOR_UIP 0x02 -#define RPL_SUPPORTED_FOR_RIOT 0x03 - /* Platform Related Configurations */ + +#define RPL_SUPPORTED_FOR_LWIP 0x01 +#define RPL_SUPPORTED_FOR_UIP 0x02 +#define RPL_SUPPORTED_FOR_RIOT 0x03 +#define RPL_SUPPORTED_FOR_LINUX 0x04 + +#ifndef RPL_PLATFORM #ifdef RPL_WITH_LWIP #define RPL_PLATFORM RPL_SUPPORTED_FOR_LWIP #define TIMER_INCLUDE "lwip_patimer.h" #endif +#endif +#ifndef RPL_PLATFORM #ifdef RPL_WITH_UIP #define RPL_PLATFORM RPL_SUPPORTED_FOR_UIP #endif +#endif +#ifndef RPL_PLATFORM #ifdef RPL_WITH_RIOT #define RPL_PLATFORM RPL_SUPPORTED_FOR_RIOT #endif +#endif -/* RPL Protocol Constants as per RFC 6550*/ +#ifndef RPL_PLATFORM +#ifdef RPL_WITH_LINUX +#define RPL_PLATFORM RPL_SUPPORTED_FOR_LINUX +#endif +#endif -#define DEFAULT_DIO_INTERVAL_MIN 3 -#define DEFAULT_DIO_INTERVAL_DOUBLINGS 20 -#define DEFAULT_DIO_REDUNDANCY_CONSTANT 10 -#ifndef _RPL_CONFIGURATIONS_H_ -#define _RPL_CONFIGURATIONS_H_ +/* Static Mmeory Related Configuration */ #ifndef RPL_CONF_USE_STATIC_ALLOCATION #define RPL_USE_STATIC_ALLOCATION 1 @@ -65,8 +76,20 @@ extern "C" { #define RPL_MAXIMUM_RPL_INSTNACE RPL_CONF_MAXIMUM_RPL_INSTNACE #endif +#ifndef RPL_CONF_MAXIMUM_RPL_PARENT +#define RPL_MAXIMUM_RPL_PARENT 50 +#else +#define RPL_MAXIMUM_RPL_PARENT RPL_CONF_MAXIMUM_RPL_PARENT +#endif + #endif +/* RPL Protocol Constants as per RFC 6550*/ + +#define DEFAULT_DIO_INTERVAL_MIN 3 +#define DEFAULT_DIO_INTERVAL_DOUBLINGS 20 +#define DEFAULT_DIO_REDUNDANCY_CONSTANT 10 + /* Trickle Related Configurations */ #ifndef RPL_CONF_DIO_INTERVAL_MIN #define RPL_DIO_INTERVAL_MIN DEFAULT_DIO_INTERVAL_MIN @@ -109,4 +132,4 @@ typedef struct _rpl_configurations{ #endif #endif /*_RPL_CONFIGURATIONS_H_*/ - \ No newline at end of file + diff --git a/include/rpl_papi.h b/include/rpl_papi.h index 3bfdd13..16320c5 100644 --- a/include/rpl_papi.h +++ b/include/rpl_papi.h @@ -1,23 +1,87 @@ -/* - * Copyright (C) 2020 Authors of Tripple - * - * This file is subject to the terms and conditions. See the file LICENSE in - * the top level directory for more details. - */ - -/** - * @ingroup PAPI - * @{ - * - * @file - * @brief Tripple Platform API exported header - * - * @} - */ - -#ifndef _RPL_PAPI_H_ -#define _RPL_PAPI_H_ - -#include - -#endif // _RPL_PAPI_H_ +/* + * Copyright (C) 2020 Authors of Tripple + * + * This file is subject to the terms and conditions. See the file LICENSE in + * the top level directory for more details. + */ + +/** + * @ingroup PAPI + * @{ + * + * @file + * @brief Tripple Platform API exported header + * + * @} + */ + +#ifndef _RPL_PAPI_H_ +#define _RPL_PAPI_H_ + +#include "init.h" +#include "rpl.h" +#include "rpl_configurations.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Memory Related Functions */ +/* If some platform has its memory manager modules then + adopt it bu writting wrapper and register the below callbacks to handle the memory + allocation + */ +typedef void *(*pfmem_alloc)(size_t memsize); +typedef void (*pfmem_free)(void *memory); + +/********************************* + Message Processing APIs + *********************************/ +#define RPL_ICMPV6_MSG_TYPE 155 +#define RPL_CTRL_MSG_CODE_DIS 0x00 +#define RPL_CTRL_MSG_CODE_DIO 0x01 +#define RPL_CTRL_MSG_CODE_DAO 0x02 +#define RPL_CTRL_MSG_CODE_DAO_ACK 0x03 +#define RPL_CTRL_MSG_CODE_DCO 0x04 +#define RPL_CTRL_MSG_CODE_DCO_ACK 0x05 + +typedef struct _rpl_icmpv6_context{ + uint8_t *icmpv6_msg_buff; /* ICMPv6 Message Buffer */ + uint16_t length; /* ICMPv6 Message length */ + rpl_ipv6_address_t *src_addr; + rpl_ipv6_address_t *dest_addr; + void *upperlayer_context; +}rpl_icmpv6_context_t; + +/* Callback to send ICMPV6 message */ +typedef int (*pfrpl_send_rpl_message)(rpl_icmpv6_context_t *message_ctx); +typedef struct _rpl_upperlayer_hooks{ + pfrpl_send_rpl_message pfsendmsg; +}rpl_upperlayer_hooks_t; + + +/* Modules initialization */ +typedef void * rpl_protocol_context; +typedef struct _rpl_instance_info{ + rpl_ipv6_address_t dodag_id; + rpl_ipv6_address_t prefix; + uint8_t prefix_length; + uint8_t instance_id; + uint8_t join_as_root; + uint8_t isGrounded; + rpl_instance_configuration_t config; +}rpl_instance_info_t; +rpl_protocol_context rpl_init(rpl_node_configurations_t *config); +int rpl_add_root_instance(rpl_protocol_context rpl_ctx, + rpl_instance_info_t *instnace_info); +int rpl_start(rpl_protocol_context rpl_ctx); + +int rpl_icmp6_handler(rpl_protocol_context rpl_ctx, + rpl_icmpv6_context_t *msg_context); + +#ifdef __cplusplus +} +#endif + +#endif /*_RPL_PAPI_H_*/ + diff --git a/include/rpl_uapi.h b/include/rpl_uapi.h index 0f4b145..e7a89bf 100644 --- a/include/rpl_uapi.h +++ b/include/rpl_uapi.h @@ -20,4 +20,13 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + + #endif // _RPL_UAPI_H_ diff --git a/src/Filelists.cmake b/src/Filelists.cmake index 23ff180..f4b5fd2 100644 --- a/src/Filelists.cmake +++ b/src/Filelists.cmake @@ -31,18 +31,22 @@ else ("${TRPL_VERSION_RC}" STREQUAL "TRPL_RC_RELEASE") endif ("${TRPL_VERSION_RC}" STREQUAL "TRPL_RC_RELEASE") # The minimum set of files needed for tripple. -set(trplcore_SRCS - ${TRPL_DIR}/src/core/msg_handler.c -) +#set(trplcore_SRCS +# ${TRPL_DIR}/src/core/msg_handler.c +#) -set(trpluapi_SRCS - ${TRPL_DIR}/src/uapi/uapi_rpl.c -) +#set(trpluapi_SRCS +# ${TRPL_DIR}/src/uapi/uapi_rpl.c +#) # APIFILES: The files which implement the sequential and socket APIs. -set(trplpapi_SRCS - ${TRPL_DIR}/src/papi/papi_icmp6.c -) +#set(trplpapi_SRCS +# ${TRPL_DIR}/src/papi/papi_icmp6.c +#) + +aux_source_directory(${TRPL_DIR}/src/core/ trplcore_SRCS) +aux_source_directory(${TRPL_DIR}/src/papi/ trplpapi_SRCS) +aux_source_directory(${TRPL_DIR}/src/uapi/ trpluapi_SRCS) # All TRPL files without apps set(trplall_SRCS @@ -77,7 +81,7 @@ configure_file(${TRPL_DIR}/src/include/init.h.cmake.in ${TRPL_DIR}/src/include/i # Tripple library add_library(rplcore ${trplall_SRCS}) -include_directories(include src/include) +include_directories(include src/include src/papi src/core) target_compile_options(rplcore PRIVATE ${TRPL_COMPILER_FLAGS}) target_compile_definitions(rplcore PRIVATE ${TRPL_DEFINITIONS}) target_include_directories(rplcore PRIVATE ${TRPL_INCLUDE_DIRS}) diff --git a/src/core/msg_handler.c b/src/core/msg_handler.c index 8274f24..6a90640 100644 --- a/src/core/msg_handler.c +++ b/src/core/msg_handler.c @@ -15,14 +15,272 @@ * @} */ -#include +#include "rpl.h" +#include "rpl_ctrl_message.h" +#include "rpl_utils.h" + +#define RPL_MSG_ICMPV6_HEADER_SIZE 4U +#define RPL_DIS_MSG_BASE_OBJ_SIZE 2U +#define RPL_CTRL_MSG_OPTIONS_FIXED_SIZE 2U +#define RPL_CTRL_MSG_OPT_PAD1_LEN 1U +#define RPL_SIO_VID_MASK 0xE0 /** * @brief RPL Message handler * * @return SUCCESS/FAILURE */ -int msg_handler(void) + +/* + 0 1 2 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Flags | Reserved | Option(s)... ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +Options: Pad1, PadN and Solicited Information Option + + RPL_Instance ID(1) + Flag(1) + DODAG_ID (16) + Version Number (1) = 19 + */ + +#define RPL_SIO_OPTION_DATA_SIZE 19U +static int rpl_parse_solicited_info_option_data(uint8_t *msg_buffer, + uint16_t offset, uint16_t opt_data_length, + rpl_dis_message_t *dis_msg) { - return SUCCESS; + uint16_t cur_index = offset; + + if (opt_data_length < RPL_SIO_OPTION_DATA_SIZE){ + return FAILURE; + } + + dis_msg->rpl_instance_id = msg_buffer[cur_index++]; + dis_msg->flags = msg_buffer[cur_index++]; + memcpy(dis_msg->dodag_id.ip6addr.addr8, (msg_buffer + cur_index), + sizeof(dis_msg->dodag_id)); + + return SUCCESS; + +} + +static void rpl_handle_mcast_dis(rpl_node_t *rplnode, + rpl_icmpv6_context_t *rcvd_msg_ctx, rpl_dis_message_t *dis_msg) +{ + rpl_instance_t *instance; + + /* Check if Solicited Information is present or not. + If its present but all predicate are not set then no need to reset + the trickle just return + */ + if (dis_msg->flags & RPL_SIO_VID_MASK){ + /* If all predicate are not set then return */ + if (dis_msg->flags & RPL_SIO_VID_MASK != + (RPL_SIO_VER_PREDICATE | RPL_SIO_INSTANCEID_PREDICATE | + RPL_SIO_DODAGID_PREDICATE)){ + return; + } + + /* Find the RPL Instnace By uisng the instnace-id received in the SIO */ + instance = rpl_find_instnace(rplnode, dis_msg->rpl_instance_id); + if (NULL == instance){ + return; + } + + if (instance->dodag.node_role == RPL_NODE_TYPE_LEAF + || memcmp(&(instance->dodag.dodag_id), &(dis_msg->dodag_id), + sizeof(rpl_ipv6_address_t)) || + instance->dodag.dodag_version != dis_msg->version){ + return; + } + + /* Reste the DIO trickle timer */ + } + else{ + /* Scan All the RPL Instnaces and reset the trickle timer , if the node + is not a leaf node in that instance*/ + instance = rplnode->rpl_instance_list; + while (instance){ + if (instance->dodag.node_role != RPL_NODE_TYPE_LEAF){ + /* Reset the DIO trickle TImer */ + } + + instance = instance->next; + } + } +} + +static void rpl_handle_ucast_dis(rpl_node_t *rplnode, + rpl_icmpv6_context_t *rcvd_msg_ctx, rpl_dis_message_t *dis_msg) +{ + rpl_instance_t *cur_instance; + + /* For Unicast DIS if Solicited Information is not present then just send + the unicast DIO */ + if (dis_msg->flags & RPL_SIO_VID_MASK){ + if (dis_msg->flags & RPL_SIO_INSTANCEID_PREDICATE){ + cur_instance = rpl_find_instnace(rplnode, dis_msg->rpl_instance_id); + if (NULL == cur_instance){ + return; + } + + /* If DODAG and Version Predicate are valid check them else + send a DIO using this instnace */ + if ((dis_msg->flags & RPL_SIO_DODAGID_PREDICATE && + memcmp(&(cur_instance->dodag.dodag_id), &(dis_msg->dodag_id), + sizeof(rpl_ipv6_address_t))) || + ((dis_msg->flags & RPL_SIO_VER_PREDICATE) && + cur_instance->dodag.dodag_version != dis_msg->version)){ + return; + } + + /* Send DIO Message to the destination address */ + rpl_send_dio(rplnode, cur_instance, rcvd_msg_ctx->dest_addr); + } + } + else{ + /* Should we send the DIO message for each of the RPL instnace a Node + is part of ?*/ + cur_instance = rplnode->rpl_instance_list; + while(cur_instance){ + rpl_send_dio(rplnode, cur_instance, rcvd_msg_ctx->dest_addr); + cur_instance = cur_instance->next; + } + } + + return; +} + +static int rpl_handle_dis(rpl_protocol_context rpl_context, + rpl_icmpv6_context_t *rcvd_msg_ctx, rpl_dis_message_t *dis_msg) +{ + rpl_node_t *rplnode = (rpl_node_t *)rpl_context; + if (RPL_UTIL_IS_ADDR_MULTICAST(rcvd_msg_ctx->dest_addr)){ + rpl_handle_mcast_dis(rplnode, rcvd_msg_ctx, dis_msg); + } + else{ + /* Unicast DIS */ + rpl_handle_ucast_dis(rplnode, rcvd_msg_ctx, dis_msg); + } + + return SUCCESS; } + +int rpl_dis_input(rpl_protocol_context rpl_context, + rpl_icmpv6_context_t *rcvd_msg_ctx) +{ + uint8_t *msg_buffer = (rcvd_msg_ctx->icmpv6_msg_buff + + RPL_MSG_ICMPV6_HEADER_SIZE); + uint16_t msg_length = rcvd_msg_ctx->length - RPL_MSG_ICMPV6_HEADER_SIZE; + uint16_t opts_length; + uint8_t cur_index; + uint8_t opt_type; + uint8_t cur_opt_length; + rpl_dis_message_t dis_msg; + int retval = SUCCESS; + + /* Validate Base Object Length */ + if (msg_length < RPL_DIS_MSG_BASE_OBJ_SIZE){ + return FAILURE; + } + + opts_length = msg_length - RPL_DIS_MSG_BASE_OBJ_SIZE; + cur_index = RPL_DIS_MSG_BASE_OBJ_SIZE; + if (opts_length > 0){ + while (opts_length >= RPL_CTRL_MSG_OPTIONS_FIXED_SIZE){ + /* Get the Option Type and Length */ + opt_type = msg_buffer[cur_index++]; + if (opt_type == RPL_CTRL_MSG_OPT_PAD1){ + opts_length -= RPL_CTRL_MSG_OPT_PAD1_LEN; + continue; + } + + cur_opt_length = msg_buffer[cur_index++]; + + /* Validate Data is present. PADN can only have length 0*/ + if ((!cur_opt_length && opt_type != RPL_CTRL_MSG_OPT_PADN) || + ((opts_length - RPL_CTRL_MSG_OPTIONS_FIXED_SIZE) < + cur_opt_length)){ + return FAILURE; + } + + switch (opt_type){ + case RPL_CTRL_MSG_OPT_PADN: + opts_length -= cur_opt_length; + break; + case RPL_CTRL_MSG_OPT_SIO: + if (rpl_parse_solicited_info_option_data(msg_buffer, + cur_index, cur_opt_length, &dis_msg) != SUCCESS){ + return FAILURE; + } + + opts_length -= cur_opt_length; + cur_index += cur_opt_length; + break; + default: + /* Option Type value is not recognized by the receiver, the receiver + MUST silently ignore the unrecognized option */ + opts_length -= cur_opt_length; + cur_index += cur_opt_length; + } + } + } + + retval = rpl_handle_dis(rpl_context, rcvd_msg_ctx, &dis_msg); + return retval; +} + +int rpl_dio_input(rpl_protocol_context rpl_context, + rpl_icmpv6_context_t *rcvd_msg_ctx) +{ + uint8_t *msg_buffer = (rcvd_msg_ctx->icmpv6_msg_buff + + RPL_MSG_ICMPV6_HEADER_SIZE); + uint16_t msg_length = rcvd_msg_ctx->length - RPL_MSG_ICMPV6_HEADER_SIZE; + uint16_t cur_index = 0; + uint16_t bytes_parsed = 0; +} + +int rpl_dao_input(rpl_protocol_context rpl_context, + rpl_icmpv6_context_t *rcvd_msg_ctx) +{ + uint8_t *msg_buffer = (rcvd_msg_ctx->icmpv6_msg_buff + + RPL_MSG_ICMPV6_HEADER_SIZE); + uint16_t msg_length = rcvd_msg_ctx->length - RPL_MSG_ICMPV6_HEADER_SIZE; + uint16_t cur_index = 0; + uint16_t bytes_parsed = 0; +} + +int rpl_dao_ack_input(rpl_protocol_context rpl_context, + rpl_icmpv6_context_t *rcvd_msg_ctx) +{ + uint8_t *msg_buffer = (rcvd_msg_ctx->icmpv6_msg_buff + + RPL_MSG_ICMPV6_HEADER_SIZE); + uint16_t msg_length = rcvd_msg_ctx->length - RPL_MSG_ICMPV6_HEADER_SIZE; + uint16_t cur_index = 0; + uint16_t bytes_parsed = 0; +} + +int rpl_dco_input(rpl_protocol_context rpl_context, + rpl_icmpv6_context_t *rcvd_msg_ctx) +{ + uint8_t *msg_buffer = (rcvd_msg_ctx->icmpv6_msg_buff + + RPL_MSG_ICMPV6_HEADER_SIZE); + uint16_t msg_length = rcvd_msg_ctx->length - RPL_MSG_ICMPV6_HEADER_SIZE; + uint16_t cur_index = 0; + uint16_t bytes_parsed = 0; +} + +int rpl_dco_ack_input(rpl_protocol_context rpl_context, + rpl_icmpv6_context_t *rcvd_msg_ctx) +{ + uint8_t *msg_buffer = (rcvd_msg_ctx->icmpv6_msg_buff + + RPL_MSG_ICMPV6_HEADER_SIZE); + uint16_t msg_length = rcvd_msg_ctx->length - RPL_MSG_ICMPV6_HEADER_SIZE; + uint16_t cur_index = 0; + uint16_t bytes_parsed = 0; +} + + +int rpl_send_dio(rpl_node_t *rplnode, rpl_instance_t *instance, + rpl_ipv6_address_t *destination){ +} + diff --git a/src/core/rpl_ctrl_message.h b/src/core/rpl_ctrl_message.h index 41cc48b..81ed6d1 100644 --- a/src/core/rpl_ctrl_message.h +++ b/src/core/rpl_ctrl_message.h @@ -19,7 +19,7 @@ #define _RPL_CTRL_MESSAGE_H_ #include -#include +#include "rpl_papi.h" /* RPL Control message option types */ #define RPL_CTRL_MSG_OPT_PAD1 0x00 diff --git a/src/core/rpl_instance_dodag.c b/src/core/rpl_instance_dodag.c index d24ef3f..5af9ee0 100644 --- a/src/core/rpl_instance_dodag.c +++ b/src/core/rpl_instance_dodag.c @@ -15,8 +15,7 @@ * @} */ -#include -#include +#include "rpl_topology.h" rpl_node_t g_rpl_node; @@ -32,7 +31,7 @@ rpl_instance_t * rpl_alloc_new_instnace(){ for (; i < RPL_MAXIMUM_RPL_INSTNACE; i++){ if (!g_rpl_instance_pool[i].is_used){ - memset(&(g_rpl_instance_pool[i]), 0, sizeof(rpl_instnace_t)); + memset(&(g_rpl_instance_pool[i]), 0, sizeof(rpl_instance_t)); new_instance = &(g_rpl_instance_pool[i]); new_instance->is_used = RPL_TRUE; break; @@ -61,8 +60,8 @@ rpl_instance_t *rpl_find_instnace(rpl_node_t *rpl_node, uint8_t instance_id){ rpl_protocol_context rpl_init(rpl_node_configurations_t *config){ memset(&g_rpl_node, 0 , sizeof(rpl_node_t)); - g_rpl_node->node_config = *config; - return &g_rpl_node; + g_rpl_node.config.stNodeConfig = *config; + return (rpl_protocol_context)(&g_rpl_node); } int rpl_add_root_instance(rpl_protocol_context rpl_ctx, @@ -86,8 +85,7 @@ int rpl_add_root_instance(rpl_protocol_context rpl_ctx, if (cur_instance != NULL){ /* Check if we have already joined a do dag in this instance and its a root in that DODAG */ - if (cur_instance->dodag && cur_instance->dodag.node_role == - RPL_NODE_TYPE_BR){ + if (cur_instance->dodag.node_role == RPL_NODE_TYPE_BR){ return RPL_ERR_INSTANCE_ROOT_EXISTS; } @@ -113,10 +111,12 @@ int rpl_add_root_instance(rpl_protocol_context rpl_ctx, /* Copy the information to DODAG */ memcpy(cur_dodag->dodag_id.ip6addr.addr8, - instnace_info->dodag_id.ip6addr.addr8); + instnace_info->dodag_id.ip6addr.addr8, + sizeof(instnace_info->dodag_id.ip6addr)); cur_dodag->dodag_prefix.prefix_length = instnace_info->prefix_length; memcpy(cur_dodag->dodag_prefix.dodag_prefix.ip6addr.addr8, - instnace_info->prefix.ip6addr.addr8); + instnace_info->prefix.ip6addr.addr8, + sizeof(instnace_info->dodag_id.ip6addr)); cur_dodag->node_role = RPL_NODE_TYPE_BR; cur_dodag->is_grounded = instnace_info->isGrounded; @@ -129,7 +129,7 @@ int rpl_add_root_instance(rpl_protocol_context rpl_ctx, int rpl_start(rpl_protocol_context rpl_ctx){ - + /* Here we will start the timers based on the node type */ } diff --git a/src/core/rpl_mrhof.h b/src/core/rpl_mrhof.h index b2256e0..7fec9a9 100644 --- a/src/core/rpl_mrhof.h +++ b/src/core/rpl_mrhof.h @@ -15,10 +15,17 @@ * @} */ - #ifndef _RPL_MRHOF_H_ - #define _RPL_MRHOF_H_ +#ifndef _RPL_MRHOF_H_ +#define _RPL_MRHOF_H_ +#ifdef __cplusplus +extern "C" { +#endif - #endif /*_RPL_MRHOF_H_*/ +#ifdef __cplusplus +} +#endif + +#endif /*_RPL_MRHOF_H_*/ diff --git a/src/core/rpl_of0.h b/src/core/rpl_of0.h index 2bfb1e9..33173a3 100644 --- a/src/core/rpl_of0.h +++ b/src/core/rpl_of0.h @@ -15,9 +15,16 @@ * @} */ - #ifndef _RPL_OF0_H_ - #define _RPL_OF0_H_ +#ifndef _RPL_OF0_H_ +#define _RPL_OF0_H_ +#ifdef __cplusplus +extern "C" { +#endif - #endif /*_RPL_OF0_H_*/ +#ifdef __cplusplus +} +#endif + +#endif /*_RPL_OF0_H_*/ diff --git a/src/core/rpl_types.h b/src/core/rpl_types.h index ade0dc8..c7efd91 100644 --- a/src/core/rpl_types.h +++ b/src/core/rpl_types.h @@ -19,30 +19,30 @@ #define _RPL_TYPES_H_ #include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif #define RPL_TRUE 1 #define RPL_FALSE 0 /* Standard Data Types */ -typedef long long_t; +/*typedef long long_t; typedef unsigned long ulong_t; typedef long long int64_t; -typedef unsigned long long uint64_t; +typedef unsigned long long uint64_t;*/ typedef uint8_t bool_t; typedef uint16_t rpl_rank_t; /* User Defined Data Types */ -typedef struct _rpl_ipv6_address{ -union{ - uint8_t addr8[16]; - uint16_t addr16[8]; - uint32_t addr32[4]; - }ip6addr; -}rpl_ipv6_address_t; - -typedef rpl_ipv6_address_t rpl_ipv6_prefix; +#ifdef __cplusplus +} +#endif - +#endif /*_RPL_TYPES_H_*/ diff --git a/src/core/trickle.c b/src/core/trickle.c index f11e8ae..35fb067 100644 --- a/src/core/trickle.c +++ b/src/core/trickle.c @@ -1,4 +1,5 @@ +#include "rpl.h" #include static void rpl_handle_trickle_timeout(void *data) diff --git a/src/include/init.h b/src/include/init.h index 3cfcd54..f132e52 100644 --- a/src/include/init.h +++ b/src/include/init.h @@ -76,9 +76,6 @@ extern "C" { * @} */ -/* Modules initialization */ -void rpl_init(void); - #ifdef __cplusplus } #endif diff --git a/src/include/init.h.cmake.in b/src/include/init.h.cmake.in index a73241c..2d6b3a4 100644 --- a/src/include/init.h.cmake.in +++ b/src/include/init.h.cmake.in @@ -76,9 +76,6 @@ extern "C" { * @} */ -/* Modules initialization */ -void rpl_init(void); - #ifdef __cplusplus } #endif diff --git a/src/include/rpl_objective_function.h b/src/include/rpl_objective_function.h index d6c90d4..6034850 100644 --- a/src/include/rpl_objective_function.h +++ b/src/include/rpl_objective_function.h @@ -20,6 +20,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + typedef struct _rpl_objective_function{ uint16_t (*pf_of_compute_path_cost)(void *rpl_parent); uint16_t (*pf_of_compute_rank) (void *rpl_parent); @@ -27,6 +31,9 @@ typedef struct _rpl_objective_function{ void * (*pf_of_select_n_preferred_parent)(void *parent_list); }rpl_objective_function_cb; +#ifdef __cplusplus +} +#endif #endif /*_RPL_OBJECTIVE_FUNCTION_*/ diff --git a/src/include/rpl_timer_interfaces.h b/src/include/rpl_timer_interfaces.h index e806e3c..b53613a 100644 --- a/src/include/rpl_timer_interfaces.h +++ b/src/include/rpl_timer_interfaces.h @@ -22,27 +22,38 @@ extern "C" { #endif -typedef void* rpl_timer_t; typedef enum _RPL_TIMER_TYPE { RPL_TIMER_TYPE_PERIODIC, RPL_TIMER_TYPE_ONCE }RPL_TIMER_TYPE; +typedef void* rpl_timer_t; + /************************************************************ Timer Related Interfaces. Each platform need to implement their own interface. *************************************************************/ +/* Callback for timeout */ + +typedef void (*fpRplTimerTimeoutHandler)(void *user_data); /* Timer APIs to be used by the RPL Protocol*/ /* Create the Timer */ -rpl_timer_t rpl_timer_create_timer_object(void,); +rpl_timer_t rpl_timer_create_timer_object(RPL_TIMER_TYPE, + fpRplTimerTimeoutHandler, void *); /*Free the timer object*/ void rpl_timer_free_timer_object(rpl_timer_t); -/*Start +/* Starts the timer */ +uint8_t rpl_timer_start_timer(rpl_timer_t); + +/* Stop the timer */ +uint8_t rpl_timer_stop_timer(rpl_timer_t); +/* Get current status of the timer */ +uint8_t rpl_timer_get_status(rpl_timer_t); #ifdef __cplusplus } diff --git a/src/include/rpl_topology.h b/src/include/rpl_topology.h index 08f7915..7787aad 100644 --- a/src/include/rpl_topology.h +++ b/src/include/rpl_topology.h @@ -21,6 +21,9 @@ #include "rpl_types.h" #include "rpl_objective_function.h" #include "rpl.h" +#include "trickle.h" +#include "rpl_configurations.h" +#include "rpl_papi.h" #ifdef __cplusplus extern "C" { @@ -189,11 +192,12 @@ typedef struct _rpl_dag_neighbor{ }rpl_dag_neighbor_t; typedef struct _rpl_dag_parent{ + struct _rpl_dag_parent *next; rpl_dag_neighbor_t *nbr_info; rpl_rank_t rank; rpl_dag_metric_container_t metric_info; uint8_t dtsn; - uint8_t flags + uint8_t flags; }rpl_dag_parent_t; typedef struct _rpl_dodag_configs{ @@ -208,6 +212,8 @@ typedef struct _rpl_dodag_configs{ uint8_t unused; }rpl_dodag_configs_t; +struct _rpl_instance; + /* RPL node can belong to one DODAG in a RPL Instance. So Its highly possible a device can be part of multiple RPL instances. @@ -223,12 +229,12 @@ typedef struct _rpl_dodag{ uint8_t is_grounded; rpl_dag_parent_t *preferred_parent; rpl_dag_parent_t *parent_list; - rpl_instnace_t *instnace; + struct _rpl_instance *instnace; }rpl_dodag_t; typedef struct _rpl_instance{ - struct _rpl_instnace *next; + struct _rpl_instance *next; /*At most, a RPL node can belong to one DODAG in a RPL Instance */ rpl_dodag_t dodag; @@ -244,7 +250,7 @@ typedef struct _rpl_instance{ But a Node can be part of only one DODAG in an RPL instnace */ typedef struct _rpl_node{ rpl_instance_t *rpl_instance_list; - rpl_configurations_t node_config; + rpl_configurations_t config; }rpl_node_t; #ifdef __cplusplus diff --git a/src/papi/papi_icmp6.c b/src/papi/papi_icmp6.c index 73e7bd2..b500282 100644 --- a/src/papi/papi_icmp6.c +++ b/src/papi/papi_icmp6.c @@ -16,14 +16,63 @@ */ #include +#include + +#define RPL_ICMPV6_HEADER_SIZE 4U /** * @brief RPL Message handler * * @return SUCCESS/FAILURE */ -int icmp6_handler(void) +int rpl_icmp6_handler(rpl_protocol_context rpl_context, + rpl_icmpv6_context_t *message_ctx) { - return SUCCESS; + uint8_t msg_type; + uint8_t msg_code; + int retval = SUCCESS; + + /* Validate the Inputs */ + if ((NULL == message_ctx) || (NULL == message_ctx->icmpv6_msg_buff)){ + return FAILURE; + } + + if (message_ctx->length < RPL_ICMPV6_HEADER_SIZE){ + return FAILURE; + } + + msg_type = message_ctx->icmpv6_msg_buff[0]; + msg_code = message_ctx->icmpv6_msg_buff[1]; + + /* Validate the type */ + if (msg_type != RPL_ICMPV6_MSG_TYPE){ + return FAILURE; + } + + switch (msg_code){ + case RPL_CTRL_MSG_CODE_DIS: + retval = rpl_dis_input(rpl_context, message_ctx); + break; + case RPL_CTRL_MSG_CODE_DIO: + retval = rpl_dio_input(rpl_context, message_ctx); + break; + case RPL_CTRL_MSG_CODE_DAO: + retval = rpl_dao_input(rpl_context, message_ctx); + break; + case RPL_CTRL_MSG_CODE_DAO_ACK: + retval = rpl_dao_ack_input(rpl_context, message_ctx); + break; + case RPL_CTRL_MSG_CODE_DCO: + retval = rpl_dco_input(rpl_context, message_ctx); + break; + case RPL_CTRL_MSG_CODE_DCO_ACK: + retval = rpl_dco_ack_input(rpl_context, message_ctx); + break; + default: + retval = FAILURE; + + } + + return retval; } diff --git a/src/uapi/uapi_rpl.c b/src/uapi/uapi_rpl.c index cd10f27..55e9986 100644 --- a/src/uapi/uapi_rpl.c +++ b/src/uapi/uapi_rpl.c @@ -5,6 +5,21 @@ * the top level directory for more details. */ +/** + * @ingroup Core + * @{ + * + * @file + * @brief RPL User API + * + * @} + *//* + * Copyright (C) 2020 Authors of Tripple + * + * This file is subject to the terms and conditions. See the file LICENSE in + * the top level directory for more details. + */ + /** * @ingroup Core * @{