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 new file mode 100644 index 0000000..2613163 --- /dev/null +++ b/include/rpl_configurations.h @@ -0,0 +1,135 @@ +/** + * @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 + * + * @} + */ + +#ifndef _RPL_CONFIGURATIONS_H_ +#define _RPL_CONFIGURATIONS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* 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 + +#ifndef RPL_PLATFORM +#ifdef RPL_WITH_LINUX +#define RPL_PLATFORM RPL_SUPPORTED_FOR_LINUX +#endif +#endif + + +/* Static Mmeory Related Configuration */ + +#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 + +#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 +#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_*/ + 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 new file mode 100644 index 0000000..81ed6d1 --- /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_papi.h" + +/* 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..5af9ee0 --- /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 "rpl_topology.h" + +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_instance_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.config.stNodeConfig = *config; + return (rpl_protocol_context)(&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.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, + 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, + sizeof(instnace_info->dodag_id.ip6addr)); + 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){ + /* 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 new file mode 100644 index 0000000..7fec9a9 --- /dev/null +++ b/src/core/rpl_mrhof.h @@ -0,0 +1,31 @@ +/* + * 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_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif /*_RPL_MRHOF_H_*/ + + diff --git a/src/core/rpl_of0.h b/src/core/rpl_of0.h new file mode 100644 index 0000000..33173a3 --- /dev/null +++ b/src/core/rpl_of0.h @@ -0,0 +1,30 @@ +/* + * 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_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif /*_RPL_OF0_H_*/ + 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/core/rpl_types.h b/src/core/rpl_types.h new file mode 100644 index 0000000..c7efd91 --- /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 +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#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 */ + +#ifdef __cplusplus +} +#endif + +#endif /*_RPL_TYPES_H_*/ + 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..35fb067 --- /dev/null +++ b/src/core/trickle.c @@ -0,0 +1,64 @@ + +#include "rpl.h" +#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/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_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/include/rpl_objective_function.h b/src/include/rpl_objective_function.h new file mode 100644 index 0000000..6034850 --- /dev/null +++ b/src/include/rpl_objective_function.h @@ -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 Include + * @{ + * + * @file + * @brief RPL objective function interfaces. + * + * @} + */ + +#ifndef _RPL_OBJECTIVE_FUNCTION_ +#define _RPL_OBJECTIVE_FUNCTION_ + +#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); + void * (*pf_of_select_preferred_parent)(void *parent_list); + 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 new file mode 100644 index 0000000..b53613a --- /dev/null +++ b/src/include/rpl_timer_interfaces.h @@ -0,0 +1,63 @@ +/* + * 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 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(RPL_TIMER_TYPE, + fpRplTimerTimeoutHandler, void *); + +/*Free the timer object*/ +void rpl_timer_free_timer_object(rpl_timer_t); + +/* 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 + } +#endif + +#endif /*_RPL_PAPI_TIMERS_H_*/ + diff --git a/src/include/rpl_topology.h b/src/include/rpl_topology.h new file mode 100644 index 0000000..7787aad --- /dev/null +++ b/src/include/rpl_topology.h @@ -0,0 +1,261 @@ +/* + * 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" +#include "trickle.h" +#include "rpl_configurations.h" +#include "rpl_papi.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{ + 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; +}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; + +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. +*/ +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; + struct _rpl_instance *instnace; +}rpl_dodag_t; + + +typedef struct _rpl_instance{ + struct _rpl_instance *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 config; +}rpl_node_t; + +#ifdef __cplusplus +} +#endif + +#endif /*_RPL_TOPOLOGY_H_*/ + 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/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; + } +} + 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 * @{