From 33f2e1253804e60a41f2fb4791a31480dba50543 Mon Sep 17 00:00:00 2001
From: weld10 <50168266+Amrican10@users.noreply.github.com>
Date: Mon, 27 Jul 2020 18:05:30 +0200
Subject: [PATCH 01/19] Create text
---
examples/containers/text | 1 +
1 file changed, 1 insertion(+)
create mode 100644 examples/containers/text
diff --git a/examples/containers/text b/examples/containers/text
new file mode 100644
index 00000000000..73505ed440d
--- /dev/null
+++ b/examples/containers/text
@@ -0,0 +1 @@
+h1
From aad78f39cf6743753d9240f604257d24278a0e5b Mon Sep 17 00:00:00 2001
From: weld10 <50168266+Amrican10@users.noreply.github.com>
Date: Mon, 27 Jul 2020 22:12:39 +0200
Subject: [PATCH 02/19] Add files via upload
---
examples/containers/#Makefile# | 49 +
examples/containers/3 nodos.csc | 168 ++++
examples/containers/Makefile | 51 +
examples/containers/client.c | 298 ++++++
examples/containers/collect-common.c | 172 ++++
examples/containers/collect-common.h | 56 ++
examples/containers/collect-data.conf | 4 +
examples/containers/collect-data.conf.bak | 4 +
.../containers/collect-tree-dense-noloss.csc | 503 ++++++++++
.../containers/collect-tree-sparse-lossy.csc | 501 ++++++++++
examples/containers/project-conf.h | 274 ++++++
.../containers/rpl-metrics-containers-OF.c | 321 +++++++
examples/containers/rpl-metrics-data.h | 85 ++
examples/containers/rpl-metrics-get.c | 262 ++++++
examples/containers/rpl-metrics-get.h | 13 +
examples/containers/rpl-metrics.c | 890 ++++++++++++++++++
examples/containers/rpl-metrics.h | 32 +
examples/containers/server.c | 193 ++++
examples/containers/simul-13-nodos.csc | 309 ++++++
19 files changed, 4185 insertions(+)
create mode 100644 examples/containers/#Makefile#
create mode 100644 examples/containers/3 nodos.csc
create mode 100644 examples/containers/Makefile
create mode 100644 examples/containers/client.c
create mode 100644 examples/containers/collect-common.c
create mode 100644 examples/containers/collect-common.h
create mode 100644 examples/containers/collect-data.conf
create mode 100644 examples/containers/collect-data.conf.bak
create mode 100644 examples/containers/collect-tree-dense-noloss.csc
create mode 100644 examples/containers/collect-tree-sparse-lossy.csc
create mode 100644 examples/containers/project-conf.h
create mode 100644 examples/containers/rpl-metrics-containers-OF.c
create mode 100644 examples/containers/rpl-metrics-data.h
create mode 100644 examples/containers/rpl-metrics-get.c
create mode 100644 examples/containers/rpl-metrics-get.h
create mode 100644 examples/containers/rpl-metrics.c
create mode 100644 examples/containers/rpl-metrics.h
create mode 100644 examples/containers/server.c
create mode 100644 examples/containers/simul-13-nodos.csc
diff --git a/examples/containers/#Makefile# b/examples/containers/#Makefile#
new file mode 100644
index 00000000000..5ece27b4927
--- /dev/null
+++ b/examples/containers/#Makefile#
@@ -0,0 +1,49 @@
+CONTIKI = ../..
+
+
+ifndef TARGET
+TARGET=z1
+endif
+
+#OPTI=0 for debugging
+ifndef OPTI
+OPTI=0
+endif
+
+
+APPS = powertrace collect-view
+CONTIKI_PROJECT = server client
+PROJECT_SOURCEFILES += collect-common.c rpl-metrics.c rpl-metrics-get.c rpl-metrics-containers-OF.c
+
+
+WITH_UIP6=1
+UIP_CONF_IPV6=1
+UIP_CONF_TCP=0
+#RPL_CONF_DAG_MC=2 !!!!!!!!!!!!!!
+SMALL=1
+
+#to debug a file add to CFLAGS -Dtag with tag=
+#DEBUG_RPL_ICMP6
+#DEBUG_RPL_DAG
+#DEBUG_RPL_METRICS
+#DEBUG_RPL_METRICS_GET
+#DEBUG_RPL_OF
+
+#use LEDS to show when there is a default parent
+#USE_LEDS_DEF_PARENT
+
+#use button to simulate loss of communication from/to a node
+#BUTTON_INTERFERENCE
+
+#-gdwarf-4 for debugging
+CFLAGS+= -DDEBUG_RPL_METRICS -DDEBUG_RPL_OF -DDEBUG_RPL_DAG
+CFLAGS+= -DUIP_CONF_IPV6_RPL -DUSE_LEDS_DEF_PARENT -DBUTTON_INTERFERENCE -DPROJECT_CONF_H=\"project-conf.h\"
+
+#ifdef PERIOD
+#CFLAGS=-DPERIOD=$(PERIOD)
+#endif
+
+all: $(CONTIKI_PROJECT)
+
+include $(CONTIKI)/Makefile.include
+
diff --git a/examples/containers/3 nodos.csc b/examples/containers/3 nodos.csc
new file mode 100644
index 00000000000..b593147bc0a
--- /dev/null
+++ b/examples/containers/3 nodos.csc
@@ -0,0 +1,168 @@
+
+
+ [APPS_DIR]/mrm
+ [APPS_DIR]/mspsim
+ [APPS_DIR]/avrora
+ [APPS_DIR]/serial_socket
+ [APPS_DIR]/collect-view
+ [APPS_DIR]/powertracker
+
+ My simulation
+ 123456
+ 100000
+
+ se.sics.cooja.radiomediums.UDGM
+ 20.0
+ 25.0
+ 1.0
+ 1.0
+
+
+ 40000
+
+
+ se.sics.cooja.mspmote.Z1MoteType
+ z11
+ server
+ [CONFIG_DIR]/server.z1
+ se.sics.cooja.interfaces.Position
+ se.sics.cooja.interfaces.RimeAddress
+ se.sics.cooja.interfaces.IPAddress
+ se.sics.cooja.interfaces.Mote2MoteRelations
+ se.sics.cooja.interfaces.MoteAttributes
+ se.sics.cooja.mspmote.interfaces.MspClock
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ se.sics.cooja.mspmote.interfaces.MspButton
+ se.sics.cooja.mspmote.interfaces.Msp802154Radio
+ se.sics.cooja.mspmote.interfaces.MspDefaultSerial
+ se.sics.cooja.mspmote.interfaces.MspLED
+ se.sics.cooja.mspmote.interfaces.MspDebugOutput
+
+
+ se.sics.cooja.mspmote.Z1MoteType
+ z12
+ client
+ [CONFIG_DIR]/client.z1
+ se.sics.cooja.interfaces.Position
+ se.sics.cooja.interfaces.RimeAddress
+ se.sics.cooja.interfaces.IPAddress
+ se.sics.cooja.interfaces.Mote2MoteRelations
+ se.sics.cooja.interfaces.MoteAttributes
+ se.sics.cooja.mspmote.interfaces.MspClock
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ se.sics.cooja.mspmote.interfaces.MspButton
+ se.sics.cooja.mspmote.interfaces.Msp802154Radio
+ se.sics.cooja.mspmote.interfaces.MspDefaultSerial
+ se.sics.cooja.mspmote.interfaces.MspLED
+ se.sics.cooja.mspmote.interfaces.MspDebugOutput
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 54.335467383479994
+ 4.747565694681829
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 1
+
+ z11
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 63.06567445836441
+ 17.713731231936247
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 2
+
+
+ se.sics.cooja.mspmote.interfaces.MspDefaultSerial
+ net~;
+
+ z12
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 58.933032056052255
+ 31.919689489884306
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 6
+
+ z12
+
+
+
+ se.sics.cooja.plugins.SimControl
+ 280
+ 1
+ 160
+ 191
+ 3
+
+
+ se.sics.cooja.plugins.Visualizer
+
+ true
+ se.sics.cooja.plugins.skins.IDVisualizerSkin
+ se.sics.cooja.plugins.skins.UDGMVisualizerSkin
+ se.sics.cooja.plugins.skins.TrafficVisualizerSkin
+ se.sics.cooja.plugins.skins.LEDVisualizerSkin
+ 3.87161492391604 0.0 0.0 3.87161492391604 -131.16600641983428 -3.580746195802032
+
+ 154
+ 2
+ 236
+ 6
+ -1
+
+
+ se.sics.cooja.plugins.RadioLogger
+
+ 150
+
+ false
+ false
+
+
+
+
+
+
+
+
+
+
+
+ 803
+ 3
+ 424
+ 371
+ 166
+
+
+ se.sics.cooja.plugins.LogListener
+
+ PRUEBA
+
+
+
+ 888
+ 0
+ 991
+ -4
+ 332
+
+
+
diff --git a/examples/containers/Makefile b/examples/containers/Makefile
new file mode 100644
index 00000000000..86e13d0b51f
--- /dev/null
+++ b/examples/containers/Makefile
@@ -0,0 +1,51 @@
+CONTIKI = ../..
+
+
+ifndef TARGET
+TARGET=z1
+endif
+
+#OPTI=0 for debugging
+ifndef OPTI
+OPTI=0
+endif
+
+
+APPS = powertrace collect-view
+CONTIKI_PROJECT = server client
+PROJECT_SOURCEFILES += collect-common.c rpl-metrics.c rpl-metrics-get.c rpl-metrics-containers-OF.c
+
+
+WITH_UIP6=1
+UIP_CONF_IPV6=1
+UIP_CONF_TCP=0
+PERIOD=30
+#RPL_CONF_DAG_MC=2
+SMALL=1
+
+#to debug a file add to CFLAGS -Dtag with tag=
+#DEBUG_RPL_ICMP6
+#DEBUG_RPL_DAG
+#DEBUG_RPL_TIMERS
+#DEBUG_RPL_METRICS
+#DEBUG_RPL_METRICS_GET
+#DEBUG_RPL_OF
+
+#use LEDS to show when there is a default parent
+#USE_LEDS_DEF_PARENT
+
+#use button to simulate loss of communication from/to a node
+#BUTTON_INTERFERENCE
+
+#-gdwarf-4 for debugging
+CFLAGS+= #-DDEBUG_RPL_METRICS -DDEBUG_RPL_OF
+CFLAGS+= -DSTATISTICS -DUIP_CONF_IPV6_RPL -DUSE_LEDS_DEF_PARENT -DBUTTON_INTERFERENCE -DPROJECT_CONF_H=\"project-conf.h\"
+
+#ifdef PERIOD
+#CFLAGS=-DPERIOD=$(PERIOD)
+#endif
+
+all: $(CONTIKI_PROJECT)
+
+include $(CONTIKI)/Makefile.include
+
diff --git a/examples/containers/client.c b/examples/containers/client.c
new file mode 100644
index 00000000000..46eb17d278a
--- /dev/null
+++ b/examples/containers/client.c
@@ -0,0 +1,298 @@
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ *
+ */
+
+#include "contiki.h"
+#include "net/uip.h"
+#include "net/uip-ds6.h"
+#include "net/uip-udp-packet.h"
+#include "net/rpl/rpl.h"
+#include "dev/serial-line.h"
+
+#ifdef BUTTON_INTERFERENCE
+#include "dev/button-sensor.h"
+#endif
+//#ifdef USE_LEDS_DEF_PARENT
+#include "dev/leds.h"
+//#endif
+
+
+#if CONTIKI_TARGET_Z1
+#include "dev/uart0.h"
+#else
+#include "dev/uart1.h"
+#endif
+#include "collect-common.h"
+#include "collect-view.h"
+
+#include
+#include
+
+#define UDP_CLIENT_PORT 8775
+#define UDP_SERVER_PORT 5688
+
+#define DEBUG DEBUG_NONE
+#include "net/uip-debug.h"
+
+static struct uip_udp_conn *client_conn;
+static uip_ipaddr_t server_ipaddr;
+
+/*---------------------------------------------------------------------------*/
+PROCESS(udp_client_process, "UDP client process");
+AUTOSTART_PROCESSES(&udp_client_process, &collect_common_process);
+/*---------------------------------------------------------------------------*/
+void
+collect_common_set_sink(void)
+{
+ /* A udp client can never become sink */
+}
+/*---------------------------------------------------------------------------*/
+
+/* Information printed with "net" in serial port interface */
+void
+collect_common_net_print(void)
+{
+ rpl_dag_t *dag;
+ uip_ds6_route_t *r;
+
+ /* Let's suppose we have only one instance */
+ dag = rpl_get_any_dag();
+ if(dag->preferred_parent != NULL) {
+ PRINTF("Preferred parent: ");
+ PRINT6ADDR(rpl_get_parent_ipaddr(dag->preferred_parent));
+ PRINTF("\n");
+ }
+ for(r = uip_ds6_route_head();
+ r != NULL;
+ r = uip_ds6_route_next(r)) {
+ PRINT6ADDR(&r->ipaddr);
+ PRINTF("\n");
+ }
+ PRINTF("---\n");
+
+}
+/*---------------------------------------------------------------------------*/
+static void
+tcpip_handler(void)
+{
+ if(uip_newdata()) {
+ /* Ignore incoming data */
+
+ }
+}
+/*---------------------------------------------------------------------------*/
+void
+collect_common_send(void)
+{
+ static uint8_t seqno;
+ struct {
+ uint8_t seqno;
+ uint8_t for_alignment;
+ struct collect_view_data_msg msg;
+ } msg;
+ /* struct collect_neighbor *n; */
+ uint16_t parent_etx;
+ uint16_t rtmetric;
+ uint16_t num_neighbors;
+ uint16_t beacon_interval;
+ rpl_parent_t *preferred_parent;
+ rimeaddr_t parent;
+ rpl_dag_t *dag;
+
+ if(client_conn == NULL) {
+ /* Not setup yet */
+ return;
+ }
+ memset(&msg, 0, sizeof(msg));
+ seqno++;
+ if(seqno == 0) {
+ /* Wrap to 128 to identify restarts */
+ seqno = 128;
+ }
+ msg.seqno = seqno;
+
+ rimeaddr_copy(&parent, &rimeaddr_null);
+ parent_etx = 0;
+
+ /* Let's suppose we have only one instance */
+ dag = rpl_get_any_dag();
+ if(dag != NULL) {
+ preferred_parent = dag->preferred_parent;
+ if(preferred_parent != NULL) {
+ uip_ds6_nbr_t *nbr;
+ nbr = uip_ds6_nbr_lookup(rpl_get_parent_ipaddr(preferred_parent));
+ if(nbr != NULL) {
+ /* Use parts of the IPv6 address as the parent address, in reversed byte order. */
+ parent.u8[RIMEADDR_SIZE - 1] = nbr->ipaddr.u8[sizeof(uip_ipaddr_t) - 2];
+ parent.u8[RIMEADDR_SIZE - 2] = nbr->ipaddr.u8[sizeof(uip_ipaddr_t) - 1];
+
+ parent_etx= preferred_parent->etx;
+ /*parent_etx is divided by 8 in the java graphics*/
+ parent_etx *= 8;
+
+ }
+ }
+ rtmetric = dag->rank;
+ beacon_interval = (uint16_t) ((2L << dag->instance->dio_intcurrent) / 1000);
+
+ num_neighbors= 0;
+
+
+ } else {
+ rtmetric = 0;
+ beacon_interval = 0;
+ num_neighbors = 0;
+ }
+
+ /* num_neighbors = collect_neighbor_list_num(&tc.neighbor_list); */
+ collect_view_construct_message(&msg.msg, &parent,
+ parent_etx, rtmetric,
+ num_neighbors, beacon_interval);
+
+ uip_udp_packet_sendto(client_conn, &msg, sizeof(msg),
+ &server_ipaddr, UIP_HTONS(UDP_SERVER_PORT));
+
+#ifdef STATISTICS
+ {
+ static uint16_t pack_sent=0;
+ printf("30 Packet sent: %u\n",++pack_sent);
+ }
+#endif /*STATISTICS*/
+
+}
+/*---------------------------------------------------------------------------*/
+void
+collect_common_net_init(void)
+{
+#if CONTIKI_TARGET_Z1
+ uart0_set_input(serial_line_input_byte);
+#else
+ uart1_set_input(serial_line_input_byte);
+#endif
+ serial_line_init();
+}
+/*---------------------------------------------------------------------------*/
+static void
+print_local_addresses(void)
+{
+ int i;
+ uint8_t state;
+
+ PRINTF("Client IPv6 addresses: ");
+ for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
+ state = uip_ds6_if.addr_list[i].state;
+ if(uip_ds6_if.addr_list[i].isused &&
+ (state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) {
+ PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr);
+ PRINTF("\n");
+ /* hack to make address "final" */
+ if (state == ADDR_TENTATIVE) {
+ uip_ds6_if.addr_list[i].state = ADDR_PREFERRED;
+ }
+ }
+ }
+}
+/*---------------------------------------------------------------------------*/
+static void
+set_global_address(void)
+{
+ uip_ipaddr_t ipaddr;
+
+ uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0);
+ uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr);
+ uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF);
+
+ /* set server address */
+ uip_ip6addr(&server_ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 1);
+
+
+}
+/*---------------------------------------------------------------------------*/
+PROCESS_THREAD(udp_client_process, ev, data)
+{
+ PROCESS_BEGIN();
+
+ PROCESS_PAUSE();
+
+
+#ifdef USE_LEDS_DEF_PARENT
+ SENSORS_ACTIVATE(button_sensor);
+#endif
+
+
+ set_global_address();
+
+ PRINTF("UDP client process started\n");
+
+ print_local_addresses();
+
+ /* new connection with remote host */
+ client_conn = udp_new(NULL, UIP_HTONS(UDP_SERVER_PORT), NULL);
+ udp_bind(client_conn, UIP_HTONS(UDP_CLIENT_PORT));
+
+ PRINTF("Created a connection with the server ");
+ PRINT6ADDR(&client_conn->ripaddr);
+ PRINTF(" local/remote port %u/%u\n",
+ UIP_HTONS(client_conn->lport), UIP_HTONS(client_conn->rport));
+
+
+#ifdef USE_LEDS_DEF_PARENT
+ leds_on(2);//RED
+ static int radio_on= 1;
+#endif
+
+
+ while(1) {
+ PROCESS_YIELD();
+ if(ev == tcpip_event) {
+ tcpip_handler();
+ }
+
+#ifdef USE_LEDS_DEF_PARENT
+ else if(ev == sensors_event && data == &button_sensor) {
+ printf("Radio: ");
+ if(radio_on){
+ radio_on=0;
+ leds_on(1);//BLUE
+ NETSTACK_RDC.off(0);
+ printf("OFF\n");
+ } else{
+ radio_on= 1;
+ leds_off(1);
+ NETSTACK_RDC.on();
+ printf("ON\n");
+ }
+
+ }
+#endif /*USE_LEDS_DEF_PARENT*/
+
+ }
+
+ PROCESS_END();
+}
+/*---------------------------------------------------------------------------*/
diff --git a/examples/containers/collect-common.c b/examples/containers/collect-common.c
new file mode 100644
index 00000000000..e61ca84e343
--- /dev/null
+++ b/examples/containers/collect-common.c
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2010, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+/**
+ * \file
+ * Example of how the collect primitive works.
+ * \author
+ * Adam Dunkels
+ */
+
+#include "contiki.h"
+#include "lib/random.h"
+#include "net/netstack.h"
+#include "dev/serial-line.h"
+#include "dev/leds.h"
+#include "collect-common.h"
+
+#include
+#include
+#include
+
+static unsigned long time_offset;
+static int send_active = 1;
+
+#ifndef PERIOD
+#define PERIOD 30
+#endif
+#define RANDWAIT (PERIOD)
+
+/*---------------------------------------------------------------------------*/
+PROCESS(collect_common_process, "collect common process");
+AUTOSTART_PROCESSES(&collect_common_process);
+/*---------------------------------------------------------------------------*/
+static unsigned long
+get_time(void)
+{
+ return clock_seconds() + time_offset;
+}
+/*---------------------------------------------------------------------------*/
+static unsigned long
+strtolong(const char *data) {
+ unsigned long value = 0;
+ int i;
+ for(i = 0; i < 10 && isdigit(data[i]); i++) {
+ value = value * 10 + data[i] - '0';
+ }
+ return value;
+}
+/*---------------------------------------------------------------------------*/
+void
+collect_common_set_send_active(int active)
+{
+ send_active = active;
+}
+/*---------------------------------------------------------------------------*/
+void
+collect_common_recv(const rimeaddr_t *originator, uint8_t seqno, uint8_t hops,
+ uint8_t *payload, uint16_t payload_len)
+{
+ unsigned long time;
+ uint16_t data;
+ int i;
+
+
+ printf("%u", 8 + payload_len / 2);
+ /* Timestamp. Ignore time synch for now. */
+ time = get_time();
+ printf(" %lu %lu 0", ((time >> 16) & 0xffff), time & 0xffff);
+ /* Ignore latency for now */
+ printf(" %u %u %u %u",
+ originator->u8[0] + (originator->u8[1] << 8), seqno, hops, 0);
+ for(i = 0; i < payload_len / 2; i++) {
+ memcpy(&data, payload, sizeof(data));
+ payload += sizeof(data);
+ printf(" %u", data);
+ }
+ printf("\n");
+ leds_blink();
+}
+/*---------------------------------------------------------------------------*/
+PROCESS_THREAD(collect_common_process, ev, data)
+{
+ static struct etimer period_timer, wait_timer;
+ PROCESS_BEGIN();
+
+ collect_common_net_init();
+
+ /* Send a packet every 60-62 seconds. */
+ etimer_set(&period_timer, CLOCK_SECOND * PERIOD);
+ while(1) {
+ PROCESS_WAIT_EVENT();
+ if(ev == serial_line_event_message) {
+ char *line;
+ line = (char *)data;
+ if(strncmp(line, "collect", 7) == 0 ||
+ strncmp(line, "gw", 2) == 0) {
+ collect_common_set_sink();
+ } else if(strncmp(line, "net", 3) == 0) {
+ collect_common_net_print();
+ } else if(strncmp(line, "time ", 5) == 0) {
+ unsigned long tmp;
+ line += 6;
+ while(*line == ' ') {
+ line++;
+ }
+ tmp = strtolong(line);
+ time_offset = clock_seconds() - tmp;
+ printf("Time offset set to %lu\n", time_offset);
+ } else if(strncmp(line, "mac ", 4) == 0) {
+ line +=4;
+ while(*line == ' ') {
+ line++;
+ }
+ if(*line == '0') {
+ NETSTACK_RDC.off(1);
+ printf("mac: turned MAC off (keeping radio on): %s\n",
+ NETSTACK_RDC.name);
+ } else {
+ NETSTACK_RDC.on();
+ printf("mac: turned MAC on: %s\n", NETSTACK_RDC.name);
+ }
+
+ } else if(strncmp(line, "~K", 2) == 0 ||
+ strncmp(line, "killall", 7) == 0) {
+ /* Ignore stop commands */
+ } else {
+ printf("unhandled command: %s\n", line);
+ }
+ }
+ if(ev == PROCESS_EVENT_TIMER) {
+ if(data == &period_timer) {
+ etimer_reset(&period_timer);
+ etimer_set(&wait_timer, random_rand() % (CLOCK_SECOND * RANDWAIT));
+ } else if(data == &wait_timer) {
+ if(send_active) {
+ /* Time to send the data */
+ collect_common_send();
+ }
+ }
+ }
+ }
+
+ PROCESS_END();
+}
+/*---------------------------------------------------------------------------*/
diff --git a/examples/containers/collect-common.h b/examples/containers/collect-common.h
new file mode 100644
index 00000000000..32019d4cd1a
--- /dev/null
+++ b/examples/containers/collect-common.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2010, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+/**
+ * \file
+ * Common code between collect client and server
+ * \author
+ * Niclas Finne
+ */
+
+#ifndef __COLLECT_COMMON_H__
+#define __COLLECT_COMMON_H__
+
+#include "contiki.h"
+#include "net/rime/rimeaddr.h"
+
+void collect_common_net_init(void);
+void collect_common_net_print(void);
+void collect_common_set_sink(void);
+void collect_common_send(void);
+void collect_common_recv(const rimeaddr_t *originator, uint8_t seqno,
+ uint8_t hops,
+ uint8_t *payload,
+ uint16_t payload_len);
+void collect_common_set_send_active(int active);
+
+PROCESS_NAME(collect_common_process);
+
+#endif /* __COLLECT_COMMON_H__ */
diff --git a/examples/containers/collect-data.conf b/examples/containers/collect-data.conf
new file mode 100644
index 00000000000..5f26d1530b6
--- /dev/null
+++ b/examples/containers/collect-data.conf
@@ -0,0 +1,4 @@
+#Configuration for Collect
+#Wed Jul 30 16:33:07 CEST 2014
+collect.bounds=2,52,636,596
+collect.nodeinfo.table=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20
diff --git a/examples/containers/collect-data.conf.bak b/examples/containers/collect-data.conf.bak
new file mode 100644
index 00000000000..347be7e3e2e
--- /dev/null
+++ b/examples/containers/collect-data.conf.bak
@@ -0,0 +1,4 @@
+#Configuration for Collect
+#Wed Jul 30 13:29:39 CEST 2014
+collect.bounds=2,52,636,596
+collect.nodeinfo.table=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20
diff --git a/examples/containers/collect-tree-dense-noloss.csc b/examples/containers/collect-tree-dense-noloss.csc
new file mode 100644
index 00000000000..c3d13cf7202
--- /dev/null
+++ b/examples/containers/collect-tree-dense-noloss.csc
@@ -0,0 +1,503 @@
+
+
+ [CONTIKI_DIR]/tools/cooja/apps/mrm
+ [CONTIKI_DIR]/tools/cooja/apps/mspsim
+ [CONTIKI_DIR]/tools/cooja/apps/avrora
+ [CONTIKI_DIR]/tools/cooja/apps/serial_socket
+ [CONTIKI_DIR]/tools/cooja/apps/collect-view
+
+ My simulation
+ 0
+ 123456
+ 1000000
+
+ se.sics.cooja.radiomediums.UDGM
+ 100.0
+ 120.0
+ 1.0
+ 1.0
+
+
+ 40000
+
+
+ se.sics.cooja.mspmote.SkyMoteType
+ sky1
+ Sky Mote Type #sky1
+
+ make udp-sink.sky TARGET=sky
+ [CONFIG_DIR]/udp-sink.sky
+ se.sics.cooja.interfaces.Position
+ se.sics.cooja.interfaces.RimeAddress
+ se.sics.cooja.interfaces.IPAddress
+ se.sics.cooja.interfaces.Mote2MoteRelations
+ se.sics.cooja.interfaces.MoteAttributes
+ se.sics.cooja.mspmote.interfaces.MspClock
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ se.sics.cooja.mspmote.interfaces.SkyButton
+ se.sics.cooja.mspmote.interfaces.SkyFlash
+ se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem
+ se.sics.cooja.mspmote.interfaces.SkyByteRadio
+ se.sics.cooja.mspmote.interfaces.MspSerial
+ se.sics.cooja.mspmote.interfaces.SkyLED
+ se.sics.cooja.mspmote.interfaces.MspDebugOutput
+ se.sics.cooja.mspmote.interfaces.SkyTemperature
+
+
+ se.sics.cooja.mspmote.SkyMoteType
+ sky2
+ Sky Mote Type #sky2
+
+ make udp-sender.sky TARGET=sky
+ [CONFIG_DIR]/udp-sender.sky
+ se.sics.cooja.interfaces.Position
+ se.sics.cooja.interfaces.RimeAddress
+ se.sics.cooja.interfaces.IPAddress
+ se.sics.cooja.interfaces.Mote2MoteRelations
+ se.sics.cooja.interfaces.MoteAttributes
+ se.sics.cooja.mspmote.interfaces.MspClock
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ se.sics.cooja.mspmote.interfaces.SkyButton
+ se.sics.cooja.mspmote.interfaces.SkyFlash
+ se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem
+ se.sics.cooja.mspmote.interfaces.SkyByteRadio
+ se.sics.cooja.mspmote.interfaces.MspSerial
+ se.sics.cooja.mspmote.interfaces.SkyLED
+ se.sics.cooja.mspmote.interfaces.MspDebugOutput
+ se.sics.cooja.mspmote.interfaces.SkyTemperature
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 242.83184008074136
+ -88.93434685786869
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 1
+
+ sky1
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 223.5175954004352
+ -69.05842098947238
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 2
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 250.51864863077387
+ -59.2420165357677
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 3
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 294.4736028715864
+ -63.23792146675066
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 4
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 188.6638305152632
+ -41.28432709660093
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 5
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 222.54731411389315
+ -32.869043991280165
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 6
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 273.694897230475
+ -29.672320046493798
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 7
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 321.64575640227054
+ -33.66822497747676
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 8
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 159.4120162043624
+ -2.500166515809672
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 9
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 196.97352255560222
+ -0.10262355721989598
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 10
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 252.91619158936365
+ 1.495738415173288
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 11
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 301.66623174735577
+ -0.10262355721989598
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 12
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 346.4203669743649
+ 1.495738415173288
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 13
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 124.24805281171236
+ 22.27444405628468
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 14
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 180.1907218454738
+ 35.86052082162674
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 15
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 224.14567608628633
+ 30.266253918250598
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 16
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 276.0924401890648
+ 35.86052082162674
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 17
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 351.2154528915445
+ 37.45888279401993
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 18
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 89.08408941906231
+ 47.04905462837903
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 19
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 180.1907218454738
+ 75.02038914525976
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 20
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 245.7235627135943
+ 66.22939829709723
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 21
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 290.4776979406035
+ 67.82776026949043
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 22
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 370.3957965602627
+ 64.63103632470406
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 23
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 93.07999435004527
+ 82.21301802102909
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 24
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 204.16615143137156
+ 106.18844760692684
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 25
+
+ sky2
+
+
+
+ se.sics.cooja.plugins.SimControl
+ 259
+ 2
+ 184
+ 0
+ 0
+
+
+ se.sics.cooja.plugins.Visualizer
+
+ se.sics.cooja.plugins.skins.IDVisualizerSkin
+ se.sics.cooja.plugins.skins.AttributeVisualizerSkin
+ se.sics.cooja.plugins.skins.UDGMVisualizerSkin
+ 1.836243522352668 0.0 0.0 1.836243522352668 -93.43273668589363 192.8080782058222
+
+ 666
+ 0
+ 510
+ 369
+ -8
+
+
+ se.sics.cooja.plugins.LogListener
+
+
+
+ 1347
+ 4
+ 150
+ 0
+ 438
+
+
+ se.sics.cooja.plugins.TimeLine
+
+ 0
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+
+
+
+ 109
+ 500.0
+
+ 1347
+ 3
+ 150
+ 0
+ 588
+
+
+ se.sics.cooja.plugins.collectview.CollectView
+ 0
+ 203
+ 1
+ 75
+ 33
+ 188
+
+
+
diff --git a/examples/containers/collect-tree-sparse-lossy.csc b/examples/containers/collect-tree-sparse-lossy.csc
new file mode 100644
index 00000000000..f3f1bbeb9a5
--- /dev/null
+++ b/examples/containers/collect-tree-sparse-lossy.csc
@@ -0,0 +1,501 @@
+
+
+ [CONTIKI_DIR]/tools/cooja/apps/mrm
+ [CONTIKI_DIR]/tools/cooja/apps/mspsim
+ [CONTIKI_DIR]/tools/cooja/apps/avrora
+ [CONTIKI_DIR]/tools/cooja/apps/serial_socket
+ [CONTIKI_DIR]/tools/cooja/apps/collect-view
+
+ My simulation
+ 0
+ 123456
+ 1000000
+
+ se.sics.cooja.radiomediums.UDGM
+ 70.0
+ 90.0
+ 1.0
+ 0.0
+
+
+ 40000
+
+
+ se.sics.cooja.mspmote.SkyMoteType
+ sky1
+ Sky Mote Type #sky1
+
+ make server.z1 TARGET=z1
+ [CONFIG_DIR]/server.sky
+ se.sics.cooja.interfaces.Position
+ se.sics.cooja.interfaces.RimeAddress
+ se.sics.cooja.interfaces.IPAddress
+ se.sics.cooja.interfaces.Mote2MoteRelations
+ se.sics.cooja.interfaces.MoteAttributes
+ se.sics.cooja.mspmote.interfaces.MspClock
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ se.sics.cooja.mspmote.interfaces.SkyButton
+ se.sics.cooja.mspmote.interfaces.SkyFlash
+ se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem
+ se.sics.cooja.mspmote.interfaces.SkyByteRadio
+ se.sics.cooja.mspmote.interfaces.MspSerial
+ se.sics.cooja.mspmote.interfaces.SkyLED
+ se.sics.cooja.mspmote.interfaces.MspDebugOutput
+ se.sics.cooja.mspmote.interfaces.SkyTemperature
+
+
+ se.sics.cooja.mspmote.SkyMoteType
+ sky2
+ Sky Mote Type #sky2
+
+ make client.sky TARGET=sky
+ [CONFIG_DIR]/client.sky
+ se.sics.cooja.interfaces.Position
+ se.sics.cooja.interfaces.RimeAddress
+ se.sics.cooja.interfaces.IPAddress
+ se.sics.cooja.interfaces.Mote2MoteRelations
+ se.sics.cooja.interfaces.MoteAttributes
+ se.sics.cooja.mspmote.interfaces.MspClock
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ se.sics.cooja.mspmote.interfaces.SkyButton
+ se.sics.cooja.mspmote.interfaces.SkyFlash
+ se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem
+ se.sics.cooja.mspmote.interfaces.SkyByteRadio
+ se.sics.cooja.mspmote.interfaces.MspSerial
+ se.sics.cooja.mspmote.interfaces.SkyLED
+ se.sics.cooja.mspmote.interfaces.MspDebugOutput
+ se.sics.cooja.mspmote.interfaces.SkyTemperature
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 242.83184008074136
+ -88.93434685786869
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 1
+
+ sky1
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 205.7645134037647
+ -62.438740480554074
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 2
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 250.51864863077387
+ -59.2420165357677
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 3
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 294.4736028715864
+ -63.23792146675066
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 4
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 176.19481691449084
+ -35.26658694986995
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 5
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 222.54731411389315
+ -32.869043991280165
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 6
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 273.694897230475
+ -29.672320046493798
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 7
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 321.64575640227054
+ -33.66822497747676
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 8
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 159.4120162043624
+ -2.500166515809672
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 9
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 196.97352255560222
+ -0.10262355721989598
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 10
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 252.91619158936365
+ 1.495738415173288
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 11
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 301.66623174735577
+ -0.10262355721989598
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 12
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 346.4203669743649
+ 1.495738415173288
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 13
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 124.24805281171236
+ 22.27444405628468
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 14
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 180.1907218454738
+ 35.86052082162674
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 15
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 224.14567608628633
+ 30.266253918250598
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 16
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 276.0924401890648
+ 35.86052082162674
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 17
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 351.2154528915445
+ 37.45888279401993
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 18
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 89.08408941906231
+ 47.04905462837903
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 19
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 180.1907218454738
+ 75.02038914525976
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 20
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 245.7235627135943
+ 66.22939829709723
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 21
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 290.4776979406035
+ 67.82776026949043
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 22
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 370.3957965602627
+ 64.63103632470406
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 23
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 93.07999435004527
+ 82.21301802102909
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 24
+
+ sky2
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 204.16615143137156
+ 106.18844760692684
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 25
+
+ sky2
+
+
+
+ se.sics.cooja.plugins.SimControl
+ 259
+ 3
+ 184
+ 0
+ 0
+
+
+ se.sics.cooja.plugins.Visualizer
+
+ se.sics.cooja.plugins.skins.IDVisualizerSkin
+ se.sics.cooja.plugins.skins.AttributeVisualizerSkin
+ se.sics.cooja.plugins.skins.UDGMVisualizerSkin
+ 1.836243522352668 0.0 0.0 1.836243522352668 -124.43273668589376 177.8080782058222
+
+ 610
+ 2
+ 482
+ 420
+ -2
+
+
+ se.sics.cooja.plugins.LogListener
+
+
+
+ 1347
+ 4
+ 150
+ 0
+ 438
+
+
+ se.sics.cooja.plugins.TimeLine
+
+ 0
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+
+ 109
+ 500.0
+
+ 1347
+ 0
+ 150
+ 0
+ 588
+
+
+ se.sics.cooja.plugins.collectview.CollectView
+ 0
+ 203
+ 1
+ 75
+ 120
+ 120
+
+
+
diff --git a/examples/containers/project-conf.h b/examples/containers/project-conf.h
new file mode 100644
index 00000000000..d059d21d23a
--- /dev/null
+++ b/examples/containers/project-conf.h
@@ -0,0 +1,274 @@
+
+#ifndef __PROJECT_CONF_H__
+#define __PROJECT_CONF_H__
+
+#define USE_METRIC_CONTAINERS
+
+#ifdef USE_METRIC_CONTAINERS
+#define RPL_CONF_DAG_MC RPL_DAG_MC_ENERGY
+#endif /* USE_METRIC_CONTAINERS*/
+
+/* objective function */
+#define RPL_CONF_OF rpl_metrics_containers_OF
+
+/* DIOs with rank lower than this will be ignored.*
+ * It must be selected in function of the metrics *
+ */
+#define RPL_CONF_MIN_HOPRANKINC 128
+/*by default, RPL_CONF_MAX_RANKINC = 7*RPL_CONF_MIN_HOPRANKINC*/
+//#define RPL_CONF_MAX_HOPRANKINC 1000
+
+/* By default used weighted composition */
+#define LEXIC_COMPOSITION
+
+/********************weighted composition****************************/
+/*
+ * The maximum difference between metrics to not change the parent *
+ */
+
+#define WEIGHTED_DIFF_THRESHOLD 64
+
+/* (optional)
+ * The weight of each metric, with the precedence order *
+ * The number of elements must be the same as *
+ * NUMBER_OF_METRICS_AND_CONST_USED *
+ */
+
+//#define METRICS_WEIGHTS {1,0}
+
+/*******************************************************************/
+
+/*******************lexicographic composition***********************/
+/*
+* Which metrics to maximize (the bigger, the better); the others *
+* are minimized. The last element must be 0 *
+*/
+
+#define MAXIMIZED_METRICS {RPL_DAG_MC_THROUGHPUT,\
+ 0}
+
+/*
+ * The maximum difference between each metric pair to consider *
+ * them equal and compare the next pair. It follows the *
+ * precedence order. *
+ * The number of elements must be the same as *
+ * NUMBER_OF_METRICS_AND_CONST_USED *
+ */
+
+#define LEXIC_DIFF_THRESHOLD {64, 0}
+
+
+/********************************************************************/
+/********************************************************************/
+
+
+/* number of path metrics and constraint objects used. */
+#define NUMBER_OF_METRICS_AND_CONST_USED 2
+
+/* difference between metrics to check optional constraints */
+#define OPTIONAL_CONSTRAINTS_THRESHOLD 0
+
+
+/* select containers used and add the routing metric object *
+ * header as described in RFC6551 (in hexadecimal) *
+ *
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |Routing-MC-Type|Res Flags|P|C|O|R| A | Prec | Length (bytes)|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | | | | | | |
+ */
+
+/*
+* Headers ONLY for path metrics. *
+* Uncomment only the used ones. *
+* Length and type cannot be changed. *
+*/
+
+//#define RPL_DAG_MC_USE_NSA 0x01000102
+#define RPL_DAG_MC_USE_ENERGY 0x02001102
+//#define RPL_DAG_MC_USE_HOPCOUNT 0x03000002
+//#define RPL_DAG_MC_USE_THROUGHPUT 0x04002204
+//#define RPL_DAG_MC_USE_LATENCY 0x05001304
+//#define RPL_DAG_MC_USE_LQL 0x06000402
+#define RPL_DAG_MC_USE_ETX 0x07000002
+//#define RPL_DAG_MC_USE_LC 0x08000303
+
+/*
+* Headers ONLY for path constraints *
+* Uncomment only the used ones. *
+* Length and type cannot be changed. *
+* For each constraint it is mandatory a metric of the same type! *
+*/
+
+//#define RPL_DAG_MC_CONST_USE_NSA 0x01030102
+//#define RPL_DAG_MC_CONST_USE_ENERGY 0x02031102
+//#define RPL_DAG_MC_CONST_USE_HOPCOUNT 0x03030202
+//#define RPL_DAG_MC_CONST_USE_THROUGHPUT
+//#define RPL_DAG_MC_CONST_USE_LATENCY
+//#define RPL_DAG_MC_CONST_USE_LQL 0x06030202
+//#define RPL_DAG_MC_CONST_USE_ETX
+//#define RPL_DAG_MC_CONST_USE_LC 0x08020303
+
+
+/******************************NSA ******************************************/
+
+/* metric */
+#define RPL_DAG_MC_NSA_A_AGGREGATION 0
+#define RPL_DAG_MC_NSA_O_OVERLOAD 0
+
+/* constraint */
+#define RPL_DAG_MC_CONST_NSA_A_AGGREGATION 0
+#define RPL_DAG_MC_CONST_NSA_O_OVERLOAD 0
+
+#define RPL_DAG_MC_NSA_AGGREGATION_BIT 2
+#define RPL_DAG_MC_NSA_OVERLOAD_BIT 1
+/***************************************************************************/
+
+
+/*****************************energy ***************************************/
+/*between 20L (minimum resolution) and 7200L (overflow of ticks)*/
+#define BATT_CHARGE 250L /*uAh*/
+
+/*simplify a division by shifting ( 32768 = 2^15 )*/
+#define TICKS_PER_SECOND 15
+
+#define CURRENT_CPU 4000 /*uA*/
+#define CURRENT_LPM 20 /*uA*/
+#define CURRENT_TRANSMIT 17400 /*uA*/
+#define CURRENT_LISTEN 18800 /*uA*/
+
+/***************************************************/
+#define RPL_DAG_MC_ENERGY_TYPE_MAINS 0
+#define RPL_DAG_MC_ENERGY_TYPE_BATTERY 1
+#define RPL_DAG_MC_ENERGY_TYPE_SCAVENGING 2
+
+#define RPL_DAG_MC_ENERGY_TYPE_MYSELF RPL_DAG_MC_ENERGY_TYPE_BATTERY
+
+/* metric */
+/*in additive mode, avoids overflow of the 8-bit variable*/
+//#define RPL_DAG_MC_ENERGY_DIVISOR 3 /*>> bits*/
+
+#define RPL_DAG_MC_ENERGY_I_INCLUDED 1
+#define RPL_DAG_MC_ENERGY_T_TYPE RPL_DAG_MC_ENERGY_TYPE_BATTERY
+#define RPL_DAG_MC_ENERGY_E_ESTIMATION 1
+#define RPL_DAG_MC_ENERGY_INITIALIZATION 1
+
+/* constraint */
+#define RPL_DAG_MC_CONST_ENERGY_I_INCLUDED 1
+#define RPL_DAG_MC_CONST_ENERGY_T_TYPE RPL_DAG_MC_ENERGY_TYPE_BATTERY
+#define RPL_DAG_MC_CONST_ENERGY_E_ESTIMATION 1
+#define RPL_DAG_MC_CONST_ENERGY_THRESHOLD 175
+/**************************************************************************/
+
+
+/****************************hop count ************************************/
+
+#define RPL_DAG_MC_HOPCOUNT_MULTIPLIER 256
+
+/* metric */
+#define RPL_DAG_MC_HOPCOUNT_INITIALIZATION 1
+/* constraint */
+#define RPL_DAG_MC_CONST_HOPCOUNT_THRESHOLD 4
+/*************************************************************************/
+
+/***************************throughput ***********************************/
+
+/*throughput is 4 Bytes, but Rank is only 2 Bytes long */
+/*value is then divided by 2^RPL_DAG_MC_THROUGHPUT_DIVISOR */
+
+#define RPL_DAG_MC_THROUGHPUT_DIVISOR 16
+
+/* metric */
+#define RPL_DAG_MC_THROUGHPUT_INITIALIZATION 6553600
+/* constraint */
+#define RPL_DAG_MC_CONST_THROUGHPUT_THRESHOLD 3276800
+/*************************************************************************/
+
+/***************************latency **************************************/
+
+/*latency is 4 Bytes, but Rank is only 2 Bytes long */
+/*value is then divided by 2^ RPL_DAG_MC_LATENCY_DIVISOR */
+
+#define RPL_DAG_MC_LATENCY_DIVISOR 16
+
+/* metric */
+#define RPL_DAG_MC_LATENCY_INITIALIZATION 6533600
+/* constraint */
+#define RPL_DAG_MC_CONST_LATENCY_THRESHOLD 655360
+/*************************************************************************/
+
+/***************************LQL ******************************************/
+
+/* metric */
+#define RPL_DAG_MC_LQL_INITIALIZATION 3
+/* constraint */
+#define RPL_DAG_MC_CONST_LQL_THRESHOLD 5
+/*************************************************************************/
+
+/***************************etx ******************************************/
+
+/* metric */
+#define RPL_DAG_MC_ETX_INITIALIZATION 5
+/* constraint */
+#define RPL_DAG_MC_CONST_ETX_THRESHOLD 7
+/*****/
+
+//#define RPL_CONF_INIT_LINK_METRIC RPL_DAG_MC_ETX_INITIALIZATION
+/*ETX when no Ack from the node is received*/
+#define RPL_DAG_MC_ETX_MAX 10
+#define RPL_DAG_MC_ETX_DIVISOR 128
+/*weight of the old ETX when the new is calculated*/
+#define ETX_ALPHA 90
+#define ETX_SCALE 100
+
+
+/*************************************************************************/
+
+/***************************LC *******************************************/
+
+#define RPL_DAG_MC_LC_I_INCLUDED 0
+
+/* don't change this */
+#define RPL_DAG_MC_LC_MASK_BIT_1 0x001
+#define RPL_DAG_MC_LC_MASK_BIT_2 0x002
+#define RPL_DAG_MC_LC_MASK_BIT_3 0x004
+#define RPL_DAG_MC_LC_MASK_BIT_4 0x008
+#define RPL_DAG_MC_LC_MASK_BIT_5 0x010
+#define RPL_DAG_MC_LC_MASK_BIT_6 0x020
+#define RPL_DAG_MC_LC_MASK_BIT_7 0x040
+#define RPL_DAG_MC_LC_MASK_BIT_8 0x080
+#define RPL_DAG_MC_LC_MASK_BIT_9 0x100
+#define RPL_DAG_MC_LC_MASK_BIT_10 0x200
+
+/* metric */
+#define RPL_DAG_MC_LC_INITIALIZATION 0 //10 bits
+/* constraint */
+#define RPL_DAG_MC_CONST_LC_THRESHOLD 1 //10 bits
+/*************************************************************************/
+
+
+
+/* DAG Metric Container Object Types by IANA. */
+#define RPL_DAG_MC_NONE 0 /* Local identifier for empty MC */
+#define RPL_DAG_MC_NSA 1 /* Node State and Attributes */
+#define RPL_DAG_MC_ENERGY 2 /* Node Energy */
+#define RPL_DAG_MC_HOPCOUNT 3 /* Hop Count */
+#define RPL_DAG_MC_THROUGHPUT 4 /* Throughput */
+#define RPL_DAG_MC_LATENCY 5 /* Latency */
+#define RPL_DAG_MC_LQL 6 /* Link Quality Level */
+#define RPL_DAG_MC_ETX 7 /* Expected Transmission Count */
+#define RPL_DAG_MC_LC 8 /* Link Color */
+
+/* DAG Metric Container aggregation mode. */
+#define RPL_DAG_MC_AGGR_ADDITIVE 0
+#define RPL_DAG_MC_AGGR_MAXIMUM 1
+#define RPL_DAG_MC_AGGR_MINIMUM 2
+#define RPL_DAG_MC_AGGR_MULTIPLICATIVE 3
+
+
+extern uint8_t depleted_battery;
+extern unsigned char node_mac[8];
+#define AM_I_NODE(node) (node_mac[7]==node)
+
+#endif /* __PROJECT_CONF_H__ */
diff --git a/examples/containers/rpl-metrics-containers-OF.c b/examples/containers/rpl-metrics-containers-OF.c
new file mode 100644
index 00000000000..7d864c26474
--- /dev/null
+++ b/examples/containers/rpl-metrics-containers-OF.c
@@ -0,0 +1,321 @@
+
+#include "net/rpl/rpl-private.h"
+#include "net/nbr-table.h"
+#include "rpl-metrics.h"
+#include "rpl-metrics-get.h"
+
+#ifdef DEBUG_RPL_OF
+#include
+#define DEBUG DEBUG_PRINT
+
+#else /*DEBUG_RPL_OF*/
+#define DEBUG DEBUG_NONE
+#endif /*DEBUG_RPL_OF*/
+
+#include "net/uip-debug.h"
+
+
+static void reset(rpl_dag_t *);
+#if defined (RPL_DAG_MC_USE_ETX) || defined (RPL_DAG_MC_CONST_USE_ETX)
+static void neighbor_link_callback(rpl_parent_t *, int, int);
+#endif /* defined (RPL_DAG_MC_USE_ETX) || defined (RPL_DAG_MC_CONST_USE_ETX) */
+static rpl_parent_t *best_parent(rpl_parent_t *, rpl_parent_t *);
+static rpl_dag_t *best_dag(rpl_dag_t *, rpl_dag_t *);
+static rpl_rank_t calculate_rank(rpl_parent_t *, rpl_rank_t);
+static rpl_parent_t *check_optional_constraints (rpl_parent_t *, rpl_parent_t *);
+static void update_metric_container(rpl_instance_t *);
+
+
+rpl_of_t rpl_metrics_containers_OF = {
+ reset,
+#if defined (RPL_DAG_MC_USE_ETX) || defined (RPL_DAG_MC_CONST_USE_ETX)
+ neighbor_link_callback,
+#endif /* defined (RPL_DAG_MC_USE_ETX) || defined (RPL_DAG_MC_CONST_USE_ETX) */
+ best_parent,
+ best_dag,
+ calculate_rank,
+ update_metric_container,
+ 1
+};
+
+typedef uint16_t rpl_path_metric_t;
+extern uint8_t rpl_leaf;
+static uint8_t etx_weight=1;
+
+
+static void
+reset(rpl_dag_t *sag)
+{
+ PRINTF("RPL: Reset OF\n");
+}
+
+/**********************************************************************/
+
+/*
+ * Function called when a packet is sent, in order to refresh
+ * etx of the link
+ */
+
+#if defined (RPL_DAG_MC_USE_ETX) || defined (RPL_DAG_MC_CONST_USE_ETX)
+
+static void
+neighbor_link_callback(rpl_parent_t *p, int status, int numtx)
+{
+ rpl_metrics_etx_refresh(p,status, numtx);
+}
+
+#endif /* defined (RPL_DAG_MC_USE_ETX) || defined (RPL_DAG_MC_CONST_USE_ETX) */
+
+
+/**********************************************************************/
+
+static rpl_rank_t
+calculate_rank(rpl_parent_t *p, rpl_rank_t base_rank)
+{
+ rpl_rank_t new_rank= 0;
+ rpl_metric_element_t array_of_metrics[NUMBER_OF_METRICS_AND_CONST_USED];
+ uint8_t number_of_elems;
+ uint8_t i,j;
+
+ if(p == NULL) {
+ if(base_rank == 0) {
+ return INFINITE_RANK;
+ }
+ new_rank = RPL_INIT_LINK_METRIC + base_rank;
+ }
+ else {
+
+ number_of_elems= rpl_metrics_array_of_metrics (&(p->dag->instance->mc), array_of_metrics);
+
+
+#ifndef LEXIC_COMPOSITION /*then WEIGHTED_COMPOSITION */
+{
+#if defined(METRICS_WEIGHTS)
+ uint8_t weights_array[]= METRICS_WEIGHTS;
+#else /* defined(METRICS_WEIGHTS) */
+ uint8_t weights_array[NUMBER_OF_METRICS_AND_CONST_USED];
+ for (i=0, j=number_of_elems; j>0; j--)
+ weights_array[i++]= j;
+#endif /* defined(METRICS_WEIGHTS) */
+
+#ifdef DEBUG_RPL_OF
+ PRINTF("RPL: METRICS: OF: weighted composition of weights[ ");
+ for (i=0; iINFINITE_RANK)
+ new_rank= INFINITE_RANK;
+
+ PRINTF("RPL: METRICS: OF: new rank: %u\n",new_rank);
+
+ return new_rank;
+}
+
+
+/**********************************************************************/
+
+
+static rpl_dag_t *
+best_dag(rpl_dag_t *d1, rpl_dag_t *d2)
+{
+ if(d1->grounded != d2->grounded) {
+ return d1->grounded ? d1 : d2;
+ }
+
+ if(d1->preference != d2->preference) {
+ return d1->preference > d2->preference ? d1 : d2;
+ }
+
+ return d1->rank < d2->rank ? d1 : d2;
+}
+
+
+
+/**********************************************************************/
+
+
+
+static rpl_parent_t *
+best_parent(rpl_parent_t *p1, rpl_parent_t *p2)
+{
+ rpl_parent_t *p_parent;
+
+#ifndef LEXIC_COMPOSITION /*then WEIGHTED_COMPOSITION */
+
+ rpl_dag_t *dag;
+ rpl_path_metric_t p1_metric;
+ rpl_path_metric_t p2_metric;
+
+ uint16_t etx1, etx2;
+
+ dag = p1->dag; /* Both parents are in the same DAG. */
+
+ p1_metric= p1->rank;
+ p2_metric= p2->rank;
+
+#if defined( RPL_DAG_MC_USE_ETX)
+ /*
+ * ETX is the only metric of the node that doesn't remain the *
+ * same for both parents. LQL and LC not implemented yet. *
+ */
+
+ etx1= p1->etx;
+ etx2= p2->etx;
+
+ p1_metric+= etx1 * etx_weight;
+ p2_metric+= etx2 * etx_weight;
+#endif /* defined( RPL_DAG_MC_USE_ETX) */
+
+ /* check optional constraints if difference between metrics smaller than OPTIONAL_CONSTRAINTS_THRESHOLD*/
+
+ if(p1_metric < p2_metric + OPTIONAL_CONSTRAINTS_THRESHOLD &&
+ p1_metric >(p2_metric>OPTIONAL_CONSTRAINTS_THRESHOLD?(p2_metric-OPTIONAL_CONSTRAINTS_THRESHOLD):0)) {
+ p_parent= check_optional_constraints (p1, p2);
+ if(p_parent!= NULL){
+ return p_parent;
+ }
+ }
+
+ /* Maintain stability of the preferred parent in case of similar ranks. */
+ if(p1 == dag->preferred_parent || p2 == dag->preferred_parent) {
+ if(p1_metric < p2_metric + WEIGHTED_DIFF_THRESHOLD &&
+ p1_metric >(p2_metric>WEIGHTED_DIFF_THRESHOLD?(p2_metric-WEIGHTED_DIFF_THRESHOLD):0)) {
+ PRINTF("RPL: MRHOF hysteresis: %u <= %u <= %u\n",
+ p2_metric>WEIGHTED_DIFF_THRESHOLD?(p2_metric-WEIGHTED_DIFF_THRESHOLD):0,
+ p1_metric,
+ p2_metric + WEIGHTED_DIFF_THRESHOLD);
+
+ return dag->preferred_parent;
+ }
+ }
+ return p1_metric < p2_metric ? p1 : p2;
+
+#else /* LEXIC_COMPOSITION */
+
+ rpl_metric_element_t array_of_metrics_1[NUMBER_OF_METRICS_AND_CONST_USED];
+ rpl_metric_element_t array_of_metrics_2[NUMBER_OF_METRICS_AND_CONST_USED];
+ uint32_t lexic_diff_thres[]= LEXIC_DIFF_THRESHOLD;
+ uint8_t number_of_elems_1, number_of_elems_2;
+ uint8_t maximization_types[]=MAXIMIZED_METRICS;
+ int16_t diff;
+ uint8_t i,j;
+
+ number_of_elems_1= rpl_metrics_array_of_metrics (&(p1->mc), array_of_metrics_1);
+ number_of_elems_2= rpl_metrics_array_of_metrics (&(p2->mc), array_of_metrics_2);
+
+ if(number_of_elems_1 != number_of_elems_2){
+ PRINTF("RPL: METRICS: OF: Parents have different metric containers to compare\n");
+ return NULL;
+ }
+ else {
+ for (i= 0; i< number_of_elems_1; i++){
+ if(array_of_metrics_1[i].type != array_of_metrics_2[i].type){
+ PRINTF("RPL: METRICS: OF: Different metric objects to compare\n");
+ return NULL;
+ }
+ diff= array_of_metrics_1[i].data- array_of_metrics_2[i].data;
+
+ /*
+ * ETX is the only metric of the node that doesn't remain the *
+ * same for both parents. LQL and LC not implemented yet. *
+ */
+ if(array_of_metrics_1[i].type == RPL_DAG_MC_ETX)
+ diff+= p1->etx - p2->etx;
+
+ if( (diff > lexic_diff_thres[i]) || (diff < -lexic_diff_thres[i]) ){
+ /*check if type is in maximization metrics array*/
+ for(j=0; j<(sizeof(maximization_types)/ sizeof(maximization_types[0])); j++){
+ if(array_of_metrics_1[i].type == maximization_types[j])
+ return(diff>0 ? p1 : p2);
+ }
+ return(diff<0 ? p1 : p2);
+ }
+ }
+ return p1->dag->preferred_parent; /* Both parents are in the same DAG. */
+ }
+
+#endif /* LEXIC_COMPOSITION */
+
+}
+
+
+
+/**********************************************************************/
+
+
+static rpl_parent_t *
+check_optional_constraints (rpl_parent_t *p1, rpl_parent_t *p2){
+
+ rpl_metric_object_t *p_obj, *opt_const[NUMBER_OF_METRICS_AND_CONST_USED>>1];
+ uint8_t i, j, imin, num_objects, num_opt_const;
+ uint16_t flags;
+ uint8_t p1_const, p2_const;
+
+ /*identify optional constraints*/
+ num_opt_const= 0;
+ num_objects= p1->mc.metric_and_const_obj;
+ for(i=0; imc.metric_and_const_objects[i];
+ flags= p_obj->flags;
+ if( READ_BIT(flags, RPL_DAG_MC_POS_C_BIT) )
+ if( READ_BIT(flags, RPL_DAG_MC_POS_O_BIT))
+ opt_const[num_opt_const++]= p_obj;
+ }
+
+ if(num_opt_const){
+
+ /* sort by precedence */
+ for (i=0; i< num_opt_const-1; i++){
+ imin= i;
+ for(j=i+1; j< num_opt_const; j++){
+ if( (RPL_METRIC_READ_PREC_FIELD((opt_const[j]->flags))) < (RPL_METRIC_READ_PREC_FIELD((opt_const[imin]->flags))) )
+ imin= j;
+ }
+ p_obj= opt_const[i];
+ opt_const[i]= opt_const[imin];
+ opt_const[imin]= p_obj;
+ }
+
+ /*compare candidates*/
+ p1_const= p2_const= 0;
+ for(i=0; imc));
+ p2_const= rpl_metrics_satisfies_constraint (opt_const[i], &(p2->mc));
+ if(p1_const!=p2_const)
+ return (p1_const ? p1 : p2);
+ }
+ }
+ return NULL;
+}
+
+
+/**********************************************************************/
+
+
+static void
+update_metric_container(rpl_instance_t *instance)
+{
+ rpl_metrics_update_metric_container(instance);
+}
+
diff --git a/examples/containers/rpl-metrics-data.h b/examples/containers/rpl-metrics-data.h
new file mode 100644
index 00000000000..81c194adfe9
--- /dev/null
+++ b/examples/containers/rpl-metrics-data.h
@@ -0,0 +1,85 @@
+#ifndef RPL_METRICS_DATA_H
+#define RPL_METRICS_DATA_H
+
+
+struct rpl_metric_object_NSA {
+ uint8_t flags;
+};
+typedef struct rpl_metric_object_NSA rpl_metric_object_NSA_t;
+
+struct rpl_metric_object_energy {
+ uint8_t flags;
+ uint8_t energy_est;
+};
+typedef struct rpl_metric_object_energy rpl_metric_object_energy_t;
+
+struct rpl_metric_object_hop_count {
+ uint8_t hop_count;
+};
+typedef struct rpl_metric_object_hop_count rpl_metric_object_hop_count_t;
+
+struct rpl_metric_object_throughput {
+ uint32_t throughput;
+};
+typedef struct rpl_metric_object_throughput rpl_metric_object_throughput_t;
+
+struct rpl_metric_object_latency {
+ uint32_t latency;
+};
+typedef struct rpl_metric_object_latency rpl_metric_object_latency_t;
+
+struct rpl_metric_object_LQL {
+ uint8_t value_and_counter;
+};
+typedef struct rpl_metric_object_LQL rpl_metric_object_LQL_t;
+
+struct rpl_metric_object_ETX {
+ uint16_t etx;
+};
+typedef struct rpl_metric_object_ETX rpl_metric_object_ETX_t;
+
+struct rpl_metric_object_LC {
+ uint16_t color_and_counter;
+};
+typedef struct rpl_metric_object_LC rpl_metric_object_LC_t;
+
+
+
+struct rpl_metric_object {
+ uint8_t type;
+ uint16_t flags;
+ uint8_t length;
+ union {
+ struct rpl_metric_object_NSA *nsa;
+ struct rpl_metric_object_LQL *lql;
+ struct rpl_metric_object_energy *energy;
+ struct rpl_metric_object_hop_count *hop_count;
+ struct rpl_metric_object_ETX *etx;
+ struct rpl_metric_object_LC *lc;
+ struct rpl_metric_object_throughput *throughput;
+ struct rpl_metric_object_latency *latency;
+ void *rpl_metric_object_data_pointer;
+ } ;
+};
+typedef struct rpl_metric_object rpl_metric_object_t;
+
+
+
+struct rpl_metric_container {
+
+ uint8_t metric_and_const_obj;
+
+ rpl_metric_object_t* metric_and_const_objects[NUMBER_OF_METRICS_AND_CONST_USED];
+};
+typedef struct rpl_metric_container rpl_metric_container_t;
+
+
+
+struct rpl_metric_element {
+ uint8_t type;
+ uint8_t aggregation_mode;
+ uint16_t data;
+};
+typedef struct rpl_metric_element rpl_metric_element_t;
+
+#endif /* RPL_METRICS_DATA_H */
diff --git a/examples/containers/rpl-metrics-get.c b/examples/containers/rpl-metrics-get.c
new file mode 100644
index 00000000000..0176d223c49
--- /dev/null
+++ b/examples/containers/rpl-metrics-get.c
@@ -0,0 +1,262 @@
+#include "net/rpl/rpl-private.h"
+#include "sys/energest.h"
+#include "dev/leds.h"
+
+
+#ifdef DEBUG_RPL_METRICS_GET
+#define DEBUG DEBUG_PRINT
+#else
+#define DEBUG DEBUG_NONE
+#endif
+#include "net/uip-debug.h"
+#include
+
+static uint16_t max_charge;
+uint8_t rpl_metrics_power_refresh();
+
+
+/********************************************************************/
+
+uint8_t rpl_metrics_get_NSA()
+{
+ // if((AM_I_NODE(2))||(AM_I_NODE(3)))
+ // return ((1<<1)+1);
+ return ((RPL_DAG_MC_NSA_A_AGGREGATION<<1)+RPL_DAG_MC_NSA_O_OVERLOAD);
+}
+
+
+/********************************************************************/
+
+#if defined(RPL_DAG_MC_USE_ENERGY) || defined(RPL_DAG_MC_CONST_USE_ENERGY)
+uint8_t rpl_metrics_get_energy()
+{
+ uint8_t power;
+ static uint8_t initialized= 0;
+
+ if(!initialized){
+ initialized++;
+ // if(AM_I_NODE(6))
+ // max_charge= (100L*3600)>>16;
+ // else
+ max_charge= (BATT_CHARGE*3600)>>16;
+ }
+power= rpl_metrics_power_refresh();
+
+#ifdef RPL_DAG_MC_ENERGY_DIVISOR
+ power>>= RPL_DAG_MC_ENERGY_DIVISOR;
+#endif
+
+ return( power==0 ? 1 : power );
+
+}
+#endif /*defined(RPL_DAG_MC_USE_ENERGY) || defined(RPL_DAG_MC_CONST_USE_ENERGY)*/
+
+
+/********************************************************************/
+
+uint8_t rpl_metrics_get_hop_count()
+{
+ rpl_dag_t *dag;
+ rpl_metric_container_t *p_container;
+ uint8_t i;
+
+ /* Let's suppose we have only one instance */
+ dag = rpl_get_any_dag();
+
+ if(dag->preferred_parent != NULL) {
+ p_container=&(dag->preferred_parent->mc);
+ for(i=0; i< p_container->metric_and_const_obj; i++){
+ if(p_container->metric_and_const_objects[i]->type == RPL_DAG_MC_HOPCOUNT)
+ return(p_container->metric_and_const_objects[i]->hop_count->hop_count + 1);
+ }
+ }
+
+ return 0;
+
+}
+
+
+/********************************************************************/
+
+uint32_t rpl_metrics_get_throughput()
+{
+
+ if(AM_I_NODE(3))
+ return (150*65536);
+ return (100*65536);
+}
+
+/********************************************************************/
+
+uint32_t rpl_metrics_get_latency()
+{
+
+ if(AM_I_NODE(3))
+ return (100*65536);
+ return (150*65536);
+}
+
+/********************************************************************/
+
+uint8_t rpl_metrics_get_LQL()
+{
+
+ // if((AM_I_NODE(2))||(AM_I_NODE(3)))
+ // return (6 <<5);
+ return ((RPL_DAG_MC_LQL_INITIALIZATION & 0x7)<<5);
+}
+
+
+/********************************************************************/
+
+#if defined(RPL_DAG_MC_USE_ETX) || defined(RPL_DAG_MC_CONST_USE_ETX)
+
+uint16_t rpl_metrics_get_ETX()
+{
+ rpl_dag_t *dag;
+
+ /* Let's suppose we have only one instance */
+ dag = rpl_get_any_dag();
+
+ if(dag->preferred_parent != NULL)
+ return (dag->preferred_parent->etx);
+ else
+ return 0 ;
+}
+#endif /* defined(RPL_DAG_MC_USE_ETX) || defined(RPL_DAG_MC_CONST_USE_ETX)*/
+
+/********************************************************************/
+
+uint16_t rpl_metrics_get_LC()
+{
+ // if((AM_I_NODE(2))||(AM_I_NODE(3)))
+ // return (2 <<6);
+ return (RPL_DAG_MC_LC_INITIALIZATION<<6);
+}
+
+
+/********************************************************************/
+
+#if defined(RPL_DAG_MC_USE_ETX) || defined(RPL_DAG_MC_CONST_USE_ETX)
+
+void rpl_metrics_etx_refresh(rpl_parent_t *p, int status, int numtx)
+{
+ uint16_t recorded_etx = p->etx;
+ uint16_t packet_etx = numtx * RPL_DAG_MC_ETX_DIVISOR;
+ uint16_t new_etx;
+
+/* When the radio was explicitly turned off, mac returns MAC_TX_ERR_FATAL.
+ * To simulate loss of communication with the parent, it is changed for
+ * no Ack received
+ */
+#ifdef BUTTON_INTERFERENCE
+ if(status== MAC_TX_ERR_FATAL)
+ status= MAC_TX_NOACK;
+#endif /*BUTTON_INTERFERENCE*/
+
+ /* Do not penalize the ETX when collisions or transmission errors occur. */
+ if(status == MAC_TX_OK || status == MAC_TX_NOACK) {
+ if(status == MAC_TX_NOACK) {
+ packet_etx = RPL_DAG_MC_ETX_MAX * RPL_DAG_MC_ETX_DIVISOR;
+ }
+
+ new_etx = ((uint32_t)recorded_etx * ETX_ALPHA +
+ (uint32_t)packet_etx * (ETX_SCALE - ETX_ALPHA)) / ETX_SCALE;
+
+ PRINTF("RPL: METRICS: ETX old: %u,new: %u (packet ETX = %u)\n",
+ recorded_etx, new_etx, packet_etx);
+ p->etx = new_etx;
+ }
+
+#ifdef DEBUG_RPL_METRICS_GET
+ if(status == MAC_TX_OK) //The MAC layer transmission was OK.
+ printf("- OK\n");
+ else if (status == MAC_TX_NOACK) //The MAC layer did not get an acknowledgement for the packet.
+ printf("- NO ACK\n");
+ else
+ printf("- PROBLEM\n");
+#endif /* DEBUG_RPL_METRICS_GET */
+
+}
+#endif /* defined(RPL_DAG_MC_USE_ETX) || defined(RPL_DAG_MC_CONST_USE_ETX) */
+
+
+
+/********************************************************************/
+
+#if defined(RPL_DAG_MC_USE_ENERGY) || defined(RPL_DAG_MC_CONST_USE_ENERGY)
+
+uint8_t rpl_metrics_power_refresh()
+{
+ uint32_t ticks_cpu, ticks_lpm, ticks_transmit, ticks_listen;
+ uint8_t batt_used;
+ uint32_t power32;
+
+ energest_flush();
+
+ ticks_lpm = energest_type_time(ENERGEST_TYPE_LPM)>>8;
+ ticks_cpu = energest_type_time(ENERGEST_TYPE_CPU)>>8;
+ ticks_transmit = energest_type_time(ENERGEST_TYPE_TRANSMIT)>>8;
+ ticks_listen = energest_type_time(ENERGEST_TYPE_LISTEN)>>8;
+
+ power32= (ticks_lpm * (uint16_t)CURRENT_LPM) + (ticks_cpu * (uint16_t)CURRENT_CPU) + (ticks_transmit * (uint16_t)CURRENT_TRANSMIT) + (ticks_listen * (uint16_t)CURRENT_LISTEN);
+
+ power32>>=(TICKS_PER_SECOND-8);
+
+ if(power32 >= ((uint32_t)max_charge<<16)){
+ batt_used= 0xFF;
+#ifdef STATISTICS
+ if(!depleted_battery)
+ printf("30 Battery used: 100%%\n");
+#endif /*STATISTICS*/
+
+ depleted_battery= 1;
+ leds_on(1);//BLUE
+
+
+ }
+ else
+ batt_used= (uint8_t) ((power32/max_charge)>>8);
+
+#ifdef STATISTICS
+ {
+ uint8_t perc;
+ static uint8_t perc_25=0;
+ static uint8_t perc_50=0;
+ static uint8_t perc_75=0;
+
+ perc= (batt_used*100)/0xFF;
+ if( (perc>= 75) && (!depleted_battery)){
+ if(!perc_75){
+ perc_75++;
+ printf("30 Battery used: 75%%\n");
+ }
+ }
+ else if(perc>= 50){
+ if(!perc_50){
+ perc_50++;
+ printf("30 Battery used: 50%%\n");
+ }
+ }
+ else if(perc>= 25){
+ if(!perc_25){
+ perc_25++;
+ printf("30 Battery used: 25%%\n");
+ }
+ }
+ }
+#endif /*STATISTICS*/
+
+
+ PRINTF("RPL:METRICS:ticks_lpm %lu-0x%08lx\n",ticks_lpm<<8,ticks_lpm<<8);
+ PRINTF("RPL:METRICS:ticks_cpu %lu-0x%08lx\n",ticks_cpu<<8,ticks_cpu<<8);
+ PRINTF("RPL:METRICS:ticks_trans %lu-0x%08lx\n",ticks_transmit<<8,ticks_transmit<<8);
+ PRINTF("RPL:METRICS:ticks_rx %lu-0x%08lx\n",ticks_listen<<8,ticks_listen<<8);
+
+ PRINTF("RPL:METRICS:consumed= %lu-0x%08lx (uAs) total= %lu\n", power32,power32, (uint32_t)max_charge<<16);
+ PRINTF("RPL:METRICS:% bat= %u\n",batt_used);
+
+
+ return batt_used;
+}
+#endif /*defined(RPL_DAG_MC_USE_ENERGY) || defined(RPL_DAG_MC_CONST_USE_ENERGY)*/
diff --git a/examples/containers/rpl-metrics-get.h b/examples/containers/rpl-metrics-get.h
new file mode 100644
index 00000000000..bd21b79ea36
--- /dev/null
+++ b/examples/containers/rpl-metrics-get.h
@@ -0,0 +1,13 @@
+#ifndef RPL_METRICS_GET_H
+#define RPL_METRICS_GET_H
+
+uint8_t rpl_metrics_get_NSA();
+uint8_t rpl_metrics_get_energy();
+uint32_t rpl_metrics_get_throughput();
+uint32_t rpl_metrics_get_latency();
+uint8_t rpl_metrics_get_LQL();
+uint16_t rpl_metrics_get_ETX();
+uint16_t rpl_metrics_get_LC();
+
+void rpl_metrics_etx_refresh(rpl_parent_t *p, int status, int numtx);
+#endif /* RPL_METRICS_GET_H */
diff --git a/examples/containers/rpl-metrics.c b/examples/containers/rpl-metrics.c
new file mode 100644
index 00000000000..4b940ea5f56
--- /dev/null
+++ b/examples/containers/rpl-metrics.c
@@ -0,0 +1,890 @@
+
+#include "rpl-metrics.h"
+#include "net/rpl/rpl-private.h"
+#include "rpl-metrics-get.h"
+#include
+#include
+
+#ifdef DEBUG_RPL_METRICS
+#define DEBUG DEBUG_PRINT
+#else
+#define DEBUG DEBUG_NONE
+#endif
+#include "net/uip-debug.h"
+
+extern uint8_t rpl_leaf;
+extern uint8_t leaf_dio;
+
+uint8_t
+rpl_metrics_create_object (rpl_metric_container_t *p_mc, uint8_t type, uint8_t pos_obj)
+{
+ rpl_metric_object_t *p_obj;
+ uint8_t error;
+
+ if( NULL == (p_mc->metric_and_const_objects[pos_obj]= malloc (sizeof(rpl_metric_object_t))))
+ return 1;
+
+ error= 0;
+ p_obj= p_mc->metric_and_const_objects[pos_obj];
+
+ switch (type){
+#if defined( RPL_DAG_MC_USE_NSA) || defined (RPL_DAG_MC_CONST_USE_NSA)
+ case RPL_DAG_MC_NSA:
+ if( NULL == (p_obj->nsa= malloc (sizeof(rpl_metric_object_NSA_t))))
+ error= 1;
+ break;
+#endif /* defined( RPL_DAG_MC_USE_NSA) || defined (RPL_DAG_MC_CONST_USE_NSA) */
+#if defined( RPL_DAG_MC_USE_ENERGY) || defined( RPL_DAG_MC_CONST_USE_ENERGY)
+ case RPL_DAG_MC_ENERGY:
+ if( NULL == (p_obj->energy= malloc (sizeof(rpl_metric_object_energy_t))))
+ error= 1;
+ break;
+#endif /*defined( RPL_DAG_MC_USE_ENERGY) || defined( RPL_DAG_MC_CONST_USE_ENERGY)*/
+#if defined( RPL_DAG_MC_USE_HOPCOUNT) || defined( RPL_DAG_MC_CONST_USE_HOPCOUNT)
+ case RPL_DAG_MC_HOPCOUNT:
+ if( NULL == (p_obj->hop_count= malloc (sizeof(rpl_metric_object_hop_count_t))))
+ error= 1;
+ break;
+#endif /*defined( RPL_DAG_MC_USE_HOPCOUNT) || defined( RPL_DAG_MC_CONST_USE_HOPCOUNT)*/
+#if defined( RPL_DAG_MC_USE_THROUGHPUT) || defined( RPL_DAG_MC_CONST_USE_THROUGHPUT)
+ case RPL_DAG_MC_THROUGHPUT:
+ if( NULL == (p_obj->throughput= malloc (sizeof(rpl_metric_object_throughput_t))))
+ error= 1;
+ break;
+#endif /*defined( RPL_DAG_MC_USE_THROUGHPUT) || defined( RPL_DAG_MC_CONST_USE_THROUGHPUT)*/
+#if defined( RPL_DAG_MC_USE_LATENCY) || defined( RPL_DAG_MC_CONST_USE_LATENCY)
+ case RPL_DAG_MC_LATENCY:
+ if( NULL == (p_obj->latency= malloc (sizeof(rpl_metric_object_latency_t))))
+ error= 1;
+ break;
+#endif /*defined( RPL_DAG_MC_USE_LATENCY) || defined( RPL_DAG_MC_CONST_USE_LATENCY)*/
+#if defined( RPL_DAG_MC_USE_LQL) || defined( RPL_DAG_MC_CONST_USE_LQL)
+ case RPL_DAG_MC_LQL:
+ if( NULL == (p_obj->lql= malloc (sizeof(rpl_metric_object_LQL_t))))
+ error= 1;
+ break;
+#endif /*defined( RPL_DAG_MC_USE_LQL) || defined( RPL_DAG_MC_CONST_USE_LQL)*/
+#if defined( RPL_DAG_MC_USE_ETX) || defined( RPL_DAG_MC_CONST_USE_ETX)
+ case RPL_DAG_MC_ETX:
+ if( NULL == (p_obj->etx= malloc (sizeof(rpl_metric_object_ETX_t))))
+ error= 1;
+ break;
+#endif /*defined( RPL_DAG_MC_USE_ETX) || defined( RPL_DAG_MC_CONST_USE_ETX)*/
+#if defined( RPL_DAG_MC_USE_LC) || defined( RPL_DAG_MC_CONST_USE_LC)
+ case RPL_DAG_MC_LC:
+ if( NULL == (p_obj->lc= malloc (sizeof(rpl_metric_object_LC_t))))
+ error= 1;
+ break;
+#endif /*defined( RPL_DAG_MC_USE_LC) || defined( RPL_DAG_MC_CONST_USE_LC)*/
+ default:
+ /* unknown metric object */
+ error= 2;
+ }
+ if(error){
+ free(p_obj);
+ PRINTF("RPL: METRICS: ERROR creating an object\n");
+ }
+
+ return error;
+}
+
+
+
+/*****************************************************************************************************/
+
+
+uint8_t
+rpl_metrics_create_root_container(rpl_metric_container_t *p_mc)
+{
+ uint8_t objects_created;
+ uint32_t header;
+ rpl_metric_object_t **p_p_obj;
+ uint32_t object_headers[NUMBER_OF_METRICS_AND_CONST_USED];
+ uint8_t i;
+
+ if (NUMBER_OF_METRICS_AND_CONST_USED){
+ objects_created= 0;
+ p_p_obj= p_mc->metric_and_const_objects;
+#ifdef RPL_DAG_MC_USE_NSA
+ if( rpl_metrics_create_object (p_mc, RPL_DAG_MC_NSA, objects_created) )
+ return 0;
+ object_headers[objects_created++]= RPL_DAG_MC_USE_NSA;
+ (*p_p_obj++)->nsa->flags= RPL_DAG_MC_NSA_O_OVERLOAD|(RPL_DAG_MC_NSA_A_AGGREGATION<<1);
+#endif /* RPL_DAG_MC_USE_NSA */
+
+#ifdef RPL_DAG_MC_USE_ENERGY
+ if( rpl_metrics_create_object (p_mc, RPL_DAG_MC_ENERGY, objects_created) )
+ return 0;
+ object_headers[objects_created++]= RPL_DAG_MC_USE_ENERGY;
+ (*p_p_obj)->energy->flags= (RPL_DAG_MC_ENERGY_I_INCLUDED<<3)|(RPL_DAG_MC_ENERGY_T_TYPE<<1)|RPL_DAG_MC_ENERGY_E_ESTIMATION;
+ (*p_p_obj++)->energy->energy_est= RPL_DAG_MC_ENERGY_INITIALIZATION;
+#endif /* RPL_DAG_MC_USE_ENERGY */
+
+#ifdef RPL_DAG_MC_USE_HOPCOUNT
+ if( rpl_metrics_create_object (p_mc, RPL_DAG_MC_HOPCOUNT, objects_created) )
+ return 0;
+ object_headers[objects_created++]= RPL_DAG_MC_USE_HOPCOUNT;
+ (*p_p_obj++)->hop_count->hop_count= RPL_DAG_MC_HOPCOUNT_INITIALIZATION;
+#endif /* RPL_DAG_MC_USE_HOPCOUNT */
+
+#ifdef RPL_DAG_MC_USE_THROUGHPUT
+ if( rpl_metrics_create_object (p_mc, RPL_DAG_MC_THROUGHPUT, objects_created) )
+ return 0;
+ object_headers[objects_created++]= RPL_DAG_MC_USE_THROUGHPUT;
+ (*p_p_obj++)->throughput->throughput= RPL_DAG_MC_THROUGHPUT_INITIALIZATION;
+#endif /* RPL_DAG_MC_USE_THROUGHPUT */
+
+#ifdef RPL_DAG_MC_USE_LATENCY
+ if( rpl_metrics_create_object (p_mc, RPL_DAG_MC_LATENCY, objects_created) )
+ return 0;
+ object_headers[objects_created++]= RPL_DAG_MC_USE_LATENCY;
+ (*p_p_obj++)->latency->latency= RPL_DAG_MC_LATENCY_INITIALIZATION;
+#endif /* RPL_DAG_MC_USE_LATENCY */
+
+#ifdef RPL_DAG_MC_USE_LQL
+ if( rpl_metrics_create_object (p_mc, RPL_DAG_MC_LQL, objects_created) )
+ return 0;
+ object_headers[objects_created++]= RPL_DAG_MC_USE_LQL;
+ (*p_p_obj++)->lql->value_and_counter= RPL_DAG_MC_LQL_INITIALIZATION<<5;
+#endif /* RPL_DAG_MC_USE_LQL */
+
+#ifdef RPL_DAG_MC_USE_ETX
+ if( rpl_metrics_create_object (p_mc, RPL_DAG_MC_ETX, objects_created) )
+ return 0;
+ object_headers[objects_created++]= RPL_DAG_MC_USE_ETX;
+ (*p_p_obj++)->etx->etx= RPL_DAG_MC_ETX_INITIALIZATION * RPL_DAG_MC_ETX_DIVISOR;
+#endif /* RPL_DAG_MC_USE_ETX */
+
+#ifdef RPL_DAG_MC_USE_LC
+ if( rpl_metrics_create_object (p_mc, RPL_DAG_MC_LC, objects_created) )
+ return 0;
+ object_headers[objects_created++]= RPL_DAG_MC_USE_LC;
+ (*p_p_obj++)->lc->color_and_counter= RPL_DAG_MC_LC_INITIALIZATION<<6;
+#endif /* RPL_DAG_MC_USE_LC */
+
+#ifdef RPL_DAG_MC_CONST_USE_NSA
+ if( rpl_metrics_create_object (p_mc, RPL_DAG_MC_NSA, objects_created) )
+ return 0;
+ object_headers[objects_created++]= RPL_DAG_MC_CONST_USE_NSA;
+ (*p_p_obj++)->nsa->flags= RPL_DAG_MC_CONST_NSA_O_OVERLOAD|(RPL_DAG_MC_CONST_NSA_A_AGGREGATION<<1);
+#endif /* RPL_DAG_MC_CONST_USE_NSA */
+
+#ifdef RPL_DAG_MC_CONST_USE_ENERGY
+ if( rpl_metrics_create_object (p_mc, RPL_DAG_MC_ENERGY, objects_created) )
+ return 0;
+ object_headers[objects_created++]= RPL_DAG_MC_CONST_USE_ENERGY;
+ (*p_p_obj)->energy->flags= (RPL_DAG_MC_CONST_ENERGY_I_INCLUDED<<3)|(RPL_DAG_MC_CONST_ENERGY_T_TYPE<<1)|RPL_DAG_MC_CONST_ENERGY_E_ESTIMATION;
+ (*p_p_obj++)->energy->energy_est= RPL_DAG_MC_CONST_ENERGY_THRESHOLD;
+#endif /* RPL_DAG_MC_CONST_USE_ENERGY */
+
+#ifdef RPL_DAG_MC_CONST_USE_HOPCOUNT
+ if( rpl_metrics_create_object (p_mc, RPL_DAG_MC_HOPCOUNT, objects_created) )
+ return 0;
+ object_headers[objects_created++]= RPL_DAG_MC_CONST_USE_HOPCOUNT;
+ (*p_p_obj++)->hop_count->hop_count= RPL_DAG_MC_CONST_HOPCOUNT_THRESHOLD;
+#endif /* RPL_DAG_MC_CONST_USE_HOPCOUNT */
+
+#ifdef RPL_DAG_MC_CONST_USE_THROUGHPUT
+ if( rpl_metrics_create_object (p_mc, RPL_DAG_MC_THROUGHPUT, objects_created) )
+ return 0;
+ object_headers[objects_created++]= RPL_DAG_MC_CONST_USE_THROUGHPUT;
+ (*p_p_obj++)->throughput->throughput= RPL_DAG_MC_CONST_THROUGHPUT_THRESHOLD;
+#endif /* RPL_DAG_MC_CONST_USE_THROUGHPUT */
+
+#ifdef RPL_DAG_MC_CONST_USE_LATENCY
+ if( rpl_metrics_create_object (p_mc, RPL_DAG_MC_LATENCY, objects_created) )
+ return 0;
+ object_headers[objects_created++]= RPL_DAG_MC_CONST_USE_LATENCY;
+ (*p_p_obj++)->latency->latency= RPL_DAG_MC_CONST_LATENCY_THRESHOLD;
+#endif /* RPL_DAG_MC_CONST_USE_LATENCY */
+
+#ifdef RPL_DAG_MC_CONST_USE_LQL
+ if( rpl_metrics_create_object (p_mc, RPL_DAG_MC_LQL, objects_created) )
+ return 0;
+ object_headers[objects_created++]= RPL_DAG_MC_CONST_USE_LQL;
+ (*p_p_obj++)->lql->value_and_counter= RPL_DAG_MC_CONST_LQL_THRESHOLD<<5;
+#endif /* RPL_DAG_MC_CONST_USE_LQL */
+
+#ifdef RPL_DAG_MC_CONST_USE_ETX
+ if( rpl_metrics_create_object (p_mc, RPL_DAG_MC_ETX, objects_created) )
+ return 0;
+ object_headers[objects_created++]= RPL_DAG_MC_CONST_USE_ETX;
+ (*p_p_obj++)->etx->etx= RPL_DAG_MC_CONST_ETX_THRESHOLD;
+#endif /* RPL_DAG_MC_CONST_USE_ETX */
+
+#ifdef RPL_DAG_MC_CONST_USE_LC
+ if( rpl_metrics_create_object (p_mc, RPL_DAG_MC_LC, objects_created) )
+ return 0;
+ object_headers[objects_created++]= RPL_DAG_MC_CONST_USE_LC;
+ (*p_p_obj++)->lc->color_and_counter= (RPL_DAG_MC_CONST_LC_THRESHOLD<<6) | RPL_DAG_MC_LC_I_INCLUDED;
+#endif /* RPL_DAG_MC_CONST_USE_LC */
+
+ p_mc->metric_and_const_obj= objects_created;
+
+#ifdef DEBUG_RPL_METRICS
+ if(NUMBER_OF_METRICS_AND_CONST_USED != objects_created)
+ printf("RPL: METRICS: NUMBER_OF_CONSTRAINTS_USED is not the same as objects created\n");
+#endif /* DEBUG_RPL_METRICS */
+
+ p_p_obj= p_mc->metric_and_const_objects;
+ for (i= 0; i< objects_created; i++){
+ header= object_headers[i];
+ (*p_p_obj)->type= RPL_METRIC_OBJECT_HEADER_TYPE(header);
+ (*p_p_obj)->flags= RPL_METRIC_OBJECT_HEADER_FLAGS(header);
+ (*p_p_obj++)->length= RPL_METRIC_OBJECT_HEADER_LENGTH(header);
+ }
+ }
+return 1;
+
+}
+
+
+/**************************************************************************************************/
+
+
+uint8_t
+rpl_metrics_copy_mc (rpl_metric_container_t *p_mc_dest, rpl_metric_container_t *p_mc_orig)
+{
+ uint8_t i;
+ uint8_t ok_ret_value;
+ uint8_t num_dest_objects, num_orig_objects;
+ rpl_metric_object_t *p_obj_dest, *p_obj_orig;
+
+ num_dest_objects= p_mc_dest->metric_and_const_obj;
+ num_orig_objects= p_mc_orig->metric_and_const_obj;
+ ok_ret_value = 1;
+ if(num_dest_objects < num_orig_objects){
+ for (i= num_dest_objects; i< num_orig_objects; i++){
+ if( rpl_metrics_create_object(p_mc_dest,p_mc_orig->metric_and_const_objects[i]->type, i)){
+ PRINTF("RPL: METRICS: Error creating an object\n");
+ num_orig_objects= i;
+ ok_ret_value= 0;
+ }
+ else{
+ p_mc_dest->metric_and_const_obj++;
+ p_mc_dest->metric_and_const_objects[i]->length = p_mc_orig->metric_and_const_objects[i]->length;
+ }
+ }
+ }
+ else if(num_dest_objects > num_orig_objects){
+ for(i= num_orig_objects; i< num_dest_objects; i++){
+ free( p_mc_dest->metric_and_const_objects[i]->rpl_metric_object_data_pointer);
+ free( p_mc_dest->metric_and_const_objects[i]);
+ p_mc_dest->metric_and_const_obj--;
+ }
+ }
+
+ for (i=0; i< num_orig_objects; i++){
+ p_obj_dest= p_mc_dest->metric_and_const_objects[i];
+ p_obj_orig= p_mc_orig->metric_and_const_objects[i];
+ if(p_obj_dest->length != p_obj_orig->length ){
+ free(p_obj_dest->rpl_metric_object_data_pointer);
+ if( NULL == (p_obj_dest->rpl_metric_object_data_pointer= malloc (sizeof(p_obj_orig->length * sizeof(uint8_t))))){
+ PRINTF("RPL: METRICS: Error allocating memory for a metric object\n");
+ return 0;
+ }
+ }
+ p_obj_dest->type = p_obj_orig->type;
+ p_obj_dest->flags = p_obj_orig->flags;
+ p_obj_dest->length = p_obj_orig->length;
+ memcpy(p_obj_dest->rpl_metric_object_data_pointer,p_obj_orig->rpl_metric_object_data_pointer, p_obj_dest->length * sizeof(uint8_t));
+ }
+ p_mc_dest->metric_and_const_obj= num_orig_objects;
+
+ return ok_ret_value;
+}
+
+
+/*************************************************************************************************/
+
+
+uint8_t
+rpl_metrics_write_object_to_metric_container (rpl_metric_container_t *mc, uint8_t *buffer, uint8_t obj_cont){
+
+ rpl_metric_object_t* p_obj= NULL;
+ uint8_t error_code;
+ uint8_t type;
+ uint8_t number_objects;
+ uint8_t i;
+ uint16_t temp16;
+ uint32_t temp32;
+
+ number_objects= mc->metric_and_const_obj;
+ if ( (obj_cont >= NUMBER_OF_METRICS_AND_CONST_USED) || (obj_cont > number_objects)){
+ PRINTF("RPL: METRICS: DIO has too many metric objects or not memory enough\n");
+ return 0;
+ }
+
+ i=0;
+ type= buffer[i++];
+
+ if ( ((obj_cont < number_objects)&&(mc->metric_and_const_objects[obj_cont]->type != type)) || (obj_cont == number_objects) ){
+ if(obj_cont != number_objects)
+ free(mc->metric_and_const_objects[obj_cont]);
+ error_code= rpl_metrics_create_object (mc, type, obj_cont);
+ if (error_code==1){
+ PRINTF("RPL: METRICS: Unable to allocate mem for an object\n");
+ return 0;
+ }
+ if (error_code==2){
+ PRINTF("RPL: METRICS: Unknown metric object\n");
+ return 0;
+ }
+ if (obj_cont == number_objects)
+ (mc->metric_and_const_obj)++;
+ }
+
+ p_obj= mc->metric_and_const_objects[obj_cont];
+ p_obj->type= type;
+ temp16= buffer[i++];
+ temp16= (temp16<<8)+buffer[i++];
+ p_obj->flags= temp16;
+ p_obj->length= buffer[i++];
+
+ switch (type){
+#if defined (RPL_DAG_MC_USE_NSA) || defined (RPL_DAG_MC_CONST_USE_NSA)
+ case RPL_DAG_MC_NSA:
+ i++; //reserved flags
+ p_obj->nsa->flags= buffer[i++];
+ PRINTF("RPL: METRICS: DIO had an NSA object\n");
+ break;
+#endif /* defined (RPL_DAG_MC_USE_NSA) || defined (RPL_DAG_MC_CONST_USE_NSA) */
+#if defined(RPL_DAG_MC_USE_ENERGY) || defined(RPL_DAG_MC_CONST_USE_ENERGY)
+ case RPL_DAG_MC_ENERGY:
+ p_obj->energy->flags= buffer[i++];
+ p_obj->energy->energy_est= buffer[i++];
+ PRINTF("RPL: METRICS: DIO had an energy object with flags:0x%02x, value:%u\n",p_obj->energy->flags, p_obj->energy->energy_est);
+ break;
+#endif /* defined(RPL_DAG_MC_USE_ENERGY) || defined(RPL_DAG_MC_CONST_USE_ENERGY) */
+#if defined(RPL_DAG_MC_USE_HOPCOUNT) || defined(RPL_DAG_MC_CONST_USE_HOPCOUNT)
+ case RPL_DAG_MC_HOPCOUNT:
+ i++; //reserved flags
+ p_obj->hop_count->hop_count= buffer[i++];
+ PRINTF("RPL: METRICS: DIO had a hop-count object with value:%u\n",buffer[i-1]);
+ break;
+#endif /* defined(RPL_DAG_MC_USE_HOPCOUNT) || defined(RPL_DAG_MC_CONST_USE_HOPCOUNT) */
+#if defined(RPL_DAG_MC_USE_THROUGHPUT) || defined(RPL_DAG_MC_CONST_USE_THROUGHPUT)
+ case RPL_DAG_MC_THROUGHPUT:
+ temp32= buffer[i++];
+ temp32= (temp32<<8)+buffer[i++];
+ temp32= (temp32<<8)+buffer[i++];
+ temp32= (temp32<<8)+buffer[i++];
+ p_obj->throughput->throughput= temp32;
+ PRINTF("RPL: METRICS: DIO had a throughput object with value:%lu\n",p_obj->throughput->throughput);
+ break;
+#endif /* defined(RPL_DAG_MC_USE_THROUGHPUT) || defined(RPL_DAG_MC_CONST_USE_THROUGHPUT) */
+#if defined(RPL_DAG_MC_USE_LATENCY) || defined(RPL_DAG_MC_CONST_USE_LATENCY)
+ case RPL_DAG_MC_LATENCY:
+ temp32= buffer[i++];
+ temp32= (temp32<<8)+buffer[i++];
+ temp32= (temp32<<8)+buffer[i++];
+ temp32= (temp32<<8)+buffer[i++];
+ p_obj->latency->latency= temp32;
+ PRINTF("RPL: METRICS: DIO had a latency object with value:%lu\n",p_obj->latency->latency);
+ break;
+#endif /* defined(RPL_DAG_MC_USE_LATENCY) || defined(RPL_DAG_MC_CONST_USE_LATENCY) */
+#if defined(RPL_DAG_MC_USE_LQL) || defined(RPL_DAG_MC_CONST_USE_LQL)
+ case RPL_DAG_MC_LQL:
+ i++; //reserved flags
+ p_obj->lql->value_and_counter= buffer[i++];
+ PRINTF("RPL: METRICS: DIO had an LQL object\n");
+ break;
+#endif /* defined(RPL_DAG_MC_USE_LQL) || defined(RPL_DAG_MC_CONST_USE_LQL) */
+#if defined(RPL_DAG_MC_USE_ETX) || defined(RPL_DAG_MC_CONST_USE_ETX)
+ case RPL_DAG_MC_ETX:
+ temp16= buffer[i++];
+ temp16= (temp16<<8)+buffer[i++];
+ p_obj->etx->etx= temp16;
+ PRINTF("RPL: METRICS: DIO had an ETX object with value:%u\n",p_obj->etx->etx);
+ break;
+#endif /* defined(RPL_DAG_MC_USE_ETX) || defined(RPL_DAG_MC_CONST_USE_ETX) */
+#if defined(RPL_DAG_MC_USE_LC) || defined(RPL_DAG_MC_CONST_USE_LC)
+ case RPL_DAG_MC_LC:
+ i++; //reserved flags
+ temp16= buffer[i++];
+ temp16= (temp16<<8)+buffer[i++];
+ p_obj->lc->color_and_counter= temp16;
+ PRINTF("RPL: METRICS: DIO had an LC object\n");
+ break;
+#endif /* defined(RPL_DAG_MC_USE_LC) || defined(RPL_DAG_MC_CONST_USE_LC) */
+ }
+ return i;
+
+}
+
+
+/********************************************************************************************/
+
+
+uint8_t
+rpl_metrics_read_from_metric_container (rpl_metric_object_t *obj, uint8_t *buffer)
+{
+
+ uint8_t type, length;
+ uint16_t temp16;
+ uint32_t temp32;
+
+ /* metric container object header */
+ type= obj->type;
+ length= obj->length;
+
+ *buffer++ = type;
+ *buffer++ = obj->flags >> 8;
+ *buffer++ = obj->flags & 0xFF;
+ *buffer++ = length;
+
+ switch (type){
+#if defined(RPL_DAG_MC_USE_NSA) || defined(RPL_DAG_MC_CONST_USE_NSA)
+ case RPL_DAG_MC_NSA:
+ *buffer++= 0; //reserved flags
+ *buffer= obj->nsa->flags;
+ PRINTF("RPL: METRICS: add in the DIO an NSA object with flags:0x%04x\n",obj->nsa->flags);
+ break;
+#endif /*defined(RPL_DAG_MC_USE_NSA) || defined(RPL_DAG_MC_CONST_USE_NSA) */
+#if defined(RPL_DAG_MC_USE_ENERGY) || defined(RPL_DAG_MC_CONST_USE_ENERGY)
+ case RPL_DAG_MC_ENERGY:
+ *buffer++= obj->energy->flags;
+ *buffer= obj->energy->energy_est;
+ PRINTF("RPL: METRICS: add in the DIO an energy object with value:%u\n",obj->energy->energy_est);
+ break;
+#endif /*defined(RPL_DAG_MC_USE_ENERGY) || defined(RPL_DAG_MC_CONST_USE_ENERGY) */
+#if defined(RPL_DAG_MC_USE_HOPCOUNT) || defined(RPL_DAG_MC_CONST_USE_HOPCOUNT)
+ case RPL_DAG_MC_HOPCOUNT:
+ *buffer++= 0; //reserved flags
+ *buffer= obj->hop_count->hop_count;
+ PRINTF("RPL: METRICS: add in the DIO a hop-count object with value:%u\n",obj->hop_count->hop_count);
+ break;
+#endif /*defined(RPL_DAG_MC_USE_HOPCOUNT) || defined(RPL_DAG_MC_CONST_USE_HOPCOUNT) */
+#if defined(RPL_DAG_MC_USE_THROUGHPUT) || defined(RPL_DAG_MC_CONST_USE_THROUGHPUT)
+ case RPL_DAG_MC_THROUGHPUT:
+ temp32= obj->throughput->throughput;
+ *buffer++= READ_FIELD(temp32, 24, 0xFF000000);
+ *buffer++= READ_FIELD(temp32, 16, 0x00FF0000);
+ *buffer++= READ_FIELD(temp32, 8, 0x0000FF00);
+ *buffer= READ_FIELD(temp32, 0, 0x000000FF);
+ PRINTF("RPL: METRICS: add in the DIO a throughput object with value:%lu\n",temp32);
+ break;
+#endif /*defined(RPL_DAG_MC_USE_THROUGHPUT) || defined(RPL_DAG_MC_CONST_USE_THROUGHPUT) */
+#if defined(RPL_DAG_MC_USE_LATENCY) || defined(RPL_DAG_MC_CONST_USE_LATENCY)
+ case RPL_DAG_MC_LATENCY:
+ temp32= obj->latency->latency;
+ *buffer++= READ_FIELD(temp32, 24, 0xFF000000);
+ *buffer++= READ_FIELD(temp32, 16, 0x00FF0000);
+ *buffer++= READ_FIELD(temp32, 8, 0x0000FF00);
+ *buffer= READ_FIELD(temp32, 0, 0x000000FF);
+ PRINTF("RPL: METRICS: add in the DIO a latency object with value:%lu\n",temp32);
+ break;
+#endif /*defined(RPL_DAG_MC_USE_LATENCY) || defined(RPL_DAG_MC_CONST_USE_LATENCY) */
+#if defined(RPL_DAG_MC_USE_LQL) || defined(RPL_DAG_MC_CONST_USE_LQL)
+ case RPL_DAG_MC_LQL:
+ *buffer++= 0; //reserved flags
+ *buffer= obj->lql->value_and_counter;
+ PRINTF("RPL: METRICS: add in the DIO an LQL object\n");
+ break;
+#endif /*defined(RPL_DAG_MC_USE_LQL) || defined(RPL_DAG_MC_CONST_USE_LQL) */
+#if defined(RPL_DAG_MC_USE_ETX) || defined(RPL_DAG_MC_CONST_USE_ETX)
+ case RPL_DAG_MC_ETX:
+ temp16= obj->etx->etx;
+ *buffer++= READ_FIELD(temp16, 8, 0xFF00);
+ *buffer= READ_FIELD(temp16, 0, 0x00FF);
+ PRINTF("RPL: METRICS: add in the DIO an ETX object with value:%u\n",temp16);
+ break;
+#endif /*defined(RPL_DAG_MC_USE_ETX) || defined(RPL_DAG_MC_CONST_USE_ETX) */
+#if defined(RPL_DAG_MC_USE_LC) || defined(RPL_DAG_MC_CONST_USE_LC)
+ case RPL_DAG_MC_LC:
+ *buffer++= 0; //reserved flags
+ temp16= obj->lc->color_and_counter;
+ *buffer++= READ_FIELD(temp16, 8, 0xFF00);
+ *buffer= READ_FIELD(temp16, 0, 0x00FF);
+ PRINTF("RPL: METRICS: add in the DIO an LC object\n");
+ break;
+#endif /*defined(RPL_DAG_MC_USE_LC) || defined(RPL_DAG_MC_CONST_USE_LC) */
+ }
+
+return (length+4); // length object body + header (bytes)
+}
+
+
+/********************************************************************************/
+
+
+uint8_t
+rpl_metrics_array_of_metrics (rpl_metric_container_t *p_mc, rpl_metric_element_t *array_of_metrics)
+{
+
+ uint8_t type;
+ uint16_t flags;
+ uint8_t agg_mode;
+ uint8_t number_of_elem= 0;
+ rpl_metric_object_t *p_obj;
+ rpl_metric_element_t temp_elem;
+ uint8_t precedence[NUMBER_OF_METRICS_AND_CONST_USED];
+ uint8_t i, j, imin;
+
+ for(i=0; i< NUMBER_OF_METRICS_AND_CONST_USED; i++){
+ p_obj= p_mc->metric_and_const_objects[i];
+ flags= p_obj->flags;
+
+ /* if not a constraint */
+ if( !READ_BIT(flags, RPL_DAG_MC_POS_C_BIT)){
+ type= p_obj->type;
+ agg_mode= RPL_METRIC_READ_A_FIELD(flags);
+ precedence[number_of_elem]= RPL_METRIC_READ_PREC_FIELD(flags);
+
+ array_of_metrics[number_of_elem].type= type;
+ array_of_metrics[number_of_elem].aggregation_mode= agg_mode;
+
+ switch (type){
+#ifdef RPL_DAG_MC_USE_NSA
+ case RPL_DAG_MC_NSA:
+ //array_of_metrics[number_of_elem++].data= p_obj->nsa->flags;
+ break;
+#endif /* RPL_DAG_MC_USE_NSA */
+#ifdef RPL_DAG_MC_USE_ENERGY
+ case RPL_DAG_MC_ENERGY:
+ array_of_metrics[number_of_elem++].data= p_obj->energy->energy_est;
+ break;
+#endif /* RPL_DAG_MC_USE_ENERGY */
+#ifdef RPL_DAG_MC_USE_HOPCOUNT
+ case RPL_DAG_MC_HOPCOUNT:
+ array_of_metrics[number_of_elem++].data= (p_obj->hop_count->hop_count) * RPL_DAG_MC_HOPCOUNT_MULTIPLIER;
+ break;
+#endif /* RPL_DAG_MC_USE_HOPCOUNT */
+#ifdef RPL_DAG_MC_USE_THROUGHPUT
+ case RPL_DAG_MC_THROUGHPUT:
+ array_of_metrics[number_of_elem++].data= (p_obj->throughput->throughput)>>RPL_DAG_MC_THROUGHPUT_DIVISOR;
+ break;
+#endif /* RPL_DAG_MC_USE_THROUGHPUT */
+#ifdef RPL_DAG_MC_USE_LATENCY
+ case RPL_DAG_MC_LATENCY:
+ array_of_metrics[number_of_elem++].data= (p_obj->latency->latency)>>RPL_DAG_MC_LATENCY_DIVISOR;
+ break;
+#endif /* RPL_DAG_MC_USE_LATENCY */
+#ifdef RPL_DAG_MC_USE_LQL
+ case RPL_DAG_MC_LQL:
+ //array_of_metrics[number_of_elem++].data= p_obj->lql->value_and_counter;
+ break;
+#endif /* RPL_DAG_MC_USE_LQL */
+#ifdef RPL_DAG_MC_USE_ETX
+ case RPL_DAG_MC_ETX:
+ array_of_metrics[number_of_elem++].data= p_obj->etx->etx;
+ break;
+#endif /* RPL_DAG_MC_USE_ETX */
+#ifdef RPL_DAG_MC_USE_LC
+ case RPL_DAG_MC_LC:
+ //array_of_metrics[number_of_elem++].data= p_obj->lc->color_and_counter;
+ break;
+#endif /* RPL_DAG_MC_USE_LC */
+ }
+ }
+ }
+
+ /* sort by precedence */
+ for (i=0; i< number_of_elem-1; i++){
+ imin= i;
+ for(j=i+1; j< number_of_elem; j++){
+ if(precedence[j] < precedence[imin])
+ imin= j;
+ }
+ temp_elem= array_of_metrics[i];
+ array_of_metrics[i]= array_of_metrics[imin];
+ array_of_metrics[imin]= temp_elem;
+ }
+
+ return number_of_elem;
+}
+
+
+/**********************************************************************************************/
+
+
+uint32_t rpl_metrics_aggregated(uint8_t metric_comb_type, uint32_t parent_metric, uint32_t new_metric)
+{
+
+ switch (metric_comb_type){
+ case RPL_DAG_MC_AGGR_ADDITIVE:
+ return (parent_metric + new_metric);
+ break;
+
+ case RPL_DAG_MC_AGGR_MAXIMUM:
+ return (parent_metric > new_metric ? parent_metric : new_metric);
+ break;
+
+ case RPL_DAG_MC_AGGR_MINIMUM:
+ return (parent_metric < new_metric ? parent_metric : new_metric);
+ break;
+
+ case RPL_DAG_MC_AGGR_MULTIPLICATIVE:
+ return (parent_metric * new_metric);
+ break;
+
+ default:
+ PRINTF("RPL: METRICS: Error aggregation type: %u\n", metric_comb_type);
+ return 0;
+ break;
+ }
+}
+
+
+/**********************************************************************************************/
+
+
+void
+rpl_metrics_update_metric_container(rpl_instance_t *instance)
+{
+
+ rpl_metric_container_t *p_parent_container, *p_instance_container;
+ rpl_metric_object_t *p_obj_parent, *p_obj_instance;
+ uint8_t i, num_constraints,constraints[5];
+ uint8_t type, metric_comb_type;
+ uint16_t flags;
+ uint32_t new_metric, parent_metric;
+ uint8_t copy_const= 0;
+
+
+ if( instance->current_dag->rank == ROOT_RANK(instance) )
+ rpl_metrics_create_root_container(&(instance->mc));
+ else{
+ p_instance_container= &(instance->mc);
+ p_parent_container= &(instance->current_dag->preferred_parent->mc);
+ num_constraints=0;
+
+ for(i=0; i< p_parent_container->metric_and_const_obj; i++){
+ p_obj_instance= p_instance_container->metric_and_const_objects[i];
+ p_obj_parent= p_parent_container->metric_and_const_objects[i];
+
+ flags= p_obj_parent->flags;
+
+ copy_const= 0;
+ /* constraint */
+
+ if( READ_BIT(flags, RPL_DAG_MC_POS_C_BIT) ) {
+ if( !READ_BIT(flags, RPL_DAG_MC_POS_O_BIT)){
+ constraints[num_constraints]= i;
+ num_constraints++;
+ }
+ copy_const=1;
+ }
+
+ metric_comb_type= RPL_METRIC_READ_A_FIELD(flags);
+ type= p_obj_parent->type;
+
+ switch (type){
+#if defined( RPL_DAG_MC_USE_NSA) || defined( RPL_DAG_MC_CONST_USE_NSA)
+ case RPL_DAG_MC_NSA:
+ if(copy_const)
+ p_obj_instance->nsa->flags= p_obj_parent->nsa->flags;
+ else
+ p_obj_instance->nsa->flags= rpl_metrics_get_NSA();
+ break;
+#endif /*defined( RPL_DAG_MC_USE_NSA) || defined( RPL_DAG_MC_CONST_USE_NSA)*/
+
+#if defined( RPL_DAG_MC_USE_ENERGY) || defined( RPL_DAG_MC_CONST_USE_ENERGY)
+ case RPL_DAG_MC_ENERGY:
+ p_obj_instance->energy->flags= p_obj_parent->energy->flags;
+ if(copy_const)
+ p_obj_instance->energy->energy_est= p_obj_parent->energy->energy_est;
+ else{
+ new_metric= rpl_metrics_get_energy();
+ parent_metric= (uint32_t)p_obj_parent->energy->energy_est;
+ new_metric= rpl_metrics_aggregated(metric_comb_type, parent_metric, new_metric);
+ p_obj_instance->energy->energy_est= (new_metric>255?255:new_metric);
+ }
+ break;
+#endif /*defined( RPL_DAG_MC_USE_ENERGY) || defined( RPL_DAG_MC_CONST_USE_ENERGY)*/
+
+#if defined( RPL_DAG_MC_USE_HOPCOUNT) || defined( RPL_DAG_MC_CONST_USE_HOPCOUNT)
+ case RPL_DAG_MC_HOPCOUNT:
+ p_obj_instance->hop_count->hop_count= p_obj_parent->hop_count->hop_count;
+ if(!copy_const)
+ (p_obj_instance->hop_count->hop_count)++;
+ break;
+#endif /*defined( RPL_DAG_MC_USE_HOPCOUNT) || defined( RPL_DAG_MC_CONST_USE_HOPCOUNT)*/
+
+#if defined( RPL_DAG_MC_USE_THROUGHPUT) || defined( RPL_DAG_MC_CONST_USE_THROUGHPUT)
+ case RPL_DAG_MC_THROUGHPUT:
+ if(copy_const)
+ new_metric= p_obj_parent->throughput->throughput;
+ else{
+ new_metric= rpl_metrics_get_throughput();
+ parent_metric= p_obj_parent->throughput->throughput;
+ new_metric= rpl_metrics_aggregated(metric_comb_type, parent_metric, new_metric);
+ }
+ p_obj_instance->throughput->throughput= new_metric;
+ break;
+#endif /*defined( RPL_DAG_MC_USE_THROUGHPUT) || defined( RPL_DAG_MC_CONST_USE_THROUGHPUT)*/2
+#if defined( RPL_DAG_MC_USE_LATENCY) || defined( RPL_DAG_MC_CONST_USE_LATENCY)
+ case RPL_DAG_MC_LATENCY:
+ if(copy_const)
+ new_metric= p_obj_parent->latency->latency;
+ else{
+ new_metric= rpl_metrics_get_latency();
+ parent_metric= p_obj_parent->latency->latency;
+ new_metric= rpl_metrics_aggregated(metric_comb_type, parent_metric, new_metric);
+ }
+ p_obj_instance->latency->latency= new_metric;
+ break;
+#endif /*defined( RPL_DAG_MC_USE_LATENCY) || defined( RPL_DAG_MC_CONST_USE_LATENCY)*/
+
+#if defined( RPL_DAG_MC_USE_LQL) || defined( RPL_DAG_MC_CONST_USE_LQL)
+ case RPL_DAG_MC_LQL:
+ if(copy_const)
+ p_obj_instance->lql->value_and_counter=p_obj_parent->lql->value_and_counter;
+ else
+ p_obj_instance->lql->value_and_counter= rpl_metrics_get_LQL();
+ break;
+#endif /*defined( RPL_DAG_MC_USE_LQL) || defined( RPL_DAG_MC_CONST_USE_LQL)*/
+
+#if defined( RPL_DAG_MC_USE_ETX) || defined( RPL_DAG_MC_CONST_USE_ETX)
+ case RPL_DAG_MC_ETX:
+ if(copy_const)
+ new_metric= p_obj_parent->etx->etx;
+ else{
+ new_metric= rpl_metrics_get_ETX();
+ parent_metric= p_obj_parent->etx->etx;
+ new_metric= rpl_metrics_aggregated(metric_comb_type, parent_metric, new_metric);
+ }
+ p_obj_instance->etx->etx= new_metric;
+ break;
+#endif /*defined( RPL_DAG_MC_USE_ETX) || defined( RPL_DAG_MC_CONST_USE_ETX)*/
+
+#if defined( RPL_DAG_MC_USE_LC) || defined( RPL_DAG_MC_CONST_USE_LC)
+ case RPL_DAG_MC_LC:
+ if(copy_const)
+ p_obj_instance->lc->color_and_counter=p_obj_parent->lc->color_and_counter;
+ else
+ p_obj_instance->lc->color_and_counter= rpl_metrics_get_LC();
+ break;
+#endif /*defined( RPL_DAG_MC_USE_LC) || defined( RPL_DAG_MC_CONST_USE_LC)*/
+ }
+ }
+
+ /*check mandatory constraints*/
+ for(i=0; imetric_and_const_objects[constraints[i]];
+ flags= p_obj_instance->flags;
+
+ if(!rpl_metrics_satisfies_constraint(p_obj_instance, p_instance_container)){
+ PRINTF("RPL: METRICS: does not satisfy a mandatory constraint and become a leaf node\n");
+ if(!rpl_leaf){
+ rpl_leaf= 1;
+ leaf_dio= 1;
+ }
+ return;
+ }
+ }
+ }
+}
+
+
+/************************************************************************************************/
+
+
+uint8_t
+rpl_metrics_satisfies_constraint(rpl_metric_object_t *p_obj_const, rpl_metric_container_t *p_instance_container)
+{
+ uint8_t return_value;
+ uint8_t i, type, metric_found, num_objects;
+ uint8_t temp_8;
+ uint16_t temp_16_const,temp_16_inst, flags;
+ uint8_t energy_type,bit_I;
+ rpl_metric_object_t *p_obj_inst;
+
+ metric_found= 0;
+ type= p_obj_const->type;
+ num_objects= p_instance_container->metric_and_const_obj;
+
+ for(i=0; (imetric_and_const_objects[i];
+ if(p_obj_inst->type == type){
+ flags= p_obj_inst->flags;
+ if( !READ_BIT(flags, RPL_DAG_MC_POS_C_BIT) )
+ metric_found++;
+ }
+ }
+
+ return_value= 1;
+ if(metric_found){
+ switch (type){
+
+#ifdef RPL_DAG_MC_CONST_USE_NSA
+ case RPL_DAG_MC_NSA:
+ if( ! ((p_obj_const->nsa->flags) & RPL_DAG_MC_NSA_OVERLOAD_BIT))
+ if( (p_obj_inst->nsa->flags) & RPL_DAG_MC_NSA_OVERLOAD_BIT)
+ return_value= 0;
+
+ if((p_obj_const->nsa->flags) & RPL_DAG_MC_NSA_AGGREGATION_BIT)
+ if( ! ((p_obj_inst->nsa->flags) & RPL_DAG_MC_NSA_AGGREGATION_BIT))
+ return_value= 0;
+ break;
+#endif /* RPL_DAG_MC_CONST_USE_NSA */
+#ifdef RPL_DAG_MC_CONST_USE_ENERGY
+ case RPL_DAG_MC_ENERGY:
+
+ bit_I= ((p_obj_const->energy->flags) >> 3) & 0x1;
+ energy_type= ((p_obj_const->energy->flags) >> 1) & 0x3;
+
+ if(bit_I){
+ if(energy_type< RPL_DAG_MC_ENERGY_TYPE_MYSELF)
+ return_value = 0;
+ }
+ else{
+ if(energy_type<= RPL_DAG_MC_ENERGY_TYPE_MYSELF)
+ return_value = 0;
+ }
+ if(p_obj_inst->energy->energy_est > p_obj_const->energy->energy_est)
+ return_value = 0;
+ break;
+#endif /* RPL_DAG_MC_CONST_USE_ENERGY */
+#ifdef RPL_DAG_MC_CONST_USE_HOPCOUNT
+ case RPL_DAG_MC_HOPCOUNT:
+ if(p_obj_const->hop_count->hop_count < p_obj_inst->hop_count->hop_count)
+ return_value= 0;
+ break;
+#endif /* RPL_DAG_MC_CONST_USE_HOPCOUNT */
+#ifdef RPL_DAG_MC_CONST_USE_THROUGHPUT
+ case RPL_DAG_MC_THROUGHPUT:
+ if(p_obj_const->throughput->throughput > p_obj_inst->throughput->throughput)
+ return_value= 0;
+ break;
+#endif /* RPL_DAG_MC_CONST_USE_THROUGHPUT */
+#ifdef RPL_DAG_MC_CONST_USE_LATENCY
+ case RPL_DAG_MC_LATENCY:
+ if(p_obj_const->latency->latency < p_obj_inst->latency->latency)
+ return_value= 0;
+ break;
+#endif /* RPL_DAG_MC_CONST_USE_LATENCY */
+#ifdef RPL_DAG_MC_CONST_USE_LQL
+ case RPL_DAG_MC_LQL:
+ temp_8= (p_obj_const->lql->value_and_counter >> 5) & 0x07;
+ if(temp_8 < ((p_obj_inst->lql->value_and_counter >> 5) & 0x07))
+ return_value= 0;
+ break;
+#endif /* RPL_DAG_MC_CONST_USE_LQL */
+#ifdef RPL_DAG_MC_CONST_USE_ETX
+ case RPL_DAG_MC_ETX:
+ if(p_obj_const->etx->etx < p_obj_inst->etx->etx);
+ return_value= 0;
+ break;
+#endif /* RPL_DAG_MC_CONST_USE_ETX */
+#ifdef RPL_DAG_MC_CONST_USE_LC
+ case RPL_DAG_MC_LC:
+ /* If 'I'=1, 1's of constraint and instance must be equal */
+ /* If 'I'=0, 0's of constraint and instance must be equal */
+ temp_16_const= (p_obj_const->lc->color_and_counter >> 6) & 0x3FF;;
+ temp_16_inst= (p_obj_inst->lc->color_and_counter >> 6) & 0x3FF;;
+ if( ! (p_obj_const->lc->color_and_counter & 0x1)){
+ temp_16_const= (~temp_16_const) & 0x3FF;;
+ temp_16_inst= (~temp_16_inst) & 0x3FF;;
+ }
+ if(temp_16_const != (temp_16_const & temp_16_inst))
+ return_value= 0;
+ break;
+#endif /* RPL_DAG_MC_CONST_USE_LC */
+ }
+ }
+ else
+ PRINTF("RPL: METRICS: not found a metric for a constraint of type %u\n",type);
+
+ return return_value;
+}
diff --git a/examples/containers/rpl-metrics.h b/examples/containers/rpl-metrics.h
new file mode 100644
index 00000000000..d7744481a08
--- /dev/null
+++ b/examples/containers/rpl-metrics.h
@@ -0,0 +1,32 @@
+#ifndef RPL_METRICS_H
+#define RPL_METRICS_H
+
+#include "net/rpl/rpl.h"
+#include "rpl-metrics-data.h"
+
+
+#define READ_BIT(flags, pos) ((((flags) & (1<> pos)
+
+#define RPL_METRIC_READ_A_FIELD(flags) READ_FIELD((flags), RPL_DAG_MC_POS_A_FIELD, 0x70)
+#define RPL_METRIC_READ_PREC_FIELD(flags) ((flags) & 0xF)
+#define RPL_METRIC_WRITE_A_FIELD(flags,val) ((flags)= (((flags) & 0xFF8F) | (val<<4)))
+#define RPL_METRIC_WRITE_PREC_FIELD(flags,val) ((flags)= (((flags) & 0xFFF0) | val))
+
+#define RPL_METRIC_OBJECT_HEADER_TYPE(header) READ_FIELD(header,24,0xFF000000)
+#define RPL_METRIC_OBJECT_HEADER_FLAGS(header) READ_FIELD(header,8,0x00FFFF00)
+#define RPL_METRIC_OBJECT_HEADER_LENGTH(header) READ_FIELD(header,0,0x000000FF)
+
+uint8_t rpl_metrics_create_object (rpl_metric_container_t *p_mc, uint8_t type, uint8_t pos_obj);
+uint8_t rpl_metrics_create_root_container(rpl_metric_container_t *mc);
+uint8_t rpl_metrics_copy_mc (rpl_metric_container_t *p_mc_dest, rpl_metric_container_t *p_mc_orig);
+uint8_t rpl_metrics_write_object_to_metric_container (rpl_metric_container_t *mc, uint8_t *buffer, uint8_t obj_cont);
+uint8_t rpl_metrics_read_from_metric_container (rpl_metric_object_t *obj, uint8_t *buffer);
+uint8_t rpl_metrics_array_of_metrics (rpl_metric_container_t *p_mc, rpl_metric_element_t *array_of_metrics);
+uint32_t rpl_metrics_aggregated(uint8_t metric_comb_type, uint32_t parent_metric, uint32_t new_metric);
+void rpl_metrics_update_metric_container(rpl_instance_t *instance);
+uint8_t rpl_metrics_satisfies_constraint(rpl_metric_object_t *p_obj, rpl_metric_container_t *p_instance_container);
+
+#endif /* RPL_METRICS_H */
+
diff --git a/examples/containers/server.c b/examples/containers/server.c
new file mode 100644
index 00000000000..1c55b8d3119
--- /dev/null
+++ b/examples/containers/server.c
@@ -0,0 +1,193 @@
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ *
+ */
+
+#include "contiki.h"
+#include "contiki-lib.h"
+#include "contiki-net.h"
+#include "net/uip.h"
+#include "net/rpl/rpl.h"
+#include "net/rime/rimeaddr.h"
+
+#include "net/netstack.h"
+#include "dev/button-sensor.h"
+#include "dev/serial-line.h"
+#if CONTIKI_TARGET_Z1
+#include "dev/uart0.h"
+#else
+#include "dev/uart1.h"
+#endif
+#include
+#include
+#include
+#include
+#include "collect-common.h"
+#include "collect-view.h"
+
+
+#define DEBUG DEBUG_NONE
+#include "net/uip-debug.h"
+
+#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
+
+#define UDP_CLIENT_PORT 8775
+#define UDP_SERVER_PORT 5688
+
+static struct uip_udp_conn *server_conn;
+
+PROCESS(udp_server_process, "UDP server process");
+AUTOSTART_PROCESSES(&udp_server_process,&collect_common_process);
+/*---------------------------------------------------------------------------*/
+void
+collect_common_set_sink(void)
+{
+}
+/*---------------------------------------------------------------------------*/
+void
+collect_common_net_print(void)
+{
+ printf("I am sink!\n");
+}
+/*---------------------------------------------------------------------------*/
+void
+collect_common_send(void)
+{
+ /* Server never sends */
+}
+/*---------------------------------------------------------------------------*/
+void
+collect_common_net_init(void)
+{
+#if CONTIKI_TARGET_Z1
+ uart0_set_input(serial_line_input_byte);
+#else
+ uart1_set_input(serial_line_input_byte);
+#endif
+ serial_line_init();
+
+ PRINTF("I am sink!\n");
+}
+/*---------------------------------------------------------------------------*/
+static void
+tcpip_handler(void)
+{
+ uint8_t *appdata;
+ rimeaddr_t sender;
+ uint8_t seqno;
+ uint8_t hops;
+
+ if(uip_newdata()) {
+ appdata = (uint8_t *)uip_appdata;
+ sender.u8[0] = UIP_IP_BUF->srcipaddr.u8[15];
+ sender.u8[1] = UIP_IP_BUF->srcipaddr.u8[14];
+ seqno = *appdata;
+ hops = uip_ds6_if.cur_hop_limit - UIP_IP_BUF->ttl + 1;
+ collect_common_recv(&sender, seqno, hops,
+ appdata + 2, uip_datalen() - 2);
+ }
+}
+/*---------------------------------------------------------------------------*/
+static void
+print_local_addresses(void)
+{
+ int i;
+ uint8_t state;
+
+ PRINTF("Server IPv6 addresses: ");
+ for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
+ state = uip_ds6_if.addr_list[i].state;
+ if(state == ADDR_TENTATIVE || state == ADDR_PREFERRED) {
+ PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr);
+ PRINTF("\n");
+ /* hack to make address "final" */
+ if (state == ADDR_TENTATIVE) {
+ uip_ds6_if.addr_list[i].state = ADDR_PREFERRED;
+ }
+ }
+ }
+}
+/*---------------------------------------------------------------------------*/
+PROCESS_THREAD(udp_server_process, ev, data)
+{
+ uip_ipaddr_t ipaddr;
+ struct uip_ds6_addr *root_if;
+
+ PROCESS_BEGIN();
+
+ PROCESS_PAUSE();
+
+ SENSORS_ACTIVATE(button_sensor);
+
+ PRINTF("UDP server started\n");
+
+#if UIP_CONF_ROUTER
+ uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 1);
+
+
+ /* uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); */
+ uip_ds6_addr_add(&ipaddr, 0, ADDR_MANUAL);
+ root_if = uip_ds6_addr_lookup(&ipaddr);
+ if(root_if != NULL) {
+ rpl_dag_t *dag;
+ dag = rpl_set_root(RPL_DEFAULT_INSTANCE,(uip_ip6addr_t *)&ipaddr);
+ uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0);
+ //rpl_set_prefix(dag, &ipaddr, 64);
+ PRINTF("created a new RPL dag\n");
+ } else {
+ PRINTF("failed to create a new RPL DAG\n");
+ }
+#endif /* UIP_CONF_ROUTER */
+
+ print_local_addresses();
+
+ /* The data sink runs with a 100% duty cycle in order to ensure high
+ packet reception rates. */
+ NETSTACK_RDC.off(1);
+
+ server_conn = udp_new(NULL, UIP_HTONS(UDP_CLIENT_PORT), NULL);
+ udp_bind(server_conn, UIP_HTONS(UDP_SERVER_PORT));
+
+ PRINTF("Created a server connection with remote address ");
+ PRINT6ADDR(&server_conn->ripaddr);
+ PRINTF(" local/remote port %u/%u\n", UIP_HTONS(server_conn->lport),
+ UIP_HTONS(server_conn->rport));
+
+ while(1) {
+ PROCESS_YIELD();
+
+ if(ev == tcpip_event) {
+ tcpip_handler();
+ } else if (ev == sensors_event && data == &button_sensor) {
+ PRINTF("Initiating global repair\n");
+ rpl_repair_root(RPL_DEFAULT_INSTANCE);
+ }
+ }
+
+ PROCESS_END();
+}
+/*---------------------------------------------------------------------------*/
diff --git a/examples/containers/simul-13-nodos.csc b/examples/containers/simul-13-nodos.csc
new file mode 100644
index 00000000000..bdc908e364c
--- /dev/null
+++ b/examples/containers/simul-13-nodos.csc
@@ -0,0 +1,309 @@
+
+
+ [APPS_DIR]/mrm
+ [APPS_DIR]/mspsim
+ [APPS_DIR]/avrora
+ [APPS_DIR]/serial_socket
+ [APPS_DIR]/collect-view
+ [APPS_DIR]/powertracker
+
+ My simulation
+ 123456
+ 100000
+
+ se.sics.cooja.radiomediums.UDGM
+ 20.0
+ 25.0
+ 1.0
+ 1.0
+
+
+ 40000
+
+
+ se.sics.cooja.mspmote.Z1MoteType
+ z11
+ server
+ [CONFIG_DIR]/server.z1
+ se.sics.cooja.interfaces.Position
+ se.sics.cooja.interfaces.RimeAddress
+ se.sics.cooja.interfaces.IPAddress
+ se.sics.cooja.interfaces.Mote2MoteRelations
+ se.sics.cooja.interfaces.MoteAttributes
+ se.sics.cooja.mspmote.interfaces.MspClock
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ se.sics.cooja.mspmote.interfaces.MspButton
+ se.sics.cooja.mspmote.interfaces.Msp802154Radio
+ se.sics.cooja.mspmote.interfaces.MspDefaultSerial
+ se.sics.cooja.mspmote.interfaces.MspLED
+ se.sics.cooja.mspmote.interfaces.MspDebugOutput
+
+
+ se.sics.cooja.mspmote.Z1MoteType
+ z12
+ client
+ [CONFIG_DIR]/client.z1
+ se.sics.cooja.interfaces.Position
+ se.sics.cooja.interfaces.RimeAddress
+ se.sics.cooja.interfaces.IPAddress
+ se.sics.cooja.interfaces.Mote2MoteRelations
+ se.sics.cooja.interfaces.MoteAttributes
+ se.sics.cooja.mspmote.interfaces.MspClock
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ se.sics.cooja.mspmote.interfaces.MspButton
+ se.sics.cooja.mspmote.interfaces.Msp802154Radio
+ se.sics.cooja.mspmote.interfaces.MspDefaultSerial
+ se.sics.cooja.mspmote.interfaces.MspLED
+ se.sics.cooja.mspmote.interfaces.MspDebugOutput
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 54.335467383479994
+ 4.747565694681829
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 1
+
+ z11
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 63.06567445836441
+ 17.713731231936247
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 2
+
+
+ se.sics.cooja.mspmote.interfaces.MspDefaultSerial
+ net~;
+
+ z12
+
+
+
+
+ false
+ [CONFIG_DIR]/../../core/net/rpl/rpl-mrhof.c
+ 168
+ printf("Rank: %u, Rank pad: %u, link met: %u\n", new_rank,p->rank, p->link_metric/ RPL_DAG_MC_ETX_DIVISOR);
+ -16777216
+
+
+ false
+ [CONFIG_DIR]/../../core/net/rpl/rpl-mrhof.c
+ 146
+ if(p == NULL) {
+ -16777216
+
+
+
+ se.sics.cooja.interfaces.Position
+ 53.40562284295976
+ 19.00518198265879
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 3
+
+ z12
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 43.43562304738165
+ 15.905700180924677
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 4
+
+ z12
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 42.14417229665909
+ 29.595078138583713
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 5
+
+ z12
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 58.933032056052255
+ 31.919689489884306
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 6
+
+ z12
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 71.37342580791453
+ 29.714458961784565
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 7
+
+ z12
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 41.816206872869124
+ 39.25897757622631
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 8
+
+
+ se.sics.cooja.mspmote.interfaces.MspDefaultSerial
+ net~;
+
+ z12
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 53.82382706523132
+ 39.25897757622631
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 9
+
+ z12
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 63.98412107415318
+ 41.106303759666645
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 10
+
+ z12
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 58.44214252383217
+ 46.648282309987664
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 11
+
+ z12
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 52.59227627627109
+ 53.11392395202884
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 12
+
+ z12
+
+
+
+
+ se.sics.cooja.interfaces.Position
+ 68.76097629590274
+ 34.65624934371747
+ 0.0
+
+
+ se.sics.cooja.mspmote.interfaces.MspMoteID
+ 13
+
+ z12
+
+
+
+ se.sics.cooja.plugins.SimControl
+ 280
+ 0
+ 160
+ 184
+ -15
+
+
+ se.sics.cooja.plugins.Visualizer
+
+ true
+ se.sics.cooja.plugins.skins.IDVisualizerSkin
+ 6.503393389095488 0.0 0.0 6.503393389095488 -258.05835444517754 -19.148014625817627
+
+ 231
+ 3
+ 400
+ 1
+ 1
+
+
+ se.sics.cooja.plugins.LogListener
+
+ ID:12
+
+
+
+ 658
+ 1
+ 458
+ 236
+ 71
+
+
+ se.sics.cooja.plugins.collectview.CollectView
+ 0
+ 233
+ 2
+ 72
+ 585
+ 7
+
+
+
From cec3bd84efcee5d43d3e8d3009aa283d1b5c43f9 Mon Sep 17 00:00:00 2001
From: weld10 <50168266+Amrican10@users.noreply.github.com>
Date: Mon, 27 Jul 2020 22:13:32 +0200
Subject: [PATCH 03/19] Delete text
---
examples/containers/text | 1 -
1 file changed, 1 deletion(-)
delete mode 100644 examples/containers/text
diff --git a/examples/containers/text b/examples/containers/text
deleted file mode 100644
index 73505ed440d..00000000000
--- a/examples/containers/text
+++ /dev/null
@@ -1 +0,0 @@
-h1
From 883944ab3e1daa3eeed4720e2b78b91791cd9a94 Mon Sep 17 00:00:00 2001
From: weld10 <50168266+Amrican10@users.noreply.github.com>
Date: Mon, 27 Jul 2020 22:47:45 +0200
Subject: [PATCH 04/19] Update rpl-of0.c
---
core/net/rpl/rpl-of0.c | 167 ++++++++++++++++++++++++-----------------
1 file changed, 97 insertions(+), 70 deletions(-)
diff --git a/core/net/rpl/rpl-of0.c b/core/net/rpl/rpl-of0.c
index d0bfd1296fa..a35d12fc9d3 100755
--- a/core/net/rpl/rpl-of0.c
+++ b/core/net/rpl/rpl-of0.c
@@ -50,6 +50,29 @@
#define DEBUG DEBUG_NONE
#include "net/ip/uip-debug.h"
+static void reset(rpl_dag_t *);
+ static rpl_parent_t *best_parent(rpl_parent_t *, rpl_parent_t *);
+ static rpl_dag_t *best_dag(rpl_dag_t *, rpl_dag_t *);
+ static rpl_rank_t calculate_rank(rpl_parent_t *, rpl_rank_t);
+ static void update_metric_container(rpl_instance_t *);
+
+
+ rpl_of_t rpl_of0 = {
+ reset,
+ NULL,
+ best_parent,
+ best_dag,
+ calculate_rank,
+ update_metric_container,
+ 0
+ };
+
+ #define DEFAULT_RANK_INCREMENT RPL_MIN_HOPRANKINC
+
+
+
+ #define MIN_DIFFERENCE (RPL_MIN_HOPRANKINC + RPL_MIN_HOPRANKINC / 2)
+
/* Constants from RFC6552. We use the default values. */
#define RANK_STRETCH 0 /* Must be in the range [0;5] */
#define RANK_FACTOR 1 /* Must be in the range [1;4] */
@@ -161,78 +184,82 @@ parent_has_usable_link(rpl_parent_t *p)
return parent_is_acceptable(p);
}
/*---------------------------------------------------------------------------*/
-static rpl_parent_t *
-best_parent(rpl_parent_t *p1, rpl_parent_t *p2)
-{
- rpl_dag_t *dag;
- uint16_t p1_cost;
- uint16_t p2_cost;
- int p1_is_acceptable;
- int p2_is_acceptable;
-
- p1_is_acceptable = p1 != NULL && parent_is_acceptable(p1);
- p2_is_acceptable = p2 != NULL && parent_is_acceptable(p2);
-
- if(!p1_is_acceptable) {
- return p2_is_acceptable ? p2 : NULL;
- }
- if(!p2_is_acceptable) {
- return p1_is_acceptable ? p1 : NULL;
- }
-
- dag = p1->dag; /* Both parents are in the same DAG. */
- p1_cost = parent_path_cost(p1);
- p2_cost = parent_path_cost(p2);
-
- /* Paths costs coarse-grained (multiple of min_hoprankinc), we operate without hysteresis */
- if(p1_cost != p2_cost) {
- /* Pick parent with lowest path cost */
- return p1_cost < p2_cost ? p1 : p2;
- } else {
- /* We have a tie! */
- /* Stik to current preferred parent if possible */
- if(p1 == dag->preferred_parent || p2 == dag->preferred_parent) {
- return dag->preferred_parent;
- }
- /* None of the nodes is the current preferred parent,
- * choose parent with best link metric */
- return parent_link_metric(p1) < parent_link_metric(p2) ? p1 : p2;
- }
-}
+ static rpl_parent_t *
+ best_parent(rpl_parent_t *p1, rpl_parent_t *p2)
+ {
+ rpl_rank_t r1, r2;
+ rpl_dag_t *dag;
+
+ PRINTF("RPL: Comparing parent ");
+ PRINT6ADDR(rpl_get_parent_ipaddr(p1));
+ PRINTF(" (confidence %d, rank %d) with parent ",
+ p1->link_metric, p1->rank);
+ PRINT6ADDR(rpl_get_parent_ipaddr(p2));
+ PRINTF(" (confidence %d, rank %d)\n",
+ p2->link_metric, p2->rank);
+
+
+
+
+ r1 = DAG_RANK(p1->rank, p1->dag->instance) * RPL_MIN_HOPRANKINC +
+ p1->link_metric;
+ r2 = DAG_RANK(p2->rank, p1->dag->instance) * RPL_MIN_HOPRANKINC +
+ p2->link_metric;
+ /* Compare two parents by looking both and their rank and at the ETX
+ for that parent. We choose the parent that has the most
+ favourable combination. */
+
+
+
+
+ dag = (rpl_dag_t *)p1->dag; /* Both parents must be in the same DAG. */
+ if(r1 < r2 + MIN_DIFFERENCE &&
+ r1 > r2 - MIN_DIFFERENCE) {
+ return dag->preferred_parent;
+ } else if(r1 < r2) {
+ return p1;
+ } else {
+ return p2;
+
+
+
+
+
+
+
+ }
+ }
/*---------------------------------------------------------------------------*/
-static rpl_dag_t *
-best_dag(rpl_dag_t *d1, rpl_dag_t *d2)
-{
- if(d1->grounded != d2->grounded) {
- return d1->grounded ? d1 : d2;
- }
+ static rpl_dag_t *
+ best_dag(rpl_dag_t *d1, rpl_dag_t *d2)
+
+ {
+ if(d1->grounded) {
+ if (!d2->grounded) {
+ return d1;
+ }
+ } else if(d2->grounded) {
+ return d2;
- if(d1->preference != d2->preference) {
- return d1->preference > d2->preference ? d1 : d2;
- }
+ }
+
+ if(d1->preference < d2->preference) {
+ return d2;
+ } else {
+ if(d1->preference > d2->preference) {
+ return d1;
+ }
+
+
+ }
+
+ if(d2->rank < d1->rank) {
+ return d2;
+
+ } else {
+ return d1;
+ }
+ }
- return d1->rank < d2->rank ? d1 : d2;
-}
-/*---------------------------------------------------------------------------*/
-static void
-update_metric_container(rpl_instance_t *instance)
-{
- instance->mc.type = RPL_DAG_MC_NONE;
-}
-/*---------------------------------------------------------------------------*/
-rpl_of_t rpl_of0 = {
- reset,
-#if RPL_WITH_DAO_ACK
- dao_ack_callback,
-#endif
- parent_link_metric,
- parent_has_usable_link,
- parent_path_cost,
- rank_via_parent,
- best_parent,
- best_dag,
- update_metric_container,
- RPL_OCP_OF0
-};
/** @}*/
From 5f8c1a4c7c8a4bc39d9615a5b37a80c911cab71f Mon Sep 17 00:00:00 2001
From: weld10 <50168266+Amrican10@users.noreply.github.com>
Date: Mon, 27 Jul 2020 22:57:16 +0200
Subject: [PATCH 05/19] Update rpl-mrhof.c
---
core/net/rpl/rpl-mrhof.c | 374 +++++++++++++++++----------------------
1 file changed, 162 insertions(+), 212 deletions(-)
diff --git a/core/net/rpl/rpl-mrhof.c b/core/net/rpl/rpl-mrhof.c
index c51ac869422..8154c5b62a1 100755
--- a/core/net/rpl/rpl-mrhof.c
+++ b/core/net/rpl/rpl-mrhof.c
@@ -1,3 +1,7 @@
+/**
+ * \addtogroup uip6
+ * @{
+ */
/*
* Copyright (c) 2010, Swedish Institute of Computer Science.
* All rights reserved.
@@ -29,288 +33,234 @@
* This file is part of the Contiki operating system.
*
*/
-
/**
* \file
- * The Minimum Rank with Hysteresis Objective Function (MRHOF), RFC6719
+ * The Minimum Rank with Hysteresis Objective Function (MRHOF)
*
- * This implementation uses the estimated number of
+ * This implementation uses the estimated number of
* transmissions (ETX) as the additive routing metric,
* and also provides stubs for the energy metric.
*
* \author Joakim Eriksson , Nicolas Tsiftes
*/
-/**
- * \addtogroup uip6
- * @{
- */
-
-#include "net/rpl/rpl.h"
#include "net/rpl/rpl-private.h"
#include "net/nbr-table.h"
-#include "net/link-stats.h"
#define DEBUG DEBUG_NONE
-#include "net/ip/uip-debug.h"
-
-/* RFC6551 and RFC6719 do not mandate the use of a specific formula to
- * compute the ETX value. This MRHOF implementation relies on the value
- * computed by the link-stats module. It has an optional feature,
- * RPL_MRHOF_CONF_SQUARED_ETX, that consists in squaring this value.
- * This basically penalizes bad links while preserving the semantics of ETX
- * (1 = perfect link, more = worse link). As a result, MRHOF will favor
- * good links over short paths. Recommended when reliability is a priority.
- * Without this feature, a hop with 50% PRR (ETX=2) is equivalent to two
- * perfect hops with 100% PRR (ETX=1+1=2). With this feature, the former
- * path obtains ETX=2*2=4 and the former ETX=1*1+1*1=2. */
-#ifdef RPL_MRHOF_CONF_SQUARED_ETX
-#define RPL_MRHOF_SQUARED_ETX RPL_MRHOF_CONF_SQUARED_ETX
-#else /* RPL_MRHOF_CONF_SQUARED_ETX */
-#define RPL_MRHOF_SQUARED_ETX 0
-#endif /* RPL_MRHOF_CONF_SQUARED_ETX */
-
-#if !RPL_MRHOF_SQUARED_ETX
-/* Configuration parameters of RFC6719. Reject parents that have a higher
- * link metric than the following. The default value is 512 but we use 1024. */
-#define MAX_LINK_METRIC 1024 /* Eq ETX of 8 */
-/* Hysteresis of MRHOF: the rank must differ more than PARENT_SWITCH_THRESHOLD_DIV
- * in order to switch preferred parent. Default in RFC6719: 192, eq ETX of 1.5.
- * We use a more aggressive setting: 96, eq ETX of 0.75.
- */
-#define PARENT_SWITCH_THRESHOLD 96 /* Eq ETX of 0.75 */
-#else /* !RPL_MRHOF_SQUARED_ETX */
-#define MAX_LINK_METRIC 2048 /* Eq ETX of 4 */
-#define PARENT_SWITCH_THRESHOLD 160 /* Eq ETX of 1.25 (results in a churn comparable
-to the threshold of 96 in the non-squared case) */
-#endif /* !RPL_MRHOF_SQUARED_ETX */
+#include "net/uip-debug.h"
+
+static void reset(rpl_dag_t *);
+static void neighbor_link_callback(rpl_parent_t *, int, int);
+static rpl_parent_t *best_parent(rpl_parent_t *, rpl_parent_t *);
+static rpl_dag_t *best_dag(rpl_dag_t *, rpl_dag_t *);
+static rpl_rank_t calculate_rank(rpl_parent_t *, rpl_rank_t);
+static void update_metric_container(rpl_instance_t *);
+
+rpl_of_t rpl_mrhof = {
+ reset,
+ neighbor_link_callback,
+ best_parent,
+ best_dag,
+ calculate_rank,
+ update_metric_container,
+ 1
+};
+
+/* Constants for the ETX moving average */
+#define ETX_SCALE 100
+#define ETX_ALPHA 90
+
+/* Reject parents that have a higher link metric than the following. */
+#define MAX_LINK_METRIC 10
/* Reject parents that have a higher path cost than the following. */
-#define MAX_PATH_COST 32768 /* Eq path ETX of 256 */
+#define MAX_PATH_COST 100
-/*---------------------------------------------------------------------------*/
-static void
-reset(rpl_dag_t *dag)
+/*
+ * The rank must differ more than 1/PARENT_SWITCH_THRESHOLD_DIV in order
+ * to switch preferred parent.
+ */
+#define PARENT_SWITCH_THRESHOLD_DIV 2
+
+typedef uint16_t rpl_path_metric_t;
+
+static rpl_path_metric_t
+calculate_path_metric(rpl_parent_t *p)
{
- PRINTF("RPL: Reset MRHOF\n");
+ if(p == NULL) {
+ return MAX_PATH_COST * RPL_DAG_MC_ETX_DIVISOR;
+ }
+
+#if RPL_DAG_MC == RPL_DAG_MC_NONE
+ return p->rank + (uint16_t)p->link_metric;
+#elif RPL_DAG_MC == RPL_DAG_MC_ETX
+ return p->mc.obj.etx + (uint16_t)p->link_metric;
+#elif RPL_DAG_MC == RPL_DAG_MC_ENERGY
+ return p->mc.obj.energy.energy_est + (uint16_t)p->link_metric;
+#else
+#error "Unsupported RPL_DAG_MC configured. See rpl.h."
+#endif /* RPL_DAG_MC */
}
-/*---------------------------------------------------------------------------*/
-#if RPL_WITH_DAO_ACK
+
static void
-dao_ack_callback(rpl_parent_t *p, int status)
+reset(rpl_dag_t *sag)
{
- if(status == RPL_DAO_ACK_UNABLE_TO_ADD_ROUTE_AT_ROOT) {
- return;
- }
- /* here we need to handle failed DAO's and other stuff */
- PRINTF("RPL: MRHOF - DAO ACK received with status: %d\n", status);
- if(status >= RPL_DAO_ACK_UNABLE_TO_ACCEPT) {
- /* punish the ETX as if this was 10 packets lost */
- link_stats_packet_sent(rpl_get_parent_lladdr(p), MAC_TX_OK, 10);
- } else if(status == RPL_DAO_ACK_TIMEOUT) { /* timeout = no ack */
- /* punish the total lack of ACK with a similar punishment */
- link_stats_packet_sent(rpl_get_parent_lladdr(p), MAC_TX_OK, 10);
- }
+ PRINTF("RPL: Reset MRHOF\n");
}
-#endif /* RPL_WITH_DAO_ACK */
-/*---------------------------------------------------------------------------*/
-static uint16_t
-parent_link_metric(rpl_parent_t *p)
+
+static void
+neighbor_link_callback(rpl_parent_t *p, int status, int numtx)
{
- const struct link_stats *stats = rpl_get_parent_link_stats(p);
- if(stats != NULL) {
-#if RPL_MRHOF_SQUARED_ETX
- uint32_t squared_etx = ((uint32_t)stats->etx * stats->etx) / LINK_STATS_ETX_DIVISOR;
- return (uint16_t)MIN(squared_etx, 0xffff);
-#else /* RPL_MRHOF_SQUARED_ETX */
- return stats->etx;
-#endif /* RPL_MRHOF_SQUARED_ETX */
+ uint16_t recorded_etx = p->link_metric;
+ uint16_t packet_etx = numtx * RPL_DAG_MC_ETX_DIVISOR;
+ uint16_t new_etx;
+
+ /* Do not penalize the ETX when collisions or transmission errors occur. */
+ if(status == MAC_TX_OK || status == MAC_TX_NOACK) {
+ if(status == MAC_TX_NOACK) {
+ packet_etx = MAX_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR;
+ }
+
+ new_etx = ((uint32_t)recorded_etx * ETX_ALPHA +
+ (uint32_t)packet_etx * (ETX_SCALE - ETX_ALPHA)) / ETX_SCALE;
+
+ PRINTF("RPL: ETX changed from %u to %u (packet ETX = %u)\n",
+ (unsigned)(recorded_etx / RPL_DAG_MC_ETX_DIVISOR),
+ (unsigned)(new_etx / RPL_DAG_MC_ETX_DIVISOR),
+ (unsigned)(packet_etx / RPL_DAG_MC_ETX_DIVISOR));
+ p->link_metric = new_etx;
}
- return 0xffff;
}
-/*---------------------------------------------------------------------------*/
-static uint16_t
-parent_path_cost(rpl_parent_t *p)
+
+static rpl_rank_t
+calculate_rank(rpl_parent_t *p, rpl_rank_t base_rank)
{
- uint16_t base;
+ rpl_rank_t new_rank;
+ rpl_rank_t rank_increase;
- if(p == NULL || p->dag == NULL || p->dag->instance == NULL) {
- return 0xffff;
+ if(p == NULL) {
+ if(base_rank == 0) {
+ return INFINITE_RANK;
+ }
+ rank_increase = RPL_INIT_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR;
+ } else {
+ rank_increase = p->link_metric;
+ if(base_rank == 0) {
+ base_rank = p->rank;
+ }
}
-#if RPL_WITH_MC
- /* Handle the different MC types */
- switch(p->dag->instance->mc.type) {
- case RPL_DAG_MC_ETX:
- base = p->mc.obj.etx;
- break;
- case RPL_DAG_MC_ENERGY:
- base = p->mc.obj.energy.energy_est << 8;
- break;
- default:
- base = p->rank;
- break;
+ if(INFINITE_RANK - base_rank < rank_increase) {
+ /* Reached the maximum rank. */
+ new_rank = INFINITE_RANK;
+ } else {
+ /* Calculate the rank based on the new rank information from DIO or
+ stored otherwise. */
+ new_rank = base_rank + rank_increase;
}
-#else /* RPL_WITH_MC */
- base = p->rank;
-#endif /* RPL_WITH_MC */
- /* path cost upper bound: 0xffff */
- return MIN((uint32_t)base + parent_link_metric(p), 0xffff);
+ return new_rank;
}
-/*---------------------------------------------------------------------------*/
-static rpl_rank_t
-rank_via_parent(rpl_parent_t *p)
-{
- uint16_t min_hoprankinc;
- uint16_t path_cost;
- if(p == NULL || p->dag == NULL || p->dag->instance == NULL) {
- return INFINITE_RANK;
+static rpl_dag_t *
+best_dag(rpl_dag_t *d1, rpl_dag_t *d2)
+{
+ if(d1->grounded != d2->grounded) {
+ return d1->grounded ? d1 : d2;
}
- min_hoprankinc = p->dag->instance->min_hoprankinc;
- path_cost = parent_path_cost(p);
+ if(d1->preference != d2->preference) {
+ return d1->preference > d2->preference ? d1 : d2;
+ }
- /* Rank lower-bound: parent rank + min_hoprankinc */
- return MAX(MIN((uint32_t)p->rank + min_hoprankinc, 0xffff), path_cost);
-}
-/*---------------------------------------------------------------------------*/
-static int
-parent_is_acceptable(rpl_parent_t *p)
-{
- uint16_t link_metric = parent_link_metric(p);
- uint16_t path_cost = parent_path_cost(p);
- /* Exclude links with too high link metrics or path cost (RFC6719, 3.2.2) */
- return link_metric <= MAX_LINK_METRIC && path_cost <= MAX_PATH_COST;
-}
-/*---------------------------------------------------------------------------*/
-static int
-parent_has_usable_link(rpl_parent_t *p)
-{
- uint16_t link_metric = parent_link_metric(p);
- /* Exclude links with too high link metrics */
- return link_metric <= MAX_LINK_METRIC;
+ return d1->rank < d2->rank ? d1 : d2;
}
-/*---------------------------------------------------------------------------*/
+
static rpl_parent_t *
best_parent(rpl_parent_t *p1, rpl_parent_t *p2)
{
rpl_dag_t *dag;
- uint16_t p1_cost;
- uint16_t p2_cost;
- int p1_is_acceptable;
- int p2_is_acceptable;
+ rpl_path_metric_t min_diff;
+ rpl_path_metric_t p1_metric;
+ rpl_path_metric_t p2_metric;
- p1_is_acceptable = p1 != NULL && parent_is_acceptable(p1);
- p2_is_acceptable = p2 != NULL && parent_is_acceptable(p2);
+ dag = p1->dag; /* Both parents are in the same DAG. */
- if(!p1_is_acceptable) {
- return p2_is_acceptable ? p2 : NULL;
- }
- if(!p2_is_acceptable) {
- return p1_is_acceptable ? p1 : NULL;
- }
+ min_diff = RPL_DAG_MC_ETX_DIVISOR /
+ PARENT_SWITCH_THRESHOLD_DIV;
- dag = p1->dag; /* Both parents are in the same DAG. */
- p1_cost = parent_path_cost(p1);
- p2_cost = parent_path_cost(p2);
+ p1_metric = calculate_path_metric(p1);
+ p2_metric = calculate_path_metric(p2);
/* Maintain stability of the preferred parent in case of similar ranks. */
if(p1 == dag->preferred_parent || p2 == dag->preferred_parent) {
- if(p1_cost < p2_cost + PARENT_SWITCH_THRESHOLD &&
- p1_cost > p2_cost - PARENT_SWITCH_THRESHOLD) {
+ if(p1_metric < p2_metric + min_diff &&
+ p1_metric > p2_metric - min_diff) {
+ PRINTF("RPL: MRHOF hysteresis: %u <= %u <= %u\n",
+ p2_metric - min_diff,
+ p1_metric,
+ p2_metric + min_diff);
return dag->preferred_parent;
}
}
- return p1_cost < p2_cost ? p1 : p2;
+ return p1_metric < p2_metric ? p1 : p2;
}
-/*---------------------------------------------------------------------------*/
-static rpl_dag_t *
-best_dag(rpl_dag_t *d1, rpl_dag_t *d2)
-{
- if(d1->grounded != d2->grounded) {
- return d1->grounded ? d1 : d2;
- }
-
- if(d1->preference != d2->preference) {
- return d1->preference > d2->preference ? d1 : d2;
- }
- return d1->rank < d2->rank ? d1 : d2;
-}
-/*---------------------------------------------------------------------------*/
-#if !RPL_WITH_MC
+#if RPL_DAG_MC == RPL_DAG_MC_NONE
static void
update_metric_container(rpl_instance_t *instance)
{
- instance->mc.type = RPL_DAG_MC_NONE;
+ instance->mc.type = RPL_DAG_MC;
}
-#else /* RPL_WITH_MC */
+#else
static void
update_metric_container(rpl_instance_t *instance)
{
+ rpl_path_metric_t path_metric;
rpl_dag_t *dag;
- uint16_t path_cost;
+#if RPL_DAG_MC == RPL_DAG_MC_ENERGY
uint8_t type;
+#endif
+
+ instance->mc.type = RPL_DAG_MC;
+ instance->mc.flags = RPL_DAG_MC_FLAG_P;
+ instance->mc.aggr = RPL_DAG_MC_AGGR_ADDITIVE;
+ instance->mc.prec = 0;
dag = instance->current_dag;
- if(dag == NULL || !dag->joined) {
+
+ if (!dag->joined) {
PRINTF("RPL: Cannot update the metric container when not joined\n");
return;
}
if(dag->rank == ROOT_RANK(instance)) {
- /* Configure MC at root only, other nodes are auto-configured when joining */
- instance->mc.type = RPL_DAG_MC;
- instance->mc.flags = 0;
- instance->mc.aggr = RPL_DAG_MC_AGGR_ADDITIVE;
- instance->mc.prec = 0;
- path_cost = dag->rank;
+ path_metric = 0;
} else {
- path_cost = parent_path_cost(dag->preferred_parent);
+ path_metric = calculate_path_metric(dag->preferred_parent);
}
- /* Handle the different MC types */
- switch(instance->mc.type) {
- case RPL_DAG_MC_NONE:
- break;
- case RPL_DAG_MC_ETX:
- instance->mc.length = sizeof(instance->mc.obj.etx);
- instance->mc.obj.etx = path_cost;
- break;
- case RPL_DAG_MC_ENERGY:
- instance->mc.length = sizeof(instance->mc.obj.energy);
- if(dag->rank == ROOT_RANK(instance)) {
- type = RPL_DAG_MC_ENERGY_TYPE_MAINS;
- } else {
- type = RPL_DAG_MC_ENERGY_TYPE_BATTERY;
- }
- instance->mc.obj.energy.flags = type << RPL_DAG_MC_ENERGY_TYPE;
- /* Energy_est is only one byte, use the least significant byte of the path metric. */
- instance->mc.obj.energy.energy_est = path_cost >> 8;
- break;
- default:
- PRINTF("RPL: MRHOF, non-supported MC %u\n", instance->mc.type);
- break;
+#if RPL_DAG_MC == RPL_DAG_MC_ETX
+ instance->mc.length = sizeof(instance->mc.obj.etx);
+ instance->mc.obj.etx = path_metric;
+
+ PRINTF("RPL: My path ETX to the root is %u.%u\n",
+ instance->mc.obj.etx / RPL_DAG_MC_ETX_DIVISOR,
+ (instance->mc.obj.etx % RPL_DAG_MC_ETX_DIVISOR * 100) /
+ RPL_DAG_MC_ETX_DIVISOR);
+#elif RPL_DAG_MC == RPL_DAG_MC_ENERGY
+ instance->mc.length = sizeof(instance->mc.obj.energy);
+
+ if(dag->rank == ROOT_RANK(instance)) {
+ type = RPL_DAG_MC_ENERGY_TYPE_MAINS;
+ } else {
+ type = RPL_DAG_MC_ENERGY_TYPE_BATTERY;
}
-}
-#endif /* RPL_WITH_MC */
-/*---------------------------------------------------------------------------*/
-rpl_of_t rpl_mrhof = {
- reset,
-#if RPL_WITH_DAO_ACK
- dao_ack_callback,
-#endif
- parent_link_metric,
- parent_has_usable_link,
- parent_path_cost,
- rank_via_parent,
- best_parent,
- best_dag,
- update_metric_container,
- RPL_OCP_MRHOF
-};
-/** @}*/
+ instance->mc.obj.energy.flags = type << RPL_DAG_MC_ENERGY_TYPE;
+ instance->mc.obj.energy.energy_est = path_metric;
+#endif /* RPL_DAG_MC == RPL_DAG_MC_ETX */
+}
+#endif /* RPL_DAG_MC == RPL_DAG_MC_NONE */
From f56aa908b362637708a4d99f4c1290839eb69a9f Mon Sep 17 00:00:00 2001
From: weld10 <50168266+Amrican10@users.noreply.github.com>
Date: Mon, 27 Jul 2020 22:57:37 +0200
Subject: [PATCH 06/19] Update rpl-mrhof.c
---
core/net/rpl/rpl-mrhof.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/core/net/rpl/rpl-mrhof.c b/core/net/rpl/rpl-mrhof.c
index 8154c5b62a1..9d75f319ba7 100755
--- a/core/net/rpl/rpl-mrhof.c
+++ b/core/net/rpl/rpl-mrhof.c
@@ -48,7 +48,7 @@
#include "net/nbr-table.h"
#define DEBUG DEBUG_NONE
-#include "net/uip-debug.h"
+#include "net/ip/uip-debug.h"
static void reset(rpl_dag_t *);
static void neighbor_link_callback(rpl_parent_t *, int, int);
From 9569cfc1e972386627c7e578fa4ed4012ce2121b Mon Sep 17 00:00:00 2001
From: weld10 <50168266+Amrican10@users.noreply.github.com>
Date: Mon, 27 Jul 2020 23:21:17 +0200
Subject: [PATCH 07/19] Update rpl.h
---
core/net/rpl/rpl.h | 82 +++++++++++++++++++++++++++++++++++++---------
1 file changed, 66 insertions(+), 16 deletions(-)
diff --git a/core/net/rpl/rpl.h b/core/net/rpl/rpl.h
index 26ee71edc49..5179ed3b96b 100755
--- a/core/net/rpl/rpl.h
+++ b/core/net/rpl/rpl.h
@@ -38,12 +38,16 @@
#ifndef RPL_H
#define RPL_H
-#include "rpl-conf.h"
-
-#include "lib/list.h"
-#include "net/ip/uip.h"
-#include "net/ipv6/uip-ds6.h"
-#include "sys/ctimer.h"
+
+ #include "net/rpl/rpl-conf.h"
+
+ #include "lib/list.h"
+ #include "net/ip/uip.h"
+ #include "net/ipv6/uip-ds6.h"
+ #include "sys/ctimer.h"
+ #ifdef USE_METRIC_CONTAINERS
+ #include "rpl-metrics-data.h"
+ #endif /* USE_METRIC_CONTAINERS */
/*---------------------------------------------------------------------------*/
typedef uint16_t rpl_rank_t;
@@ -72,6 +76,26 @@ typedef uint16_t rpl_ocp_t;
#define RPL_DAG_MC_AGGR_MINIMUM 2
#define RPL_DAG_MC_AGGR_MULTIPLICATIVE 3
+ /* position of the fields in metric container *
+ * object header flags */
+ #define RPL_DAG_MC_POS_P_BIT 10
+ #define RPL_DAG_MC_POS_C_BIT 9
+ #define RPL_DAG_MC_POS_O_BIT 8
+ #define RPL_DAG_MC_POS_R_BIT 7
+ #define RPL_DAG_MC_POS_A_FIELD 4
+ #define RPL_DAG_MC_POS_PREC_FIELD 0
+
+ /* The bit index within the flags field of
+ the rpl_metric_object_energy structure. */
+ #define RPL_DAG_MC_ENERGY_INCLUDED 3
+ #define RPL_DAG_MC_ENERGY_TYPE 1
+ #define RPL_DAG_MC_ENERGY_ESTIMATION 0
+
+ #define RPL_DAG_MC_ENERGY_TYPE_MAINS 0
+ #define RPL_DAG_MC_ENERGY_TYPE_BATTERY 1
+ #define RPL_DAG_MC_ENERGY_TYPE_SCAVENGING 2
+
+
/* The bit index within the flags field of the rpl_metric_object_energy structure. */
#define RPL_DAG_MC_ENERGY_INCLUDED 3
#define RPL_DAG_MC_ENERGY_TYPE 1
@@ -91,6 +115,7 @@ struct rpl_metric_object_energy {
uint8_t energy_est;
};
+#ifndef USE_METRIC_CONTAINERS
/* Logical representation of a DAG Metric Container. */
struct rpl_metric_container {
uint8_t type;
@@ -104,6 +129,7 @@ struct rpl_metric_container {
} obj;
};
typedef struct rpl_metric_container rpl_metric_container_t;
+#endif /* USE_METRIC_CONTAINERS */
/*---------------------------------------------------------------------------*/
struct rpl_instance;
struct rpl_dag;
@@ -111,16 +137,28 @@ struct rpl_dag;
#define RPL_PARENT_FLAG_UPDATED 0x1
#define RPL_PARENT_FLAG_LINK_METRIC_VALID 0x2
-struct rpl_parent {
- struct rpl_dag *dag;
-#if RPL_WITH_MC
- rpl_metric_container_t mc;
-#endif /* RPL_WITH_MC */
- rpl_rank_t rank;
- uint8_t dtsn;
- uint8_t flags;
-};
-typedef struct rpl_parent rpl_parent_t;
+ struct rpl_parent {
+ struct rpl_parent *next;
+ struct rpl_dag *dag;
+ #if RPL_DAG_MC != RPL_DAG_MC_NONE
+ rpl_metric_container_t mc;
+ #endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */
+ rpl_rank_t rank;
+
+ //#ifdef RPL_DAG_MC_USE_ETX
+ uint16_t etx;
+ //#endif /* RPL_DAG_MC_USE_ETX */
+ #ifdef RPL_DAG_MC_USE_LQL
+ uint8_t lql;
+ #endif /* RPL_DAG_MC_USE_LQL */
+ #ifdef RPL_DAG_MC_USE_LC
+ uint16_t lc;
+ #endif /* RPL_DAG_MC_USE_LC */
+
+ uint8_t dtsn;
+ uint8_t updated;
+ };
+ typedef struct rpl_parent rpl_parent_t;
/*---------------------------------------------------------------------------*/
/* RPL DIO prefix suboption */
struct rpl_prefix {
@@ -144,6 +182,7 @@ struct rpl_dag {
rpl_parent_t *preferred_parent;
rpl_rank_t rank;
struct rpl_instance *instance;
+ LIST_STRUCT(parents);
rpl_prefix_t prefix_info;
uint32_t lifetime;
};
@@ -200,6 +239,11 @@ typedef struct rpl_instance rpl_instance_t;
*/
struct rpl_of {
void (*reset)(struct rpl_dag *);
+
+ #if defined(RPL_DAG_MC_USE_ETX) || defined(RPL_DAG_MC_CONST_USE_ETX)
+ void (*neighbor_link_callback)(rpl_parent_t *, int, int);
+ #endif /* defined(RPL_DAG_MC_USE_ETX) || defined(RPL_DAG_MC_CONST_USE_ETX) */
+
#if RPL_WITH_DAO_ACK
void (*dao_ack_callback)(rpl_parent_t *, int status);
#endif
@@ -209,6 +253,7 @@ struct rpl_of {
rpl_rank_t (*rank_via_parent)(rpl_parent_t *);
rpl_parent_t *(*best_parent)(rpl_parent_t *, rpl_parent_t *);
rpl_dag_t *(*best_dag)(rpl_dag_t *, rpl_dag_t *);
+ rpl_rank_t (*calculate_rank)(rpl_parent_t *, rpl_rank_t);
void (*update_metric_container)( rpl_instance_t *);
rpl_ocp_t ocp;
};
@@ -277,8 +322,12 @@ rpl_instance_t *rpl_get_instance(uint8_t instance_id);
int rpl_update_header(void);
int rpl_finalize_header(uip_ipaddr_t *addr);
int rpl_verify_hbh_header(int);
+void rpl_update_header_empty(void);
+int rpl_update_header_final(uip_ipaddr_t *addr);
+int rpl_verify_header(int);
void rpl_insert_header(void);
void rpl_remove_header(void);
+uint8_t rpl_invert_header(void);
const struct link_stats *rpl_get_parent_link_stats(rpl_parent_t *p);
int rpl_parent_is_fresh(rpl_parent_t *p);
int rpl_parent_is_reachable(rpl_parent_t *p);
@@ -288,6 +337,7 @@ const linkaddr_t *rpl_get_parent_lladdr(rpl_parent_t *p);
uip_ipaddr_t *rpl_get_parent_ipaddr(rpl_parent_t *nbr);
rpl_parent_t *rpl_get_parent(uip_lladdr_t *addr);
rpl_rank_t rpl_get_parent_rank(uip_lladdr_t *addr);
+uint16_t rpl_get_parent_link_metric(uip_lladdr_t *addr);
void rpl_dag_init(void);
uip_ds6_nbr_t *rpl_get_nbr(rpl_parent_t *parent);
void rpl_print_neighbor_list(void);
From 1abbc9277442dc6496be9d203317392b28c17b1a Mon Sep 17 00:00:00 2001
From: weld10 <50168266+Amrican10@users.noreply.github.com>
Date: Mon, 27 Jul 2020 23:37:57 +0200
Subject: [PATCH 08/19] Update rpl-icmp6.c
---
core/net/rpl/rpl-icmp6.c | 223 +++++++++++++++++++++++++++++++++++++++
1 file changed, 223 insertions(+)
diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c
index 6430e3df982..9ee1aa549b1 100755
--- a/core/net/rpl/rpl-icmp6.c
+++ b/core/net/rpl/rpl-icmp6.c
@@ -62,6 +62,46 @@
#define DEBUG DEBUG_PRINT
#include "net/ip/uip-debug.h"
+#include "net/nbr-table.h"
+
+
+ static void reset(rpl_dag_t *);
+ static void neighbor_link_callback(rpl_parent_t *, int, int);
+ static rpl_parent_t *best_parent(rpl_parent_t *, rpl_parent_t *);
+ static rpl_dag_t *best_dag(rpl_dag_t *, rpl_dag_t *);
+ static rpl_rank_t calculate_rank(rpl_parent_t *, rpl_rank_t);
+ static void update_metric_container(rpl_instance_t *);
+
+ rpl_of_t rpl_mrhof = {
+ reset,
+ neighbor_link_callback,
+ best_parent,
+ best_dag,
+ calculate_rank,
+ update_metric_container,
+ 1
+ };
+
+ /* Constants for the ETX moving average */
+ #define ETX_SCALE 100
+ #define ETX_ALPHA 90
+
+
+
+ /* Reject parents that have a higher link metric than the following. */
+ #define MAX_LINK_METRIC 10
+
+
+ /* Reject parents that have a higher path cost than the following. */
+ #define MAX_PATH_COST 100
+
+ /*
+ * The rank must differ more than 1/PARENT_SWITCH_THRESHOLD_DIV in order
+ * to switch preferred parent.
+ */
+ #define PARENT_SWITCH_THRESHOLD_DIV 2
+
+
/*---------------------------------------------------------------------------*/
#define RPL_DIO_GROUNDED 0x80
@@ -79,8 +119,191 @@ static void dao_input(void);
static void dao_ack_input(void);
static void dco_input(void);
static void dco_ack_input(void);
+/*----------------------------------------------------------------------------*/
+typedef uint16_t rpl_path_metric_t;
+
+ static rpl_path_metric_t
+ calculate_path_metric(rpl_parent_t *p)
+ {
+ if(p == NULL) {
+ return MAX_PATH_COST * RPL_DAG_MC_ETX_DIVISOR;
+ }
+
+#if RPL_DAG_MC == RPL_DAG_MC_NONE
+ return p->rank + (uint16_t)p->link_metric;
+#elif RPL_DAG_MC == RPL_DAG_MC_ETX
+ return p->mc.obj.etx + (uint16_t)p->link_metric;
+#elif RPL_DAG_MC == RPL_DAG_MC_ENERGY
+ return p->mc.obj.energy.energy_est + (uint16_t)p->link_metric;
+#else
+#error "Unsupported RPL_DAG_MC configured. See rpl.h."
+#endif /* RPL_DAG_MC */
+}
+
+static void
+reset(rpl_dag_t *sag)
+{
+ PRINTF("RPL: Reset MRHOF\n");
+}
+
+static void
+neighbor_link_callback(rpl_parent_t *p, int status, int numtx)
+{
+ uint16_t recorded_etx = p->link_metric;
+ uint16_t packet_etx = numtx * RPL_DAG_MC_ETX_DIVISOR;
+ uint16_t new_etx;
+
+ /* Do not penalize the ETX when collisions or transmission errors occur. */
+ if(status == MAC_TX_OK || status == MAC_TX_NOACK) {
+ if(status == MAC_TX_NOACK) {
+ packet_etx = MAX_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR;
+ }
+
+ new_etx = ((uint32_t)recorded_etx * ETX_ALPHA +
+ (uint32_t)packet_etx * (ETX_SCALE - ETX_ALPHA)) / ETX_SCALE;
+
+ PRINTF("RPL: ETX changed from %u to %u (packet ETX = %u)\n",
+ (unsigned)(recorded_etx / RPL_DAG_MC_ETX_DIVISOR),
+ (unsigned)(new_etx / RPL_DAG_MC_ETX_DIVISOR),
+ (unsigned)(packet_etx / RPL_DAG_MC_ETX_DIVISOR));
+ p->link_metric = new_etx;
+ }
+}
+
+static rpl_rank_t
+calculate_rank(rpl_parent_t *p, rpl_rank_t base_rank)
+{
+ rpl_rank_t new_rank;
+ rpl_rank_t rank_increase;
+
+ if(p == NULL) {
+ if(base_rank == 0) {
+ return INFINITE_RANK;
+ }
+ rank_increase = RPL_INIT_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR;
+ } else {
+ rank_increase = p->link_metric;
+ if(base_rank == 0) {
+ base_rank = p->rank;
+ }
+ }
+ if(INFINITE_RANK - base_rank < rank_increase) {
+ /* Reached the maximum rank. */
+ new_rank = INFINITE_RANK;
+ } else {
+ /* Calculate the rank based on the new rank information from DIO or
+ stored otherwise. */
+ new_rank = base_rank + rank_increase;
+ }
+
+ return new_rank;
+}
+
+static rpl_dag_t *
+best_dag(rpl_dag_t *d1, rpl_dag_t *d2)
+{
+ if(d1->grounded != d2->grounded) {
+ return d1->grounded ? d1 : d2;
+ }
+
+ if(d1->preference != d2->preference) {
+ return d1->preference > d2->preference ? d1 : d2;
+ }
+
+ return d1->rank < d2->rank ? d1 : d2;
+}
+
+static rpl_parent_t *
+best_parent(rpl_parent_t *p1, rpl_parent_t *p2)
+{
+ rpl_dag_t *dag;
+ rpl_path_metric_t min_diff;
+ rpl_path_metric_t p1_metric;
+ rpl_path_metric_t p2_metric;
+
+ dag = p1->dag; /* Both parents are in the same DAG. */
+
+ min_diff = RPL_DAG_MC_ETX_DIVISOR /
+ PARENT_SWITCH_THRESHOLD_DIV;
+
+ p1_metric = calculate_path_metric(p1);
+ p2_metric = calculate_path_metric(p2);
+
+ /* Maintain stability of the preferred parent in case of similar ranks. */
+ if(p1 == dag->preferred_parent || p2 == dag->preferred_parent) {
+ if(p1_metric < p2_metric + min_diff &&
+ p1_metric > p2_metric - min_diff) {
+ PRINTF("RPL: MRHOF hysteresis: %u <= %u <= %u\n",
+ p2_metric - min_diff,
+ p1_metric,
+ p2_metric + min_diff);
+ return dag->preferred_parent;
+ }
+ }
+
+ return p1_metric < p2_metric ? p1 : p2;
+}
+
+#if RPL_DAG_MC == RPL_DAG_MC_NONE
+static void
+update_metric_container(rpl_instance_t *instance)
+{
+ instance->mc.type = RPL_DAG_MC;
+}
+#else
+static void
+update_metric_container(rpl_instance_t *instance)
+{
+ rpl_path_metric_t path_metric;
+ rpl_dag_t *dag;
+#if RPL_DAG_MC == RPL_DAG_MC_ENERGY
+ uint8_t type;
+#endif
+
+ instance->mc.type = RPL_DAG_MC;
+ instance->mc.flags = RPL_DAG_MC_FLAG_P;
+ instance->mc.aggr = RPL_DAG_MC_AGGR_ADDITIVE;
+ instance->mc.prec = 0;
+
+ dag = instance->current_dag;
+
+ if (!dag->joined) {
+ PRINTF("RPL: Cannot update the metric container when not joined\n");
+ return;
+ }
+
+ if(dag->rank == ROOT_RANK(instance)) {
+ path_metric = 0;
+ } else {
+ path_metric = calculate_path_metric(dag->preferred_parent);
+ }
+
+#if RPL_DAG_MC == RPL_DAG_MC_ETX
+ instance->mc.length = sizeof(instance->mc.obj.etx);
+ instance->mc.obj.etx = path_metric;
+
+ PRINTF("RPL: My path ETX to the root is %u.%u\n",
+ instance->mc.obj.etx / RPL_DAG_MC_ETX_DIVISOR,
+ (instance->mc.obj.etx % RPL_DAG_MC_ETX_DIVISOR * 100) /
+ RPL_DAG_MC_ETX_DIVISOR);
+#elif RPL_DAG_MC == RPL_DAG_MC_ENERGY
+ instance->mc.length = sizeof(instance->mc.obj.energy);
+
+ if(dag->rank == ROOT_RANK(instance)) {
+ type = RPL_DAG_MC_ENERGY_TYPE_MAINS;
+ } else {
+ type = RPL_DAG_MC_ENERGY_TYPE_BATTERY;
+ }
+
+ instance->mc.obj.energy.flags = type << RPL_DAG_MC_ENERGY_TYPE;
+ instance->mc.obj.energy.energy_est = path_metric;
+#endif /* RPL_DAG_MC == RPL_DAG_MC_ETX */
+}
+#endif /* RPL_DAG_MC == RPL_DAG_MC_NONE */
+/*------------------------------------------------------------------*/
+
static void dao_output_target_seq(rpl_parent_t *parent, uip_ipaddr_t *prefix,
uint8_t lifetime, uint8_t seq_no);
void dco_output
From 0e9a44ba180cb8de56b0e29b7a44c5764e414823 Mon Sep 17 00:00:00 2001
From: weld10 <50168266+Amrican10@users.noreply.github.com>
Date: Sat, 1 Aug 2020 17:11:49 +0200
Subject: [PATCH 09/19] Update client.c
---
examples/containers/client.c | 280 ++++++++++++++++++++++++++++++-----
1 file changed, 242 insertions(+), 38 deletions(-)
diff --git a/examples/containers/client.c b/examples/containers/client.c
index 46eb17d278a..a33fe908abe 100644
--- a/examples/containers/client.c
+++ b/examples/containers/client.c
@@ -28,11 +28,26 @@
*/
#include "contiki.h"
-#include "net/uip.h"
-#include "net/uip-ds6.h"
-#include "net/uip-udp-packet.h"
+#include
+#include
+#include
+#include "lib/random.h"
+#include "sys/ctimer.h"
+#include "net/ip/uip.h"
+#include "net/ipv6/uip-ds6.h"
+#include "net/ip/uip-udp-packet.h"
#include "net/rpl/rpl.h"
+#include "sys/ctimer.h"
+#ifdef WITH_COMPOWER
+#include "powertrace.h"
+#endif
+#include
+#include
+#include "common-hdr.h"
#include "dev/serial-line.h"
+#include "net/rime/rimeaddr.h"
+#include "common-hdr.h"
+#include "udp-app.h"
#ifdef BUTTON_INTERFERENCE
#include "dev/button-sensor.h"
@@ -53,11 +68,39 @@
#include
#include
-#define UDP_CLIENT_PORT 8775
-#define UDP_SERVER_PORT 5688
+#define UDP_CLIENT_PORT 8765
+#define UDP_SERVER_PORT 5678
+
+#define DEBUG DEBUG_PRINT
+#include "net/ip/uip-debug.h"
+
+#include "net/ipv6/uip-ds6-route.h"
-#define DEBUG DEBUG_NONE
-#include "net/uip-debug.h"
+#define UDP_EXAMPLE_ID 190
+
+#ifndef PERIOD
+#define PERIOD 300
+#endif
+
+#define START_INTERVAL (15 * CLOCK_SECOND)
+#define SEND_INTERVAL (PERIOD * CLOCK_SECOND)
+#define SEND_TIME (random_rand() % (SEND_INTERVAL))
+#define MAX_PAYLOAD_LEN 1024
+#if 0
+typedef struct _app_stat_
+{
+ uint32_t lastseq;
+ uint32_t dropcnt;
+ uint32_t unordered;
+ uint32_t rcvcnt;
+ uint32_t dupcnt;
+ long leastLatency;
+}app_stat_t;
+
+app_stat_t g_stats;
+#endif
+
+dpkt_stat_t g_pktstat;
static struct uip_udp_conn *client_conn;
static uip_ipaddr_t server_ipaddr;
@@ -65,6 +108,45 @@ static uip_ipaddr_t server_ipaddr;
/*---------------------------------------------------------------------------*/
PROCESS(udp_client_process, "UDP client process");
AUTOSTART_PROCESSES(&udp_client_process, &collect_common_process);
+
+static int seq_id;
+ static int reply;
+
+ long dpkt_latency_time(struct timeval *tv)
+ {
+ long duration=0;
+ long sentTime=0;
+ long recvTime=0;
+ struct timeval curTime;
+ gettimeofday(&curTime, NULL);
+
+ sentTime = tv->tv_sec * 1000000;
+ sentTime += tv->tv_usec;
+
+ recvTime = curTime.tv_sec * 1000000;
+ recvTime += curTime.tv_usec;
+
+ if (recvTime > sentTime){
+ duration = recvTime-sentTime;
+ }
+
+ #if 0
+ if (curTime.tv_sec > tv->tv_sec){
+ duration = (curTime.tv_sec - tv->tv_sec) * 1000000;
+
+
+
+ }
+
+ if (curTime.tv_usec > tv->tv_usec){
+ duration += (curTime.tv_usec - tv->tv_usec);
+
+
+ }
+ #endif
+
+ return duration;
+ }
/*---------------------------------------------------------------------------*/
void
collect_common_set_sink(void)
@@ -100,10 +182,70 @@ collect_common_net_print(void)
static void
tcpip_handler(void)
{
+ dpkt_t *pkt;
+ long curpktlatency;
+
if(uip_newdata()) {
- /* Ignore incoming data */
+ pkt = (dpkt_t *)uip_appdata;
+
+ if (!g_pktstat.lastseq){
+ g_pktstat.lastseq = pkt->seq;
+ g_pktstat.rcvcnt++;
+ g_pktstat.leastLatency = g_pktstat.maxLatency = curpktlatency = dpkt_latency_time(&(pkt->sendTime));
+ return;
+ }
+
+ PRINTF("Recvd Response with seq[%u] last rsp seq[%u]\n",pkt->seq, g_pktstat.lastseq);
+
+ if (pkt->seq == g_pktstat.lastseq){
+ g_pktstat.dupcnt++;
+ }
+ else if(pkt->seq < g_pktstat.lastseq) {
+ g_pktstat.unordered++;
+ g_pktstat.rcvcnt++;
+ }
+ else{
+ g_pktstat.lastseq = pkt->seq;
+ g_pktstat.rcvcnt++;
+ }
+
+ curpktlatency = dpkt_latency_time(&(pkt->sendTime));
+ if (curpktlatency < g_pktstat.leastLatency){
+ g_pktstat.leastLatency = curpktlatency;
+
+ }
+ if (curpktlatency > g_pktstat.maxLatency){
+ g_pktstat.maxLatency = curpktlatency;
+}
+
+reply++;
+ printf("DATA recv (s:%d, r:%d) end2nd latency[%lu] minlatency[%lu]\n", seq_id, reply, curpktlatency, g_pktstat.leastLatency);
+ }
+ }
+
+ uint32_t g_seq = 0;
+ uint32_t g_payload_len=32;
+
+static void
+send_packet(void *ptr)
+{
+ char buf[MAX_PAYLOAD_LEN];
+ dpkt_t *pkt=(dpkt_t*)buf;
+ if(sizeof(buf) < sizeof(pkt)+g_payload_len) {
+ printf("buffer size mismatch .. expect no UDP pkt\n");
+ return;
}
+
+ seq_id++;
+ pkt->seq = seq_id;
+ gettimeofday(&(pkt->sendTime), NULL);
+
+ PRINTF("DATA send to %d 'Hello %d' size-%lu\n",
+ server_ipaddr.u8[sizeof(server_ipaddr.u8) - 1], seq_id, sizeof(pkt)+g_payload_len);
+
+ uip_udp_packet_sendto(client_conn, buf, sizeof(pkt)+g_payload_len,
+ &server_ipaddr, UIP_HTONS(UDP_SERVER_PORT));
}
/*---------------------------------------------------------------------------*/
void
@@ -136,7 +278,7 @@ collect_common_send(void)
}
msg.seqno = seqno;
- rimeaddr_copy(&parent, &rimeaddr_null);
+ //rimeaddr_copy(&parent, &rimeaddr_null);
parent_etx = 0;
/* Let's suppose we have only one instance */
@@ -189,11 +331,11 @@ collect_common_send(void)
void
collect_common_net_init(void)
{
-#if CONTIKI_TARGET_Z1
+/*#if CONTIKI_TARGET_Z1
uart0_set_input(serial_line_input_byte);
#else
uart1_set_input(serial_line_input_byte);
-#endif
+#endif*/
serial_line_init();
}
/*---------------------------------------------------------------------------*/
@@ -223,18 +365,53 @@ set_global_address(void)
{
uip_ipaddr_t ipaddr;
- uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0);
+ uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0);
uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr);
uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF);
- /* set server address */
- uip_ip6addr(&server_ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 1);
+/* Mode 2 - 16 bits inline */
+ uip_ip6addr(&server_ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0x00ff, 0xfe00, 1);
}
+
+ int g_send_interval=0;
+ int g_auto_start = 1;
+ void set_udp_param(void)
+ {
+ char *ptr = getenv("UDPCLI_SEND_INT");
+ if(!ptr){
+ PRINTF("UDP_SEND_INT env var not found\n");
+ return;
+ }
+
+ g_send_interval = (int)(atof(ptr)*CLOCK_SECOND);
+
+ char *ptr1 = getenv("AUTO_START");
+ if(!ptr1){
+ PRINTF("AUTO_START env var not found\n");
+ return;
+ }
+
+ g_auto_start = (int)(atof(ptr1));
+
+ ptr = getenv("UDP_PAYLOAD_LEN");
+ if(ptr) g_payload_len = (int)atoi(ptr);
+ PRINTF("UDP g_send_interval:%d g_payload_len:%d\n",
+ g_send_interval, g_payload_len);
+
+ memset(&g_pktstat, 0, sizeof(g_pktstat));
+ }
+
+ static struct etimer periodic;
+ int udp_started = 0;
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(udp_client_process, ev, data)
{
+
+//static struct etimer periodic;
+ static struct ctimer backoff_timer;
+ unsigned long backoff;
PROCESS_BEGIN();
PROCESS_PAUSE();
@@ -253,6 +430,10 @@ PROCESS_THREAD(udp_client_process, ev, data)
/* new connection with remote host */
client_conn = udp_new(NULL, UIP_HTONS(UDP_SERVER_PORT), NULL);
+ if(client_conn == NULL) {
+ PRINTF("No UDP connection available, exiting the process!\n");
+ PROCESS_EXIT();
+ }
udp_bind(client_conn, UIP_HTONS(UDP_CLIENT_PORT));
PRINTF("Created a connection with the server ");
@@ -260,39 +441,62 @@ PROCESS_THREAD(udp_client_process, ev, data)
PRINTF(" local/remote port %u/%u\n",
UIP_HTONS(client_conn->lport), UIP_HTONS(client_conn->rport));
+backoff = g_send_interval/4 + (g_send_interval / 4 * (uint32_t)random_rand()) / RANDOM_RAND_MAX;
+ PRINTF("Gnerated backoff[%lu]\n",backoff);
+
+ if(g_send_interval > 0){
+ etimer_set(&periodic, g_send_interval);
+ udp_started = 1;
+ }
+
+ PRINTF("Will enter to while\n");
-#ifdef USE_LEDS_DEF_PARENT
- leds_on(2);//RED
- static int radio_on= 1;
-#endif
while(1) {
+ PRINTF("Will call PROCESS Yield\n");
PROCESS_YIELD();
+ PRINTF("PROCESS Yield exited\n");
if(ev == tcpip_event) {
tcpip_handler();
}
-#ifdef USE_LEDS_DEF_PARENT
- else if(ev == sensors_event && data == &button_sensor) {
- printf("Radio: ");
- if(radio_on){
- radio_on=0;
- leds_on(1);//BLUE
- NETSTACK_RDC.off(0);
- printf("OFF\n");
- } else{
- radio_on= 1;
- leds_off(1);
- NETSTACK_RDC.on();
- printf("ON\n");
- }
-
- }
-#endif /*USE_LEDS_DEF_PARENT*/
-
- }
+PRINTF("udp_started[%d]\n", udp_started);
+ if(etimer_expired(&periodic)) {
+ etimer_reset(&periodic);
+ PRINTF("Timer Expired [%d]\n",g_auto_start);
+ //send_packet(NULL);
+ if (g_auto_start){
+ //ctimer_set(&backoff_timer, SEND_TIME, send_packet, NULL);
+ backoff = g_send_interval/4 + (g_send_interval / 4 * (uint32_t)random_rand()) / RANDOM_RAND_MAX;
+ ctimer_set(&backoff_timer, backoff, send_packet, NULL);
+ }
+
+ }
+ }
+ PRINTF("Process Stopped\n");
+ PROCESS_END();
+ }
+
+ void start_udp_process()
+ {
+ PRINTF("Need to start the UDP process\n ");
+ if(!g_auto_start && g_send_interval > 0){
+ udp_started = 1;
+ g_auto_start = 1;
+ PRINTF("Started the UDP process[%d]\n", g_send_interval);
+ }
+ }
+
+void udp_get_app_stat(udpapp_stat_t *appstat)
+{
+ PRINTF("Stats Called on Node\n");
- PROCESS_END();
+ appstat->totalpktsent = seq_id;
+ appstat->totalpktrecvd = g_pktstat.rcvcnt;
+ appstat->totalduppkt = g_pktstat.dupcnt;
+ appstat->minroudtriptime = g_pktstat.leastLatency;
+ appstat->maxroundtriptime = g_pktstat.maxLatency;
}
+
/*---------------------------------------------------------------------------*/
From 5aa7f631f4be564b1874133c8046265b8a033770 Mon Sep 17 00:00:00 2001
From: weld10 <50168266+Amrican10@users.noreply.github.com>
Date: Sat, 1 Aug 2020 17:12:45 +0200
Subject: [PATCH 10/19] Update project-conf.h
---
examples/containers/project-conf.h | 69 ++++++++++++++++++++++++++++++
1 file changed, 69 insertions(+)
diff --git a/examples/containers/project-conf.h b/examples/containers/project-conf.h
index d059d21d23a..dcc3703013c 100644
--- a/examples/containers/project-conf.h
+++ b/examples/containers/project-conf.h
@@ -2,6 +2,75 @@
#ifndef __PROJECT_CONF_H__
#define __PROJECT_CONF_H__
+/********************************************************************/
+#ifndef PROJECT_CONF_H_
+#define PROJECT_CONF_H_
+
+#ifndef WITH_NON_STORING
+#define WITH_NON_STORING 0 /* Set this to run with non-storing mode */
+#endif /* WITH_NON_STORING */
+
+#undef NBR_TABLE_CONF_MAX_NEIGHBORS
+#undef UIP_CONF_MAX_ROUTES
+
+#ifdef TEST_MORE_ROUTES
+/* configure number of neighbors and routes */
+#define NBR_TABLE_CONF_MAX_NEIGHBORS 10
+#define UIP_CONF_MAX_ROUTES 30
+#else
+/* configure number of neighbors and routes */
+#define NBR_TABLE_CONF_MAX_NEIGHBORS 100
+#define UIP_CONF_MAX_ROUTES 100
+#endif /* TEST_MORE_ROUTES */
+
+#undef NETSTACK_CONF_RDC
+#define NETSTACK_CONF_RDC nullrdc_driver
+#undef NULLRDC_CONF_802154_AUTOACK
+#define NULLRDC_CONF_802154_AUTOACK 1
+
+/* Define as minutes */
+#define RPL_CONF_DEFAULT_LIFETIME_UNIT 60
+
+/* 10 minutes lifetime of routes */
+#define RPL_CONF_DEFAULT_LIFETIME 10
+
+#define RPL_CONF_DEFAULT_ROUTE_INFINITE_LIFETIME 1
+#define SCSLOWPAN_CONF_FRAG_FORWARDING 0
+#define SICSLOWPAN_CONF_REASS_CONTEXTS 10
+
+#define SERVER_REPLY 1
+
+#if WITH_NON_STORING
+#undef RPL_NS_CONF_LINK_NUM
+#define RPL_NS_CONF_LINK_NUM 40 /* Number of links maintained at the root. Can be set to 0 at non-root nodes. */
+#undef UIP_CONF_MAX_ROUTES
+#define UIP_CONF_MAX_ROUTES 0 /* No need for routes */
+#undef RPL_CONF_MOP
+#define RPL_CONF_MOP RPL_MOP_NON_STORING /* Mode of operation*/
+#endif /* WITH_NON_STORING */
+
+#define RPL_CONF_WITH_DCO 1
+
+#endif
+
+
+/********************************************************************/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#define USE_METRIC_CONTAINERS
#ifdef USE_METRIC_CONTAINERS
From 2ce1c131f5ea7ea73e5db29f92bbc9c76464edb8 Mon Sep 17 00:00:00 2001
From: weld10 <50168266+Amrican10@users.noreply.github.com>
Date: Sat, 1 Aug 2020 17:13:52 +0200
Subject: [PATCH 11/19] Update rpl-metrics-containers-OF.c
---
examples/containers/rpl-metrics-containers-OF.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/examples/containers/rpl-metrics-containers-OF.c b/examples/containers/rpl-metrics-containers-OF.c
index 7d864c26474..92178af7970 100644
--- a/examples/containers/rpl-metrics-containers-OF.c
+++ b/examples/containers/rpl-metrics-containers-OF.c
@@ -12,7 +12,7 @@
#define DEBUG DEBUG_NONE
#endif /*DEBUG_RPL_OF*/
-#include "net/uip-debug.h"
+#include "net/ip/uip-debug.h"
static void reset(rpl_dag_t *);
From fc59fbcd25adae9ffbe1be33a1b7f3f8e4b026aa Mon Sep 17 00:00:00 2001
From: weld10 <50168266+Amrican10@users.noreply.github.com>
Date: Sat, 1 Aug 2020 17:15:19 +0200
Subject: [PATCH 12/19] Update rpl-metrics-get.c
---
examples/containers/rpl-metrics-get.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/examples/containers/rpl-metrics-get.c b/examples/containers/rpl-metrics-get.c
index 0176d223c49..9f5099f8c20 100644
--- a/examples/containers/rpl-metrics-get.c
+++ b/examples/containers/rpl-metrics-get.c
@@ -8,7 +8,7 @@
#else
#define DEBUG DEBUG_NONE
#endif
-#include "net/uip-debug.h"
+#include "net/ip/uip-debug.h"
#include
static uint16_t max_charge;
@@ -81,8 +81,8 @@ uint8_t rpl_metrics_get_hop_count()
uint32_t rpl_metrics_get_throughput()
{
- if(AM_I_NODE(3))
- return (150*65536);
+ /* if(AM_I_NODE(3))
+ return (150*65536);*/
return (100*65536);
}
@@ -91,9 +91,9 @@ uint32_t rpl_metrics_get_throughput()
uint32_t rpl_metrics_get_latency()
{
- if(AM_I_NODE(3))
+ /*if(AM_I_NODE(3))
return (100*65536);
- return (150*65536);
+ return (150*65536);*/
}
/********************************************************************/
@@ -206,11 +206,11 @@ uint8_t rpl_metrics_power_refresh()
if(power32 >= ((uint32_t)max_charge<<16)){
batt_used= 0xFF;
#ifdef STATISTICS
- if(!depleted_battery)
+ // if(!depleted_battery)
printf("30 Battery used: 100%%\n");
#endif /*STATISTICS*/
- depleted_battery= 1;
+ // depleted_battery= 1;
leds_on(1);//BLUE
@@ -226,7 +226,7 @@ uint8_t rpl_metrics_power_refresh()
static uint8_t perc_75=0;
perc= (batt_used*100)/0xFF;
- if( (perc>= 75) && (!depleted_battery)){
+ if( (perc>= 75)){ // && (!depleted_battery)
if(!perc_75){
perc_75++;
printf("30 Battery used: 75%%\n");
From 7cc53c45446464d5d8234dbcaf9c140ef6394d81 Mon Sep 17 00:00:00 2001
From: weld10 <50168266+Amrican10@users.noreply.github.com>
Date: Sat, 1 Aug 2020 17:16:10 +0200
Subject: [PATCH 13/19] Update server.c
---
examples/containers/server.c | 237 ++++++++++++++++++++++++++++++-----
1 file changed, 207 insertions(+), 30 deletions(-)
diff --git a/examples/containers/server.c b/examples/containers/server.c
index 1c55b8d3119..3f703f290e7 100644
--- a/examples/containers/server.c
+++ b/examples/containers/server.c
@@ -30,38 +30,108 @@
#include "contiki.h"
#include "contiki-lib.h"
#include "contiki-net.h"
-#include "net/uip.h"
+#include "net/ip/uip.h"
#include "net/rpl/rpl.h"
#include "net/rime/rimeaddr.h"
#include "net/netstack.h"
#include "dev/button-sensor.h"
#include "dev/serial-line.h"
-#if CONTIKI_TARGET_Z1
-#include "dev/uart0.h"
-#else
-#include "dev/uart1.h"
-#endif
+//#if CONTIKI_TARGET_Z1
+//#include "dev/uart0.h"
+//#else
+//#include "dev/uart1.h"
+//#endif
#include
#include
#include
#include
#include "collect-common.h"
#include "collect-view.h"
+#include "common-hdr.h"
+#include "udp-app.h"
-#define DEBUG DEBUG_NONE
-#include "net/uip-debug.h"
+#define DEBUG DEBUG_PRINT
+#include "net/ip/uip-debug.h"
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
-#define UDP_CLIENT_PORT 8775
-#define UDP_SERVER_PORT 5688
+#define UDP_CLIENT_PORT 8765
+#define UDP_SERVER_PORT 5678
+
+#define UDP_EXAMPLE_ID 190
static struct uip_udp_conn *server_conn;
PROCESS(udp_server_process, "UDP server process");
AUTOSTART_PROCESSES(&udp_server_process,&collect_common_process);
+
+#define MAX_NODES 1000
+
+ #if 0
+ typedef struct _dpkt_stat_
+ {
+ uip_ipaddr_t ip;
+ uint32_t lastseq;
+ uint32_t dropcnt;
+ uint32_t unordered;
+ uint32_t rcvcnt;
+ uint32_t dupcnt;
+ long leastLatency;
+ }dpkt_stat_t;
+ #endif
+
+ dpkt_stat_t g_dstats[MAX_NODES];
+ uint32_t g_ds_cnt;
+
+
+ dpkt_stat_t *get_dpkt_stat(uip_ipaddr_t *srcip)
+ {
+ int i;
+ dpkt_stat_t *ds;
+
+ for(i=0;iip)) {
+ return ds;
+ }
+ }
+ return NULL;
+ }
+
+ long dpkt_latency_time(struct timeval *tv)
+
+ {
+ long duration=0;
+ long sentTime=0;
+ long recvTime=0;
+ struct timeval curTime;
+ gettimeofday(&curTime, NULL);
+
+
+ sentTime = tv->tv_sec * 1000000;
+ sentTime += tv->tv_usec;
+
+ recvTime = curTime.tv_sec * 1000000;
+ recvTime += curTime.tv_usec;
+
+ if (recvTime > sentTime){
+ duration = recvTime-sentTime;
+ }
+
+ #if 0
+ if (curTime.tv_sec > tv->tv_sec){
+ duration = (curTime.tv_sec - tv->tv_sec) * 1000000;
+ }
+
+ if (curTime.tv_usec > tv->tv_usec){
+ duration += (curTime.tv_usec - tv->tv_usec);
+ }
+ #endif
+
+ return duration;
+ }
/*---------------------------------------------------------------------------*/
void
collect_common_set_sink(void)
@@ -83,11 +153,11 @@ collect_common_send(void)
void
collect_common_net_init(void)
{
-#if CONTIKI_TARGET_Z1
+/*#if CONTIKI_TARGET_Z1
uart0_set_input(serial_line_input_byte);
#else
uart1_set_input(serial_line_input_byte);
-#endif
+#endif */
serial_line_init();
PRINTF("I am sink!\n");
@@ -96,20 +166,66 @@ collect_common_net_init(void)
static void
tcpip_handler(void)
{
- uint8_t *appdata;
- rimeaddr_t sender;
- uint8_t seqno;
- uint8_t hops;
-
- if(uip_newdata()) {
- appdata = (uint8_t *)uip_appdata;
- sender.u8[0] = UIP_IP_BUF->srcipaddr.u8[15];
- sender.u8[1] = UIP_IP_BUF->srcipaddr.u8[14];
- seqno = *appdata;
- hops = uip_ds6_if.cur_hop_limit - UIP_IP_BUF->ttl + 1;
- collect_common_recv(&sender, seqno, hops,
- appdata + 2, uip_datalen() - 2);
+ dpkt_t *pkt;
+ dpkt_stat_t *ds;
+ long curpktlatency;
+
+ if(!uip_newdata()) {
+ return;
}
+
+ pkt = (dpkt_t *)uip_appdata;
+ ds = get_dpkt_stat(&(UIP_IP_BUF->srcipaddr));
+ if(!ds) {
+ if(g_ds_cnt>=MAX_NODES) {
+ printf("dstats exceeded!\n");
+ return;
+ }
+
+ ds = &g_dstats[g_ds_cnt++];
+ memset(ds, 0, sizeof(dpkt_stat_t));
+ ds->ip = UIP_IP_BUF->srcipaddr;
+ }
+
+ if (!ds->lastseq){
+ ds->lastseq = pkt->seq;
+ ds->rcvcnt++;
+ ds->leastLatency = ds->maxLatency = curpktlatency = dpkt_latency_time(&(pkt->sendTime));
+ goto SEND_REPLY;
+ }
+
+ if (pkt->seq == ds->lastseq){
+ ds->dupcnt++;
+ }
+ else if(pkt->seq < ds->lastseq) {
+ ds->unordered++;
+ ds->rcvcnt++;
+ }
+ else{
+ ds->lastseq = pkt->seq;
+ ds->rcvcnt++;
+ }
+
+ curpktlatency = dpkt_latency_time(&(pkt->sendTime));
+ if (curpktlatency < ds->leastLatency){
+ ds->leastLatency = curpktlatency;
+ }
+
+ if (curpktlatency > ds->maxLatency){
+ ds->maxLatency = curpktlatency;
+ }
+
+ SEND_REPLY:
+ PRINTF("DATA Received from [%d] with seq[%d] in duration[%ld mus] min duration[%ld mus] pkt drop[%u]\n",
+ ds->ip.u8[sizeof(ds->ip.u8) - 1], pkt->seq, curpktlatency, ds->leastLatency, (ds->lastseq - ds->rcvcnt));
+
+#if SERVER_REPLY
+ PRINTF("DATA sending reply\n");
+ uip_ipaddr_copy(&server_conn->ripaddr, &UIP_IP_BUF->srcipaddr);
+ //uip_udp_packet_send(server_conn, "Reply", sizeof("Reply"));
+ uip_udp_packet_send(server_conn, (unsigned char *)pkt, sizeof(dpkt_t));
+ uip_create_unspecified(&server_conn->ripaddr);
+#endif
}
/*---------------------------------------------------------------------------*/
static void
@@ -146,17 +262,38 @@ PROCESS_THREAD(udp_server_process, ev, data)
PRINTF("UDP server started\n");
#if UIP_CONF_ROUTER
- uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 1);
-
+/* The choice of server address determines its 6LoWPAN header compression.
+ * Obviously the choice made here must also be selected in udp-client.c.
+ *
+ * For correct Wireshark decoding using a sniffer, add the /64 prefix to the
+ * 6LowPAN protocol preferences,
+ * e.g. set Context 0 to fd00::. At present Wireshark copies Context/128 and
+ * then overwrites it.
+ * (Setting Context 0 to fd00::1111:2222:3333:4444 will report a 16 bit
+ * compressed address of fd00::1111:22ff:fe33:xxxx)
+ * Note Wireshark's IPCMV6 checksum verification depends on the correct
+ * uncompressed addresses.
+ */
+
+#if 0
+/* Mode 1 - 64 bits inline */
+ uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 1);
+#elif 1
+/* Mode 2 - 16 bits inline */
+ uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0x00ff, 0xfe00, 1);
+#else
+/* Mode 3 - derived from link local (MAC) address */
+ uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0);
+ uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr);
+#endif
- /* uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); */
uip_ds6_addr_add(&ipaddr, 0, ADDR_MANUAL);
root_if = uip_ds6_addr_lookup(&ipaddr);
if(root_if != NULL) {
rpl_dag_t *dag;
dag = rpl_set_root(RPL_DEFAULT_INSTANCE,(uip_ip6addr_t *)&ipaddr);
- uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0);
- //rpl_set_prefix(dag, &ipaddr, 64);
+ uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0);
+ rpl_set_prefix(dag, &ipaddr, 64);
PRINTF("created a new RPL dag\n");
} else {
PRINTF("failed to create a new RPL DAG\n");
@@ -170,6 +307,10 @@ PROCESS_THREAD(udp_server_process, ev, data)
NETSTACK_RDC.off(1);
server_conn = udp_new(NULL, UIP_HTONS(UDP_CLIENT_PORT), NULL);
+if(server_conn == NULL) {
+ PRINTF("No UDP connection available, exiting the process!\n");
+ PROCESS_EXIT();
+ }
udp_bind(server_conn, UIP_HTONS(UDP_SERVER_PORT));
PRINTF("Created a server connection with remote address ");
@@ -191,3 +332,39 @@ PROCESS_THREAD(udp_server_process, ev, data)
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
+
+ void start_udp_process()
+ {
+ return;
+ }
+ /*
+ uint32_t lastseq;
+ uint32_t dropcnt;
+ uint32_t unordered;
+ uint32_t rcvcnt;
+ uint32_t dupcnt;
+ */
+ void udp_get_app_stat(udpapp_stat_t *appstat)
+ {
+ unsigned int s = 0;
+ unsigned int r = 0;
+ unsigned int d = 0;
+ unsigned int i = 0;
+
+ PRINTF("Stats Called on BR\n");
+ dpkt_stat_t *ds;
+ for(i=0;ircvcnt){
+ continue;
+ }
+
+ s += ds->lastseq;
+ r += ds->rcvcnt;
+ d += ds->dupcnt;
+ }
+
+ appstat->totalpktsent = s;
+ appstat->totalpktrecvd = r;
+ appstat->totalduppkt = d;
+ }
From c8a0bc76275c2a6d07aa65326f9aad794a9ff11b Mon Sep 17 00:00:00 2001
From: weld10 <50168266+Amrican10@users.noreply.github.com>
Date: Sat, 1 Aug 2020 17:22:58 +0200
Subject: [PATCH 14/19] Update rpl-icmp6.c
---
core/net/rpl/rpl-icmp6.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c
index 9ee1aa549b1..39837d48d01 100755
--- a/core/net/rpl/rpl-icmp6.c
+++ b/core/net/rpl/rpl-icmp6.c
@@ -332,6 +332,11 @@ void RPL_DEBUG_DAO_OUTPUT(rpl_parent_t *);
static uint8_t dao_sequence = RPL_LOLLIPOP_INIT;
+uint8_t rpl_leaf = RPL_LEAF_ONLY;
+uint8_t leaf_dio = 0;
+
+extern rpl_of_t RPL_OF;
+
#if RPL_WITH_DCO
uint8_t path_sequence = RPL_LOLLIPOP_INIT;
static uint8_t dco_sequence = RPL_LOLLIPOP_INIT;
From 1b96091703b58704f5f0413296e58603cac64c69 Mon Sep 17 00:00:00 2001
From: weld10 <50168266+Amrican10@users.noreply.github.com>
Date: Sat, 1 Aug 2020 17:25:12 +0200
Subject: [PATCH 15/19] Update rpl-timers.c
---
core/net/rpl/rpl-timers.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/core/net/rpl/rpl-timers.c b/core/net/rpl/rpl-timers.c
index 88c98353def..b9420f94836 100755
--- a/core/net/rpl/rpl-timers.c
+++ b/core/net/rpl/rpl-timers.c
@@ -77,6 +77,8 @@ static uint16_t next_dis;
/* dio_send_ok is true if the node is ready to send DIOs */
static uint8_t dio_send_ok;
+extern uint8_t rpl_leaf;
+
/*---------------------------------------------------------------------------*/
static void
handle_periodic_timer(void *ptr)
From 5e684776f543b30db5b4227d32ba765b8a4e7370 Mon Sep 17 00:00:00 2001
From: weld10 <50168266+Amrican10@users.noreply.github.com>
Date: Sat, 1 Aug 2020 17:26:02 +0200
Subject: [PATCH 16/19] Update rpl.c
---
core/net/rpl/rpl.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/core/net/rpl/rpl.c b/core/net/rpl/rpl.c
index b601a71da6c..b66ebb8eceb 100755
--- a/core/net/rpl/rpl.c
+++ b/core/net/rpl/rpl.c
@@ -266,7 +266,7 @@ rpl_link_neighbor_callback(const linkaddr_t *addr, int status, int numtx)
if(parent != NULL) {
/* Trigger DAG rank recalculation. */
PRINTF("RPL: rpl_link_neighbor_callback triggering update\n");
- parent->flags |= RPL_PARENT_FLAG_UPDATED;
+ parent->updated = 1;
}
}
}
@@ -293,7 +293,7 @@ rpl_ipv6_neighbor_callback(uip_ds6_nbr_t *nbr)
p->rank = INFINITE_RANK;
/* Trigger DAG rank recalculation. */
PRINTF("RPL: rpl_ipv6_neighbor_callback infinite rank\n");
- p->flags |= RPL_PARENT_FLAG_UPDATED;
+ p->updated = 1;
}
}
}
From 88a67b2eba7191744d43099097c7e8da1c1746a5 Mon Sep 17 00:00:00 2001
From: weld10 <50168266+Amrican10@users.noreply.github.com>
Date: Sat, 1 Aug 2020 17:26:50 +0200
Subject: [PATCH 17/19] Update rpl.h
---
core/net/rpl/rpl.h | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/core/net/rpl/rpl.h b/core/net/rpl/rpl.h
index 5179ed3b96b..903d07b2df2 100755
--- a/core/net/rpl/rpl.h
+++ b/core/net/rpl/rpl.h
@@ -45,6 +45,14 @@
#include "net/ip/uip.h"
#include "net/ipv6/uip-ds6.h"
#include "sys/ctimer.h"
+
+struct rpl_metric_object_energy {
+ uint8_t flags;
+ uint8_t energy_est;
+};
+
+typedef struct rpl_metric_object_energy rpl_metric_object_energy_t;
+
#ifdef USE_METRIC_CONTAINERS
#include "rpl-metrics-data.h"
#endif /* USE_METRIC_CONTAINERS */
@@ -110,10 +118,10 @@ typedef uint16_t rpl_ocp_t;
#define RPL_OCP_OF0 0
#define RPL_OCP_MRHOF 1
-struct rpl_metric_object_energy {
+/*struct rpl_metric_object_energy {
uint8_t flags;
uint8_t energy_est;
-};
+};*/
#ifndef USE_METRIC_CONTAINERS
/* Logical representation of a DAG Metric Container. */
@@ -154,9 +162,10 @@ struct rpl_dag;
#ifdef RPL_DAG_MC_USE_LC
uint16_t lc;
#endif /* RPL_DAG_MC_USE_LC */
-
+ uint8_t link_metric;
uint8_t dtsn;
uint8_t updated;
+ uint8_t flags;
};
typedef struct rpl_parent rpl_parent_t;
/*---------------------------------------------------------------------------*/
@@ -337,7 +346,7 @@ const linkaddr_t *rpl_get_parent_lladdr(rpl_parent_t *p);
uip_ipaddr_t *rpl_get_parent_ipaddr(rpl_parent_t *nbr);
rpl_parent_t *rpl_get_parent(uip_lladdr_t *addr);
rpl_rank_t rpl_get_parent_rank(uip_lladdr_t *addr);
-uint16_t rpl_get_parent_link_metric(uip_lladdr_t *addr);
+
void rpl_dag_init(void);
uip_ds6_nbr_t *rpl_get_nbr(rpl_parent_t *parent);
void rpl_print_neighbor_list(void);
From eeced68fbce5522d7a1b122206efaa6ff4f76388 Mon Sep 17 00:00:00 2001
From: weld10 <50168266+Amrican10@users.noreply.github.com>
Date: Sat, 1 Aug 2020 17:29:26 +0200
Subject: [PATCH 18/19] Create udp-app.h
---
examples/containers/udp-app.h | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
create mode 100644 examples/containers/udp-app.h
diff --git a/examples/containers/udp-app.h b/examples/containers/udp-app.h
new file mode 100644
index 00000000000..eb45834fc5b
--- /dev/null
+++ b/examples/containers/udp-app.h
@@ -0,0 +1,17 @@
+#ifndef __UDP_APP_H__
+
+#include "contiki.h"
+typedef struct _udpapp_stat{
+ unsigned int totalpktsent; /*Requests*/
+ unsigned int totalpktrecvd; /*Request/response received*/
+ unsigned int totalduppkt; /*Duplicate request/response*/
+ long minroudtriptime;
+ long maxroundtriptime;
+ long minupwardtime;
+ long maxupwardtime;
+}udpapp_stat_t;
+
+void start_udp_process();
+void udp_get_app_stat(udpapp_stat_t *);
+
+#endif /*__UDP_APP_H__*/
From 28107e68c409f5f18d5b9f7b2a7f96fbcb9066fd Mon Sep 17 00:00:00 2001
From: weld10 <50168266+Amrican10@users.noreply.github.com>
Date: Sat, 1 Aug 2020 17:30:31 +0200
Subject: [PATCH 19/19] Create common-hdr.h
---
examples/containers/common-hdr.h | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
create mode 100644 examples/containers/common-hdr.h
diff --git a/examples/containers/common-hdr.h b/examples/containers/common-hdr.h
new file mode 100644
index 00000000000..990bc566984
--- /dev/null
+++ b/examples/containers/common-hdr.h
@@ -0,0 +1,27 @@
+#ifndef _COMMON_HDR_H_
+#define _COMMON_HDR_H_
+
+#include
+#include
+#include
+typedef struct _dpkt_
+{
+ uint32_t seq;
+ struct timeval sendTime;
+ uint8_t buflen;
+ uint8_t buf[1];
+}dpkt_t;
+
+typedef struct _dpkt_stat_
+{
+ uip_ipaddr_t ip;
+ uint32_t lastseq;
+ uint32_t dropcnt;
+ uint32_t unordered;
+ uint32_t rcvcnt;
+ uint32_t dupcnt;
+ long leastLatency;
+ long maxLatency;
+}dpkt_stat_t;
+
+#endif // _COMMON_HDR_H_