From 5c52e1ce2e2ba6cb8b7c0622f3cd136a7d15f291 Mon Sep 17 00:00:00 2001 From: Oliver Hahm Date: Sat, 22 Jun 2013 05:11:53 +0200 Subject: [PATCH] coding conventions for most of system libraries --- sys/auto_init/auto_init.c | 5 +- sys/chardev_thread.c | 43 +- sys/config/config.c | 4 +- sys/include/board_uart0.h | 2 +- sys/include/chardev_thread.h | 2 +- sys/include/ping.h | 20 +- sys/include/posix_io.h | 8 +- sys/include/ps.h | 4 +- sys/include/radio/radio.h | 91 +- sys/include/radio/types.h | 75 +- sys/include/shell.h | 12 +- sys/include/shell_commands.h | 2 +- sys/include/timex.h | 4 +- sys/include/transceiver.h | 4 +- sys/include/vtimer.h | 12 +- sys/net/mm/mmr.c | 1184 +++++++------- sys/net/mm/mmr.h | 43 +- sys/net/mm/mmstack.c | 1058 ++++++------ sys/net/mm/mmstack.h | 17 +- sys/net/sixlowpan/bordermultiplex.c | 155 +- sys/net/sixlowpan/bordermultiplex.h | 28 +- sys/net/sixlowpan/flowcontrol.c | 133 +- sys/net/sixlowpan/flowcontrol.h | 26 +- sys/net/sixlowpan/ieee802154_frame.c | 220 +-- sys/net/sixlowpan/ieee802154_frame.h | 26 +- sys/net/sixlowpan/rpl/objective_functions.c | 3 +- sys/net/sixlowpan/rpl/of0.c | 99 +- sys/net/sixlowpan/rpl/rpl.c | 1632 ++++++++++--------- sys/net/sixlowpan/rpl/rpl.h | 22 +- sys/net/sixlowpan/rpl/rpl_dodag.c | 582 ++++--- sys/net/sixlowpan/rpl/rpl_dodag.h | 27 +- sys/net/sixlowpan/rpl/rpl_structs.h | 145 +- sys/net/sixlowpan/rpl/trickle.c | 342 ++-- sys/net/sixlowpan/rpl/trickle.h | 22 +- sys/net/sixlowpan/semaphore.c | 39 +- sys/net/sixlowpan/semaphore.h | 20 +- sys/net/sixlowpan/serialnumber.c | 91 +- sys/net/sixlowpan/sixlowborder.c | 156 +- sys/net/sixlowpan/sixlowborder.h | 20 +- sys/net/sixlowpan/sixlowip.c | 469 +++--- sys/net/sixlowpan/sixlowip.h | 60 +- sys/net/sixlowpan/sixlowmac.c | 138 +- sys/net/sixlowpan/sixlowmac.h | 24 +- sys/net/sixlowpan/sixlownd.c | 980 ++++++----- sys/net/sixlowpan/sixlownd.h | 100 +- sys/net/sixlowpan/sixlowpan.c | 1585 +++++++++--------- sys/net/sixlowpan/sixlowpan.h | 84 +- sys/posix/posix_io.c | 28 +- sys/ps/ps.c | 25 +- sys/shell/commands/sc_cc1100.c | 87 +- sys/shell/commands/sc_cc110x_ng.c | 68 +- sys/shell/commands/sc_disk.c | 89 +- sys/shell/commands/sc_id.c | 29 +- sys/shell/commands/sc_ltc4150.c | 27 +- sys/shell/commands/sc_ps.c | 20 +- sys/shell/commands/sc_rtc.c | 56 +- sys/shell/commands/sc_sht11.c | 60 +- sys/shell/commands/shell_commands.c | 49 +- sys/shell/shell.c | 145 +- sys/syslog/syslog-api.c | 75 +- sys/syslog/syslog-out.c | 173 +- sys/syslog/syslog.c | 283 ++-- sys/tracelog/tracelog.c | 267 +-- sys/transceiver/transceiver.c | 219 ++- sys/uart0/uart0.c | 20 +- sys/vtimer/vtimer.c | 141 +- 66 files changed, 6664 insertions(+), 5015 deletions(-) diff --git a/sys/auto_init/auto_init.c b/sys/auto_init/auto_init.c index 1fc2468c59..0136bcd94d 100644 --- a/sys/auto_init/auto_init.c +++ b/sys/auto_init/auto_init.c @@ -1,5 +1,5 @@ /** - * Auto initialization for used modules + * Auto initialization for used modules * * Copyright (C) 2013 INRIA. * @@ -27,7 +27,8 @@ extern int main(void); -void auto_init(void) { +void auto_init(void) +{ #ifdef MODULE_BOARD_DISPLAY extern void lcd_init(); lcd_init(); diff --git a/sys/chardev_thread.c b/sys/chardev_thread.c index de8c373a73..f274924e73 100644 --- a/sys/chardev_thread.c +++ b/sys/chardev_thread.c @@ -1,5 +1,5 @@ /** - * Character device messaging loop. + * Character device messaging loop. * * Copyright (C) 2013, INRIA. * @@ -28,12 +28,18 @@ //#define ENABLE_DEBUG #include -static int min(int a, int b) { - if (b>a) return a; - else return b; +static int min(int a, int b) +{ + if(b > a) { + return a; + } + else { + return b; + } } -void chardev_loop(ringbuffer_t *rb) { +void chardev_loop(ringbuffer_t *rb) +{ msg_t m; int pid = thread_getpid(); @@ -43,14 +49,15 @@ void chardev_loop(ringbuffer_t *rb) { puts("UART0 thread started."); - while (1) { + while(1) { msg_receive(&m); - if (m.sender_pid != pid) { + if(m.sender_pid != pid) { DEBUG("Receiving message from another thread\n"); - switch (m.type) { + + switch(m.type) { case OPEN: - if (reader_pid == -1) { + if(reader_pid == -1) { reader_pid = m.sender_pid; /* no error */ m.content.value = 0; @@ -58,10 +65,12 @@ void chardev_loop(ringbuffer_t *rb) { else { m.content.value = -EBUSY; } - msg_reply(&m,&m); + + msg_reply(&m, &m); break; + case READ: - if (m.sender_pid != reader_pid) { + if(m.sender_pid != reader_pid) { m.content.value = -EINVAL; r = NULL; msg_reply(&m, &m); @@ -69,9 +78,11 @@ void chardev_loop(ringbuffer_t *rb) { else { r = (struct posix_iop_t *)m.content.ptr; } + break; + case CLOSE: - if (m.sender_pid == reader_pid) { + if(m.sender_pid == reader_pid) { DEBUG("uart0_thread: closing file from %i\n", reader_pid); reader_pid = -1; r = NULL; @@ -80,15 +91,17 @@ void chardev_loop(ringbuffer_t *rb) { else { m.content.value = -EINVAL; } - msg_reply(&m,&m); + + msg_reply(&m, &m); break; + default: m.content.value = -EINVAL; msg_reply(&m, &m); } } - if (rb->avail && (r != NULL)) { + if(rb->avail && (r != NULL)) { int state = disableIRQ(); int nbytes = min(r->nbytes, rb->avail); DEBUG("uart0_thread [%i]: sending %i bytes received from %i to pid %i\n", pid, nbytes, m.sender_pid, reader_pid); @@ -97,7 +110,7 @@ void chardev_loop(ringbuffer_t *rb) { m.sender_pid = reader_pid; m.type = OPEN; - m.content.ptr = (char*)r; + m.content.ptr = (char *)r; msg_reply(&m, &m); diff --git a/sys/config/config.c b/sys/config/config.c index bb894b1c07..67330b3928 100644 --- a/sys/config/config.c +++ b/sys/config/config.c @@ -1,5 +1,5 @@ /** - * System wide configuration struct. + * System wide configuration struct. * * Copyright (C) 2013 INRIA. * @@ -10,7 +10,7 @@ * @ingroup config * @{ * @file config_c - * @brief Provides system configuration struct with default values. + * @brief Provides system configuration struct with default values. * @author Oliver Hahm * @} */ diff --git a/sys/include/board_uart0.h b/sys/include/board_uart0.h index d38c22c75b..1fa131d2f9 100644 --- a/sys/include/board_uart0.h +++ b/sys/include/board_uart0.h @@ -1,5 +1,5 @@ #ifndef __BOARD_UART0_H -#define __BOARD_UART0_H +#define __BOARD_UART0_H extern int uart0_handler_pid; diff --git a/sys/include/chardev_thread.h b/sys/include/chardev_thread.h index bb811bddde..7615abfe9e 100644 --- a/sys/include/chardev_thread.h +++ b/sys/include/chardev_thread.h @@ -1,5 +1,5 @@ #ifndef __CHARDEV_THREAD_H -#define __CHARDEV_THREAD_H +#define __CHARDEV_THREAD_H #include diff --git a/sys/include/ping.h b/sys/include/ping.h index be73f81074..7f51fd6666 100644 --- a/sys/include/ping.h +++ b/sys/include/ping.h @@ -8,18 +8,18 @@ void print_success(void); void print_failed(void); void gpio_n_timer_init(void); void adjust_timer(void); -static void ping_handler(void *payload, int payload_size, - packet_info_t *packet_info); -static void pong_handler(void *payload, int payload_size, - packet_info_t *packet_info); +static void ping_handler(void *payload, int payload_size, + packet_info_t *packet_info); +static void pong_handler(void *payload, int payload_size, + packet_info_t *packet_info); void pong(uint16_t src); -typedef struct pong{ - int hopcount; - int ttl; - radio_address_t radio_address; +typedef struct pong { + int hopcount; + int ttl; + radio_address_t radio_address; } ping_r; -typedef struct ping_payload{ - char* payload; +typedef struct ping_payload { + char *payload; } ping_payload; diff --git a/sys/include/posix_io.h b/sys/include/posix_io.h index b39bdb3a38..bb9ad426a4 100644 --- a/sys/include/posix_io.h +++ b/sys/include/posix_io.h @@ -1,5 +1,5 @@ #ifndef __READ_H -#define __READ_H +#define __READ_H #define OPEN 0 #define CLOSE 1 @@ -12,8 +12,8 @@ struct posix_iop_t { }; int posix_open(int pid, int flags); -int posix_close(int pid); -int posix_read(int pid, char* buffer, int bufsize); -int posix_write(int pid, char* buffer, int bufsize); +int posix_close(int pid); +int posix_read(int pid, char *buffer, int bufsize); +int posix_write(int pid, char *buffer, int bufsize); #endif /* __READ_H */ diff --git a/sys/include/ps.h b/sys/include/ps.h index 25cc8cf18f..12093cbf55 100644 --- a/sys/include/ps.h +++ b/sys/include/ps.h @@ -1,7 +1,7 @@ #ifndef __PS_H -#define __PS_H +#define __PS_H void thread_print_all(void); -void _ps_handler(char*); +void _ps_handler(char *); #endif /* __PS_H */ diff --git a/sys/include/radio/radio.h b/sys/include/radio/radio.h index c45431ce59..7894fca014 100644 --- a/sys/include/radio/radio.h +++ b/sys/include/radio/radio.h @@ -1,28 +1,14 @@ -/****************************************************************************** -Copyright 2008-2009 , Freie Universitaet Berlin (FUB). All rights reserved. - -These sources were developed at the Freie Universitaet Berlin, Computer Systems -and Telematics group (http://cst.mi.fu-berlin.de). -------------------------------------------------------------------------------- -This file is part of RIOT. - -This program is free software: you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation, either version 3 of the License, or (at your option) any later -version. - -RIOT is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program. If not, see http://www.gnu.org/licenses/ . --------------------------------------------------------------------------------- -For further information and questions please use the web site - http://scatterweb.mi.fu-berlin.de -and the mailinglist (subscription via web site) - scatterweb@lists.spline.inf.fu-berlin.de -*******************************************************************************/ +/** + * Generic radio driver interface + * + * Copyright (C) 2008-2009 Freie Universitaet Berlin (FUB). + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + */ #ifndef RADIO_H_ #define RADIO_H_ @@ -58,41 +44,40 @@ and the mailinglist (subscription via web site) #define L1_PROTOCOL_CATCH_ALL (0xff) ///< Catch all protocol ID -enum layer_1_protocols -{ - LAYER_1_PROTOCOL_LL_ACK = 1, ///< Link-Level Acknowledgement (LL-ACK) - LAYER_1_PROTOCOL_MM = 2, ///< Micro Mesh network packet (MM) +enum layer_1_protocols { + LAYER_1_PROTOCOL_LL_ACK = 1, ///< Link-Level Acknowledgement (LL-ACK) + LAYER_1_PROTOCOL_MM = 2, ///< Micro Mesh network packet (MM) }; /** * Radio/MAC API. */ -typedef struct radio { - const char* name; - const radio_address_t broadcast_address; - const uint8_t output_power_max; - /** - * @return the average transmission duration of one packet - * in milliseconds, e.g. till ACK received. - */ - int (*get_avg_transmission_duration)(void); - radio_address_t (*get_address)(void); - bool (*set_address)(radio_address_t address); - bool (*set_output_power)(uint8_t pa_idx); - bool (*set_packet_monitor)(packet_monitor_t monitor); - /** - * @return -1 if an error occurs (e.g. handler table full) else >= 0. - */ - int (*set_packet_handler)(protocol_t protocol, packet_handler_t handler); - /** - * @return A negative value if operation failed; else the number of transmitted bytes. - */ - int (*send)(radio_address_t address, protocol_t protocol, int priority, char *payload, int payload_len); - void (*print_stats)(void); - void (*print_config)(void); +typedef struct { + const char *name; + const radio_address_t broadcast_address; + const uint8_t output_power_max; + /** + * @return the average transmission duration of one packet + * in milliseconds, e.g. till ACK received. + */ + int (*get_avg_transmission_duration)(void); + radio_address_t (*get_address)(void); + bool (*set_address)(radio_address_t address); + bool (*set_output_power)(uint8_t pa_idx); + bool (*set_packet_monitor)(packet_monitor_t monitor); + /** + * @return -1 if an error occurs (e.g. handler table full) else >= 0. + */ + int (*set_packet_handler)(protocol_t protocol, packet_handler_t handler); + /** + * @return A negative value if operation failed; else the number of transmitted bytes. + */ + int (*send)(radio_address_t address, protocol_t protocol, int priority, char *payload, int payload_len); + void (*print_stats)(void); + void (*print_config)(void); } radio_t; -extern const struct radio* feuerware_radios[FEUERWARE_CONF_NUM_RADIOS]; +extern const struct radio *feuerware_radios[FEUERWARE_CONF_NUM_RADIOS]; /** @} */ diff --git a/sys/include/radio/types.h b/sys/include/radio/types.h index a0d6b4c27d..efb4facfc8 100644 --- a/sys/include/radio/types.h +++ b/sys/include/radio/types.h @@ -1,28 +1,14 @@ -/****************************************************************************** -Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved. - -These sources were developed at the Freie Universitaet Berlin, Computer Systems -and Telematics group (http://cst.mi.fu-berlin.de). -------------------------------------------------------------------------------- -This file is part of RIOT. - -This program is free software: you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation, either version 3 of the License, or (at your option) any later -version. - -RIOT is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program. If not, see http://www.gnu.org/licenses/ . --------------------------------------------------------------------------------- -For further information and questions please use the web site - http://scatterweb.mi.fu-berlin.de -and the mailinglist (subscription via web site) - scatterweb@lists.spline.inf.fu-berlin.de -*******************************************************************************/ +/** + * Generic radio driver interface data structures and prototypes + * + * Copyright (C) 2009 Freie Universitaet Berlin (FUB). + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + */ #ifndef COMMONTYPES_H_ #define COMMONTYPES_H_ @@ -33,6 +19,7 @@ and the mailinglist (subscription via web site) * * @author Freie Universität Berlin, Computer Systems & Telematics * @author Thomas Hillebrandt + * @author Oliver Hahm * @version $Revision: 2061 $ * * @note $Id: common-types.h 2061 2010-04-01 12:13:22Z hillebra $ @@ -50,11 +37,10 @@ typedef uint16_t radio_address_t; ///< Radio layer address type /** * @brief Packet transmission priorities of various layers. */ -enum transmission_priorities -{ - PRIORITY_ALARM = 0, - PRIORITY_WARNING = 1, - PRIORITY_DATA = 2 +enum transmission_priorities { + PRIORITY_ALARM = 0, + PRIORITY_WARNING = 1, + PRIORITY_DATA = 2 }; /** @@ -62,23 +48,23 @@ enum transmission_priorities * This struct is passed along all receive functions of * all layers. Each layers fills in additional information. */ -typedef struct __attribute__ ((packed)) packet_info_t -{ - uint16_t source; ///< Net layer: source - uint16_t destination; ///< Net layer: destination - radio_address_t phy_src; ///< Radio layer: source - uint8_t rssi; ///< Radio layer: RSSI - uint8_t lqi; ///< Radio layer: LQI - uint8_t ttl; ///< Net layer: TTL - uint8_t tos; ///< Net layer: TOS - bool promiscuous; ///< Radio layer: whether network interface is in promiscuous mode +typedef struct __attribute__((packed)) packet_info_t { + uint16_t source; ///< Net layer: source + uint16_t destination; ///< Net layer: destination + radio_address_t phy_src; ///< Radio layer: source + uint8_t rssi; ///< Radio layer: RSSI + uint8_t lqi; ///< Radio layer: LQI + uint8_t ttl; ///< Net layer: TTL + uint8_t tos; ///< Net layer: TOS + bool promiscuous; ///< Radio layer: whether network interface is in promiscuous mode } packet_info_t; /** * @brief General link layer packet format */ -typedef struct __attribute__ ((packed)) { +typedef struct __attribute__((packed)) +{ uint8_t processing; ///< internal processing state uint16_t src; ///< Radio source address uint16_t dst; ///< Radio destination address @@ -87,7 +73,8 @@ typedef struct __attribute__ ((packed)) { timex_t toa; ///< Time of Arrival uint8_t length; ///< Length of payload uint8_t *data; ///< Payload -} radio_packet_t; +} +radio_packet_t; /** @@ -96,7 +83,7 @@ typedef struct __attribute__ ((packed)) { * @param [in] payload_size Size of the packet payload data in bytes * @param [in/out] packet_info Cross-layer meta data */ -typedef void (*packet_handler_t)(void* payload, int payload_size, packet_info_t* packet_info); +typedef void (*packet_handler_t)(void *payload, int payload_size, packet_info_t *packet_info); /** * Packet monitor of all layers. Normally there can be one packet @@ -107,6 +94,6 @@ typedef void (*packet_handler_t)(void* payload, int payload_size, packet_info_t* * @param protocol Protocol type of the packet payload data * @param packet_info Cross-layer meta data */ -typedef void (*packet_monitor_t)(void* payload, int payload_size, protocol_t protocol, packet_info_t* packet_info); +typedef void (*packet_monitor_t)(void *payload, int payload_size, protocol_t protocol, packet_info_t *packet_info); #endif /* COMMONTYPES_H_ */ diff --git a/sys/include/shell.h b/sys/include/shell.h index 00f34148b1..5f95f58c49 100644 --- a/sys/include/shell.h +++ b/sys/include/shell.h @@ -25,7 +25,7 @@ and the mailinglist (subscription via web site) *******************************************************************************/ #ifndef __SHELL_H -#define __SHELL_H +#define __SHELL_H /** * @defgroup shell Simple Shell Interpreter @@ -35,15 +35,15 @@ and the mailinglist (subscription via web site) //#include "hashtable.h" typedef struct shell_command_t { - char* name; - char* desc; - void (*handler)(char*); + char *name; + char *desc; + void (*handler)(char *); } shell_command_t; typedef struct shell_t { const shell_command_t *command_list; - int (*readchar)(void); - void (*put_char)(int); + int (*readchar)(void); + void (*put_char)(int); } shell_t; /** diff --git a/sys/include/shell_commands.h b/sys/include/shell_commands.h index 22efd8dfb9..563968e8e2 100644 --- a/sys/include/shell_commands.h +++ b/sys/include/shell_commands.h @@ -1,5 +1,5 @@ #ifndef __SHELL_COMMANDS_H -#define __SHELL_COMMANDS_H +#define __SHELL_COMMANDS_H #include diff --git a/sys/include/timex.h b/sys/include/timex.h index 424dc9b354..f18691a044 100644 --- a/sys/include/timex.h +++ b/sys/include/timex.h @@ -1,5 +1,5 @@ #ifndef __TIMEX_H -#define __TIMEX_H +#define __TIMEX_H #include @@ -9,7 +9,7 @@ typedef struct timex_t { } timex_t; /* a+b */ -timex_t timex_add(const timex_t a, const timex_t b); +timex_t timex_add(const timex_t a, const timex_t b); /* a-b*/ timex_t timex_sub(const timex_t a, const timex_t b); diff --git a/sys/include/transceiver.h b/sys/include/transceiver.h index 572d2162b1..210d57e55e 100644 --- a/sys/include/transceiver.h +++ b/sys/include/transceiver.h @@ -1,5 +1,5 @@ #ifndef TRANSCEIVER_H -#define TRANSCEIVER_H +#define TRANSCEIVER_H #include @@ -84,7 +84,7 @@ typedef struct { extern int transceiver_pid; /** - * @brief Initializes the transceiver module for certain transceiver types + * @brief Initializes the transceiver module for certain transceiver types * * @param transceivers Specifies all transceivers to init **/ diff --git a/sys/include/vtimer.h b/sys/include/vtimer.h index d25aa52d47..371cee9048 100644 --- a/sys/include/vtimer.h +++ b/sys/include/vtimer.h @@ -17,7 +17,7 @@ * Timer library header file. */ #ifndef __VTIMER_H -#define __VTIMER_H +#define __VTIMER_H #include "queue.h" #include "timex.h" @@ -34,8 +34,8 @@ typedef struct vtimer_t { queue_node_t queue_entry; timex_t absolute; - void(*action)(void*); - void* arg; + void(*action)(void *); + void *arg; unsigned int pid; } vtimer_t; @@ -43,7 +43,7 @@ typedef struct vtimer_t { * @brief Current system time * @return Time as timex_t since system boot */ -void vtimer_now(timex_t* out); +void vtimer_now(timex_t *out); /** * @brief Initializes the vtimer subsystem. To be called once at system initialization. Will be initialized by auto_init. @@ -54,7 +54,7 @@ int vtimer_init(void); /** * @brief will cause the calling thread to be suspended from excecution until the number of microseconds has elapsed - * @param[in] us number of microseconds + * @param[in] us number of microseconds * @return 0 on success, < 0 on error */ int vtimer_usleep(uint32_t us); @@ -94,6 +94,6 @@ int vtimer_remove(vtimer_t *t); /** * @brief Prints a vtimer_t */ -void vtimer_print(vtimer_t* t); +void vtimer_print(vtimer_t *t); #endif /* __VTIMER_H */ diff --git a/sys/net/mm/mmr.c b/sys/net/mm/mmr.c index 1bf3ae2f92..66a7058003 100644 --- a/sys/net/mm/mmr.c +++ b/sys/net/mm/mmr.c @@ -62,8 +62,8 @@ and the mailinglist (subscription via web site) #define RREQ_ID_SEQUENCE_NUMBER_START (1) #define RREQ_THRESHOLD (3) -#define RREQ_NONE (0xFF) // Send no RREQs for these messages, value - // must be greater than RREQ_THRESHOLD +#define RREQ_NONE (0xFF) /* Send no RREQs for these messages, value */ +/* must be greater than RREQ_THRESHOLD */ #define TTL_START (1) #define TTL_THRESHOLD (10) @@ -77,11 +77,10 @@ and the mailinglist (subscription via web site) #define MESSAGE_QUEUE_SIZE (20) -typedef struct message_queue_entry_t -{ - net_message_t message; - volatile uint32_t timestamp; - uint8_t retry_count; +typedef struct { + net_message_t message; + volatile uint32_t timestamp; + uint8_t retry_count; } message_queue_entry_t; static message_queue_entry_t message_queue[MESSAGE_QUEUE_SIZE]; @@ -91,7 +90,7 @@ static message_queue_entry_t message_queue[MESSAGE_QUEUE_SIZE]; /*---------------------------------------------------------------------------*/ static struct utimer ut; -static volatile bool rreq_to_active = false; // RREQ timeout active bit +static volatile bool rreq_to_active = false; /* RREQ timeout active bit */ static const char *rreq_timeout_process_name = "mmrd"; static uint16_t rreq_timeout_process_pid; static void rreq_timeout_process(void); @@ -101,18 +100,17 @@ static void post_next_rreq_timeout(void); // Statistic data structures /*---------------------------------------------------------------------------*/ -typedef struct mmr_stat -{ - uint32_t rreq_originated; - uint32_t rrep_originated; - uint32_t rerr_originated; - uint32_t rreq_received; - uint32_t rrep_received; - uint32_t rerr_received; - uint32_t messages_no_route_found; // RREQ found no route - uint32_t messages_no_route_avail_on_forward; // Forwarding: no route in route table - uint32_t messages_broken_link_on_forward; // Forwarding: broken link detected - uint32_t rreq_duplicated; +typedef struct mmr_stat { + uint32_t rreq_originated; + uint32_t rrep_originated; + uint32_t rerr_originated; + uint32_t rreq_received; + uint32_t rrep_received; + uint32_t rerr_received; + uint32_t messages_no_route_found; /* RREQ found no route */ + uint32_t messages_no_route_avail_on_forward; /* Forwarding: no route in route table */ + uint32_t messages_broken_link_on_forward; /* Forwarding: broken link detected */ + uint32_t rreq_duplicated; } mmr_stat_t; static mmr_stat_t mmr_stats; @@ -126,7 +124,7 @@ static mmr_stat_t mmr_stats; */ static uint32_t rtc_now(void) { - return (uint32_t)(clock_get_systemtime()/1000); + return (uint32_t)(clock_get_systemtime() / 1000); } /*---------------------------------------------------------------------------*/ @@ -140,49 +138,61 @@ static uint32_t rtc_now(void) * @param length Length of address list * @param list Address list with route information */ -static void rt_extract_routes(uint16_t local_addr, uint8_t length, uint16_t* list) +static void rt_extract_routes(uint16_t local_addr, uint8_t length, uint16_t *list) { - DEBUG("call [%u]: rt_extract_routes\n", fk_thread->pid); - uint16_t net_id = NETWORK_ADDR_BC(list[0]); // BC address of source of RREQ - route_table_entry_t* rte = rt_lookup_route(net_id); // Should exist (preconfigured) - if (rte == NULL) { - DEBUG("exit [%u]: rt_extract_routes\n", fk_thread->pid); - return; // else exit here - } + DEBUG("call [%u]: rt_extract_routes\n", fk_thread->pid); + uint16_t net_id = NETWORK_ADDR_BC(list[0]); /* BC address of source of RREQ */ + route_table_entry_t *rte = rt_lookup_route(net_id); /* Should exist (preconfigured) */ - int i = 0; - while (i < length && list[i] != local_addr) i++; - if (i == length) { - DEBUG("exit [%u]: rt_extract_routes\n", fk_thread->pid); - return; - } + if(rte == NULL) { + DEBUG("exit [%u]: rt_extract_routes\n", fk_thread->pid); + return; /* else exit here */ + } - int pos = i; - int leftNeighbour = -1; - int rightNeighbour = -1; - if (pos > 0) - { - leftNeighbour = list[pos-1]; - } - if (pos+1 != length) - { - rightNeighbour = list[pos+1]; - } + int i = 0; - i = 0; - while (i < length) - { - uint16_t next = list[i]; - if (local_addr != next) - { - int distance = pos - i; - int router = leftNeighbour; - if (distance < 0) { router = rightNeighbour; distance *= -1; } - rt_add_route(next, (uint16_t)router, (uint8_t)distance, rte->interface_id); - } - i++; - } - DEBUG("exit [%u]: rt_extract_routes\n", fk_thread->pid); + while(i < length && list[i] != local_addr) { + i++; + } + + if(i == length) { + DEBUG("exit [%u]: rt_extract_routes\n", fk_thread->pid); + return; + } + + int pos = i; + int leftNeighbour = -1; + int rightNeighbour = -1; + + if(pos > 0) { + leftNeighbour = list[pos - 1]; + } + + if(pos + 1 != length) { + rightNeighbour = list[pos + 1]; + } + + i = 0; + + while(i < length) { + uint16_t next = list[i]; + + if(local_addr != next) { + int distance = pos - i; + int router = leftNeighbour; + + if(distance < 0) { + router = rightNeighbour; + distance *= -1; + } + + rt_add_route(next, (uint16_t)router, (uint8_t)distance, rte->interface_id); + } + + i++; + } + + DEBUG("exit [%u]: rt_extract_routes\n", fk_thread->pid); } /*---------------------------------------------------------------------------*/ @@ -197,60 +207,63 @@ static void rt_extract_routes(uint16_t local_addr, uint8_t length, uint16_t* lis * @return A pointer to a message queue entry or NULL if * message queue is full. */ -static message_queue_entry_t* mq_add(net_message_t* msg) +static message_queue_entry_t *mq_add(net_message_t *msg) { - DEBUG("call [%u]: mq_add\n", fk_thread->pid); + DEBUG("call [%u]: mq_add\n", fk_thread->pid); - // Holds eventually first active RREQ to same destination - message_queue_entry_t* pFirstFoundDup = NULL; + /* Holds eventually first active RREQ to same destination */ + message_queue_entry_t *pFirstFoundDup = NULL; - // Find the first active RREQ to this destination - int i; - for (i = 0; i < MESSAGE_QUEUE_SIZE; i++) - { - if (message_queue[i].timestamp != 0 && message_queue[i].message.destination == msg->destination && - message_queue[i].retry_count != RREQ_NONE) - { - DEBUG("%s FOUND Duplicated Request to %u.%u in route req queue\n",__FUNCTION__,(0xFF00&msg->destination)>>8,(0xFF&msg->destination)); + /* Find the first active RREQ to this destination */ + int i; - // Save the first found entry to modify later if insertion was successful - pFirstFoundDup = &message_queue[i]; - break; - } - } + for(i = 0; i < MESSAGE_QUEUE_SIZE; i++) { + if(message_queue[i].timestamp != 0 && + message_queue[i].message.destination == msg->destination && + message_queue[i].retry_count != RREQ_NONE) { + DEBUG("%s FOUND Duplicated Request to %u.%u in route req queue\n", + __FUNCTION__, (0xFF00 & msg->destination) >> 8, (0xFF & msg->destination)); - // If RREQ for same destination found then reset values - // even if the new message will get dropped later on because of - // limited queue space. Route to this destination gets queried - // again for sure so make new RREQ as soon as possible... - if (pFirstFoundDup != NULL) { - pFirstFoundDup->retry_count = 0; - pFirstFoundDup->timestamp = 1; - mmr_stats.rreq_duplicated++; - } + /* Save the first found entry to modify later if insertion was successful */ + pFirstFoundDup = &message_queue[i]; + break; + } + } - // Find free position to insert new message - for (i = 0; i < MESSAGE_QUEUE_SIZE; i++) - { - if (message_queue[i].timestamp == 0) - { - // Free position found, add entry - message_queue[i].message = *msg; - if (pFirstFoundDup != NULL) { - // There is already a RREQ for this destination, so don't generate a new one - message_queue[i].retry_count = RREQ_NONE; - } else { - // Set initial RREQ retry counter to zero - message_queue[i].retry_count = 0; - } - message_queue[i].timestamp = 1; - DEBUG("exit [%u]: mq_add\n", fk_thread->pid); - return &message_queue[i]; - } - } + /* If RREQ for same destination found then reset values + * even if the new message will get dropped later on because of + * limited queue space. Route to this destination gets queried + * again for sure so make new RREQ as soon as possible... */ + if(pFirstFoundDup != NULL) { + pFirstFoundDup->retry_count = 0; + pFirstFoundDup->timestamp = 1; + mmr_stats.rreq_duplicated++; + } - DEBUG("exit [%u]: mq_add\n", fk_thread->pid); - return NULL; + /* Find free position to insert new message */ + for(i = 0; i < MESSAGE_QUEUE_SIZE; i++) { + if(message_queue[i].timestamp == 0) { + /* Free position found, add entry */ + message_queue[i].message = *msg; + + if(pFirstFoundDup != NULL) { + /* There is already a RREQ for this destination, so don't + * generate a new one */ + message_queue[i].retry_count = RREQ_NONE; + } + else { + /* Set initial RREQ retry counter to zero */ + message_queue[i].retry_count = 0; + } + + message_queue[i].timestamp = 1; + DEBUG("exit [%u]: mq_add\n", fk_thread->pid); + return &message_queue[i]; + } + } + + DEBUG("exit [%u]: mq_add\n", fk_thread->pid); + return NULL; } /** @@ -262,17 +275,18 @@ static message_queue_entry_t* mq_add(net_message_t* msg) */ static int mq_msgs_for_destination(uint16_t dst) { - DEBUG("call [%u]: mq_msgs_for_destination\n", fk_thread->pid); - int i, dst_count = 0; - for (i = 0; i < MESSAGE_QUEUE_SIZE; i++) - { - if (message_queue[i].timestamp != 0 && message_queue[i].message.destination == dst) - { - dst_count++; - } - } - DEBUG("exit [%u]: mq_msgs_for_destination\n", fk_thread->pid); - return dst_count; + DEBUG("call [%u]: mq_msgs_for_destination\n", fk_thread->pid); + int i, dst_count = 0; + + for(i = 0; i < MESSAGE_QUEUE_SIZE; i++) { + if(message_queue[i].timestamp != 0 && + message_queue[i].message.destination == dst) { + dst_count++; + } + } + + DEBUG("exit [%u]: mq_msgs_for_destination\n", fk_thread->pid); + return dst_count; } /** @@ -282,16 +296,17 @@ static int mq_msgs_for_destination(uint16_t dst) */ static void mq_remove_msgs_for_destination(uint16_t dst) { - DEBUG("call [%u]: mq_remove_msgs_for_destination\n", fk_thread->pid); - int i; - for (i = 0; i < MESSAGE_QUEUE_SIZE; i++) - { - if (message_queue[i].timestamp != 0 && message_queue[i].message.destination == dst) - { - message_queue[i].timestamp = 0; - } - } - DEBUG("exit [%u]: mq_remove_msgs_for_destination\n", fk_thread->pid); + DEBUG("call [%u]: mq_remove_msgs_for_destination\n", fk_thread->pid); + int i; + + for(i = 0; i < MESSAGE_QUEUE_SIZE; i++) { + if(message_queue[i].timestamp != 0 && + message_queue[i].message.destination == dst) { + message_queue[i].timestamp = 0; + } + } + + DEBUG("exit [%u]: mq_remove_msgs_for_destination\n", fk_thread->pid); } /** @@ -301,44 +316,53 @@ static void mq_remove_msgs_for_destination(uint16_t dst) */ static void mq_dequeue_and_send(uint16_t dst) { - int i; - DEBUG("call [%u]: mq_dequeue_and_send\n", fk_thread->pid); + int i; + DEBUG("call [%u]: mq_dequeue_and_send\n", fk_thread->pid); - // Stop any pending RREQ-Timeout, it's possibly handled now - rreq_to_active = false; - utimer_remove(&ut); + /* Stop any pending RREQ-Timeout, it's possibly handled now */ + rreq_to_active = false; + utimer_remove(&ut); - // Prioritize packets for given destination, route entry should exist - route_table_entry_t* rte = rt_lookup_route(dst); - if (rte != NULL) - { - for (i = 0; i < MESSAGE_QUEUE_SIZE; i++) - { - if (message_queue[i].timestamp != 0 && message_queue[i].message.destination == dst) - { - bool res = net_enqueue_for_transmission(&message_queue[i].message, rte->interface_id, rte->gateway, true); - if (res) message_queue[i].timestamp = 0; - } - } - } - // Now all other packets - for (i = 0; i < MESSAGE_QUEUE_SIZE; i++) - { - if (message_queue[i].timestamp != 0 && message_queue[i].message.destination != dst) - { - route_table_entry_t* rte = rt_lookup_route(message_queue[i].message.destination); - if (rte != NULL) - { - bool res = net_enqueue_for_transmission(&message_queue[i].message, rte->interface_id, rte->gateway, true); - if (res) message_queue[i].timestamp = 0; - } - } - } + /* Prioritize packets for given destination, route entry should exist */ + route_table_entry_t *rte = rt_lookup_route(dst); - // This function was triggered either by RREP packet or RREQ-Timeout. - // So update or set new RREQ-Timeout for other packets in queue. - post_next_rreq_timeout(); - DEBUG("exit [%u]: mq_dequeue_and_send\n", fk_thread->pid); + if(rte != NULL) { + for(i = 0; i < MESSAGE_QUEUE_SIZE; i++) { + if(message_queue[i].timestamp != 0 && + message_queue[i].message.destination == dst) { + bool res = net_enqueue_for_transmission(&message_queue[i].message, + rte->interface_id, + rte->gateway, true); + + if(res) { + message_queue[i].timestamp = 0; + } + } + } + } + + /* Now all other packets */ + for(i = 0; i < MESSAGE_QUEUE_SIZE; i++) { + if(message_queue[i].timestamp != 0 && + message_queue[i].message.destination != dst) { + route_table_entry_t *rte = rt_lookup_route(message_queue[i].message.destination); + + if(rte != NULL) { + bool res = net_enqueue_for_transmission(&message_queue[i].message, + rte->interface_id, + rte->gateway, true); + + if(res) { + message_queue[i].timestamp = 0; + } + } + } + } + + /* This function was triggered either by RREP packet or RREQ-Timeout. */ + /* So update or set new RREQ-Timeout for other packets in queue. */ + post_next_rreq_timeout(); + DEBUG("exit [%u]: mq_dequeue_and_send\n", fk_thread->pid); } /*---------------------------------------------------------------------------*/ @@ -347,10 +371,10 @@ static void mq_dequeue_and_send(uint16_t dst) void mmr_init(void) { - rt_init(); - memset(message_queue, 0, sizeof(message_queue_entry_t) * MESSAGE_QUEUE_SIZE); - rreq_timeout_process_pid = thread_create(2500, PRIORITY_MMREQ, CREATE_STACKTEST, - rreq_timeout_process, rreq_timeout_process_name); + rt_init(); + memset(message_queue, 0, sizeof(message_queue_entry_t) * MESSAGE_QUEUE_SIZE); + rreq_timeout_process_pid = thread_create(2500, PRIORITY_MMREQ, CREATE_STACKTEST, + rreq_timeout_process, rreq_timeout_process_name); } /*---------------------------------------------------------------------------*/ @@ -364,14 +388,16 @@ void mmr_init(void) * * @return true if the net message contains a RERR; false otherwise. */ -static bool is_route_error(net_message_t* msg) +static bool is_route_error(net_message_t *msg) { - if (msg->protocol == LAYER_2_PROTOCOL_MMR) - { - // First byte in {RREQ, RREP, RERR} is always type - if (msg->payload[0] == MMR_TYPE_RERR) return true; - } - return false; + if(msg->protocol == LAYER_2_PROTOCOL_MMR) { + /* First byte in {RREQ, RREP, RERR} is always type */ + if(msg->payload[0] == MMR_TYPE_RERR) { + return true; + } + } + + return false; } /** @@ -379,37 +405,38 @@ static bool is_route_error(net_message_t* msg) * * @param rreq_msg Corresponding route request message */ -static void generate_route_reply_message(mmr_rreq_message_t* rreq_msg) +static void generate_route_reply_message(mmr_rreq_message_t *rreq_msg) { - DEBUG("call [%u]: generate_route_reply_message\n", fk_thread->pid); - // Create RREP message - mmr_rrep_message_t rrep_msg; - rrep_msg.type = MMR_TYPE_RREP; - rrep_msg.length = rreq_msg->length; - rrep_msg.destination = rreq_msg->source; - rrep_msg.source = rreq_msg->destination; - memcpy(rrep_msg.address, rreq_msg->address, rreq_msg->length * sizeof(uint16_t)); + DEBUG("call [%u]: generate_route_reply_message\n", fk_thread->pid); + /* Create RREP message */ + mmr_rrep_message_t rrep_msg; + rrep_msg.type = MMR_TYPE_RREP; + rrep_msg.length = rreq_msg->length; + rrep_msg.destination = rreq_msg->source; + rrep_msg.source = rreq_msg->destination; + memcpy(rrep_msg.address, rreq_msg->address, rreq_msg->length * sizeof(uint16_t)); - // Create MMR message containing the RREP message - net_message_t net_msg; - net_msg.protocol = LAYER_2_PROTOCOL_MMR; - net_msg.flags_tos = PRIORITY_ALARM; - net_msg.seq_clr_id = 0; - net_msg.ttl = TTL_THRESHOLD; - net_msg.source = rrep_msg.source; - net_msg.destination = rrep_msg.destination; - memcpy(net_msg.payload, (void*)&rrep_msg, sizeof(mmr_rrep_message_t)); + /* Create MMR message containing the RREP message */ + net_message_t net_msg; + net_msg.protocol = LAYER_2_PROTOCOL_MMR; + net_msg.flags_tos = PRIORITY_ALARM; + net_msg.seq_clr_id = 0; + net_msg.ttl = TTL_THRESHOLD; + net_msg.source = rrep_msg.source; + net_msg.destination = rrep_msg.destination; + memcpy(net_msg.payload, (void *)&rrep_msg, sizeof(mmr_rrep_message_t)); - // Source address must exist in route table to find correct - // interface id and next hop (should be created by RREQ) - route_table_entry_t* rte = rt_lookup_route(net_msg.destination); - if (rte != NULL) - { - // Send message to next hop - mmr_stats.rrep_originated++; - net_enqueue_for_transmission(&net_msg, rte->interface_id, rte->gateway, true); - } - DEBUG("exit [%u]: generate_route_reply_message\n", fk_thread->pid); + /* Source address must exist in route table to find correct */ + /* interface id and next hop (should be created by RREQ) */ + route_table_entry_t *rte = rt_lookup_route(net_msg.destination); + + if(rte != NULL) { + /* Send message to next hop */ + mmr_stats.rrep_originated++; + net_enqueue_for_transmission(&net_msg, rte->interface_id, rte->gateway, true); + } + + DEBUG("exit [%u]: generate_route_reply_message\n", fk_thread->pid); } /** @@ -423,27 +450,27 @@ static void generate_route_reply_message(mmr_rreq_message_t* rreq_msg) */ static void generate_route_error_message(uint16_t dst, uint16_t gateway, int intf, uint8_t type, uint16_t type_data) { - DEBUG("call [%u]: generate_route_error_message\n", fk_thread->pid); - // Define RERR message - mmr_rerr_message_t rerr_msg; - rerr_msg.type = MMR_TYPE_RERR; - rerr_msg.error_type = type; - rerr_msg.type_specific_info = type_data; + DEBUG("call [%u]: generate_route_error_message\n", fk_thread->pid); + /* Define RERR message */ + mmr_rerr_message_t rerr_msg; + rerr_msg.type = MMR_TYPE_RERR; + rerr_msg.error_type = type; + rerr_msg.type_specific_info = type_data; - // Wrap RERR message in net message - net_message_t net_msg; - net_msg.protocol = LAYER_2_PROTOCOL_MMR; - net_msg.flags_tos = PRIORITY_DATA; - net_msg.seq_clr_id = 0; - net_msg.ttl = TTL_THRESHOLD; - net_msg.source = net_get_address_in_subnet(dst); - net_msg.destination = dst; - memcpy(net_msg.payload, (void*)&rerr_msg, sizeof(mmr_rerr_message_t)); + /* Wrap RERR message in net message */ + net_message_t net_msg; + net_msg.protocol = LAYER_2_PROTOCOL_MMR; + net_msg.flags_tos = PRIORITY_DATA; + net_msg.seq_clr_id = 0; + net_msg.ttl = TTL_THRESHOLD; + net_msg.source = net_get_address_in_subnet(dst); + net_msg.destination = dst; + memcpy(net_msg.payload, (void *)&rerr_msg, sizeof(mmr_rerr_message_t)); - // Send message to next hop - mmr_stats.rerr_originated++; - net_enqueue_for_transmission(&net_msg, intf, gateway, true); - DEBUG("exit [%u]: generate_route_error_message\n", fk_thread->pid); + /* Send message to next hop */ + mmr_stats.rerr_originated++; + net_enqueue_for_transmission(&net_msg, intf, gateway, true); + DEBUG("exit [%u]: generate_route_error_message\n", fk_thread->pid); } /** @@ -452,42 +479,43 @@ static void generate_route_error_message(uint16_t dst, uint16_t gateway, int int * @param msg The route request packet * @param packet_info Additional packet information */ -static void receive_route_request_message(mmr_rreq_message_t* msg, packet_info_t* packet_info) +static void receive_route_request_message(mmr_rreq_message_t *msg, + packet_info_t *packet_info) { - DEBUG("call [%u]: receive_route_request_message\n", fk_thread->pid); - uint16_t my_addr = net_get_address_in_subnet(msg->source); + DEBUG("call [%u]: receive_route_request_message\n", fk_thread->pid); + uint16_t my_addr = net_get_address_in_subnet(msg->source); #if (MMR_INFO_LEVEL >= LEVEL_WARN) - if (my_addr == 0) - { - puts("MMR [WARN]: received RREQ with unknown network part of source address"); - puts("MMR [WARN]: => can't find own net address in sub net!"); - } -#endif - // If address list of RREQ message has enough space - if (msg->length < ADDRESS_LIST_SIZE) - { - // append our node id to list - msg->address[msg->length++] = my_addr; - // add routes with overhearing - rt_extract_routes(my_addr, msg->length, msg->address); - } - // Distance between sender and receiver is too long, discard packet - else - { - // Drop RREQ packet => set TTL to zero - *packet_info->ttl_ptr = 0; - DEBUG("exit [%u]: receive_route_request_message\n", fk_thread->pid); - return; - } - // If RREQ message was send to us, then send RREP message - if (msg->destination == my_addr) - { - // Don't forward RREQ packet any further => set TTL to zero - *packet_info->ttl_ptr = 0; - generate_route_reply_message(msg); - } - DEBUG("exit [%u]: receive_route_request_message\n", fk_thread->pid); + if(my_addr == 0) { + puts("MMR [WARN]: received RREQ with unknown network part of source address"); + puts("MMR [WARN]: => can't find own net address in sub net!"); + } + +#endif + + /* If address list of RREQ message has enough space */ + if(msg->length < ADDRESS_LIST_SIZE) { + /* append our node id to list */ + msg->address[msg->length++] = my_addr; + /* add routes with overhearing */ + rt_extract_routes(my_addr, msg->length, msg->address); + } + /* Distance between sender and receiver is too long, discard packet */ + else { + /* Drop RREQ packet => set TTL to zero */ + *packet_info->ttl_ptr = 0; + DEBUG("exit [%u]: receive_route_request_message\n", fk_thread->pid); + return; + } + + /* If RREQ message was send to us, then send RREP message */ + if(msg->destination == my_addr) { + /* Don't forward RREQ packet any further => set TTL to zero */ + *packet_info->ttl_ptr = 0; + generate_route_reply_message(msg); + } + + DEBUG("exit [%u]: receive_route_request_message\n", fk_thread->pid); } /** @@ -496,12 +524,13 @@ static void receive_route_request_message(mmr_rreq_message_t* msg, packet_info_t * @param msg The route reply packet * @param packet_info Additional packet information */ -static void receive_route_reply_message(mmr_rrep_message_t* msg, packet_info_t* packet_info) +static void receive_route_reply_message(mmr_rrep_message_t *msg, + packet_info_t *packet_info) { - DEBUG("call [%u]: receive_route_reply_message\n", fk_thread->pid); - // RREP received: Send out queued packets for which routes are now known - mq_dequeue_and_send(msg->source); - DEBUG("exit [%u]: receive_route_reply_message\n", fk_thread->pid); + DEBUG("call [%u]: receive_route_reply_message\n", fk_thread->pid); + /* RREP received: Send out queued packets for which routes are now known */ + mq_dequeue_and_send(msg->source); + DEBUG("exit [%u]: receive_route_reply_message\n", fk_thread->pid); } /** @@ -510,21 +539,24 @@ static void receive_route_reply_message(mmr_rrep_message_t* msg, packet_info_t* * @param msg The route error packet * @param packet_info Additional packet information */ -static void receive_route_error_message(mmr_rerr_message_t* msg, packet_info_t* packet_info) +static void receive_route_error_message(mmr_rerr_message_t *msg, + packet_info_t *packet_info) { - DEBUG("call [%u]: receive_route_error_message\n", fk_thread->pid); - switch (msg->error_type) - { - case RERR_NODE_UNREACHABLE: - rt_remove_route(msg->type_specific_info); - break; - default: + DEBUG("call [%u]: receive_route_error_message\n", fk_thread->pid); + + switch(msg->error_type) { + case RERR_NODE_UNREACHABLE: + rt_remove_route(msg->type_specific_info); + break; + + default: #if (MMR_INFO_LEVEL >= LEVEL_INFO) - puts("MMR [INFO]: RERR error type is unknown"); + puts("MMR [INFO]: RERR error type is unknown"); #endif - break; - } - DEBUG("exit [%u]: receive_route_error_message\n", fk_thread->pid); + break; + } + + DEBUG("exit [%u]: receive_route_error_message\n", fk_thread->pid); } /** @@ -538,13 +570,16 @@ static void receive_route_error_message(mmr_rerr_message_t* msg, packet_info_t* */ static int compute_rreq_timeout(int ttl, uint16_t dst) { - int t_hop = net_get_interface_transmission_duration(dst); - if (t_hop == -1) { - t_hop = RREQ_TIMEOUT_PER_TTL * ttl; - } else { - t_hop = (t_hop * ttl + 999) / 1000; - } - return RREQ_TIMEOUT_BASE + 2 * t_hop; + int t_hop = net_get_interface_transmission_duration(dst); + + if(t_hop == -1) { + t_hop = RREQ_TIMEOUT_PER_TTL * ttl; + } + else { + t_hop = (t_hop * ttl + 999) / 1000; + } + + return RREQ_TIMEOUT_BASE + 2 * t_hop; } /** @@ -556,43 +591,46 @@ static int compute_rreq_timeout(int ttl, uint16_t dst) * @param mq_entry Pointer to a message queue entry (the packet * for which to find the route) */ -static void rreq_broadcast(message_queue_entry_t* mq_entry) +static void rreq_broadcast(message_queue_entry_t *mq_entry) { - DEBUG("call [%u]: rreq_broadcast\n", fk_thread->pid); - if(mq_entry->retry_count == RREQ_NONE) - { - DEBUG("call [%u]: rreq duplicated do not send\n", fk_thread->pid); - return; - } - // Create RREQ message - mmr_rreq_message_t rreq_msg; - rreq_msg.type = MMR_TYPE_RREQ; - rreq_msg.length = 1; - rreq_msg.destination = mq_entry->message.destination; - rreq_msg.source = mq_entry->message.source; - rreq_msg.address[0] = mq_entry->message.source; + DEBUG("call [%u]: rreq_broadcast\n", fk_thread->pid); - // Wrap RREQ message in net message - net_message_t net_msg; - net_msg.protocol = LAYER_2_PROTOCOL_MMR; - net_msg.flags_tos = PRIORITY_DATA; - net_msg.seq_clr_id = 0; - net_msg.ttl = mq_entry->retry_count == 0 ? TTL_START : TTL_THRESHOLD; - net_msg.source = rreq_msg.source; - net_msg.destination = NETWORK_ADDR_BC(rreq_msg.destination); - memcpy(net_msg.payload, (void*)&rreq_msg, sizeof(mmr_rreq_message_t)); + if(mq_entry->retry_count == RREQ_NONE) { + DEBUG("call [%u]: rreq duplicated do not send\n", fk_thread->pid); + return; + } - // Broadcast the net message - mq_entry->retry_count++; - mq_entry->timestamp = rtc_now(); - // Find the broadcast route table entry - route_table_entry_t* rte = rt_lookup_route(net_msg.destination); - if (rte != NULL) - { - // Next hop address is broadcast address of lower layer - net_enqueue_for_transmission(&net_msg, rte->interface_id, rte->gateway, true); - } - DEBUG("exit [%u]: rreq_broadcast\n", fk_thread->pid); + /* Create RREQ message */ + mmr_rreq_message_t rreq_msg; + rreq_msg.type = MMR_TYPE_RREQ; + rreq_msg.length = 1; + rreq_msg.destination = mq_entry->message.destination; + rreq_msg.source = mq_entry->message.source; + rreq_msg.address[0] = mq_entry->message.source; + + /* Wrap RREQ message in net message */ + net_message_t net_msg; + net_msg.protocol = LAYER_2_PROTOCOL_MMR; + net_msg.flags_tos = PRIORITY_DATA; + net_msg.seq_clr_id = 0; + net_msg.ttl = mq_entry->retry_count == 0 ? TTL_START : TTL_THRESHOLD; + net_msg.source = rreq_msg.source; + net_msg.destination = NETWORK_ADDR_BC(rreq_msg.destination); + memcpy(net_msg.payload, (void *)&rreq_msg, sizeof(mmr_rreq_message_t)); + + /* Broadcast the net message */ + mq_entry->retry_count++; + mq_entry->timestamp = rtc_now(); + /* Find the broadcast route table entry */ + route_table_entry_t *rte = rt_lookup_route(net_msg.destination); + + if(rte != NULL) { + /* Next hop address is broadcast address of lower layer */ + net_enqueue_for_transmission(&net_msg, rte->interface_id, + rte->gateway, true); + } + + DEBUG("exit [%u]: rreq_broadcast\n", fk_thread->pid); } /** @@ -601,53 +639,59 @@ static void rreq_broadcast(message_queue_entry_t* mq_entry) */ static void post_next_rreq_timeout(void) { - DEBUG("call [%u]: post_next_rreq_timeout\n", fk_thread->pid); - int i, j = -1; - uint32_t now, next = 0xffffffff; - for (i = 0; i < MESSAGE_QUEUE_SIZE; i++) - { - if (message_queue[i].timestamp != 0 && message_queue[i].retry_count != RREQ_NONE) - { - int ttl = message_queue[i].retry_count == 1 ? TTL_START : TTL_THRESHOLD; - int to = compute_rreq_timeout(ttl, message_queue[i].message.destination); - if (message_queue[i].timestamp + to < next) - { - next = message_queue[i].timestamp + to; - j = i; - } - } - } - if (j == -1) { - DEBUG("exit [%u]: post_next_rreq_timeout\n", fk_thread->pid); - return; - } - // Stop any utimer - rreq_to_active = false; - utimer_remove(&ut); - // If current time greater than RREQ timeout value - now = rtc_now(); - if (now >= next) - { - // Schedule RREQ-Timeout immediately - msg m; - m.type = MSG_TIMER; - m.content.ptr = (char*)&message_queue[j]; - rreq_to_active = true; - if (msg_send(&m, rreq_timeout_process_pid, false) != 1) { - // Message could not be send (receiver not waiting), schedule timer with minimum delay + DEBUG("call [%u]: post_next_rreq_timeout\n", fk_thread->pid); + int i, j = -1; + uint32_t now, next = 0xffffffff; + + for(i = 0; i < MESSAGE_QUEUE_SIZE; i++) { + if((message_queue[i].timestamp != 0) && (message_queue[i].retry_count != + RREQ_NONE)) { + int ttl = message_queue[i].retry_count == 1 ? TTL_START : TTL_THRESHOLD; + int to = compute_rreq_timeout(ttl, + message_queue[i].message.destination); + + if(message_queue[i].timestamp + to < next) { + next = message_queue[i].timestamp + to; + j = i; + } + } + } + + if(j == -1) { + DEBUG("exit [%u]: post_next_rreq_timeout\n", fk_thread->pid); + return; + } + + /* Stop any utimer */ + rreq_to_active = false; + utimer_remove(&ut); + /* If current time greater than RREQ timeout value */ + now = rtc_now(); + + if(now >= next) { + /* Schedule RREQ-Timeout immediately */ + msg m; + m.type = MSG_TIMER; + m.content.ptr = (char *)&message_queue[j]; + rreq_to_active = true; + + if(msg_send(&m, rreq_timeout_process_pid, false) != 1) { + /* Message could not be send (receiver not waiting), schedule + * timer with minimum delay */ #if (MMR_INFO_LEVEL >= LEVEL_WARN) - puts("MMR [WARN]: Immediate schedule of RREQ-Timeout failed, process not waiting!"); + puts("MMR [WARN]: Immediate schedule of RREQ-Timeout failed, process not waiting!"); #endif - utimer_set_wpid(&ut, 1, rreq_timeout_process_pid, &message_queue[j]); - } - } - else - { - // Set new utimer with time difference - rreq_to_active = true; - utimer_set_wpid(&ut, next - now, rreq_timeout_process_pid, &message_queue[j]); - } - DEBUG("exit [%u]: post_next_rreq_timeout\n", fk_thread->pid); + utimer_set_wpid(&ut, 1, rreq_timeout_process_pid, &message_queue[j]); + } + } + else { + /* Set new utimer with time difference */ + rreq_to_active = true; + utimer_set_wpid(&ut, next - now, rreq_timeout_process_pid, + &message_queue[j]); + } + + DEBUG("exit [%u]: post_next_rreq_timeout\n", fk_thread->pid); } /** @@ -657,251 +701,267 @@ static void post_next_rreq_timeout(void) * Each time it is called, it rebroadcasts the route request message with a * new rreq id and incremented TTL. */ -static void rreq_timeout(message_queue_entry_t* mqe) +static void rreq_timeout(message_queue_entry_t *mqe) { - DEBUG("call [%u]: rreq_timeout\n", fk_thread->pid); - // Test if valid entry passed - if (mqe->timestamp == 0) - { + DEBUG("call [%u]: rreq_timeout\n", fk_thread->pid); + + /* Test if valid entry passed */ + if(mqe->timestamp == 0) { #if (MMR_INFO_LEVEL >= LEVEL_WARN) - puts("MMR [WARN]: invalid message queue entry for RREQ-Timeout"); + puts("MMR [WARN]: invalid message queue entry for RREQ-Timeout"); #endif - goto post_next_to; - } - // See if route to destination was found - route_table_entry_t* rte = rt_lookup_route(mqe->message.destination); - // If found and no messages in queue for destination: return (queued - // packets are send on reception of RREP); If found but messages in - // queue: trigger send immediately here! - if (rte != NULL) - { - int msg_count = mq_msgs_for_destination(mqe->message.destination); - if (msg_count > 0) - { - mq_dequeue_and_send(mqe->message.destination); - DEBUG("exit [%u]: rreq_timeout\n", fk_thread->pid); - return; - } - else - { - // Added just for security but this case should never occur + goto post_next_to; + } + + /* See if route to destination was found */ + route_table_entry_t *rte = rt_lookup_route(mqe->message.destination); + + /* If found and no messages in queue for destination: return (queued + * packets are send on reception of RREP); If found but messages in queue: + * trigger send immediately here! */ + if(rte != NULL) { + int msg_count = mq_msgs_for_destination(mqe->message.destination); + + if(msg_count > 0) { + mq_dequeue_and_send(mqe->message.destination); + DEBUG("exit [%u]: rreq_timeout\n", fk_thread->pid); + return; + } + else { + /* Added just for security but this case should never occur */ #if (MMR_INFO_LEVEL >= LEVEL_WARN) - puts("MMR [WARN]: RREQ-Timeout occurred, route is available but no messages for destination"); + puts("MMR [WARN]: RREQ-Timeout occurred, route is available but no messages for destination"); #endif - // Anyway: jump to update next RREQ-Timeout - goto post_next_to; - } - } - // Otherwise send new RREQ if below threshold (means also retry count != RREQ_NONE) - if (mqe->retry_count < RREQ_THRESHOLD) - { - // Broadcast new RREQ message (with incremented TTL) - rreq_broadcast(mqe); - } - else - { - // Remove all messages for this destination - mmr_stats.messages_no_route_found++; - mq_remove_msgs_for_destination(mqe->message.destination); - } - // Anyway: update or set next RREQ-Timeout - post_next_to: - post_next_rreq_timeout(); - DEBUG("exit [%u]: rreq_timeout\n", fk_thread->pid); + /* Anyway: jump to update next RREQ-Timeout */ + goto post_next_to; + } + } + + /* Otherwise send new RREQ if below threshold (means also retry count != + * RREQ_NONE) */ + if(mqe->retry_count < RREQ_THRESHOLD) { + /* Broadcast new RREQ message (with incremented TTL) */ + rreq_broadcast(mqe); + } + else { + /* Remove all messages for this destination */ + mmr_stats.messages_no_route_found++; + mq_remove_msgs_for_destination(mqe->message.destination); + } + + /* Anyway: update or set next RREQ-Timeout */ +post_next_to: + post_next_rreq_timeout(); + DEBUG("exit [%u]: rreq_timeout\n", fk_thread->pid); } static void rreq_timeout_process(void) { - msg m; - do - { - msg_receive(&m); - if (m.type == MSG_TIMER && rreq_to_active) - { - rreq_to_active = false; - rreq_timeout((message_queue_entry_t*)m.content.ptr); - } - } while (m.type != MSG_EXIT); + msg m; + + do { + msg_receive(&m); + + if(m.type == MSG_TIMER && rreq_to_active) { + rreq_to_active = false; + rreq_timeout((message_queue_entry_t *)m.content.ptr); + } + } + while(m.type != MSG_EXIT); } -void mmr_peek(net_message_t* message, packet_info_t* packet_info) +void mmr_peek(net_message_t *message, packet_info_t *packet_info) { - DEBUG("call [%u]: mmr_peek\n", fk_thread->pid); - // Only look at micro mesh routing messages - if (message->protocol == LAYER_2_PROTOCOL_MMR) - { - uint8_t type = message->payload[0]; - uint16_t my_addr = net_get_address_in_subnet(message->source); - if (type == MMR_TYPE_RREP) - { - // Add routes to route table - mmr_rrep_message_t* rrep_msg = (mmr_rrep_message_t*)message->payload; + DEBUG("call [%u]: mmr_peek\n", fk_thread->pid); + + /* Only look at micro mesh routing messages */ + if(message->protocol == LAYER_2_PROTOCOL_MMR) { + uint8_t type = message->payload[0]; + uint16_t my_addr = net_get_address_in_subnet(message->source); + + if(type == MMR_TYPE_RREP) { + /* Add routes to route table */ + mmr_rrep_message_t *rrep_msg = (mmr_rrep_message_t *)message->payload; #if (MMR_INFO_LEVEL >= LEVEL_WARN) - if (my_addr == 0) - { - puts("MMR [WARN]: received RREP with unknown network part of source address"); - puts("MMR [WARN]: => can't find own net address in sub net!"); - } + + if(my_addr == 0) { + puts("MMR [WARN]: received RREP with unknown network part of source address"); + puts("MMR [WARN]: => can't find own net address in sub net!"); + } + #endif - rt_extract_routes(my_addr, rrep_msg->length, rrep_msg->address); - } - else if (type == MMR_TYPE_RERR) - { + rt_extract_routes(my_addr, rrep_msg->length, rrep_msg->address); + } + else if(type == MMR_TYPE_RERR) { #if (MMR_INFO_LEVEL >= LEVEL_WARN) - if (my_addr == 0) - { - puts("MMR [WARN]: received RERR with unknown network part of source address"); - puts("MMR [WARN]: => can't find own net address in sub net!"); - } + + if(my_addr == 0) { + puts("MMR [WARN]: received RERR with unknown network part of source address"); + puts("MMR [WARN]: => can't find own net address in sub net!"); + } + #endif - // If not destination of RERR, then remove route to unavailable node in RERR packet - if (message->destination != my_addr) - { - mmr_rerr_message_t* rerr_msg = (mmr_rerr_message_t*)message->payload; - if (rerr_msg->error_type == RERR_NODE_UNREACHABLE) - { - rt_remove_route(rerr_msg->type_specific_info); - } - } - } - } - DEBUG("exit [%u]: mmr_peek\n", fk_thread->pid); + + /* If not destination of RERR, then remove route to unavailable + * node in RERR packet */ + if(message->destination != my_addr) { + mmr_rerr_message_t *rerr_msg = + (mmr_rerr_message_t *)message->payload; + + if(rerr_msg->error_type == RERR_NODE_UNREACHABLE) { + rt_remove_route(rerr_msg->type_specific_info); + } + } + } + } + + DEBUG("exit [%u]: mmr_peek\n", fk_thread->pid); } -bool mmr_send(net_message_t* message) +bool mmr_send(net_message_t *message) { - DEBUG("call [%u]: mmr_send\n", fk_thread->pid); - bool enqueue = true; - if (message->destination == net_get_address_in_subnet(message->destination)) - { + DEBUG("call [%u]: mmr_send\n", fk_thread->pid); + bool enqueue = true; + + if(message->destination == net_get_address_in_subnet(message->destination)) { #if (MMR_INFO_LEVEL >= LEVEL_WARN) - puts("MMR [WARN]: message is already at destination, why is routing called?"); + puts("MMR [WARN]: message is already at destination, why is routing called?"); #endif - DEBUG("exit [%u]: mmr_send\n", fk_thread->pid); - return false; - } - if (NETWORK_ADDR_NET(message->destination) == 0) - { + DEBUG("exit [%u]: mmr_send\n", fk_thread->pid); + return false; + } + + if(NETWORK_ADDR_NET(message->destination) == 0) { #if (MMR_INFO_LEVEL >= LEVEL_WARN) - puts("MMR [WARN]: NET part of address cannot be 0!"); + puts("MMR [WARN]: NET part of address cannot be 0!"); #endif - DEBUG("exit [%u]: mmr_send\n", fk_thread->pid); - return false; - } - if (NETWORK_ADDR_HOST(message->destination) == 0) - { + DEBUG("exit [%u]: mmr_send\n", fk_thread->pid); + return false; + } + + if(NETWORK_ADDR_HOST(message->destination) == 0) { #if (MMR_INFO_LEVEL >= LEVEL_INFO) - puts("MMR [INFO]: broadcast destination, why is routing called? A route entry should exist!"); + puts("MMR [INFO]: broadcast destination, why is routing called? A route entry should exist!"); #endif - enqueue = false; - } + enqueue = false; + } - // Look up next hop address for this destination in routing table - route_table_entry_t* rte = rt_lookup_route(message->destination); + /* Look up next hop address for this destination in routing table */ + route_table_entry_t *rte = rt_lookup_route(message->destination); - // If next hop address found in routing table, forward message - if (rte != NULL) - { - DEBUG("exit [%u]: mmr_send\n", fk_thread->pid); - return net_enqueue_for_transmission(message, rte->interface_id, rte->gateway, true); - } - // Otherwise, save message in queue; broadcast RREQ message - else - { - if (!enqueue) { DEBUG("exit [%u]: mmr_send\n", fk_thread->pid); return false; } // Don't enqueue broadcast destinations - message_queue_entry_t* mqe = mq_add(message); - if (mqe != NULL) - { - rreq_broadcast(mqe); - post_next_rreq_timeout(); - mmr_stats.rreq_originated++; - DEBUG("exit [%u]: mmr_send\n", fk_thread->pid); - return true; - } - } - DEBUG("exit [%u]: mmr_send\n", fk_thread->pid); - return false; + /* If next hop address found in routing table, forward message */ + if(rte != NULL) { + DEBUG("exit [%u]: mmr_send\n", fk_thread->pid); + return net_enqueue_for_transmission(message, rte->interface_id, rte->gateway, true); + } + /* Otherwise, save message in queue; broadcast RREQ message */ + else { + if(!enqueue) { + /* Don't enqueue broadcast destinations */ + DEBUG("exit [%u]: mmr_send\n", fk_thread->pid); + return false; + } + + message_queue_entry_t *mqe = mq_add(message); + + if(mqe != NULL) { + rreq_broadcast(mqe); + post_next_rreq_timeout(); + mmr_stats.rreq_originated++; + DEBUG("exit [%u]: mmr_send\n", fk_thread->pid); + return true; + } + } + + DEBUG("exit [%u]: mmr_send\n", fk_thread->pid); + return false; } -void mmr_packet_dropped(net_message_t* message, uint16_t next_hop, int error) +void mmr_packet_dropped(net_message_t *message, uint16_t next_hop, int error) { - DEBUG("call [%u]: mmr_packet_dropped\n", fk_thread->pid); - if (error == ROUTE_ERROR_BROKEN_ROUTE) - { - // Local failure detected - remove all routes through broken link - rt_remove_gateway_routes(next_hop); - mmr_stats.messages_broken_link_on_forward++; - } - else if (error == ROUTE_ERROR_MISSING_ROUTE) - { - mmr_stats.messages_no_route_avail_on_forward++; - } + DEBUG("call [%u]: mmr_packet_dropped\n", fk_thread->pid); + + if(error == ROUTE_ERROR_BROKEN_ROUTE) { + /* Local failure detected - remove all routes through broken link */ + rt_remove_gateway_routes(next_hop); + mmr_stats.messages_broken_link_on_forward++; + } + else if(error == ROUTE_ERROR_MISSING_ROUTE) { + mmr_stats.messages_no_route_avail_on_forward++; + } + + /* If source != net_addr, send RERR to source of message */ + if(message->source != net_get_address_in_subnet(message->source)) { + /* Do not generate RERR if it is already a RERR message */ + if(is_route_error(message)) { + DEBUG("exit [%u]: mmr_packet_dropped\n", fk_thread->pid); + return; + } + + /* Find next hop to source */ + route_table_entry_t *rte = rt_lookup_route(message->source); + + if(rte != NULL) { + generate_route_error_message(message->source, rte->gateway, + rte->interface_id, + RERR_NODE_UNREACHABLE, + message->destination); + } - // If source != net_addr, send RERR to source of message - if (message->source != net_get_address_in_subnet(message->source)) - { - // Do not generate RERR if it is already a RERR message - if (is_route_error(message)) { DEBUG("exit [%u]: mmr_packet_dropped\n", fk_thread->pid); return; } - // Find next hop to source - route_table_entry_t* rte = rt_lookup_route(message->source); - if (rte != NULL) - { - generate_route_error_message(message->source, rte->gateway, - rte->interface_id, RERR_NODE_UNREACHABLE, message->destination); - } #if (MMR_INFO_LEVEL >= LEVEL_WARN) - else - { - printf("MMR [WARN]: cannot send RERR to source #%u, no route found!\n", message->source); - } + else { + printf("MMR [WARN]: cannot send RERR to source #%u, no route found!\n", + message->source); + } + #endif - } - DEBUG("exit [%u]: mmr_packet_dropped\n", fk_thread->pid); + } + + DEBUG("exit [%u]: mmr_packet_dropped\n", fk_thread->pid); } -void mmr_receive(void* msg, int msg_size, packet_info_t* packet_info) +void mmr_receive(void *msg, int msg_size, packet_info_t *packet_info) { - DEBUG("call [%u]: mmr_receive\n", fk_thread->pid); - uint8_t* p = (uint8_t*) msg; - uint8_t type = p[0]; - if (type == MMR_TYPE_RREQ) - { - receive_route_request_message((mmr_rreq_message_t*)msg, packet_info); - mmr_stats.rreq_received++; - } - else if (type == MMR_TYPE_RREP) - { - receive_route_reply_message((mmr_rrep_message_t*)msg, packet_info); - mmr_stats.rrep_received++; - } - else if (type == MMR_TYPE_RERR) - { - receive_route_error_message((mmr_rerr_message_t*)msg, packet_info); - mmr_stats.rerr_received++; - } + DEBUG("call [%u]: mmr_receive\n", fk_thread->pid); + uint8_t *p = (uint8_t *) msg; + uint8_t type = p[0]; + + if(type == MMR_TYPE_RREQ) { + receive_route_request_message((mmr_rreq_message_t *)msg, packet_info); + mmr_stats.rreq_received++; + } + else if(type == MMR_TYPE_RREP) { + receive_route_reply_message((mmr_rrep_message_t *)msg, packet_info); + mmr_stats.rrep_received++; + } + else if(type == MMR_TYPE_RERR) { + receive_route_error_message((mmr_rerr_message_t *)msg, packet_info); + mmr_stats.rerr_received++; + } + #if (MMR_INFO_LEVEL >= LEVEL_INFO) - else - { - printf("MMR [INFO]: can't handle message of type %u\n", type); - } + else { + printf("MMR [INFO]: can't handle message of type %u\n", type); + } + #endif - DEBUG("exit [%u]: mmr_receive\n", fk_thread->pid); + DEBUG("exit [%u]: mmr_receive\n", fk_thread->pid); } void mmr_print_stats(void) { - printf("ROUTING LAYER STATS\r\n"); - printf("-------------------\r\n"); - printf("Route requests originated: %lu\r\n", mmr_stats.rreq_originated); - printf("Route requests duplicated: %lu\r\n", mmr_stats.rreq_duplicated); - printf("Route replies originated: %lu\r\n", mmr_stats.rrep_originated); - printf("Route errors originated: %lu\r\n", mmr_stats.rerr_originated); - printf("Route requests received: %lu\r\n", mmr_stats.rreq_received); - printf("Route replies received: %lu\r\n", mmr_stats.rrep_received); - printf("Route errors received: %lu\r\n", mmr_stats.rerr_received); - printf("\r\n"); - printf("#Messages with no route found: %lu\r\n", mmr_stats.messages_no_route_found); - printf("#Messages with broken link on forward: %lu\r\n", mmr_stats.messages_broken_link_on_forward); - printf("#Messages with no route available on forward: %lu\r\n", mmr_stats.messages_no_route_avail_on_forward); - printf("\r\n"); + printf("ROUTING LAYER STATS\r\n"); + printf("-------------------\r\n"); + printf("Route requests originated: %lu\r\n", mmr_stats.rreq_originated); + printf("Route requests duplicated: %lu\r\n", mmr_stats.rreq_duplicated); + printf("Route replies originated: %lu\r\n", mmr_stats.rrep_originated); + printf("Route errors originated: %lu\r\n", mmr_stats.rerr_originated); + printf("Route requests received: %lu\r\n", mmr_stats.rreq_received); + printf("Route replies received: %lu\r\n", mmr_stats.rrep_received); + printf("Route errors received: %lu\r\n", mmr_stats.rerr_received); + printf("\r\n"); + printf("#Messages with no route found: %lu\r\n", mmr_stats.messages_no_route_found); + printf("#Messages with broken link on forward: %lu\r\n", mmr_stats.messages_broken_link_on_forward); + printf("#Messages with no route available on forward: %lu\r\n", mmr_stats.messages_no_route_avail_on_forward); + printf("\r\n"); } diff --git a/sys/net/mm/mmr.h b/sys/net/mm/mmr.h index 17d3d658c4..8ec55c2abb 100644 --- a/sys/net/mm/mmr.h +++ b/sys/net/mm/mmr.h @@ -60,13 +60,12 @@ and the mailinglist (subscription via web site) * | Source | Address[1..n] | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -typedef struct __attribute__ ((packed)) mmr_rreq_message_t -{ - uint8_t type; ///< Must be first byte in struct for type detection - uint8_t length; - uint16_t destination; - uint16_t source; - uint16_t address[ADDRESS_LIST_SIZE]; +typedef struct __attribute__((packed)) { + uint8_t type; ///< Must be first byte in struct for type detection + uint8_t length; + uint16_t destination; + uint16_t source; + uint16_t address[ADDRESS_LIST_SIZE]; } mmr_rreq_message_t; /** @@ -80,13 +79,12 @@ typedef struct __attribute__ ((packed)) mmr_rreq_message_t * | Source | Address[1..n] | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -typedef struct __attribute__ ((packed)) mmr_rrep_message_t -{ - uint8_t type; ///< Must be first byte in struct for type detection - uint8_t length; - uint16_t destination; - uint16_t source; - uint16_t address[ADDRESS_LIST_SIZE]; +typedef struct __attribute__((packed)) { + uint8_t type; ///< Must be first byte in struct for type detection + uint8_t length; + uint16_t destination; + uint16_t source; + uint16_t address[ADDRESS_LIST_SIZE]; } mmr_rrep_message_t; /** @@ -111,11 +109,10 @@ typedef struct __attribute__ ((packed)) mmr_rrep_message_t * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * */ -typedef struct __attribute__ ((packed)) mmr_rerr_message_t -{ - uint8_t type; ///< Must be first byte in struct for type detection - uint8_t error_type; - uint16_t type_specific_info; +typedef struct __attribute__((packed)) { + uint8_t type; ///< Must be first byte in struct for type detection + uint8_t error_type; + uint16_t type_specific_info; } mmr_rerr_message_t; /** @@ -131,7 +128,7 @@ void mmr_init(void); * @param message incoming packet * @param packet_info Additional packet information */ -void mmr_peek(net_message_t* message, packet_info_t* packet_info); +void mmr_peek(net_message_t *message, packet_info_t *packet_info); /** * Called by the network layer to request transmission of a packet that @@ -145,7 +142,7 @@ void mmr_peek(net_message_t* message, packet_info_t* packet_info); * @return true if packet was successfully stored for transmission; false otherwise * (e.g. message queue full). */ -bool mmr_send(net_message_t* message); +bool mmr_send(net_message_t *message); /** * Called by the network layer which forwards notifications of dropped packets @@ -155,7 +152,7 @@ bool mmr_send(net_message_t* message); * @param next_hop next hop network address of dropped packet (can be undefined) * @param error Error type which informs about reason */ -void mmr_packet_dropped(net_message_t* message, uint16_t next_hop, int error); +void mmr_packet_dropped(net_message_t *message, uint16_t next_hop, int error); /** * @brief Receive a message from network layer. @@ -164,7 +161,7 @@ void mmr_packet_dropped(net_message_t* message, uint16_t next_hop, int error); * @param msg_size Size of received message * @param packet_info Additional packet information */ -void mmr_receive(void* msg, int msg_size, packet_info_t* packet_info); +void mmr_receive(void *msg, int msg_size, packet_info_t *packet_info); /** * @brief Print routing layer statistics. diff --git a/sys/net/mm/mmstack.c b/sys/net/mm/mmstack.c index 83a41b44e7..94870b92eb 100644 --- a/sys/net/mm/mmstack.c +++ b/sys/net/mm/mmstack.c @@ -71,12 +71,11 @@ and the mailinglist (subscription via web site) * | Timestamp | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -typedef struct __attribute__ ((packed)) mms_ping_message_t -{ - uint8_t type; ///< Type of ping message (request or reply) - uint8_t identifier; ///< Unique identifier for ping process - uint16_t seq_num; ///< Sequence number (increasing number within that process) - uint32_t timestamp; ///< Timestamp of request message +typedef struct __attribute__((packed)) { + uint8_t type; ///< Type of ping message (request or reply) + uint8_t identifier; ///< Unique identifier for ping process + uint16_t seq_num; ///< Sequence number (increasing number within that process) + uint32_t timestamp; ///< Timestamp of request message } mms_ping_message_t; /** @@ -94,7 +93,7 @@ static uint8_t mms_ping_packets; ///< Number of ping replies received static int mms_ping_dups; ///< Duplicates static bool ping_bc_mode; ///< If option -b is set and address is BC static bool ping_silent_mode; ///< If option -s is set -static bool* dups; ///< Helper buffer to check for DUPs +static bool *dups; ///< Helper buffer to check for DUPs static float rtt_min; ///< Min. RTT static float rtt_max; ///< Max. RTT static float rtt_avg; ///< Avg. RTT @@ -123,9 +122,8 @@ static uint16_t mms_ping_pid; ///< Process ID of process ping is running withi * | Type | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -typedef struct __attribute__ ((packed)) mms_ssh_message_t -{ - uint8_t type; ///< Type of SSH message +typedef struct __attribute__((packed)) { + uint8_t type; ///< Type of SSH message } mms_ssh_message_t; /** @@ -137,10 +135,9 @@ typedef struct __attribute__ ((packed)) mms_ssh_message_t * | Type | Data | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -typedef struct __attribute__ ((packed)) mms_ssh_data_message_t -{ - uint8_t type; ///< Type of SSH message - uint8_t data[MMS_SSH_DATA_MAX]; ///< Message information +typedef struct __attribute__((packed)) { + uint8_t type; ///< Type of SSH message + uint8_t data[MMS_SSH_DATA_MAX]; ///< Message information } mms_ssh_data_message_t; /** @@ -173,14 +170,14 @@ static volatile int ssh_socket = -1; /*---------------------------------------------------------------------------*/ static route_interface_t r_iface = { - rt_add_route, - rt_add_fix_route, - rt_lookup_route, - mmr_peek, - mmr_send, - mmr_packet_dropped, - mmr_receive, - mmr_print_stats + rt_add_route, + rt_add_fix_route, + rt_lookup_route, + mmr_peek, + mmr_send, + mmr_packet_dropped, + mmr_receive, + mmr_print_stats }; /*---------------------------------------------------------------------------*/ @@ -191,310 +188,411 @@ static route_interface_t r_iface = { ASCCMD(route, CMDFLAG_SERIAL, "[-adfFg] print kernel route table"); CMD_FUNCTION(route, cmdargs) { - if (cmdargs->arg_size > 0) - { - char* msg = (char*)cmdargs->args; - while (*msg == ' ') msg++; - if (*msg == '-' && *(msg+1) == 'f') - { - mms_flush_routes(false); - printf("Kernel route table flushed (non-static)!\n"); - return CMD_SUCCESS; - } - else if (*msg == '-' && *(msg+1) == 'F') - { - mms_flush_routes(true); - printf("Kernel route table flushed (static)!\n"); - return CMD_SUCCESS; - } - else if (*msg == '-' && *(msg+1) == 'd') - { - msg++; msg++; - while (*msg == ' ') msg++; - uint16_t address = net_strtoaddr(msg, &msg); - if (rt_remove_static_route(address)) { - printf("Static route deleted successfully!\n"); - return CMD_SUCCESS; - } - return CMD_ERROR; - } - else if (*msg == '-' && *(msg+1) == 'g') - { - msg++; msg++; - while (*msg == ' ') msg++; - uint16_t address = net_strtoaddr(msg, &msg); - int c = rt_remove_static_gateway_routes(address); - printf("%u static route(s) deleted!\n", c); - return CMD_SUCCESS; - } - else if (*msg == '-' && *(msg+1) == 'a') - { - msg++; msg++; - while (*msg == ' ') msg++; - uint16_t address = net_strtoaddr(msg, &msg); - uint16_t gateway = net_strtoaddr(msg, &msg); - int metric = (int)strtoul(msg, &msg, 0); - int iface = (int)strtoul(msg, &msg, 0); - if (address != 0 && gateway != 0) { - if (rt_add_static_route(address, gateway, metric, iface)) { - printf("Static route added successfully!\n"); - return CMD_SUCCESS; - } - } - return CMD_ERROR; - } - else - { - printf("Usage: route [-adfFg] print kernel route table\n\n"); - printf(" -a , add static route to kernel route table\n"); - printf(" -d , delete static route out of kernel route table\n"); - printf(" -f, flush non-static routes out of kernel route table\n"); - printf(" -F, flush static routes out of kernel route table\n"); - printf(" -g , delete static routes out of kernel route table with a\n" - " specific gateway\n\n"); - printf(" = destination network address\n"); - printf(" = gateway network address\n"); - printf(" = metric, e.g. number of hops\n"); - printf(" = network interface number\n\n"); - return CMD_ERROR; - } - } - else - { - mms_print_routes(); - return CMD_SUCCESS; - } + if(cmdargs->arg_size > 0) { + char *msg = (char *)cmdargs->args; + + while(*msg == ' ') { + msg++; + } + + if(*msg == '-' && *(msg + 1) == 'f') { + mms_flush_routes(false); + printf("Kernel route table flushed (non-static)!\n"); + return CMD_SUCCESS; + } + else if(*msg == '-' && *(msg + 1) == 'F') { + mms_flush_routes(true); + printf("Kernel route table flushed (static)!\n"); + return CMD_SUCCESS; + } + else if(*msg == '-' && *(msg + 1) == 'd') { + msg++; + msg++; + + while(*msg == ' ') { + msg++; + } + + uint16_t address = net_strtoaddr(msg, &msg); + + if(rt_remove_static_route(address)) { + printf("Static route deleted successfully!\n"); + return CMD_SUCCESS; + } + + return CMD_ERROR; + } + else if(*msg == '-' && *(msg + 1) == 'g') { + msg++; + msg++; + + while(*msg == ' ') { + msg++; + } + + uint16_t address = net_strtoaddr(msg, &msg); + int c = rt_remove_static_gateway_routes(address); + printf("%u static route(s) deleted!\n", c); + return CMD_SUCCESS; + } + else if(*msg == '-' && *(msg + 1) == 'a') { + msg++; + msg++; + + while(*msg == ' ') { + msg++; + } + + uint16_t address = net_strtoaddr(msg, &msg); + uint16_t gateway = net_strtoaddr(msg, &msg); + int metric = (int)strtoul(msg, &msg, 0); + int iface = (int)strtoul(msg, &msg, 0); + + if(address != 0 && gateway != 0) { + if(rt_add_static_route(address, gateway, metric, iface)) { + printf("Static route added successfully!\n"); + return CMD_SUCCESS; + } + } + + return CMD_ERROR; + } + else { + printf("Usage: route [-adfFg] print kernel route table\n\n"); + printf(" -a , add static route to kernel route table\n"); + printf(" -d , delete static route out of kernel route table\n"); + printf(" -f, flush non-static routes out of kernel route table\n"); + printf(" -F, flush static routes out of kernel route table\n"); + printf(" -g , delete static routes out of kernel route table with a\n" + " specific gateway\n\n"); + printf(" = destination network address\n"); + printf(" = gateway network address\n"); + printf(" = metric, e.g. number of hops\n"); + printf(" = network interface number\n\n"); + return CMD_ERROR; + } + } + else { + mms_print_routes(); + return CMD_SUCCESS; + } } ASCCMD(ifconfig, CMDFLAG_SERIAL, "[IFACE]: print interface configuration"); CMD_FUNCTION(ifconfig, cmdargs) { - if (cmdargs->arg_size > 0) - { - char* msg; - int iface = (int)strtoul(cmdargs->args, &msg, 0); - if (cmdargs->arg_size > 1) - { - while (*msg == ' ') msg++; - if (*msg == '-' && (*(msg+1) == 'P' || *(msg+1) == 'p')) - { - msg++; msg++; - uint8_t power = (uint8_t)strtoul(msg, &msg, 0); - if (*msg != '\0') return CMD_ERROR; - if (mms_set_output_power(iface, power)) - { - printf("Output power set!\n"); - return CMD_SUCCESS; - } - return CMD_ERROR; - } - else if (*msg == '-' && (*(msg+1) == 'A' || *(msg+1) == 'a')) - { - msg++; msg++; - while (*msg == ' ') msg++; - uint16_t address = net_strtoaddr(msg, &msg); - if (mms_set_interface_address(iface, address)) - { - printf("Interface address set!\n"); - return CMD_SUCCESS; - } - return CMD_ERROR; - } - else - { - printf("Usage: ifconfig [IFACE] [-AP] print interface configuration\n\n"); - printf(" -A , set interface address, e.g. ifconfig 0 -A 1.1\n"); - printf(" -P , set output power on interface\n\n"); - return CMD_ERROR; - } - } - else - { - mms_print_ifconfig(iface); - } - } - else - { - mms_print_ifconfig(-1); - } - return CMD_SUCCESS; + if(cmdargs->arg_size > 0) { + char *msg; + int iface = (int)strtoul(cmdargs->args, &msg, 0); + + if(cmdargs->arg_size > 1) { + while(*msg == ' ') { + msg++; + } + + if(*msg == '-' && (*(msg + 1) == 'P' || *(msg + 1) == 'p')) { + msg++; + msg++; + uint8_t power = (uint8_t)strtoul(msg, &msg, 0); + + if(*msg != '\0') { + return CMD_ERROR; + } + + if(mms_set_output_power(iface, power)) { + printf("Output power set!\n"); + return CMD_SUCCESS; + } + + return CMD_ERROR; + } + else if(*msg == '-' && (*(msg + 1) == 'A' || *(msg + 1) == 'a')) { + msg++; + msg++; + + while(*msg == ' ') { + msg++; + } + + uint16_t address = net_strtoaddr(msg, &msg); + + if(mms_set_interface_address(iface, address)) { + printf("Interface address set!\n"); + return CMD_SUCCESS; + } + + return CMD_ERROR; + } + else { + printf("Usage: ifconfig [IFACE] [-AP] print interface configuration\n\n"); + printf(" -A , set interface address, e.g. ifconfig 0 -A 1.1\n"); + printf(" -P , set output power on interface\n\n"); + return CMD_ERROR; + } + } + else { + mms_print_ifconfig(iface); + } + } + else { + mms_print_ifconfig(-1); + } + + return CMD_SUCCESS; } ASCCMD(ping, CMDFLAG_SERIAL, "ping [-bchpstw] destination"); CMD_FUNCTION(ping, cmdargs) { - if (cmdargs->arg_size > 0) - { - int i; - msg m; - uint8_t count = MMS_PING_PACKETS; - uint8_t prio = PRIORITY_DATA; - bool bc = false; - ping_bc_mode = false; - ping_silent_mode = false; - int ttl = 10; - long timeout = 3; - char adrbuf[10]; - const char* msg = cmdargs->args; - read_ping_cmd: - while (*msg == ' ') msg++; - if (*msg == '-' && (*(msg+1) == 'B' || *(msg+1) == 'b')) { - bc = true; - msg++; msg++; - goto read_ping_cmd; - } else if (*msg == '-' && (*(msg+1) == 'C' || *(msg+1) == 'c')) { - msg++; msg++; - unsigned long tc = strtoul(msg, (char**)&msg, 0); - if (tc == 0) return CMD_ERROR; - if (tc > 255) { - puts("Not more than 255 ping messages allowed!"); - return CMD_ERROR; - } - count = (uint8_t) tc; - goto read_ping_cmd; - } else if (*msg == '-' && (*(msg+1) == 'H' || *(msg+1) == 'h')) { - printf("Usage: ping [-bchpstw] destination\n\n"); - printf(" -b, do a broadcast ping\n"); - printf(" -c , set number of ping messages\n"); - printf(" -h, print a help synopsis\n"); - printf(" -p , set the ping message priority\n"); - printf(" PRIO = 1: alarm\n"); - printf(" PRIO = 2: warning\n"); - printf(" PRIO = 3: data (default)\n"); - printf(" -s, silent mode (no messages printed out)\n"); - printf(" -t , TTL value of ping messages (default: 10)\n"); - printf(" -w , time to wait for a response, in seconds (default: 3)\n\n"); - return CMD_SUCCESS; - } else if (*msg == '-' && (*(msg+1) == 'p' || *(msg+1) == 'P')) { - msg++; msg++; - unsigned long tp = strtoul(msg, (char**)&msg, 0); - if (tp == 0) return CMD_ERROR; - if (tp == 1) prio = 0; - else if (tp == 2) prio = 1; - else prio = 2; - goto read_ping_cmd; - } else if (*msg == '-' && (*(msg+1) == 's' || *(msg+1) == 'S')) { - ping_silent_mode = true; - msg++; msg++; - goto read_ping_cmd; - } else if (*msg == '-' && (*(msg+1) == 't' || *(msg+1) == 'T')) { - msg++; msg++; - unsigned long to = strtoul(msg, (char**)&msg, 0); - if (to == 0 || to > 255) return CMD_ERROR; - ttl = to; - goto read_ping_cmd; - } else if (*msg == '-' && (*(msg+1) == 'w' || *(msg+1) == 'W')) { - msg++; msg++; - unsigned long to = strtoul(msg, (char**)&msg, 0); - if (to == 0) return CMD_ERROR; - timeout = to; - goto read_ping_cmd; - } - uint16_t address = net_strtoaddr((char*)msg, (char**)&msg); - if (address == 0) return CMD_ERROR; - int iface_addr = net_get_address_in_subnet(address); - // No ping to unsupported network or own address - if (iface_addr == 0 || iface_addr == address) return CMD_ERROR; - // If broadcast destination address, limit TTL to one hop - if (address == NETWORK_ADDR_BC(address)) { - if (!bc) { - puts("Do you want to ping broadcast? Then -b"); - return CMD_ERROR; - } - ttl = 1; - ping_bc_mode = true; - } - // Try to malloc duplicate detection buffer - dups = (bool*) malloc(count * sizeof(bool)); - if (dups == NULL) { - puts("Not enough system memory to fulfill your request!"); - return CMD_ERROR; - } - net_addrtostr(address, adrbuf, sizeof(adrbuf)); - printf("PING %s %lu bytes of data.\n", adrbuf, sizeof(mms_ping_message_t)); - mms_ping_packets = 0; - mms_ping_dups = 0; - mms_ping_last_proc_id = (rand() % 255) + 1; - rtt_min = 0xffffffff; - rtt_max = 0x00000000; - rtt_avg = 0x00000000; - mms_ping_pid = fk_thread->pid; - long ts_start = (uint32_t)clock_get_systemtime(); - for (i = 1; i <= count; i++) - { - // No duplicate for this sequence number possible - dups[i-1] = false; - // Send ping echo request to destination - mms_ping(address, i, prio, ttl); - // Set timeout for next ping echo request packet to ::timeout seconds - utimer_set_wpid(&mms_ping_utimer, timeout, mms_ping_pid, NULL); - // Wait for ping echo reply or timeout - msg_receive(&m); - // Remove user timer because maybe woken up by ping response - utimer_remove(&mms_ping_utimer); - } - ts_start = (uint32_t)clock_get_systemtime() - ts_start; - printf("--- %s ping statistics ---\n", adrbuf); - if (mms_ping_dups == 0) { - printf("%u packets transmitted, %u received, %u%% packet loss, time %lu ms\n", count, - mms_ping_packets, ((count-mms_ping_packets)*100)/count, ts_start); - } else { - printf("%u packets transmitted, %u received, +%i duplicates, %u%% packet loss, time %lu ms\n", count, - mms_ping_packets, mms_ping_dups, ((count-mms_ping_packets)*100)/count, ts_start); - } - if (mms_ping_packets > 0) - { - printf("rtt min/avg/max = %.2f/%.2f/%.2f ms\n", rtt_min, rtt_avg/(mms_ping_packets+mms_ping_dups), rtt_max); - } - if (!ping_bc_mode && mms_ping_packets == count) { - // Calculate approximate throughput - printf("--- %s throughput statistics ---\n", adrbuf); - float bw = (count * (8+4+62+2) * 1000) / (float)ts_start; // for CC1100 - printf("approximate throughput (air): %.2f byte/sec\n", 2*bw); - bw = (count * 58 * 1000) / (float)ts_start; // for CC1100 - printf("approximate throughput (dll): %.2f byte/sec\n", 2*bw); - bw = (count * NET_MESSAGE_PAYLOAD_LENGTH * 1000) / (float)ts_start; - printf("approximate throughput (net): %.2f byte/sec\n", 2*bw); - bw = (count * UDPL_MESSAGE_LENGTH * 1000) / (float)ts_start; - printf("approximate throughput (trans/UDPL): %.2f byte/sec\n", 2*bw); - bw = (count * TCPL_MESSAGE_LENGTH * 1000) / (float)ts_start; - printf("approximate throughput (trans/TCPL): %.2f byte/sec\n", bw); - } - // Ping is over, clear random ping process id and buffer - mms_ping_last_proc_id = 0; - free(dups); - return CMD_SUCCESS; - } - return CMD_ERROR; + if(cmdargs->arg_size > 0) { + int i; + msg m; + uint8_t count = MMS_PING_PACKETS; + uint8_t prio = PRIORITY_DATA; + bool bc = false; + ping_bc_mode = false; + ping_silent_mode = false; + int ttl = 10; + long timeout = 3; + char adrbuf[10]; + const char *msg = cmdargs->args; + read_ping_cmd: + + while(*msg == ' ') { + msg++; + } + + if(*msg == '-' && (*(msg + 1) == 'B' || *(msg + 1) == 'b')) { + bc = true; + msg++; + msg++; + goto read_ping_cmd; + } + else if(*msg == '-' && (*(msg + 1) == 'C' || *(msg + 1) == 'c')) { + msg++; + msg++; + unsigned long tc = strtoul(msg, (char **)&msg, 0); + + if(tc == 0) { + return CMD_ERROR; + } + + if(tc > 255) { + puts("Not more than 255 ping messages allowed!"); + return CMD_ERROR; + } + + count = (uint8_t) tc; + goto read_ping_cmd; + } + else if(*msg == '-' && (*(msg + 1) == 'H' || *(msg + 1) == 'h')) { + printf("Usage: ping [-bchpstw] destination\n\n"); + printf(" -b, do a broadcast ping\n"); + printf(" -c , set number of ping messages\n"); + printf(" -h, print a help synopsis\n"); + printf(" -p , set the ping message priority\n"); + printf(" PRIO = 1: alarm\n"); + printf(" PRIO = 2: warning\n"); + printf(" PRIO = 3: data (default)\n"); + printf(" -s, silent mode (no messages printed out)\n"); + printf(" -t , TTL value of ping messages (default: 10)\n"); + printf(" -w , time to wait for a response, in seconds (default: 3)\n\n"); + return CMD_SUCCESS; + } + else if(*msg == '-' && (*(msg + 1) == 'p' || *(msg + 1) == 'P')) { + msg++; + msg++; + unsigned long tp = strtoul(msg, (char **)&msg, 0); + + if(tp == 0) { + return CMD_ERROR; + } + + if(tp == 1) { + prio = 0; + } + else if(tp == 2) { + prio = 1; + } + else { + prio = 2; + } + + goto read_ping_cmd; + } + else if(*msg == '-' && (*(msg + 1) == 's' || *(msg + 1) == 'S')) { + ping_silent_mode = true; + msg++; + msg++; + goto read_ping_cmd; + } + else if(*msg == '-' && (*(msg + 1) == 't' || *(msg + 1) == 'T')) { + msg++; + msg++; + unsigned long to = strtoul(msg, (char **)&msg, 0); + + if(to == 0 || to > 255) { + return CMD_ERROR; + } + + ttl = to; + goto read_ping_cmd; + } + else if(*msg == '-' && (*(msg + 1) == 'w' || *(msg + 1) == 'W')) { + msg++; + msg++; + unsigned long to = strtoul(msg, (char **)&msg, 0); + + if(to == 0) { + return CMD_ERROR; + } + + timeout = to; + goto read_ping_cmd; + } + + uint16_t address = net_strtoaddr((char *)msg, (char **)&msg); + + if(address == 0) { + return CMD_ERROR; + } + + int iface_addr = net_get_address_in_subnet(address); + + /* No ping to unsupported network or own address */ + if(iface_addr == 0 || iface_addr == address) { + return CMD_ERROR; + } + + /* If broadcast destination address, limit TTL to one hop */ + if(address == NETWORK_ADDR_BC(address)) { + if(!bc) { + puts("Do you want to ping broadcast? Then -b"); + return CMD_ERROR; + } + + ttl = 1; + ping_bc_mode = true; + } + + /* Try to malloc duplicate detection buffer */ + dups = (bool *) malloc(count * sizeof(bool)); + + if(dups == NULL) { + puts("Not enough system memory to fulfill your request!"); + return CMD_ERROR; + } + + net_addrtostr(address, adrbuf, sizeof(adrbuf)); + printf("PING %s %lu bytes of data.\n", adrbuf, sizeof(mms_ping_message_t)); + mms_ping_packets = 0; + mms_ping_dups = 0; + mms_ping_last_proc_id = (rand() % 255) + 1; + rtt_min = 0xffffffff; + rtt_max = 0x00000000; + rtt_avg = 0x00000000; + mms_ping_pid = fk_thread->pid; + long ts_start = (uint32_t)clock_get_systemtime(); + + for(i = 1; i <= count; i++) { + /* No duplicate for this sequence number possible */ + dups[i - 1] = false; + /* Send ping echo request to destination */ + mms_ping(address, i, prio, ttl); + /* Set timeout for next ping echo request packet to ::timeout seconds */ + utimer_set_wpid(&mms_ping_utimer, timeout, mms_ping_pid, NULL); + /* Wait for ping echo reply or timeout */ + msg_receive(&m); + /* Remove user timer because maybe woken up by ping response */ + utimer_remove(&mms_ping_utimer); + } + + ts_start = (uint32_t)clock_get_systemtime() - ts_start; + printf("--- %s ping statistics ---\n", adrbuf); + + if(mms_ping_dups == 0) { + printf("%u packets transmitted, %u received, %u%% packet loss, time %lu ms\n", count, + mms_ping_packets, ((count - mms_ping_packets) * 100) / count, ts_start); + } + else { + printf("%u packets transmitted, %u received, +%i duplicates, %u%% packet loss, time %lu ms\n", count, + mms_ping_packets, mms_ping_dups, ((count - mms_ping_packets) * 100) / count, ts_start); + } + + if(mms_ping_packets > 0) { + printf("rtt min/avg/max = %.2f/%.2f/%.2f ms\n", rtt_min, rtt_avg / (mms_ping_packets + mms_ping_dups), rtt_max); + } + + if(!ping_bc_mode && mms_ping_packets == count) { + /* Calculate approximate throughput */ + printf("--- %s throughput statistics ---\n", adrbuf); + float bw = (count * (8 + 4 + 62 + 2) * 1000) / (float)ts_start; /* for CC1100 */ + printf("approximate throughput (air): %.2f byte/sec\n", 2 * bw); + bw = (count * 58 * 1000) / (float)ts_start; /* for CC1100 */ + printf("approximate throughput (dll): %.2f byte/sec\n", 2 * bw); + bw = (count * NET_MESSAGE_PAYLOAD_LENGTH * 1000) / (float)ts_start; + printf("approximate throughput (net): %.2f byte/sec\n", 2 * bw); + bw = (count * UDPL_MESSAGE_LENGTH * 1000) / (float)ts_start; + printf("approximate throughput (trans/UDPL): %.2f byte/sec\n", 2 * bw); + bw = (count * TCPL_MESSAGE_LENGTH * 1000) / (float)ts_start; + printf("approximate throughput (trans/TCPL): %.2f byte/sec\n", bw); + } + + /* Ping is over, clear random ping process id and buffer */ + mms_ping_last_proc_id = 0; + free(dups); + return CMD_SUCCESS; + } + + return CMD_ERROR; } ASCCMD(ssh, CMDFLAG_SERIAL, "Usage: ssh [-q] destination"); CMD_FUNCTION(ssh, cmdargs) { - if (cmdargs->arg_size > 0) { - bool quit = false; - const char* msg = cmdargs->args; - while (*msg == ' ') msg++; - if (*msg == '-' && (*(msg+1) == 'Q' || *(msg+1) == 'q')) - { - quit = true; - msg++; msg++; - } - uint16_t address = net_strtoaddr((char*)msg, (char**)&msg); - if (address == 0) return CMD_ERROR; - int iface_addr = net_get_address_in_subnet(address); - // No ssh to unsupported network or own address - if (iface_addr == 0 || iface_addr == address) return CMD_ERROR; - // If broadcast destination address, also exit here - if (address == NETWORK_ADDR_BC(address)) return CMD_ERROR; - if (!quit) { - mms_ssh_connect(address); - } else { - mms_ssh_close(address); - } - return CMD_SUCCESS; - } - return CMD_ERROR; + if(cmdargs->arg_size > 0) { + bool quit = false; + const char *msg = cmdargs->args; + + while(*msg == ' ') { + msg++; + } + + if(*msg == '-' && (*(msg + 1) == 'Q' || *(msg + 1) == 'q')) { + quit = true; + msg++; + msg++; + } + + uint16_t address = net_strtoaddr((char *)msg, (char **)&msg); + + if(address == 0) { + return CMD_ERROR; + } + + int iface_addr = net_get_address_in_subnet(address); + + /* No ssh to unsupported network or own address */ + if(iface_addr == 0 || iface_addr == address) { + return CMD_ERROR; + } + + /* If broadcast destination address, also exit here */ + if(address == NETWORK_ADDR_BC(address)) { + return CMD_ERROR; + } + + if(!quit) { + mms_ssh_connect(address); + } + else { + mms_ssh_close(address); + } + + return CMD_SUCCESS; + } + + return CMD_ERROR; } //#endif @@ -502,63 +600,74 @@ CMD_FUNCTION(ssh, cmdargs) // Ping message handler and send function /*---------------------------------------------------------------------------*/ -static void mms_ping_handler(void* message, int message_size, packet_info_t* packet_info) +static void mms_ping_handler(void *message, int message_size, + packet_info_t *packet_info) { - mms_ping_message_t* ping = (mms_ping_message_t*)message; - if (ping->type == MMS_PING_ECHO_REQUEST) - { - ping->type = MMS_PING_ECHO_REPLY; - net_send((void*)ping, sizeof(mms_ping_message_t), packet_info->source, - LAYER_2_PROTOCOL_PING, packet_info->tos, 10); - } - else if (ping->type == MMS_PING_ECHO_REPLY) - { - if (ping->identifier == mms_ping_last_proc_id) - { - msg m; - bool wasDup = false; - char* msgDup; - char buf[10]; + mms_ping_message_t *ping = (mms_ping_message_t *)message; - if (dups[ping->seq_num-1]) { - wasDup = true; - mms_ping_dups++; - msgDup = "(DUP!)"; - } else { - mms_ping_packets++; - dups[ping->seq_num-1] = true; - msgDup = ""; - } + if(ping->type == MMS_PING_ECHO_REQUEST) { + ping->type = MMS_PING_ECHO_REPLY; + net_send((void *)ping, sizeof(mms_ping_message_t), packet_info->source, + LAYER_2_PROTOCOL_PING, packet_info->tos, 10); + } + else if(ping->type == MMS_PING_ECHO_REPLY) { + if(ping->identifier == mms_ping_last_proc_id) { + msg m; + bool wasDup = false; + char *msgDup; + char buf[10]; - if (!ping_bc_mode && !wasDup) { - utimer_remove(&mms_ping_utimer); // Stop timeout timer - } + if(dups[ping->seq_num - 1]) { + wasDup = true; + mms_ping_dups++; + msgDup = "(DUP!)"; + } + else { + mms_ping_packets++; + dups[ping->seq_num - 1] = true; + msgDup = ""; + } - float ms = ((uint32_t)clock_get_systemtime() - ping->timestamp); - if (ms < rtt_min) rtt_min = ms; - if (ms > rtt_max) rtt_max = ms; - rtt_avg += ms; - if (!ping_silent_mode) { - net_addrtostr(packet_info->source, buf, sizeof(buf)); - printf("%lu bytes from %s: seq=%u ttl=%u time=%.2f ms %s\n", - sizeof(mms_ping_message_t), buf, - ping->seq_num, *packet_info->ttl_ptr, ms, msgDup); - } - if (!ping_bc_mode && !wasDup) msg_send(&m, mms_ping_pid, false); - } - } + if(!ping_bc_mode && !wasDup) { + utimer_remove(&mms_ping_utimer); /* Stop timeout timer */ + } + + float ms = ((uint32_t)clock_get_systemtime() - ping->timestamp); + + if(ms < rtt_min) { + rtt_min = ms; + } + + if(ms > rtt_max) { + rtt_max = ms; + } + + rtt_avg += ms; + + if(!ping_silent_mode) { + net_addrtostr(packet_info->source, buf, sizeof(buf)); + printf("%lu bytes from %s: seq=%u ttl=%u time=%.2f ms %s\n", + sizeof(mms_ping_message_t), buf, + ping->seq_num, *packet_info->ttl_ptr, ms, msgDup); + } + + if(!ping_bc_mode && !wasDup) { + msg_send(&m, mms_ping_pid, false); + } + } + } } static void mms_ping(uint16_t destination, uint8_t seq, uint8_t prio, int ttl) { - mms_ping_message_t ping_request; - ping_request.type = MMS_PING_ECHO_REQUEST; - ping_request.identifier = 0; - ping_request.identifier = mms_ping_last_proc_id; - ping_request.seq_num = seq; - ping_request.timestamp = (uint32_t)clock_get_systemtime(); - net_send((void*)&ping_request, sizeof(mms_ping_message_t), - destination, LAYER_2_PROTOCOL_PING, prio, ttl); + mms_ping_message_t ping_request; + ping_request.type = MMS_PING_ECHO_REQUEST; + ping_request.identifier = 0; + ping_request.identifier = mms_ping_last_proc_id; + ping_request.seq_num = seq; + ping_request.timestamp = (uint32_t)clock_get_systemtime(); + net_send((void *)&ping_request, sizeof(mms_ping_message_t), + destination, LAYER_2_PROTOCOL_PING, prio, ttl); } /*---------------------------------------------------------------------------*/ @@ -567,85 +676,101 @@ static void mms_ping(uint16_t destination, uint8_t seq, uint8_t prio, int ttl) static void mms_ssh_connect(uint16_t destination) { - mms_ssh_message_t ssh; - ssh.type = MMS_SSH_CON_REQUEST; - mms_send((void*)&ssh, sizeof(mms_ssh_message_t), destination, - LAYER_3_PROTOCOL_SSH, PRIORITY_DATA); + mms_ssh_message_t ssh; + ssh.type = MMS_SSH_CON_REQUEST; + mms_send((void *)&ssh, sizeof(mms_ssh_message_t), destination, + LAYER_3_PROTOCOL_SSH, PRIORITY_DATA); } static void mms_ssh_reply_connect(uint16_t destination, int socket, bool accept) { - mms_ssh_message_t ssh; - ssh.type = accept ? MMS_SSH_CON_ACCEPT : MMS_SSH_CON_REJECT; - trans_sendto(socket, (void*)&ssh, sizeof(mms_ssh_message_t), - LAYER_3_PROTOCOL_SSH, PRIORITY_DATA, destination); + mms_ssh_message_t ssh; + ssh.type = accept ? MMS_SSH_CON_ACCEPT : MMS_SSH_CON_REJECT; + trans_sendto(socket, (void *)&ssh, sizeof(mms_ssh_message_t), + LAYER_3_PROTOCOL_SSH, PRIORITY_DATA, destination); } static void mms_ssh_close(uint16_t destination) { - mms_ssh_message_t ssh; - ssh.type = MMS_SSH_CON_CLOSE; - mms_send((void*)&ssh, sizeof(mms_ssh_message_t), destination, - LAYER_3_PROTOCOL_SSH, PRIORITY_DATA); + mms_ssh_message_t ssh; + ssh.type = MMS_SSH_CON_CLOSE; + mms_send((void *)&ssh, sizeof(mms_ssh_message_t), destination, + LAYER_3_PROTOCOL_SSH, PRIORITY_DATA); } -static void mms_ssh_handler(void* message, int message_size, packet_info_t* packet_info) +static void mms_ssh_handler(void *message, int message_size, + packet_info_t *packet_info) { - char adrbuf[10]; - mms_ssh_message_t* ssh = (mms_ssh_message_t*)message; - if (ssh->type == MMS_SSH_CON_REQUEST) { - if (ssh_socket > -1) { - mms_ssh_reply_connect(packet_info->source, -1, false); - return; - } - ssh_socket = trans_socket(SOCK_TCPL); - if (ssh_socket < 0) { - mms_ssh_reply_connect(packet_info->source, -1, false); - return; - } - trans_connect(ssh_socket, packet_info->source); - mms_ssh_reply_connect(packet_info->source, ssh_socket, true); - } else if (ssh->type == MMS_SSH_CON_ACCEPT) { - net_addrtostr(packet_info->source, adrbuf, sizeof(adrbuf)); - printf("SSH connection accepted by %s\n", adrbuf); - } else if (ssh->type == MMS_SSH_CON_REJECT) { - net_addrtostr(packet_info->source, adrbuf, sizeof(adrbuf)); - printf("SSH connection rejected by %s\n", adrbuf); - } else if (ssh->type == MMS_SSH_CON_CLOSE) { - if (ssh_socket > -1) { - uint16_t peer; - trans_getpeername(ssh_socket, &peer); - if (peer == packet_info->source) { - if (trans_close(ssh_socket, CLOSE_IMMEDIATE) == 1) { - ssh_socket = -1; - } - } - } - } else if (ssh->type == MMS_SSH_DATA) { - mms_ssh_data_message_t* ssh_data = (mms_ssh_data_message_t*)message; - printf((char*)ssh_data->data); - fflush(stderr); - } + char adrbuf[10]; + mms_ssh_message_t *ssh = (mms_ssh_message_t *)message; + + if(ssh->type == MMS_SSH_CON_REQUEST) { + if(ssh_socket > -1) { + mms_ssh_reply_connect(packet_info->source, -1, false); + return; + } + + ssh_socket = trans_socket(SOCK_TCPL); + + if(ssh_socket < 0) { + mms_ssh_reply_connect(packet_info->source, -1, false); + return; + } + + trans_connect(ssh_socket, packet_info->source); + mms_ssh_reply_connect(packet_info->source, ssh_socket, true); + } + else if(ssh->type == MMS_SSH_CON_ACCEPT) { + net_addrtostr(packet_info->source, adrbuf, sizeof(adrbuf)); + printf("SSH connection accepted by %s\n", adrbuf); + } + else if(ssh->type == MMS_SSH_CON_REJECT) { + net_addrtostr(packet_info->source, adrbuf, sizeof(adrbuf)); + printf("SSH connection rejected by %s\n", adrbuf); + } + else if(ssh->type == MMS_SSH_CON_CLOSE) { + if(ssh_socket > -1) { + uint16_t peer; + trans_getpeername(ssh_socket, &peer); + + if(peer == packet_info->source) { + if(trans_close(ssh_socket, CLOSE_IMMEDIATE) == 1) { + ssh_socket = -1; + } + } + } + } + else if(ssh->type == MMS_SSH_DATA) { + mms_ssh_data_message_t *ssh_data = (mms_ssh_data_message_t *)message; + printf((char *)ssh_data->data); + fflush(stderr); + } } -void mms_net_printf(const char * format) +void mms_net_printf(const char *format) { - if (ssh_socket > -1) { - mms_ssh_data_message_t ssh_data; - ssh_data.type = MMS_SSH_DATA; - int i = 0; - int len = strlen(format); - while (i < len) { - int chunk = len - i > (MMS_SSH_DATA_MAX-1) ? (MMS_SSH_DATA_MAX-1) : len - i; - memset(ssh_data.data, 0, sizeof(ssh_data.data)); - memcpy(ssh_data.data, format + i, chunk); - if (trans_send(ssh_socket, (void*)&ssh_data, sizeof(mms_ssh_data_message_t), - LAYER_3_PROTOCOL_SSH, PRIORITY_DATA) < 0) break; - i += chunk; - } - } else { - printf(format); - } + if(ssh_socket > -1) { + mms_ssh_data_message_t ssh_data; + ssh_data.type = MMS_SSH_DATA; + int i = 0; + int len = strlen(format); + + while(i < len) { + int chunk = len - i > (MMS_SSH_DATA_MAX - 1) ? (MMS_SSH_DATA_MAX - 1) : len - i; + memset(ssh_data.data, 0, sizeof(ssh_data.data)); + memcpy(ssh_data.data, format + i, chunk); + + if(trans_send(ssh_socket, (void *)&ssh_data, sizeof(mms_ssh_data_message_t), + LAYER_3_PROTOCOL_SSH, PRIORITY_DATA) < 0) { + break; + } + + i += chunk; + } + } + else { + printf(format); + } } /*---------------------------------------------------------------------------*/ @@ -654,144 +779,147 @@ void mms_net_printf(const char * format) void mms_init(void) { - mms_initp(LAYER_2_PROTOCOL_MMR, &r_iface); + mms_initp(LAYER_2_PROTOCOL_MMR, &r_iface); } -void mms_initp(protocol_t rp, route_interface_t* ri) +void mms_initp(protocol_t rp, route_interface_t *ri) { - // Initialize routing & network layer - mmr_init(); - net_init(ri); - // Initialize transport layer - trans_init(); - // Add routing as protocol handler for given route messages - net_set_protocol_handler(rp, ri->receive); - // Add transport as protocol handler for UDPL and TCPL messages - net_set_protocol_handler(LAYER_2_PROTOCOL_UDPL, trans_receive_udpl); - net_set_protocol_handler(LAYER_2_PROTOCOL_TCPL, trans_receive_tcpl); - // Add MMS ping handler - net_set_protocol_handler(LAYER_2_PROTOCOL_PING, mms_ping_handler); - // Add SSH handler - trans_set_protocol_handler(LAYER_3_PROTOCOL_SSH, mms_ssh_handler); + /* Initialize routing & network layer */ + mmr_init(); + net_init(ri); + /* Initialize transport layer */ + trans_init(); + /* Add routing as protocol handler for given route messages */ + net_set_protocol_handler(rp, ri->receive); + /* Add transport as protocol handler for UDPL and TCPL messages */ + net_set_protocol_handler(LAYER_2_PROTOCOL_UDPL, trans_receive_udpl); + net_set_protocol_handler(LAYER_2_PROTOCOL_TCPL, trans_receive_tcpl); + /* Add MMS ping handler */ + net_set_protocol_handler(LAYER_2_PROTOCOL_PING, mms_ping_handler); + /* Add SSH handler */ + trans_set_protocol_handler(LAYER_3_PROTOCOL_SSH, mms_ssh_handler); } /*---------------------------------------------------------------------------*/ -int mms_add_interface(const char* name, uint16_t addr, const radio_t* radio) +int mms_add_interface(const char *name, uint16_t addr, const radio_t *radio) { - return net_add_interface(name, addr, radio); + return net_add_interface(name, addr, radio); } /*---------------------------------------------------------------------------*/ uint16_t mms_get_interface_address(int interface_id) { - return net_get_interface_address(interface_id); + return net_get_interface_address(interface_id); } /*---------------------------------------------------------------------------*/ bool mms_set_interface_address(int interface_id, uint16_t addr) { - return net_set_interface_address(interface_id, addr); + return net_set_interface_address(interface_id, addr); } /*---------------------------------------------------------------------------*/ bool mms_set_output_power(int interface_id, uint8_t pa_idx) { - return net_set_output_power(interface_id, pa_idx); + return net_set_output_power(interface_id, pa_idx); } /*---------------------------------------------------------------------------*/ int mms_set_protocol_handler(protocol_t protocol, packet_handler_t handler) { - return trans_set_protocol_handler(protocol, handler); + return trans_set_protocol_handler(protocol, handler); } /*---------------------------------------------------------------------------*/ -void mms_receive(void* msg, int msg_size, packet_info_t* packet_info) +void mms_receive(void *msg, int msg_size, packet_info_t *packet_info) { - net_receive(msg, msg_size, packet_info); + net_receive(msg, msg_size, packet_info); } /*---------------------------------------------------------------------------*/ int mms_socket(int type) { - return trans_socket(type); + return trans_socket(type); } /*---------------------------------------------------------------------------*/ int mms_connect(int socket, uint16_t dest_addr) { - return trans_connect(socket, dest_addr); + return trans_connect(socket, dest_addr); } /*---------------------------------------------------------------------------*/ -int mms_sock_send(int socket, void* buffer, int length, protocol_t protocol, uint8_t priority) +int mms_sock_send(int socket, void *buffer, int length, protocol_t protocol, + uint8_t priority) { - return trans_send(socket, buffer, length, protocol, priority); + return trans_send(socket, buffer, length, protocol, priority); } /*---------------------------------------------------------------------------*/ -int mms_sock_sendto(int socket, void* buffer, int length, protocol_t protocol, uint8_t priority, uint16_t dest_addr) +int mms_sock_sendto(int socket, void *buffer, int length, protocol_t protocol, + uint8_t priority, uint16_t dest_addr) { - return trans_sendto(socket, buffer, length, protocol, priority, dest_addr); + return trans_sendto(socket, buffer, length, protocol, priority, dest_addr); } /*---------------------------------------------------------------------------*/ -int mms_send(void* msg, int msg_len, uint16_t dst, protocol_t protocol, uint8_t priority) +int mms_send(void *msg, int msg_len, uint16_t dst, protocol_t protocol, + uint8_t priority) { - return trans_sendto(-1, msg, msg_len, protocol, priority, dst); + return trans_sendto(-1, msg, msg_len, protocol, priority, dst); } /*---------------------------------------------------------------------------*/ int mms_poll(int socket) { - return trans_poll(socket); + return trans_poll(socket); } /*---------------------------------------------------------------------------*/ int mms_close(int socket, int how) { - return trans_close(socket, how); + return trans_close(socket, how); } /*---------------------------------------------------------------------------*/ void mms_flush_routes(bool flush_static) { - rt_flush_routes(flush_static); + rt_flush_routes(flush_static); } /*---------------------------------------------------------------------------*/ void mms_print_routes(void) { - rt_print_routes(); + rt_print_routes(); } /*---------------------------------------------------------------------------*/ void mms_print_ifconfig(int iface) { - net_print_ifconfig(iface); + net_print_ifconfig(iface); } /*---------------------------------------------------------------------------*/ void mms_print_stats(void) { - net_print_stats(); - printf("\r\n"); - r_iface.print_stats(); + net_print_stats(); + printf("\r\n"); + r_iface.print_stats(); } diff --git a/sys/net/mm/mmstack.h b/sys/net/mm/mmstack.h index 22ce8790e3..927da70b84 100644 --- a/sys/net/mm/mmstack.h +++ b/sys/net/mm/mmstack.h @@ -59,7 +59,7 @@ void mms_init(void); * @param rp Routing protocol type identifier. * @param ri Pointer to route interface. */ -void mms_initp(protocol_t rp, route_interface_t* ri); +void mms_initp(protocol_t rp, route_interface_t *ri); /** * @brief Add network interface. @@ -70,7 +70,7 @@ void mms_initp(protocol_t rp, route_interface_t* ri); * * @return Interface identifier or -1 if an error occurs. */ -int mms_add_interface(const char* name, uint16_t addr, const radio_t* radio); +int mms_add_interface(const char *name, uint16_t addr, const radio_t *radio); /** * @brief Get the address of the network interface with given id. @@ -129,12 +129,14 @@ int mms_connect(int socket, uint16_t dest_addr); /** * @see ::trans_send(int,void*,int,protocol_t,uint8_t) */ -int mms_sock_send(int socket, void* buffer, int length, protocol_t protocol, uint8_t priority); +int mms_sock_send(int socket, void *buffer, int length, protocol_t protocol, + uint8_t priority); /** * @see ::trans_sendto(int,void*,int,protocol_t,uint8_t,uint16_t) */ -int mms_sock_sendto(int socket, void* buffer, int length, protocol_t protocol, uint8_t priority, uint16_t dest_addr); +int mms_sock_sendto(int socket, void *buffer, int length, protocol_t protocol, + uint8_t priority, uint16_t dest_addr); /** * @brief Convenience function to send a message via UDPL socket. @@ -148,7 +150,8 @@ int mms_sock_sendto(int socket, void* buffer, int length, protocol_t protocol, u * @return Upon successful completion, mms_send() returns a value greater zero. * Otherwise, a negative value is returned to indicate the error. */ -int mms_send(void* msg, int msg_len, uint16_t dst, protocol_t protocol, uint8_t priority); +int mms_send(void *msg, int msg_len, uint16_t dst, protocol_t protocol, + uint8_t priority); /** * @see ::trans_poll(int) @@ -170,7 +173,7 @@ int mms_close(int socket, int how); * @param msg_size Size of incoming packet. * @param packet_info Additional packet information. */ -void mms_receive(void* msg, int msg_size, packet_info_t* packet_info); +void mms_receive(void *msg, int msg_size, packet_info_t *packet_info); /** * @brief Flush kernel route table. @@ -188,7 +191,7 @@ void mms_flush_routes(bool flush_static); * * @param format String that contains the text to be written to stdout. */ -void mms_net_printf(const char * format); +void mms_net_printf(const char *format); /** * @brief Print kernel route table. diff --git a/sys/net/sixlowpan/bordermultiplex.c b/sys/net/sixlowpan/bordermultiplex.c index 0e8d2d384a..e122ba09d8 100644 --- a/sys/net/sixlowpan/bordermultiplex.c +++ b/sys/net/sixlowpan/bordermultiplex.c @@ -1,3 +1,21 @@ +/** + * 6lowpan border router multiplexer + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup sixlowpan + * @{ + * @file bordermultiplex.c + * @brief multiplexiing border router information + * @author Martin Lenders + * @author Oliver Hahm + * @} + */ + #include #include @@ -16,158 +34,179 @@ #define END_ESC 0xDC #define ESC_ESC 0xDD -void demultiplex(border_packet_t *packet, int len) { - switch (packet->type) { - case (BORDER_PACKET_RAW_TYPE):{ - fputs(((char *)packet) + sizeof (border_packet_t), stdin); +void demultiplex(border_packet_t *packet, int len) +{ + switch(packet->type) { + case(BORDER_PACKET_RAW_TYPE): { + fputs(((char *)packet) + sizeof(border_packet_t), stdin); break; } - case (BORDER_PACKET_L3_TYPE):{ + + case(BORDER_PACKET_L3_TYPE): { border_l3_header_t *l3_header_buf = (border_l3_header_t *)packet; - switch (l3_header_buf->ethertype) { - case (BORDER_ETHERTYPE_IPV6):{ - struct ipv6_hdr_t *ipv6_buf = (struct ipv6_hdr_t *)(((unsigned char *)packet) + sizeof (border_l3_header_t)); + + switch(l3_header_buf->ethertype) { + case(BORDER_ETHERTYPE_IPV6): { + struct ipv6_hdr_t *ipv6_buf = (struct ipv6_hdr_t *)(((unsigned char *)packet) + sizeof(border_l3_header_t)); border_send_ipv6_over_lowpan(ipv6_buf, 1, 1); break; } + default: printf("ERROR: Unknown ethertype 0x%04x\n", l3_header_buf->ethertype); break; } + break; } - case (BORDER_PACKET_CONF_TYPE):{ + + case(BORDER_PACKET_CONF_TYPE): { border_conf_header_t *conf_header_buf = (border_conf_header_t *)packet; - switch (conf_header_buf->conftype) { - case (BORDER_CONF_CONTEXT):{ + + switch(conf_header_buf->conftype) { + case(BORDER_CONF_CONTEXT): { border_context_packet_t *context = (border_context_packet_t *)packet; ipv6_addr_t target_addr; ipv6_set_all_nds_mcast_addr(&target_addr); mutex_lock(&lowpan_context_mutex); lowpan_context_update( - context->context.cid, - &context->context.prefix, - context->context.length, - context->context.comp, - context->context.lifetime - ); - mutex_unlock(&lowpan_context_mutex,0); + context->context.cid, + &context->context.prefix, + context->context.length, + context->context.comp, + context->context.lifetime + ); + mutex_unlock(&lowpan_context_mutex, 0); abr_add_context(context->context.version, &abr_addr, context->context.cid); - // Send router advertisement + /* Send router advertisement */ break; } - case (BORDER_CONF_IPADDR):{ + + case(BORDER_CONF_IPADDR): { //border_addr_packet_t *addr_packet = (border_addr_packet_t *)packet; - // add address + /* add address */ break; } + default: printf("ERROR: Unknown conftype %02x\n", conf_header_buf->conftype); break; } + break; } + default: printf("ERROR: Unknown border packet type %02x\n", packet->type); break; } } -void multiplex_send_ipv6_over_uart(struct ipv6_hdr_t *packet) { +void multiplex_send_ipv6_over_uart(struct ipv6_hdr_t *packet) +{ border_l3_header_t *serial_buf; - + serial_buf = (border_l3_header_t *)get_serial_out_buffer(0); serial_buf->empty = 0; serial_buf->type = BORDER_PACKET_L3_TYPE; serial_buf->ethertype = BORDER_ETHERTYPE_IPV6; - memcpy(get_serial_in_buffer(0)+sizeof (border_l3_header_t), packet, IPV6_HDR_LEN + packet->length); - - flowcontrol_send_over_uart((border_packet_t *) serial_buf, sizeof (border_l3_header_t)); + memcpy(get_serial_in_buffer(0) + sizeof(border_l3_header_t), packet, IPV6_HDR_LEN + packet->length); + + flowcontrol_send_over_uart((border_packet_t *) serial_buf, sizeof(border_l3_header_t)); } -void multiplex_send_addr_over_uart(ipv6_addr_t *addr) { +void multiplex_send_addr_over_uart(ipv6_addr_t *addr) +{ border_addr_packet_t *serial_buf; - + serial_buf = (border_addr_packet_t *)get_serial_in_buffer(0); serial_buf->empty = 0; serial_buf->type = BORDER_PACKET_CONF_TYPE; serial_buf->conftype = BORDER_CONF_IPADDR; memcpy(&serial_buf->addr, addr, sizeof(ipv6_addr_t)); - - flowcontrol_send_over_uart((border_packet_t *) serial_buf, sizeof (border_addr_packet_t)); + + flowcontrol_send_over_uart((border_packet_t *) serial_buf, sizeof(border_addr_packet_t)); } -int readpacket(uint8_t *packet_buf, size_t size) { +int readpacket(uint8_t *packet_buf, size_t size) +{ uint8_t *line_buf_ptr = packet_buf; - uint8_t byte = END+1; + uint8_t byte = END + 1; uint8_t esc = 0; - - while (1) { + + while(1) { byte = uart0_readc(); - - if (byte == END) { + + if(byte == END) { break; } - - if ( (line_buf_ptr - packet_buf) >= size-1) { + + if((line_buf_ptr - packet_buf) >= size - 1) { return -SIXLOWERROR_ARRAYFULL; } - - if (esc) { + + if(esc) { esc = 0; - switch (byte) { - case(END_ESC):{ + + switch(byte) { + case(END_ESC): { *line_buf_ptr++ = END; continue; } - case(ESC_ESC):{ + + case(ESC_ESC): { *line_buf_ptr++ = ESC; continue; } + default: continue; } } - - if (byte == ESC) { + + if(byte == ESC) { esc = 1; continue; } - + *line_buf_ptr++ = byte; } - + return (line_buf_ptr - packet_buf - 1); } -int writepacket(uint8_t *packet_buf, size_t size) { +int writepacket(uint8_t *packet_buf, size_t size) +{ uint8_t *byte_ptr = packet_buf; - - while ((byte_ptr - packet_buf) < size) { - if ((byte_ptr - packet_buf) > BORDER_BUFFER_SIZE) { + + while((byte_ptr - packet_buf) < size) { + if((byte_ptr - packet_buf) > BORDER_BUFFER_SIZE) { return -1; } - - switch (*byte_ptr) { - case(END):{ + + switch(*byte_ptr) { + case(END): { *byte_ptr = END_ESC; uart0_putc(ESC); break; } - case(ESC):{ + + case(ESC): { *byte_ptr = ESC_ESC; uart0_putc(ESC); break; } - default:{ + + default: { break; } } + uart0_putc(*byte_ptr); byte_ptr++; } - + uart0_putc(END); - + return (byte_ptr - packet_buf); } diff --git a/sys/net/sixlowpan/bordermultiplex.h b/sys/net/sixlowpan/bordermultiplex.h index f793cace40..e131409949 100644 --- a/sys/net/sixlowpan/bordermultiplex.h +++ b/sys/net/sixlowpan/bordermultiplex.h @@ -1,3 +1,21 @@ +/** + * 6lowpan border router multiplexer + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup sixlowpan + * @{ + * @file bordermultiplex.h + * @brief data structs for border router multiplexing + * @author Martin Lenders + * @author Oliver Hahm + * @} + */ + #ifndef BORDERMULTIPLEX_H #define BORDERMULTIPLEX_H @@ -18,27 +36,27 @@ /* ethertypes for L3 packets */ #define BORDER_ETHERTYPE_IPV6 0x86DD -typedef struct __attribute__ ((packed)) border_packet_t { +typedef struct __attribute__((packed)) { uint8_t empty; uint8_t type; uint8_t seq_num; } border_packet_t; -typedef struct __attribute__ ((packed)) border_l3_header_t { +typedef struct __attribute__((packed)) { uint8_t empty; uint8_t type; uint8_t seq_num; uint16_t ethertype; } border_l3_header_t; -typedef struct __attribute__ ((packed)) border_conf_header_t { +typedef struct __attribute__((packed)) { uint8_t empty; uint8_t type; uint8_t seq_num; uint8_t conftype; } border_conf_header_t; -typedef struct __attribute__ ((packed)) border_addr_packet_t { +typedef struct __attribute__((packed)) { uint8_t empty; uint8_t type; uint8_t seq_num; @@ -47,7 +65,7 @@ typedef struct __attribute__ ((packed)) border_addr_packet_t { ipv6_addr_t addr; } border_addr_packet_t; -typedef struct __attribute__ ((packed)) border_context_packet_t { +typedef struct __attribute__((packed)) { uint8_t empty; uint8_t type; uint8_t seq_num; diff --git a/sys/net/sixlowpan/flowcontrol.c b/sys/net/sixlowpan/flowcontrol.c index 11ebe81e53..b1efee889d 100644 --- a/sys/net/sixlowpan/flowcontrol.c +++ b/sys/net/sixlowpan/flowcontrol.c @@ -1,3 +1,21 @@ +/** + * 6lowpan border router flow control + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup sixlowpan + * @{ + * @file flowcontrol.c + * @brief flowcontrol for constraint node border router implementation + * @author Martin Lenders + * @author Oliver Hahm + * @} + */ + #include #include #include @@ -20,53 +38,59 @@ flowcontrol_stat_t slwin_stat; sem_t connection_established; int16_t synack_seqnum = -1; -ipv6_addr_t init_threeway_handshake(void) { +ipv6_addr_t init_threeway_handshake(void) +{ border_syn_packet_t *syn; msg_t m; m.content.ptr = NULL; - msg_send(&m,border_get_serial_reader(),1); + msg_send(&m, border_get_serial_reader(), 1); msg_receive(&m); - + syn = (border_syn_packet_t *)m.content.ptr; border_conf_header_t *synack = (border_conf_header_t *)get_serial_out_buffer(0); ipv6_addr_t addr; - memcpy(&addr, &(syn->addr), sizeof (ipv6_addr_t)); - + memcpy(&addr, &(syn->addr), sizeof(ipv6_addr_t)); + slwin_stat.next_exp = syn->next_seq_num; slwin_stat.last_frame = syn->next_exp - 1; slwin_stat.last_ack = slwin_stat.last_frame; - + synack->empty = 0; synack->type = BORDER_PACKET_CONF_TYPE; synack->conftype = BORDER_CONF_SYNACK; - - sending_slot_pid = thread_create(sending_slot_stack, SENDING_SLOT_STACK_SIZE, PRIORITY_MAIN-1, CREATE_SLEEPING, sending_slot, "sending slot"); - flowcontrol_send_over_uart((border_packet_t *)synack, sizeof (border_conf_header_t)); - + + sending_slot_pid = thread_create(sending_slot_stack, SENDING_SLOT_STACK_SIZE, PRIORITY_MAIN - 1, CREATE_SLEEPING, sending_slot, "sending slot"); + flowcontrol_send_over_uart((border_packet_t *)synack, sizeof(border_conf_header_t)); + synack_seqnum = synack->seq_num; - + return addr; } -ipv6_addr_t flowcontrol_init(void) { +ipv6_addr_t flowcontrol_init(void) +{ int i; - - sem_init(&slwin_stat.send_win_not_full,BORDER_SWS); + + sem_init(&slwin_stat.send_win_not_full, BORDER_SWS); + for(i = 0; i < BORDER_SWS; i++) { slwin_stat.send_win[i].frame_len = 0; } - memset(&slwin_stat.send_win,0, sizeof(struct send_slot) * BORDER_SWS); - + + memset(&slwin_stat.send_win, 0, sizeof(struct send_slot) * BORDER_SWS); + for(i = 0; i < BORDER_RWS; i++) { slwin_stat.recv_win[i].received = 0; slwin_stat.recv_win[i].frame_len = 0; } - memset(&slwin_stat.recv_win,0, sizeof(struct recv_slot) * BORDER_RWS); - + + memset(&slwin_stat.recv_win, 0, sizeof(struct recv_slot) * BORDER_RWS); + return init_threeway_handshake(); } -static void sending_slot(void) { +static void sending_slot(void) +{ msg_t m; uint8_t seq_num; struct send_slot *slot; @@ -76,93 +100,104 @@ static void sending_slot(void) { msg_receive(&m); seq_num = *((uint8_t *)m.content.ptr); slot = &(slwin_stat.send_win[seq_num % BORDER_SWS]); - tmp = (border_packet_t*) slot->frame; + tmp = (border_packet_t *)slot->frame; - if (seq_num == tmp->seq_num) { - writepacket(slot->frame,slot->frame_len); - - if (set_timeout(&slot->timeout, BORDER_SL_TIMEOUT, (void*) m.content.ptr) != 0) { + if(seq_num == tmp->seq_num) { + writepacket(slot->frame, slot->frame_len); + + if(set_timeout(&slot->timeout, BORDER_SL_TIMEOUT, (void *)m.content.ptr) != 0) { printf("ERROR: Error invoking timeout timer\n"); } } } } -static int set_timeout(vtimer_t *timeout, long useconds, void *args) { +static int set_timeout(vtimer_t *timeout, long useconds, void *args) +{ timex_t interval; interval.seconds = useconds / 1000000; interval.microseconds = (useconds % 1000000) * 1000; - + return vtimer_set_msg(timeout, interval, sending_slot_pid, args); } -static int in_window(uint8_t seq_num, uint8_t min, uint8_t max) { +static int in_window(uint8_t seq_num, uint8_t min, uint8_t max) +{ uint8_t pos = seq_num - min; uint8_t maxpos = max - min + 1; return pos < maxpos; } -void flowcontrol_send_over_uart(border_packet_t *packet, int len) { +void flowcontrol_send_over_uart(border_packet_t *packet, int len) +{ struct send_slot *slot; uint8_t args[] = {packet->seq_num}; - + sem_wait(&(slwin_stat.send_win_not_full)); packet->seq_num = ++slwin_stat.last_frame; slot = &(slwin_stat.send_win[packet->seq_num % BORDER_SWS]); memcpy(slot->frame, (uint8_t *)packet, len); slot->frame_len = len; - if (set_timeout(&slot->timeout, BORDER_SL_TIMEOUT, (void *)args) != 0) { + + if(set_timeout(&slot->timeout, BORDER_SL_TIMEOUT, (void *)args) != 0) { printf("ERROR: Error invoking timeout timer\n"); return; } + writepacket((uint8_t *)packet, len); } -void send_ack(uint8_t seq_num) { +void send_ack(uint8_t seq_num) +{ border_packet_t *packet = (border_packet_t *)get_serial_out_buffer(0); packet->empty = 0; packet->type = BORDER_PACKET_ACK_TYPE; packet->seq_num = seq_num; - writepacket((uint8_t *)packet, sizeof (border_packet_t)); + writepacket((uint8_t *)packet, sizeof(border_packet_t)); } -void flowcontrol_deliver_from_uart(border_packet_t *packet, int len) { - if (packet->type == BORDER_PACKET_ACK_TYPE) { - if (in_window(packet->seq_num, slwin_stat.last_ack+1, slwin_stat.last_frame)) { - if (synack_seqnum == packet->seq_num) { +void flowcontrol_deliver_from_uart(border_packet_t *packet, int len) +{ + if(packet->type == BORDER_PACKET_ACK_TYPE) { + if(in_window(packet->seq_num, slwin_stat.last_ack + 1, slwin_stat.last_frame)) { + if(synack_seqnum == packet->seq_num) { synack_seqnum = -1; sem_signal(&connection_established); } + do { struct send_slot *slot; slot = &(slwin_stat.send_win[++slwin_stat.last_ack % BORDER_SWS]); vtimer_remove(&slot->timeout); - memset(&slot->frame,0,BORDER_BUFFER_SIZE); + memset(&slot->frame, 0, BORDER_BUFFER_SIZE); sem_signal(&slwin_stat.send_win_not_full); - } while (slwin_stat.last_ack != packet->seq_num); + } + while(slwin_stat.last_ack != packet->seq_num); } - } else { + } + else { struct recv_slot *slot; - + slot = &(slwin_stat.recv_win[packet->seq_num % BORDER_RWS]); - if ( !in_window(packet->seq_num, - slwin_stat.next_exp, - slwin_stat.next_exp + BORDER_RWS - 1)) { + + if(!in_window(packet->seq_num, + slwin_stat.next_exp, + slwin_stat.next_exp + BORDER_RWS - 1)) { return; } - + memcpy(slot->frame, (uint8_t *)packet, len); slot->received = 1; - - if (packet->seq_num == slwin_stat.next_exp) { - while (slot->received) { + + if(packet->seq_num == slwin_stat.next_exp) { + while(slot->received) { demultiplex((border_packet_t *)slot->frame, slot->frame_len); - memset(&slot->frame,0,BORDER_BUFFER_SIZE); + memset(&slot->frame, 0, BORDER_BUFFER_SIZE); slot->received = 0; slot = &slwin_stat.recv_win[++(slwin_stat.next_exp) % BORDER_RWS]; } } - + send_ack(slwin_stat.next_exp - 1); } } diff --git a/sys/net/sixlowpan/flowcontrol.h b/sys/net/sixlowpan/flowcontrol.h index 060e049014..61c1842afb 100644 --- a/sys/net/sixlowpan/flowcontrol.h +++ b/sys/net/sixlowpan/flowcontrol.h @@ -1,3 +1,21 @@ +/** + * 6lowpan border router flow control + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup sixlowpan + * @{ + * @file flowcontrol.h + * @brief data structs for border router flowcontrol + * @author Martin Lenders + * @author Oliver Hahm + * @} + */ + #ifndef FLOWCONTROL_H #define FLOWCONTROL_H @@ -22,17 +40,17 @@ #define SENDING_SLOT_STACK_SIZE (256) -typedef struct flowcontrol_stat_t { +typedef struct { /* Sender state */ uint8_t last_ack; uint8_t last_frame; sem_t send_win_not_full; struct send_slot { - vtimer_t timeout; + vtimer_t timeout; uint8_t frame[BORDER_BUFFER_SIZE]; size_t frame_len; } send_win[BORDER_SWS]; - + /* Receiver state */ uint8_t next_exp; struct recv_slot { @@ -42,7 +60,7 @@ typedef struct flowcontrol_stat_t { } recv_win[BORDER_RWS]; } flowcontrol_stat_t; -typedef struct __attribute__ ((packed)) border_syn_packet_t { +typedef struct __attribute__((packed)) { uint8_t empty; uint8_t type; uint8_t next_seq_num; diff --git a/sys/net/sixlowpan/ieee802154_frame.c b/sys/net/sixlowpan/ieee802154_frame.c index 65ee2f1d2e..fb5aa48dbc 100644 --- a/sys/net/sixlowpan/ieee802154_frame.c +++ b/sys/net/sixlowpan/ieee802154_frame.c @@ -1,80 +1,102 @@ +/** + * implementation for the IEEE 802.15.4 frame format + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup sixlowpan + * @{ + * @file ieee802154_frame.c + * @brief IEEE 802.14.4 framing operations + * @author Stephan Zeisberg + * @author Oliver Hahm + * @} + */ + #include "ieee802154_frame.h" -//uint8_t mac_buf[IEEE_802154_HDR_LEN + IEEE_802154_PAYLOAD_LEN]; uint8_t ieee802154_hdr_ptr; uint8_t ieee802154_payload_ptr; uint16_t ieee802154_payload_len; -uint8_t init_802154_frame(ieee802154_frame_t *frame, uint8_t *buf){ +uint8_t init_802154_frame(ieee802154_frame_t *frame, uint8_t *buf) +{ /* Frame Control Field - 802.15.4 - 2006 - 7.2.1.1 */ uint8_t index = 0; - + buf[index] = ((frame->fcf.frame_type << 5) | - (frame->fcf.sec_enb << 4) | - (frame->fcf.frame_pend << 3) | - (frame->fcf.ack_req << 2) | - (frame->fcf.panid_comp << 1)); + (frame->fcf.sec_enb << 4) | + (frame->fcf.frame_pend << 3) | + (frame->fcf.ack_req << 2) | + (frame->fcf.panid_comp << 1)); index++; buf[index] = ((frame->fcf.dest_addr_m << 4) | - (frame->fcf.frame_ver << 2) | - (frame->fcf.src_addr_m)); + (frame->fcf.frame_ver << 2) | + (frame->fcf.src_addr_m)); index++; /* Sequence Number - 802.15.4 - 2006 - 7.2.1.2 */ - buf[index] = frame->seq_nr; + buf[index] = frame->seq_nr; index++; /* Destination PAN Identifier - 802.15.4 - 2006 - 7.2.1.3 */ - if(frame->fcf.dest_addr_m == 0x02 || frame->fcf.dest_addr_m == 0x03){ + if(frame->fcf.dest_addr_m == 0x02 || frame->fcf.dest_addr_m == 0x03) { buf[index] = ((frame->dest_pan_id >> 8) & 0xff); - buf[index+1] = (frame->dest_pan_id & 0xff); + buf[index + 1] = (frame->dest_pan_id & 0xff); } + index += 2; /* Destination Address - 802.15.4 - 2006 - 7.2.1.4 */ - if(frame->fcf.dest_addr_m == 0x02){ - buf[index] = frame->dest_addr[0]; - buf[index+1] = frame->dest_addr[1]; + if(frame->fcf.dest_addr_m == 0x02) { + buf[index] = frame->dest_addr[0]; + buf[index + 1] = frame->dest_addr[1]; index += 2; - } else if(frame->fcf.dest_addr_m == 0x03){ - buf[index] = frame->dest_addr[0]; - buf[index+1] = frame->dest_addr[1]; - buf[index+2] = frame->dest_addr[2]; - buf[index+3] = frame->dest_addr[3]; - buf[index+4] = frame->dest_addr[4]; - buf[index+5] = frame->dest_addr[5]; - buf[index+6] = frame->dest_addr[6]; - buf[index+7] = frame->dest_addr[7]; + } + else if(frame->fcf.dest_addr_m == 0x03) { + buf[index] = frame->dest_addr[0]; + buf[index + 1] = frame->dest_addr[1]; + buf[index + 2] = frame->dest_addr[2]; + buf[index + 3] = frame->dest_addr[3]; + buf[index + 4] = frame->dest_addr[4]; + buf[index + 5] = frame->dest_addr[5]; + buf[index + 6] = frame->dest_addr[6]; + buf[index + 7] = frame->dest_addr[7]; index += 8; } /* Source PAN Identifier - 802.15.4 - 2006 - 7.2.1.5 */ - if(!(frame->fcf.panid_comp & 0x01)){ - if(frame->fcf.src_addr_m == 0x02 || frame->fcf.src_addr_m == 0x03){ - buf[index] = ((frame->src_pan_id >> 8) & 0xff); - buf[index+1] = (frame->src_pan_id & 0xff); + if(!(frame->fcf.panid_comp & 0x01)) { + if(frame->fcf.src_addr_m == 0x02 || frame->fcf.src_addr_m == 0x03) { + buf[index] = ((frame->src_pan_id >> 8) & 0xff); + buf[index + 1] = (frame->src_pan_id & 0xff); index += 2; } } + /* Source Address field - 802.15.4 - 2006 - 7.2.1.6 */ - if(frame->fcf.src_addr_m == 0x02){ - buf[index] = frame->src_addr[0]; - buf[index+1] = frame->src_addr[1]; - index += 2; - } else if(frame->fcf.src_addr_m == 0x03){ - buf[index] = frame->src_addr[0]; - buf[index+1] = frame->src_addr[1]; - buf[index+2] = frame->src_addr[2]; - buf[index+3] = frame->src_addr[3]; - buf[index+4] = frame->src_addr[4]; - buf[index+5] = frame->src_addr[5]; - buf[index+6] = frame->src_addr[6]; - buf[index+7] = frame->src_addr[7]; + if(frame->fcf.src_addr_m == 0x02) { + buf[index] = frame->src_addr[0]; + buf[index + 1] = frame->src_addr[1]; + index += 2; + } + else if(frame->fcf.src_addr_m == 0x03) { + buf[index] = frame->src_addr[0]; + buf[index + 1] = frame->src_addr[1]; + buf[index + 2] = frame->src_addr[2]; + buf[index + 3] = frame->src_addr[3]; + buf[index + 4] = frame->src_addr[4]; + buf[index + 5] = frame->src_addr[5]; + buf[index + 6] = frame->src_addr[6]; + buf[index + 7] = frame->src_addr[7]; index += 8; } - return index; + return index; } /** 2 1 2 VAR 2 VAR @@ -82,39 +104,44 @@ uint8_t init_802154_frame(ieee802154_frame_t *frame, uint8_t *buf){ * | FCF | DSN | DPID | DAD | SPID | SAD | * ------------------------------------------- */ -uint8_t get_802154_hdr_len(ieee802154_frame_t *frame){ +uint8_t get_802154_hdr_len(ieee802154_frame_t *frame) +{ uint8_t len = 0; - if(frame->fcf.dest_addr_m == 0x02){ + if(frame->fcf.dest_addr_m == 0x02) { len += 2; - } else if(frame->fcf.dest_addr_m == 0x03){ + } + else if(frame->fcf.dest_addr_m == 0x03) { len += 8; } - - if(frame->fcf.src_addr_m == 0x02){ + + if(frame->fcf.src_addr_m == 0x02) { len += 2; - } else if(frame->fcf.src_addr_m == 0x03){ + } + else if(frame->fcf.src_addr_m == 0x03) { len += 8; } - - if((frame->fcf.dest_addr_m == 0x02) || (frame->fcf.dest_addr_m == 0x03)){ + + if((frame->fcf.dest_addr_m == 0x02) || (frame->fcf.dest_addr_m == 0x03)) { len += 2; } - if((frame->fcf.src_addr_m == 0x02) || (frame->fcf.src_addr_m == 0x03)){ + + if((frame->fcf.src_addr_m == 0x02) || (frame->fcf.src_addr_m == 0x03)) { len += 2; - } - + } + /* if src pan id == dest pan id set compression bit */ - if(frame->src_pan_id == frame->dest_pan_id){ + if(frame->src_pan_id == frame->dest_pan_id) { frame->fcf.panid_comp = 1; len -= 2; - } - + } + /* (DPID + DAD + SPID + SAD) + (FCF + DSN) */ return (len + 3); } -uint8_t read_802154_frame(uint8_t *buf, ieee802154_frame_t *frame, uint8_t len){ +uint8_t read_802154_frame(uint8_t *buf, ieee802154_frame_t *frame, uint8_t len) +{ uint8_t index = 0; uint8_t hdrlen; @@ -138,60 +165,64 @@ uint8_t read_802154_frame(uint8_t *buf, ieee802154_frame_t *frame, uint8_t len){ index++; - frame->dest_pan_id = (((uint16_t)buf[index]) << 8) | buf[index+1]; - + frame->dest_pan_id = (((uint16_t)buf[index]) << 8) | buf[index + 1]; + index += 2; - switch(frame->fcf.dest_addr_m){ - case(0):{ + switch(frame->fcf.dest_addr_m) { + case(0): { printf("fcf.dest_addr_m: pan identifier/address fields empty\n"); break; } - case(2):{ + + case(2): { frame->dest_addr[0] = buf[index]; - frame->dest_addr[1] = buf[index+1]; + frame->dest_addr[1] = buf[index + 1]; index += 2; break; } - case(3):{ + + case(3): { frame->dest_addr[0] = buf[index]; - frame->dest_addr[1] = buf[index+1]; - frame->dest_addr[2] = buf[index+2]; - frame->dest_addr[3] = buf[index+3]; - frame->dest_addr[4] = buf[index+4]; - frame->dest_addr[5] = buf[index+5]; - frame->dest_addr[6] = buf[index+6]; - frame->dest_addr[7] = buf[index+7]; + frame->dest_addr[1] = buf[index + 1]; + frame->dest_addr[2] = buf[index + 2]; + frame->dest_addr[3] = buf[index + 3]; + frame->dest_addr[4] = buf[index + 4]; + frame->dest_addr[5] = buf[index + 5]; + frame->dest_addr[6] = buf[index + 6]; + frame->dest_addr[7] = buf[index + 7]; index += 8; break; } } - - if(!(frame->fcf.panid_comp == 1)){ - frame->src_pan_id = (((uint16_t)buf[index]) << 8) | buf[index+1]; + + if(!(frame->fcf.panid_comp == 1)) { + frame->src_pan_id = (((uint16_t)buf[index]) << 8) | buf[index + 1]; index += 2; } - - switch(frame->fcf.src_addr_m){ - case(0):{ + + switch(frame->fcf.src_addr_m) { + case(0): { printf("fcf.src_addr_m: pan identifier/address fields empty\n"); break; } - case(2):{ + + case(2): { frame->src_addr[0] = buf[index]; - frame->src_addr[1] = buf[index+1]; + frame->src_addr[1] = buf[index + 1]; index += 2; break; } - case(3):{ + + case(3): { frame->src_addr[0] = buf[index]; - frame->src_addr[1] = buf[index+1]; - frame->src_addr[2] = buf[index+2]; - frame->src_addr[3] = buf[index+3]; - frame->src_addr[4] = buf[index+4]; - frame->src_addr[5] = buf[index+5]; - frame->src_addr[6] = buf[index+6]; - frame->src_addr[7] = buf[index+7]; + frame->src_addr[1] = buf[index + 1]; + frame->src_addr[2] = buf[index + 2]; + frame->src_addr[3] = buf[index + 3]; + frame->src_addr[4] = buf[index + 4]; + frame->src_addr[5] = buf[index + 5]; + frame->src_addr[6] = buf[index + 6]; + frame->src_addr[7] = buf[index + 7]; index += 8; break; } @@ -200,19 +231,20 @@ uint8_t read_802154_frame(uint8_t *buf, ieee802154_frame_t *frame, uint8_t len){ frame->payload = (buf + index); hdrlen = index; frame->payload_len = (len - hdrlen); - - return hdrlen; + + return hdrlen; } -void print_802154_fcf_frame(ieee802154_frame_t *frame){ +void print_802154_fcf_frame(ieee802154_frame_t *frame) +{ printf("frame type: %02x\n" - "security enabled: %02x\n" - "frame pending: %02x\n" + "security enabled: %02x\n" + "frame pending: %02x\n" "ack requested: %02x\n" "pan id compression: %02x\n" "destination address mode: %02x\n" "frame version: %02x\n" - "source address mode: %02x\n", + "source address mode: %02x\n", frame->fcf.frame_type, frame->fcf.sec_enb, frame->fcf.frame_pend, @@ -220,5 +252,5 @@ void print_802154_fcf_frame(ieee802154_frame_t *frame){ frame->fcf.panid_comp, frame->fcf.dest_addr_m, frame->fcf.frame_ver, - frame->fcf.src_addr_m); + frame->fcf.src_addr_m); } diff --git a/sys/net/sixlowpan/ieee802154_frame.h b/sys/net/sixlowpan/ieee802154_frame.h index e482dd9c27..7ae6b482a2 100644 --- a/sys/net/sixlowpan/ieee802154_frame.h +++ b/sys/net/sixlowpan/ieee802154_frame.h @@ -1,3 +1,21 @@ +/** + * Data struct and prototypes for the IEEE 802.15.4 frame format + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup sixlowpan + * @{ + * @file ieee802154_frame.h + * @brief IEEE 802.14.4 framing data structs and prototypes + * @author Stephan Zeisberg + * @author Oliver Hahm + * @} + */ + #ifndef IEEE802154_FRAME #define IEEE802154_FRAME @@ -6,7 +24,7 @@ /* maximum 802.15.4 header length */ #define IEEE_802154_MAX_HDR_LEN 23 -/* mininmum */ +/* mininmum */ #define IEEE_802154_PAYLOAD_LEN 21 #define IEEE_802154_BEACON_FRAME 0 @@ -19,7 +37,7 @@ #define IEEE_802154_PAN_ID 0x1234 -typedef struct __attribute__ ((packed)) { +typedef struct __attribute__((packed)) { uint8_t frame_type; uint8_t sec_enb; uint8_t frame_pend; @@ -27,10 +45,10 @@ typedef struct __attribute__ ((packed)) { uint8_t panid_comp; uint8_t dest_addr_m; uint8_t frame_ver; - uint8_t src_addr_m; + uint8_t src_addr_m; } ieee802154_fcf_frame_t; -typedef struct __attribute__ ((packed)) { +typedef struct __attribute__((packed)) { ieee802154_fcf_frame_t fcf; uint8_t seq_nr; uint16_t dest_pan_id; diff --git a/sys/net/sixlowpan/rpl/objective_functions.c b/sys/net/sixlowpan/rpl/objective_functions.c index 9eb637111d..cf22f81215 100644 --- a/sys/net/sixlowpan/rpl/objective_functions.c +++ b/sys/net/sixlowpan/rpl/objective_functions.c @@ -1,6 +1,7 @@ #include "objective_functions.h" -void of0(void){ +void of0(void) +{ } diff --git a/sys/net/sixlowpan/rpl/of0.c b/sys/net/sixlowpan/rpl/of0.c index 2719dedd26..81658dbd4c 100644 --- a/sys/net/sixlowpan/rpl/of0.c +++ b/sys/net/sixlowpan/rpl/of0.c @@ -1,52 +1,79 @@ +/** + * Objective function 0 for RPL implementation + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup rpl + * @{ + * @file of0.c + * @brief RPL objective function 0 + * @author Eric Engel + * @} + */ + #include #include "of0.h" rpl_of_t rpl_of0 = { - 0x0, - calc_rank, - which_parent, - which_dodag, - reset, - NULL + 0x0, + calc_rank, + which_parent, + which_dodag, + reset, + NULL }; -rpl_of_t *rpl_get_of0(void){ - return &rpl_of0; +rpl_of_t *rpl_get_of0(void) +{ + return &rpl_of0; } -void reset(rpl_dodag_t *dodag){ - //Nothing to do in OF0 +void reset(rpl_dodag_t *dodag) +{ + /* Nothing to do in OF0 */ } -uint16_t calc_rank(rpl_parent_t * parent, uint16_t base_rank){ - if(base_rank == 0) { - if(parent == NULL) { - return INFINITE_RANK; - } - base_rank = parent->rank; - } +uint16_t calc_rank(rpl_parent_t *parent, uint16_t base_rank) +{ + if(base_rank == 0) { + if(parent == NULL) { + return INFINITE_RANK; + } - uint16_t add; - if(parent != NULL){ - add = parent->dodag->minhoprankincrease; - } - else{ - add = DEFAULT_MIN_HOP_RANK_INCREASE; - } - if( base_rank + add < base_rank ){ - return INFINITE_RANK; - } - return base_rank + add; + base_rank = parent->rank; + } + + uint16_t add; + + if(parent != NULL) { + add = parent->dodag->minhoprankincrease; + } + else { + add = DEFAULT_MIN_HOP_RANK_INCREASE; + } + + if(base_rank + add < base_rank) { + return INFINITE_RANK; + } + + return base_rank + add; } -//We simply return the Parent with lower rank -rpl_parent_t * which_parent(rpl_parent_t *p1, rpl_parent_t *p2){ - if(p1->rank < p2->rank){ - return p1; - } - return p2; +/* We simply return the Parent with lower rank */ +rpl_parent_t *which_parent(rpl_parent_t *p1, rpl_parent_t *p2) +{ + if(p1->rank < p2->rank) { + return p1; + } + + return p2; } -rpl_dodag_t * which_dodag(rpl_dodag_t *d1, rpl_dodag_t *d2){ - return d1; +rpl_dodag_t *which_dodag(rpl_dodag_t *d1, rpl_dodag_t *d2) +{ + return d1; } diff --git a/sys/net/sixlowpan/rpl/rpl.c b/sys/net/sixlowpan/rpl/rpl.c index 14d72486b3..09c77ed1c8 100644 --- a/sys/net/sixlowpan/rpl/rpl.c +++ b/sys/net/sixlowpan/rpl/rpl.c @@ -1,3 +1,20 @@ +/** + * RPL implementation + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup rpl + * @{ + * @file rpl.c + * @brief basic RPL functions + * @author Eric Engel + * @} + */ + #include #include #include @@ -14,7 +31,7 @@ #include "sys/net/sixlowpan/sixlowerror.h" char rpl_process_buf[RPL_PROCESS_STACKSIZE]; -//global variables +/* global variables */ char i_am_root = 0; rpl_of_t *objective_functions[NUMBER_IMPLEMENTED_OFS]; rpl_routing_entry_t routing_table[RPL_MAX_ROUTING_ENTRIES]; @@ -22,783 +39,868 @@ unsigned int rpl_process_pid; ipv6_addr_t my_address; mutex_t rpl_send_mutex; mutex_t rpl_recv_mutex; -//receive buffer without LL_HDR +/* receive buffer without LL_HDR */ uint8_t rpl_buffer[BUFFER_SIZE - LL_HDR_LEN]; -//in send buffer we need space fpr LL_HDR +/* in send buffer we need space fpr LL_HDR */ uint8_t rpl_send_buffer[BUFFER_SIZE]; msg_t msg_queue[RPL_PKT_RECV_BUF_SIZE]; -//SEND BUFFERS -static struct ipv6_hdr_t* ipv6_send_buf; -static struct icmpv6_hdr_t* icmp_send_buf; +/* SEND BUFFERS */ +static struct ipv6_hdr_t *ipv6_send_buf; +static struct icmpv6_hdr_t *icmp_send_buf; static struct rpl_dio_t *rpl_send_dio_buf; static struct rpl_dis_t *rpl_send_dis_buf; static struct rpl_dao_t *rpl_send_dao_buf; -static struct rpl_dao_ack_t * rpl_send_dao_ack_buf; -static struct rpl_opt_dodag_conf_t * rpl_send_opt_dodag_conf_buf; -//static struct rpl_opt_solicited_t * rpl_send_opt_solicited_buf; -static struct rpl_opt_target_t * rpl_send_opt_target_buf; -static struct rpl_opt_transit_t * rpl_send_opt_transit_buf; +static struct rpl_dao_ack_t *rpl_send_dao_ack_buf; +static struct rpl_opt_dodag_conf_t *rpl_send_opt_dodag_conf_buf; +/* static struct rpl_opt_solicited_t * rpl_send_opt_solicited_buf; */ +static struct rpl_opt_target_t *rpl_send_opt_target_buf; +static struct rpl_opt_transit_t *rpl_send_opt_transit_buf; -//RECEIVE BUFFERS -//Unbenutzter dao_ack buffer auskommentiert, damit keine warnings erscheinen -static struct ipv6_hdr_t* ipv6_buf; +/* RECEIVE BUFFERS */ +static struct ipv6_hdr_t *ipv6_buf; static struct rpl_dio_t *rpl_dio_buf; static struct rpl_dis_t *rpl_dis_buf; static struct rpl_dao_t *rpl_dao_buf; -static struct rpl_dao_ack_t * rpl_dao_ack_buf; +static struct rpl_dao_ack_t *rpl_dao_ack_buf; static struct rpl_opt_t *rpl_opt_buf; -static struct rpl_opt_dodag_conf_t * rpl_opt_dodag_conf_buf; -static struct rpl_opt_solicited_t * rpl_opt_solicited_buf; -static struct rpl_opt_target_t * rpl_opt_target_buf; -static struct rpl_opt_transit_t * rpl_opt_transit_buf; +static struct rpl_opt_dodag_conf_t *rpl_opt_dodag_conf_buf; +static struct rpl_opt_solicited_t *rpl_opt_solicited_buf; +static struct rpl_opt_target_t *rpl_opt_target_buf; +static struct rpl_opt_transit_t *rpl_opt_transit_buf; -// SEND BUFFERS -static struct ipv6_hdr_t * get_rpl_send_ipv6_buf(void){ - return ((struct ipv6_hdr_t*)&(rpl_send_buffer[0])); -} -static uint8_t * get_rpl_send_payload_buf(uint8_t ext_len){ - //return &(rpl_send_buffer[LLHDR_IPV6HDR_LEN + ext_len]); - return &(rpl_send_buffer[IPV6_HDR_LEN + ext_len]); -} -static struct icmpv6_hdr_t * get_rpl_send_icmpv6_buf(uint8_t ext_len){ - //return ((struct icmpv6_hdr_t*)&(rpl_send_buffer[LLHDR_IPV6HDR_LEN + ext_len])); - return ((struct icmpv6_hdr_t*)&(rpl_send_buffer[IPV6_HDR_LEN + ext_len])); -} -static struct rpl_dio_t* get_rpl_send_dio_buf(void){ - //return ((struct rpl_dio_t*)&(rpl_send_buffer[LLHDR_ICMPV6HDR_LEN])); - return ((struct rpl_dio_t*)&(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN])); -} -static struct rpl_dao_t* get_rpl_send_dao_buf(void){ - //return ((struct rpl_dao_t*)&(rpl_send_buffer[LLHDR_ICMPV6HDR_LEN])); - return ((struct rpl_dao_t*)&(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN])); -} -static struct rpl_dao_ack_t* get_rpl_send_dao_ack_buf(void){ - return ((struct rpl_dao_ack_t*)&(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN])); -} -static struct rpl_dis_t* get_rpl_send_dis_buf(void){ - //return ((struct rpl_dis_t*)&(rpl_send_buffer[LLHDR_ICMPV6HDR_LEN])); - return ((struct rpl_dis_t*)&(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN])); -} -static struct rpl_opt_dodag_conf_t* get_rpl_send_opt_dodag_conf_buf(uint8_t rpl_msg_len){ - //return ((struct rpl_opt_dodag_conf_t*)&(rpl_send_buffer[LLHDR_ICMPV6HDR_LEN + rpl_msg_len])); - return ((struct rpl_opt_dodag_conf_t*)&(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len])); -} -static struct rpl_opt_target_t* get_rpl_send_opt_target_buf(uint8_t rpl_msg_len){ - //return ((struct rpl_opt_target_t*)&(rpl_send_buffer[LLHDR_ICMPV6HDR_LEN + rpl_msg_len])); - return ((struct rpl_opt_target_t*)&(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len])); +/* SEND BUFFERS */ +static struct ipv6_hdr_t *get_rpl_send_ipv6_buf(void) +{ + return ((struct ipv6_hdr_t *)&(rpl_send_buffer[0])); } -static struct rpl_opt_transit_t* get_rpl_send_opt_transit_buf(uint8_t rpl_msg_len){ - //return ((struct rpl_opt_transit_t*)&(rpl_send_buffer[LLHDR_ICMPV6HDR_LEN + rpl_msg_len])); - return ((struct rpl_opt_transit_t*)&(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len])); +static uint8_t *get_rpl_send_payload_buf(uint8_t ext_len) +{ + return &(rpl_send_buffer[IPV6_HDR_LEN + ext_len]); } -//RECEIVE BUFFERS -static struct ipv6_hdr_t * get_rpl_ipv6_buf(void){ - return ((struct ipv6_hdr_t*)&(rpl_buffer[0])); -} -static struct rpl_dio_t* get_rpl_dio_buf(void){ - return ((struct rpl_dio_t*)&(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN])); +static struct icmpv6_hdr_t *get_rpl_send_icmpv6_buf(uint8_t ext_len) +{ + return ((struct icmpv6_hdr_t *)&(rpl_send_buffer[IPV6_HDR_LEN + ext_len])); } -static struct rpl_dao_t* get_rpl_dao_buf(void){ - return ((struct rpl_dao_t*)&(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN])); -} -static struct rpl_dao_ack_t* get_rpl_dao_ack_buf(void){ - return ((struct rpl_dao_ack_t*)&(buffer[LLHDR_ICMPV6HDR_LEN])); -} -static struct rpl_dis_t* get_rpl_dis_buf(void){ - return ((struct rpl_dis_t*)&(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN])); -} -static struct rpl_opt_t* get_rpl_opt_buf(uint8_t rpl_msg_len){ - return ((struct rpl_opt_t*)&(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len])); +static struct rpl_dio_t *get_rpl_send_dio_buf(void) +{ + return ((struct rpl_dio_t *)&(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN])); } -static struct rpl_opt_dodag_conf_t* get_rpl_opt_dodag_conf_buf(uint8_t rpl_msg_len){ - return ((struct rpl_opt_dodag_conf_t*)&(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len])); +static struct rpl_dao_t *get_rpl_send_dao_buf(void) +{ + return ((struct rpl_dao_t *)&(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN])); } -static struct rpl_opt_solicited_t* get_rpl_opt_solicited_buf(uint8_t rpl_msg_len){ - return ((struct rpl_opt_solicited_t*)&(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len])); +static struct rpl_dao_ack_t *get_rpl_send_dao_ack_buf(void) +{ + return ((struct rpl_dao_ack_t *)&(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN])); } -static struct rpl_opt_target_t* get_rpl_opt_target_buf(uint8_t rpl_msg_len){ - return ((struct rpl_opt_target_t*)&(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len])); +static struct rpl_dis_t *get_rpl_send_dis_buf(void) +{ + return ((struct rpl_dis_t *)&(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN])); } -static struct rpl_opt_transit_t* get_rpl_opt_transit_buf(uint8_t rpl_msg_len){ - return ((struct rpl_opt_transit_t*)&(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len])); +static struct rpl_opt_dodag_conf_t *get_rpl_send_opt_dodag_conf_buf(uint8_t rpl_msg_len) +{ + return ((struct rpl_opt_dodag_conf_t *)&(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len])); } -//Diese Funktion findet eine implementierte OF anhand des Objective Code Point -rpl_of_t *rpl_get_of_for_ocp(uint16_t ocp){ - for(uint16_t i=0; i < NUMBER_IMPLEMENTED_OFS; i++){ - if(ocp == objective_functions[i]->ocp){ - return objective_functions[i]; - } - } - return NULL; +static struct rpl_opt_target_t *get_rpl_send_opt_target_buf(uint8_t rpl_msg_len) +{ + return ((struct rpl_opt_target_t *)&(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len])); } -uint8_t rpl_init(transceiver_type_t trans, uint16_t rpl_address){ - mutex_init(&rpl_send_mutex); - mutex_init(&rpl_recv_mutex); - if(rpl_address == 0){ - return SIXLOWERROR_ADDRESS; - } - //initialize routing table - rpl_clear_routing_table(); - init_trickle(); - rpl_process_pid = thread_create(rpl_process_buf, RPL_PROCESS_STACKSIZE, - PRIORITY_MAIN-1, CREATE_STACKTEST, - rpl_process, "rpl_process"); - - //INSERT NEW OBJECTIVE FUNCTIONS HERE - objective_functions[0] = rpl_get_of0(); - //objective_functions[1] = rpl_get_of_ETX() +static struct rpl_opt_transit_t *get_rpl_send_opt_transit_buf(uint8_t rpl_msg_len) +{ + return ((struct rpl_opt_transit_t *)&(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len])); +} - sixlowpan_init(trans,rpl_address,0); - //Wir benötigen einen Link Local prefix, um unsere entsprechende Addresse im Netz abzufragen - ipv6_addr_t ll_address; - ipv6_set_ll_prefix(&ll_address); +/* RECEIVE BUFFERS */ +static struct ipv6_hdr_t *get_rpl_ipv6_buf(void) +{ + return ((struct ipv6_hdr_t *)&(rpl_buffer[0])); +} + +static struct rpl_dio_t *get_rpl_dio_buf(void) +{ + return ((struct rpl_dio_t *)&(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN])); +} + +static struct rpl_dao_t *get_rpl_dao_buf(void) +{ + return ((struct rpl_dao_t *)&(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN])); +} + +static struct rpl_dao_ack_t *get_rpl_dao_ack_buf(void) +{ + return ((struct rpl_dao_ack_t *)&(buffer[LLHDR_ICMPV6HDR_LEN])); +} + +static struct rpl_dis_t *get_rpl_dis_buf(void) +{ + return ((struct rpl_dis_t *)&(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN])); +} + +static struct rpl_opt_t *get_rpl_opt_buf(uint8_t rpl_msg_len) +{ + return ((struct rpl_opt_t *)&(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len])); +} + +static struct rpl_opt_dodag_conf_t *get_rpl_opt_dodag_conf_buf(uint8_t rpl_msg_len) +{ + return ((struct rpl_opt_dodag_conf_t *)&(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len])); +} + +static struct rpl_opt_solicited_t *get_rpl_opt_solicited_buf(uint8_t rpl_msg_len) +{ + return ((struct rpl_opt_solicited_t *)&(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len])); +} + +static struct rpl_opt_target_t *get_rpl_opt_target_buf(uint8_t rpl_msg_len) +{ + return ((struct rpl_opt_target_t *)&(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len])); +} + +static struct rpl_opt_transit_t *get_rpl_opt_transit_buf(uint8_t rpl_msg_len) +{ + return ((struct rpl_opt_transit_t *)&(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len])); +} + +/* Diese Funktion findet eine implementierte OF anhand des Objective Code Point */ +rpl_of_t *rpl_get_of_for_ocp(uint16_t ocp) +{ + for(uint16_t i = 0; i < NUMBER_IMPLEMENTED_OFS; i++) { + if(ocp == objective_functions[i]->ocp) { + return objective_functions[i]; + } + } + + return NULL; +} + +uint8_t rpl_init(transceiver_type_t trans, uint16_t rpl_address) +{ + mutex_init(&rpl_send_mutex); + mutex_init(&rpl_recv_mutex); + + if(rpl_address == 0) { + return SIXLOWERROR_ADDRESS; + } + + /* initialize routing table */ + rpl_clear_routing_table(); + init_trickle(); + rpl_process_pid = thread_create(rpl_process_buf, RPL_PROCESS_STACKSIZE, + PRIORITY_MAIN - 1, CREATE_STACKTEST, + rpl_process, "rpl_process"); + + /* INSERT NEW OBJECTIVE FUNCTIONS HERE */ + objective_functions[0] = rpl_get_of0(); + /* objective_functions[1] = rpl_get_of_ETX() */ + + sixlowpan_init(trans, rpl_address, 0); + /* Wir benötigen einen Link Local prefix, um unsere entsprechende Addresse im Netz abzufragen */ + ipv6_addr_t ll_address; + ipv6_set_ll_prefix(&ll_address); ipv6_get_saddr(&my_address, &ll_address); - set_rpl_process_pid(rpl_process_pid); + set_rpl_process_pid(rpl_process_pid); - //some fake routing entries... - /*if(rpl_address != 1){ - ll_address.uint8[15]=1; - rpl_add_routing_entry(&ll_address, &ll_address, 9000); - ll_address.uint8[15]=2; - rpl_add_routing_entry(&ll_address, &ll_address, 8000); - ll_address.uint8[15]=3; - rpl_add_routing_entry(&ll_address, &ll_address, 7000); - ll_address.uint8[15]=4; - rpl_add_routing_entry(&ll_address, &ll_address, 6000); - ll_address.uint8[15]=5; - rpl_add_routing_entry(&ll_address, &ll_address, 5000); - ll_address.uint8[15]=6; - rpl_add_routing_entry(&ll_address, &ll_address, 4000); - ll_address.uint8[15]=7; - rpl_add_routing_entry(&ll_address, &ll_address, 4000); - ll_address.uint8[15]=8; - rpl_add_routing_entry(&ll_address, &ll_address, 4000); - } */ - return SUCCESS; + return SUCCESS; } -void rpl_init_root(void){ - rpl_instance_t *inst; - rpl_dodag_t *dodag; +void rpl_init_root(void) +{ + rpl_instance_t *inst; + rpl_dodag_t *dodag; - inst = rpl_new_instance(RPL_DEFAULT_INSTANCE); - if(inst == NULL){ - printf("Error - No memory for another RPL instance\n"); - return; - } - inst->id = RPL_DEFAULT_INSTANCE; - inst->joined = 1; - - dodag = rpl_new_dodag(RPL_DEFAULT_INSTANCE, &my_address); - if(dodag != NULL) { - dodag->of = rpl_get_of_for_ocp(RPL_DEFAULT_OCP); - dodag->instance = inst; - dodag->mop = RPL_DEFAULT_MOP; - dodag->dtsn = 1; - dodag->prf = 0; - dodag->dio_interval_doubling = DEFAULT_DIO_INTERVAL_DOUBLINGS; - dodag->dio_min = DEFAULT_DIO_INTERVAL_MIN; - dodag->dio_redundancy = DEFAULT_DIO_REDUNDANCY_CONSTANT; - dodag->maxrankincrease = 0; - dodag->minhoprankincrease = (uint16_t)DEFAULT_MIN_HOP_RANK_INCREASE; - dodag->default_lifetime = (uint8_t)RPL_DEFAULT_LIFETIME; - dodag->lifetime_unit = RPL_LIFETIME_UNIT; - dodag->version = RPL_COUNTER_INIT; - dodag->grounded = RPL_GROUNDED; - dodag->my_rank = RPL_ROOT_RANK; - dodag->joined = 1; - dodag->my_preferred_parent = NULL; - } - else{ - printf("Error - could not generate DODAG\n"); - return; - } - i_am_root = 1; - start_trickle(dodag->dio_min, dodag->dio_interval_doubling, dodag->dio_redundancy); - puts("ROOT INIT FINISHED"); + inst = rpl_new_instance(RPL_DEFAULT_INSTANCE); + + if(inst == NULL) { + printf("Error - No memory for another RPL instance\n"); + return; + } + + inst->id = RPL_DEFAULT_INSTANCE; + inst->joined = 1; + + dodag = rpl_new_dodag(RPL_DEFAULT_INSTANCE, &my_address); + + if(dodag != NULL) { + dodag->of = rpl_get_of_for_ocp(RPL_DEFAULT_OCP); + dodag->instance = inst; + dodag->mop = RPL_DEFAULT_MOP; + dodag->dtsn = 1; + dodag->prf = 0; + dodag->dio_interval_doubling = DEFAULT_DIO_INTERVAL_DOUBLINGS; + dodag->dio_min = DEFAULT_DIO_INTERVAL_MIN; + dodag->dio_redundancy = DEFAULT_DIO_REDUNDANCY_CONSTANT; + dodag->maxrankincrease = 0; + dodag->minhoprankincrease = (uint16_t)DEFAULT_MIN_HOP_RANK_INCREASE; + dodag->default_lifetime = (uint8_t)RPL_DEFAULT_LIFETIME; + dodag->lifetime_unit = RPL_LIFETIME_UNIT; + dodag->version = RPL_COUNTER_INIT; + dodag->grounded = RPL_GROUNDED; + dodag->my_rank = RPL_ROOT_RANK; + dodag->joined = 1; + dodag->my_preferred_parent = NULL; + } + else { + printf("Error - could not generate DODAG\n"); + return; + } + + i_am_root = 1; + start_trickle(dodag->dio_min, dodag->dio_interval_doubling, dodag->dio_redundancy); + puts("ROOT INIT FINISHED"); } -void send_DIO(ipv6_addr_t* destination){ - //puts("\nSEND DIO"); - mutex_lock(&rpl_send_mutex); - rpl_dodag_t * mydodag; - icmp_send_buf = get_rpl_send_icmpv6_buf(ipv6_ext_hdr_len); +void send_DIO(ipv6_addr_t *destination) +{ + mutex_lock(&rpl_send_mutex); + rpl_dodag_t *mydodag; + icmp_send_buf = get_rpl_send_icmpv6_buf(ipv6_ext_hdr_len); - mydodag = rpl_get_my_dodag(); - if(mydodag == NULL){ - printf("Error, trying to send DIO without being part of a dodag. This should not happen\n"); - mutex_unlock(&rpl_send_mutex, 0); - return; - } + mydodag = rpl_get_my_dodag(); - icmp_send_buf->type = ICMP_RPL_CONTROL; - icmp_send_buf->code = ICMP_CODE_DIO; - icmp_send_buf->checksum = ~icmpv6_csum(PROTO_NUM_ICMPV6); + if(mydodag == NULL) { + printf("Error, trying to send DIO without being part of a dodag. This should not happen\n"); + mutex_unlock(&rpl_send_mutex, 0); + return; + } - rpl_send_dio_buf = get_rpl_send_dio_buf(); - memset(rpl_send_dio_buf, 0, sizeof(*rpl_send_dio_buf)); - rpl_send_dio_buf->rpl_instanceid = mydodag->instance->id; - rpl_send_dio_buf->version_number = mydodag->version; - rpl_send_dio_buf->rank = mydodag->my_rank; - rpl_send_dio_buf->g_mop_prf = (mydodag->grounded << RPL_GROUNDED_SHIFT) | (mydodag->mop << RPL_MOP_SHIFT) | mydodag->prf; - rpl_send_dio_buf->dtsn = mydodag->dtsn; - rpl_send_dio_buf->flags = 0; - rpl_send_dio_buf->reserved = 0; - rpl_send_dio_buf->dodagid = mydodag->dodag_id; - //printf("Send DIO with DODAGID: \n"); - //ipv6_print_addr(&rpl_dio_buf->dodagid); + icmp_send_buf->type = ICMP_RPL_CONTROL; + icmp_send_buf->code = ICMP_CODE_DIO; + icmp_send_buf->checksum = ~icmpv6_csum(PROTO_NUM_ICMPV6); - int opt_hdr_len = 0; - //DODAG Configuration Option! - rpl_send_opt_dodag_conf_buf = get_rpl_send_opt_dodag_conf_buf(DIO_BASE_LEN); - rpl_send_opt_dodag_conf_buf->type = RPL_OPT_DODAG_CONF; - rpl_send_opt_dodag_conf_buf->length = RPL_OPT_DODAG_CONF_LEN; - rpl_send_opt_dodag_conf_buf->flags_a_pcs = 0; - rpl_send_opt_dodag_conf_buf->DIOIntDoubl = mydodag->dio_interval_doubling; - rpl_send_opt_dodag_conf_buf->DIOIntMin = mydodag->dio_min; - rpl_send_opt_dodag_conf_buf->DIORedun = mydodag->dio_redundancy; - rpl_send_opt_dodag_conf_buf->MaxRankIncrease = mydodag->maxrankincrease; - rpl_send_opt_dodag_conf_buf->MinHopRankIncrease = mydodag->minhoprankincrease; - rpl_send_opt_dodag_conf_buf->ocp = mydodag->of->ocp; - rpl_send_opt_dodag_conf_buf->reserved = 0; - rpl_send_opt_dodag_conf_buf->default_lifetime = mydodag->default_lifetime; - rpl_send_opt_dodag_conf_buf->lifetime_unit = mydodag->lifetime_unit; - + rpl_send_dio_buf = get_rpl_send_dio_buf(); + memset(rpl_send_dio_buf, 0, sizeof(*rpl_send_dio_buf)); + rpl_send_dio_buf->rpl_instanceid = mydodag->instance->id; + rpl_send_dio_buf->version_number = mydodag->version; + rpl_send_dio_buf->rank = mydodag->my_rank; + rpl_send_dio_buf->g_mop_prf = (mydodag->grounded << RPL_GROUNDED_SHIFT) | (mydodag->mop << RPL_MOP_SHIFT) | mydodag->prf; + rpl_send_dio_buf->dtsn = mydodag->dtsn; + rpl_send_dio_buf->flags = 0; + rpl_send_dio_buf->reserved = 0; + rpl_send_dio_buf->dodagid = mydodag->dodag_id; - opt_hdr_len += RPL_OPT_LEN + RPL_OPT_DODAG_CONF_LEN; - - - uint16_t plen = ICMPV6_HDR_LEN + DIO_BASE_LEN + opt_hdr_len; - rpl_send(destination,(uint8_t*)icmp_send_buf, plen, PROTO_NUM_ICMPV6, NULL); - mutex_unlock(&rpl_send_mutex, 0); + int opt_hdr_len = 0; + /* DODAG Configuration Option! */ + rpl_send_opt_dodag_conf_buf = get_rpl_send_opt_dodag_conf_buf(DIO_BASE_LEN); + rpl_send_opt_dodag_conf_buf->type = RPL_OPT_DODAG_CONF; + rpl_send_opt_dodag_conf_buf->length = RPL_OPT_DODAG_CONF_LEN; + rpl_send_opt_dodag_conf_buf->flags_a_pcs = 0; + rpl_send_opt_dodag_conf_buf->DIOIntDoubl = mydodag->dio_interval_doubling; + rpl_send_opt_dodag_conf_buf->DIOIntMin = mydodag->dio_min; + rpl_send_opt_dodag_conf_buf->DIORedun = mydodag->dio_redundancy; + rpl_send_opt_dodag_conf_buf->MaxRankIncrease = mydodag->maxrankincrease; + rpl_send_opt_dodag_conf_buf->MinHopRankIncrease = mydodag->minhoprankincrease; + rpl_send_opt_dodag_conf_buf->ocp = mydodag->of->ocp; + rpl_send_opt_dodag_conf_buf->reserved = 0; + rpl_send_opt_dodag_conf_buf->default_lifetime = mydodag->default_lifetime; + rpl_send_opt_dodag_conf_buf->lifetime_unit = mydodag->lifetime_unit; + + + opt_hdr_len += RPL_OPT_LEN + RPL_OPT_DODAG_CONF_LEN; + + + uint16_t plen = ICMPV6_HDR_LEN + DIO_BASE_LEN + opt_hdr_len; + rpl_send(destination, (uint8_t *)icmp_send_buf, plen, PROTO_NUM_ICMPV6, NULL); + mutex_unlock(&rpl_send_mutex, 0); } -void send_DIS(ipv6_addr_t *destination){ - //puts("Send DIS"); +void send_DIS(ipv6_addr_t *destination) +{ + mutex_lock(&rpl_send_mutex); + icmp_send_buf = get_rpl_send_icmpv6_buf(ipv6_ext_hdr_len); - mutex_lock(&rpl_send_mutex); - icmp_send_buf = get_rpl_send_icmpv6_buf(ipv6_ext_hdr_len); + icmp_send_buf->type = ICMP_RPL_CONTROL; + icmp_send_buf->code = ICMP_CODE_DIS; + icmp_send_buf->checksum = ~icmpv6_csum(PROTO_NUM_ICMPV6); - icmp_send_buf->type = ICMP_RPL_CONTROL; - icmp_send_buf->code = ICMP_CODE_DIS; - icmp_send_buf->checksum = ~icmpv6_csum(PROTO_NUM_ICMPV6); - - rpl_send_dis_buf = get_rpl_send_dis_buf(); + rpl_send_dis_buf = get_rpl_send_dis_buf(); - uint16_t plen = ICMPV6_HDR_LEN + DIS_BASE_LEN; - rpl_send(destination,(uint8_t*)icmp_send_buf, plen, PROTO_NUM_ICMPV6, NULL); - mutex_unlock(&rpl_send_mutex, 0); + uint16_t plen = ICMPV6_HDR_LEN + DIS_BASE_LEN; + rpl_send(destination, (uint8_t *)icmp_send_buf, plen, PROTO_NUM_ICMPV6, NULL); + mutex_unlock(&rpl_send_mutex, 0); } -void send_DAO(ipv6_addr_t *destination, uint8_t lifetime, bool default_lifetime, uint8_t start_index){ - if(i_am_root){ - return; - } - mutex_lock(&rpl_send_mutex); - rpl_dodag_t * my_dodag; - my_dodag = rpl_get_my_dodag(); - - if(destination == NULL){ - destination = &my_dodag->my_preferred_parent->addr; - } - if(default_lifetime){ - lifetime=my_dodag->default_lifetime; - } - //puts("sending DAO"); +void send_DAO(ipv6_addr_t *destination, uint8_t lifetime, bool default_lifetime, uint8_t start_index) +{ + if(i_am_root) { + return; + } - icmp_send_buf = get_rpl_send_icmpv6_buf(ipv6_ext_hdr_len); + mutex_lock(&rpl_send_mutex); + rpl_dodag_t *my_dodag; + my_dodag = rpl_get_my_dodag(); - icmp_send_buf->type = ICMP_RPL_CONTROL; - icmp_send_buf->code = ICMP_CODE_DAO; - icmp_send_buf->checksum = ~icmpv6_csum(PROTO_NUM_ICMPV6); + if(destination == NULL) { + destination = &my_dodag->my_preferred_parent->addr; + } - if(my_dodag == NULL){ - mutex_unlock(&rpl_send_mutex, 0); - return; - } - rpl_send_dao_buf = get_rpl_send_dao_buf(); - memset(rpl_send_dao_buf,0,sizeof(*rpl_send_dao_buf)); - rpl_send_dao_buf->rpl_instanceid = my_dodag->instance->id; - rpl_send_dao_buf->k_d_flags = 0x00; - rpl_send_dao_buf->dao_sequence = my_dodag->dao_seq; - uint16_t opt_len = 0; - rpl_send_opt_target_buf = get_rpl_send_opt_target_buf(DAO_BASE_LEN); - //Alle Ziele aus der Routing Tabelle als Target eintragen - uint8_t entries = 0; - uint8_t continue_index = 0; - for(uint8_t i=start_index; itype=RPL_OPT_TARGET; - rpl_send_opt_target_buf->length=RPL_OPT_TARGET_LEN; - rpl_send_opt_target_buf->flags=0x00; - rpl_send_opt_target_buf->prefix_length= RPL_DODAG_ID_LEN; - memcpy(&rpl_send_opt_target_buf->target,&routing_table[i].address,sizeof(ipv6_addr_t)); - opt_len += RPL_OPT_TARGET_LEN +2; - rpl_send_opt_transit_buf = get_rpl_send_opt_transit_buf(DAO_BASE_LEN + opt_len); - rpl_send_opt_transit_buf->type=RPL_OPT_TRANSIT; - rpl_send_opt_transit_buf->length=RPL_OPT_TRANSIT_LEN; - rpl_send_opt_transit_buf->e_flags=0x00; - rpl_send_opt_transit_buf->path_control=0x00;//not used - rpl_send_opt_transit_buf->path_sequence=0x00;//not used - rpl_send_opt_transit_buf->path_lifetime=lifetime; - opt_len += RPL_OPT_TRANSIT_LEN +2; - rpl_send_opt_target_buf = get_rpl_send_opt_target_buf(DAO_BASE_LEN + opt_len); - entries++; - } - if(entries >= 5){ - //split DAO, so packages dont get too big. - //The value 5 is based on experience - continue_index = i+1; - break; - } - } - //Add own address - rpl_send_opt_target_buf->type=RPL_OPT_TARGET; - rpl_send_opt_target_buf->length=RPL_OPT_TARGET_LEN; - rpl_send_opt_target_buf->flags=0x00; - rpl_send_opt_target_buf->prefix_length= RPL_DODAG_ID_LEN; - memcpy(&rpl_send_opt_target_buf->target,&my_address,sizeof(ipv6_addr_t)); - opt_len += RPL_OPT_TARGET_LEN +2; + if(default_lifetime) { + lifetime = my_dodag->default_lifetime; + } - rpl_send_opt_transit_buf = get_rpl_send_opt_transit_buf(DAO_BASE_LEN + opt_len); - rpl_send_opt_transit_buf->type=RPL_OPT_TRANSIT; - rpl_send_opt_transit_buf->length=RPL_OPT_TRANSIT_LEN; - rpl_send_opt_transit_buf->e_flags=0x00; - rpl_send_opt_transit_buf->path_control=0x00; - rpl_send_opt_transit_buf->path_sequence=0x00; - rpl_send_opt_transit_buf->path_lifetime=lifetime; - opt_len += RPL_OPT_TRANSIT_LEN +2; - - uint16_t plen = ICMPV6_HDR_LEN + DAO_BASE_LEN + opt_len; - rpl_send(destination,(uint8_t*)icmp_send_buf, plen, PROTO_NUM_ICMPV6, NULL); - mutex_unlock(&rpl_send_mutex, 0); - if(continue_index > 1){ - send_DAO(destination, lifetime, default_lifetime, continue_index); - } + icmp_send_buf = get_rpl_send_icmpv6_buf(ipv6_ext_hdr_len); + + icmp_send_buf->type = ICMP_RPL_CONTROL; + icmp_send_buf->code = ICMP_CODE_DAO; + icmp_send_buf->checksum = ~icmpv6_csum(PROTO_NUM_ICMPV6); + + if(my_dodag == NULL) { + mutex_unlock(&rpl_send_mutex, 0); + return; + } + + rpl_send_dao_buf = get_rpl_send_dao_buf(); + memset(rpl_send_dao_buf, 0, sizeof(*rpl_send_dao_buf)); + rpl_send_dao_buf->rpl_instanceid = my_dodag->instance->id; + rpl_send_dao_buf->k_d_flags = 0x00; + rpl_send_dao_buf->dao_sequence = my_dodag->dao_seq; + uint16_t opt_len = 0; + rpl_send_opt_target_buf = get_rpl_send_opt_target_buf(DAO_BASE_LEN); + /* Alle Ziele aus der Routing Tabelle als Target eintragen */ + uint8_t entries = 0; + uint8_t continue_index = 0; + + for(uint8_t i = start_index; i < RPL_MAX_ROUTING_ENTRIES; i++) { + if(routing_table[i].used) { + rpl_send_opt_target_buf->type = RPL_OPT_TARGET; + rpl_send_opt_target_buf->length = RPL_OPT_TARGET_LEN; + rpl_send_opt_target_buf->flags = 0x00; + rpl_send_opt_target_buf->prefix_length = RPL_DODAG_ID_LEN; + memcpy(&rpl_send_opt_target_buf->target, &routing_table[i].address, sizeof(ipv6_addr_t)); + opt_len += RPL_OPT_TARGET_LEN + 2; + rpl_send_opt_transit_buf = get_rpl_send_opt_transit_buf(DAO_BASE_LEN + opt_len); + rpl_send_opt_transit_buf->type = RPL_OPT_TRANSIT; + rpl_send_opt_transit_buf->length = RPL_OPT_TRANSIT_LEN; + rpl_send_opt_transit_buf->e_flags = 0x00; + rpl_send_opt_transit_buf->path_control = 0x00; /* not used */ + rpl_send_opt_transit_buf->path_sequence = 0x00; /* not used */ + rpl_send_opt_transit_buf->path_lifetime = lifetime; + opt_len += RPL_OPT_TRANSIT_LEN + 2; + rpl_send_opt_target_buf = get_rpl_send_opt_target_buf(DAO_BASE_LEN + opt_len); + entries++; + } + + if(entries >= 5) { + /* split DAO, so packages dont get too big. */ + /* The value 5 is based on experience */ + continue_index = i + 1; + break; + } + } + + /* Add own address */ + rpl_send_opt_target_buf->type = RPL_OPT_TARGET; + rpl_send_opt_target_buf->length = RPL_OPT_TARGET_LEN; + rpl_send_opt_target_buf->flags = 0x00; + rpl_send_opt_target_buf->prefix_length = RPL_DODAG_ID_LEN; + memcpy(&rpl_send_opt_target_buf->target, &my_address, sizeof(ipv6_addr_t)); + opt_len += RPL_OPT_TARGET_LEN + 2; + + rpl_send_opt_transit_buf = get_rpl_send_opt_transit_buf(DAO_BASE_LEN + opt_len); + rpl_send_opt_transit_buf->type = RPL_OPT_TRANSIT; + rpl_send_opt_transit_buf->length = RPL_OPT_TRANSIT_LEN; + rpl_send_opt_transit_buf->e_flags = 0x00; + rpl_send_opt_transit_buf->path_control = 0x00; + rpl_send_opt_transit_buf->path_sequence = 0x00; + rpl_send_opt_transit_buf->path_lifetime = lifetime; + opt_len += RPL_OPT_TRANSIT_LEN + 2; + + uint16_t plen = ICMPV6_HDR_LEN + DAO_BASE_LEN + opt_len; + rpl_send(destination, (uint8_t *)icmp_send_buf, plen, PROTO_NUM_ICMPV6, NULL); + mutex_unlock(&rpl_send_mutex, 0); + + if(continue_index > 1) { + send_DAO(destination, lifetime, default_lifetime, continue_index); + } } -void send_DAO_ACK(ipv6_addr_t *destination){ - //puts("Send DAO_ACK to"); - ipv6_print_addr(destination); - rpl_dodag_t * my_dodag; - my_dodag = rpl_get_my_dodag(); - if(my_dodag == NULL){ - return; - } - mutex_lock(&rpl_send_mutex); - icmp_send_buf = get_rpl_send_icmpv6_buf(ipv6_ext_hdr_len); +void send_DAO_ACK(ipv6_addr_t *destination) +{ + ipv6_print_addr(destination); + rpl_dodag_t *my_dodag; + my_dodag = rpl_get_my_dodag(); - icmp_send_buf->type = ICMP_RPL_CONTROL; - icmp_send_buf->code = ICMP_CODE_DAO_ACK; - icmp_send_buf->checksum = ~icmpv6_csum(PROTO_NUM_ICMPV6); - - rpl_send_dao_ack_buf = get_rpl_send_dao_ack_buf(); - rpl_send_dao_ack_buf->rpl_instanceid = my_dodag->instance->id; - rpl_send_dao_ack_buf->d_reserved = 0; - rpl_send_dao_ack_buf->dao_sequence = my_dodag->dao_seq; - rpl_send_dao_ack_buf->status = 0; + if(my_dodag == NULL) { + return; + } - uint16_t plen = ICMPV6_HDR_LEN + DIS_BASE_LEN; - rpl_send(destination,(uint8_t*)icmp_send_buf, plen, PROTO_NUM_ICMPV6, NULL); - mutex_unlock(&rpl_send_mutex, 0); + mutex_lock(&rpl_send_mutex); + icmp_send_buf = get_rpl_send_icmpv6_buf(ipv6_ext_hdr_len); + + icmp_send_buf->type = ICMP_RPL_CONTROL; + icmp_send_buf->code = ICMP_CODE_DAO_ACK; + icmp_send_buf->checksum = ~icmpv6_csum(PROTO_NUM_ICMPV6); + + rpl_send_dao_ack_buf = get_rpl_send_dao_ack_buf(); + rpl_send_dao_ack_buf->rpl_instanceid = my_dodag->instance->id; + rpl_send_dao_ack_buf->d_reserved = 0; + rpl_send_dao_ack_buf->dao_sequence = my_dodag->dao_seq; + rpl_send_dao_ack_buf->status = 0; + + uint16_t plen = ICMPV6_HDR_LEN + DIS_BASE_LEN; + rpl_send(destination, (uint8_t *)icmp_send_buf, plen, PROTO_NUM_ICMPV6, NULL); + mutex_unlock(&rpl_send_mutex, 0); } -void rpl_process(void){ +void rpl_process(void) +{ - msg_t m_recv; - msg_init_queue(msg_queue, RPL_PKT_RECV_BUF_SIZE); + msg_t m_recv; + msg_init_queue(msg_queue, RPL_PKT_RECV_BUF_SIZE); - while(1){ - msg_receive(&m_recv); - uint8_t *code; - code = ((uint8_t*)m_recv.content.ptr); - //pakettypen unterscheiden - ipv6_buf = get_ipv6_buf(); - //mutex_lock(&rpl_recv_mutex); - //mutex_lock(&rpl_send_mutex); - memcpy(&rpl_buffer,ipv6_buf,ipv6_buf->length+IPV6_HDR_LEN); - switch(*code) { - case(ICMP_CODE_DIS):{ - recv_rpl_dis(); - mutex_unlock(&rpl_recv_mutex, 0); - //mutex_unlock(&rpl_send_mutex, 0); - break; - } - case(ICMP_CODE_DIO):{ - recv_rpl_dio(); - mutex_unlock(&rpl_recv_mutex, 0); - //mutex_unlock(&rpl_send_mutex, 0); - break; - } - case(ICMP_CODE_DAO):{ - recv_rpl_dao(); - mutex_unlock(&rpl_recv_mutex, 0); - //mutex_unlock(&rpl_send_mutex, 0); - break; - } - case(ICMP_CODE_DAO_ACK):{ - recv_rpl_dao_ack(); - mutex_unlock(&rpl_recv_mutex, 0); - //mutex_unlock(&rpl_send_mutex, 0); - break; - } - default: - mutex_unlock(&rpl_recv_mutex, 0); - //mutex_unlock(&rpl_send_mutex, 0); - puts("default unlock"); - break; - } - } + while(1) { + msg_receive(&m_recv); + uint8_t *code; + code = ((uint8_t *)m_recv.content.ptr); + /* pakettypen unterscheiden */ + ipv6_buf = get_ipv6_buf(); + memcpy(&rpl_buffer, ipv6_buf, ipv6_buf->length + IPV6_HDR_LEN); + + switch(*code) { + case(ICMP_CODE_DIS): { + recv_rpl_dis(); + mutex_unlock(&rpl_recv_mutex, 0); + break; + } + + case(ICMP_CODE_DIO): { + recv_rpl_dio(); + mutex_unlock(&rpl_recv_mutex, 0); + break; + } + + case(ICMP_CODE_DAO): { + recv_rpl_dao(); + mutex_unlock(&rpl_recv_mutex, 0); + break; + } + + case(ICMP_CODE_DAO_ACK): { + recv_rpl_dao_ack(); + mutex_unlock(&rpl_recv_mutex, 0); + break; + } + + default: + mutex_unlock(&rpl_recv_mutex, 0); + puts("default unlock"); + break; + } + } } -void recv_rpl_dio(void){ - ipv6_buf = get_rpl_ipv6_buf(); - - rpl_dio_buf = get_rpl_dio_buf(); - int len = DIO_BASE_LEN; +void recv_rpl_dio(void) +{ + ipv6_buf = get_rpl_ipv6_buf(); - rpl_instance_t * dio_inst = rpl_get_instance(rpl_dio_buf->rpl_instanceid); - rpl_instance_t * my_inst = rpl_get_my_instance(); - - if(dio_inst == NULL){ - if(my_inst != NULL){ - //Dieser Knoten ist schon Teil eines DODAGS -> kein beitritt zu anderer Instanz moeglich - return; - } - dio_inst = rpl_new_instance(rpl_dio_buf->rpl_instanceid); - if(dio_inst == NULL){ - return; - } - }else if(my_inst->id != dio_inst->id){ - printf("Andere Instanz, wir haben %d es kam aber %d\n",my_inst->id, dio_inst->id); - //DIO von fremder Instanz ignorieren, Knoten können Momentan nur einer Instanz beitreten und das wird - //die Instanz sein, der sie als erstes beitreten. Danach kann die Instanz nicht mehr gewechselt werden - //Unterstützung für mehrere Instanzen könnte in Zukunft implementiert werden - return; - } - //printf("Try to find dodag with id:\n"); - //ipv6_print_addr(&rpl_dio_buf->dodagid); - rpl_dodag_t dio_dodag; - memset(&dio_dodag, 0,sizeof(dio_dodag)); + rpl_dio_buf = get_rpl_dio_buf(); + int len = DIO_BASE_LEN; - memcpy(&dio_dodag.dodag_id,&rpl_dio_buf->dodagid,sizeof(dio_dodag.dodag_id)); - dio_dodag.dtsn = rpl_dio_buf->dtsn; - dio_dodag.mop = ((rpl_dio_buf->g_mop_prf >> RPL_MOP_SHIFT ) & RPL_SHIFTED_MOP_MASK); - dio_dodag.grounded = rpl_dio_buf->g_mop_prf >> RPL_GROUNDED_SHIFT; - dio_dodag.prf = (rpl_dio_buf->g_mop_prf & RPL_PRF_MASK); - dio_dodag.version = rpl_dio_buf->version_number; - dio_dodag.instance = dio_inst; + rpl_instance_t *dio_inst = rpl_get_instance(rpl_dio_buf->rpl_instanceid); + rpl_instance_t *my_inst = rpl_get_my_instance(); - uint8_t has_dodag_conf_opt = 0; - //So lange das Paket größer ist, als die DIO Größe + Größe der bisher verarbeiteten Optionen, - //sind noch weitere Optionen zu bearbeiten - - //dabei müssen wir jedoch von der ipv6_buf->length die Größe des ICMP Headers abziehen - //weil get_rpl_opt_buf die Paketlänge OHNE ipv6 und icmpv6 header übergeben werden muss - //in ipv6_buf->length ist die IPV6_HDR_LEN nicht enthalten, also muss nur noch die ICMPV6_HDR_LEN - //abgezogen werden - - while(len < (ipv6_buf->length - ICMPV6_HDR_LEN) ){ - rpl_opt_buf = get_rpl_opt_buf(len); - switch(rpl_opt_buf->type){ + if(dio_inst == NULL) { + if(my_inst != NULL) { + /* Dieser Knoten ist schon Teil eines DODAGS -> kein beitritt zu anderer Instanz moeglich */ + return; + } - case(RPL_OPT_PAD1):{ - len += 1; - break; - } - case(RPL_OPT_PADN):{ - len += rpl_opt_buf->length +2; - break; - } - case(RPL_OPT_DAG_METRIC_CONTAINER):{ - len += rpl_opt_buf->length +2; - break; - } - case(RPL_OPT_ROUTE_INFO):{ - len += rpl_opt_buf->length +2; - break; - } - case(RPL_OPT_DODAG_CONF):{ - has_dodag_conf_opt = 1; - if(rpl_opt_buf->length != RPL_OPT_DODAG_CONF_LEN){ - //error malformed - return; - } - rpl_opt_dodag_conf_buf = get_rpl_opt_dodag_conf_buf(len); - dio_dodag.dio_interval_doubling = rpl_opt_dodag_conf_buf->DIOIntDoubl; - dio_dodag.dio_min = rpl_opt_dodag_conf_buf->DIOIntMin; - dio_dodag.dio_redundancy = rpl_opt_dodag_conf_buf->DIORedun; - dio_dodag.maxrankincrease = rpl_opt_dodag_conf_buf->MaxRankIncrease; - dio_dodag.minhoprankincrease = rpl_opt_dodag_conf_buf->MinHopRankIncrease; - dio_dodag.default_lifetime = rpl_opt_dodag_conf_buf->default_lifetime; - dio_dodag.lifetime_unit = rpl_opt_dodag_conf_buf->lifetime_unit; - dio_dodag.of = rpl_get_of_for_ocp(rpl_opt_dodag_conf_buf->ocp); - len += RPL_OPT_DODAG_CONF_LEN +2; - break; - } - case(RPL_OPT_PREFIX_INFO):{ - if(rpl_opt_buf->length != RPL_OPT_PREFIX_INFO_LEN){ - //error malformed - return; - } - len += RPL_OPT_PREFIX_INFO_LEN +2; - break; - } - default: - printf("[Error] Unsupported DIO option\n"); - return; - } - } + dio_inst = rpl_new_instance(rpl_dio_buf->rpl_instanceid); - //handle packet content... - rpl_dodag_t *my_dodag = rpl_get_my_dodag(); - if(my_dodag == NULL){ - if(!has_dodag_conf_opt){ - puts("send DIS"); - send_DIS(&ipv6_buf->srcaddr); - return; - } - - if(rpl_dio_buf->rank < ROOT_RANK){ - printf("DIO with Rank < ROOT_RANK\n"); - return; - } - if(dio_dodag.mop != RPL_DEFAULT_MOP){ - printf("Required MOP not supported\n"); - return; - } - if(dio_dodag.of == NULL){ - printf("Required objective function not supported\n"); - return; - } - if(rpl_dio_buf->rank != INFINITE_RANK){ - puts("Will join DODAG\n"); - ipv6_print_addr(&dio_dodag.dodag_id); - rpl_join_dodag(&dio_dodag, &ipv6_buf->srcaddr, rpl_dio_buf->rank); - } - else{ - printf("Cannot access DODAG because of DIO with infinite rank\n"); - return; - } - } + if(dio_inst == NULL) { + return; + } + } + else if(my_inst->id != dio_inst->id) { + printf("Andere Instanz, wir haben %d es kam aber %d\n", my_inst->id, dio_inst->id); + /* DIO von fremder Instanz ignorieren, Knoten können Momentan nur + * einer Instanz beitreten und das wird die Instanz sein, der sie als + * erstes beitreten. Danach kann die Instanz nicht mehr gewechselt + * werden Unterstützung für mehrere Instanzen könnte in Zukunft + * implementiert werden */ + return; + } - if(rpl_equal_id(&my_dodag->dodag_id, &dio_dodag.dodag_id)){ - //Mein DODAG - if(RPL_COUNTER_GREATER_THAN(dio_dodag.version,my_dodag->version) ){ - if(my_dodag->my_rank == ROOT_RANK){ - //Jemand hat ein DIO mit einer höheren Version als der richtigen gesendet - //Wir erhöhen diese Version noch einmal, und machen sie zur neuen - printf("[Warning] Inconsistent Dodag Version\n"); - my_dodag->version = RPL_COUNTER_INCREMENT(dio_dodag.version); - reset_trickletimer(); - } - else{ - printf("[Info] New Version of dodag %d\n", dio_dodag.version); - rpl_global_repair(&dio_dodag, &ipv6_buf->srcaddr, rpl_dio_buf->rank); - } - return; - } - else if( RPL_COUNTER_GREATER_THAN(my_dodag->version, dio_dodag.version) ){ - //ein Knoten hat noch eine kleinere Versionsnummer -> mehr DIOs senden - reset_trickletimer(); - return; - } - } + rpl_dodag_t dio_dodag; + memset(&dio_dodag, 0, sizeof(dio_dodag)); - //Version stimmt, DODAG stimmt - if(rpl_dio_buf->rank == INFINITE_RANK) { - reset_trickletimer(); - } - //Wenn wir root sind, ist nichts weiter zu tun - if(my_dodag->my_rank == ROOT_RANK){ - if(rpl_dio_buf->rank != INFINITE_RANK){ - trickle_increment_counter(); - } - return; - } + memcpy(&dio_dodag.dodag_id, &rpl_dio_buf->dodagid, sizeof(dio_dodag.dodag_id)); + dio_dodag.dtsn = rpl_dio_buf->dtsn; + dio_dodag.mop = ((rpl_dio_buf->g_mop_prf >> RPL_MOP_SHIFT) & RPL_SHIFTED_MOP_MASK); + dio_dodag.grounded = rpl_dio_buf->g_mop_prf >> RPL_GROUNDED_SHIFT; + dio_dodag.prf = (rpl_dio_buf->g_mop_prf & RPL_PRF_MASK); + dio_dodag.version = rpl_dio_buf->version_number; + dio_dodag.instance = dio_inst; - // - // Parent Handling - // + uint8_t has_dodag_conf_opt = 0; + /* So lange das Paket größer ist, als die DIO Größe + Größe der bisher + * verarbeiteten Optionen, sind noch weitere Optionen zu bearbeiten */ - //Ist Knoten bereits Parent? - rpl_parent_t *parent; - parent = rpl_find_parent(&ipv6_buf->srcaddr); - if(parent == NULL){ - //neuen möglichen Elternknoten hinzufuegen - parent = rpl_new_parent(my_dodag, &ipv6_buf->srcaddr, rpl_dio_buf->rank); - if(parent == NULL){ - return; - } - } - else{ - //DIO ok - trickle_increment_counter(); - } - - //update parent rank - parent->rank = rpl_dio_buf->rank; - rpl_parent_update(parent); - if(rpl_equal_id(&parent->addr, &my_dodag->my_preferred_parent->addr) && (parent->dtsn != rpl_dio_buf->dtsn)){ - delay_dao(); - } - parent->dtsn = rpl_dio_buf->dtsn; - -} + /* dabei müssen wir jedoch von der ipv6_buf->length die Größe des ICMP + * Headers abziehen weil get_rpl_opt_buf die Paketlänge OHNE ipv6 und + * icmpv6 header übergeben werden muss in ipv6_buf->length ist die + * IPV6_HDR_LEN nicht enthalten, also muss nur noch die ICMPV6_HDR_LEN + * abgezogen werden */ -void recv_rpl_dis(void){ - rpl_dodag_t *my_dodag = rpl_get_my_dodag(); - if(my_dodag == NULL){ - return; - } - ipv6_buf = get_rpl_ipv6_buf(); - rpl_dis_buf = get_rpl_dis_buf(); - int len = DIS_BASE_LEN; - while(len < (ipv6_buf->length - ICMPV6_HDR_LEN) ){ - rpl_opt_buf = get_rpl_opt_buf(len); - switch(rpl_opt_buf->type){ - case(RPL_OPT_PAD1):{ - len += 1; - break; - } - case(RPL_OPT_PADN):{ - len += rpl_opt_buf->length +2; - break; - } - case(RPL_OPT_SOLICITED_INFO):{ - len+= RPL_OPT_SOLICITED_INFO_LEN+2; - //extract + check - if(rpl_opt_buf->length != RPL_OPT_SOLICITED_INFO_LEN){ - //error malformed - return; - } - rpl_opt_solicited_buf = get_rpl_opt_solicited_buf(len); - if(rpl_opt_solicited_buf->VID_Flags & RPL_DIS_I_MASK){ - if(my_dodag->instance->id != rpl_opt_solicited_buf->rplinstanceid){ - return; - } - } - if(rpl_opt_solicited_buf->VID_Flags & RPL_DIS_D_MASK){ - if(!rpl_equal_id(&my_dodag->dodag_id, &rpl_opt_solicited_buf->dodagid)){ - return; - } - } - if(rpl_opt_solicited_buf->VID_Flags & RPL_DIS_V_MASK){ - if(my_dodag->version != rpl_opt_solicited_buf->version){ - return; - } - } - break; - } - default: - return; - } - } - send_DIO(&ipv6_buf->srcaddr); + while(len < (ipv6_buf->length - ICMPV6_HDR_LEN)) { + rpl_opt_buf = get_rpl_opt_buf(len); + + switch(rpl_opt_buf->type) { + + case(RPL_OPT_PAD1): { + len += 1; + break; + } + + case(RPL_OPT_PADN): { + len += rpl_opt_buf->length + 2; + break; + } + + case(RPL_OPT_DAG_METRIC_CONTAINER): { + len += rpl_opt_buf->length + 2; + break; + } + + case(RPL_OPT_ROUTE_INFO): { + len += rpl_opt_buf->length + 2; + break; + } + + case(RPL_OPT_DODAG_CONF): { + has_dodag_conf_opt = 1; + + if(rpl_opt_buf->length != RPL_OPT_DODAG_CONF_LEN) { + /* error malformed */ + return; + } + + rpl_opt_dodag_conf_buf = get_rpl_opt_dodag_conf_buf(len); + dio_dodag.dio_interval_doubling = rpl_opt_dodag_conf_buf->DIOIntDoubl; + dio_dodag.dio_min = rpl_opt_dodag_conf_buf->DIOIntMin; + dio_dodag.dio_redundancy = rpl_opt_dodag_conf_buf->DIORedun; + dio_dodag.maxrankincrease = rpl_opt_dodag_conf_buf->MaxRankIncrease; + dio_dodag.minhoprankincrease = rpl_opt_dodag_conf_buf->MinHopRankIncrease; + dio_dodag.default_lifetime = rpl_opt_dodag_conf_buf->default_lifetime; + dio_dodag.lifetime_unit = rpl_opt_dodag_conf_buf->lifetime_unit; + dio_dodag.of = rpl_get_of_for_ocp(rpl_opt_dodag_conf_buf->ocp); + len += RPL_OPT_DODAG_CONF_LEN + 2; + break; + } + + case(RPL_OPT_PREFIX_INFO): { + if(rpl_opt_buf->length != RPL_OPT_PREFIX_INFO_LEN) { + /* error malformed */ + return; + } + + len += RPL_OPT_PREFIX_INFO_LEN + 2; + break; + } + + default: + printf("[Error] Unsupported DIO option\n"); + return; + } + } + + /* handle packet content... */ + rpl_dodag_t *my_dodag = rpl_get_my_dodag(); + + if(my_dodag == NULL) { + if(!has_dodag_conf_opt) { + puts("send DIS"); + send_DIS(&ipv6_buf->srcaddr); + return; + } + + if(rpl_dio_buf->rank < ROOT_RANK) { + printf("DIO with Rank < ROOT_RANK\n"); + return; + } + + if(dio_dodag.mop != RPL_DEFAULT_MOP) { + printf("Required MOP not supported\n"); + return; + } + + if(dio_dodag.of == NULL) { + printf("Required objective function not supported\n"); + return; + } + + if(rpl_dio_buf->rank != INFINITE_RANK) { + puts("Will join DODAG\n"); + ipv6_print_addr(&dio_dodag.dodag_id); + rpl_join_dodag(&dio_dodag, &ipv6_buf->srcaddr, rpl_dio_buf->rank); + } + else { + printf("Cannot access DODAG because of DIO with infinite rank\n"); + return; + } + } + + if(rpl_equal_id(&my_dodag->dodag_id, &dio_dodag.dodag_id)) { + /* Mein DODAG */ + if(RPL_COUNTER_GREATER_THAN(dio_dodag.version, my_dodag->version)) { + if(my_dodag->my_rank == ROOT_RANK) { + /* Jemand hat ein DIO mit einer höheren Version als der richtigen gesendet */ + /* Wir erhöhen diese Version noch einmal, und machen sie zur neuen */ + printf("[Warning] Inconsistent Dodag Version\n"); + my_dodag->version = RPL_COUNTER_INCREMENT(dio_dodag.version); + reset_trickletimer(); + } + else { + printf("[Info] New Version of dodag %d\n", dio_dodag.version); + rpl_global_repair(&dio_dodag, &ipv6_buf->srcaddr, rpl_dio_buf->rank); + } + + return; + } + else if(RPL_COUNTER_GREATER_THAN(my_dodag->version, dio_dodag.version)) { + /* ein Knoten hat noch eine kleinere Versionsnummer -> mehr DIOs senden */ + reset_trickletimer(); + return; + } + } + + /* Version stimmt, DODAG stimmt */ + if(rpl_dio_buf->rank == INFINITE_RANK) { + reset_trickletimer(); + } + + /* Wenn wir root sind, ist nichts weiter zu tun */ + if(my_dodag->my_rank == ROOT_RANK) { + if(rpl_dio_buf->rank != INFINITE_RANK) { + trickle_increment_counter(); + } + + return; + } + + /* */ + /* Parent Handling */ + /* */ + + /* Ist Knoten bereits Parent? */ + rpl_parent_t *parent; + parent = rpl_find_parent(&ipv6_buf->srcaddr); + + if(parent == NULL) { + /* neuen möglichen Elternknoten hinzufuegen */ + parent = rpl_new_parent(my_dodag, &ipv6_buf->srcaddr, rpl_dio_buf->rank); + + if(parent == NULL) { + return; + } + } + else { + /* DIO ok */ + trickle_increment_counter(); + } + + /* update parent rank */ + parent->rank = rpl_dio_buf->rank; + rpl_parent_update(parent); + + if(rpl_equal_id(&parent->addr, &my_dodag->my_preferred_parent->addr) && (parent->dtsn != rpl_dio_buf->dtsn)) { + delay_dao(); + } + + parent->dtsn = rpl_dio_buf->dtsn; } -void recv_rpl_dao(void){ - rpl_dodag_t *my_dodag = rpl_get_my_dodag(); - if(my_dodag == NULL){ - printf("[Error] got DAO without beeing part of a Dodag\n"); - return; - } - ipv6_buf = get_rpl_ipv6_buf(); - rpl_dao_buf = get_rpl_dao_buf(); - int len = DAO_BASE_LEN; - uint8_t increment_seq = 0; - while(len < (ipv6_buf->length - ICMPV6_HDR_LEN) ){ - rpl_opt_buf = get_rpl_opt_buf(len); - switch(rpl_opt_buf->type){ +void recv_rpl_dis(void) +{ + rpl_dodag_t *my_dodag = rpl_get_my_dodag(); - case(RPL_OPT_PAD1):{ - len += 1; - break; - } - case(RPL_OPT_PADN):{ - len += rpl_opt_buf->length +2; - break; - } - case(RPL_OPT_DAG_METRIC_CONTAINER):{ - len += rpl_opt_buf->length +2; - break; - } - case(RPL_OPT_TARGET):{ - rpl_opt_target_buf = get_rpl_opt_target_buf(len); - if(rpl_opt_target_buf->prefix_length != RPL_DODAG_ID_LEN){ - printf("prefixes are not supported yet"); - break; - } - len += rpl_opt_target_buf->length +2; - rpl_opt_transit_buf = get_rpl_opt_transit_buf(len); - if(rpl_opt_transit_buf->type != RPL_OPT_TRANSIT){ - printf("[Error] - no Transit Inforamtion to Target Option, type = %d\n", rpl_opt_transit_buf->type); - break; - } - len += rpl_opt_transit_buf->length +2; - //Die eigentliche Lebenszeit einer Route errechnet sich aus (Lifetime aus DAO) * (Lifetime Unit) Sekunden - rpl_add_routing_entry(&rpl_opt_target_buf->target, &ipv6_buf->srcaddr, rpl_opt_transit_buf->path_lifetime * my_dodag->lifetime_unit); - //puts("Updated route \n"); - increment_seq = 1; - break; - } - case(RPL_OPT_TRANSIT):{ - len += rpl_opt_buf->length +2; - break; - } - case(RPL_OPT_TARGET_DESC):{ - len += rpl_opt_buf->length +2; - break; - } + if(my_dodag == NULL) { + return; + } - default: - return; - } - } - send_DAO_ACK(&ipv6_buf->srcaddr); - if(increment_seq){ - RPL_COUNTER_INCREMENT(my_dodag->dao_seq); - delay_dao(); - } -} + ipv6_buf = get_rpl_ipv6_buf(); + rpl_dis_buf = get_rpl_dis_buf(); + int len = DIS_BASE_LEN; -void recv_rpl_dao_ack(void){ - rpl_dodag_t *my_dodag = rpl_get_my_dodag(); - if(my_dodag == NULL){ - return; - } - rpl_dao_ack_buf = get_rpl_dao_ack_buf(); - if(rpl_dao_ack_buf->rpl_instanceid != my_dodag->instance->id){ - return; - } - if(rpl_dao_ack_buf->status != 0){ - return; - } - //puts("Received DAO ACK"); - dao_ack_received(); + while(len < (ipv6_buf->length - ICMPV6_HDR_LEN)) { + rpl_opt_buf = get_rpl_opt_buf(len); + + switch(rpl_opt_buf->type) { + case(RPL_OPT_PAD1): { + len += 1; + break; + } + + case(RPL_OPT_PADN): { + len += rpl_opt_buf->length + 2; + break; + } + + case(RPL_OPT_SOLICITED_INFO): { + len += RPL_OPT_SOLICITED_INFO_LEN + 2; + + /* extract + check */ + if(rpl_opt_buf->length != RPL_OPT_SOLICITED_INFO_LEN) { + /* error malformed */ + return; + } + + rpl_opt_solicited_buf = get_rpl_opt_solicited_buf(len); + + if(rpl_opt_solicited_buf->VID_Flags & RPL_DIS_I_MASK) { + if(my_dodag->instance->id != rpl_opt_solicited_buf->rplinstanceid) { + return; + } + } + + if(rpl_opt_solicited_buf->VID_Flags & RPL_DIS_D_MASK) { + if(!rpl_equal_id(&my_dodag->dodag_id, &rpl_opt_solicited_buf->dodagid)) { + return; + } + } + + if(rpl_opt_solicited_buf->VID_Flags & RPL_DIS_V_MASK) { + if(my_dodag->version != rpl_opt_solicited_buf->version) { + return; + } + } + + break; + } + + default: + return; + } + } + + send_DIO(&ipv6_buf->srcaddr); } -void rpl_send(ipv6_addr_t *destination, uint8_t *payload, uint16_t p_len, uint8_t next_header, void *tcp_socket){ - uint8_t *p_ptr; +void recv_rpl_dao(void) +{ + rpl_dodag_t *my_dodag = rpl_get_my_dodag(); + + if(my_dodag == NULL) { + printf("[Error] got DAO without beeing part of a Dodag\n"); + return; + } + + ipv6_buf = get_rpl_ipv6_buf(); + rpl_dao_buf = get_rpl_dao_buf(); + int len = DAO_BASE_LEN; + uint8_t increment_seq = 0; + + while(len < (ipv6_buf->length - ICMPV6_HDR_LEN)) { + rpl_opt_buf = get_rpl_opt_buf(len); + + switch(rpl_opt_buf->type) { + + case(RPL_OPT_PAD1): { + len += 1; + break; + } + + case(RPL_OPT_PADN): { + len += rpl_opt_buf->length + 2; + break; + } + + case(RPL_OPT_DAG_METRIC_CONTAINER): { + len += rpl_opt_buf->length + 2; + break; + } + + case(RPL_OPT_TARGET): { + rpl_opt_target_buf = get_rpl_opt_target_buf(len); + + if(rpl_opt_target_buf->prefix_length != RPL_DODAG_ID_LEN) { + printf("prefixes are not supported yet"); + break; + } + + len += rpl_opt_target_buf->length + 2; + rpl_opt_transit_buf = get_rpl_opt_transit_buf(len); + + if(rpl_opt_transit_buf->type != RPL_OPT_TRANSIT) { + printf("[Error] - no Transit Inforamtion to Target Option, type = %d\n", rpl_opt_transit_buf->type); + break; + } + + len += rpl_opt_transit_buf->length + 2; + /* Die eigentliche Lebenszeit einer Route errechnet sich aus (Lifetime aus DAO) * (Lifetime Unit) Sekunden */ + rpl_add_routing_entry(&rpl_opt_target_buf->target, &ipv6_buf->srcaddr, rpl_opt_transit_buf->path_lifetime * my_dodag->lifetime_unit); + /* puts("Updated route \n"); */ + increment_seq = 1; + break; + } + + case(RPL_OPT_TRANSIT): { + len += rpl_opt_buf->length + 2; + break; + } + + case(RPL_OPT_TARGET_DESC): { + len += rpl_opt_buf->length + 2; + break; + } + + default: + return; + } + } + + send_DAO_ACK(&ipv6_buf->srcaddr); + + if(increment_seq) { + RPL_COUNTER_INCREMENT(my_dodag->dao_seq); + delay_dao(); + } +} + +void recv_rpl_dao_ack(void) +{ + rpl_dodag_t *my_dodag = rpl_get_my_dodag(); + + if(my_dodag == NULL) { + return; + } + + rpl_dao_ack_buf = get_rpl_dao_ack_buf(); + + if(rpl_dao_ack_buf->rpl_instanceid != my_dodag->instance->id) { + return; + } + + if(rpl_dao_ack_buf->status != 0) { + return; + } + + /* puts("Received DAO ACK"); */ + dao_ack_received(); + +} + +void rpl_send(ipv6_addr_t *destination, uint8_t *payload, uint16_t p_len, uint8_t next_header, void *tcp_socket) +{ + uint8_t *p_ptr; ipv6_send_buf = get_rpl_send_ipv6_buf(); p_ptr = get_rpl_send_payload_buf(ipv6_ext_hdr_len); packet_length = 0; @@ -813,92 +915,106 @@ void rpl_send(ipv6_addr_t *destination, uint8_t *payload, uint16_t p_len, uint8_ memcpy(&(ipv6_send_buf->destaddr), destination, 16); ipv6_get_saddr(&(ipv6_send_buf->srcaddr), &(ipv6_send_buf->destaddr)); - //Wenn das Paket in der rpl.c "zusammegebaut" wurde, wurde dafür ohnehin der rpl_send_buf verwendet. - //In diesem Fall muss also keine memcopy Aktion durchgeführt werden, da sich der payload bereits - //im richtigen Speicherbereich befindet. - if(p_ptr != payload){ - memcpy(p_ptr,payload,p_len); - } + /* Wenn das Paket in der rpl.c "zusammegebaut" wurde, wurde dafür ohnehin + * der rpl_send_buf verwendet. In diesem Fall muss also keine memcopy + * Aktion durchgeführt werden, da sich der payload bereits im richtigen + * Speicherbereich befindet. */ + if(p_ptr != payload) { + memcpy(p_ptr, payload, p_len); + } packet_length = IPV6_HDR_LEN + p_len; - if(ipv6_prefix_mcast_match(&ipv6_send_buf->destaddr)){ - lowpan_init((ieee_802154_long_t*)&(ipv6_send_buf->destaddr.uint16[4]),(uint8_t*)ipv6_send_buf); - } - else{ - //find right next hop before sending - ipv6_addr_t *next_hop = rpl_get_next_hop(&ipv6_send_buf->destaddr); - if(next_hop == NULL){ - if(i_am_root){ - //oops... ich bin root und weiß nicht wohin mit dem paketn - printf("[Error] destination unknown\n"); - return; - } - else{ - next_hop = rpl_get_my_preferred_parent(); - if(next_hop == NULL){ - //kein preferred parent eingetragen - puts("[Error] no preferred parent, dropping package"); - return; - } - } - } - lowpan_init((ieee_802154_long_t*)&(next_hop->uint16[4]),(uint8_t*)ipv6_send_buf); - } + if(ipv6_prefix_mcast_match(&ipv6_send_buf->destaddr)) { + lowpan_init((ieee_802154_long_t *)&(ipv6_send_buf->destaddr.uint16[4]), (uint8_t *)ipv6_send_buf); + } + else { + /* find right next hop before sending */ + ipv6_addr_t *next_hop = rpl_get_next_hop(&ipv6_send_buf->destaddr); + + if(next_hop == NULL) { + if(i_am_root) { + /* oops... ich bin root und weiß nicht wohin mit dem paketn */ + printf("[Error] destination unknown\n"); + return; + } + else { + next_hop = rpl_get_my_preferred_parent(); + + if(next_hop == NULL) { + /* kein preferred parent eingetragen */ + puts("[Error] no preferred parent, dropping package"); + return; + } + } + } + + lowpan_init((ieee_802154_long_t *)&(next_hop->uint16[4]), (uint8_t *)ipv6_send_buf); + } } -ipv6_addr_t *rpl_get_next_hop(ipv6_addr_t * addr){ - for(uint8_t i=0; ilifetime = lifetime; - return; - } - for(uint8_t i=0; ilifetime = lifetime; + return; + } + + for(uint8_t i = 0; i < RPL_MAX_ROUTING_ENTRIES; i++) { + if(!routing_table[i].used) { + routing_table[i].address = *addr; + routing_table[i].next_hop = *next_hop; + routing_table[i].lifetime = lifetime; + routing_table[i].used = 1; + break; + } + } } -void rpl_del_routing_entry(ipv6_addr_t *addr){ - for(uint8_t i=0; i + * @} + */ + +#include #include #include #include @@ -22,9 +40,9 @@ void recv_rpl_dis(void); void recv_rpl_dao(void); void recv_rpl_dao_ack(void); void rpl_send(ipv6_addr_t *destination, uint8_t *payload, uint16_t p_len, uint8_t next_header, void *tcp_socket); -ipv6_addr_t *rpl_get_next_hop(ipv6_addr_t * addr); +ipv6_addr_t *rpl_get_next_hop(ipv6_addr_t *addr); void rpl_add_routing_entry(ipv6_addr_t *addr, ipv6_addr_t *next_hop, uint16_t lifetime); void rpl_del_routing_entry(ipv6_addr_t *addr); -rpl_routing_entry_t * rpl_find_routing_entry(ipv6_addr_t *addr); +rpl_routing_entry_t *rpl_find_routing_entry(ipv6_addr_t *addr); void rpl_clear_routing_table(void); rpl_routing_entry_t *rpl_get_routing_table(void); diff --git a/sys/net/sixlowpan/rpl/rpl_dodag.c b/sys/net/sixlowpan/rpl/rpl_dodag.c index 912e2de692..c53ca3e023 100644 --- a/sys/net/sixlowpan/rpl/rpl_dodag.c +++ b/sys/net/sixlowpan/rpl/rpl_dodag.c @@ -1,3 +1,21 @@ +/** + * RPL dodag implementation + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup rpl + * @{ + * @file rpl_dodag.c + * @brief RPL dodag functions + * @author Eric Engel + * @} + */ + +#include #include #include @@ -9,307 +27,365 @@ rpl_instance_t instances[RPL_MAX_INSTANCES]; rpl_dodag_t dodags[RPL_MAX_DODAGS]; rpl_parent_t parents[RPL_MAX_PARENTS]; -rpl_instance_t *rpl_new_instance(uint8_t instanceid){ - rpl_instance_t *inst; - rpl_instance_t *end ; - for(inst=&instances[0], end = inst+RPL_MAX_INSTANCES; inst < end;inst++){ - if(inst->used == 0){ - memset(inst, 0, sizeof(*inst)); - inst->used = 1; - inst->id = instanceid; - return inst; - } - } - return NULL; +rpl_instance_t *rpl_new_instance(uint8_t instanceid) +{ + rpl_instance_t *inst; + rpl_instance_t *end ; + + for(inst = &instances[0], end = inst + RPL_MAX_INSTANCES; inst < end; inst++) { + if(inst->used == 0) { + memset(inst, 0, sizeof(*inst)); + inst->used = 1; + inst->id = instanceid; + return inst; + } + } + + return NULL; } -rpl_instance_t *rpl_get_instance(uint8_t instanceid){ - for(int i=0;iused == 0){ - memset(dodag, 0,sizeof(*dodag)); - dodag->instance = inst; - dodag->my_rank = INFINITE_RANK; - dodag->used = 1; - memcpy(&dodag->dodag_id,dodagid,sizeof(*dodagid)); - return dodag; - } - } - return NULL; + rpl_dodag_t *dodag; + rpl_dodag_t *end; + + for(dodag = &dodags[0], end = dodag + RPL_MAX_DODAGS; dodag < end; dodag++) { + if(dodag->used == 0) { + memset(dodag, 0, sizeof(*dodag)); + dodag->instance = inst; + dodag->my_rank = INFINITE_RANK; + dodag->used = 1; + memcpy(&dodag->dodag_id, dodagid, sizeof(*dodagid)); + return dodag; + } + } + + return NULL; } -rpl_dodag_t *rpl_get_dodag(ipv6_addr_t *id){ - for(int i=0;ijoined = 0; - dodag->my_preferred_parent = NULL; - rpl_delete_all_parents(); +void rpl_leave_dodag(rpl_dodag_t *dodag) +{ + dodag->joined = 0; + dodag->my_preferred_parent = NULL; + rpl_delete_all_parents(); } -bool rpl_equal_id(ipv6_addr_t *id1, ipv6_addr_t *id2){ - for(uint8_t i=0;i<4;i++){ - if(id1->uint32[i] != id2->uint32[i]){ - return false; - } - } - return true; +bool rpl_equal_id(ipv6_addr_t *id1, ipv6_addr_t *id2) +{ + for(uint8_t i = 0; i < 4; i++) { + if(id1->uint32[i] != id2->uint32[i]) { + return false; + } + } + + return true; } -rpl_parent_t *rpl_new_parent(rpl_dodag_t *dodag, ipv6_addr_t *address, uint16_t rank){ - rpl_parent_t *parent; - rpl_parent_t *end; +rpl_parent_t *rpl_new_parent(rpl_dodag_t *dodag, ipv6_addr_t *address, uint16_t rank) +{ + rpl_parent_t *parent; + rpl_parent_t *end; - for(parent= &parents[0], end=parents+RPL_MAX_PARENTS; parent < end; parent++){ - if(parent->used == 0){ - memset(parent, 0, sizeof(*parent)); - parent->used = 1; - parent->addr = *address; - parent->rank = rank; - parent->dodag = dodag; - //dtsn is set at the end of recv_dio function - parent->dtsn = 0; - return parent; - } - } - rpl_delete_worst_parent(); - return rpl_new_parent(dodag, address, rank); + for(parent = &parents[0], end = parents + RPL_MAX_PARENTS; parent < end; parent++) { + if(parent->used == 0) { + memset(parent, 0, sizeof(*parent)); + parent->used = 1; + parent->addr = *address; + parent->rank = rank; + parent->dodag = dodag; + /* dtsn is set at the end of recv_dio function */ + parent->dtsn = 0; + return parent; + } + } + + rpl_delete_worst_parent(); + return rpl_new_parent(dodag, address, rank); } -rpl_parent_t *rpl_find_parent(ipv6_addr_t *address){ - rpl_parent_t *parent; - rpl_parent_t *end; +rpl_parent_t *rpl_find_parent(ipv6_addr_t *address) +{ + rpl_parent_t *parent; + rpl_parent_t *end; - for(parent= &parents[0], end=parents+RPL_MAX_PARENTS; parent < end; parent++){ - if( (parent->used) && (rpl_equal_id(address, &parent->addr)) ){ - return parent; - } - } - return NULL; + for(parent = &parents[0], end = parents + RPL_MAX_PARENTS; parent < end; parent++) { + if((parent->used) && (rpl_equal_id(address, &parent->addr))) { + return parent; + } + } + + return NULL; } -void rpl_delete_parent(rpl_parent_t * parent){ - rpl_dodag_t * my_dodag = rpl_get_my_dodag(); - if( (my_dodag != NULL) && rpl_equal_id(&my_dodag->my_preferred_parent->addr, &parent->addr) ){ - my_dodag->my_preferred_parent = NULL; - } - memset(parent,0,sizeof(*parent)); +void rpl_delete_parent(rpl_parent_t *parent) +{ + rpl_dodag_t *my_dodag = rpl_get_my_dodag(); + + if((my_dodag != NULL) && rpl_equal_id(&my_dodag->my_preferred_parent->addr, + &parent->addr)) { + my_dodag->my_preferred_parent = NULL; + } + + memset(parent, 0, sizeof(*parent)); } -void rpl_delete_worst_parent(void){ - uint8_t worst = 0xFF; - uint16_t max_rank = 0x0000; - for(int i=0;i max_rank){ - worst = i; - max_rank = parents[i].rank; - } - } - if(worst == 0xFF){ - //Fehler, keine parents -> sollte nicht passieren - return; - } - rpl_delete_parent(&parents[worst]); +void rpl_delete_worst_parent(void) +{ + uint8_t worst = 0xFF; + uint16_t max_rank = 0x0000; + + for(int i = 0; i < RPL_MAX_PARENTS; i++) { + if(parents[i].rank > max_rank) { + worst = i; + max_rank = parents[i].rank; + } + } + + if(worst == 0xFF) { + /* Fehler, keine parents -> sollte nicht passieren */ + return; + } + + rpl_delete_parent(&parents[worst]); } -void rpl_delete_all_parents(void){ - rpl_dodag_t * my_dodag = rpl_get_my_dodag(); - my_dodag->my_preferred_parent = NULL; - for(int i=0;imy_preferred_parent = NULL; + + for(int i = 0; i < RPL_MAX_PARENTS; i++) { + memset(&parents[i], 0, sizeof(parents[i])); + } } -rpl_parent_t * rpl_find_preferred_parent(void){ - rpl_parent_t * best = NULL; - rpl_dodag_t * my_dodag = rpl_get_my_dodag(); +rpl_parent_t *rpl_find_preferred_parent(void) +{ + rpl_parent_t *best = NULL; + rpl_dodag_t *my_dodag = rpl_get_my_dodag(); - for(uint8_t i=0;iof->which_parent(best, &parents[i]); - } - } - } + for(uint8_t i = 0; i < RPL_MAX_PARENTS; i++) { + if(parents[i].used) { + if((parents[i].rank == INFINITE_RANK) || (parents[i].lifetime <= 1)) { + puts("bad parent"); + continue; + } + else if(best == NULL) { + puts("parent"); + best = &parents[i]; + } + else { + best = my_dodag->of->which_parent(best, &parents[i]); + } + } + } + if(best == NULL) { + return NULL; + } - if(best == NULL){ - return NULL; - } - - if(!rpl_equal_id(&my_dodag->my_preferred_parent->addr, &best->addr)){ - if(my_dodag->mop != NO_DOWNWARD_ROUTES){ - //send DAO with ZERO_LIFETIME to old parent - send_DAO(&my_dodag->my_preferred_parent->addr, 0, false, 0); - } - my_dodag->my_preferred_parent = best; - if(my_dodag->mop != NO_DOWNWARD_ROUTES){ - delay_dao(); - } - reset_trickletimer(); - } - - return best; + if(!rpl_equal_id(&my_dodag->my_preferred_parent->addr, &best->addr)) { + if(my_dodag->mop != NO_DOWNWARD_ROUTES) { + /* send DAO with ZERO_LIFETIME to old parent */ + send_DAO(&my_dodag->my_preferred_parent->addr, 0, false, 0); + } + + my_dodag->my_preferred_parent = best; + + if(my_dodag->mop != NO_DOWNWARD_ROUTES) { + delay_dao(); + } + + reset_trickletimer(); + } + + return best; } -void rpl_parent_update(rpl_parent_t * parent){ - rpl_dodag_t * my_dodag = rpl_get_my_dodag(); - uint16_t old_rank = my_dodag->my_rank; - - //update Parent lifetime - if(parent != NULL){ - parent->lifetime = my_dodag->default_lifetime * my_dodag->lifetime_unit; - } +void rpl_parent_update(rpl_parent_t *parent) +{ + rpl_dodag_t *my_dodag = rpl_get_my_dodag(); + uint16_t old_rank = my_dodag->my_rank; - if(rpl_find_preferred_parent() == NULL){ - rpl_local_repair(); - } - - if(rpl_calc_rank(old_rank, my_dodag->minhoprankincrease) != rpl_calc_rank(my_dodag->my_rank, my_dodag->minhoprankincrease)){ - if(my_dodag->my_rank < my_dodag->min_rank){ - my_dodag->min_rank = my_dodag->my_rank; - } - reset_trickletimer(); - } + /* update Parent lifetime */ + if(parent != NULL) { + parent->lifetime = my_dodag->default_lifetime * my_dodag->lifetime_unit; + } + + if(rpl_find_preferred_parent() == NULL) { + rpl_local_repair(); + } + + if(rpl_calc_rank(old_rank, my_dodag->minhoprankincrease) != + rpl_calc_rank(my_dodag->my_rank, my_dodag->minhoprankincrease)) { + if(my_dodag->my_rank < my_dodag->min_rank) { + my_dodag->min_rank = my_dodag->my_rank; + } + + reset_trickletimer(); + } } -void rpl_join_dodag(rpl_dodag_t *dodag, ipv6_addr_t *parent, uint16_t parent_rank){ - rpl_dodag_t *my_dodag; - rpl_parent_t *preferred_parent; - my_dodag = rpl_new_dodag(dodag->instance->id, &dodag->dodag_id); - if(my_dodag == NULL){ - return; - } - preferred_parent = rpl_new_parent(my_dodag, parent, parent_rank); - if(preferred_parent == NULL){ - rpl_del_dodag(my_dodag); - return; - } - my_dodag->instance->joined = 1; - my_dodag->of = dodag->of; - my_dodag->mop = dodag->mop; - my_dodag->dtsn = dodag->dtsn; - my_dodag->prf = dodag->prf; - my_dodag->dio_interval_doubling = dodag->dio_interval_doubling; - my_dodag->dio_min = dodag->dio_min; - my_dodag->dio_redundancy = dodag->dio_redundancy; - my_dodag->maxrankincrease = dodag->maxrankincrease; - my_dodag->minhoprankincrease = dodag->minhoprankincrease; - my_dodag->default_lifetime = dodag->default_lifetime; - my_dodag->lifetime_unit = dodag->lifetime_unit; - my_dodag->version = dodag->version; - my_dodag->grounded = dodag->grounded; - my_dodag->joined = 1; - my_dodag->my_preferred_parent = preferred_parent; - my_dodag->my_rank = dodag->of->calc_rank(preferred_parent, dodag->my_rank); - my_dodag->dao_seq = RPL_COUNTER_INIT; - my_dodag->min_rank = my_dodag->my_rank; - - start_trickle(my_dodag->dio_min, my_dodag->dio_interval_doubling, my_dodag->dio_redundancy); - delay_dao(); +void rpl_join_dodag(rpl_dodag_t *dodag, ipv6_addr_t *parent, uint16_t parent_rank) +{ + rpl_dodag_t *my_dodag; + rpl_parent_t *preferred_parent; + my_dodag = rpl_new_dodag(dodag->instance->id, &dodag->dodag_id); + + if(my_dodag == NULL) { + return; + } + + preferred_parent = rpl_new_parent(my_dodag, parent, parent_rank); + + if(preferred_parent == NULL) { + rpl_del_dodag(my_dodag); + return; + } + + my_dodag->instance->joined = 1; + my_dodag->of = dodag->of; + my_dodag->mop = dodag->mop; + my_dodag->dtsn = dodag->dtsn; + my_dodag->prf = dodag->prf; + my_dodag->dio_interval_doubling = dodag->dio_interval_doubling; + my_dodag->dio_min = dodag->dio_min; + my_dodag->dio_redundancy = dodag->dio_redundancy; + my_dodag->maxrankincrease = dodag->maxrankincrease; + my_dodag->minhoprankincrease = dodag->minhoprankincrease; + my_dodag->default_lifetime = dodag->default_lifetime; + my_dodag->lifetime_unit = dodag->lifetime_unit; + my_dodag->version = dodag->version; + my_dodag->grounded = dodag->grounded; + my_dodag->joined = 1; + my_dodag->my_preferred_parent = preferred_parent; + my_dodag->my_rank = dodag->of->calc_rank(preferred_parent, dodag->my_rank); + my_dodag->dao_seq = RPL_COUNTER_INIT; + my_dodag->min_rank = my_dodag->my_rank; + + start_trickle(my_dodag->dio_min, my_dodag->dio_interval_doubling, my_dodag->dio_redundancy); + delay_dao(); } -void rpl_global_repair(rpl_dodag_t *dodag, ipv6_addr_t * p_addr, uint16_t rank){ - puts("[INFO] Global repair started"); - rpl_dodag_t * my_dodag = rpl_get_my_dodag(); - if(my_dodag == NULL){ - printf("[Error] - no global repair possible, if not part of a DODAG\n"); - return; - } - rpl_delete_all_parents(); - my_dodag->version = dodag->version; - my_dodag->dtsn++; - my_dodag->my_preferred_parent = rpl_new_parent(my_dodag, p_addr, rank); - if(my_dodag->my_preferred_parent == NULL){ - printf("[Error] no more parent after global repair\n"); - my_dodag->my_rank = INFINITE_RANK; - }else{ - //Calc new Rank - my_dodag->my_rank = my_dodag->of->calc_rank(my_dodag->my_preferred_parent, my_dodag->my_rank); - my_dodag->min_rank = my_dodag->my_rank; - reset_trickletimer(); - delay_dao(); - } - printf("Migrated to DODAG Version %d. My new Rank: %d\n", my_dodag->version, my_dodag->my_rank); +void rpl_global_repair(rpl_dodag_t *dodag, ipv6_addr_t *p_addr, uint16_t rank) +{ + puts("[INFO] Global repair started"); + rpl_dodag_t *my_dodag = rpl_get_my_dodag(); - + if(my_dodag == NULL) { + printf("[Error] - no global repair possible, if not part of a DODAG\n"); + return; + } + + rpl_delete_all_parents(); + my_dodag->version = dodag->version; + my_dodag->dtsn++; + my_dodag->my_preferred_parent = rpl_new_parent(my_dodag, p_addr, rank); + + if(my_dodag->my_preferred_parent == NULL) { + printf("[Error] no more parent after global repair\n"); + my_dodag->my_rank = INFINITE_RANK; + } + else { + /* Calc new Rank */ + my_dodag->my_rank = my_dodag->of->calc_rank(my_dodag->my_preferred_parent, + my_dodag->my_rank); + my_dodag->min_rank = my_dodag->my_rank; + reset_trickletimer(); + delay_dao(); + } + + printf("Migrated to DODAG Version %d. My new Rank: %d\n", my_dodag->version, + my_dodag->my_rank); } -void rpl_local_repair(void){ - puts("[INFO] Local Repair started"); - rpl_dodag_t * my_dodag = rpl_get_my_dodag(); - if(my_dodag == NULL){ - printf("[Error] - no local repair possible, if not part of a DODAG\n"); - return; - } - my_dodag->my_rank = INFINITE_RANK; - my_dodag->dtsn++; - rpl_delete_all_parents(); - reset_trickletimer(); +void rpl_local_repair(void) +{ + puts("[INFO] Local Repair started"); + rpl_dodag_t *my_dodag = rpl_get_my_dodag(); + + if(my_dodag == NULL) { + printf("[Error] - no local repair possible, if not part of a DODAG\n"); + return; + } + + my_dodag->my_rank = INFINITE_RANK; + my_dodag->dtsn++; + rpl_delete_all_parents(); + reset_trickletimer(); } -ipv6_addr_t *rpl_get_my_preferred_parent(){ - rpl_dodag_t * my_dodag = rpl_get_my_dodag(); - if(my_dodag == NULL){ - return NULL; - } - return &my_dodag->my_preferred_parent->addr; +ipv6_addr_t *rpl_get_my_preferred_parent() +{ + rpl_dodag_t *my_dodag = rpl_get_my_dodag(); + + if(my_dodag == NULL) { + return NULL; + } + + return &my_dodag->my_preferred_parent->addr; } -uint16_t rpl_calc_rank(uint16_t abs_rank, uint16_t minhoprankincrease){ - return abs_rank / minhoprankincrease; +uint16_t rpl_calc_rank(uint16_t abs_rank, uint16_t minhoprankincrease) +{ + return abs_rank / minhoprankincrease; } diff --git a/sys/net/sixlowpan/rpl/rpl_dodag.h b/sys/net/sixlowpan/rpl/rpl_dodag.h index 19873f158f..a4ad7e0ace 100644 --- a/sys/net/sixlowpan/rpl/rpl_dodag.h +++ b/sys/net/sixlowpan/rpl/rpl_dodag.h @@ -1,5 +1,22 @@ +/** + * RPL dodag prototypes + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup rpl + * @{ + * @file rpl_dodag.h + * @brief RPL dodag header + * @author Eric Engel + * @} + */ + +#include #include "rpl_structs.h" -//#include "of0.h" rpl_instance_t *rpl_new_instance(uint8_t instanceid); rpl_instance_t *rpl_get_instance(uint8_t instanceid); @@ -11,14 +28,14 @@ void rpl_join_dodag(rpl_dodag_t *dodag, ipv6_addr_t *parent, uint16_t parent_ran void rpl_del_dodag(rpl_dodag_t *dodag); rpl_parent_t *rpl_new_parent(rpl_dodag_t *dodag, ipv6_addr_t *address, uint16_t rank); rpl_parent_t *rpl_find_parent(ipv6_addr_t *address); -void rpl_leave_dodag(rpl_dodag_t * dodag); +void rpl_leave_dodag(rpl_dodag_t *dodag); bool rpl_equal_id(ipv6_addr_t *id1, ipv6_addr_t *id2); ipv6_addr_t *rpl_get_my_preferred_parent(void); void rpl_delete_parent(rpl_parent_t *parent); void rpl_delete_worst_parent(void); void rpl_delete_all_parents(void); -rpl_parent_t * rpl_find_preferred_parent(void); -void rpl_parent_update(rpl_parent_t * parent); -void rpl_global_repair(rpl_dodag_t *dodag, ipv6_addr_t * p_addr, uint16_t rank); +rpl_parent_t *rpl_find_preferred_parent(void); +void rpl_parent_update(rpl_parent_t *parent); +void rpl_global_repair(rpl_dodag_t *dodag, ipv6_addr_t *p_addr, uint16_t rank); void rpl_local_repair(void); uint16_t rpl_calc_rank(uint16_t abs_rank, uint16_t minhoprankincrease); diff --git a/sys/net/sixlowpan/rpl/rpl_structs.h b/sys/net/sixlowpan/rpl/rpl_structs.h index c9e95dad1b..c3b04a1ea9 100644 --- a/sys/net/sixlowpan/rpl/rpl_structs.h +++ b/sys/net/sixlowpan/rpl/rpl_structs.h @@ -1,22 +1,40 @@ +/** + * RPL data structs + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup rpl + * @{ + * @file rpl_structs.h + * @brief RPL data structs + * @author Eric Engel + * @} + */ + +#include #include "sys/net/sixlowpan/sixlowip.h" #ifndef RPL_STRUCTS_H_INCLUDED #define RPL_STRUCTS_H_INCLUDED -// Modes of Operation +/* Modes of Operation */ #define NO_DOWNWARD_ROUTES 0x00 #define NON_STORING_MODE 0x01 #define STORING_MODE_NO_MC 0x02 #define STORING_MODE_MC 0x03 -//ICMP type +/* ICMP type */ #define ICMP_RPL_CONTROL 155 #define RPL_SEQUENCE_WINDOW 16 #define ICMP_CODE_DIS 0x00 #define ICMP_CODE_DIO 0x01 #define ICMP_CODE_DAO 0x02 #define ICMP_CODE_DAO_ACK 0x03 -//packet base lengths +/* packet base lengths */ #define DIO_BASE_LEN 24 #define DIS_BASE_LEN 2 #define DAO_BASE_LEN 4 @@ -30,7 +48,7 @@ #define RPL_OPT_TARGET_LEN 18 #define RPL_OPT_TRANSIT_LEN 4 -//message options +/* message options */ #define RPL_OPT_PAD1 0 #define RPL_OPT_PADN 1 #define RPL_OPT_DAG_METRIC_CONTAINER 2 @@ -42,7 +60,7 @@ #define RPL_OPT_PREFIX_INFO 8 #define RPL_OPT_TARGET_DESC 9 -//Counters +/* Counters */ #define RPL_COUNTER_MAX 255 #define RPL_COUNTER_LOWER_REGION 127 #define RPL_COUNTER_SEQ_WINDOW 16 @@ -52,11 +70,11 @@ #define RPL_COUNTER_GREATER_THAN_LOCAL(A,B) (((A B) && (A-B < RPL_COUNTER_SEQ_WINDOW))) #define RPL_COUNTER_GREATER_THAN(A,B) ((A>RPL_COUNTER_LOWER_REGION) ? ((B > RPL_COUNTER_LOWER_REGION ) ? RPL_COUNTER_GREATER_THAN_LOCAL(A,B) : 0): (( B>RPL_COUNTER_LOWER_REGION ) ? 1: RPL_COUNTER_GREATER_THAN_LOCAL(A,B))) -// Default values +/* Default values */ #define RPL_DEFAULT_MOP STORING_MODE_NO_MC -// RPL Constants and Variables +/* RPL Constants and Variables */ #define BASE_RANK 0 #define ROOT_RANK 1 @@ -64,21 +82,21 @@ #define RPL_DEFAULT_INSTANCE 0 #define DEFAULT_PATH_CONTROL_SIZE 0 #define DEFAULT_DIO_INTERVAL_MIN 11 -//standard value: -//#define DEFAULT_DIO_INTERVAL_MIN 3 +/* standard value: */ +/* #define DEFAULT_DIO_INTERVAL_MIN 3 */ #define DEFAULT_DIO_INTERVAL_DOUBLINGS 7 -//standard value: -//#define DEFAULT_DIO_INTERVAL_DOUBLINGS 20 +/* standard value: */ +/* #define DEFAULT_DIO_INTERVAL_DOUBLINGS 20 */ #define DEFAULT_DIO_REDUNDANCY_CONSTANT 10 #define DEFAULT_MIN_HOP_RANK_INCREASE 256 -//DAO_DELAY is in seconds +/* DAO_DELAY is in seconds */ #define DEFAULT_DAO_DELAY 3 #define REGULAR_DAO_INTERVAL 300 #define DAO_SEND_RETRIES 4 #define DEFAULT_WAIT_FOR_DAO_ACK 15 #define RPL_DODAG_ID_LEN 16 -//others +/* others */ #define NUMBER_IMPLEMENTED_OFS 1 #define RPL_MAX_DODAGS 3 @@ -98,46 +116,47 @@ #define RPL_GROUNDED_SHIFT 7 #define RPL_DEFAULT_OCP 0 -struct __attribute__((packed)) rpl_dio_t{ +struct __attribute__((packed)) rpl_dio_t { uint8_t rpl_instanceid; uint8_t version_number; uint16_t rank; uint8_t g_mop_prf; uint8_t dtsn; - uint8_t flags; + uint8_t flags; uint8_t reserved; ipv6_addr_t dodagid; }; -struct __attribute__((packed)) rpl_dis_t{ +struct __attribute__((packed)) rpl_dis_t { uint8_t flags; uint8_t reserved; }; -struct __attribute__((packed)) rpl_dao_t{ +struct __attribute__((packed)) rpl_dao_t { uint8_t rpl_instanceid; uint8_t k_d_flags; uint8_t reserved; uint8_t dao_sequence; }; -struct __attribute__((packed)) rpl_dao_ack_t{ +struct __attribute__((packed)) rpl_dao_ack_t { uint8_t rpl_instanceid; uint8_t d_reserved; uint8_t dao_sequence; uint8_t status; }; -//may be present in dao or dao_ack packets -struct __attribute__((packed)) dodag_id_t{ +/* may be present in dao or dao_ack packets */ +struct __attribute__((packed)) dodag_id_t { ipv6_addr_t dodagid; }; -typedef struct __attribute__((packed)) rpl_opt_t { + +typedef struct __attribute__((packed)) { uint8_t type; uint8_t length; } rpl_opt_t; -typedef struct __attribute__((packed)) rpl_opt_dodag_conf_t { +typedef struct __attribute__((packed)) { uint8_t type; uint8_t length; uint8_t flags_a_pcs; @@ -152,80 +171,78 @@ typedef struct __attribute__((packed)) rpl_opt_dodag_conf_t { uint16_t lifetime_unit; } rpl_opt_dodag_conf_t; -typedef struct __attribute__((packed)) rpl_opt_solicited_t { - uint8_t type; - uint8_t length; - uint8_t rplinstanceid; - uint8_t VID_Flags; - ipv6_addr_t dodagid; - uint8_t version; +typedef struct __attribute__((packed)) { + uint8_t type; + uint8_t length; + uint8_t rplinstanceid; + uint8_t VID_Flags; + ipv6_addr_t dodagid; + uint8_t version; } rpl_opt_solicited_t; -//ipv6_addr_t target may be replaced by a target prefix of variable length -typedef struct __attribute__((packed)) rpl_opt_target_t { - uint8_t type; - uint8_t length; - uint8_t flags; - uint8_t prefix_length; - ipv6_addr_t target; +/* ipv6_addr_t target may be replaced by a target prefix of variable length */ +typedef struct __attribute__((packed)) { + uint8_t type; + uint8_t length; + uint8_t flags; + uint8_t prefix_length; + ipv6_addr_t target; } rpl_opt_target_t; -typedef struct __attribute__((packed)) rpl_opt_transit_t { - uint8_t type; - uint8_t length; - uint8_t e_flags; - uint8_t path_control; - uint8_t path_sequence; - uint8_t path_lifetime; +typedef struct __attribute__((packed)) { + uint8_t type; + uint8_t length; + uint8_t e_flags; + uint8_t path_control; + uint8_t path_sequence; + uint8_t path_lifetime; } rpl_opt_transit_t; struct rpl_dodag_t; -typedef struct rpl_parent_t { +typedef struct { ipv6_addr_t addr; uint16_t rank; - uint8_t dtsn; + uint8_t dtsn; struct rpl_dodag_t *dodag; - uint16_t lifetime; - uint8_t used; + uint16_t lifetime; + uint8_t used; } rpl_parent_t; struct rpl_of_t; -typedef struct rpl_instance_t { - //struct rpl_dodag_t *current_dodoag; +typedef struct { uint8_t id; uint8_t used; - uint8_t joined; + uint8_t joined; } rpl_instance_t; -typedef struct rpl_dodag_t { +typedef struct { rpl_instance_t *instance; ipv6_addr_t dodag_id; uint8_t used; uint8_t mop; uint8_t dtsn; - uint8_t prf; + uint8_t prf; uint8_t dio_interval_doubling; uint8_t dio_min; uint8_t dio_redundancy; uint16_t maxrankincrease; uint16_t minhoprankincrease; uint8_t default_lifetime; - uint16_t lifetime_unit; + uint16_t lifetime_unit; uint8_t version; uint8_t grounded; uint16_t my_rank; - uint8_t dao_seq; - uint16_t min_rank; + uint8_t dao_seq; + uint16_t min_rank; uint8_t joined; rpl_parent_t *my_preferred_parent; - struct rpl_of_t *of; - + struct rpl_of_t *of; } rpl_dodag_t; -typedef struct rpl_of_t { +typedef struct { uint16_t ocp; uint16_t (*calc_rank)(rpl_parent_t *, uint16_t); rpl_parent_t *(*which_parent)(rpl_parent_t *, rpl_parent_t *); @@ -234,12 +251,12 @@ typedef struct rpl_of_t { void (*parent_state_callback)(rpl_parent_t *, int, int); } rpl_of_t; -typedef struct rpl_routing_entry_t { - uint8_t used; - ipv6_addr_t address; - ipv6_addr_t next_hop; - uint16_t lifetime; - +typedef struct { + uint8_t used; + ipv6_addr_t address; + ipv6_addr_t next_hop; + uint16_t lifetime; + } rpl_routing_entry_t; #endif diff --git a/sys/net/sixlowpan/rpl/trickle.c b/sys/net/sixlowpan/rpl/trickle.c index e1201ad3f9..53886fa8aa 100644 --- a/sys/net/sixlowpan/rpl/trickle.c +++ b/sys/net/sixlowpan/rpl/trickle.c @@ -1,3 +1,21 @@ +/** + * Trickle implementation + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup rpl + * @{ + * @file trickle.c + * @brief Trickle implementation + * @author Eric Engel + * @} + */ + +#include #include #include #include @@ -32,180 +50,202 @@ timex_t I_time; timex_t dao_time; timex_t rt_time; -//struct für trickle parameter?? -void reset_trickletimer(void){ - I = Imin; - c = 0; - //start timer - t = (I/2) + ( rand() % ( I - (I/2) + 1 ) ); - t_time = timex_set(0,t*1000); - I_time = timex_set(0,I*1000); - timex_normalize(&t_time); - timex_normalize(&I_time); - vtimer_remove(&trickle_t_timer); - vtimer_remove(&trickle_I_timer); - vtimer_set_wakeup(&trickle_t_timer, t_time, timer_over_pid); - vtimer_set_wakeup(&trickle_I_timer, I_time, interval_over_pid); +void reset_trickletimer(void) +{ + I = Imin; + c = 0; + /* start timer */ + t = (I / 2) + (rand() % (I - (I / 2) + 1)); + t_time = timex_set(0, t * 1000); + I_time = timex_set(0, I * 1000); + timex_normalize(&t_time); + timex_normalize(&I_time); + vtimer_remove(&trickle_t_timer); + vtimer_remove(&trickle_I_timer); + vtimer_set_wakeup(&trickle_t_timer, t_time, timer_over_pid); + vtimer_set_wakeup(&trickle_I_timer, I_time, interval_over_pid); } -void init_trickle(void){ - //Create threads - ack_received = true; - timer_over_pid = thread_create(timer_over_buf, TRICKLE_TIMER_STACKSIZE, - PRIORITY_MAIN-1,CREATE_STACKTEST, - trickle_timer_over, "trickle_timer_over"); +void init_trickle(void) +{ + /* Create threads */ + ack_received = true; + timer_over_pid = thread_create(timer_over_buf, TRICKLE_TIMER_STACKSIZE, + PRIORITY_MAIN - 1, CREATE_STACKTEST, + trickle_timer_over, "trickle_timer_over"); - interval_over_pid = thread_create(interval_over_buf, TRICKLE_INTERVAL_STACKSIZE, - PRIORITY_MAIN-1, CREATE_STACKTEST, - trickle_interval_over, "trickle_interval_over"); - dao_delay_over_pid = thread_create(dao_delay_over_buf, DAO_DELAY_STACKSIZE, - PRIORITY_MAIN-1, CREATE_STACKTEST, - dao_delay_over, "dao_delay_over"); - rt_timer_over_pid = thread_create(routing_table_buf, RT_STACKSIZE, - PRIORITY_MAIN-1, CREATE_STACKTEST, - rt_timer_over, "rt_timer_over"); - -} - -void start_trickle(uint8_t DIOIntMin, uint8_t DIOIntDoubl, uint8_t DIORedundancyConstant){ - c = 0; - k = DIORedundancyConstant; - Imin = pow(2, DIOIntMin); - Imax = DIOIntDoubl; - //Eigentlich laut Spezifikation erste Bestimmung von I wie auskommentiert: - //I = Imin + ( rand() % ( (Imin << Imax) - Imin + 1 ) ); - I = Imin + ( rand() % (4*Imin) ) ; - - t = (I/2) + ( rand() % ( I - (I/2) + 1 ) ); - t_time = timex_set(0,t*1000); - timex_normalize(&t_time); - I_time = timex_set(0,I*1000); - timex_normalize(&I_time); - vtimer_remove(&trickle_t_timer); - vtimer_remove(&trickle_I_timer); - vtimer_set_wakeup(&trickle_t_timer, t_time, timer_over_pid); - vtimer_set_wakeup(&trickle_I_timer, I_time, interval_over_pid); + interval_over_pid = thread_create(interval_over_buf, TRICKLE_INTERVAL_STACKSIZE, + PRIORITY_MAIN - 1, CREATE_STACKTEST, + trickle_interval_over, "trickle_interval_over"); + dao_delay_over_pid = thread_create(dao_delay_over_buf, DAO_DELAY_STACKSIZE, + PRIORITY_MAIN - 1, CREATE_STACKTEST, + dao_delay_over, "dao_delay_over"); + rt_timer_over_pid = thread_create(routing_table_buf, RT_STACKSIZE, + PRIORITY_MAIN - 1, CREATE_STACKTEST, + rt_timer_over, "rt_timer_over"); } -void trickle_increment_counter(void){ - //call this function, when received DIO message +void start_trickle(uint8_t DIOIntMin, uint8_t DIOIntDoubl, + uint8_t DIORedundancyConstant) +{ + c = 0; + k = DIORedundancyConstant; + Imin = pow(2, DIOIntMin); + Imax = DIOIntDoubl; + /* Eigentlich laut Spezifikation erste Bestimmung von I wie auskommentiert: */ + /* I = Imin + ( rand() % ( (Imin << Imax) - Imin + 1 ) ); */ + I = Imin + (rand() % (4 * Imin)) ; + + t = (I / 2) + (rand() % (I - (I / 2) + 1)); + t_time = timex_set(0, t * 1000); + timex_normalize(&t_time); + I_time = timex_set(0, I * 1000); + timex_normalize(&I_time); + vtimer_remove(&trickle_t_timer); + vtimer_remove(&trickle_I_timer); + vtimer_set_wakeup(&trickle_t_timer, t_time, timer_over_pid); + vtimer_set_wakeup(&trickle_I_timer, I_time, interval_over_pid); +} + +void trickle_increment_counter(void) +{ + /* call this function, when received DIO message */ c++; } void trickle_timer_over(void) { - ipv6_addr_t mcast; - ipv6_set_all_nds_mcast_addr(&mcast); - while(1){ - thread_sleep(); - //Laut RPL Spezifikation soll k=0 wie k= Unendlich behandelt werden, also immer gesendet werden - if( (c < k) || (k == 0)){ - send_DIO(&mcast); - } - } + ipv6_addr_t mcast; + ipv6_set_all_nds_mcast_addr(&mcast); + + while(1) { + thread_sleep(); + + /* Laut RPL Spezifikation soll k=0 wie k= Unendlich behandelt werden, also immer gesendet werden */ + if((c < k) || (k == 0)) { + send_DIO(&mcast); + } + } } -void trickle_interval_over(void){ - while(1){ - thread_sleep(); - I = I*2; - printf("TRICKLE new Interval %u\n",I); - if( I == 0 ){ - puts("[WARNING] Interval was 0"); - if( Imax == 0){ - puts("[WARNING] Imax == 0"); - } - I = (Imin << Imax); - } - if(I > (Imin << Imax)){ - I=(Imin << Imax); - } - c=0; - t = (I/2) + ( rand() % ( I - (I/2) + 1 ) ); - //start timer - t_time = timex_set(0,t*1000); - timex_normalize(&t_time); - I_time = timex_set(0,I*1000); - timex_normalize(&I_time); - //vtimer_remove(&trickle_t_timer); - //vtimer_remove(&trickle_I_timer); - if(vtimer_set_wakeup(&trickle_t_timer, t_time, timer_over_pid) != 0){ - puts("[ERROR] setting Wakeup"); - } - if(vtimer_set_wakeup(&trickle_I_timer, I_time, interval_over_pid) != 0){ - puts("[ERROR] setting Wakeup"); - } - } +void trickle_interval_over(void) +{ + while(1) { + thread_sleep(); + I = I * 2; + printf("TRICKLE new Interval %u\n", I); + + if(I == 0) { + puts("[WARNING] Interval was 0"); + + if(Imax == 0) { + puts("[WARNING] Imax == 0"); + } + + I = (Imin << Imax); + } + + if(I > (Imin << Imax)) { + I = (Imin << Imax); + } + + c = 0; + t = (I / 2) + (rand() % (I - (I / 2) + 1)); + /* start timer */ + t_time = timex_set(0, t * 1000); + timex_normalize(&t_time); + I_time = timex_set(0, I * 1000); + timex_normalize(&I_time); + + if(vtimer_set_wakeup(&trickle_t_timer, t_time, timer_over_pid) != 0) { + puts("[ERROR] setting Wakeup"); + } + + if(vtimer_set_wakeup(&trickle_I_timer, I_time, interval_over_pid) != 0) { + puts("[ERROR] setting Wakeup"); + } + } } -void delay_dao(void){ - dao_time = timex_set(DEFAULT_DAO_DELAY,0); - dao_counter = 0; - ack_received = false; - vtimer_remove(&dao_timer); - vtimer_set_wakeup(&dao_timer, dao_time, dao_delay_over_pid); +void delay_dao(void) +{ + dao_time = timex_set(DEFAULT_DAO_DELAY, 0); + dao_counter = 0; + ack_received = false; + vtimer_remove(&dao_timer); + vtimer_set_wakeup(&dao_timer, dao_time, dao_delay_over_pid); } -//This function is used for regular update of the routes. The Timer can be overwritten, as the normal delay_dao function gets called -void long_delay_dao(void){ - dao_time = timex_set(REGULAR_DAO_INTERVAL,0); - dao_counter = 0; - ack_received = false; - vtimer_remove(&dao_timer); - vtimer_set_wakeup(&dao_timer, dao_time, dao_delay_over_pid); +/* This function is used for regular update of the routes. The Timer can be overwritten, as the normal delay_dao function gets called */ +void long_delay_dao(void) +{ + dao_time = timex_set(REGULAR_DAO_INTERVAL, 0); + dao_counter = 0; + ack_received = false; + vtimer_remove(&dao_timer); + vtimer_set_wakeup(&dao_timer, dao_time, dao_delay_over_pid); } -void dao_delay_over(void){ - while(1){ - thread_sleep(); - if((ack_received == false) && (dao_counter < DAO_SEND_RETRIES)){ - dao_counter++; - send_DAO(NULL, 0, true, 0); - dao_time = timex_set(DEFAULT_WAIT_FOR_DAO_ACK,0); - vtimer_set_wakeup(&dao_timer, dao_time, dao_delay_over_pid); - } - else if(ack_received == false){ - long_delay_dao(); - } - } +void dao_delay_over(void) +{ + while(1) { + thread_sleep(); + + if((ack_received == false) && (dao_counter < DAO_SEND_RETRIES)) { + dao_counter++; + send_DAO(NULL, 0, true, 0); + dao_time = timex_set(DEFAULT_WAIT_FOR_DAO_ACK, 0); + vtimer_set_wakeup(&dao_timer, dao_time, dao_delay_over_pid); + } + else if(ack_received == false) { + long_delay_dao(); + } + } } -void dao_ack_received(){ - ack_received = true; - long_delay_dao(); +void dao_ack_received() +{ + ack_received = true; + long_delay_dao(); } -void rt_timer_over(void){ - rpl_routing_entry_t * rt; - while(1){ - rpl_dodag_t * my_dodag = rpl_get_my_dodag(); - if(my_dodag != NULL){ - rt = rpl_get_routing_table(); - for(uint8_t i=0; imy_preferred_parent != NULL){ - if(my_dodag->my_preferred_parent->lifetime <= 1){ - puts("parent lifetime timeout"); - rpl_parent_update(NULL); - } - else{ - my_dodag->my_preferred_parent->lifetime--; - } - } - } - //Wake up every second - vtimer_usleep(1000000); - } +void rt_timer_over(void) +{ + rpl_routing_entry_t *rt; + + while(1) { + rpl_dodag_t *my_dodag = rpl_get_my_dodag(); + + if(my_dodag != NULL) { + rt = rpl_get_routing_table(); + + for(uint8_t i = 0; i < RPL_MAX_ROUTING_ENTRIES; i++) { + if(rt[i].used) { + if(rt[i].lifetime <= 1) { + memset(&rt[i], 0, sizeof(rt[i])); + } + else { + rt[i].lifetime--; + } + } + } + + /* Parent is NULL for root too */ + if(my_dodag->my_preferred_parent != NULL) { + if(my_dodag->my_preferred_parent->lifetime <= 1) { + puts("parent lifetime timeout"); + rpl_parent_update(NULL); + } + else { + my_dodag->my_preferred_parent->lifetime--; + } + } + } + + /* Wake up every second */ + vtimer_usleep(1000000); + } } diff --git a/sys/net/sixlowpan/rpl/trickle.h b/sys/net/sixlowpan/rpl/trickle.h index 637a97ee4e..72ec98dfc0 100644 --- a/sys/net/sixlowpan/rpl/trickle.h +++ b/sys/net/sixlowpan/rpl/trickle.h @@ -1,12 +1,26 @@ +/** + * Trickle constants and prototypes + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup rpl + * @{ + * @file trickle.h + * @brief Trickle + * @author Eric Engel + * @} + */ + #include #include -#define TRICKLE_TIMER_STACKSIZE 3072 -//#define TRICKLE_TIMER_STACKSIZE 4096 +#define TRICKLE_TIMER_STACKSIZE 3072 #define TRICKLE_INTERVAL_STACKSIZE 3072 -//#define DAO_DELAY_STACKSIZE 2048 #define DAO_DELAY_STACKSIZE 3072 -//#define DAO_DELAY_STACKSIZE 4096 #define RT_STACKSIZE 512 void reset_trickletimer(void); diff --git a/sys/net/sixlowpan/semaphore.c b/sys/net/sixlowpan/semaphore.c index dc30a71acd..fbc21f03a8 100644 --- a/sys/net/sixlowpan/semaphore.c +++ b/sys/net/sixlowpan/semaphore.c @@ -1,31 +1,54 @@ +/** + * Semaphore implemenation + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup sixlowpan + * @{ + * @file semaphore.c + * @brief Implemntation of semaphores using mutexes + * @author Martin Lenders + * @author Oliver Hahm + * @} + */ + #include #include "semaphore.h" -void sem_init(sem_t *sem, int8_t value) { +void sem_init(sem_t *sem, int8_t value) +{ sem->value = value; mutex_init(&sem->mutex); sem->locked = 0; } -int sem_wait(sem_t *sem) { +int sem_wait(sem_t *sem) +{ int res; + if(--(sem->value) <= 0 && !sem->locked) { sem->locked = !(sem->locked); res = mutex_lock(&(sem->mutex)); - if (res < 0) { + + if(res < 0) { return res; } } - + return 0; } -int sem_signal(sem_t *sem) { - if (++(sem->value) > 0 && sem->locked) { +int sem_signal(sem_t *sem) +{ + if(++(sem->value) > 0 && sem->locked) { sem->locked = !(sem->locked); - mutex_unlock(&(sem->mutex),0); + mutex_unlock(&(sem->mutex), 0); } - + return 0; } diff --git a/sys/net/sixlowpan/semaphore.h b/sys/net/sixlowpan/semaphore.h index 9352e4eb5c..b30b0e4d03 100644 --- a/sys/net/sixlowpan/semaphore.h +++ b/sys/net/sixlowpan/semaphore.h @@ -1,3 +1,21 @@ +/** + * Semaphore data struct and prototypes + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup sixlowpan + * @{ + * @file semaphore.h + * @brief data struct and prototypes for semaphores + * @author Martin Lenders + * @author Oliver Hahm + * @} + */ + #ifndef SEMAPHORE_H #define SEMAPHORE_H @@ -13,5 +31,5 @@ typedef struct sem_t { void sem_init(sem_t *sem, int8_t value); int sem_wait(sem_t *sem); int sem_signal(sem_t *sem); - + #endif /* SEMAPHORE_H*/ diff --git a/sys/net/sixlowpan/serialnumber.c b/sys/net/sixlowpan/serialnumber.c index 77a9fef541..909cf0e96b 100644 --- a/sys/net/sixlowpan/serialnumber.c +++ b/sys/net/sixlowpan/serialnumber.c @@ -1,58 +1,101 @@ +/** + * serial number arithmetics (corresponding RFC1982) for version field in ABRO + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup sixlowpan + * @{ + * @file serialnumber.c + * @brief serial number arithmetics (corresponding RFC1982) for version field in ABRO + * @author Martin Lenders + * @author Oliver Hahm + * @} + */ + + #include "serialnumber.h" -int serial_add8(uint8_t s, uint8_t n) { - if (n > 127) +int serial_add8(uint8_t s, uint8_t n) +{ + if(n > 127) { return -1; - uint16_t sum = s+n; - return (uint8_t)(sum%256); + } + + uint16_t sum = s + n; + return (uint8_t)(sum % 256); } -int serial_add16(uint16_t s, uint16_t n) { - if (n > 32767) +int serial_add16(uint16_t s, uint16_t n) +{ + if(n > 32767) { return -1; - uint32_t sum = s+n; - return (uint16_t)(sum%65536); + } + + uint32_t sum = s + n; + return (uint16_t)(sum % 65536); } -int serial_add32(uint32_t s, uint32_t n) { - if (n > 2147483647) +int serial_add32(uint32_t s, uint32_t n) +{ + if(n > 2147483647) { return -1; - uint64_t sum = s+n; - return (uint32_t)(sum%4294967296); + } + + uint64_t sum = s + n; + return (uint32_t)(sum % 4294967296); } -serial_comp_res_t serial_comp8(uint8_t s1, uint8_t s2) { - if (s1 == s2) +serial_comp_res_t serial_comp8(uint8_t s1, uint8_t s2) +{ + if(s1 == s2) { return EQUAL; - if ((s1 < s2 && s1 - s2 < 128) || (s1 > s2 && s1 - s2 > 128)) { + } + + if((s1 < s2 && s1 - s2 < 128) || (s1 > s2 && s1 - s2 > 128)) { return LESS; } - if ((s1 < s2 && s1 - s2 > 128) || (s1 > s2 && s1 - s2 < 128)) { + + if((s1 < s2 && s1 - s2 > 128) || (s1 > s2 && s1 - s2 < 128)) { return GREATER; } + return UNDEF; } -serial_comp_res_t serial_comp16(uint16_t s1, uint16_t s2) { - if (s1 == s2) +serial_comp_res_t serial_comp16(uint16_t s1, uint16_t s2) +{ + if(s1 == s2) { return EQUAL; - if ((s1 < s2 && s1 - s2 < 32768) || (s1 > s2 && s1 - s2 > 32768)) { + } + + if((s1 < s2 && s1 - s2 < 32768) || (s1 > s2 && s1 - s2 > 32768)) { return LESS; } - if ((s1 < s2 && s1 - s2 > 32768) || (s1 > s2 && s1 - s2 < 32768)) { + + if((s1 < s2 && s1 - s2 > 32768) || (s1 > s2 && s1 - s2 < 32768)) { return GREATER; } + return UNDEF; } -serial_comp_res_t serial_comp32(uint32_t s1, uint32_t s2) { - if (s1 == s2) +serial_comp_res_t serial_comp32(uint32_t s1, uint32_t s2) +{ + if(s1 == s2) { return EQUAL; - if ((s1 < s2 && s1 - s2 < 2147483648) || (s1 > s2 && s1 - s2 > 2147483648)) { + } + + if((s1 < s2 && s1 - s2 < 2147483648) || (s1 > s2 && s1 - s2 > 2147483648)) { return LESS; } - if ((s1 < s2 && s1 - s2 > 2147483648) || (s1 > s2 && s1 - s2 < 2147483648)) { + + if((s1 < s2 && s1 - s2 > 2147483648) || (s1 > s2 && s1 - s2 < 2147483648)) { return GREATER; } + return UNDEF; } diff --git a/sys/net/sixlowpan/sixlowborder.c b/sys/net/sixlowpan/sixlowborder.c index d50687d70d..d777a5f3f2 100644 --- a/sys/net/sixlowpan/sixlowborder.c +++ b/sys/net/sixlowpan/sixlowborder.c @@ -1,3 +1,21 @@ +/** + * 6lowpan border router implementation + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup sixlowpan + * @{ + * @file sixlowborder.c + * @brief constraint node implementation for a 6lowpan border router + * @author Martin Lenders + * @author Oliver Hahm + * @} + */ + #include #include #include @@ -28,140 +46,156 @@ uint16_t serial_reader_pid; uint8_t serial_out_buf[BORDER_BUFFER_SIZE]; uint8_t serial_in_buf[BORDER_BUFFER_SIZE]; -uint8_t *get_serial_out_buffer(int offset) { - if (offset > BUFFER_SIZE) { +uint8_t *get_serial_out_buffer(int offset) +{ + if(offset > BUFFER_SIZE) { return NULL; } - + return &(serial_out_buf[offset]); } -uint8_t *get_serial_in_buffer(int offset) { - if (offset > BUFFER_SIZE) { +uint8_t *get_serial_in_buffer(int offset) +{ + if(offset > BUFFER_SIZE) { return NULL; } - + return &(serial_in_buf[offset]); } -uint16_t border_get_serial_reader() { +uint16_t border_get_serial_reader() +{ return serial_reader_pid; } -void serial_reader_f(void) { +void serial_reader_f(void) +{ int main_pid = 0; int bytes; msg_t m; border_packet_t *uart_buf; - + posix_open(uart0_handler_pid, 0); - + msg_receive(&m); main_pid = m.sender_pid; - + while(1) { posix_open(uart0_handler_pid, 0); bytes = readpacket(get_serial_in_buffer(0), BORDER_BUFFER_SIZE); - if (bytes < 0) { - switch (bytes) { - case (-SIXLOWERROR_ARRAYFULL):{ + + if(bytes < 0) { + switch(bytes) { + case(-SIXLOWERROR_ARRAYFULL): { printf("ERROR: Array was full\n"); break; } - default:{ + + default: { printf("ERROR: unknown\n"); break; } } + continue; } - - uart_buf = (border_packet_t*)get_serial_in_buffer(0); - if (uart_buf->empty == 0) { - if (uart_buf->type == BORDER_PACKET_CONF_TYPE) { - border_conf_header_t *conf_packet = (border_conf_header_t*)uart_buf; - if (conf_packet->conftype == BORDER_CONF_SYN) { + + uart_buf = (border_packet_t *)get_serial_in_buffer(0); + + if(uart_buf->empty == 0) { + if(uart_buf->type == BORDER_PACKET_CONF_TYPE) { + border_conf_header_t *conf_packet = (border_conf_header_t *)uart_buf; + + if(conf_packet->conftype == BORDER_CONF_SYN) { m.content.ptr = (char *)conf_packet; msg_send(&m, main_pid, 1); continue; } } + flowcontrol_deliver_from_uart(uart_buf, bytes); } } } -uint8_t border_initialize(transceiver_type_t trans,ipv6_addr_t *border_router_addr) { +uint8_t border_initialize(transceiver_type_t trans, ipv6_addr_t *border_router_addr) +{ ipv6_addr_t addr; - + serial_reader_pid = thread_create( - serial_reader_stack, READER_STACK_SIZE, - PRIORITY_MAIN-1, CREATE_STACKTEST, - serial_reader_f, "serial_reader"); - - if (border_router_addr == NULL) { + serial_reader_stack, READER_STACK_SIZE, + PRIORITY_MAIN - 1, CREATE_STACKTEST, + serial_reader_f, "serial_reader"); + + if(border_router_addr == NULL) { border_router_addr = &addr; - + addr = flowcontrol_init(); } - - /* only allow addresses generated accoding to - * RFC 4944 (Section 6) & RFC 2464 (Section 4) from short address + + /* only allow addresses generated accoding to + * RFC 4944 (Section 6) & RFC 2464 (Section 4) from short address * -- for now */ - if ( border_router_addr->uint16[4] != HTONS(IEEE_802154_PAN_ID ^ 0x0200) || - border_router_addr->uint16[5] != HTONS(0x00FF) || - border_router_addr->uint16[6] != HTONS(0xFE00) - ) { + if(border_router_addr->uint16[4] != HTONS(IEEE_802154_PAN_ID ^ 0x0200) || + border_router_addr->uint16[5] != HTONS(0x00FF) || + border_router_addr->uint16[6] != HTONS(0xFE00) + ) { return SIXLOWERROR_ADDRESS; } - - // radio-address is 8-bit so this must be tested extra - if (border_router_addr->uint8[14] != 0) { + + /* radio-address is 8-bit so this must be tested extra */ + if(border_router_addr->uint8[14] != 0) { return SIXLOWERROR_ADDRESS; } - - memcpy(&(abr_addr.uint8[0]),&(border_router_addr->uint8[0]),16); - - sixlowpan_init(trans,border_router_addr->uint8[15],1); - + + memcpy(&(abr_addr.uint8[0]), &(border_router_addr->uint8[0]), 16); + + sixlowpan_init(trans, border_router_addr->uint8[15], 1); + ipv6_init_iface_as_router(); - + return SUCCESS; } -void border_send_ipv6_over_lowpan(struct ipv6_hdr_t *packet, uint8_t aro_flag, uint8_t sixco_flag) { - uint16_t offset = IPV6_HDR_LEN+HTONS(packet->length); - +void border_send_ipv6_over_lowpan(struct ipv6_hdr_t *packet, uint8_t aro_flag, uint8_t sixco_flag) +{ + uint16_t offset = IPV6_HDR_LEN + HTONS(packet->length); + packet->flowlabel = HTONS(packet->flowlabel); packet->length = HTONS(packet->length); - + memset(buffer, 0, BUFFER_SIZE); - memcpy(buffer+LL_HDR_LEN, packet, offset); - - lowpan_init((ieee_802154_long_t*)&(packet->destaddr.uint16[4]), (uint8_t*)packet); + memcpy(buffer + LL_HDR_LEN, packet, offset); + + lowpan_init((ieee_802154_long_t *)&(packet->destaddr.uint16[4]), (uint8_t *)packet); } -void border_process_lowpan(void) { +void border_process_lowpan(void) +{ msg_t m; struct ipv6_hdr_t *ipv6_buf; - + while(1) { msg_receive(&m); ipv6_buf = (struct ipv6_hdr_t *)m.content.ptr; - - if (ipv6_buf->nextheader == PROTO_NUM_ICMPV6) { + + if(ipv6_buf->nextheader == PROTO_NUM_ICMPV6) { struct icmpv6_hdr_t *icmp_buf = (struct icmpv6_hdr_t *)(((uint8_t *)ipv6_buf) + IPV6_HDR_LEN); - if (icmp_buf->type == ICMP_REDIRECT) { + + if(icmp_buf->type == ICMP_REDIRECT) { continue; } - if (icmpv6_demultiplex(icmp_buf) == 0) { + + if(icmpv6_demultiplex(icmp_buf) == 0) { continue; } - // Here, other ICMPv6 message types for ND may follow. + + /* Here, other ICMPv6 message types for ND may follow. */ } - - // TODO: Bei ICMPv6-Paketen entsprechende LoWPAN-Optionen verarbeiten und entfernen + + /* TODO: Bei ICMPv6-Paketen entsprechende LoWPAN-Optionen verarbeiten und entfernen */ multiplex_send_ipv6_over_uart(ipv6_buf); } } diff --git a/sys/net/sixlowpan/sixlowborder.h b/sys/net/sixlowpan/sixlowborder.h index f2e790c7b7..6726fe6817 100644 --- a/sys/net/sixlowpan/sixlowborder.h +++ b/sys/net/sixlowpan/sixlowborder.h @@ -1,3 +1,21 @@ +/** + * 6lowpan border router prototypes + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup sixlowpan + * @{ + * @file sixlowborder.h + * @brief header for 6lowpan border router + * @author Martin Lenders + * @author Oliver Hahm + * @} + */ + /* 6LoWPAN Border Router header file */ #ifndef SIXLOWBORDER_H @@ -17,7 +35,7 @@ uint16_t border_get_serial_reader(void); uint8_t *get_serial_out_buffer(int offset); uint8_t *get_serial_in_buffer(int offset); -uint8_t border_initialize(transceiver_type_t trans,ipv6_addr_t *border_router_addr); +uint8_t border_initialize(transceiver_type_t trans, ipv6_addr_t *border_router_addr); void border_send_ipv6_over_lowpan(struct ipv6_hdr_t *packet, uint8_t aro_flag, uint8_t sixco_flag); void border_process_lowpan(void); diff --git a/sys/net/sixlowpan/sixlowip.c b/sys/net/sixlowpan/sixlowip.c index 284756b1f4..6480c06dba 100644 --- a/sys/net/sixlowpan/sixlowip.c +++ b/sys/net/sixlowpan/sixlowip.c @@ -1,3 +1,23 @@ +/** + * IPv6 implementation + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup sixlowpan + * @{ + * @file sixlowip.c + * @brief 6lowpan IP layer functions + * @author Stephan Zeisberg + * @author Martin Lenders + * @author Eric Engel + * @author Oliver Gesch + * @} + */ + #include #include #include @@ -16,8 +36,8 @@ uint8_t ip_send_buffer[BUFFER_SIZE]; uint8_t buffer[BUFFER_SIZE]; msg_t msg_queue[IP_PKT_RECV_BUF_SIZE]; -struct ipv6_hdr_t* ipv6_buf; -struct icmpv6_hdr_t* icmp_buf; +struct ipv6_hdr_t *ipv6_buf; +struct icmpv6_hdr_t *icmp_buf; uint8_t ipv6_ext_hdr_len; uint8_t *nextheader; iface_t iface; @@ -26,43 +46,51 @@ int udp_packet_handler_pid = 0; int tcp_packet_handler_pid = 0; int rpl_process_pid = 0; -struct ipv6_hdr_t* get_ipv6_buf_send(void){ - return ((struct ipv6_hdr_t*)&(ip_send_buffer[LL_HDR_LEN])); +struct ipv6_hdr_t *get_ipv6_buf_send(void) +{ + return ((struct ipv6_hdr_t *) & (ip_send_buffer[LL_HDR_LEN])); } -uint8_t * get_payload_buf_send(uint8_t ext_len){ +uint8_t *get_payload_buf_send(uint8_t ext_len) +{ return &(ip_send_buffer[LLHDR_IPV6HDR_LEN + ext_len]); } -struct ipv6_hdr_t* get_ipv6_buf(void){ - return ((struct ipv6_hdr_t*)&(buffer[LL_HDR_LEN])); +struct ipv6_hdr_t *get_ipv6_buf(void) +{ + return ((struct ipv6_hdr_t *) & (buffer[LL_HDR_LEN])); } -struct icmpv6_hdr_t* get_icmpv6_buf(uint8_t ext_len){ - return ((struct icmpv6_hdr_t*)&(buffer[LLHDR_IPV6HDR_LEN + ext_len])); +struct icmpv6_hdr_t *get_icmpv6_buf(uint8_t ext_len) +{ + return ((struct icmpv6_hdr_t *) & (buffer[LLHDR_IPV6HDR_LEN + ext_len])); } -uint8_t * get_payload_buf(uint8_t ext_len){ +uint8_t *get_payload_buf(uint8_t ext_len) +{ return &(buffer[LLHDR_IPV6HDR_LEN + ext_len]); } -void sixlowpan_bootstrapping(void){ - +void sixlowpan_bootstrapping(void) +{ + init_rtr_sol(OPT_SLLAO); } -void sixlowpan_send(ipv6_addr_t *addr, uint8_t *payload, uint16_t p_len, uint8_t next_header){ - uint8_t *p_ptr; - if (next_header == IPPROTO_TCP) - { - p_ptr = get_payload_buf_send(ipv6_ext_hdr_len); - ipv6_buf = get_ipv6_buf_send(); - } - else - { - ipv6_buf = get_ipv6_buf(); - p_ptr = get_payload_buf(ipv6_ext_hdr_len); - } +void sixlowpan_send(ipv6_addr_t *addr, uint8_t *payload, uint16_t p_len, + uint8_t next_header) +{ + uint8_t *p_ptr; + + if(next_header == IPPROTO_TCP) { + p_ptr = get_payload_buf_send(ipv6_ext_hdr_len); + ipv6_buf = get_ipv6_buf_send(); + } + else { + ipv6_buf = get_ipv6_buf(); + p_ptr = get_payload_buf(ipv6_ext_hdr_len); + } + icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len); packet_length = 0; @@ -71,143 +99,161 @@ void sixlowpan_send(ipv6_addr_t *addr, uint8_t *payload, uint16_t p_len, uint8_t ipv6_buf->flowlabel = 0; ipv6_buf->nextheader = next_header; ipv6_buf->hoplimit = MULTIHOP_HOPLIMIT; - ipv6_buf->length = p_len; + ipv6_buf->length = p_len; memcpy(&(ipv6_buf->destaddr), addr, 16); ipv6_get_saddr(&(ipv6_buf->srcaddr), &(ipv6_buf->destaddr)); - memcpy(p_ptr,payload,p_len); + memcpy(p_ptr, payload, p_len); packet_length = IPV6_HDR_LEN + p_len; - lowpan_init((ieee_802154_long_t*)&(ipv6_buf->destaddr.uint16[4]),(uint8_t*)ipv6_buf); + lowpan_init((ieee_802154_long_t *)&(ipv6_buf->destaddr.uint16[4]), + (uint8_t *)ipv6_buf); } -int icmpv6_demultiplex(const struct icmpv6_hdr_t *hdr) { +int icmpv6_demultiplex(const struct icmpv6_hdr_t *hdr) +{ switch(hdr->type) { - case(ICMP_RTR_SOL):{ + case(ICMP_RTR_SOL): { puts("INFO: packet type: icmp router solicitation"); /* processing router solicitation */ recv_rtr_sol(); /* init solicited router advertisment*/ break; } - case(ICMP_RTR_ADV):{ + + case(ICMP_RTR_ADV): { puts("INFO: packet type: icmp router advertisment"); /* processing router advertisment */ recv_rtr_adv(); /* init neighbor solicitation */ break; } - case(ICMP_NBR_SOL):{ + + case(ICMP_NBR_SOL): { puts("INFO: packet type: icmp neighbor solicitation"); recv_nbr_sol(); break; } - case(ICMP_NBR_ADV):{ + + case(ICMP_NBR_ADV): { puts("INFO: packet type: icmp neighbor advertisment"); recv_nbr_adv(); break; } - case(ICMP_RPL_CONTROL):{ - puts("INFO: packet type: RPL message"); - if(rpl_process_pid != 0){ - msg_t m_send; - m_send.content.ptr = (char*) &hdr->code; - msg_send(&m_send, rpl_process_pid, 1); - } - else{ - puts("INFO: no RPL handler registered"); - } - break; - } + + case(ICMP_RPL_CONTROL): { + puts("INFO: packet type: RPL message"); + + if(rpl_process_pid != 0) { + msg_t m_send; + m_send.content.ptr = (char *) &hdr->code; + msg_send(&m_send, rpl_process_pid, 1); + } + else { + puts("INFO: no RPL handler registered"); + } + + break; + } + default: return -1; } - + return 0; } -void ipv6_process(void){ - msg_t m_recv_lowpan, m_send_lowpan; - msg_t m_recv, m_send; - ipv6_addr_t myaddr; - ipv6_init_address(&myaddr, 0xabcd, 0x0, 0x0, 0x0, 0x3612, 0x00ff, 0xfe00, get_radio_address()); - - while(1){ +void ipv6_process(void) +{ + msg_t m_recv_lowpan, m_send_lowpan; + msg_t m_recv, m_send; + ipv6_addr_t myaddr; + ipv6_init_address(&myaddr, 0xabcd, 0x0, 0x0, 0x0, 0x3612, 0x00ff, 0xfe00, + get_radio_address()); + + while(1) { msg_receive(&m_recv_lowpan); - ipv6_buf = (struct ipv6_hdr_t*) m_recv_lowpan.content.ptr; + ipv6_buf = (struct ipv6_hdr_t *) m_recv_lowpan.content.ptr; /* identifiy packet */ nextheader = &ipv6_buf->nextheader; - if ((ipv6_get_addr_match(&myaddr, &ipv6_buf->destaddr) >= 112) && (ipv6_buf->destaddr.uint8[15] != myaddr.uint8[15])) - { - memcpy(get_ipv6_buf_send(), get_ipv6_buf(), IPV6_HDR_LEN+ipv6_buf->length); - lowpan_init((ieee_802154_long_t*)&(ipv6_buf->destaddr.uint16[4]),(uint8_t*)get_ipv6_buf_send()); - } - else - { - switch(*nextheader) { - case(PROTO_NUM_ICMPV6):{ - /* checksum test*/ - if(icmpv6_csum(PROTO_NUM_ICMPV6) != 0xffff){ - printf("ERROR: wrong checksum\n"); - } - icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len); - icmpv6_demultiplex(icmp_buf); - break; - } - case(IPPROTO_TCP): - { - if (tcp_packet_handler_pid != 0) - { - m_send.content.ptr = (char*) ipv6_buf; - msg_send_receive(&m_send, &m_recv, tcp_packet_handler_pid); - } - else - { - printf("INFO: No TCP handler registered.\n"); - } - break; - } - case(IPPROTO_UDP): - { - if (udp_packet_handler_pid != 0) - { - m_send.content.ptr = (char*) ipv6_buf; - msg_send_receive(&m_send, &m_recv, udp_packet_handler_pid); - } - else - { - printf("INFO: No UDP handler registered.\n"); - } - break; - } - case(PROTO_NUM_NONE): - { - printf("INFO: Packet with no Header following the IPv6 Header received.\n"); - break; - } - default: - break; - } - } + if((ipv6_get_addr_match(&myaddr, &ipv6_buf->destaddr) >= 112) && + (ipv6_buf->destaddr.uint8[15] != myaddr.uint8[15])) { + memcpy(get_ipv6_buf_send(), get_ipv6_buf(), + IPV6_HDR_LEN + ipv6_buf->length); + lowpan_init((ieee_802154_long_t *)&(ipv6_buf->destaddr.uint16[4]), + (uint8_t *)get_ipv6_buf_send()); + } + else { + switch(*nextheader) { + case(PROTO_NUM_ICMPV6): { + /* checksum test*/ + if(icmpv6_csum(PROTO_NUM_ICMPV6) != 0xffff) { + printf("ERROR: wrong checksum\n"); + } + + icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len); + icmpv6_demultiplex(icmp_buf); + break; + } + + case(IPPROTO_TCP): { + if(tcp_packet_handler_pid != 0) { + m_send.content.ptr = (char *) ipv6_buf; + msg_send_receive(&m_send, &m_recv, tcp_packet_handler_pid); + } + else { + printf("INFO: No TCP handler registered.\n"); + } + + break; + } + + case(IPPROTO_UDP): { + if(udp_packet_handler_pid != 0) { + m_send.content.ptr = (char *) ipv6_buf; + msg_send_receive(&m_send, &m_recv, udp_packet_handler_pid); + } + else { + printf("INFO: No UDP handler registered.\n"); + } + + break; + } + + case(PROTO_NUM_NONE): { + printf("INFO: Packet with no Header following the IPv6 Header received.\n"); + break; + } + + default: + break; + } + } + msg_reply(&m_recv_lowpan, &m_send_lowpan); - } + } } -void ipv6_iface_add_addr(ipv6_addr_t *addr, uint8_t state, uint32_t val_ltime, uint32_t pref_ltime, uint8_t type){ - if(ipv6_addr_unspec_match(addr) == 128){ +void ipv6_iface_add_addr(ipv6_addr_t *addr, uint8_t state, uint32_t val_ltime, + uint32_t pref_ltime, uint8_t type) +{ + if(ipv6_addr_unspec_match(addr) == 128) { printf("ERROR: unspecified address (::) can't be assigned to interface.\n"); return; } + if(ipv6_iface_addr_match(addr) != 0) { return; } - if(iface_addr_list_count < IFACE_ADDR_LIST_LEN){ - memcpy(&(iface.addr_list[iface_addr_list_count].addr.uint8[0]), &(addr->uint8[0]), 16); + + if(iface_addr_list_count < IFACE_ADDR_LIST_LEN) { + memcpy(&(iface.addr_list[iface_addr_list_count].addr.uint8[0]), + &(addr->uint8[0]), 16); iface.addr_list[iface_addr_list_count].state = state; timex_t valtime = {val_ltime, 0}; timex_t preftime = {pref_ltime, 0}; @@ -217,56 +263,67 @@ void ipv6_iface_add_addr(ipv6_addr_t *addr, uint8_t state, uint32_t val_ltime, u iface.addr_list[iface_addr_list_count].pref_ltime = timex_add(now, preftime); iface.addr_list[iface_addr_list_count].type = type; iface_addr_list_count++; - // Register to Solicited-Node multicast address according to RFC 4291 - if (type == ADDR_TYPE_ANYCAST || type == ADDR_TYPE_LINK_LOCAL || - type == ADDR_TYPE_GLOBAL || type == ADDR_TYPE_UNICAST) { + + /* Register to Solicited-Node multicast address according to RFC 4291 */ + if(type == ADDR_TYPE_ANYCAST || type == ADDR_TYPE_LINK_LOCAL || + type == ADDR_TYPE_GLOBAL || type == ADDR_TYPE_UNICAST) { ipv6_addr_t sol_node_mcast_addr; ipv6_set_sol_node_mcast_addr(addr, &sol_node_mcast_addr); - if (ipv6_iface_addr_match(&sol_node_mcast_addr) == NULL) { + + if(ipv6_iface_addr_match(&sol_node_mcast_addr) == NULL) { ipv6_iface_add_addr(&sol_node_mcast_addr, state, val_ltime, pref_ltime, ADDR_TYPE_SOL_NODE_MCAST); } } } } -addr_list_t * ipv6_iface_addr_match(ipv6_addr_t *addr){ +addr_list_t *ipv6_iface_addr_match(ipv6_addr_t *addr) +{ int i; - for(i = 0; i < iface_addr_list_count; i++){ + + for(i = 0; i < iface_addr_list_count; i++) { if(memcmp(&(iface.addr_list[i].addr.uint8[0]), - &(addr->uint8[0]),16) == 0){ + &(addr->uint8[0]), 16) == 0) { return &(iface.addr_list[i]); } } + return NULL; } -addr_list_t * ipv6_iface_addr_prefix_eq(ipv6_addr_t *addr){ +addr_list_t *ipv6_iface_addr_prefix_eq(ipv6_addr_t *addr) +{ int i; - for(i = 0; i < iface_addr_list_count; i++){ + + for(i = 0; i < iface_addr_list_count; i++) { if(memcmp(&(iface.addr_list[i].addr.uint8[0]), - &(addr->uint8[0]), 8) == 0){ + &(addr->uint8[0]), 8) == 0) { return &(iface.addr_list[i]); } } + return NULL; } -void ipv6_iface_print_addrs(void){ - for(int i = 0; i < iface_addr_list_count; i++){ +void ipv6_iface_print_addrs(void) +{ + for(int i = 0; i < iface_addr_list_count; i++) { ipv6_print_addr(&(iface.addr_list[i].addr)); - } + } } -void ipv6_init_addr_prefix(ipv6_addr_t *inout, ipv6_addr_t *prefix){ +void ipv6_init_addr_prefix(ipv6_addr_t *inout, ipv6_addr_t *prefix) +{ inout->uint16[0] = prefix->uint16[0]; inout->uint16[1] = prefix->uint16[1]; inout->uint16[2] = prefix->uint16[2]; inout->uint16[3] = prefix->uint16[3]; - memcpy(&(inout->uint8[8]),&(iface.laddr.uint8[0]), 8); + memcpy(&(inout->uint8[8]), &(iface.laddr.uint8[0]), 8); } -void ipv6_set_prefix(ipv6_addr_t *inout, ipv6_addr_t *prefix){ +void ipv6_set_prefix(ipv6_addr_t *inout, ipv6_addr_t *prefix) +{ inout->uint16[0] = prefix->uint16[0]; inout->uint16[1] = prefix->uint16[1]; inout->uint16[2] = prefix->uint16[2]; @@ -277,7 +334,8 @@ void ipv6_set_prefix(ipv6_addr_t *inout, ipv6_addr_t *prefix){ inout->uint16[7] = 0; } -void ipv6_set_all_rtrs_mcast_addr(ipv6_addr_t *ipaddr){ +void ipv6_set_all_rtrs_mcast_addr(ipv6_addr_t *ipaddr) +{ ipaddr->uint16[0] = HTONS(0xff02); ipaddr->uint16[1] = 0; ipaddr->uint16[2] = 0; @@ -288,7 +346,8 @@ void ipv6_set_all_rtrs_mcast_addr(ipv6_addr_t *ipaddr){ ipaddr->uint16[7] = HTONS(0x0002); } -void ipv6_set_all_nds_mcast_addr(ipv6_addr_t *ipaddr){ +void ipv6_set_all_nds_mcast_addr(ipv6_addr_t *ipaddr) +{ ipaddr->uint16[0] = HTONS(0xff02); ipaddr->uint16[1] = 0; ipaddr->uint16[2] = 0; @@ -299,7 +358,8 @@ void ipv6_set_all_nds_mcast_addr(ipv6_addr_t *ipaddr){ ipaddr->uint16[7] = HTONS(0x0001); } -void ipv6_set_loaddr(ipv6_addr_t *ipaddr){ +void ipv6_set_loaddr(ipv6_addr_t *ipaddr) +{ ipaddr->uint16[0] = 0; ipaddr->uint16[1] = 0; ipaddr->uint16[2] = 0; @@ -310,63 +370,74 @@ void ipv6_set_loaddr(ipv6_addr_t *ipaddr){ ipaddr->uint16[7] = HTONS(0x0001); } -void ipv6_get_saddr(ipv6_addr_t *src, ipv6_addr_t *dst){ +void ipv6_get_saddr(ipv6_addr_t *src, ipv6_addr_t *dst) +{ /* try to find best match if dest is not mcast or link local */ int8_t itmp = -1; - uint8_t tmp = 0; - uint8_t bmatch = 0; + uint8_t tmp = 0; + uint8_t bmatch = 0; - if(!(ipv6_prefix_ll_match(dst)) && !(ipv6_prefix_mcast_match(dst))){ - for(int i = 0; i < IFACE_ADDR_LIST_LEN; i++){ - if(iface.addr_list[i].state == ADDR_STATE_PREFERRED){ - if(!(ipv6_prefix_ll_match(&(iface.addr_list[i].addr)))){ + if(!(ipv6_prefix_ll_match(dst)) && !(ipv6_prefix_mcast_match(dst))) { + for(int i = 0; i < IFACE_ADDR_LIST_LEN; i++) { + if(iface.addr_list[i].state == ADDR_STATE_PREFERRED) { + if(!(ipv6_prefix_ll_match(&(iface.addr_list[i].addr)))) { tmp = ipv6_get_addr_match(dst, &(iface.addr_list[i].addr)); - if(tmp >= bmatch){ + + if(tmp >= bmatch) { bmatch = tmp; itmp = i; } } } } - } else { - for(int j=0; j < IFACE_ADDR_LIST_LEN; j++){ + } + else { + for(int j = 0; j < IFACE_ADDR_LIST_LEN; j++) { if((iface.addr_list[j].state == ADDR_STATE_PREFERRED) && - ipv6_prefix_ll_match(&(iface.addr_list[j].addr))){ - itmp = j; - } + ipv6_prefix_ll_match(&(iface.addr_list[j].addr))) { + itmp = j; + } } } - if(itmp == -1){ + if(itmp == -1) { memset(src, 0, 16); - } else { + } + else { memcpy(src, &(iface.addr_list[itmp].addr), 16); } } -uint8_t ipv6_get_addr_match(ipv6_addr_t *src, ipv6_addr_t *dst){ +uint8_t ipv6_get_addr_match(ipv6_addr_t *src, ipv6_addr_t *dst) +{ uint8_t val = 0, xor; - for(int i = 0; i < 16; i++){ + + for(int i = 0; i < 16; i++) { /* if bytes are equal add 8 */ - if(src->uint8[i] == dst->uint8[i]){ - val += 8; - } else { + if(src->uint8[i] == dst->uint8[i]) { + val += 8; + } + else { xor = src->uint8[i] ^ dst->uint8[i]; + /* while bits from byte equal add 1 */ - for(int j = 0; j < 8; j++){ - if((xor & 0x80) == 0){ + for(int j = 0; j < 8; j++) { + if((xor & 0x80) == 0) { val++; xor = xor << 1; - } else { + } + else { break; } } } } + return val; } -void ipv6_set_ll_prefix(ipv6_addr_t *ipaddr){ +void ipv6_set_ll_prefix(ipv6_addr_t *ipaddr) +{ ipaddr->uint16[0] = HTONS(0xfe80); ipaddr->uint16[1] = 0; ipaddr->uint16[2] = 0; @@ -375,7 +446,8 @@ void ipv6_set_ll_prefix(ipv6_addr_t *ipaddr){ void ipv6_init_address(ipv6_addr_t *addr, uint16_t addr0, uint16_t addr1, uint16_t addr2, uint16_t addr3, uint16_t addr4, - uint16_t addr5, uint16_t addr6, uint16_t addr7){ + uint16_t addr5, uint16_t addr6, uint16_t addr7) +{ addr->uint16[0] = HTONS(addr0); addr->uint16[1] = HTONS(addr1); addr->uint16[2] = HTONS(addr2); @@ -386,43 +458,52 @@ void ipv6_init_address(ipv6_addr_t *addr, uint16_t addr0, uint16_t addr1, addr->uint16[7] = HTONS(addr7); } -uint8_t ipv6_prefix_ll_match(ipv6_addr_t *addr){ - if(addr->uint8[0] == 0xfe && addr->uint8[1] == 0x80){ +uint8_t ipv6_prefix_ll_match(ipv6_addr_t *addr) +{ + if(addr->uint8[0] == 0xfe && addr->uint8[1] == 0x80) { return 1; } + return 0; } -uint8_t ipv6_prefix_mcast_match(ipv6_addr_t *addr){ - if(addr->uint8[0] == 0xff && addr->uint8[1] == 0x02){ +uint8_t ipv6_prefix_mcast_match(ipv6_addr_t *addr) +{ + if(addr->uint8[0] == 0xff && addr->uint8[1] == 0x02) { return 1; } - return 0; + + return 0; } -uint8_t ipv6_addr_unspec_match(ipv6_addr_t *addr){ - if((addr->uint16[0] == 0) && (addr->uint16[1] == 0) && +uint8_t ipv6_addr_unspec_match(ipv6_addr_t *addr) +{ + if((addr->uint16[0] == 0) && (addr->uint16[1] == 0) && (addr->uint16[2] == 0) && (addr->uint16[3] == 0) && (addr->uint16[4] == 0) && (addr->uint16[5] == 0) && - (addr->uint16[6] == 0) && (addr->uint16[7] == 0)){ + (addr->uint16[6] == 0) && (addr->uint16[7] == 0)) { return 1; } + return 0; } -uint8_t ipv6_addr_sol_node_mcast_match(ipv6_addr_t *addr){ +uint8_t ipv6_addr_sol_node_mcast_match(ipv6_addr_t *addr) +{ /* note: cool if-condition*/ if((addr->uint8[0] == 0xFF) && (addr->uint8[1] == 0x02) && (addr->uint16[1] == 0x00) && (addr->uint16[2] == 0x00) && (addr->uint16[3] == 0x00) && (addr->uint16[4] == 0x00) && (addr->uint8[10] == 0x00) && (addr->uint8[11] == 0x01) && - (addr->uint8[12] == 0xFF)){ + (addr->uint8[12] == 0xFF)) { return 1; } + return 0; } -void ipv6_set_sol_node_mcast_addr(ipv6_addr_t *addr_in, ipv6_addr_t *addr_out){ +void ipv6_set_sol_node_mcast_addr(ipv6_addr_t *addr_in, ipv6_addr_t *addr_out) +{ /* copy only the last 24-bit of the ip-address that is beeing resolved */ addr_out->uint16[0] = HTONS(0xff02); addr_out->uint16[1] = 0; @@ -435,30 +516,34 @@ void ipv6_set_sol_node_mcast_addr(ipv6_addr_t *addr_in, ipv6_addr_t *addr_out){ addr_out->uint16[7] = addr_in->uint16[7]; } -void ipv6_print_addr(ipv6_addr_t *ipaddr){ +void ipv6_print_addr(ipv6_addr_t *ipaddr) +{ printf("%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n", - ((uint8_t *)ipaddr)[0], ((uint8_t *)ipaddr)[1], ((uint8_t *)ipaddr)[2], - ((uint8_t *)ipaddr)[3], ((uint8_t *)ipaddr)[4], ((uint8_t *)ipaddr)[5], - ((uint8_t *)ipaddr)[6], ((uint8_t *)ipaddr)[7], ((uint8_t *)ipaddr)[8], - ((uint8_t *)ipaddr)[9], ((uint8_t *)ipaddr)[10], ((uint8_t *)ipaddr)[11], - ((uint8_t *)ipaddr)[12], ((uint8_t *)ipaddr)[13], ((uint8_t *)ipaddr)[14], - ((uint8_t *)ipaddr)[15]); + ((uint8_t *)ipaddr)[0], ((uint8_t *)ipaddr)[1], ((uint8_t *)ipaddr)[2], + ((uint8_t *)ipaddr)[3], ((uint8_t *)ipaddr)[4], ((uint8_t *)ipaddr)[5], + ((uint8_t *)ipaddr)[6], ((uint8_t *)ipaddr)[7], ((uint8_t *)ipaddr)[8], + ((uint8_t *)ipaddr)[9], ((uint8_t *)ipaddr)[10], ((uint8_t *)ipaddr)[11], + ((uint8_t *)ipaddr)[12], ((uint8_t *)ipaddr)[13], ((uint8_t *)ipaddr)[14], + ((uint8_t *)ipaddr)[15]); } -uint8_t ipv6_next_hdr_unknown(uint8_t next_hdr) { +uint8_t ipv6_next_hdr_unknown(uint8_t next_hdr) +{ return next_hdr == PROTO_NUM_ICMPV6 || next_hdr == PROTO_NUM_NONE; } -uint32_t get_remaining_time(timex_t *t){ +uint32_t get_remaining_time(timex_t *t) +{ timex_t now; vtimer_now(&now); - + return (timex_sub(*t, now).seconds); } -void set_remaining_time(timex_t *t, uint32_t time){ +void set_remaining_time(timex_t *t, uint32_t time) +{ timex_t tmp = {time, 0}; timex_t now; @@ -466,33 +551,39 @@ void set_remaining_time(timex_t *t, uint32_t time){ *t = timex_add(now, tmp); } -void ipv6_init_iface_as_router(void) { +void ipv6_init_iface_as_router(void) +{ ipv6_addr_t addr; - + ipv6_set_all_rtrs_mcast_addr(&addr); - ipv6_iface_add_addr(&addr,ADDR_STATE_PREFERRED,0,0,ADDR_TYPE_MULTICAST); + ipv6_iface_add_addr(&addr, ADDR_STATE_PREFERRED, 0, 0, ADDR_TYPE_MULTICAST); } -uint8_t ipv6_is_router(void) { +uint8_t ipv6_is_router(void) +{ ipv6_addr_t addr; - + ipv6_set_all_rtrs_mcast_addr(&addr); - if (ipv6_iface_addr_match(&addr) != NULL) { + + if(ipv6_iface_addr_match(&addr) != NULL) { return 1; } - + return 0; } -void set_tcp_packet_handler_pid(int pid) { - tcp_packet_handler_pid = pid; +void set_tcp_packet_handler_pid(int pid) +{ + tcp_packet_handler_pid = pid; } -void set_udp_packet_handler_pid(int pid) { - udp_packet_handler_pid = pid; +void set_udp_packet_handler_pid(int pid) +{ + udp_packet_handler_pid = pid; } -void set_rpl_process_pid(int pid){ - rpl_process_pid = pid; +void set_rpl_process_pid(int pid) +{ + rpl_process_pid = pid; } diff --git a/sys/net/sixlowpan/sixlowip.h b/sys/net/sixlowpan/sixlowip.h index 5db70f1fec..2f945502ac 100644 --- a/sys/net/sixlowpan/sixlowip.h +++ b/sys/net/sixlowpan/sixlowip.h @@ -1,3 +1,23 @@ +/** + * IPv6 constants, data structs, and prototypes + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup sixlowpan + * @{ + * @file sixlowip.h + * @brief 6lowpan IP layer header + * @author Stephan Zeisberg + * @author Martin Lenders + * @author Eric Engel + * @author Oliver Gesch + * @} + */ + /* 6LoWPAN IP header file */ #ifndef SIXLOWIP_H @@ -9,12 +29,12 @@ /* set maximum transmission unit */ #define MTU 256 -/* IPv6 field values */ +/* IPv6 field values */ #define IPV6_VER 0x60 #define PROTO_NUM_ICMPV6 58 #define PROTO_NUM_NONE 59 #define ND_HOPLIMIT 0xFF -#define SIXLOWPAN_IPV6_LL_ADDR_LEN 8 +#define SIXLOWPAN_IPV6_LL_ADDR_LEN 8 /* size of global buffer */ #define BUFFER_SIZE (LL_HDR_LEN + MTU) @@ -36,7 +56,7 @@ extern double start; /* base header lengths */ #define LL_HDR_LEN 0x4 #define ICMPV6_HDR_LEN 0x4 -#define IPV6_HDR_LEN 0x28 +#define IPV6_HDR_LEN 0x28 #define LLHDR_IPV6HDR_LEN (LL_HDR_LEN + IPV6_HDR_LEN) #define LLHDR_ICMPV6HDR_LEN (LL_HDR_LEN + IPV6_HDR_LEN + ICMPV6_HDR_LEN) #define IPV6HDR_ICMPV6HDR_LEN (IPV6_HDR_LEN + ipv6_ext_hdr_len + ICMPV6_HDR_LEN) @@ -46,7 +66,7 @@ extern double start; #define ADDR_STATE_TENTATIVE 0 #define ADDR_STATE_PREFERRED 1 #define ADDR_STATE_DEPRECATED 2 -/* addresses with this state are always permitted */ +/* addresses with this state are always permitted */ #define ADDR_STATE_ANY 4 /* how the address is configured */ #define ADDR_CONFIGURED_AUTO 1 @@ -64,7 +84,7 @@ extern double start; #define DISPATCH_TYPE_IPV6 0x41 #define DISPATCH_TYPE_LOWPAN_HC1 0x42 /* compression types */ -#define COMPRESSION_TYPE_NONE +#define COMPRESSION_TYPE_NONE /* buffer */ extern uint8_t buffer[BUFFER_SIZE]; @@ -72,19 +92,19 @@ extern uint8_t buffer[BUFFER_SIZE]; /* ipv6 extension header length */ -typedef union __attribute__ ((packed)) ipv6_addr_t{ +typedef union __attribute__((packed)) { uint8_t uint8[16]; uint16_t uint16[8]; uint32_t uint32[4]; } ipv6_addr_t; -struct __attribute__ ((packed)) icmpv6_hdr_t{ +struct __attribute__((packed)) icmpv6_hdr_t { uint8_t type; uint8_t code; uint16_t checksum; }; -typedef struct __attribute__ ((packed)) ipv6_hdr_t{ +typedef struct __attribute__((packed)) { uint8_t version_trafficclass; uint8_t trafficclass_flowlabel; uint16_t flowlabel; @@ -96,17 +116,17 @@ typedef struct __attribute__ ((packed)) ipv6_hdr_t{ } ipv6_hdr_t; /* link layer addressing */ -typedef union __attribute__ ((packed)) ieee_802154_long_t { +typedef union __attribute__((packed)) { uint8_t uint8[8]; - uint16_t uint16[4]; + uint16_t uint16[4]; } ieee_802154_long_t; -typedef union __attribute__ ((packed)) ieee_802154_short_t { +typedef union __attribute__((packed)) { uint8_t uint8[2]; uint16_t uint16[1]; } ieee_802154_short_t; -typedef struct __attribute__ ((packed)) addr_list_t { +typedef struct __attribute__((packed)) { uint8_t state; timex_t val_ltime; timex_t pref_ltime; @@ -114,7 +134,7 @@ typedef struct __attribute__ ((packed)) addr_list_t { ipv6_addr_t addr; } addr_list_t; -typedef struct __attribute__ ((packed)) iface_t { +typedef struct __attribute__((packed)) { ieee_802154_short_t saddr; ieee_802154_long_t laddr; addr_list_t addr_list[IFACE_ADDR_LIST_LEN]; @@ -126,10 +146,10 @@ typedef struct __attribute__ ((packed)) iface_t { extern iface_t iface; /* function prototypes */ -struct icmpv6_hdr_t* get_icmpv6_buf(uint8_t ext_len); -struct ipv6_hdr_t* get_ipv6_buf(void); -uint8_t * get_payload_buf(uint8_t ext_len); -uint8_t * get_payload_buf_send(uint8_t ext_len); +struct icmpv6_hdr_t *get_icmpv6_buf(uint8_t ext_len); +struct ipv6_hdr_t *get_ipv6_buf(void); +uint8_t *get_payload_buf(uint8_t ext_len); +uint8_t *get_payload_buf_send(uint8_t ext_len); int icmpv6_demultiplex(const struct icmpv6_hdr_t *hdr); void ipv6_init_iface_as_router(void); @@ -147,10 +167,10 @@ void ipv6_get_saddr(ipv6_addr_t *src, ipv6_addr_t *dst); uint8_t ipv6_get_addr_match(ipv6_addr_t *src, ipv6_addr_t *dst); uint8_t ipv6_prefix_mcast_match(ipv6_addr_t *addr); uint8_t ipv6_prefix_ll_match(ipv6_addr_t *addr); -void ipv6_iface_add_addr(ipv6_addr_t* addr, uint8_t state, uint32_t val_ltime, +void ipv6_iface_add_addr(ipv6_addr_t *addr, uint8_t state, uint32_t val_ltime, uint32_t pref_ltime, uint8_t type); -addr_list_t * ipv6_iface_addr_prefix_eq(ipv6_addr_t *addr); -addr_list_t * ipv6_iface_addr_match(ipv6_addr_t *addr); +addr_list_t *ipv6_iface_addr_prefix_eq(ipv6_addr_t *addr); +addr_list_t *ipv6_iface_addr_match(ipv6_addr_t *addr); void ipv6_iface_print_addrs(void); void ipv6_init_addr_prefix(ipv6_addr_t *inout, ipv6_addr_t *prefix); void ipv6_init_address(ipv6_addr_t *addr, uint16_t addr0, uint16_t addr1, diff --git a/sys/net/sixlowpan/sixlowmac.c b/sys/net/sixlowpan/sixlowmac.c index 0d772fea86..7f17ca09e5 100644 --- a/sys/net/sixlowpan/sixlowmac.c +++ b/sys/net/sixlowpan/sixlowmac.c @@ -1,4 +1,23 @@ -/* 6LoWPAN MAC - layer 2 implementations */ +/* + * 6LoWPAN MAC - layer 2 implementations + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup sixlowpan + * @{ + * @file sixlowmac.c + * @brief 6lowpan link layer functions + * @author Stephan Zeisberg + * @author Martin Lenders + * @author Eric Engel + * @author Oliver Gesch + * @} + */ + #include #include @@ -24,7 +43,6 @@ static uint8_t r_src_addr; uint8_t buf[PAYLOAD_SIZE]; uint16_t packet_length; static uint8_t macdsn; -//static uint8_t macbsn; mutex_t buf_mutex; @@ -34,58 +52,65 @@ int transceiver_type; static transceiver_command_t tcmd; uint16_t fragmentcounter = 0; -uint8_t get_radio_address(void){ +uint8_t get_radio_address(void) +{ int16_t address; tcmd.transceivers = transceiver_type; tcmd.data = &address; - mesg.content.ptr = (char*)&tcmd; + mesg.content.ptr = (char *)&tcmd; mesg.type = GET_ADDRESS; - msg_send_receive(&mesg,&mesg,transceiver_pid); - + msg_send_receive(&mesg, &mesg, transceiver_pid); + return (uint8_t)address; } -void set_radio_address(uint8_t addr){ +void set_radio_address(uint8_t addr) +{ int16_t address = (int16_t)addr; - + tcmd.transceivers = transceiver_type; tcmd.data = &address; - mesg.content.ptr = (char*)&tcmd; + mesg.content.ptr = (char *)&tcmd; mesg.type = SET_ADDRESS; msg_send_receive(&mesg, &mesg, transceiver_pid); } -void set_radio_channel(uint8_t channel){ +void set_radio_channel(uint8_t channel) +{ int16_t chan = (int16_t)channel; - + tcmd.transceivers = transceiver_type; tcmd.data = &chan; - mesg.content.ptr = (char*)&tcmd; + mesg.content.ptr = (char *)&tcmd; mesg.type = SET_CHANNEL; - msg_send_receive(&mesg,&mesg,transceiver_pid); + msg_send_receive(&mesg, &mesg, transceiver_pid); } -void switch_to_rx(void){ +void switch_to_rx(void) +{ mesg.type = SWITCH_RX; - mesg.content.ptr = (char*) &tcmd; + mesg.content.ptr = (char *) &tcmd; tcmd.transceivers = TRANSCEIVER_CC1100; msg_send(&mesg, transceiver_pid, 1); } -void init_802154_short_addr(ieee_802154_short_t *saddr){ +void init_802154_short_addr(ieee_802154_short_t *saddr) +{ saddr->uint8[0] = 0; saddr->uint8[1] = get_radio_address(); } -ieee_802154_long_t* mac_get_eui(ipv6_addr_t *ipaddr){ - return ((ieee_802154_long_t *) &(ipaddr->uint8[8])); +ieee_802154_long_t *mac_get_eui(ipv6_addr_t *ipaddr) +{ + return ((ieee_802154_long_t *) & (ipaddr->uint8[8])); } -void init_802154_long_addr(ieee_802154_long_t *laddr){ +void init_802154_long_addr(ieee_802154_long_t *laddr) +{ // 16bit Pan-ID:16-zero-bits:16-bit-short-addr = 48bit laddr->uint16[0] = IEEE_802154_PAN_ID; - + /* RFC 4944 Section 6 / RFC 2464 Section 4 */ laddr->uint8[0] ^= 0x02; laddr->uint8[2] = 0; @@ -96,30 +121,32 @@ void init_802154_long_addr(ieee_802154_long_t *laddr){ laddr->uint8[7] = get_radio_address(); } -void recv_ieee802154_frame(void){ +void recv_ieee802154_frame(void) +{ msg_t m; radio_packet_t *p; uint8_t hdrlen, length; ieee802154_frame_t frame; - + msg_init_queue(msg_q, RADIO_RCV_BUF_SIZE); - while (1) { + while(1) { msg_receive(&m); - if (m.type == PKT_PENDING) { - p = (radio_packet_t*) m.content.ptr; + if(m.type == PKT_PENDING) { + + p = (radio_packet_t *) m.content.ptr; hdrlen = read_802154_frame(p->data, &frame, p->length); length = p->length - hdrlen; /* deliver packet to network(6lowpan)-layer */ - fragmentcounter++; - lowpan_read(frame.payload, length, (ieee_802154_long_t*)&frame.src_addr, - (ieee_802154_long_t*)&frame.dest_addr); + fragmentcounter++; + lowpan_read(frame.payload, length, (ieee_802154_long_t *)&frame.src_addr, + (ieee_802154_long_t *)&frame.dest_addr); p->processing--; } - else if (m.type == ENOBUFFER) { + else if(m.type == ENOBUFFER) { puts("Transceiver buffer full"); } else { @@ -129,7 +156,8 @@ void recv_ieee802154_frame(void){ } void set_ieee802154_fcf_values(ieee802154_frame_t *frame, uint8_t dest_mode, - uint8_t src_mode){ + uint8_t src_mode) +{ frame->fcf.frame_type = IEEE_802154_DATA_FRAME; frame->fcf.sec_enb = 0; frame->fcf.frame_pend = 0; @@ -140,7 +168,8 @@ void set_ieee802154_fcf_values(ieee802154_frame_t *frame, uint8_t dest_mode, frame->fcf.dest_addr_m = dest_mode; } -void set_ieee802154_frame_values(ieee802154_frame_t *frame){ +void set_ieee802154_frame_values(ieee802154_frame_t *frame) +{ // TODO: addresse aus ip paket auslesen und in frame einfuegen frame->dest_pan_id = IEEE_802154_PAN_ID; frame->src_pan_id = IEEE_802154_PAN_ID; @@ -148,25 +177,26 @@ void set_ieee802154_frame_values(ieee802154_frame_t *frame){ macdsn++; } -void send_ieee802154_frame(ieee_802154_long_t *addr, uint8_t *payload, - uint8_t length, uint8_t mcast){ +void send_ieee802154_frame(ieee_802154_long_t *addr, uint8_t *payload, + uint8_t length, uint8_t mcast) +{ uint16_t daddr; /* TODO: check if dedicated response struct is necessary */ msg_t transceiver_rsp; r_src_addr = local_address; mesg.type = SND_PKT; - mesg.content.ptr = (char*) &tcmd; + mesg.content.ptr = (char *) &tcmd; tcmd.transceivers = transceiver_type; tcmd.data = &p; - - ieee802154_frame_t frame; - + + ieee802154_frame_t frame; + memset(&frame, 0, sizeof(frame)); - set_ieee802154_fcf_values(&frame, IEEE_802154_LONG_ADDR_M, + set_ieee802154_fcf_values(&frame, IEEE_802154_LONG_ADDR_M, IEEE_802154_LONG_ADDR_M); - set_ieee802154_frame_values(&frame); - + set_ieee802154_frame_values(&frame); + memcpy(&(frame.dest_addr[0]), &(addr->uint8[0]), 8); memcpy(&(frame.src_addr[0]), &(iface.laddr.uint8[0]), 8); @@ -174,18 +204,20 @@ void send_ieee802154_frame(ieee_802154_long_t *addr, uint8_t *payload, frame.payload = payload; frame.payload_len = length; uint8_t hdrlen = get_802154_hdr_len(&frame); - - memset(&buf,0,PAYLOAD_SIZE); - init_802154_frame(&frame,(uint8_t*)&buf); - memcpy(&buf[hdrlen],frame.payload,frame.payload_len); - + + memset(&buf, 0, PAYLOAD_SIZE); + init_802154_frame(&frame, (uint8_t *)&buf); + memcpy(&buf[hdrlen], frame.payload, frame.payload_len); + /* mutex unlock */ mutex_unlock(&buf_mutex, 0); - + p.length = hdrlen + frame.payload_len; - if(mcast == 0){ + + if(mcast == 0) { p.dst = daddr; - } else { + } + else { p.dst = 0; } @@ -196,14 +228,14 @@ void send_ieee802154_frame(ieee_802154_long_t *addr, uint8_t *payload, hwtimer_wait(5000); } -void sixlowmac_init(transceiver_type_t type){ - int recv_pid = thread_create(radio_stack_buffer, RADIO_STACK_SIZE, - PRIORITY_MAIN-2, CREATE_STACKTEST, recv_ieee802154_frame , "radio"); - // hwtimer_init(); +void sixlowmac_init(transceiver_type_t type) +{ + int recv_pid = thread_create(radio_stack_buffer, RADIO_STACK_SIZE, + PRIORITY_MAIN - 2, CREATE_STACKTEST, recv_ieee802154_frame , "radio"); transceiver_type = type; transceiver_init(transceiver_type); transceiver_start(); transceiver_register(type, recv_pid); - macdsn = rand() % 256; + macdsn = rand() % 256; } diff --git a/sys/net/sixlowpan/sixlowmac.h b/sys/net/sixlowpan/sixlowmac.h index f9b63e0d53..9dff1d6e06 100644 --- a/sys/net/sixlowpan/sixlowmac.h +++ b/sys/net/sixlowpan/sixlowmac.h @@ -1,4 +1,22 @@ -/* 6LoWPAN MAC header file */ +/* + * 6LoWPAN MAC - layer 2 prototypes + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup sixlowpan + * @{ + * @file sixlowmac.h + * @brief 6lowpan link layer functions + * @author Stephan Zeisberg + * @author Martin Lenders + * @author Eric Engel + * @author Oliver Gesch + * @} + */ #ifndef SIXLOWMAC_H #define SIXLOWMAC_H @@ -18,11 +36,11 @@ extern uint16_t fragmentcounter; uint8_t get_radio_address(void); void set_radio_address(uint8_t addr); -void send_ieee802154_frame(ieee_802154_long_t *addr, uint8_t *payload, +void send_ieee802154_frame(ieee_802154_long_t *addr, uint8_t *payload, uint8_t length, uint8_t mcast); void init_802154_long_addr(ieee_802154_long_t *laddr); void init_802154_short_addr(ieee_802154_short_t *saddr); void sixlowmac_init(transceiver_type_t type); -ieee_802154_long_t* mac_get_eui(ipv6_addr_t *ipaddr); +ieee_802154_long_t *mac_get_eui(ipv6_addr_t *ipaddr); #endif /* SIXLOWMAC_H*/ diff --git a/sys/net/sixlowpan/sixlownd.c b/sys/net/sixlowpan/sixlownd.c index f3865cdb64..cf27152d48 100644 --- a/sys/net/sixlowpan/sixlownd.c +++ b/sys/net/sixlowpan/sixlownd.c @@ -1,3 +1,22 @@ +/* + * 6lowpan neighbor discovery + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup sixlowpan + * @{ + * @file sixlownd.c + * @brief 6lowpan neighbor discovery functions + * @author Stephan Zeisberg + * @author Martin Lenders + * @author Oliver Gesch + * @} + */ + #include "sixlowip.h" #include "sixlownd.h" #include "sixlowmac.h" @@ -32,7 +51,7 @@ iface_t iface; /* datastructures */ abr_cache_t abr_cache[ABR_CACHE_SIZE]; nbr_cache_t nbr_cache[NBR_CACHE_SIZE]; -def_rtr_lst_t def_rtr_lst[DEF_RTR_LST_SIZE]; +def_rtr_lst_t def_rtr_lst[DEF_RTR_LST_SIZE]; plist_t plist[OPT_PI_LIST_LEN]; /* pointer */ @@ -64,80 +83,94 @@ uint8_t recvd_cids_len = 0; plist_t *recvd_prefixes[OPT_PI_LIST_LEN]; uint8_t recvd_pref_len = 0; -static abr_cache_t* abr_get_most_current(void); -static abr_cache_t* abr_get_oldest(void); +static abr_cache_t *abr_get_most_current(void); +static abr_cache_t *abr_get_oldest(void); -int min(int a, int b) { - if (a < b) { +int min(int a, int b) +{ + if(a < b) { return a; - } else { + } + else { return b; } } -static struct para_prob_t* get_para_prob_buf(uint8_t ext_len){ - return ((struct para_prob_t*)&(buffer[LLHDR_ICMPV6HDR_LEN + ext_len])); +static struct para_prob_t *get_para_prob_buf(uint8_t ext_len) +{ + return ((struct para_prob_t *) & (buffer[LLHDR_ICMPV6HDR_LEN + ext_len])); } -static struct rtr_adv_t* get_rtr_adv_buf(uint8_t ext_len){ - return ((struct rtr_adv_t*)&(buffer[LLHDR_ICMPV6HDR_LEN + ext_len])); +static struct rtr_adv_t *get_rtr_adv_buf(uint8_t ext_len) +{ + return ((struct rtr_adv_t *) & (buffer[LLHDR_ICMPV6HDR_LEN + ext_len])); } -static struct nbr_sol_t* get_nbr_sol_buf(uint8_t ext_len){ - return ((struct nbr_sol_t*)&(buffer[LLHDR_ICMPV6HDR_LEN + ext_len])); +static struct nbr_sol_t *get_nbr_sol_buf(uint8_t ext_len) +{ + return ((struct nbr_sol_t *) & (buffer[LLHDR_ICMPV6HDR_LEN + ext_len])); } -static struct nbr_adv_t* get_nbr_adv_buf(uint8_t ext_len){ - return ((struct nbr_adv_t*)&(buffer[LLHDR_ICMPV6HDR_LEN + ext_len])); +static struct nbr_adv_t *get_nbr_adv_buf(uint8_t ext_len) +{ + return ((struct nbr_adv_t *) & (buffer[LLHDR_ICMPV6HDR_LEN + ext_len])); } -static struct opt_buf_t* get_opt_buf(uint8_t ext_len, uint8_t opt_len){ - return ((struct opt_buf_t*)&(buffer[LLHDR_ICMPV6HDR_LEN + - ext_len + opt_len])); -} - -static struct opt_stllao_t* get_opt_stllao_buf(uint8_t ext_len, uint8_t opt_len){ - return ((struct opt_stllao_t*)&(buffer[LLHDR_ICMPV6HDR_LEN + +static struct opt_buf_t *get_opt_buf(uint8_t ext_len, uint8_t opt_len) +{ + return ((struct opt_buf_t *) & (buffer[LLHDR_ICMPV6HDR_LEN + ext_len + opt_len])); } -static struct opt_mtu_t* get_opt_mtu_buf(uint8_t ext_len, uint8_t opt_len){ - return ((struct opt_mtu_t*)&(buffer[LLHDR_ICMPV6HDR_LEN + - ext_len + opt_len])); -} - -static struct opt_abro_t* get_opt_abro_buf(uint8_t ext_len, uint8_t opt_len){ - return ((struct opt_abro_t*)&(buffer[LLHDR_ICMPV6HDR_LEN + - ext_len + opt_len])); -} - -static struct opt_6co_hdr_t* get_opt_6co_hdr_buf(uint8_t ext_len, uint8_t opt_len){ - return ((struct opt_6co_hdr_t*)&(buffer[LLHDR_ICMPV6HDR_LEN + +static struct opt_stllao_t *get_opt_stllao_buf(uint8_t ext_len, uint8_t opt_len) +{ + return ((struct opt_stllao_t *)&(buffer[LLHDR_ICMPV6HDR_LEN + ext_len + opt_len])); } -static uint8_t* get_opt_6co_prefix_buf(uint8_t ext_len, uint8_t opt_len){ - return ((uint8_t*)&(buffer[LLHDR_ICMPV6HDR_LEN + +static struct opt_mtu_t *get_opt_mtu_buf(uint8_t ext_len, uint8_t opt_len) +{ + return ((struct opt_mtu_t *) & (buffer[LLHDR_ICMPV6HDR_LEN + + ext_len + opt_len])); +} + +static struct opt_abro_t *get_opt_abro_buf(uint8_t ext_len, uint8_t opt_len) +{ + return ((struct opt_abro_t *)&(buffer[LLHDR_ICMPV6HDR_LEN + + ext_len + opt_len])); +} + +static struct opt_6co_hdr_t *get_opt_6co_hdr_buf(uint8_t ext_len, uint8_t opt_len) +{ + return ((struct opt_6co_hdr_t *)&(buffer[LLHDR_ICMPV6HDR_LEN + ext_len + opt_len])); } -static struct opt_pi_t* get_opt_pi_buf(uint8_t ext_len, uint8_t opt_len){ - return ((struct opt_pi_t*)&(buffer[LLHDR_ICMPV6HDR_LEN + - ext_len + opt_len])); +static uint8_t *get_opt_6co_prefix_buf(uint8_t ext_len, uint8_t opt_len) +{ + return ((uint8_t *)&(buffer[LLHDR_ICMPV6HDR_LEN + ext_len + opt_len])); } -static struct opt_aro_t* get_opt_aro_buf(uint8_t ext_len, uint8_t opt_len){ - return ((struct opt_aro_t*)&(buffer[LLHDR_ICMPV6HDR_LEN + - ext_len + opt_len])); +static struct opt_pi_t *get_opt_pi_buf(uint8_t ext_len, uint8_t opt_len) +{ + return ((struct opt_pi_t *)&(buffer[LLHDR_ICMPV6HDR_LEN + ext_len + + opt_len])); +} + +static struct opt_aro_t *get_opt_aro_buf(uint8_t ext_len, uint8_t opt_len) +{ + return ((struct opt_aro_t *)&(buffer[LLHDR_ICMPV6HDR_LEN + ext_len + + opt_len])); } /* send router solicitation message - RFC4861 section 4.1 */ -void init_rtr_sol(uint8_t sllao){ +void init_rtr_sol(uint8_t sllao) +{ ipv6_buf = get_ipv6_buf(); - icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len); - + icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len); + packet_length = 0; - + icmp_buf->type = ICMP_RTR_SOL; icmp_buf->code = 0; ipv6_buf->version_trafficclass = IPV6_VER; @@ -148,23 +181,24 @@ void init_rtr_sol(uint8_t sllao){ ipv6_set_all_rtrs_mcast_addr(&ipv6_buf->destaddr); //iface_find_src_ipaddr(&ipv6_buf->srcaddr, ADDR_STATE_PREFERRED, - // ADDR_TYPE_MULTICAST); + /* ADDR_TYPE_MULTICAST); */ ipv6_get_saddr(&(ipv6_buf->srcaddr), &(ipv6_buf->destaddr)); opt_hdr_len = RTR_SOL_LEN; - ipv6_buf->length = ICMPV6_HDR_LEN + RTR_SOL_LEN + OPT_STLLAO_MAX_LEN; - - if(sllao == OPT_SLLAO){ + ipv6_buf->length = ICMPV6_HDR_LEN + RTR_SOL_LEN + OPT_STLLAO_MAX_LEN; + + if(sllao == OPT_SLLAO) { opt_stllao_buf = get_opt_stllao_buf(ipv6_ext_hdr_len, opt_hdr_len); set_llao(opt_stllao_buf, OPT_SLLAO_TYPE, 2); packet_length = IPV6_HDR_LEN + ICMPV6_HDR_LEN + ipv6_ext_hdr_len + RTR_SOL_LEN + OPT_STLLAO_MAX_LEN; - } else { - packet_length = IPV6_HDR_LEN + ICMPV6_HDR_LEN + ipv6_ext_hdr_len + - RTR_SOL_LEN; } - + else { + packet_length = IPV6_HDR_LEN + ICMPV6_HDR_LEN + ipv6_ext_hdr_len + + RTR_SOL_LEN; + } + icmp_buf->checksum = 0; icmp_buf->checksum = ~icmpv6_csum(PROTO_NUM_ICMPV6); @@ -172,65 +206,79 @@ void init_rtr_sol(uint8_t sllao){ printf("INFO: send router solicitation to: "); ipv6_print_addr(&ipv6_buf->destaddr); #endif - lowpan_init((ieee_802154_long_t*)&(ipv6_buf->destaddr.uint16[4]),(uint8_t*)ipv6_buf); + lowpan_init((ieee_802154_long_t *)&(ipv6_buf->destaddr.uint16[4]), + (uint8_t *)ipv6_buf); } -void recv_rtr_sol(void){ +void recv_rtr_sol(void) +{ opt_hdr_len = RTR_SOL_LEN; ipv6_buf = get_ipv6_buf(); /* check if source option is set*/ - if(opt_stllao_buf->type == OPT_SLLAO_TYPE){ + if(opt_stllao_buf->type == OPT_SLLAO_TYPE) { opt_stllao_buf = get_opt_stllao_buf(ipv6_ext_hdr_len, opt_hdr_len); - llao = (uint8_t*)opt_stllao_buf; + llao = (uint8_t *)opt_stllao_buf; opt_hdr_len += (opt_stllao_buf->length) << 3; } - if(llao != NULL){ + + if(llao != NULL) { nbr_entry = nbr_cache_search(&ipv6_buf->srcaddr); - if(nbr_entry != NULL){ + + if(nbr_entry != NULL) { /* found neighbor in cache, update values and check long addr */ - if(memcmp(&llao[2],&nbr_entry->laddr,8) == 0){ + if(memcmp(&llao[2], &nbr_entry->laddr, 8) == 0) { nbr_entry->isrouter = 0; - } else { + } + else { /* new long addr found, update */ - memcpy(&nbr_entry->laddr,&llao[2],8); + memcpy(&nbr_entry->laddr, &llao[2], 8); nbr_entry->state = NBR_STATUS_STALE; nbr_entry->isrouter = 0; } - } else { + } + else { /* nothing found, add neigbor into cache*/ - nbr_cache_add(&ipv6_buf->srcaddr,(ieee_802154_long_t*)&llao[2], - 0, NBR_STATUS_STALE, NBR_CACHE_TYPE_TEN, + nbr_cache_add(&ipv6_buf->srcaddr, (ieee_802154_long_t *)&llao[2], + 0, NBR_STATUS_STALE, NBR_CACHE_TYPE_TEN, NBR_CACHE_LTIME_TEN, NULL); } } /* send solicited router advertisment */ - if (abr_count > 0) { + if(abr_count > 0) { init_rtr_adv(&ipv6_buf->srcaddr, 0, 0, OPT_PI, OPT_6CO, OPT_ABRO); - } else { + } + else { init_rtr_adv(&ipv6_buf->srcaddr, 0, 0, OPT_PI, 0, 0); } + #ifdef ENABLE_DEBUG printf("INFO: send router advertisment to: "); ipv6_print_addr(&ipv6_buf->destaddr); #endif - lowpan_init((ieee_802154_long_t*)&(ipv6_buf->destaddr.uint16[4]),(uint8_t*)ipv6_buf); + lowpan_init((ieee_802154_long_t *)&(ipv6_buf->destaddr.uint16[4]), + (uint8_t *)ipv6_buf); } -uint8_t set_opt_6co_flags(uint8_t compression_flag, uint8_t cid) { +uint8_t set_opt_6co_flags(uint8_t compression_flag, uint8_t cid) +{ uint8_t flags; - if (compression_flag) + + if(compression_flag) { flags = OPT_6CO_FLAG_C; - else + } + else { flags = 0; - + } + flags |= cid & OPT_6CO_FLAG_CID; return flags; } -void get_opt_6co_flags(uint8_t *compression_flag, uint8_t *cid, uint8_t flags) { +void get_opt_6co_flags(uint8_t *compression_flag, uint8_t *cid, uint8_t flags) +{ compression_flag[0] = flags & OPT_6CO_FLAG_CID; compression_flag[0] = compression_flag[0] != 0; cid[0] = flags & OPT_6CO_FLAG_CID; @@ -238,12 +286,14 @@ void get_opt_6co_flags(uint8_t *compression_flag, uint8_t *cid, uint8_t flags) { lowpan_context_t *abr_get_context(abr_cache_t *abr, uint8_t cid); -void init_rtr_adv(ipv6_addr_t *addr, uint8_t sllao, uint8_t mtu, uint8_t pi, uint8_t sixco, uint8_t abro){ +void init_rtr_adv(ipv6_addr_t *addr, uint8_t sllao, uint8_t mtu, uint8_t pi, + uint8_t sixco, uint8_t abro) +{ lowpan_context_t *contexts = NULL; - + abr_cache_t *msg_abr = NULL; ipv6_buf = get_ipv6_buf(); - icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len); + icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len); ipv6_buf->version_trafficclass = IPV6_VER; ipv6_buf->trafficclass_flowlabel = 0; @@ -251,20 +301,21 @@ void init_rtr_adv(ipv6_addr_t *addr, uint8_t sllao, uint8_t mtu, uint8_t pi, uin ipv6_buf->nextheader = PROTO_NUM_ICMPV6; ipv6_buf->hoplimit = ND_HOPLIMIT; - if(addr == NULL){ + if(addr == NULL) { /* not solicited */ ipv6_set_all_nds_mcast_addr(&ipv6_buf->destaddr); - } else { + } + else { memcpy(&ipv6_buf->destaddr, addr, 16); } - - ipv6_get_saddr(&(ipv6_buf->srcaddr), &(ipv6_buf->destaddr)); + + ipv6_get_saddr(&(ipv6_buf->srcaddr), &(ipv6_buf->destaddr)); icmp_buf->type = ICMP_RTR_ADV; icmp_buf->code = 0; - + //TODO: gethoplimit func, set current ttl - + rtr_adv_buf = get_rtr_adv_buf(ipv6_ext_hdr_len); rtr_adv_buf->hoplimit = MULTIHOP_HOPLIMIT; /* set M and O flag, last 6 bits are zero */ @@ -273,18 +324,18 @@ void init_rtr_adv(ipv6_addr_t *addr, uint8_t sllao, uint8_t mtu, uint8_t pi, uin rtr_adv_buf->reachable_time = 0; rtr_adv_buf->retrans_timer = 0; opt_hdr_len = RTR_ADV_LEN; - + packet_length = IPV6_HDR_LEN + ICMPV6_HDR_LEN + RTR_ADV_LEN; - if(sllao == OPT_SLLAO){ + if(sllao == OPT_SLLAO) { /* set link layer address option */ opt_stllao_buf = get_opt_stllao_buf(ipv6_ext_hdr_len, opt_hdr_len); - set_llao(opt_stllao_buf,OPT_SLLAO_TYPE, 2); + set_llao(opt_stllao_buf, OPT_SLLAO_TYPE, 2); opt_hdr_len += OPT_STLLAO_MAX_LEN; packet_length += OPT_STLLAO_MAX_LEN; } - - if(mtu == OPT_MTU){ + + if(mtu == OPT_MTU) { /* set MTU options */ opt_mtu_buf = get_opt_mtu_buf(ipv6_ext_hdr_len, opt_hdr_len); opt_mtu_buf->type = OPT_MTU_TYPE; @@ -294,84 +345,95 @@ void init_rtr_adv(ipv6_addr_t *addr, uint8_t sllao, uint8_t mtu, uint8_t pi, uin opt_hdr_len += OPT_MTU_HDR_LEN; packet_length += OPT_MTU_HDR_LEN; } + /* set payload length field */ - - if(abro == OPT_ABRO){ + + if(abro == OPT_ABRO) { /* set authoritive border router option */ - if (abr_count > 0) { + if(abr_count > 0) { msg_abr = abr_get_most_current(); opt_abro_buf = get_opt_abro_buf(ipv6_ext_hdr_len, opt_hdr_len); opt_abro_buf->type = OPT_ABRO_TYPE; opt_abro_buf->length = OPT_ABRO_LEN; opt_abro_buf->version = HTONS(msg_abr->version); opt_abro_buf->reserved = 0; - memcpy(&(opt_abro_buf->addr), &(msg_abr->abr_addr), sizeof (ipv6_addr_t)); + memcpy(&(opt_abro_buf->addr), &(msg_abr->abr_addr), sizeof(ipv6_addr_t)); } } - - if(sixco == OPT_6CO){ + + if(sixco == OPT_6CO) { /* set 6lowpan context option */ int contexts_len = 0; mutex_lock(&lowpan_context_mutex); - if (msg_abr == NULL) { + + if(msg_abr == NULL) { contexts = lowpan_context_get(); contexts_len = lowpan_context_len(); - } else { + } + else { lowpan_context_t c_tmp[LOWPAN_CONTEXT_MAX]; - + contexts_len = 0; - for (int i = 0; i < LOWPAN_CONTEXT_MAX; i++) { + + for(int i = 0; i < LOWPAN_CONTEXT_MAX; i++) { lowpan_context_t *ctx = abr_get_context(msg_abr, i); - if (ctx != NULL) { - memcpy(&(c_tmp[contexts_len++]), ctx, sizeof (lowpan_context_t)); + + if(ctx != NULL) { + memcpy(&(c_tmp[contexts_len++]), ctx, sizeof(lowpan_context_t)); } } - - contexts = (lowpan_context_t*)calloc(contexts_len, sizeof(lowpan_context_t)); - memcpy(contexts,c_tmp,contexts_len); + + contexts = (lowpan_context_t *)calloc(contexts_len, sizeof(lowpan_context_t)); + memcpy(contexts, c_tmp, contexts_len); } - for(int i = 0; i < contexts_len; i++){ + + for(int i = 0; i < contexts_len; i++) { opt_6co_hdr_buf = get_opt_6co_hdr_buf(ipv6_ext_hdr_len, opt_hdr_len); opt_6co_hdr_buf->type = OPT_6CO_TYPE; - if (contexts[i].length > 64) { + + if(contexts[i].length > 64) { opt_6co_hdr_buf->length = OPT_6CO_MAX_LEN; - } else { + } + else { opt_6co_hdr_buf->length = OPT_6CO_MIN_LEN; } + opt_6co_hdr_buf->c_length = contexts[i].length; - opt_6co_hdr_buf->c_flags = set_opt_6co_flags(contexts[i].comp,contexts[i].num); + opt_6co_hdr_buf->c_flags = set_opt_6co_flags(contexts[i].comp, contexts[i].num); opt_6co_hdr_buf->reserved = 0; opt_6co_hdr_buf->val_ltime = HTONS(contexts[i].lifetime); - + opt_hdr_len += OPT_6CO_HDR_LEN; packet_length += OPT_6CO_HDR_LEN; - // attach prefixes + /* attach prefixes */ opt_6co_prefix_buf = get_opt_6co_prefix_buf(ipv6_ext_hdr_len, opt_hdr_len); - - if (opt_6co_hdr_buf->c_length > 64) { - memset((void*)opt_6co_prefix_buf,0,16); - memcpy((void*)opt_6co_prefix_buf, (void*)&(contexts[i].prefix.uint8[0]), opt_6co_hdr_buf->c_length / 8); + + if(opt_6co_hdr_buf->c_length > 64) { + memset((void *)opt_6co_prefix_buf, 0, 16); + memcpy((void *)opt_6co_prefix_buf, (void *) & (contexts[i].prefix.uint8[0]), opt_6co_hdr_buf->c_length / 8); opt_hdr_len += 16; packet_length += 16; - } else { - memset((void*)opt_6co_prefix_buf,0,8); - memcpy((void*)opt_6co_prefix_buf, (void*)&(contexts[i].prefix.uint8[0]), opt_6co_hdr_buf->c_length / 8); + } + else { + memset((void *)opt_6co_prefix_buf, 0, 8); + memcpy((void *)opt_6co_prefix_buf, (void *) & (contexts[i].prefix.uint8[0]), opt_6co_hdr_buf->c_length / 8); opt_hdr_len += 8; packet_length += 8; } - + } - - if (msg_abr != NULL && contexts != NULL) { + + if(msg_abr != NULL && contexts != NULL) { free(contexts); } + mutex_unlock(&lowpan_context_mutex, 0); } - if(pi == OPT_PI){ + if(pi == OPT_PI) { /* set prefix option */ - for(int i=0;iaddr.uint8[0]), &(plist[i].addr.uint8[0]), 16); opt_pi_buf->type = OPT_PI_TYPE; @@ -394,12 +456,13 @@ void init_rtr_adv(ipv6_addr_t *addr, uint8_t sllao, uint8_t mtu, uint8_t pi, uin icmp_buf->checksum = ~icmpv6_csum(PROTO_NUM_ICMPV6); } -void recv_rtr_adv(void){ +void recv_rtr_adv(void) +{ int8_t trigger_ns = -1; int8_t abro_found = 0; - int16_t abro_version = 0; // later replaced, just to supress warnings + int16_t abro_version = 0; /* later replaced, just to supress warnings */ ipv6_addr_t abro_addr; - + ipv6_buf = get_ipv6_buf(); opt_hdr_len = RTR_ADV_LEN; rtr_adv_buf = get_rtr_adv_buf(ipv6_ext_hdr_len); @@ -407,66 +470,74 @@ void recv_rtr_adv(void){ recvd_cids_len = 0; /* update interface reachable time and retrans timer */ - if(rtr_adv_buf->reachable_time != 0){ - iface.adv_reachable_time = HTONL(rtr_adv_buf->reachable_time); + if(rtr_adv_buf->reachable_time != 0) { + iface.adv_reachable_time = HTONL(rtr_adv_buf->reachable_time); } - - if(rtr_adv_buf->retrans_timer != 0){ + + if(rtr_adv_buf->retrans_timer != 0) { iface.adv_retrans_timer = HTONL(rtr_adv_buf->retrans_timer); } def_rtr_entry = def_rtr_lst_search(&ipv6_buf->srcaddr); - if(rtr_adv_buf->router_lifetime != 0){ + + if(rtr_adv_buf->router_lifetime != 0) { if(def_rtr_entry != NULL) { set_remaining_time(&(def_rtr_entry->inval_time), HTONL(rtr_adv_buf->router_lifetime)); - } + } else { def_rtr_lst_add(&(ipv6_buf->srcaddr), HTONL(rtr_adv_buf->router_lifetime)); trigger_ns = 1; } - } else { - /* remove router from default router list */ - if(def_rtr_entry != NULL){ - def_rtr_lst_rem(def_rtr_entry); - } } - + else { + /* remove router from default router list */ + if(def_rtr_entry != NULL) { + def_rtr_lst_rem(def_rtr_entry); + } + } + mutex_lock(&lowpan_context_mutex); + /* read options */ - while(packet_length > IPV6HDR_ICMPV6HDR_LEN + opt_hdr_len){ + while(packet_length > IPV6HDR_ICMPV6HDR_LEN + opt_hdr_len) { opt_buf = get_opt_buf(ipv6_ext_hdr_len, opt_hdr_len); - switch(opt_buf->type){ - case(OPT_SLLAO_TYPE):{ + switch(opt_buf->type) { + case(OPT_SLLAO_TYPE): { break; } - case(OPT_MTU_TYPE):{ + + case(OPT_MTU_TYPE): { break; } + /* rfc 4862 section 5.5.3 */ - case(OPT_PI_TYPE):{ + case(OPT_PI_TYPE): { opt_pi_buf = get_opt_pi_buf(ipv6_ext_hdr_len, opt_hdr_len); + /* crazy condition, read 5.5.3a-b-c for further information */ - if(ipv6_prefix_ll_match(&opt_pi_buf->addr) || - (HTONL(opt_pi_buf->pref_ltime) > - HTONL(opt_pi_buf->val_ltime))){ + if(ipv6_prefix_ll_match(&opt_pi_buf->addr) || + (HTONL(opt_pi_buf->pref_ltime) > + HTONL(opt_pi_buf->val_ltime))) { break; - } + } else { /* check if on-link flag is set */ - if(opt_pi_buf->l_a_reserved1 & OPT_PI_FLAG_L){ + if(opt_pi_buf->l_a_reserved1 & OPT_PI_FLAG_L) { /* TODO: do on-link pi handling */ } - if(opt_pi_buf->l_a_reserved1 & OPT_PI_FLAG_A){ + + if(opt_pi_buf->l_a_reserved1 & OPT_PI_FLAG_A) { addr_list_ptr = ipv6_iface_addr_prefix_eq(&opt_pi_buf->addr); - if(addr_list_ptr == NULL){ + + if(addr_list_ptr == NULL) { /* 5.5.3d */ - if(opt_pi_buf->val_ltime != 0){ + if(opt_pi_buf->val_ltime != 0) { /* iid will also be added here */ ipv6_init_addr_prefix(&newaddr, &opt_pi_buf->addr); - /* add into address list - * TODO: duplicate address detection is not - * implementet yet, so all new addresse will + /* add into address list + * TODO: duplicate address detection is not + * implementet yet, so all new addresse will * be added with state PREFFERED */ ipv6_iface_add_addr(&newaddr, ADDR_STATE_PREFERRED, @@ -476,15 +547,15 @@ void recv_rtr_adv(void){ printf("INFO: added address to interface\n"); trigger_ns = 1; } - } + } else { - /* 5.5.3e */ + /* 5.5.3e */ set_remaining_time(&(addr_list_ptr->pref_ltime), opt_pi_buf->pref_ltime); /* 7200 = 2hours in seconds */ - if (HTONL(opt_pi_buf->val_ltime) > 7200 || - HTONL(opt_pi_buf->val_ltime) > - get_remaining_time(&(addr_list_ptr->val_ltime))) { + if(HTONL(opt_pi_buf->val_ltime) > 7200 || + HTONL(opt_pi_buf->val_ltime) > + get_remaining_time(&(addr_list_ptr->val_ltime))) { set_remaining_time(&(addr_list_ptr->val_ltime), HTONL(opt_pi_buf->val_ltime)); } else { @@ -494,77 +565,85 @@ void recv_rtr_adv(void){ } } } - // TODO: save found prefixes + + /* TODO: save found prefixes */ break; } - case(OPT_6CO_TYPE):{ + + case(OPT_6CO_TYPE): { uint8_t comp; uint8_t num; - + opt_6co_hdr_buf = get_opt_6co_hdr_buf(ipv6_ext_hdr_len, opt_hdr_len); - - get_opt_6co_flags(&comp,&num, opt_6co_hdr_buf->c_flags); - + + get_opt_6co_flags(&comp, &num, opt_6co_hdr_buf->c_flags); + ipv6_addr_t prefix; memset(&prefix, 0, 16); - + opt_6co_prefix_buf = get_opt_6co_prefix_buf(ipv6_ext_hdr_len, opt_hdr_len + OPT_6CO_HDR_LEN); - + memcpy(&prefix, opt_6co_prefix_buf, opt_6co_hdr_buf->c_length); - - lowpan_context_update ( - num, - &prefix, - opt_6co_hdr_buf->c_length, - comp, - HTONS(opt_6co_hdr_buf->val_ltime) - ); + + lowpan_context_update( + num, + &prefix, + opt_6co_hdr_buf->c_length, + comp, + HTONS(opt_6co_hdr_buf->val_ltime) + ); recvd_cids[recvd_cids_len] = num; - recvd_cids_len = (recvd_cids_len + 1)%LOWPAN_CONTEXT_MAX; + recvd_cids_len = (recvd_cids_len + 1) % LOWPAN_CONTEXT_MAX; break; } - case(OPT_ABRO_TYPE):{ + + case(OPT_ABRO_TYPE): { opt_abro_buf = get_opt_abro_buf(ipv6_ext_hdr_len, opt_hdr_len); abro_found = 1; abro_version = HTONS(opt_abro_buf->version); memcpy(&(abro_addr), &(opt_abro_buf->addr), sizeof(ipv6_addr_t)); - break; + break; } + default: break; } + /* multiplied with 8 because options length is in units of 8 bytes */ - opt_hdr_len += (opt_buf->length * 8); + opt_hdr_len += (opt_buf->length * 8); } - - if (abro_found) { + + if(abro_found) { int i; - for (i = 0; i < recvd_cids_len; i++) { - abr_add_context(abro_version,&abro_addr,recvd_cids[i]); + + for(i = 0; i < recvd_cids_len; i++) { + abr_add_context(abro_version, &abro_addr, recvd_cids[i]); } } - mutex_unlock(&lowpan_context_mutex,0); - - if(trigger_ns >= 0){ - /* send ns - draft-ietf-6lowpan-nd-15#section-5.5.1 - * - * section-10.2.4 + + mutex_unlock(&lowpan_context_mutex, 0); + + if(trigger_ns >= 0) { + /* send ns - draft-ietf-6lowpan-nd-15#section-5.5.1 + * + * section-10.2.4 * "Next the 6LN registers that address with one or more of its * default routers by sending a unicast NS message with an ARO * containing its tentative global IPv6 address to register * - * if new address was configured, set src to newaddr(gp16) */ - init_nbr_sol(&newaddr, &(ipv6_buf->srcaddr), &(ipv6_buf->srcaddr), OPT_SLLAO,OPT_ARO); + * if new address was configured, set src to newaddr(gp16) */ + init_nbr_sol(&newaddr, &(ipv6_buf->srcaddr), &(ipv6_buf->srcaddr), OPT_SLLAO, OPT_ARO); #ifdef ENABLE_DEBUG printf("INFO: send neighbor solicitation to: "); ipv6_print_addr(&(ipv6_buf->destaddr)); #endif - lowpan_init((ieee_802154_long_t*)&(ipv6_buf->destaddr.uint16[4]), (uint8_t*)ipv6_buf); + lowpan_init((ieee_802154_long_t *) & (ipv6_buf->destaddr.uint16[4]), (uint8_t *)ipv6_buf); } } void init_nbr_sol(ipv6_addr_t *src, ipv6_addr_t *dest, ipv6_addr_t *targ, - uint8_t sllao, uint8_t aro){ + uint8_t sllao, uint8_t aro) +{ ipv6_buf = get_ipv6_buf(); ipv6_buf->version_trafficclass = IPV6_VER; ipv6_buf->trafficclass_flowlabel = 0; @@ -572,32 +651,34 @@ void init_nbr_sol(ipv6_addr_t *src, ipv6_addr_t *dest, ipv6_addr_t *targ, ipv6_buf->nextheader = PROTO_NUM_ICMPV6; ipv6_buf->hoplimit = ND_HOPLIMIT; - if(dest == NULL){ + if(dest == NULL) { ipv6_set_sol_node_mcast_addr(targ, &(ipv6_buf->destaddr)); - } else{ + } + else { memcpy(&(ipv6_buf->destaddr.uint8[0]), &(dest->uint8[0]), 16); } - - ipv6_ext_hdr_len = 0; + + ipv6_ext_hdr_len = 0; icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len); icmp_buf->type = ICMP_NBR_SOL; icmp_buf->code = 0; - - nbr_sol_buf = get_nbr_sol_buf(ipv6_ext_hdr_len); - nbr_sol_buf->reserved = 0; + + nbr_sol_buf = get_nbr_sol_buf(ipv6_ext_hdr_len); + nbr_sol_buf->reserved = 0; memcpy(&(nbr_sol_buf->tgtaddr), targ, 16); opt_hdr_len = NBR_SOL_LEN; - + packet_length = IPV6_HDR_LEN + ICMPV6_HDR_LEN + NBR_SOL_LEN; - if(ipv6_iface_addr_match(targ) == NULL){ - if(src == NULL){ - ipv6_get_saddr(&(ipv6_buf->srcaddr),&(ipv6_buf->destaddr)); - } else{ + if(ipv6_iface_addr_match(targ) == NULL) { + if(src == NULL) { + ipv6_get_saddr(&(ipv6_buf->srcaddr), &(ipv6_buf->destaddr)); + } + else { memcpy(&(ipv6_buf->srcaddr), src, 16); } - - if(sllao == OPT_SLLAO){ + + if(sllao == OPT_SLLAO) { /* set sllao option */ opt_stllao_buf = get_opt_stllao_buf(ipv6_ext_hdr_len, opt_hdr_len); set_llao(opt_stllao_buf, OPT_SLLAO_TYPE, 1); @@ -607,7 +688,7 @@ void init_nbr_sol(ipv6_addr_t *src, ipv6_addr_t *dest, ipv6_addr_t *targ, } } - if(aro == OPT_ARO){ + if(aro == OPT_ARO) { /* set aro option */ opt_aro_buf = get_opt_aro_buf(ipv6_ext_hdr_len, opt_hdr_len); opt_aro_buf->type = OPT_ARO_TYPE; @@ -615,9 +696,9 @@ void init_nbr_sol(ipv6_addr_t *src, ipv6_addr_t *dest, ipv6_addr_t *targ, opt_aro_buf->status = 0; opt_aro_buf->reserved1 = 0; opt_aro_buf->reserved2 = 0; - memcpy(&(opt_aro_buf->eui64), mac_get_eui(src),8); - opt_hdr_len += OPT_ARO_HDR_LEN; - + memcpy(&(opt_aro_buf->eui64), mac_get_eui(src), 8); + opt_hdr_len += OPT_ARO_HDR_LEN; + packet_length += OPT_ARO_HDR_LEN; } @@ -627,134 +708,160 @@ void init_nbr_sol(ipv6_addr_t *src, ipv6_addr_t *dest, ipv6_addr_t *targ, icmp_buf->checksum = ~icmpv6_csum(PROTO_NUM_ICMPV6); } -void recv_nbr_sol(void){ +void recv_nbr_sol(void) +{ ipv6_buf = get_ipv6_buf(); llao = NULL; opt_hdr_len = NBR_SOL_LEN; - + uint8_t send_na = 0; uint8_t sllao_set = 0; uint8_t aro_state = OPT_ARO_STATE_SUCCESS; - + /* check whick options are set, we need that because an aro - * option condition is that a sllao option is set. thus that we don't + * option condition is that a sllao option is set. thus that we don't * know which option comes first we need to this here */ - while(packet_length > IPV6HDR_ICMPV6HDR_LEN + opt_hdr_len){ + while(packet_length > IPV6HDR_ICMPV6HDR_LEN + opt_hdr_len) { opt_buf = get_opt_buf(ipv6_ext_hdr_len, opt_hdr_len); - if(opt_buf->type == OPT_SLLAO_TYPE){ + + if(opt_buf->type == OPT_SLLAO_TYPE) { sllao_set = 1; } + opt_hdr_len += (opt_buf->length * 8); - } + } + opt_hdr_len = NBR_SOL_LEN; - while(packet_length > IPV6HDR_ICMPV6HDR_LEN + opt_hdr_len){ + while(packet_length > IPV6HDR_ICMPV6HDR_LEN + opt_hdr_len) { opt_buf = get_opt_buf(ipv6_ext_hdr_len, opt_hdr_len); - - switch(opt_buf->type){ - case(OPT_SLLAO_TYPE):{ + + switch(opt_buf->type) { + case(OPT_SLLAO_TYPE): { opt_stllao_buf = get_opt_stllao_buf(ipv6_ext_hdr_len, opt_hdr_len); - llao = (uint8_t*)opt_stllao_buf; - if(llao != NULL && - !(ipv6_addr_unspec_match(&ipv6_buf->srcaddr))){ + llao = (uint8_t *)opt_stllao_buf; + + if(llao != NULL && + !(ipv6_addr_unspec_match(&ipv6_buf->srcaddr))) { nbr_entry = nbr_cache_search(&(ipv6_buf->srcaddr)); - if(nbr_entry != NULL){ - switch(opt_stllao_buf->length){ - case(1):{ - if(memcmp(&llao[2],&(nbr_entry->saddr),2) == 0){ + + if(nbr_entry != NULL) { + switch(opt_stllao_buf->length) { + case(1): { + if(memcmp(&llao[2], &(nbr_entry->saddr), 2) == 0) { nbr_entry->isrouter = 0; - } else { - memcpy(&nbr_entry->saddr, &llao[2],2); + } + else { + memcpy(&nbr_entry->saddr, &llao[2], 2); nbr_entry->state = NBR_STATUS_STALE; nbr_entry->isrouter = 0; } + break; } - case(2):{ - if(memcmp(&llao[2],&(nbr_entry->laddr),8) == 0){ + + case(2): { + if(memcmp(&llao[2], &(nbr_entry->laddr), 8) == 0) { nbr_entry->isrouter = 0; - } else { - memcpy(&nbr_entry->laddr, &llao[2],8); + } + else { + memcpy(&nbr_entry->laddr, &llao[2], 8); nbr_entry->state = NBR_STATUS_STALE; nbr_entry->isrouter = 0; } + break; } + default: break; } - } else { - switch(opt_stllao_buf->length){ - case(1):{ + } + else { + switch(opt_stllao_buf->length) { + case(1): { nbr_cache_add(&ipv6_buf->srcaddr, - NULL ,0, NBR_STATUS_STALE, + NULL , 0, NBR_STATUS_STALE, NBR_CACHE_TYPE_TEN, - NBR_CACHE_LTIME_TEN, - (ieee_802154_short_t*)&llao[2]); + NBR_CACHE_LTIME_TEN, + (ieee_802154_short_t *)&llao[2]); break; } - case(2):{ + + case(2): { nbr_cache_add(&ipv6_buf->srcaddr, - (ieee_802154_long_t*)&llao[2],0, - NBR_STATUS_STALE, + (ieee_802154_long_t *)&llao[2], 0, + NBR_STATUS_STALE, NBR_CACHE_TYPE_TEN, NBR_CACHE_LTIME_TEN, NULL); break; } + default: break; } } } + break; } - case(OPT_ARO_TYPE):{ - /* check if sllao option is set, and if address src address - * isn't unspecified - draft-ietf-6lowpan-nd-15#section-6.5 */ - if(!(ipv6_addr_unspec_match(&ipv6_buf->srcaddr)) && - sllao_set == 1){ - opt_aro_buf = get_opt_aro_buf(ipv6_ext_hdr_len, + + case(OPT_ARO_TYPE): { + /* check if sllao option is set, and if address src address + * isn't unspecified - draft-ietf-6lowpan-nd-15#section-6.5 */ + if(!(ipv6_addr_unspec_match(&ipv6_buf->srcaddr)) && + sllao_set == 1) { + opt_aro_buf = get_opt_aro_buf(ipv6_ext_hdr_len, opt_hdr_len); - if((opt_aro_buf->length == 2) && - (opt_aro_buf->status == 0)){ + + if((opt_aro_buf->length == 2) && + (opt_aro_buf->status == 0)) { /* check neighbor cache for duplicates */ nbr_entry = nbr_cache_search(&(ipv6_buf->srcaddr)); - if(nbr_entry == NULL){ + + if(nbr_entry == NULL) { /* create neighbor cache */ aro_state = nbr_cache_add(&ipv6_buf->srcaddr, - &(opt_aro_buf->eui64),0, + &(opt_aro_buf->eui64), 0, NBR_STATUS_STALE, NBR_CACHE_TYPE_TEN, opt_aro_buf->reg_ltime, NULL); - } else { - if(memcmp(&(nbr_entry->addr.uint16[4]), - &(opt_aro_buf->eui64.uint16[0]),8) == 0){ + } + else { + if(memcmp(&(nbr_entry->addr.uint16[4]), + &(opt_aro_buf->eui64.uint16[0]), 8) == 0) { /* update neighbor cache entry */ - if(opt_aro_buf->reg_ltime == 0){ + if(opt_aro_buf->reg_ltime == 0) { /* delete neighbor cache entry */ - nbr_cache_rem(&nbr_entry->addr); - } else { + nbr_cache_rem(&nbr_entry->addr); + } + else { set_remaining_time(&(nbr_entry->ltime), (uint32_t)opt_aro_buf->reg_ltime); nbr_entry->state = NBR_STATUS_STALE; nbr_entry->isrouter = 0; memcpy(&(nbr_entry->addr.uint8[0]), - &(ipv6_buf->srcaddr.uint8[0]),16); + &(ipv6_buf->srcaddr.uint8[0]), 16); } + aro_state = OPT_ARO_STATE_SUCCESS; - } else { - // duplicate found + } + else { + /* duplicate found */ aro_state = OPT_ARO_STATE_DUP_ADDR; } - } + } } } + break; } + default: break; } + opt_hdr_len += (opt_buf->length * 8); } @@ -762,57 +869,60 @@ void recv_nbr_sol(void){ nbr_sol_buf = get_nbr_sol_buf(ipv6_ext_hdr_len); alist_targ = ipv6_iface_addr_match(&(nbr_sol_buf->tgtaddr)); - if(alist_targ != NULL){ + + if(alist_targ != NULL) { alist_dest = ipv6_iface_addr_match(&(ipv6_buf->destaddr)); - if((memcmp(&(alist_targ->addr),&(alist_dest->addr),16) == 0) || - ipv6_addr_sol_node_mcast_match(&ipv6_buf->destaddr)){ + if((memcmp(&(alist_targ->addr), &(alist_dest->addr), 16) == 0) || + ipv6_addr_sol_node_mcast_match(&ipv6_buf->destaddr)) { memcpy(&(ipv6_buf->destaddr.uint8[0]), - &(ipv6_buf->srcaddr.uint8[0]),16); + &(ipv6_buf->srcaddr.uint8[0]), 16); memcpy(&(ipv6_buf->srcaddr.uint8[0]), - &(nbr_sol_buf->tgtaddr.uint8[0]),16); + &(nbr_sol_buf->tgtaddr.uint8[0]), 16); send_na = 1; } } - if(send_na){ + + if(send_na) { /* solicited na */ uint8_t flags = (NBR_ADV_FLAG_O | NBR_ADV_FLAG_S); - init_nbr_adv(&(ipv6_buf->srcaddr), &(ipv6_buf->destaddr), + init_nbr_adv(&(ipv6_buf->srcaddr), &(ipv6_buf->destaddr), &(alist_targ->addr), flags, 0, OPT_ARO, aro_state); #ifdef ENABLE_DEBUG printf("INFO: send neighbor advertisment to: "); ipv6_print_addr(&ipv6_buf->destaddr); #endif - lowpan_init((ieee_802154_long_t*)&(ipv6_buf->destaddr.uint16[4]),(uint8_t*)ipv6_buf); + lowpan_init((ieee_802154_long_t *) & (ipv6_buf->destaddr.uint16[4]), (uint8_t *)ipv6_buf); } } -void init_nbr_adv(ipv6_addr_t *src, ipv6_addr_t *dst, ipv6_addr_t *tgt, - uint8_t rso, uint8_t sllao, uint8_t aro, uint8_t aro_state){ +void init_nbr_adv(ipv6_addr_t *src, ipv6_addr_t *dst, ipv6_addr_t *tgt, + uint8_t rso, uint8_t sllao, uint8_t aro, uint8_t aro_state) +{ ipv6_buf = get_ipv6_buf(); ipv6_buf->version_trafficclass = IPV6_VER; ipv6_buf->trafficclass_flowlabel = 0; ipv6_buf->flowlabel = 0; ipv6_buf->nextheader = PROTO_NUM_ICMPV6; ipv6_buf->hoplimit = ND_HOPLIMIT; - + ipv6_ext_hdr_len = 0; icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len); icmp_buf->type = ICMP_NBR_ADV; icmp_buf->code = 0; - + memcpy(&(ipv6_buf->destaddr.uint8[0]), &(dst->uint8[0]), 16); memcpy(&(ipv6_buf->srcaddr.uint8[0]), &(src->uint8[0]), 16); - + nbr_adv_buf = get_nbr_adv_buf(ipv6_ext_hdr_len); nbr_adv_buf->rso = rso; - - memset(&(nbr_adv_buf->reserved[0]),0,3); - memcpy(&(nbr_adv_buf->tgtaddr.uint8[0]), &(tgt->uint8[0]),16); - + + memset(&(nbr_adv_buf->reserved[0]), 0, 3); + memcpy(&(nbr_adv_buf->tgtaddr.uint8[0]), &(tgt->uint8[0]), 16); + packet_length = IPV6_HDR_LEN + ICMPV6_HDR_LEN + NBR_ADV_LEN; - - if(sllao == OPT_SLLAO){ + + if(sllao == OPT_SLLAO) { /* set sllao option */ opt_stllao_buf = get_opt_stllao_buf(ipv6_ext_hdr_len, opt_hdr_len); set_llao(opt_stllao_buf, OPT_SLLAO_TYPE, 1); @@ -821,27 +931,28 @@ void init_nbr_adv(ipv6_addr_t *src, ipv6_addr_t *dst, ipv6_addr_t *tgt, packet_length += OPT_STLLAO_MIN_LEN; } - if(aro == OPT_ARO){ + if(aro == OPT_ARO) { /* set aro option */ opt_aro_buf = get_opt_aro_buf(ipv6_ext_hdr_len, opt_hdr_len); opt_aro_buf->type = OPT_ARO_TYPE; opt_aro_buf->length = OPT_ARO_LEN; - opt_aro_buf->status = 0; // TODO + opt_aro_buf->status = 0; /* TODO */ opt_aro_buf->reserved1 = 0; opt_aro_buf->reserved2 = 0; - memcpy(&(opt_aro_buf->eui64), mac_get_eui(dst),8); + memcpy(&(opt_aro_buf->eui64), mac_get_eui(dst), 8); opt_hdr_len += OPT_ARO_HDR_LEN; packet_length += OPT_ARO_HDR_LEN; } ipv6_buf->length = packet_length - IPV6_HDR_LEN; - + icmp_buf->checksum = 0; icmp_buf->checksum = ~icmpv6_csum(PROTO_NUM_ICMPV6); } -void recv_nbr_adv(void){ +void recv_nbr_adv(void) +{ opt_hdr_len = NBR_ADV_LEN; llao = NULL; nbr_entry = NULL; @@ -849,186 +960,212 @@ void recv_nbr_adv(void){ nbr_adv_buf = get_nbr_adv_buf(ipv6_ext_hdr_len); /* check if options are present */ - while(packet_length > IPV6HDR_ICMPV6HDR_LEN + opt_hdr_len){ + while(packet_length > IPV6HDR_ICMPV6HDR_LEN + opt_hdr_len) { opt_buf = get_opt_buf(ipv6_ext_hdr_len, opt_hdr_len); - switch(opt_buf->type){ - case(OPT_TLLAO_TYPE):{ - llao = (uint8_t*)get_opt_stllao_buf(ipv6_ext_hdr_len, - opt_hdr_len); + + switch(opt_buf->type) { + case(OPT_TLLAO_TYPE): { + llao = (uint8_t *)get_opt_stllao_buf(ipv6_ext_hdr_len, + opt_hdr_len); break; } - case(OPT_ARO_TYPE):{ + + case(OPT_ARO_TYPE): { break; } } + opt_hdr_len += (opt_buf->length * 8); } addr_list_t *addr; - addr = ipv6_iface_addr_match(&nbr_adv_buf->tgtaddr); - - if(addr == NULL){ + addr = ipv6_iface_addr_match(&nbr_adv_buf->tgtaddr); + + if(addr == NULL) { nbr_entry = nbr_cache_search(&nbr_adv_buf->tgtaddr); - if(nbr_entry != NULL){ - if(llao != 0){ + + if(nbr_entry != NULL) { + if(llao != 0) { /* TODO: untersheiden zwischen short und long stllao option */ - new_ll = memcmp(&llao[2], &(nbr_entry->laddr), 8); + new_ll = memcmp(&llao[2], &(nbr_entry->laddr), 8); } - if(nbr_entry->state == NBR_STATUS_INCOMPLETE){ - if(llao == NULL){ + + if(nbr_entry->state == NBR_STATUS_INCOMPLETE) { + if(llao == NULL) { return; } + /* TODO: untersheiden zwischen short und long stllao option */ memcpy(&nbr_entry->laddr, &llao[2], 8); - if(nbr_adv_buf->rso & NBR_ADV_FLAG_S){ + + if(nbr_adv_buf->rso & NBR_ADV_FLAG_S) { nbr_entry->state = NBR_STATUS_REACHABLE; /* TODO: set rechability */ - } else { + } + else { nbr_entry->state = NBR_STATUS_STALE; } + nbr_entry->isrouter = nbr_adv_buf->rso & NBR_ADV_FLAG_R; - } else { - if(new_ll && !(nbr_adv_buf->rso & NBR_ADV_FLAG_O)){ - if(nbr_entry->state == NBR_STATUS_REACHABLE){ + } + else { + if(new_ll && !(nbr_adv_buf->rso & NBR_ADV_FLAG_O)) { + if(nbr_entry->state == NBR_STATUS_REACHABLE) { nbr_entry->state = NBR_STATUS_STALE; } + return; - } else { - if((nbr_adv_buf->rso & NBR_ADV_FLAG_O) || + } + else { + if((nbr_adv_buf->rso & NBR_ADV_FLAG_O) || (!(nbr_adv_buf->rso & NBR_ADV_FLAG_O) && llao != 0 && - !new_ll)){ - if(llao != 0){ + !new_ll)) { + if(llao != 0) { memcpy(&nbr_entry->laddr, &llao[2], 8); } - if(nbr_adv_buf->rso & NBR_ADV_FLAG_S){ + + if(nbr_adv_buf->rso & NBR_ADV_FLAG_S) { nbr_entry->state = NBR_STATUS_REACHABLE; /* TODO: set rechablility */ - } else { - if(llao != 0 && new_ll){ + } + else { + if(llao != 0 && new_ll) { nbr_entry->state = NBR_STATUS_STALE; } } } } - } + } } } } /* link-layer address option - RFC4861 section 4.6.1/ RFC4944 8. */ -void set_llao(opt_stllao_t *sllao, uint8_t type, uint8_t length){ +void set_llao(opt_stllao_t *sllao, uint8_t type, uint8_t length) +{ sllao->type = type; sllao->length = length; - - uint8_t *llao = (uint8_t*)sllao; - // get link layer address + + uint8_t *llao = (uint8_t *)sllao; + + /* get link layer address */ switch(length) { - case(1):{ + case(1): { memcpy(&llao[2], &(iface.saddr), 2); memset(&llao[4], 0, 4); break; } - case(2):{ - memcpy(&llao[2], &(iface.laddr), 8); + + case(2): { + memcpy(&llao[2], &(iface.laddr), 8); memset(&llao[10], 0, 6); break; } - default:{ + + default: { printf("ERROR: llao not set\n"); break; } } } -uint16_t icmpv6_csum(uint8_t proto){ +uint16_t icmpv6_csum(uint8_t proto) +{ ipv6_buf = get_ipv6_buf(); uint16_t sum; uint16_t len = ipv6_buf->length; sum = len + proto; sum = csum(sum, (uint8_t *)&ipv6_buf->srcaddr, 2 * sizeof(ipv6_addr_t)); - sum = csum(sum,(uint8_t*)get_icmpv6_buf(0),len); - + sum = csum(sum, (uint8_t *)get_icmpv6_buf(0), len); + return (sum == 0) ? 0xffff : HTONS(sum); } -void init_para_prob(ipv6_addr_t *src, ipv6_addr_t *dest, uint8_t code, uint32_t pointer, uint8_t *packet, uint8_t packet_len) { +void init_para_prob(ipv6_addr_t *src, ipv6_addr_t *dest, uint8_t code, uint32_t pointer, uint8_t *packet, uint8_t packet_len) +{ struct para_prob_t *para_prob_buf; - - + + packet_length = IPV6_HDR_LEN + ICMPV6_HDR_LEN + PARA_PROB_LEN; - - memcpy(&(ipv6_buf[packet_length]),packet,min(MTU-packet_length,packet_len)); - + + memcpy(&(ipv6_buf[packet_length]), packet, min(MTU - packet_length, packet_len)); + ipv6_buf = get_ipv6_buf(); ipv6_buf->version_trafficclass = IPV6_VER; ipv6_buf->trafficclass_flowlabel = 0; ipv6_buf->flowlabel = 0; ipv6_buf->nextheader = PROTO_NUM_ICMPV6; ipv6_buf->hoplimit = ND_HOPLIMIT; - + ipv6_ext_hdr_len = 0; icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len); icmp_buf->type = ICMP_PARA_PROB; icmp_buf->code = code; - + memcpy(&(ipv6_buf->destaddr.uint8[0]), &(dest->uint8[0]), 16); memcpy(&(ipv6_buf->srcaddr.uint8[0]), &(src->uint8[0]), 16); - + para_prob_buf = get_para_prob_buf(ipv6_ext_hdr_len); - + para_prob_buf->pointer = pointer; - - packet_length += min(MTU-packet_length,packet_len); - + + packet_length += min(MTU - packet_length, packet_len); + ipv6_buf->length = packet_length - IPV6_HDR_LEN; - + icmp_buf->checksum = 0; icmp_buf->checksum = ~icmpv6_csum(PROTO_NUM_ICMPV6); } //------------------------------------------------------------------------------ -// neighbor cache functions +/* neighbor cache functions */ -nbr_cache_t * nbr_cache_search(ipv6_addr_t *ipaddr){ +nbr_cache_t *nbr_cache_search(ipv6_addr_t *ipaddr) +{ int i; - for(i = 0; i < NBR_CACHE_SIZE; i++){ - if(memcmp(&(nbr_cache[i].addr.uint8[0]), &(ipaddr->uint8[0]), 16) == 0){ + + for(i = 0; i < NBR_CACHE_SIZE; i++) { + if(memcmp(&(nbr_cache[i].addr.uint8[0]), &(ipaddr->uint8[0]), 16) == 0) { return &nbr_cache[i]; - } + } } + return NULL; } -uint8_t nbr_cache_add(ipv6_addr_t *ipaddr, ieee_802154_long_t *laddr, - uint8_t isrouter, uint8_t state, uint8_t type, - uint16_t ltime, ieee_802154_short_t *saddr){ - if(nbr_count == NBR_CACHE_SIZE){ +uint8_t nbr_cache_add(ipv6_addr_t *ipaddr, ieee_802154_long_t *laddr, + uint8_t isrouter, uint8_t state, uint8_t type, + uint16_t ltime, ieee_802154_short_t *saddr) +{ + if(nbr_count == NBR_CACHE_SIZE) { printf("ERROR: neighbor cache full\n"); return OPT_ARO_STATE_NBR_CACHE_FULL; } - + memcpy(&(nbr_cache[nbr_count].addr), ipaddr, 16); memcpy(&(nbr_cache[nbr_count].laddr), laddr, 8); nbr_cache[nbr_count].isrouter = isrouter; nbr_cache[nbr_count].state = state; nbr_cache[nbr_count].type = type; - - //vtimer_set_wakeup(&(nbr_cache[nbr_count].ltime), t, - // nd_nbr_cache_rem_pid); + + //vtimer_set_wakeup(&(nbr_cache[nbr_count].ltime), t, + /* nd_nbr_cache_rem_pid); */ nbr_count++; - + return OPT_ARO_STATE_SUCCESS; } -void nbr_cache_auto_rem(void){ +void nbr_cache_auto_rem(void) +{ int i; - for(i = 0; i < NBR_CACHE_SIZE; i++){ - if(get_remaining_time(&(nbr_cache[i].ltime)) == 0 && - nbr_cache[i].type == NBR_CACHE_TYPE_TEN){ - memmove(&(nbr_cache[i]),&(nbr_cache[nbr_count]), + + for(i = 0; i < NBR_CACHE_SIZE; i++) { + if(get_remaining_time(&(nbr_cache[i].ltime)) == 0 && + nbr_cache[i].type == NBR_CACHE_TYPE_TEN) { + memmove(&(nbr_cache[i]), &(nbr_cache[nbr_count]), sizeof(nbr_cache_t)); memset(&(nbr_cache[nbr_count]), 0, sizeof(nbr_cache_t)); nbr_count--; @@ -1036,137 +1173,158 @@ void nbr_cache_auto_rem(void){ } } -void nbr_cache_rem(ipv6_addr_t *addr){ +void nbr_cache_rem(ipv6_addr_t *addr) +{ int i; - for(i = 0; i < NBR_CACHE_SIZE; i++){ - if(memcmp(&(nbr_cache[i].addr.uint8[0]),&(addr->uint8[0]),16) == 0){ - memmove(&(nbr_cache[i]),&(nbr_cache[nbr_count]), + + for(i = 0; i < NBR_CACHE_SIZE; i++) { + if(memcmp(&(nbr_cache[i].addr.uint8[0]), &(addr->uint8[0]), 16) == 0) { + memmove(&(nbr_cache[i]), &(nbr_cache[nbr_count]), sizeof(nbr_cache_t)); memset(&(nbr_cache[nbr_count]), 0, sizeof(nbr_cache_t)); - nbr_count--; + nbr_count--; } } } //------------------------------------------------------------------------------ -// authoritive border router list functions -/** +/* authoritive border router list functions */ +/** * @brief Finds the most current (by version number) authoritive border * router information. * @pre assumes that abro versions are centrally managed * @return The most current authoritive border router information, NULL * if no such information is given. */ -static abr_cache_t *abr_get_most_current(void){ +static abr_cache_t *abr_get_most_current(void) +{ abr_cache_t *abr = NULL; int i; int version = abr_cache[0].version; - for(i = 0; i < abr_count; i++){ - if (serial_comp16(version,abr_cache[i].version) == GREATER) { + + for(i = 0; i < abr_count; i++) { + if(serial_comp16(version, abr_cache[i].version) == GREATER) { abr = &(abr_cache[i]); version = abr_cache[i].version; } } - + return abr; } -static abr_cache_t *abr_get_oldest(void){ +static abr_cache_t *abr_get_oldest(void) +{ abr_cache_t *abr = NULL; int i; int version = abr_cache[0].version; - for(i = 0; i < abr_count; i++){ - if (serial_comp16(version,abr_cache[i].version) == LESS) { + + for(i = 0; i < abr_count; i++) { + if(serial_comp16(version, abr_cache[i].version) == LESS) { abr = &(abr_cache[i]); version = abr_cache[i].version; } } - + return abr; } -abr_cache_t *abr_get_version(uint16_t version, ipv6_addr_t *abr_addr) { +abr_cache_t *abr_get_version(uint16_t version, ipv6_addr_t *abr_addr) +{ int i = 0; - - for (i = 0; i < ABR_CACHE_SIZE; i++){ - if (abr_cache[i].version == version && - memcmp( &(abr_cache[i].abr_addr.uint8[0]), - &(abr_addr->uint8[0]),16 - ) == 0){ + + for(i = 0; i < ABR_CACHE_SIZE; i++) { + if(abr_cache[i].version == version && + memcmp(&(abr_cache[i].abr_addr.uint8[0]), + &(abr_addr->uint8[0]), 16 + ) == 0) { return &(abr_cache[i]); } } - + return NULL; } -lowpan_context_t *abr_get_context(abr_cache_t *abr, uint8_t cid) { - if (abr->cids[cid] != cid) { +lowpan_context_t *abr_get_context(abr_cache_t *abr, uint8_t cid) +{ + if(abr->cids[cid] != cid) { return NULL; } + return lowpan_context_num_lookup(abr->cids[cid]); } -abr_cache_t *abr_add_context( uint16_t version, ipv6_addr_t *abr_addr, - uint8_t cid){ +abr_cache_t *abr_add_context(uint16_t version, ipv6_addr_t *abr_addr, + uint8_t cid) +{ abr_cache_t *abr = abr_get_version(version, abr_addr); - - if (abr == NULL) { - if (abr_count == ABR_CACHE_SIZE) { + + if(abr == NULL) { + if(abr_count == ABR_CACHE_SIZE) { abr = abr_get_oldest(); - } else { + } + else { abr = &(abr_cache[abr_count++]); } + abr->version = version; - memcpy(&(abr->abr_addr), abr_addr, sizeof (ipv6_addr_t)); + memcpy(&(abr->abr_addr), abr_addr, sizeof(ipv6_addr_t)); memset(abr->cids, 0xFF, LOWPAN_CONTEXT_MAX); } - + abr->cids[cid] = cid; - + return abr; } -void abr_remove_context(uint8_t cid) { +void abr_remove_context(uint8_t cid) +{ int i; - for (i = 0; i < abr_count; i++) { + + for(i = 0; i < abr_count; i++) { abr_cache[i].cids[cid] = 0xFF; } } //------------------------------------------------------------------------------ -// default router list functions +/* default router list functions */ -def_rtr_lst_t * def_rtr_lst_search(ipv6_addr_t *ipaddr){ +def_rtr_lst_t *def_rtr_lst_search(ipv6_addr_t *ipaddr) +{ int i; - for(i = 0; i < DEF_RTR_LST_SIZE; i++){ - if(memcmp(&def_rtr_lst[i].addr.uint8[0], - &(ipaddr->uint8[0]), 16) == 0){ + + for(i = 0; i < DEF_RTR_LST_SIZE; i++) { + if(memcmp(&def_rtr_lst[i].addr.uint8[0], + &(ipaddr->uint8[0]), 16) == 0) { return &def_rtr_lst[i]; } } + return NULL; } -void def_rtr_lst_add(ipv6_addr_t *ipaddr, uint32_t rtr_ltime){ - if(def_rtr_count == DEF_RTR_LST_SIZE){ +void def_rtr_lst_add(ipv6_addr_t *ipaddr, uint32_t rtr_ltime) +{ + if(def_rtr_count == DEF_RTR_LST_SIZE) { DEBUG("ERROR: default router list full\n"); - } else { + } + else { memcpy(&(def_rtr_lst[def_rtr_count].addr), ipaddr, 16); timex_t rltime = {rtr_ltime, 0}; timex_t now; vtimer_now(&now); - + def_rtr_lst[def_rtr_count].inval_time = timex_add(now, rltime); - + def_rtr_count++; } } -void def_rtr_lst_rem(def_rtr_lst_t *entry){ +void def_rtr_lst_rem(def_rtr_lst_t *entry) +{ int i; - for(i = 0; i < DEF_RTR_LST_SIZE; i++){ - if(&def_rtr_lst[i] == entry){ + + for(i = 0; i < DEF_RTR_LST_SIZE; i++) { + if(&def_rtr_lst[i] == entry) { /* search the to deleted item, then memmove the last item to its * position, and decrement array count */ memmove(entry, &def_rtr_lst[def_rtr_count], sizeof(def_rtr_lst_t)); @@ -1177,13 +1335,15 @@ void def_rtr_lst_rem(def_rtr_lst_t *entry){ } //------------------------------------------------------------------------------ -// prefix list functions +/* prefix list functions */ int8_t plist_add(ipv6_addr_t *addr, uint8_t size, uint32_t val_ltime, - uint32_t pref_ltime, uint8_t adv_opt, uint8_t l_a_reserved1){ - if(prefix_count == OPT_PI_LIST_LEN){ + uint32_t pref_ltime, uint8_t adv_opt, uint8_t l_a_reserved1) +{ + if(prefix_count == OPT_PI_LIST_LEN) { return SIXLOWERROR_ARRAYFULL; - } else { + } + else { plist[prefix_count].inuse = 1; plist[prefix_count].length = size; plist[prefix_count].adv = adv_opt; diff --git a/sys/net/sixlowpan/sixlownd.h b/sys/net/sixlowpan/sixlownd.h index d1ce0f8b8f..f59517e52c 100644 --- a/sys/net/sixlowpan/sixlownd.h +++ b/sys/net/sixlowpan/sixlownd.h @@ -1,4 +1,21 @@ -/* 6LoWPAN ND header file */ +/* + * 6lowpan neighbor discovery + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup sixlowpan + * @{ + * @file sixlownd.h + * @brief 6lowpan neighbor discovery constants, data structs, and prototypes + * @author Stephan Zeisberg + * @author Martin Lenders + * @author Oliver Gesch + * @} + */ #ifndef SIXLOWND_H #define SIXLOWND_H @@ -31,19 +48,19 @@ #define NBR_ADV_FLAG_S 0x40 #define NBR_ADV_FLAG_O 0x20 /* icmp message types rfc4443 */ -#define ICMP_PARA_PROB 4 +#define ICMP_PARA_PROB 4 /* icmp message types rfc4861 4.*/ #define ICMP_RTR_ADV 134 #define ICMP_RTR_SOL 133 #define ICMP_NBR_ADV 136 -#define ICMP_NBR_SOL 135 -#define ICMP_REDIRECT 137 // will be filtered out by the border router +#define ICMP_NBR_SOL 135 +#define ICMP_REDIRECT 137 /* will be filtered out by the border router */ /* stllao option rfc4861 4.6.1 */ #define OPT_STLLAO_MIN_LEN 8 #define OPT_STLLAO_MAX_LEN 16 #define OPT_SLLAO_TYPE 1 -#define OPT_TLLAO_TYPE 2 -/* prefix info option rfc 4.6.2 */ +#define OPT_TLLAO_TYPE 2 +/* prefix info option rfc 4.6.2 */ #define OPT_PI_LIST_LEN 5 //TODO: initalwert suchen #define OPT_PI_TYPE 3 #define OPT_PI_LEN 4 @@ -56,10 +73,10 @@ #define OPT_MTU_LEN 1 #define OPT_MTU_HDR_LEN 8 /* aro - address registration option draft-ietf-6lowpan-nd-14 4.2 */ -#define OPT_ARO_TYPE 31 // TBD1 +#define OPT_ARO_TYPE 31 /* TBD1 */ #define OPT_ARO_LEN 2 #define OPT_ARO_HDR_LEN 16 -#define OPT_ARO_LTIME 300 // geeigneten wert finden +#define OPT_ARO_LTIME 300 /* geeigneten wert finden */ #define OPT_ARO_STATE_SUCCESS 0 #define OPT_ARO_STATE_DUP_ADDR 1 #define OPT_ARO_STATE_NBR_CACHE_FULL 2 @@ -68,7 +85,7 @@ #define OPT_6CO_MIN_LEN 2 #define OPT_6CO_MAX_LEN 3 #define OPT_6CO_HDR_LEN 8 -#define OPT_6CO_LTIME 5 // geeigneten Wert finden +#define OPT_6CO_LTIME 5 /* geeigneten Wert finden */ #define OPT_6CO_FLAG_C 0x10 #define OPT_6CO_FLAG_CID 0x0F #define OPT_6CO_FLAG_C_VALUE_SET 1 @@ -84,7 +101,7 @@ #define NBR_CACHE_TYPE_GC 1 #define NBR_CACHE_TYPE_REG 2 #define NBR_CACHE_TYPE_TEN 3 -#define NBR_CACHE_LTIME_TEN 20 +#define NBR_CACHE_LTIME_TEN 20 /* neighbor status values */ #define NBR_STATUS_INCOMPLETE 0 #define NBR_STATUS_REACHABLE 1 @@ -92,7 +109,7 @@ #define NBR_STATUS_DELAY 3 #define NBR_STATUS_PROBE 4 /* default router list size */ -#define DEF_RTR_LST_SIZE 3 // geeigneten wert finden +#define DEF_RTR_LST_SIZE 3 /* geeigneten wert finden */ extern unsigned int nd_nbr_cache_rem_pid; @@ -105,27 +122,27 @@ enum option_types_t { OPT_6CO, OPT_ABRO, OPT_DAR, - OPT_DAC, + OPT_DAC, }; -typedef struct __attribute__ ((packed)) opt_buf_t { +typedef struct __attribute__((packed)) { uint8_t type; - uint8_t length; + uint8_t length; } opt_buf_t; -typedef struct __attribute__ ((packed)) opt_stllao_t { +typedef struct __attribute__((packed)) { uint8_t type; uint8_t length; } opt_stllao_t; -typedef struct __attribute__ ((packed)) opt_mtu_t { +typedef struct __attribute__((packed)) { uint8_t type; uint8_t length; uint16_t reserved; uint32_t mtu; } opt_mtu_t; -typedef struct __attribute__ ((packed)) opt_pi_t { +typedef struct __attribute__((packed)) { uint8_t type; uint8_t length; uint8_t prefix_length; @@ -133,10 +150,10 @@ typedef struct __attribute__ ((packed)) opt_pi_t { uint32_t val_ltime; uint32_t pref_ltime; uint32_t reserved2; - ipv6_addr_t addr; + ipv6_addr_t addr; } opt_pi_t; -typedef struct __attribute__ ((packed)) opt_aro_t { +typedef struct __attribute__((packed)) { uint8_t type; uint8_t length; uint8_t status; @@ -146,7 +163,7 @@ typedef struct __attribute__ ((packed)) opt_aro_t { ieee_802154_long_t eui64; } opt_aro_t; -typedef struct __attribute__ ((packed)) opt_6co_hdr_t { +typedef struct __attribute__((packed)) { uint8_t type; uint8_t length; uint8_t c_length; @@ -155,7 +172,7 @@ typedef struct __attribute__ ((packed)) opt_6co_hdr_t { uint16_t val_ltime; } opt_6co_hdr_t; -typedef struct __attribute__ ((packed)) opt_abro_t { +typedef struct __attribute__((packed)) { uint8_t type; uint8_t length; uint16_t version; @@ -163,8 +180,8 @@ typedef struct __attribute__ ((packed)) opt_abro_t { ipv6_addr_t addr; } opt_abro_t; -typedef struct __attribute__ ((packed)) plist_t { - uint8_t inuse; +typedef struct __attribute__((packed)) { + uint8_t inuse; uint8_t adv; ipv6_addr_t addr; uint8_t length; @@ -174,7 +191,7 @@ typedef struct __attribute__ ((packed)) plist_t { uint8_t infinite; } plist_t; -struct __attribute__ ((packed)) rtr_adv_t { +struct __attribute__((packed)) rtr_adv_t { uint8_t hoplimit; uint8_t autoconfig_flags; uint16_t router_lifetime; @@ -182,18 +199,18 @@ struct __attribute__ ((packed)) rtr_adv_t { uint32_t retrans_timer; }; -struct __attribute__ ((packed)) nbr_sol_t { +struct __attribute__((packed)) nbr_sol_t { uint32_t reserved; - ipv6_addr_t tgtaddr; + ipv6_addr_t tgtaddr; }; -struct __attribute__ ((packed)) nbr_adv_t { +struct __attribute__((packed)) nbr_adv_t { uint8_t rso; uint8_t reserved[3]; - ipv6_addr_t tgtaddr; + ipv6_addr_t tgtaddr; }; -struct __attribute__ ((packed)) para_prob_t { +struct __attribute__((packed)) para_prob_t { uint8_t pointer; }; @@ -205,7 +222,7 @@ typedef struct __attribute__((packed)) abr_cache_t { } abr_cache_t; /* neighbor cache - rfc4861 5.1. */ -typedef struct __attribute__ ((packed)) nbr_cache_t { +typedef struct __attribute__((packed)) { uint8_t type; uint8_t state; uint8_t isrouter; @@ -216,7 +233,7 @@ typedef struct __attribute__ ((packed)) nbr_cache_t { } nbr_cache_t; /* default router list - rfc4861 5.1. */ -typedef struct __attribute__ ((packed)) def_rtr_lst_t { +typedef struct __attribute__((packed)) { ipv6_addr_t addr; timex_t inval_time; } def_rtr_lst_t; @@ -224,33 +241,34 @@ typedef struct __attribute__ ((packed)) def_rtr_lst_t { void init_rtr_sol(uint8_t sllao); void recv_rtr_sol(void); void recv_rtr_adv(void); -void init_rtr_adv(ipv6_addr_t *addr, uint8_t sllao, uint8_t mtu, uint8_t pi, +void init_rtr_adv(ipv6_addr_t *addr, uint8_t sllao, uint8_t mtu, uint8_t pi, uint8_t sixco, uint8_t abro); uint8_t plist_search(ipv6_addr_t *addr); uint8_t plist_cmp(ipv6_addr_t *addr1, ipv6_addr_t *addr2); int8_t plist_add(ipv6_addr_t *addr, uint8_t size, uint32_t val_ltime, - uint32_t pref_ltime, uint8_t adv_opt, uint8_t l_a_reserved1); + uint32_t pref_ltime, uint8_t adv_opt, uint8_t l_a_reserved1); void set_llao(opt_stllao_t *sllao, uint8_t type, uint8_t length); abr_cache_t *abr_get_version(uint16_t version, ipv6_addr_t *abr_addr); -abr_cache_t *abr_add_context( uint16_t version, ipv6_addr_t *abr_addr, - uint8_t cid); +abr_cache_t *abr_add_context(uint16_t version, ipv6_addr_t *abr_addr, + uint8_t cid); void abr_remove_context(uint8_t cid); -nbr_cache_t * nbr_cache_search(ipv6_addr_t *ipaddr); +nbr_cache_t *nbr_cache_search(ipv6_addr_t *ipaddr); uint8_t nbr_cache_add(ipv6_addr_t *ipaddr, ieee_802154_long_t *laddr, - uint8_t isrouter, uint8_t state, uint8_t type, - uint16_t ltime, ieee_802154_short_t *saddr); + uint8_t isrouter, uint8_t state, uint8_t type, + uint16_t ltime, ieee_802154_short_t *saddr); void nbr_cache_auto_rem(void); void nbr_cache_rem(ipv6_addr_t *addr); uint16_t icmpv6_csum(uint8_t proto); -def_rtr_lst_t * def_rtr_lst_search(ipv6_addr_t *ipaddr); +def_rtr_lst_t *def_rtr_lst_search(ipv6_addr_t *ipaddr); void def_rtr_lst_add(ipv6_addr_t *ipaddr, uint32_t rtr_ltime); void def_rtr_lst_rem(def_rtr_lst_t *entry); -void init_para_prob(ipv6_addr_t *src, ipv6_addr_t *dest, uint8_t code, uint32_t pointer, uint8_t *packet, uint8_t packet_len); +void init_para_prob(ipv6_addr_t *src, ipv6_addr_t *dest, uint8_t code, + uint32_t pointer, uint8_t *packet, uint8_t packet_len); void init_nbr_sol(ipv6_addr_t *src, ipv6_addr_t *dest, ipv6_addr_t *targ, uint8_t slloa, uint8_t aro); -void init_nbr_adv(ipv6_addr_t *src, ipv6_addr_t *dst, ipv6_addr_t *tgt, +void init_nbr_adv(ipv6_addr_t *src, ipv6_addr_t *dst, ipv6_addr_t *tgt, uint8_t rso, uint8_t sllao, uint8_t aro, uint8_t aro_state); void recv_nbr_adv(void); void recv_nbr_sol(void); diff --git a/sys/net/sixlowpan/sixlowpan.c b/sys/net/sixlowpan/sixlowpan.c index 0ab48479b8..bc27db6c57 100644 --- a/sys/net/sixlowpan/sixlowpan.c +++ b/sys/net/sixlowpan/sixlowpan.c @@ -1,3 +1,24 @@ +/* + * 6lowpan implementation + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup sixlowpan + * @{ + * @file sixlowpan.c + * @brief 6lowpan functions + * @author Stephan Zeisberg + * @author Martin Lenders + * @author Oliver Gesch + * @author Eric Engel + * @} + */ + +#include "sixlowip.h" #include #include #include @@ -66,614 +87,620 @@ uint16_t local_address = 0; void lowpan_context_auto_remove(void); /* deliver packet to mac*/ -void lowpan_init(ieee_802154_long_t *addr, uint8_t *data){ +void lowpan_init(ieee_802154_long_t *addr, uint8_t *data) +{ uint8_t mcast = 0; - ipv6_buf = (ipv6_hdr_t *) data; + ipv6_buf = (ipv6_hdr_t *) data; - memcpy(&laddr.uint8[0], &addr->uint8[0], 8); + memcpy(&laddr.uint8[0], &addr->uint8[0], 8); - if(ipv6_prefix_mcast_match(&ipv6_buf->destaddr)){ + if(ipv6_prefix_mcast_match(&ipv6_buf->destaddr)) { /* send broadcast */ mcast = 1; - } + } lowpan_iphc_encoding(&laddr, ipv6_buf, data); data = &comp_buf[0]; packet_length = comp_len; - - if (static_route == 1) - { - if (laddr.uint8[7] < local_address) - { - laddr.uint8[7] = local_address - 1; - } - else - { - laddr.uint8[7] = local_address + 1; - } - } + + if(static_route == 1) { + if(laddr.uint8[7] < local_address) { + laddr.uint8[7] = local_address - 1; + } + else { + laddr.uint8[7] = local_address + 1; + } + } /* check if packet needs to be fragmented */ - if(packet_length + header_size > PAYLOAD_SIZE - IEEE_802154_MAX_HDR_LEN){ + if(packet_length + header_size > PAYLOAD_SIZE - IEEE_802154_MAX_HDR_LEN) { uint8_t fragbuf[packet_length + header_size]; uint8_t remaining; uint8_t i = 2; /* first fragment */ max_frame = PAYLOAD_SIZE - IEEE_802154_MAX_HDR_LEN; max_frag_initial = ((max_frame - 4 - header_size) / 8) * 8; - - memcpy(fragbuf + 4, data, max_frag_initial); - + + memcpy(fragbuf + 4, data, max_frag_initial); + fragbuf[0] = (((0xc0 << 8) | packet_length) >> 8) & 0xff; fragbuf[1] = ((0xc0 << 8) | packet_length) & 0xff; fragbuf[2] = (tag >> 8) & 0xff; - fragbuf[3] = tag & 0xff; + fragbuf[3] = tag & 0xff; - send_ieee802154_frame(&laddr,(uint8_t*)&fragbuf, + send_ieee802154_frame(&laddr, (uint8_t *)&fragbuf, max_frag_initial + header_size + 4, mcast); /* subsequent fragments */ position = max_frag_initial; max_frag = ((max_frame - 5) / 8) * 8; - data += position; + data += position; - while(packet_length - position > max_frame - 5){ - memset(&fragbuf,0,packet_length + header_size); + while(packet_length - position > max_frame - 5) { + memset(&fragbuf, 0, packet_length + header_size); memcpy(fragbuf + 5, data, max_frag); - + fragbuf[0] = (((0xe0 << 8) | packet_length) >> 8) & 0xff; fragbuf[1] = ((0xe0 << 8) | packet_length) & 0xff; - fragbuf[2] = (tag >> 8) & 0xff; + fragbuf[2] = (tag >> 8) & 0xff; fragbuf[3] = tag & 0xff; fragbuf[4] = position / 8; - - send_ieee802154_frame(&laddr,(uint8_t*)&fragbuf, max_frag + 5, + + send_ieee802154_frame(&laddr, (uint8_t *)&fragbuf, max_frag + 5, mcast); data += max_frag; position += max_frag; - i++; + i++; } - + remaining = packet_length - position; - memset(&fragbuf,0,packet_length + header_size); - memcpy(fragbuf + 5, data, remaining); - + memset(&fragbuf, 0, packet_length + header_size); + memcpy(fragbuf + 5, data, remaining); + fragbuf[0] = (((0xe0 << 8) | packet_length) >> 8) & 0xff; fragbuf[1] = ((0xe0 << 8) | packet_length) & 0xff; fragbuf[2] = (tag >> 8) & 0xff; fragbuf[3] = tag & 0xff; fragbuf[4] = position / 8; - send_ieee802154_frame(&laddr, (uint8_t*)&fragbuf, remaining + 5, mcast); - } else { + send_ieee802154_frame(&laddr, (uint8_t *)&fragbuf, remaining + 5, mcast); + } + else { send_ieee802154_frame(&laddr, data, packet_length, mcast); - } + } tag++; } void printLongLocalAddr(ieee_802154_long_t *saddr) - { - printf("%02x%02x:%02x%02x:%02x%02x:%02x%02x\n", - ((uint8_t *)saddr)[0], ((uint8_t *)saddr)[1], ((uint8_t *)saddr)[2], - ((uint8_t *)saddr)[3], ((uint8_t *)saddr)[4], ((uint8_t *)saddr)[5], - ((uint8_t *)saddr)[6], ((uint8_t *)saddr)[7]); - } +{ + printf("%02x%02x:%02x%02x:%02x%02x:%02x%02x\n", + ((uint8_t *)saddr)[0], ((uint8_t *)saddr)[1], ((uint8_t *)saddr)[2], + ((uint8_t *)saddr)[3], ((uint8_t *)saddr)[4], ((uint8_t *)saddr)[5], + ((uint8_t *)saddr)[6], ((uint8_t *)saddr)[7]); +} void printReasBuffers(void) - { - lowpan_reas_buf_t *temp_buffer; - lowpan_interval_list_t *temp_interval; - temp_buffer = head; +{ + lowpan_reas_buf_t *temp_buffer; + lowpan_interval_list_t *temp_interval; + temp_buffer = head; - printf("\n\n--- Reassembly Buffers ---\n"); + printf("\n\n--- Reassembly Buffers ---\n"); - while (temp_buffer != NULL) - { - printLongLocalAddr(&temp_buffer->s_laddr); - printf("Ident.: %i, Packet Size: %i/%i, Timestamp: %li\n", temp_buffer->ident_no, temp_buffer->current_packet_size, temp_buffer->packet_size, temp_buffer->timestamp); - temp_interval = temp_buffer->interval_list_head; - while (temp_interval != NULL) - { - printf("\t%i - %i\n", temp_interval->start, temp_interval->end); - temp_interval = temp_interval->next; - } - temp_buffer = temp_buffer->next; - } - } + while(temp_buffer != NULL) { + printLongLocalAddr(&temp_buffer->s_laddr); + printf("Ident.: %i, Packet Size: %i/%i, Timestamp: %li\n", + temp_buffer->ident_no, temp_buffer->current_packet_size, + temp_buffer->packet_size, temp_buffer->timestamp); + temp_interval = temp_buffer->interval_list_head; + + while(temp_interval != NULL) { + printf("\t%i - %i\n", temp_interval->start, temp_interval->end); + temp_interval = temp_interval->next; + } + + temp_buffer = temp_buffer->next; + } +} void printFIFOBuffers(void) - { - lowpan_reas_buf_t *temp_buffer; - lowpan_interval_list_t *temp_interval; - temp_buffer = packet_fifo; +{ + lowpan_reas_buf_t *temp_buffer; + lowpan_interval_list_t *temp_interval; + temp_buffer = packet_fifo; - printf("\n\n--- Reassembly Buffers ---\n"); + printf("\n\n--- Reassembly Buffers ---\n"); - while (temp_buffer != NULL) - { - printLongLocalAddr(&temp_buffer->s_laddr); - printf("Ident.: %i, Packet Size: %i/%i, Timestamp: %li\n", temp_buffer->ident_no, temp_buffer->current_packet_size, temp_buffer->packet_size, temp_buffer->timestamp); - temp_interval = temp_buffer->interval_list_head; - while (temp_interval != NULL) - { - printf("\t%i - %i\n", temp_interval->start, temp_interval->end); - temp_interval = temp_interval->next; - } - temp_buffer = temp_buffer->next; - } - } + while(temp_buffer != NULL) { + printLongLocalAddr(&temp_buffer->s_laddr); + printf("Ident.: %i, Packet Size: %i/%i, Timestamp: %li\n", + temp_buffer->ident_no, temp_buffer->current_packet_size, + temp_buffer->packet_size, temp_buffer->timestamp); + temp_interval = temp_buffer->interval_list_head; + + while(temp_interval != NULL) { + printf("\t%i - %i\n", temp_interval->start, temp_interval->end); + temp_interval = temp_interval->next; + } + + temp_buffer = temp_buffer->next; + } +} void lowpan_transfer(void) - { - msg_t m_recv, m_send; - ipv6_hdr_t *ipv6_buf; - lowpan_reas_buf_t *current_buf; - uint8_t gotosleep; +{ + msg_t m_recv, m_send; + ipv6_hdr_t *ipv6_buf; + lowpan_reas_buf_t *current_buf; + uint8_t gotosleep; - while (1) - { + while(1) { - gotosleep = 1; - mutex_lock(&fifo_mutex); - current_buf = packet_fifo; - if (current_buf != NULL) - { - mutex_unlock(&fifo_mutex, 0); - if((current_buf->packet)[0] == LOWPAN_IPV6_DISPATCH) - { - ipv6_buf = get_ipv6_buf(); - memcpy(ipv6_buf, (current_buf->packet)+1, current_buf->packet_size - 1); - m_send.content.ptr = (char*) ipv6_buf; - packet_length = current_buf->packet_size - 1; - msg_send_receive(&m_send, &m_recv, ip_process_pid); - } - else if(((current_buf->packet)[0] & 0xe0) == LOWPAN_IPHC_DISPATCH) - { - lowpan_iphc_decoding(current_buf->packet, current_buf->packet_size, ¤t_buf->s_laddr, ¤t_buf->d_laddr); + gotosleep = 1; + mutex_lock(&fifo_mutex); + current_buf = packet_fifo; - ipv6_buf = get_ipv6_buf(); - m_send.content.ptr = (char*) ipv6_buf; - msg_send_receive(&m_send, &m_recv, ip_process_pid); - } - else - { -// printf("ERROR: packet with unknown dispatch received\n"); - } - collect_garbage_fifo(current_buf); - gotosleep = 0; - } + if(current_buf != NULL) { + mutex_unlock(&fifo_mutex, 0); + + if((current_buf->packet)[0] == LOWPAN_IPV6_DISPATCH) { + ipv6_buf = get_ipv6_buf(); + memcpy(ipv6_buf, (current_buf->packet) + 1, current_buf->packet_size - 1); + m_send.content.ptr = (char *)ipv6_buf; + packet_length = current_buf->packet_size - 1; + msg_send_receive(&m_send, &m_recv, ip_process_pid); + } + else if(((current_buf->packet)[0] & 0xe0) == LOWPAN_IPHC_DISPATCH) { + lowpan_iphc_decoding(current_buf->packet, + current_buf->packet_size, + current_buf->s_laddr, + current_buf->d_laddr); + + ipv6_buf = get_ipv6_buf(); + m_send.content.ptr = (char *) ipv6_buf; + msg_send_receive(&m_send, &m_recv, ip_process_pid); + } + else { + // printf("ERROR: packet with unknown dispatch received\n"); + } + + collect_garbage_fifo(current_buf); + gotosleep = 0; + } - if (gotosleep == 1) - { - mutex_unlock(&fifo_mutex, 0); - thread_sleep(); - } - } - } + if(gotosleep == 1) { + mutex_unlock(&fifo_mutex, 0); + thread_sleep(); + } + } +} -uint8_t ll_get_addr_match(ieee_802154_long_t *src, ieee_802154_long_t *dst){ +uint8_t ll_get_addr_match(ieee_802154_long_t *src, ieee_802154_long_t *dst) +{ uint8_t val = 0, xor; - for(int i = 0; i < 8; i++){ + + for(int i = 0; i < 8; i++) { /* if bytes are equal add 8 */ - if(src->uint8[i] == dst->uint8[i]){ + if(src->uint8[i] == dst->uint8[i]) { val += 8; - } else { + } + else { xor = src->uint8[i] ^ dst->uint8[i]; + /* while bits from byte equal add 1 */ - for(int j = 0; j < 8; j++){ - if((xor & 0x80) == 0){ + for(int j = 0; j < 8; j++) { + if((xor & 0x80) == 0) { val++; xor = xor << 1; - } else { + } + else { break; } } } } + return val; } -lowpan_reas_buf_t *new_packet_buffer(uint16_t datagram_size, uint16_t datagram_tag, ieee_802154_long_t *s_laddr, ieee_802154_long_t *d_laddr, - lowpan_reas_buf_t *current_buf, lowpan_reas_buf_t *temp_buf) - { - lowpan_reas_buf_t *new_buf = NULL; +lowpan_reas_buf_t *new_packet_buffer(uint16_t datagram_size, + uint16_t datagram_tag, + ieee_802154_long_t *s_laddr, + ieee_802154_long_t *d_laddr, + lowpan_reas_buf_t *current_buf, + lowpan_reas_buf_t *temp_buf) +{ + lowpan_reas_buf_t *new_buf = NULL; - /* Allocate new memory for a new packet to be reassembled */ - new_buf = malloc(sizeof(lowpan_reas_buf_t)); + /* Allocate new memory for a new packet to be reassembled */ + new_buf = malloc(sizeof(lowpan_reas_buf_t)); - if (new_buf != NULL) - { - init_reas_bufs(new_buf); + if(new_buf != NULL) { + init_reas_bufs(new_buf); - new_buf->packet = malloc(datagram_size); - if(new_buf->packet != NULL) - { - memcpy(&new_buf->s_laddr, s_laddr, SIXLOWPAN_IPV6_LL_ADDR_LEN); - memcpy(&new_buf->d_laddr, d_laddr, SIXLOWPAN_IPV6_LL_ADDR_LEN); + new_buf->packet = malloc(datagram_size); - new_buf->ident_no = datagram_tag; - new_buf->packet_size = datagram_size; + if(new_buf->packet != NULL) { + memcpy(&new_buf->s_laddr, s_laddr, SIXLOWPAN_IPV6_LL_ADDR_LEN); + memcpy(&new_buf->d_laddr, d_laddr, SIXLOWPAN_IPV6_LL_ADDR_LEN); - timex_t now; - vtimer_now(&now); - new_buf->timestamp = now.microseconds; + new_buf->ident_no = datagram_tag; + new_buf->packet_size = datagram_size; - if ((current_buf == NULL) && (temp_buf == NULL)) - { - head = new_buf; - } - else - { - temp_buf->next = new_buf; - } - return new_buf; - } - else - { - return NULL; - } - } - else - { - return NULL; - } - } + timex_t now; + vtimer_now(&now); + new_buf->timestamp = now.microseconds; -lowpan_reas_buf_t *get_packet_frag_buf(uint16_t datagram_size, uint16_t datagram_tag, ieee_802154_long_t *s_laddr, ieee_802154_long_t *d_laddr) - { - lowpan_reas_buf_t *current_buf = NULL, *temp_buf = NULL; - current_buf = head; - while (current_buf != NULL) - { - if (((ll_get_addr_match(¤t_buf->s_laddr, s_laddr)) == 64) && - ((ll_get_addr_match(¤t_buf->d_laddr, d_laddr)) == 64) && - (current_buf->packet_size == datagram_size) && - (current_buf->ident_no == datagram_tag) && - current_buf->interval_list_head != NULL) - { - /* Found buffer for current packet fragment */ - timex_t now; - vtimer_now(&now); - current_buf->timestamp = now.microseconds; - return current_buf; - } - temp_buf = current_buf; - current_buf = current_buf->next; - } + if((current_buf == NULL) && (temp_buf == NULL)) { + head = new_buf; + } + else { + temp_buf->next = new_buf; + } - return new_packet_buffer(datagram_size, datagram_tag, s_laddr, d_laddr, current_buf, temp_buf); - } + return new_buf; + } + else { + return NULL; + } + } + else { + return NULL; + } +} + +lowpan_reas_buf_t *get_packet_frag_buf(uint16_t datagram_size, + uint16_t datagram_tag, + ieee_802154_long_t *s_laddr, + ieee_802154_long_t *d_laddr) +{ + lowpan_reas_buf_t *current_buf = NULL, *temp_buf = NULL; + current_buf = head; + + while(current_buf != NULL) { + if(((ll_get_addr_match(¤t_buf->s_laddr, s_laddr)) == 64) && + ((ll_get_addr_match(¤t_buf->d_laddr, d_laddr)) == 64) && + (current_buf->packet_size == datagram_size) && + (current_buf->ident_no == datagram_tag) && + current_buf->interval_list_head != NULL) { + /* Found buffer for current packet fragment */ + timex_t now; + vtimer_now(&now); + current_buf->timestamp = now.microseconds; + return current_buf; + } + + temp_buf = current_buf; + current_buf = current_buf->next; + } + + return new_packet_buffer(datagram_size, datagram_tag, s_laddr, d_laddr, + current_buf, temp_buf); +} uint8_t isInInterval(uint8_t start1, uint8_t end1, uint8_t start2, uint8_t end2) - { - /* 1: Interval 1 and 2 are the same or overlapping */ - /* 0: Interval 1 and 2 are not overlapping or the same */ +{ + /* 1: Interval 1 and 2 are the same or overlapping */ + /* 0: Interval 1 and 2 are not overlapping or the same */ - if (((start1 < start2) && (start2 <= end1)) || - ((start2 < start1) && (start1 <= end2)) || - ((start1 == start2) && (end1 == end2))) - { - return 1; - } - else - { - return 0; - } - } + if(((start1 < start2) && (start2 <= end1)) || + ((start2 < start1) && (start1 <= end2)) || + ((start1 == start2) && (end1 == end2))) { + return 1; + } + else { + return 0; + } +} -uint8_t handle_packet_frag_interval(lowpan_reas_buf_t *current_buf, uint8_t datagram_offset, uint8_t frag_size) - { - /* 0: Error, discard fragment */ - /* 1: Finished correctly */ - lowpan_interval_list_t *temp_interval = NULL, *current_interval = NULL, *new_interval = NULL; - current_interval = current_buf->interval_list_head; - while (current_interval != NULL) - { - if (isInInterval(current_interval->start, current_interval->end, datagram_offset, datagram_offset+frag_size) == 1) - { - /* Interval is overlapping or the same as one of a previous fragment, discard fragment */ - return 0; - } - temp_interval = current_interval; - current_interval = current_interval->next; - } - new_interval = malloc(sizeof(lowpan_interval_list_t)); +uint8_t handle_packet_frag_interval(lowpan_reas_buf_t *current_buf, + uint8_t datagram_offset, uint8_t frag_size) +{ + /* 0: Error, discard fragment */ + /* 1: Finished correctly */ + lowpan_interval_list_t *temp_interval = NULL, *current_interval = NULL, *new_interval = NULL; + current_interval = current_buf->interval_list_head; - if (new_interval != NULL) - { - new_interval->start = datagram_offset; - new_interval->end = datagram_offset+frag_size-1; - new_interval->next = NULL; - if ((current_interval == NULL) && (temp_interval == NULL)) - { - current_buf->interval_list_head = new_interval; - } - else - { - temp_interval->next = new_interval; - } - return 1; - } + while(current_interval != NULL) { + if(isInInterval(current_interval->start, current_interval->end, datagram_offset, datagram_offset + frag_size) == 1) { + /* Interval is overlapping or the same as one of a previous fragment, discard fragment */ + return 0; + } - return 0; - } + temp_interval = current_interval; + current_interval = current_interval->next; + } + + new_interval = malloc(sizeof(lowpan_interval_list_t)); + + if(new_interval != NULL) { + new_interval->start = datagram_offset; + new_interval->end = datagram_offset + frag_size - 1; + new_interval->next = NULL; + + if((current_interval == NULL) && (temp_interval == NULL)) { + current_buf->interval_list_head = new_interval; + } + else { + temp_interval->next = new_interval; + } + + return 1; + } + + return 0; +} lowpan_reas_buf_t *collect_garbage_fifo(lowpan_reas_buf_t *current_buf) - { - lowpan_interval_list_t *temp_list, *current_list; - lowpan_reas_buf_t *temp_buf, *my_buf, *return_buf; +{ + lowpan_interval_list_t *temp_list, *current_list; + lowpan_reas_buf_t *temp_buf, *my_buf, *return_buf; - mutex_lock(&fifo_mutex); + mutex_lock(&fifo_mutex); - temp_buf = packet_fifo; - my_buf = temp_buf; + temp_buf = packet_fifo; + my_buf = temp_buf; - if (packet_fifo == current_buf) - { - packet_fifo = current_buf->next; - return_buf = packet_fifo; - } - else - { - while (temp_buf != current_buf) - { - my_buf = temp_buf; - temp_buf = temp_buf->next; - } + if(packet_fifo == current_buf) { + packet_fifo = current_buf->next; + return_buf = packet_fifo; + } + else { + while(temp_buf != current_buf) { + my_buf = temp_buf; + temp_buf = temp_buf->next; + } - my_buf->next = current_buf->next; + my_buf->next = current_buf->next; - return_buf = my_buf->next; - } - mutex_unlock(&fifo_mutex, 0); + return_buf = my_buf->next; + } - current_list = current_buf->interval_list_head; - temp_list = current_list; + mutex_unlock(&fifo_mutex, 0); - while (current_list != NULL) - { - temp_list = current_list->next; - free(current_list); - current_list = temp_list; - } + current_list = current_buf->interval_list_head; + temp_list = current_list; - free(current_buf->packet); - free(current_buf); + while(current_list != NULL) { + temp_list = current_list->next; + free(current_list); + current_list = temp_list; + } - return return_buf; - } + free(current_buf->packet); + free(current_buf); + + return return_buf; +} lowpan_reas_buf_t *collect_garbage(lowpan_reas_buf_t *current_buf) - { - lowpan_interval_list_t *temp_list, *current_list; - lowpan_reas_buf_t *temp_buf, *my_buf, *return_buf; +{ + lowpan_interval_list_t *temp_list, *current_list; + lowpan_reas_buf_t *temp_buf, *my_buf, *return_buf; - temp_buf = head; - my_buf = temp_buf; + temp_buf = head; + my_buf = temp_buf; - if (head == current_buf) - { - head = current_buf->next; - return_buf = head; - } - else - { - while (temp_buf != current_buf) - { - my_buf = temp_buf; - temp_buf = temp_buf->next; - } + if(head == current_buf) { + head = current_buf->next; + return_buf = head; + } + else { + while(temp_buf != current_buf) { + my_buf = temp_buf; + temp_buf = temp_buf->next; + } - my_buf->next = current_buf->next; + my_buf->next = current_buf->next; - return_buf = my_buf->next; - } + return_buf = my_buf->next; + } - current_list = current_buf->interval_list_head; - temp_list = current_list; + current_list = current_buf->interval_list_head; + temp_list = current_list; - while (current_list != NULL) - { - temp_list = current_list->next; - free(current_list); - current_list = temp_list; - } + while(current_list != NULL) { + temp_list = current_list->next; + free(current_list); + current_list = temp_list; + } - free(current_buf->packet); - free(current_buf); + free(current_buf->packet); + free(current_buf); - return return_buf; - } + return return_buf; +} -void handle_packet_fragment(uint8_t *data, uint8_t datagram_offset, uint16_t datagram_size, - uint16_t datagram_tag, ieee_802154_long_t *s_laddr, ieee_802154_long_t *d_laddr, - uint8_t hdr_length, uint8_t frag_size) - { - lowpan_reas_buf_t *current_buf; - /* Is there already a reassembly buffer for this packet fragment? */ - current_buf = get_packet_frag_buf(datagram_size, datagram_tag, s_laddr, d_laddr); - if ((current_buf != NULL) && (handle_packet_frag_interval(current_buf, datagram_offset, frag_size) == 1)) - { - /* Copy fragment bytes into corresponding packet space area */ - memcpy(current_buf->packet+datagram_offset, data+hdr_length, frag_size); - current_buf->current_packet_size += frag_size; - if (current_buf->current_packet_size == current_buf->packet_size) - { - add_fifo_packet(current_buf); - if (thread_getstatus(transfer_pid) == STATUS_SLEEPING) - { - thread_wakeup(transfer_pid); - } - } - } - else - { - /* No memory left or duplicate */ - if (current_buf == NULL) - { - printf("ERROR: no memory left!\n"); - } - else - { - printf("ERROR: duplicate fragment!\n"); - } - } - } +void handle_packet_fragment(uint8_t *data, uint8_t datagram_offset, + uint16_t datagram_size, uint16_t datagram_tag, + ieee_802154_long_t *s_laddr, + ieee_802154_long_t *d_laddr, uint8_t hdr_length, + uint8_t frag_size) +{ + lowpan_reas_buf_t *current_buf; + /* Is there already a reassembly buffer for this packet fragment? */ + current_buf = get_packet_frag_buf(datagram_size, datagram_tag, s_laddr, d_laddr); + + if((current_buf != NULL) && (handle_packet_frag_interval(current_buf, + datagram_offset, + frag_size) == 1)) { + /* Copy fragment bytes into corresponding packet space area */ + memcpy(current_buf->packet + datagram_offset, data + hdr_length, frag_size); + current_buf->current_packet_size += frag_size; + + if(current_buf->current_packet_size == current_buf->packet_size) { + add_fifo_packet(current_buf); + + if(thread_getstatus(transfer_pid) == STATUS_SLEEPING) { + thread_wakeup(transfer_pid); + } + } + } + else { + /* No memory left or duplicate */ + if(current_buf == NULL) { + printf("ERROR: no memory left!\n"); + } + else { + printf("ERROR: duplicate fragment!\n"); + } + } +} void check_timeout(void) - { - lowpan_reas_buf_t *temp_buf, *smallest_time = NULL; - long cur_time; - int count = 0; +{ + lowpan_reas_buf_t *temp_buf, *smallest_time = NULL; + long cur_time; + int count = 0; - timex_t now; - vtimer_now(&now); - cur_time = now.microseconds; - temp_buf = head; + timex_t now; + vtimer_now(&now); + cur_time = now.microseconds; + temp_buf = head; - while (temp_buf != NULL) - { - if ((cur_time - temp_buf->timestamp) >= LOWPAN_REAS_BUF_TIMEOUT) - { - printf("TIMEOUT! cur_time: %li, temp_buf: %li\n", cur_time, temp_buf->timestamp); - temp_buf = collect_garbage(temp_buf); - } - else - { - if (smallest_time == NULL) - { - smallest_time = temp_buf; - } - else if (temp_buf->timestamp < smallest_time->timestamp) - { - smallest_time = temp_buf; - } - temp_buf = temp_buf->next; - count++; - } - } - if ((count > 10) && (smallest_time != NULL)) - { - collect_garbage(smallest_time); - } - } + while(temp_buf != NULL) { + if((cur_time - temp_buf->timestamp) >= LOWPAN_REAS_BUF_TIMEOUT) { + printf("TIMEOUT! cur_time: %li, temp_buf: %li\n", cur_time, + temp_buf->timestamp); + temp_buf = collect_garbage(temp_buf); + } + else { + if(smallest_time == NULL) { + smallest_time = temp_buf; + } + else if(temp_buf->timestamp < smallest_time->timestamp) { + smallest_time = temp_buf; + } + + temp_buf = temp_buf->next; + count++; + } + } + + if((count > 10) && (smallest_time != NULL)) { + collect_garbage(smallest_time); + } +} void add_fifo_packet(lowpan_reas_buf_t *current_packet) - { - lowpan_reas_buf_t *temp_buf, *my_buf; +{ + lowpan_reas_buf_t *temp_buf, *my_buf; - if (head == current_packet) - { - head = current_packet->next; - } - else - { - temp_buf = head; - while (temp_buf != current_packet) - { - my_buf = temp_buf; - temp_buf = temp_buf->next; - } - my_buf->next = current_packet->next; - } - mutex_lock(&fifo_mutex); - if (packet_fifo == NULL) - { - packet_fifo = current_packet; - } - else - { - temp_buf = packet_fifo; - while (temp_buf != NULL) - { - my_buf = temp_buf; - temp_buf = temp_buf->next; - } - my_buf->next = current_packet; - } - mutex_unlock(&fifo_mutex, 0); - current_packet->next = NULL; - } + if(head == current_packet) { + head = current_packet->next; + } + else { + temp_buf = head; + + while(temp_buf != current_packet) { + my_buf = temp_buf; + temp_buf = temp_buf->next; + } + + my_buf->next = current_packet->next; + } + + mutex_lock(&fifo_mutex); + + if(packet_fifo == NULL) { + packet_fifo = current_packet; + } + else { + temp_buf = packet_fifo; + + while(temp_buf != NULL) { + my_buf = temp_buf; + temp_buf = temp_buf->next; + } + + my_buf->next = current_packet; + } + + mutex_unlock(&fifo_mutex, 0); + current_packet->next = NULL; +} void lowpan_read(uint8_t *data, uint8_t length, ieee_802154_long_t *s_laddr, - ieee_802154_long_t *d_laddr){ + ieee_802154_long_t *d_laddr) +{ /* check if packet is fragmented */ uint8_t hdr_length = 0; - uint8_t datagram_offset = 0; + uint8_t datagram_offset = 0; uint16_t datagram_size = 0; uint16_t datagram_tag = 0; check_timeout(); /* Fragmented Packet */ - if (((data[0] & 0xf8) == (0xc0)) || ((data[0] & 0xf8) == (0xe0))) - { - /* get 11-bit from first 2 byte*/ - datagram_size = (((uint16_t)(data[0] << 8)) | data[1]) & 0x07ff; + if(((data[0] & 0xf8) == (0xc0)) || ((data[0] & 0xf8) == (0xe0))) { + /* get 11-bit from first 2 byte*/ + datagram_size = (((uint16_t)(data[0] << 8)) | data[1]) & 0x07ff; - /* get 16-bit datagram tag */ - datagram_tag = (((uint16_t)(data[2] << 8)) | data[3]); + /* get 16-bit datagram tag */ + datagram_tag = (((uint16_t)(data[2] << 8)) | data[3]); - switch(data[0] & 0xf8) - { - /* First Fragment */ - case(0xc0): - { - datagram_offset = 0; - hdr_length += 4; - break; - } - /* Subsequent Fragment */ - case(0xe0): - { - datagram_offset = data[4]; - hdr_length += 5; - break; - } - } - frag_size = length - hdr_length; - byte_offset = datagram_offset * 8; + switch(data[0] & 0xf8) { + /* First Fragment */ + case(0xc0): { + datagram_offset = 0; + hdr_length += 4; + break; + } - if((frag_size % 8) != 0) - { - if((byte_offset + frag_size) != datagram_size) - { - printf("ERROR: received invalid fragment\n"); - return; - } - } - handle_packet_fragment(data, byte_offset, datagram_size, datagram_tag, s_laddr, d_laddr, hdr_length, frag_size); - } + /* Subsequent Fragment */ + case(0xe0): { + datagram_offset = data[4]; + hdr_length += 5; + break; + } + } + + frag_size = length - hdr_length; + byte_offset = datagram_offset * 8; + + if((frag_size % 8) != 0) { + if((byte_offset + frag_size) != datagram_size) { + printf("ERROR: received invalid fragment\n"); + return; + } + } + + handle_packet_fragment(data, byte_offset, datagram_size, datagram_tag, + s_laddr, d_laddr, hdr_length, frag_size); + } /* Regular Packet */ - else - { - lowpan_reas_buf_t *current_buf = get_packet_frag_buf(length, 0, s_laddr, d_laddr); - /* Copy packet bytes into corresponding packet space area */ - memcpy(current_buf->packet, data, length); - current_buf->current_packet_size += length; - add_fifo_packet(current_buf); - if (thread_getstatus(transfer_pid) == STATUS_SLEEPING) - { - thread_wakeup(transfer_pid); - } - } + else { + lowpan_reas_buf_t *current_buf = get_packet_frag_buf(length, 0, s_laddr, + d_laddr); + /* Copy packet bytes into corresponding packet space area */ + memcpy(current_buf->packet, data, length); + current_buf->current_packet_size += length; + add_fifo_packet(current_buf); - } + if(thread_getstatus(transfer_pid) == STATUS_SLEEPING) { + thread_wakeup(transfer_pid); + } + } -void lowpan_ipv6_set_dispatch(uint8_t *data){ +} + +void lowpan_ipv6_set_dispatch(uint8_t *data) +{ memmove(data + 1, data, packet_length); data[0] = LOWPAN_IPV6_DISPATCH; packet_length++; } /* draft-ietf-6lowpan-hc-13#section-3.1 */ -void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra, uint8_t * ptr){ - ipv6_buf = ipv6_buf_extra; +void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra, + uint8_t *ptr) +{ + ipv6_buf = ipv6_buf_extra; uint16_t payload_length = ipv6_buf->length; uint8_t lowpan_iphc[2]; @@ -686,38 +713,43 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra, /* set iphc dispatch */ lowpan_iphc[0] = LOWPAN_IPHC_DISPATCH; - + /* TF: Traffic Class, Flow Label: - * first we need to change DSCP and ECN because in 6lowpan-nd-13 these + * first we need to change DSCP and ECN because in 6lowpan-nd-13 these * fields are reverse, the original order is DSCP/ECN (rfc 3168) */ - tc = (ipv6_buf->version_trafficclass << 4) | (ipv6_buf->trafficclass_flowlabel >> 4); + tc = (ipv6_buf->version_trafficclass << 4) | + (ipv6_buf->trafficclass_flowlabel >> 4); tc = (tc >> 2) | (tc << 6); - - if((ipv6_buf->flowlabel == 0) && - (ipv6_buf->trafficclass_flowlabel & 0x0f) == 0){ + + if((ipv6_buf->flowlabel == 0) && + (ipv6_buf->trafficclass_flowlabel & 0x0f) == 0) { /* flowlabel is elided */ lowpan_iphc[0] |= LOWPAN_IPHC_FL_C; - if(((ipv6_buf->version_trafficclass & 0x0f) == 0) && - ((ipv6_buf->trafficclass_flowlabel & 0xf0) == 0)){ + + if(((ipv6_buf->version_trafficclass & 0x0f) == 0) && + ((ipv6_buf->trafficclass_flowlabel & 0xf0) == 0)) { /* traffic class is elided */ - lowpan_iphc[0] |= LOWPAN_IPHC_TC_C; - } else { + lowpan_iphc[0] |= LOWPAN_IPHC_TC_C; + } + else { /* ECN + DSCP (1 byte), Flow Label is elided */ ipv6_hdr_fields[hdr_pos] = tc; hdr_pos++; - } - } else { + } + } + else { /* flowlabel not compressible */ - if(((ipv6_buf->version_trafficclass & 0x0f) == 0) && - ((ipv6_buf->trafficclass_flowlabel & 0xf0) == 0)){ + if(((ipv6_buf->version_trafficclass & 0x0f) == 0) && + ((ipv6_buf->trafficclass_flowlabel & 0xf0) == 0)) { /* traffic class is elided */ lowpan_iphc[0] |= LOWPAN_IPHC_TC_C; /* ECN + 2-bit Pad + Flow Label (3 bytes), DSCP is elided */ - ipv6_hdr_fields[hdr_pos] = ((tc & 0xc0) | - (ipv6_buf->trafficclass_flowlabel & 0x0f)); + ipv6_hdr_fields[hdr_pos] = ((tc & 0xc0) | + (ipv6_buf->trafficclass_flowlabel & 0x0f)); memcpy(&(ipv6_hdr_fields[hdr_pos]), &ipv6_buf->flowlabel , 2); - hdr_pos += 3; - } else { + hdr_pos += 3; + } + else { /* ECN + DSCP + 4-bit Pad + Flow Label (4 bytes) */ memcpy(&ipv6_hdr_fields[hdr_pos], &ipv6_buf->version_trafficclass, 4); ipv6_hdr_fields[hdr_pos] = tc; @@ -725,29 +757,32 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra, } } - /* NH: Next Header: + /* NH: Next Header: * TODO: NHC */ ipv6_hdr_fields[hdr_pos] = ipv6_buf->nextheader; hdr_pos++; /* HLIM: Hop Limit: */ - switch(ipv6_buf->hoplimit){ - case(1):{ + switch(ipv6_buf->hoplimit) { + case(1): { /* 01: The Hop Limit field is compressed and the hop limit is 1. */ lowpan_iphc[0] |= 0x01; break; } - case(64):{ + + case(64): { /* 10: The Hop Limit field is compressed and the hop limit is 64. */ lowpan_iphc[0] |= 0x02; break; } - case(255):{ + + case(255): { /* 11: The Hop Limit field is compressed and the hop limit is 255. */ lowpan_iphc[0] |= 0x03; break; } - default:{ + + default: { ipv6_hdr_fields[hdr_pos] = ipv6_buf->hoplimit; hdr_pos++; break; @@ -755,32 +790,35 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra, } mutex_lock(&lowpan_context_mutex); + /* CID: Context Identifier Extension: */ - if((lowpan_context_lookup(&ipv6_buf->srcaddr) != NULL ) || - (lowpan_context_lookup(&ipv6_buf->destaddr) != NULL)){ + if((lowpan_context_lookup(&ipv6_buf->srcaddr) != NULL) || + (lowpan_context_lookup(&ipv6_buf->destaddr) != NULL)) { lowpan_iphc[1] |= LOWPAN_IPHC_CID; - memmove(&ipv6_hdr_fields[1],&ipv6_hdr_fields[0], hdr_pos); + memmove(&ipv6_hdr_fields[1], &ipv6_hdr_fields[0], hdr_pos); hdr_pos++; } /* SAC: Source Address Compression */ - if(ipv6_addr_unspec_match(&(ipv6_buf->srcaddr))){ + if(ipv6_addr_unspec_match(&(ipv6_buf->srcaddr))) { /* SAC = 1 and SAM = 00 */ lowpan_iphc[1] |= LOWPAN_IPHC_SAC; - } else if((con = lowpan_context_lookup(&ipv6_buf->srcaddr)) != NULL) { + } + else if((con = lowpan_context_lookup(&ipv6_buf->srcaddr)) != NULL) { /* 1: Source address compression uses stateful, context-based * compression. */ lowpan_iphc[1] |= LOWPAN_IPHC_SAC; ipv6_hdr_fields[0] |= (con->num << 4); - - if(memcmp(&(ipv6_buf->srcaddr.uint8[8]),&(iface.laddr.uint8[0]), 8) == 0){ + + if(memcmp(&(ipv6_buf->srcaddr.uint8[8]), &(iface.laddr.uint8[0]), 8) == 0) { /* 0 bits. The address is derived using context information * and possibly the link-layer addresses.*/ lowpan_iphc[1] |= 0x30; - } else if((ipv6_buf->srcaddr.uint16[4] == 0) && - (ipv6_buf->srcaddr.uint16[5] == 0) && - (ipv6_buf->srcaddr.uint16[6] == 0) && - ((ipv6_buf->srcaddr.uint8[14]) & 0x80) == 0){ + } + else if((ipv6_buf->srcaddr.uint16[4] == 0) && + (ipv6_buf->srcaddr.uint16[5] == 0) && + (ipv6_buf->srcaddr.uint16[6] == 0) && + ((ipv6_buf->srcaddr.uint8[14]) & 0x80) == 0) { /* 49-bit of interface identifier are 0, so we can compress * source address-iid to 16-bit */ memcpy(&ipv6_hdr_fields[hdr_pos], &ipv6_buf->srcaddr.uint16[7], 2); @@ -788,23 +826,26 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra, /* 16 bits. The address is derived using context information * and the 16 bits carried inline. */ lowpan_iphc[1] |= 0x20; - } else { - memcpy(&ipv6_hdr_fields[hdr_pos], &(ipv6_buf->srcaddr.uint16[4]),8); + } + else { + memcpy(&ipv6_hdr_fields[hdr_pos], &(ipv6_buf->srcaddr.uint16[4]), 8); hdr_pos += 8; /* 64 bits. The address is derived using context information - * and the 64 bits carried inline. */ + * and the 64 bits carried inline. */ lowpan_iphc[1] |= 0x10; - } - } else if(ipv6_prefix_ll_match(&ipv6_buf->srcaddr)){ + } + } + else if(ipv6_prefix_ll_match(&ipv6_buf->srcaddr)) { /* 0: Source address compression uses stateless compression.*/ - if(memcmp(&(ipv6_buf->srcaddr.uint8[8]),&(iface.laddr.uint8[0]), 8) == 0){ + if(memcmp(&(ipv6_buf->srcaddr.uint8[8]), &(iface.laddr.uint8[0]), 8) == 0) { /* 0 bits. The address is derived using context information * and possibly the link-layer addresses.*/ lowpan_iphc[1] |= 0x30; - } else if((ipv6_buf->srcaddr.uint16[4] == 0) && - (ipv6_buf->srcaddr.uint16[5] == 0) && - (ipv6_buf->srcaddr.uint16[6] == 0) && - ((ipv6_buf->srcaddr.uint8[14]) & 0x80) == 0){ + } + else if((ipv6_buf->srcaddr.uint16[4] == 0) && + (ipv6_buf->srcaddr.uint16[5] == 0) && + (ipv6_buf->srcaddr.uint16[6] == 0) && + ((ipv6_buf->srcaddr.uint8[14]) & 0x80) == 0) { /* 49-bit of interface identifier are 0, so we can compress * source address-iid to 16-bit */ memcpy(&ipv6_hdr_fields[hdr_pos], &ipv6_buf->srcaddr.uint16[7], 2); @@ -812,54 +853,59 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra, /* 16 bits. The address is derived using context information * and the 16 bits carried inline. */ lowpan_iphc[1] |= 0x20; - } else { - memcpy(&ipv6_hdr_fields[hdr_pos], &(ipv6_buf->srcaddr.uint16[4]),8); + } + else { + memcpy(&ipv6_hdr_fields[hdr_pos], &(ipv6_buf->srcaddr.uint16[4]), 8); hdr_pos += 8; /* 64 bits. The address is derived using context information - * and the 64 bits carried inline. */ + * and the 64 bits carried inline. */ lowpan_iphc[1] |= 0x10; - } - } else { + } + } + else { /* full address carried inline */ memcpy(&ipv6_hdr_fields[hdr_pos], &(ipv6_buf->srcaddr.uint8[0]), 16); hdr_pos += 16; } /* M: Multicast Compression */ - if(ipv6_prefix_mcast_match(&ipv6_buf->destaddr)){ + if(ipv6_prefix_mcast_match(&ipv6_buf->destaddr)) { /* 1: Destination address is a multicast address. */ lowpan_iphc[1] |= LOWPAN_IPHC_M; + /* just another cool if condition */ - if((ipv6_buf->destaddr.uint8[1] == 2) && + if((ipv6_buf->destaddr.uint8[1] == 2) && (ipv6_buf->destaddr.uint16[1] == 0) && (ipv6_buf->destaddr.uint16[2] == 0) && (ipv6_buf->destaddr.uint16[3] == 0) && (ipv6_buf->destaddr.uint16[4] == 0) && (ipv6_buf->destaddr.uint16[5] == 0) && (ipv6_buf->destaddr.uint16[6] == 0) && - (ipv6_buf->destaddr.uint8[14] == 0)){ + (ipv6_buf->destaddr.uint8[14] == 0)) { /* 11: 8 bits. The address takes the form FF02::00XX. */ lowpan_iphc[1] |= 0x03; ipv6_hdr_fields[hdr_pos] = ipv6_buf->destaddr.uint8[15]; hdr_pos++; - } else if((ipv6_buf->destaddr.uint16[1] == 0) && - (ipv6_buf->destaddr.uint16[2] == 0) && - (ipv6_buf->destaddr.uint16[3] == 0) && - (ipv6_buf->destaddr.uint16[4] == 0) && - (ipv6_buf->destaddr.uint16[5] == 0) && - (ipv6_buf->destaddr.uint8[12] == 0)){ + } + else if((ipv6_buf->destaddr.uint16[1] == 0) && + (ipv6_buf->destaddr.uint16[2] == 0) && + (ipv6_buf->destaddr.uint16[3] == 0) && + (ipv6_buf->destaddr.uint16[4] == 0) && + (ipv6_buf->destaddr.uint16[5] == 0) && + (ipv6_buf->destaddr.uint8[12] == 0)) { /* 10: 32 bits. The address takes the form FFXX::00XX:XXXX. */ lowpan_iphc[1] |= 0x02; /* copy second and last 3 byte */ ipv6_hdr_fields[hdr_pos] = ipv6_buf->destaddr.uint8[1]; hdr_pos++; memcpy(&ipv6_hdr_fields[hdr_pos], &ipv6_buf->destaddr.uint8[13], 3); - hdr_pos += 3; - } else if((ipv6_buf->destaddr.uint16[1] == 0) && - (ipv6_buf->destaddr.uint16[2] == 0) && - (ipv6_buf->destaddr.uint16[3] == 0) && - (ipv6_buf->destaddr.uint16[4] == 0) && - (ipv6_buf->destaddr.uint8[10] == 0)){ + hdr_pos += 3; + } + else if((ipv6_buf->destaddr.uint16[1] == 0) && + (ipv6_buf->destaddr.uint16[2] == 0) && + (ipv6_buf->destaddr.uint16[3] == 0) && + (ipv6_buf->destaddr.uint16[4] == 0) && + (ipv6_buf->destaddr.uint8[10] == 0)) { /* 01: 48 bits. The address takes the form FFXX::00XX:XXXX:XXXX */ lowpan_iphc[1] |= 0x01; /* copy second and last 5 byte */ @@ -867,26 +913,29 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra, hdr_pos++; memcpy(&ipv6_hdr_fields[hdr_pos], &ipv6_buf->destaddr.uint8[11], 5); hdr_pos += 5; - } else { + } + else { memcpy(&ipv6_hdr_fields[hdr_pos], &ipv6_buf->destaddr.uint8[0], 16); hdr_pos += 16; - } - } else { + } + } + else { /* 0: Destination address is not a multicast address. */ - if((con = lowpan_context_lookup(&ipv6_buf->destaddr)) != NULL){ + if((con = lowpan_context_lookup(&ipv6_buf->destaddr)) != NULL) { /* 1: Destination address compression uses stateful, context-based * compression. */ lowpan_iphc[1] |= LOWPAN_IPHC_DAC; ipv6_hdr_fields[0] = con->num; - if(memcmp(&(ipv6_buf->destaddr.uint8[8]),&(dest->uint8[0]), 8) == 0){ + if(memcmp(&(ipv6_buf->destaddr.uint8[8]), &(dest->uint8[0]), 8) == 0) { /* 0 bits. The address is derived using context information * and possibly the link-layer addresses.*/ lowpan_iphc[1] |= 0x03; - } else if((ipv6_buf->destaddr.uint16[4] == 0) && - (ipv6_buf->destaddr.uint16[5] == 0) && - (ipv6_buf->destaddr.uint16[6] == 0) && - ((ipv6_buf->destaddr.uint8[14]) & 0x80) == 0){ + } + else if((ipv6_buf->destaddr.uint16[4] == 0) && + (ipv6_buf->destaddr.uint16[5] == 0) && + (ipv6_buf->destaddr.uint16[6] == 0) && + ((ipv6_buf->destaddr.uint8[14]) & 0x80) == 0) { /* 49-bit of interface identifier are 0, so we can compress * source address-iid to 16-bit */ memcpy(&ipv6_hdr_fields[hdr_pos], &ipv6_buf->destaddr.uint16[7], 2); @@ -894,22 +943,25 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra, /* 16 bits. The address is derived using context information * and the 16 bits carried inline. */ lowpan_iphc[1] |= 0x02; - } else { - memcpy(&ipv6_hdr_fields[hdr_pos], &(ipv6_buf->destaddr.uint16[4]),8); + } + else { + memcpy(&ipv6_hdr_fields[hdr_pos], &(ipv6_buf->destaddr.uint16[4]), 8); hdr_pos += 8; /* 64 bits. The address is derived using context information * and the 64 bits carried inline. */ lowpan_iphc[1] |= 0x01; } - } else if(ipv6_prefix_ll_match(&ipv6_buf->destaddr)){ - if(memcmp(&(ipv6_buf->destaddr.uint8[8]),&(dest->uint8[0]), 8) == 0){ + } + else if(ipv6_prefix_ll_match(&ipv6_buf->destaddr)) { + if(memcmp(&(ipv6_buf->destaddr.uint8[8]), &(dest->uint8[0]), 8) == 0) { /* 0 bits. The address is derived using context information * and possibly the link-layer addresses.*/ lowpan_iphc[1] |= 0x03; - } else if((ipv6_buf->destaddr.uint16[4] == 0) && - (ipv6_buf->destaddr.uint16[5] == 0) && - (ipv6_buf->destaddr.uint16[6] == 0) && - ((ipv6_buf->destaddr.uint8[14]) & 0x80) == 0){ + } + else if((ipv6_buf->destaddr.uint16[4] == 0) && + (ipv6_buf->destaddr.uint16[5] == 0) && + (ipv6_buf->destaddr.uint16[6] == 0) && + ((ipv6_buf->destaddr.uint8[14]) & 0x80) == 0) { /* 49-bit of interface identifier are 0, so we can compress * source address-iid to 16-bit */ memcpy(&ipv6_hdr_fields[hdr_pos], &ipv6_buf->destaddr.uint16[7], 2); @@ -917,52 +969,56 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra, /* 16 bits. The address is derived using context information * and the 16 bits carried inline. */ lowpan_iphc[1] |= 0x02; - } else { - memcpy(&ipv6_hdr_fields[hdr_pos], &(ipv6_buf->destaddr.uint16[4]),8); + } + else { + memcpy(&ipv6_hdr_fields[hdr_pos], &(ipv6_buf->destaddr.uint16[4]), 8); hdr_pos += 8; /* 64 bits. The address is derived using context information * and the 64 bits carried inline. */ lowpan_iphc[1] |= 0x01; } - } else { - memcpy(&ipv6_hdr_fields[hdr_pos],&(ipv6_buf->destaddr.uint8[0]), 16); + } + else { + memcpy(&ipv6_hdr_fields[hdr_pos], &(ipv6_buf->destaddr.uint8[0]), 16); hdr_pos += 16; } } - mutex_unlock(&lowpan_context_mutex,0); - + + mutex_unlock(&lowpan_context_mutex, 0); + comp_buf[0] = lowpan_iphc[0]; comp_buf[1] = lowpan_iphc[1]; /*uint8_t *ptr; if (ipv6_buf->nextheader == IPPROTO_TCP) - { + { ptr = get_payload_buf_send(ipv6_ext_hdr_len); - } + } else - { + { ptr = get_payload_buf(ipv6_ext_hdr_len); - } - */ - memcpy(&ipv6_hdr_fields[hdr_pos],&ptr[IPV6_HDR_LEN],ipv6_buf->length); + } + */ + memcpy(&ipv6_hdr_fields[hdr_pos], &ptr[IPV6_HDR_LEN], ipv6_buf->length); comp_len = 2 + hdr_pos + payload_length; } -void lowpan_iphc_decoding(uint8_t *data, uint8_t length, - ieee_802154_long_t *s_laddr, - ieee_802154_long_t *d_laddr){ +void lowpan_iphc_decoding(uint8_t *data, uint8_t length, + ieee_802154_long_t *s_laddr, + ieee_802154_long_t *d_laddr) +{ uint8_t hdr_pos = 0; uint8_t *ipv6_hdr_fields = data; uint8_t lowpan_iphc[2]; uint8_t cid = 0; uint8_t sci = 0; uint8_t dci = 0; - + uint8_t ll_prefix[2] = {0xfe, 0x80}; uint8_t m_prefix[2] = {0xff, 0x02}; lowpan_context_t *con = NULL; - + ipv6_buf = get_ipv6_buf(); lowpan_iphc[0] = ipv6_hdr_fields[0]; @@ -970,138 +1026,156 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length, hdr_pos += 2; /* first check if CID flag is set */ - if(lowpan_iphc[1] & LOWPAN_IPHC_CID){ + if(lowpan_iphc[1] & LOWPAN_IPHC_CID) { hdr_pos++; cid = 1; } /* TF: Traffic Class, Flow Label: */ - if(lowpan_iphc[0] & LOWPAN_IPHC_FL_C){ + if(lowpan_iphc[0] & LOWPAN_IPHC_FL_C) { /* flowlabel is elided */ - if(lowpan_iphc[0] & LOWPAN_IPHC_TC_C){ + if(lowpan_iphc[0] & LOWPAN_IPHC_TC_C) { /* traffic class is elided */ ipv6_buf->version_trafficclass = 0x60; ipv6_buf->trafficclass_flowlabel = 0; - ipv6_buf->flowlabel = 0; - } else { + ipv6_buf->flowlabel = 0; + } + else { /* toogle ecn/dscp order */ - ipv6_buf->version_trafficclass = 0x60 | (0x0f & + ipv6_buf->version_trafficclass = 0x60 | (0x0f & (ipv6_hdr_fields[hdr_pos] >> 2)); ipv6_buf->trafficclass_flowlabel = ((ipv6_hdr_fields[hdr_pos] >> 2) & 0x30) | ((ipv6_hdr_fields[hdr_pos] << 6) & 0xc0); - ipv6_buf->flowlabel = 0; - hdr_pos += 3; + ipv6_buf->flowlabel = 0; + hdr_pos += 3; } - } else { + } + else { /* flowlabel carried inline */ - if(lowpan_iphc[0] & LOWPAN_IPHC_TC_C){ + if(lowpan_iphc[0] & LOWPAN_IPHC_TC_C) { /* traffic class is elided */ ipv6_buf->version_trafficclass = 0x60; /* ecn + 4 bit flowlabel*/ - ipv6_buf->trafficclass_flowlabel = ((ipv6_hdr_fields[hdr_pos] >> 2) & 0x30) | - (ipv6_hdr_fields[hdr_pos] & 0x0f); + ipv6_buf->trafficclass_flowlabel = ((ipv6_hdr_fields[hdr_pos] >> 2) & 0x30) | + (ipv6_hdr_fields[hdr_pos] & 0x0f); hdr_pos++; /* copy 2byte flowlabel */ memcpy(&ipv6_buf->flowlabel, &ipv6_hdr_fields[hdr_pos], 2); - hdr_pos += 2; - } else { + hdr_pos += 2; + } + else { ipv6_buf->version_trafficclass = 0x60 | (0x0f & (ipv6_hdr_fields[hdr_pos] >> 2)); - ipv6_buf->trafficclass_flowlabel = ((ipv6_hdr_fields[hdr_pos] >> 2) & 0x30) | - (ipv6_hdr_fields[hdr_pos] & 0x0f) | - (ipv6_hdr_fields[hdr_pos + 1] & 0x0f); + ipv6_buf->trafficclass_flowlabel = ((ipv6_hdr_fields[hdr_pos] >> 2) & 0x30) | + (ipv6_hdr_fields[hdr_pos] & 0x0f) | + (ipv6_hdr_fields[hdr_pos + 1] & 0x0f); hdr_pos += 2; - memcpy(&ipv6_buf->trafficclass_flowlabel, + memcpy(&ipv6_buf->trafficclass_flowlabel, &ipv6_hdr_fields[hdr_pos], 2); - hdr_pos += 2; + hdr_pos += 2; } } - + /* NH: Next Header: */ - if(lowpan_iphc[0] & LOWPAN_IPHC_NH){ + if(lowpan_iphc[0] & LOWPAN_IPHC_NH) { // TODO: next header decompression - } else { + } + else { ipv6_buf->nextheader = ipv6_hdr_fields[hdr_pos]; hdr_pos++; } /* HLIM: Hop Limit: */ - if(lowpan_iphc[0] & 0x03){ - switch(lowpan_iphc[0] & 0x03){ - case(0x01):{ + if(lowpan_iphc[0] & 0x03) { + switch(lowpan_iphc[0] & 0x03) { + case(0x01): { ipv6_buf->hoplimit = 1; break; } - case(0x02):{ + + case(0x02): { ipv6_buf->hoplimit = 64; break; } - case(0x03):{ + + case(0x03): { ipv6_buf->hoplimit = 255; break; } + default: break; - } - } else { + } + } + else { ipv6_buf->hoplimit = ipv6_hdr_fields[hdr_pos]; hdr_pos++; } - + /* CID: Context Identifier Extension: + SAC: Source Address Compression */ - if(lowpan_iphc[1] & LOWPAN_IPHC_SAC){ + if(lowpan_iphc[1] & LOWPAN_IPHC_SAC) { /* 1: Source address compression uses stateful, context-based * compression.*/ - if(cid){ + if(cid) { sci = ipv6_hdr_fields[3] >> 4; } - + mutex_lock(&lowpan_context_mutex); + /* check context number */ - if(((lowpan_iphc[1] & LOWPAN_IPHC_SAM) >> 4) & 0x03){ - con = lowpan_context_num_lookup(sci); + if(((lowpan_iphc[1] & LOWPAN_IPHC_SAM) >> 4) & 0x03) { + con = lowpan_context_num_lookup(sci); } - if(con == NULL){ + if(con == NULL) { printf("ERROR: context not found\n"); return; } - switch(((lowpan_iphc[1] & LOWPAN_IPHC_SAM) >> 4) & 0x03){ - case(0x01):{ + + switch(((lowpan_iphc[1] & LOWPAN_IPHC_SAM) >> 4) & 0x03) { + case(0x01): { /* 64-bits */ memcpy(&(ipv6_buf->srcaddr.uint8[8]), &ipv6_hdr_fields[hdr_pos], 8); - /* By draft-ietf-6lowpan-hc-15 3.1.1. Bits covered by context information are always used. */ + /* By draft-ietf-6lowpan-hc-15 3.1.1. Bits covered by context + * information are always used. */ memcpy(&(ipv6_buf->srcaddr.uint8[0]), &con->prefix, con->length); hdr_pos += 8; break; } - case(0x02):{ + + case(0x02): { /* 16-bits */ memset(&(ipv6_buf->srcaddr.uint8[8]), 0, 6); memcpy(&(ipv6_buf->srcaddr.uint8[14]), &ipv6_hdr_fields[hdr_pos], 2); - /* By draft-ietf-6lowpan-hc-15 3.1.1. Bits covered by context information are always used. */ + /* By draft-ietf-6lowpan-hc-15 3.1.1. Bits covered by context + * information are always used. */ memcpy(&(ipv6_buf->srcaddr.uint8[0]), &con->prefix, con->length); hdr_pos += 2; break; } - case(0x03):{ + + case(0x03): { /* 0-bits */ memset(&(ipv6_buf->srcaddr.uint8[8]), 0, 8); - memcpy(&(ipv6_buf->srcaddr.uint8[8]), &s_laddr->uint8[0], 8); - /* By draft-ietf-6lowpan-hc-15 3.1.1. Bits covered by context information are always used. */ + memcpy(&(ipv6_buf->srcaddr.uint8[8]), &s_laddr->uint8[0], 8); + /* By draft-ietf-6lowpan-hc-15 3.1.1. Bits covered by context + * information are always used. */ memcpy(&(ipv6_buf->srcaddr.uint8[0]), &con->prefix, con->length); break; } - default:{ + + default: { /* unspecified address */ memset(&(ipv6_buf->srcaddr.uint8[0]), 0, 16); break; } } - mutex_unlock(&lowpan_context_mutex,0); - } else { - switch(((lowpan_iphc[1] & LOWPAN_IPHC_SAM) >> 4) & 0x03){ - case(0x01):{ + + mutex_unlock(&lowpan_context_mutex, 0); + } + else { + switch(((lowpan_iphc[1] & LOWPAN_IPHC_SAM) >> 4) & 0x03) { + case(0x01): { /* 64-bits */ memcpy(&(ipv6_buf->srcaddr.uint8[0]), &ll_prefix[0], 2); memset(&(ipv6_buf->srcaddr.uint8[2]), 0, 6); @@ -1109,7 +1183,8 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length, hdr_pos += 8; break; } - case(0x02):{ + + case(0x02): { /* 16-bits */ memcpy(&(ipv6_buf->srcaddr.uint8[0]), &ll_prefix[0], 2); memset(&(ipv6_buf->srcaddr.uint8[2]), 0, 12); @@ -1117,16 +1192,18 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length, hdr_pos += 2; break; } - case(0x03):{ + + case(0x03): { /* 0-bits */ memcpy(&(ipv6_buf->srcaddr.uint8[0]), &ll_prefix[0], 2); memset(&(ipv6_buf->srcaddr.uint8[8]), 0, 14); memcpy(&(ipv6_buf->srcaddr.uint8[8]), &s_laddr->uint8[0], 8); break; } - default:{ + + default: { /* full address carried inline */ - memcpy(&(ipv6_buf->srcaddr.uint8[0]), + memcpy(&(ipv6_buf->srcaddr.uint8[0]), &ipv6_hdr_fields[hdr_pos], 16); hdr_pos += 16; break; @@ -1135,96 +1212,111 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length, } /* M: Multicast Compression + DAC: Destination Address Compression */ - if(lowpan_iphc[1] & LOWPAN_IPHC_M){ + if(lowpan_iphc[1] & LOWPAN_IPHC_M) { /* 1: Destination address is a multicast address. */ - if(lowpan_iphc[1] & LOWPAN_IPHC_DAC){ + if(lowpan_iphc[1] & LOWPAN_IPHC_DAC) { /* 1: Destination address compression uses stateful, context-based - * compression. - * If M=1 and DAC=1: */ - if(cid){ + * compression. + * If M=1 and DAC=1: */ + if(cid) { dci = ipv6_hdr_fields[3] & 0x0f; } + mutex_lock(&lowpan_context_mutex); - if((lowpan_iphc[1] & LOWPAN_IPHC_DAM) & 0x03){ - con = lowpan_context_num_lookup(dci); + + if((lowpan_iphc[1] & LOWPAN_IPHC_DAM) & 0x03) { + con = lowpan_context_num_lookup(dci); } - if(con == NULL){ + + if(con == NULL) { printf("ERROR: context not found\n"); return; } + // TODO: - mutex_unlock(&lowpan_context_mutex,0); - } else { + mutex_unlock(&lowpan_context_mutex, 0); + } + else { /* If M=1 and DAC=0: */ - switch(lowpan_iphc[1] & 0x03){ - case(0x01):{ + switch(lowpan_iphc[1] & 0x03) { + case(0x01): { m_prefix[1] = ipv6_hdr_fields[hdr_pos]; hdr_pos++; break; } - case(0x02):{ + + case(0x02): { m_prefix[1] = ipv6_hdr_fields[hdr_pos]; hdr_pos++; break; } + default: break; } - - switch(lowpan_iphc[1] & 0x03){ - case(0x01):{ + + switch(lowpan_iphc[1] & 0x03) { + case(0x01): { memcpy(&(ipv6_buf->destaddr.uint8[0]), &m_prefix[0], 2); memset(&(ipv6_buf->destaddr.uint8[2]), 0, 9); memcpy(&(ipv6_buf->destaddr.uint8[11]), &ipv6_hdr_fields[hdr_pos], 5); hdr_pos += 5; break; } - case(0x02):{ + + case(0x02): { memcpy(&(ipv6_buf->destaddr.uint8[0]), &m_prefix[0], 2); memset(&(ipv6_buf->destaddr.uint8[2]), 0, 11); memcpy(&(ipv6_buf->destaddr.uint8[13]), &ipv6_hdr_fields[hdr_pos], 3); hdr_pos += 3; break; } - case(0x03):{ + + case(0x03): { memcpy(&(ipv6_buf->destaddr.uint8[0]), &m_prefix[0], 2); memset(&(ipv6_buf->destaddr.uint8[2]), 0, 13); memcpy(&(ipv6_buf->destaddr.uint8[15]), &ipv6_hdr_fields[hdr_pos], 1); hdr_pos++; break; } - default:{ + + default: { memcpy(&(ipv6_buf->destaddr.uint8[0]), &ipv6_hdr_fields[hdr_pos], 16); break; } - } + } } - } else { - if(lowpan_iphc[1] & LOWPAN_IPHC_DAC){ + } + else { + if(lowpan_iphc[1] & LOWPAN_IPHC_DAC) { /* 1: Destination address compression uses stateful, context-based - * compression. + * compression. * If M=1 and DAC=1: */ - if(cid){ + if(cid) { dci = ipv6_hdr_fields[3] & 0x0f; } + mutex_lock(&lowpan_context_mutex); - if((lowpan_iphc[1] & LOWPAN_IPHC_DAM) & 0x03){ + + if((lowpan_iphc[1] & LOWPAN_IPHC_DAM) & 0x03) { con = lowpan_context_num_lookup(dci); } - if(con == NULL){ + + if(con == NULL) { printf("ERROR: context not found\n"); return; } - - switch((lowpan_iphc[1] & LOWPAN_IPHC_DAM) & 0x03){ - case(0x01):{ + + switch((lowpan_iphc[1] & LOWPAN_IPHC_DAM) & 0x03) { + case(0x01): { memcpy(&(ipv6_buf->destaddr.uint8[8]), &ipv6_hdr_fields[hdr_pos], 8); /* By draft-ietf-6lowpan-hc-15 3.1.1. Bits covered by context information are always used. */ memcpy(&(ipv6_buf->srcaddr.uint8[0]), &con->prefix, con->length); hdr_pos += 8; break; } - case(0x02):{ + + case(0x02): { memset(&(ipv6_buf->destaddr.uint8[8]), 0, 6); memcpy(&(ipv6_buf->destaddr.uint8[14]), &ipv6_hdr_fields[hdr_pos], 2); /* By draft-ietf-6lowpan-hc-15 3.1.1. Bits covered by context information are always used. */ @@ -1232,49 +1324,56 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length, hdr_pos += 2; break; } - case(0x03):{ + + case(0x03): { memset(&(ipv6_buf->destaddr.uint8[0]), 0, 8); memcpy(&(ipv6_buf->destaddr.uint8[8]), &d_laddr->uint8[0], 8); /* By draft-ietf-6lowpan-hc-15 3.1.1. Bits covered by context information are always used. */ memcpy(&(ipv6_buf->srcaddr.uint8[0]), &con->prefix, con->length); break; } + default: break; } - mutex_unlock(&lowpan_context_mutex,0); - } else { - switch((lowpan_iphc[1] & LOWPAN_IPHC_DAM) & 0x03){ - case(0x01):{ + + mutex_unlock(&lowpan_context_mutex, 0); + } + else { + switch((lowpan_iphc[1] & LOWPAN_IPHC_DAM) & 0x03) { + case(0x01): { memcpy(&(ipv6_buf->destaddr.uint8[0]), &ll_prefix[0], 2); memset(&(ipv6_buf->destaddr.uint8[2]), 0, 6); - memcpy(&(ipv6_buf->destaddr.uint8[8]), + memcpy(&(ipv6_buf->destaddr.uint8[8]), &ipv6_hdr_fields[hdr_pos], 8); hdr_pos += 8; break; } - case(0x02):{ + + case(0x02): { memcpy(&(ipv6_buf->destaddr.uint8[0]), &ll_prefix[0], 2); memset(&(ipv6_buf->destaddr.uint8[2]), 0, 12); - memcpy(&(ipv6_buf->destaddr.uint8[14]), + memcpy(&(ipv6_buf->destaddr.uint8[14]), &ipv6_hdr_fields[hdr_pos], 2); hdr_pos += 2; break; } - case(0x03):{ + + case(0x03): { memcpy(&(ipv6_buf->destaddr.uint8[0]), &ll_prefix, 2); memset(&(ipv6_buf->destaddr.uint8[2]), 0, 14); memcpy(&(ipv6_buf->destaddr.uint8[8]), &d_laddr->uint8[0], 8); break; } - default:{ - memcpy(&(ipv6_buf->destaddr.uint8[0]), + + default: { + memcpy(&(ipv6_buf->destaddr.uint8[0]), &ipv6_hdr_fields[hdr_pos], 16); - hdr_pos += 16; + hdr_pos += 16; break; } - } - } + } + } } uint8_t *ptr = get_payload_buf(ipv6_ext_hdr_len); @@ -1283,121 +1382,141 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length, /* ipv6 length */ ipv6_buf->length = length - hdr_pos; - packet_length = IPV6_HDR_LEN + ipv6_buf->length; + packet_length = IPV6_HDR_LEN + ipv6_buf->length; } -uint8_t lowpan_context_len(){ +uint8_t lowpan_context_len() +{ return context_len; } -void lowpan_context_remove(uint8_t num) { - int i,j; - for(i = 0; i < LOWPAN_CONTEXT_MAX; i++){ - if(contexts[i].num == num){ +void lowpan_context_remove(uint8_t num) +{ + int i, j; + + for(i = 0; i < LOWPAN_CONTEXT_MAX; i++) { + if(contexts[i].num == num) { context_len--; break; } } - + abr_remove_context(num); - + for(j = i; j < LOWPAN_CONTEXT_MAX; j++) { - contexts[j] = contexts[j+1]; + contexts[j] = contexts[j + 1]; } } -lowpan_context_t *lowpan_context_update(uint8_t num, const ipv6_addr_t *prefix, - uint8_t length, uint8_t comp, - uint16_t lifetime) { +lowpan_context_t *lowpan_context_update(uint8_t num, const ipv6_addr_t *prefix, + uint8_t length, uint8_t comp, + uint16_t lifetime) +{ lowpan_context_t *context; - - if (lifetime == 0){ + + if(lifetime == 0) { lowpan_context_remove(num); return NULL; } - - if (context_len == LOWPAN_CONTEXT_MAX) + + if(context_len == LOWPAN_CONTEXT_MAX) { return NULL; - + } + context = lowpan_context_num_lookup(num); - - if (context == NULL) { + + if(context == NULL) { context = &(contexts[context_len++]); } - + context->num = num; - memset((void*)(&context->prefix),0,16); + memset((void *)(&context->prefix), 0, 16); // length in bits - memcpy((void*)(&context->prefix),(void*)prefix,length/8); + memcpy((void *)(&context->prefix), (void *)prefix, length / 8); context->length = length; context->comp = comp; context->lifetime = lifetime; return context; } -lowpan_context_t *lowpan_context_get() { +lowpan_context_t *lowpan_context_get() +{ return contexts; } -lowpan_context_t * lowpan_context_lookup(ipv6_addr_t *addr){ +lowpan_context_t *lowpan_context_lookup(ipv6_addr_t *addr) +{ int i; - + lowpan_context_t *context = NULL; - - for(i = 0; i < lowpan_context_len(); i++){ - if(contexts[i].length > 0 && memcmp((void*)addr,&(contexts[i].prefix),contexts[i].length) == 0){ - if (context == NULL || context->length < contexts[i].length) { // longer prefixes are always prefered + + for(i = 0; i < lowpan_context_len(); i++) { + if(contexts[i].length > 0 && memcmp((void *)addr, &(contexts[i].prefix), + contexts[i].length) == 0) { + /* longer prefixes are always prefered */ + if(context == NULL || context->length < contexts[i].length) { context = &contexts[i]; } } } - return context; + + return context; } -lowpan_context_t * lowpan_context_num_lookup(uint8_t num){ +lowpan_context_t *lowpan_context_num_lookup(uint8_t num) +{ int i; - for(i = 0; i < lowpan_context_len(); i++){ - if(contexts[i].num == num){ + + for(i = 0; i < lowpan_context_len(); i++) { + if(contexts[i].num == num) { return &contexts[i]; } } + return NULL; } -void lowpan_context_auto_remove(void) { - timex_t minute = timex_set(60,0); +void lowpan_context_auto_remove(void) +{ + timex_t minute = timex_set(60, 0); int i; int8_t to_remove[LOWPAN_CONTEXT_MAX]; int8_t to_remove_size; - while(1){ + + while(1) { vtimer_sleep(minute); to_remove_size = 0; mutex_lock(&lowpan_context_mutex); + for(i = 0; i < lowpan_context_len(); i++) { - if (--(contexts[i].lifetime) == 0) { + if(--(contexts[i].lifetime) == 0) { to_remove[to_remove_size++] = contexts[i].num; } } + for(i = 0; i < to_remove_size; i++) { lowpan_context_remove(to_remove[i]); } - mutex_unlock(&lowpan_context_mutex,0); + + mutex_unlock(&lowpan_context_mutex, 0); } } -void init_reas_bufs(lowpan_reas_buf_t *buf) { - memset(&buf->s_laddr, 0, SIXLOWPAN_IPV6_LL_ADDR_LEN); - memset(&buf->d_laddr, 0, SIXLOWPAN_IPV6_LL_ADDR_LEN); - buf->ident_no = 0; - buf->timestamp = 0; - buf->packet_size = 0; - buf->current_packet_size = 0; - buf->packet = NULL; - buf->interval_list_head = NULL; - buf->next = NULL; +void init_reas_bufs(lowpan_reas_buf_t *buf) +{ + memset(&buf->s_laddr, 0, SIXLOWPAN_IPV6_LL_ADDR_LEN); + memset(&buf->d_laddr, 0, SIXLOWPAN_IPV6_LL_ADDR_LEN); + buf->ident_no = 0; + buf->timestamp = 0; + buf->packet_size = 0; + buf->current_packet_size = 0; + buf->packet = NULL; + buf->interval_list_head = NULL; + buf->next = NULL; } -void sixlowpan_init(transceiver_type_t trans, uint8_t r_addr, int as_border){ +void sixlowpan_init(transceiver_type_t trans, uint8_t r_addr, int as_border) +{ ipv6_addr_t tmp; /* init mac-layer and radio transceiver */ sixlowmac_init(trans); @@ -1406,13 +1525,13 @@ void sixlowpan_init(transceiver_type_t trans, uint8_t r_addr, int as_border){ rtc_enable(); /* init interface addresses */ - memset(&iface,0,sizeof(iface_t)); - set_radio_address(r_addr); + memset(&iface, 0, sizeof(iface_t)); + set_radio_address(r_addr); init_802154_short_addr(&(iface.saddr)); init_802154_long_addr(&(iface.laddr)); /* init global buffer mutex */ mutex_init(&buf_mutex); - + /* init lowpan context mutex */ mutex_init(&lowpan_context_mutex); @@ -1423,43 +1542,49 @@ void sixlowpan_init(transceiver_type_t trans, uint8_t r_addr, int as_border){ /* init link-local address */ ipv6_set_ll_prefix(&lladdr); - + memcpy(&(lladdr.uint8[8]), &(iface.laddr.uint8[0]), 8); - ipv6_iface_add_addr(&lladdr, ADDR_STATE_PREFERRED, 0, 0, - ADDR_TYPE_LINK_LOCAL); + ipv6_iface_add_addr(&lladdr, ADDR_STATE_PREFERRED, 0, 0, + ADDR_TYPE_LINK_LOCAL); ipv6_set_loaddr(&tmp); - ipv6_iface_add_addr(&tmp, ADDR_STATE_PREFERRED, 0, 0, + ipv6_iface_add_addr(&tmp, ADDR_STATE_PREFERRED, 0, 0, ADDR_TYPE_LOOPBACK); ipv6_set_all_nds_mcast_addr(&tmp); - ipv6_iface_add_addr(&tmp, ADDR_STATE_PREFERRED, 0, 0, + ipv6_iface_add_addr(&tmp, ADDR_STATE_PREFERRED, 0, 0, ADDR_TYPE_LOOPBACK); - - ipv6_iface_add_addr(&lladdr, ADDR_STATE_PREFERRED, 0, 0, + + ipv6_iface_add_addr(&lladdr, ADDR_STATE_PREFERRED, 0, 0, ADDR_CONFIGURED_AUTO); - if (as_border) { - ip_process_pid = thread_create(ip_process_buf, IP_PROCESS_STACKSIZE, - PRIORITY_MAIN-1, CREATE_STACKTEST, - border_process_lowpan, "border_process_lowpan"); - } else { - ip_process_pid = thread_create(ip_process_buf, IP_PROCESS_STACKSIZE, - PRIORITY_MAIN-1, CREATE_STACKTEST, + + if(as_border) { + ip_process_pid = thread_create(ip_process_buf, IP_PROCESS_STACKSIZE, + PRIORITY_MAIN - 1, CREATE_STACKTEST, + border_process_lowpan, + "border_process_lowpan"); + } + else { + ip_process_pid = thread_create(ip_process_buf, IP_PROCESS_STACKSIZE, + PRIORITY_MAIN - 1, CREATE_STACKTEST, ipv6_process, "ip_process"); } + nd_nbr_cache_rem_pid = thread_create(nc_buf, NC_STACKSIZE, - PRIORITY_MAIN-1, CREATE_STACKTEST, + PRIORITY_MAIN - 1, CREATE_STACKTEST, nbr_cache_auto_rem, "nbr_cache_rem"); - contexts_rem_pid = thread_create(con_buf, CON_STACKSIZE, - PRIORITY_MAIN+1, CREATE_STACKTEST, + contexts_rem_pid = thread_create(con_buf, CON_STACKSIZE, + PRIORITY_MAIN + 1, CREATE_STACKTEST, lowpan_context_auto_remove, "lowpan_context_rem"); transfer_pid = thread_create(lowpan_transfer_buf, LOWPAN_TRANSFER_BUF_STACKSIZE, - PRIORITY_MAIN-1, CREATE_STACKTEST, - lowpan_transfer, "lowpan_transfer"); + PRIORITY_MAIN - 1, CREATE_STACKTEST, + lowpan_transfer, "lowpan_transfer"); } -void sixlowpan_adhoc_init(transceiver_type_t trans, ipv6_addr_t *prefix, uint8_t r_addr){ +void sixlowpan_adhoc_init(transceiver_type_t trans, ipv6_addr_t *prefix, + uint8_t r_addr) +{ /* init network prefix */ ipv6_set_prefix(prefix, prefix); - plist_add(prefix, 64, OPT_PI_VLIFETIME_INFINITE,0,1,OPT_PI_FLAG_A); + plist_add(prefix, 64, OPT_PI_VLIFETIME_INFINITE, 0, 1, OPT_PI_FLAG_A); ipv6_init_iface_as_router(); - sixlowpan_init(trans, r_addr,0); + sixlowpan_init(trans, r_addr, 0); } diff --git a/sys/net/sixlowpan/sixlowpan.h b/sys/net/sixlowpan/sixlowpan.h index e8f9650777..76eb95886e 100644 --- a/sys/net/sixlowpan/sixlowpan.h +++ b/sys/net/sixlowpan/sixlowpan.h @@ -1,10 +1,30 @@ +/* + * 6lowpan constants, data structs, and prototypes + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup sixlowpan + * @{ + * @file sixlowpan.h + * @brief 6lowpan header + * @author Stephan Zeisberg + * @author Martin Lenders + * @author Oliver Gesch + * @author Eric Engel + * @} + */ + #ifndef SIXLOWPAN_H #define SIXLOWPAN_H -#define IP_PROCESS_STACKSIZE 3072 -#define NC_STACKSIZE 512 -#define CON_STACKSIZE 512 -#define LOWPAN_TRANSFER_BUF_STACKSIZE 512 +#define IP_PROCESS_STACKSIZE 3072 +#define NC_STACKSIZE 512 +#define CON_STACKSIZE 512 +#define LOWPAN_TRANSFER_BUF_STACKSIZE 512 /* fragment size in bytes*/ #define FRAG_PART_ONE_HDR_LEN 4 @@ -23,7 +43,7 @@ #define LOWPAN_IPV6_DISPATCH 0x41 #define LOWPAN_CONTEXT_MAX 16 -#define LOWPAN_REAS_BUF_TIMEOUT 15 * 1000 * 1000 // TODO: Set back to 3 * 1000 * 1000 +#define LOWPAN_REAS_BUF_TIMEOUT 15 * 1000 * 1000 /* TODO: Set back to 3 * 1000 * 1000 */ #include "transceiver.h" #include "sixlowip.h" @@ -44,43 +64,53 @@ typedef struct lowpan_context_t { } lowpan_context_t; typedef struct lowpan_interval_list_t { - uint8_t start; - uint8_t end; - struct lowpan_interval_list_t *next; + uint8_t start; + uint8_t end; + struct lowpan_interval_list_t *next; } lowpan_interval_list_t; typedef struct lowpan_reas_buf_t { - ieee_802154_long_t s_laddr; // Source Address - ieee_802154_long_t d_laddr; // Destination Address - uint16_t ident_no; // Identification Number - long timestamp; // Timestamp of last packet fragment - uint16_t packet_size; // Size of reassembled packet with possible IPHC header - uint16_t current_packet_size; // Additive size of currently already received fragments - uint8_t *packet; // Pointer to allocated memory for reassembled packet + 6LoWPAN Dispatch Byte - lowpan_interval_list_t *interval_list_head; // Pointer to list of intervals of received packet fragments (if any) - struct lowpan_reas_buf_t *next; // Pointer to next reassembly buffer (if any) + /* Source Address */ + ieee_802154_long_t s_laddr; + /* Destination Address */ + ieee_802154_long_t d_laddr; + /* Identification Number */ + uint16_t ident_no; + /* Timestamp of last packet fragment */ + long timestamp; + /* Size of reassembled packet with possible IPHC header */ + uint16_t packet_size; + /* Additive size of currently already received fragments */ + uint16_t current_packet_size; + /* Pointer to allocated memory for reassembled packet + 6LoWPAN Dispatch Byte */ + uint8_t *packet; + /* Pointer to list of intervals of received packet fragments (if any) */ + lowpan_interval_list_t *interval_list_head; + /* Pointer to next reassembly buffer (if any) */ + struct lowpan_reas_buf_t *next; } lowpan_reas_buf_t; extern lowpan_reas_buf_t *head; void sixlowpan_init(transceiver_type_t trans, uint8_t r_addr, int as_border); -void sixlowpan_adhoc_init(transceiver_type_t trans, ipv6_addr_t *prefix, uint8_t r_addr); +void sixlowpan_adhoc_init(transceiver_type_t trans, ipv6_addr_t *prefix, + uint8_t r_addr); void lowpan_init(ieee_802154_long_t *addr, uint8_t *data); void lowpan_read(uint8_t *data, uint8_t length, ieee_802154_long_t *s_laddr, - ieee_802154_long_t *d_laddr); -void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra, uint8_t * ptr); + ieee_802154_long_t *d_laddr); +void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra, uint8_t *ptr); void lowpan_iphc_decoding(uint8_t *data, uint8_t length, ieee_802154_long_t *s_laddr, ieee_802154_long_t *d_laddr); uint8_t lowpan_context_len(void); void add_fifo_packet(lowpan_reas_buf_t *current_packet); -lowpan_context_t * lowpan_context_update( - uint8_t num, const ipv6_addr_t *prefix, - uint8_t length, uint8_t comp, - uint16_t lifetime); -lowpan_context_t * lowpan_context_get(void); -lowpan_context_t * lowpan_context_lookup(ipv6_addr_t *addr); -lowpan_context_t * lowpan_context_num_lookup(uint8_t num); +lowpan_context_t *lowpan_context_update( + uint8_t num, const ipv6_addr_t *prefix, + uint8_t length, uint8_t comp, + uint16_t lifetime); +lowpan_context_t *lowpan_context_get(void); +lowpan_context_t *lowpan_context_lookup(ipv6_addr_t *addr); +lowpan_context_t *lowpan_context_num_lookup(uint8_t num); lowpan_reas_buf_t *collect_garbage_fifo(lowpan_reas_buf_t *current_buf); lowpan_reas_buf_t *collect_garbage(lowpan_reas_buf_t *current_buf); void check_timeout(void); diff --git a/sys/posix/posix_io.c b/sys/posix/posix_io.c index 794701e14f..d10ef6a821 100644 --- a/sys/posix/posix_io.c +++ b/sys/posix/posix_io.c @@ -1,5 +1,5 @@ /** - * POSIX implementation of basic IO operations. + * POSIX implementation of basic IO operations. * * Copyright (C) 2013, INRIA. * @@ -10,7 +10,7 @@ * @ingroup posix * @{ * @file posix_io.c - * @brief Implementation of basic POSIX IO functionality. + * @brief Implementation of basic POSIX IO functionality. * @author Kaspar Schleiser * @} */ @@ -21,7 +21,8 @@ #include -static int _posix_fileop(int pid, int op, int flags) { +static int _posix_fileop(int pid, int op, int flags) +{ msg_t m; m.type = op; m.content.value = flags; @@ -29,32 +30,37 @@ static int _posix_fileop(int pid, int op, int flags) { return m.content.value; } -static int _posix_fileop_data(int pid, int op, char* buffer, int nbytes) { +static int _posix_fileop_data(int pid, int op, char *buffer, int nbytes) +{ struct posix_iop_t r; r.nbytes = nbytes; r.buffer = buffer; msg_t m; m.type = op; - m.content.ptr = (char*) &r; + m.content.ptr = (char *) &r; msg_send_receive(&m, &m, pid); return r.nbytes; } -int posix_open(int pid, int flags) { - return _posix_fileop(pid, OPEN, flags); +int posix_open(int pid, int flags) +{ + return _posix_fileop(pid, OPEN, flags); } -int posix_close(int pid) { - return _posix_fileop(pid, CLOSE, 0); +int posix_close(int pid) +{ + return _posix_fileop(pid, CLOSE, 0); } -int posix_read(int pid, char* buffer, int bufsize) { +int posix_read(int pid, char *buffer, int bufsize) +{ return _posix_fileop_data(pid, READ, buffer, bufsize); } -int posix_write(int pid, char* buffer, int bufsize) { +int posix_write(int pid, char *buffer, int bufsize) +{ return _posix_fileop_data(pid, WRITE, buffer, bufsize); } diff --git a/sys/ps/ps.c b/sys/ps/ps.c index 5f21dab26a..cd2756a0eb 100644 --- a/sys/ps/ps.c +++ b/sys/ps/ps.c @@ -1,5 +1,5 @@ /** - * Print thread information. + * Print thread information. * * Copyright (C) 2013, INRIA. * @@ -10,7 +10,7 @@ * @ingroup ps * @{ * @file ps.c - * @brief UNIX like ps command + * @brief UNIX like ps command * @author Kaspar Schleiser * @} */ @@ -22,7 +22,7 @@ #include /* list of states copied from tcb.h */ -const char *state_names[] = { +const char *state_names[] = { "running", "pending", "stopped", @@ -36,23 +36,25 @@ const char *state_names[] = { /** * @brief Prints a list of running threads including stack usage to stdout. */ -void thread_print_all(void) { +void thread_print_all(void) +{ extern unsigned long hwtimer_now(void); const char queued_name[] = {'_', 'Q'}; int i; int overall_stacksz = 0; printf("\tpid | %-21s| %-9sQ | pri | stack ( used) location | runtime | switches \n", "name", "state"); - for( i = 0; i < MAXTHREADS; i++ ) { - tcb_t* p = (tcb_t*)sched_threads[i]; - if( p != NULL ) { + for(i = 0; i < MAXTHREADS; i++) { + tcb_t *p = (tcb_t *)sched_threads[i]; + + if(p != NULL) { int state = p->status; // copy state int statebit = number_of_highest_bit(state >> 1); // get state index - const char* sname = state_names[statebit]; // get state name - const char* queued = queued_name + (state & BIT0); // get queued flag + const char *sname = state_names[statebit]; // get state name + const char *queued = queued_name + (state & BIT0); // get queued flag int stacksz = p->stack_size; // get max used stack - double runtime = 0/0.0; + double runtime = 0 / 0.0; int switches = -1; #if SCHEDSTATISTICS runtime = pidlist[i].runtime / (double) hwtimer_now() * 100; @@ -61,8 +63,9 @@ void thread_print_all(void) { overall_stacksz += stacksz; stacksz -= thread_measure_stack_usage(p->stack_start); printf("\t%3u | %-21s| %-8s %.1s | %3i | %5i (%5i) %p | %6.3f%% | %8i\n", - p->pid, p->name, sname, queued, p->priority, p->stack_size, stacksz, p->stack_start, runtime, switches); + p->pid, p->name, sname, queued, p->priority, p->stack_size, stacksz, p->stack_start, runtime, switches); } } + printf("\t%5s %-21s|%13s%6s %5i\n", "|", "SUM", "|", "|", overall_stacksz); } diff --git a/sys/shell/commands/sc_cc1100.c b/sys/shell/commands/sc_cc1100.c index 23530c7fea..d7334275de 100644 --- a/sys/shell/commands/sc_cc1100.c +++ b/sys/shell/commands/sc_cc1100.c @@ -1,3 +1,20 @@ +/** + * Shell commands for cc110x driver + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup shell_commands + * @{ + * @file sc_cc1100.c + * @brief provides shell commands to configure cc110x driver + * @author Oliver Hahm + * @} + */ + #include #include #include @@ -14,43 +31,50 @@ char text_msg[TEXT_SIZE]; msg_t mesg; transceiver_command_t tcmd; -void _cc1100_get_set_address_handler(char *addr) { +void _cc1100_get_set_address_handler(char *addr) +{ int16_t a; tcmd.transceivers = TRANSCEIVER_CC1100; tcmd.data = &a; - mesg.content.ptr = (char*) &tcmd; - a = atoi(addr+5); - if (strlen(addr) > 5) { + mesg.content.ptr = (char *) &tcmd; + a = atoi(addr + 5); + + if(strlen(addr) > 5) { printf("[cc110x] Trying to set address %i\n", a); mesg.type = SET_ADDRESS; } else { mesg.type = GET_ADDRESS; } + msg_send_receive(&mesg, &mesg, transceiver_pid); printf("[cc110x] Got address: %i\n", a); } -void _cc1100_get_set_channel_handler(char *chan) { +void _cc1100_get_set_channel_handler(char *chan) +{ int16_t c; tcmd.transceivers = TRANSCEIVER_CC1100; tcmd.data = &c; - mesg.content.ptr = (char*) &tcmd; - c = atoi(chan+5); - if (strlen(chan) > 5) { + mesg.content.ptr = (char *) &tcmd; + c = atoi(chan + 5); + + if(strlen(chan) > 5) { printf("[cc110x] Trying to set channel %i\n", c); mesg.type = SET_CHANNEL; } else { mesg.type = GET_CHANNEL; } + msg_send_receive(&mesg, &mesg, transceiver_pid); printf("[cc110x] Got channel: %i\n", c); } -void _cc1100_send_handler(char *pkt) { +void _cc1100_send_handler(char *pkt) +{ radio_packet_t p; uint32_t response; uint16_t addr; @@ -59,40 +83,47 @@ void _cc1100_send_handler(char *pkt) { tcmd.transceivers = TRANSCEIVER_CC1100; tcmd.data = &p; - tok = strtok(pkt+7, " "); - if (tok) { + tok = strtok(pkt + 7, " "); + + if(tok) { addr = atoi(tok); tok = strtok(NULL, " "); - if (tok) { + + if(tok) { memset(text_msg, 0, TEXT_SIZE); memcpy(text_msg, tok, strlen(tok)); /* if (sscanf(pkt, "txtsnd %hu %s", &(addr), text_msg) == 2) {*/ - p.data = (uint8_t*) text_msg; + p.data = (uint8_t *) text_msg; p.length = strlen(text_msg) + 1; p.dst = addr; mesg.type = SND_PKT; - mesg.content.ptr = (char*) &tcmd; - printf("[cc110x] Sending packet of length %u to %hu: %s\n", p.length, p.dst, (char*) p.data); + mesg.content.ptr = (char *) &tcmd; + printf("[cc110x] Sending packet of length %u to %hu: %s\n", p.length, p.dst, (char *) p.data); msg_send_receive(&mesg, &mesg, transceiver_pid); response = mesg.content.value; printf("[cc110x] Packet sent: %lu\n", response); return; } } - puts("Usage:\ttxtsnd "); + + puts("Usage:\ttxtsnd "); } #else -void _cc110x_get_set_address_handler(char *addr) { +void _cc110x_get_set_address_handler(char *addr) +{ int16_t a; - a = atoi(addr+5); - if (strlen(addr) > 5) { + a = atoi(addr + 5); + + if(strlen(addr) > 5) { printf("[cc110x] Setting address %i ... ", a); cc1100_set_address((radio_address_t)a); - if (cc1100_get_address() == (radio_address_t)a) { + + if(cc1100_get_address() == (radio_address_t)a) { puts("[OK]"); - } else { + } + else { puts("Error!"); } } @@ -101,16 +132,20 @@ void _cc110x_get_set_address_handler(char *addr) { } } -void _cc110x_get_set_channel_handler(char *addr) { +void _cc110x_get_set_channel_handler(char *addr) +{ int16_t a; - a = atoi(addr+5); - if (strlen(addr) > 5) { + a = atoi(addr + 5); + + if(strlen(addr) > 5) { printf("[cc110x] Setting channel %i...", a); cc1100_set_channel(a); - if (cc1100_get_channel() == a) { + + if(cc1100_get_channel() == a) { puts("OK"); - } else { + } + else { puts("Error!"); } } diff --git a/sys/shell/commands/sc_cc110x_ng.c b/sys/shell/commands/sc_cc110x_ng.c index 356db3f3a0..4273a90864 100644 --- a/sys/shell/commands/sc_cc110x_ng.c +++ b/sys/shell/commands/sc_cc110x_ng.c @@ -1,3 +1,20 @@ +/** + * Shell commands for cc110x_ng driver + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup shell_commands + * @{ + * @file sc_cc110x_ng.c + * @brief provides shell commands to configure cc110x_ng driver + * @author Oliver Hahm + * @} + */ + #include #include #include @@ -12,43 +29,50 @@ char text_msg[TEXT_SIZE]; msg_t mesg; transceiver_command_t tcmd; -void _cc110x_ng_get_set_address_handler(char *addr) { +void _cc110x_ng_get_set_address_handler(char *addr) +{ int16_t a; tcmd.transceivers = TRANSCEIVER_CC1100; tcmd.data = &a; - mesg.content.ptr = (char*) &tcmd; - a = atoi(addr+5); - if (strlen(addr) > 5) { + mesg.content.ptr = (char *) &tcmd; + a = atoi(addr + 5); + + if(strlen(addr) > 5) { printf("[cc110x] Trying to set address %i\n", a); mesg.type = SET_ADDRESS; } else { mesg.type = GET_ADDRESS; } + msg_send_receive(&mesg, &mesg, transceiver_pid); printf("[cc110x] Got address: %i\n", a); } -void _cc110x_ng_get_set_channel_handler(char *chan) { +void _cc110x_ng_get_set_channel_handler(char *chan) +{ int16_t c; tcmd.transceivers = TRANSCEIVER_CC1100; tcmd.data = &c; - mesg.content.ptr = (char*) &tcmd; - c = atoi(chan+5); - if (strlen(chan) > 5) { + mesg.content.ptr = (char *) &tcmd; + c = atoi(chan + 5); + + if(strlen(chan) > 5) { printf("[cc110x] Trying to set channel %i\n", c); mesg.type = SET_CHANNEL; } else { mesg.type = GET_CHANNEL; } + msg_send_receive(&mesg, &mesg, transceiver_pid); printf("[cc110x] Got channel: %i\n", c); } -void _cc110x_ng_send_handler(char *pkt) { +void _cc110x_ng_send_handler(char *pkt) +{ radio_packet_t p; uint32_t response; uint16_t addr; @@ -57,37 +81,41 @@ void _cc110x_ng_send_handler(char *pkt) { tcmd.transceivers = TRANSCEIVER_CC1100; tcmd.data = &p; - tok = strtok(pkt+7, " "); - if (tok) { + tok = strtok(pkt + 7, " "); + + if(tok) { addr = atoi(tok); tok = strtok(NULL, " "); - if (tok) { + + if(tok) { memset(text_msg, 0, TEXT_SIZE); memcpy(text_msg, tok, strlen(tok)); - /* if (sscanf(pkt, "txtsnd %hu %s", &(addr), text_msg) == 2) {*/ - p.data = (uint8_t*) text_msg; + p.data = (uint8_t *) text_msg; p.length = strlen(text_msg) + 1; p.dst = addr; mesg.type = SND_PKT; - mesg.content.ptr = (char*) &tcmd; - printf("[cc110x] Sending packet of length %u to %hu: %s\n", p.length, p.dst, (char*) p.data); + mesg.content.ptr = (char *) &tcmd; + printf("[cc110x] Sending packet of length %u to %hu: %s\n", p.length, p.dst, (char *) p.data); msg_send_receive(&mesg, &mesg, transceiver_pid); response = mesg.content.value; printf("[cc110x] Packet sent: %" PRIu32 "\n", response); return; } } + puts("Usage:\ttxtsnd "); } -void _cc110x_ng_monitor_handler(char *mode) { +void _cc110x_ng_monitor_handler(char *mode) +{ unsigned int m; tcmd.transceivers = TRANSCEIVER_CC1100; tcmd.data = &m; - mesg.content.ptr = (char*) &tcmd; - m = atoi(mode+8); - if (strlen(mode) > 8) { + mesg.content.ptr = (char *) &tcmd; + m = atoi(mode + 8); + + if(strlen(mode) > 8) { printf("Setting monitor mode: %u\n", m); mesg.type = SET_MONITOR; msg_send(&mesg, transceiver_pid, 1); diff --git a/sys/shell/commands/sc_disk.c b/sys/shell/commands/sc_disk.c index 8d6a830f87..4e6ca8b466 100644 --- a/sys/shell/commands/sc_disk.c +++ b/sys/shell/commands/sc_disk.c @@ -1,3 +1,20 @@ +/** + * Shell commands for accessing storage + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup shell_commands + * @{ + * @file sc_disk.c + * @brief provides shell commands to access storage (like mmc) + * @author Oliver Hahm + * @} + */ + #include #include #include @@ -5,25 +22,33 @@ #include "shell_commands.h" #include "diskio.h" -static inline uint8_t sector_read(unsigned char *read_buf, unsigned long sector, unsigned long length, unsigned long offset) { +static inline uint8_t sector_read(unsigned char *read_buf, unsigned long sector, unsigned long length, unsigned long offset) +{ unsigned long i; - if (MCI_read(read_buf, sector, 1) == RES_OK) { + + if(MCI_read(read_buf, sector, 1) == RES_OK) { printf("[disk] Read sector %lu (%lu):\n", sector, offset); - for (i = offset + 1; i <= offset + length; i++) { - printf(" %u", read_buf[i-1]); - if (!(i % 16)) { + + for(i = offset + 1; i <= offset + length; i++) { + printf(" %u", read_buf[i - 1]); + + if(!(i % 16)) { puts(""); } } + puts(""); return 1; } + return 0; } -void _get_sectorsize(char *unused) { +void _get_sectorsize(char *unused) +{ unsigned short ssize; - if (MCI_ioctl(GET_SECTOR_SIZE, &ssize) == RES_OK) { + + if(MCI_ioctl(GET_SECTOR_SIZE, &ssize) == RES_OK) { printf("[disk] sector size is %u\n", ssize); } else { @@ -31,9 +56,11 @@ void _get_sectorsize(char *unused) { } } -void _get_blocksize(char *unused) { +void _get_blocksize(char *unused) +{ unsigned long bsize; - if (MCI_ioctl(GET_BLOCK_SIZE, &bsize) == RES_OK) { + + if(MCI_ioctl(GET_BLOCK_SIZE, &bsize) == RES_OK) { printf("[disk] block size is %lu\n", bsize); } else { @@ -41,9 +68,11 @@ void _get_blocksize(char *unused) { } } -void _get_sectorcount(char *unused) { +void _get_sectorcount(char *unused) +{ unsigned long scount; - if (MCI_ioctl(GET_SECTOR_COUNT, &scount) == RES_OK) { + + if(MCI_ioctl(GET_SECTOR_COUNT, &scount) == RES_OK) { printf("[disk] sector count is %lu\n", scount); } else { @@ -51,19 +80,23 @@ void _get_sectorcount(char *unused) { } } -void _read_sector(char *sector) { +void _read_sector(char *sector) +{ unsigned long sectornr, scount; unsigned short ssize; - if (strlen(sector) > strlen(DISK_READ_SECTOR_CMD) + 1) { + if(strlen(sector) > strlen(DISK_READ_SECTOR_CMD) + 1) { sectornr = atol(sector + strlen(DISK_READ_SECTOR_CMD) + 1); - if ((MCI_ioctl(GET_SECTOR_COUNT, &scount) == RES_OK) && (MCI_ioctl(GET_SECTOR_SIZE, &ssize) == RES_OK)) { + + if((MCI_ioctl(GET_SECTOR_COUNT, &scount) == RES_OK) && (MCI_ioctl(GET_SECTOR_SIZE, &ssize) == RES_OK)) { unsigned char read_buf[ssize]; - if (sector_read(read_buf, sectornr, ssize, 0)) { - return; + + if(sector_read(read_buf, sectornr, ssize, 0)) { + return; } } + printf("[disk] Error while reading sector %lu\n", sectornr); } else { @@ -72,33 +105,39 @@ void _read_sector(char *sector) { } } -void _read_bytes(char *bytes) { +void _read_bytes(char *bytes) +{ unsigned long sector = 1, scount, offset; unsigned short ssize, length; char *tok; /* tokenize user input */ tok = strtok(bytes + strlen(DISK_READ_BYTES_CMD) + 1, " "); - if (tok) { + + if(tok) { offset = atol(tok); tok = strtok(NULL, " "); - if (tok) { + + if(tok) { length = atoi(tok); - if (length) { + + if(length) { /* get card info */ - if ((MCI_ioctl(GET_SECTOR_COUNT, &scount) == RES_OK) && (MCI_ioctl(GET_SECTOR_SIZE, &ssize) == RES_OK)) { + if((MCI_ioctl(GET_SECTOR_COUNT, &scount) == RES_OK) && (MCI_ioctl(GET_SECTOR_SIZE, &ssize) == RES_OK)) { /* calculate sector and offset position */ sector = (offset / ssize) + 1; offset = (offset % ssize); /* preapre buffer (size must be a multiple of sector size) */ unsigned char read_buf[((length / ssize) + 1) * 512]; + /* read from several sectors */ - if (length > (ssize - offset)) { + if(length > (ssize - offset)) { /* buffer offset */ unsigned long j = 0; /* chunk from current sector */ unsigned short tmp = ssize - offset; - while (length) { + + while(length) { sector_read(read_buf + j, sector++, tmp, offset); /* decrease length and recalculate chunk */ length -= tmp; @@ -109,15 +148,17 @@ void _read_bytes(char *bytes) { } /* length > (ssize - offset) */ /* read only one sector */ else { - if (sector_read(read_buf, sector, length, offset)) { + if(sector_read(read_buf, sector, length, offset)) { return; } } /* length < (ssize - offset) */ } /* ioctl */ + printf("[disk] Error while reading sector %lu\n", sector); return; } /* length */ } /* strtok #2 */ } /* strtok #1 */ + printf("[disk] Usage:\n%s \n", DISK_READ_BYTES_CMD); } diff --git a/sys/shell/commands/sc_id.c b/sys/shell/commands/sc_id.c index 3807484ff3..330c1fdaff 100644 --- a/sys/shell/commands/sc_id.c +++ b/sys/shell/commands/sc_id.c @@ -1,13 +1,32 @@ +/** + * Shell commands for configuring the node id + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup shell_commands + * @{ + * @file sc_id.c + * @brief provides shell commands to configure node id + * @author Oliver Hahm + * @} + */ + #include #include #include #include -void _id_handler(char *id) { +void _id_handler(char *id) +{ long newid; - newid = atoi(id+3); - if (strlen(id) < 3) { + newid = atoi(id + 3); + + if(strlen(id) < 3) { #ifdef MODULE_CONFIG printf("Current id: %u\n", sysconfig.id); #endif @@ -16,9 +35,11 @@ void _id_handler(char *id) { printf("Setting new id %lu\n", newid); #ifdef MODULE_CONFIG sysconfig.id = newid; - if (!config_save()) { + + if(!config_save()) { puts("ERROR setting new id"); } + #endif } } diff --git a/sys/shell/commands/sc_ltc4150.c b/sys/shell/commands/sc_ltc4150.c index c29519c14c..61d69ca7b0 100644 --- a/sys/shell/commands/sc_ltc4150.c +++ b/sys/shell/commands/sc_ltc4150.c @@ -1,10 +1,29 @@ +/** + * Shell commands for coulomb counter + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup shell_commands + * @{ + * @file sc_ltc4150.c + * @brief provides shell commands to access ltc4150 + * @author Oliver Hahm + * @} + */ + #include #include -void _get_current_handler(char* unused) { - printf("Power usage: %.4f mA (%.4f mA avg/ %.4f mAh total / %i usec)\n", ltc4150_get_current_mA(), ltc4150_get_avg_mA(), ltc4150_get_total_mAh(), ltc4150_get_interval()); +void _get_current_handler(char *unused) +{ + printf("Power usage: %.4f mA (%.4f mA avg/ %.4f mAh total / %i usec)\n", ltc4150_get_current_mA(), ltc4150_get_avg_mA(), ltc4150_get_total_mAh(), ltc4150_get_interval()); } -void _reset_current_handler(char* unused) { - ltc4150_start(); +void _reset_current_handler(char *unused) +{ + ltc4150_start(); } diff --git a/sys/shell/commands/sc_ps.c b/sys/shell/commands/sc_ps.c index 2064e32c3d..dc6f1d9589 100644 --- a/sys/shell/commands/sc_ps.c +++ b/sys/shell/commands/sc_ps.c @@ -1,6 +1,24 @@ +/** + * Shell commands for ps + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup shell_commands + * @{ + * @file sc_ps.c + * @brief shows all thread information + * @author Oliver Hahm + * @} + */ + #include "ps.h" -void _ps_handler(char* unnused) { +void _ps_handler(char *unnused) +{ thread_print_all(); } diff --git a/sys/shell/commands/sc_rtc.c b/sys/shell/commands/sc_rtc.c index 74550f81e9..c733542877 100644 --- a/sys/shell/commands/sc_rtc.c +++ b/sys/shell/commands/sc_rtc.c @@ -1,3 +1,20 @@ +/** + * Shell commands for real time clock + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup shell_commands + * @{ + * @file sc_rtc.c + * @brief provides shell commands to access the rtc + * @author Oliver Hahm + * @} + */ + #include #include #include @@ -5,46 +22,49 @@ #ifdef MODULE_RTC #include -void _gettime_handler(void) { +void _gettime_handler(void) +{ struct tm now; rtc_get_localtime(&now); printf("%s", asctime(&now)); } -void _settime_handler(char* c) { +void _settime_handler(char *c) +{ struct tm now; int res; uint16_t month, epoch_year; res = sscanf(c, "date %hu-%hu-%u %u:%u:%u", - &epoch_year, - &month, - (unsigned int*) &(now.tm_mday), - (unsigned int*) &(now.tm_hour), - (unsigned int*) &(now.tm_min), - (unsigned int*) &(now.tm_sec)); - - if (res < 6) { + &epoch_year, + &month, + (unsigned int *) & (now.tm_mday), + (unsigned int *) & (now.tm_hour), + (unsigned int *) & (now.tm_min), + (unsigned int *) & (now.tm_sec)); + + if(res < 6) { printf("Usage: date YYYY-MM-DD hh:mm:ss\n"); return; } else { puts("OK"); } - + now.tm_year = epoch_year - 1900; now.tm_mon = month - 1; rtc_set_localtime(&now); } -void _date_handler(char* c) { - if (strlen(c) == 4) { - _gettime_handler(); - } - else { - _settime_handler(c); - } +void _date_handler(char *c) +{ + if(strlen(c) == 4) { + _gettime_handler(); + } + else { + _settime_handler(c); + } } #endif diff --git a/sys/shell/commands/sc_sht11.c b/sys/shell/commands/sc_sht11.c index 3c2428d56a..7ec209e7d1 100644 --- a/sys/shell/commands/sc_sht11.c +++ b/sys/shell/commands/sc_sht11.c @@ -1,3 +1,20 @@ +/** + * Shell commands for temperature and humidity sensor + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup shell_commands + * @{ + * @file sc_sht11.c + * @brief provides shell commands to poll sht11 sensor + * @author Oliver Hahm + * @} + */ + #include #include #include @@ -8,51 +25,58 @@ extern float sht11_temperature_offset; -void _get_humidity_handler(char* unused) { +void _get_humidity_handler(char *unused) +{ uint8_t success; sht11_val_t sht11_val; - success = sht11_read_sensor(&sht11_val, HUMIDITY|TEMPERATURE); - if (!success) { + success = sht11_read_sensor(&sht11_val, HUMIDITY | TEMPERATURE); + + if(!success) { printf("Error reading SHT11\n"); } else { printf("Relative humidity: %5.2f%% / Temperature compensated humidity; %5.2f%%\n", - (double) sht11_val.relhum, (double) sht11_val.relhum_temp); + (double) sht11_val.relhum, (double) sht11_val.relhum_temp); } } -void _get_temperature_handler(char* unused) { +void _get_temperature_handler(char *unused) +{ uint8_t success; sht11_val_t sht11_val; success = sht11_read_sensor(&sht11_val, TEMPERATURE); - if (!success) { + + if(!success) { printf("Error reading SHT11\n"); } else { printf("Temperature: %-6.2f°C\n", (double) sht11_val.temperature); } } -void _get_weather_handler(char* unused) { +void _get_weather_handler(char *unused) +{ uint8_t success; sht11_val_t sht11_val; - success = sht11_read_sensor(&sht11_val, HUMIDITY|TEMPERATURE); - if (!success) { + success = sht11_read_sensor(&sht11_val, HUMIDITY | TEMPERATURE); + + if(!success) { printf("Error reading SHT11\n"); } else { printf("Relative humidity: %5.2f%% / Temperature compensated humidity; %5.2f%% ", - (double) sht11_val.relhum, (double) sht11_val.relhum_temp); + (double) sht11_val.relhum, (double) sht11_val.relhum_temp); printf("Temperature: %-6.2f°C\n", (double) sht11_val.temperature); } } -void _set_offset_handler(char* offset) { - if (strlen(offset) == 6) { - puts("Usage: offset "); - } - else { - sht11_temperature_offset = atoi(offset+7); - printf("Temperature offset set to %f\n", (double) sht11_temperature_offset); - } +void _set_offset_handler(char *offset) +{ + if(strlen(offset) == 6) { + puts("Usage: offset "); + } + else { + sht11_temperature_offset = atoi(offset + 7); + printf("Temperature offset set to %f\n", (double) sht11_temperature_offset); + } } #endif diff --git a/sys/shell/commands/shell_commands.c b/sys/shell/commands/shell_commands.c index 037045a288..cfa0bcfa4c 100644 --- a/sys/shell/commands/shell_commands.c +++ b/sys/shell/commands/shell_commands.c @@ -1,26 +1,43 @@ +/** + * Provides prototypes for available shell commands + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup shell_commands + * @{ + * @file shell_commands.c + * @brief sets up the system shell command struct + * @author Oliver Hahm + * @} + */ + #include #include -extern void _id_handler(char* id); +extern void _id_handler(char *id); #ifdef MODULE_PS -extern void _ps_handler(char* unused); +extern void _ps_handler(char *unused); #endif #ifdef MODULE_RTC -extern void _date_handler(char* now); +extern void _date_handler(char *now); #endif #ifdef MODULE_SHT11 -extern void _get_temperature_handler(char* unused); -extern void _get_humidity_handler(char* unused); -extern void _get_weather_handler(char* unused); -extern void _set_offset_handler(char* offset); +extern void _get_temperature_handler(char *unused); +extern void _get_humidity_handler(char *unused); +extern void _get_weather_handler(char *unused); +extern void _set_offset_handler(char *offset); #endif #ifdef MODULE_LTC4150 -extern void _get_current_handler(char* unused); -extern void _reset_current_handler(char* unused); +extern void _get_current_handler(char *unused); +extern void _reset_current_handler(char *unused); #endif #ifdef MODULE_CC110X @@ -45,10 +62,10 @@ extern void _cc110x_ng_monitor_handler(char *mode); #ifdef MODULE_MCI extern void _get_sectorsize(char *unused); -extern void _get_blocksize(char* unused); -extern void _get_sectorcount(char* unused); -extern void _read_sector(char* sector); -extern void _read_bytes(char* bytes); +extern void _get_blocksize(char *unused); +extern void _get_sectorcount(char *unused); +extern void _read_sector(char *sector); +extern void _read_bytes(char *bytes); #endif const shell_command_t _shell_command_list[] = { @@ -63,11 +80,11 @@ const shell_command_t _shell_command_list[] = { {"temp", "Prints measured temperature.", _get_temperature_handler}, {"hum", "Prints measured humidity.", _get_humidity_handler}, {"weather", "Prints measured humidity and temperature.", _get_weather_handler}, - {"offset", "Set temperature offset.", _set_offset_handler}, + {"offset", "Set temperature offset.", _set_offset_handler}, #endif #ifdef MODULE_LTC4150 - {"cur", "Prints current and average power consumption.", _get_current_handler}, - {"rstcur", "Resets coulomb counter.", _reset_current_handler}, + {"cur", "Prints current and average power consumption.", _get_current_handler}, + {"rstcur", "Resets coulomb counter.", _reset_current_handler}, #endif #ifdef MODULE_CC110X #ifdef MODULE_TRANSCEIVER diff --git a/sys/shell/shell.c b/sys/shell/shell.c index c17908a8c0..63ef711c56 100644 --- a/sys/shell/shell.c +++ b/sys/shell/shell.c @@ -1,28 +1,13 @@ -/****************************************************************************** -Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved. - -These sources were developed at the Freie Universitaet Berlin, Computer Systems -and Telematics group (http://cst.mi.fu-berlin.de). -------------------------------------------------------------------------------- -This file is part of RIOT. - -This program is free software: you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation, either version 3 of the License, or (at your option) any later -version. - -RIOT is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program. If not, see http://www.gnu.org/licenses/ . --------------------------------------------------------------------------------- -For further information and questions please use the web site - http://scatterweb.mi.fu-berlin.de -and the mailinglist (subscription via web site) - scatterweb@lists.spline.inf.fu-berlin.de -*******************************************************************************/ +/** + * Shell interpreter + * + * Copyright (C) 2009, Freie Universitaet Berlin (FUB). + * Copyright (C) 2013, INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + */ /** * @ingroup shell @@ -49,68 +34,81 @@ and the mailinglist (subscription via web site) #include #include -static void(*find_handler(const shell_command_t *command_list, char *command))(char*) { - const shell_command_t* entry = command_list; - if (entry) { - while (entry->name != NULL) { - if ( strcmp(entry->name, command) == 0) { - return entry->handler; - } else { - entry++; - } - } - } - +static void(*find_handler(const shell_command_t *command_list, char *command))(char *) +{ + const shell_command_t *entry = command_list; + + if(entry) { + while(entry->name != NULL) { + if(strcmp(entry->name, command) == 0) { + return entry->handler; + } + else { + entry++; + } + } + } + #ifdef MODULE_SHELL_COMMANDS entry = _shell_command_list; - while (entry->name != NULL) { - if ( strcmp(entry->name, command) == 0) { + + while(entry->name != NULL) { + if(strcmp(entry->name, command) == 0) { return entry->handler; - } else { + } + else { entry++; } } + #endif return NULL; } -static void print_help(const shell_command_t *command_list) { +static void print_help(const shell_command_t *command_list) +{ const shell_command_t *entry = command_list; printf("%-20s %s\n", "Command", "Description"); puts("---------------------------------------"); - if (entry) { - while (entry->name != NULL) { - printf("%-20s %s\n", entry->name, entry->desc); - entry++; - } - } - + if(entry) { + while(entry->name != NULL) { + printf("%-20s %s\n", entry->name, entry->desc); + entry++; + } + } + #ifdef MODULE_SHELL_COMMANDS entry = _shell_command_list; - while (entry->name != NULL) { + + while(entry->name != NULL) { printf("%-20s %s\n", entry->name, entry->desc); entry++; } + #endif } -static void handle_input_line(shell_t *shell, char* line) { - char* saveptr; - char* linedup = strdup(line); - char* command = strtok_r(linedup, " ", &saveptr); +static void handle_input_line(shell_t *shell, char *line) +{ + char *saveptr; + char *linedup = strdup(line); + char *command = strtok_r(linedup, " ", &saveptr); - void (*handler)(char*) = NULL; - - if (command) { + void (*handler)(char *) = NULL; + + if(command) { handler = find_handler(shell->command_list, command); - if (handler != NULL) { + + if(handler != NULL) { handler(line); - } else { - if ( strcmp("help", command) == 0) { + } + else { + if(strcmp("help", command) == 0) { print_help(shell->command_list); - } else { + } + else { puts("shell: command not found."); } } @@ -119,21 +117,24 @@ static void handle_input_line(shell_t *shell, char* line) { free(linedup); } -static int readline(shell_t *shell, char* buf, size_t size) { +static int readline(shell_t *shell, char *buf, size_t size) +{ char *line_buf_ptr = buf; int c; - while (1) { - if ( (line_buf_ptr - buf) >= ((int) size)-1) { + while(1) { + if((line_buf_ptr - buf) >= ((int) size) - 1) { return -1; } c = shell->readchar(); shell->put_char(c); - if (c == 13) continue; + if(c == 13) { + continue; + } - if (c == 10) { + if(c == 10) { *line_buf_ptr = '\0'; return 0; } @@ -141,6 +142,7 @@ static int readline(shell_t *shell, char* buf, size_t size) { *line_buf_ptr++ = c; } } + return 1; } @@ -151,22 +153,27 @@ static inline void print_prompt(shell_t *shell) return; } -void shell_run(shell_t *shell) { +void shell_run(shell_t *shell) +{ char line_buf[255]; print_prompt(shell); + while(1) { int res = readline(shell, line_buf, sizeof(line_buf)); - if (! res ) { - char* line_copy = strdup(line_buf); + + if(! res) { + char *line_copy = strdup(line_buf); handle_input_line(shell, line_copy); free(line_copy); } + print_prompt(shell); } } -void shell_init(shell_t *shell, const shell_command_t *shell_commands, int(*readchar)(void), void(*put_char)(int)) { +void shell_init(shell_t *shell, const shell_command_t *shell_commands, int(*readchar)(void), void(*put_char)(int)) +{ shell->command_list = shell_commands; shell->readchar = readchar; shell->put_char = put_char; diff --git a/sys/syslog/syslog-api.c b/sys/syslog/syslog-api.c index 8e157e5480..63528532e8 100644 --- a/sys/syslog/syslog-api.c +++ b/sys/syslog/syslog-api.c @@ -32,81 +32,78 @@ and the mailinglist (subscription via web site) #define VSYSLOG(level, strModule, strFmt, argp) vsyslog(level, strModule, strFmt, argp) void -syslog( - const uint8_t level, - const char (*const strModule), - const char* strFmt, ... -) { - va_list argp; +syslog(const uint8_t level, const char(*const strModule), const char *strFmt, ...) +{ + va_list argp; - va_start(argp, strFmt); - VSYSLOG(level, strModule, strFmt, argp); - va_end(argp); + va_start(argp, strFmt); + VSYSLOG(level, strModule, strFmt, argp); + va_end(argp); } /*-----------------------------------------------------------------------------------*/ #if (SYSLOG_CONF_LEVEL & SL_EMERGENCY) == SL_EMERGENCY -void syslog_emergency(const char (*const mod), const char* strFmt, ...) +void syslog_emergency(const char(*const mod), const char *strFmt, ...) { - va_list argp; + va_list argp; - va_start(argp, strFmt); - VSYSLOG(SL_EMERGENCY, mod, strFmt, argp); - va_end(argp); + va_start(argp, strFmt); + VSYSLOG(SL_EMERGENCY, mod, strFmt, argp); + va_end(argp); } #endif /*-----------------------------------------------------------------------------------*/ #if (SYSLOG_CONF_LEVEL & SL_CRITICAL) == SL_CRITICAL -void syslog_critical(const char (*const mod), const char* strFmt, ...) +void syslog_critical(const char(*const mod), const char *strFmt, ...) { - va_list argp; + va_list argp; - va_start(argp, strFmt); - VSYSLOG(SL_CRITICAL, mod, strFmt, argp); - va_end(argp); + va_start(argp, strFmt); + VSYSLOG(SL_CRITICAL, mod, strFmt, argp); + va_end(argp); } #endif /*-----------------------------------------------------------------------------------*/ #if (SYSLOG_CONF_LEVEL & SL_WARN) == SL_WARN -void syslog_warn(const char (*const mod), const char* strFmt, ...) +void syslog_warn(const char(*const mod), const char *strFmt, ...) { - va_list argp; + va_list argp; - va_start(argp, strFmt); - VSYSLOG(SL_WARN, mod, strFmt, argp); - va_end(argp); + va_start(argp, strFmt); + VSYSLOG(SL_WARN, mod, strFmt, argp); + va_end(argp); } #endif /*-----------------------------------------------------------------------------------*/ #if (SYSLOG_CONF_LEVEL & SL_NOTICE) == SL_NOTICE -void syslog_notice(const char (*const mod), const char* strFmt, ...) +void syslog_notice(const char(*const mod), const char *strFmt, ...) { - va_list argp; + va_list argp; - va_start(argp, strFmt); - VSYSLOG(SL_NOTICE, mod, strFmt, argp); - va_end(argp); + va_start(argp, strFmt); + VSYSLOG(SL_NOTICE, mod, strFmt, argp); + va_end(argp); } #endif /*-----------------------------------------------------------------------------------*/ #if (SYSLOG_CONF_LEVEL & SL_INFO) == SL_INFO -void syslog_info(const char (*const mod), const char* strFmt, ...) +void syslog_info(const char(*const mod), const char *strFmt, ...) { - va_list argp; + va_list argp; - va_start(argp, strFmt); - VSYSLOG(SL_INFO, mod, strFmt, argp); - va_end(argp); + va_start(argp, strFmt); + VSYSLOG(SL_INFO, mod, strFmt, argp); + va_end(argp); } #endif /*-----------------------------------------------------------------------------------*/ #if SYSLOG_ISLEVEL(SL_DEBUG) -void syslog_debug(const char (*const mod), const char* strFmt, ...) +void syslog_debug(const char(*const mod), const char *strFmt, ...) { - va_list argp; + va_list argp; - va_start(argp, strFmt); - VSYSLOG(SL_DEBUG, mod, strFmt, argp); - va_end(argp); + va_start(argp, strFmt); + VSYSLOG(SL_DEBUG, mod, strFmt, argp); + va_end(argp); } #endif diff --git a/sys/syslog/syslog-out.c b/sys/syslog/syslog-out.c index 78a62e0cd2..e308b8e656 100644 --- a/sys/syslog/syslog-out.c +++ b/sys/syslog/syslog-out.c @@ -57,123 +57,132 @@ and the mailinglist (subscription via web site) #endif /*-----------------------------------------------------------------------------------*/ -void -syslog_format_ascii(struct syslog_args* args, struct syslog_chainlink* chainlink) +void syslog_format_ascii(struct syslog_args *args, struct syslog_chainlink *chainlink) { - char buffer[SYSLOG_CONF_BUFSIZE + 25]; - int msglen = 0; + char buffer[SYSLOG_CONF_BUFSIZE + 25]; + int msglen = 0; - if( args->message[0] != '\t' ) { - const char* strlevel = syslog_leveltostring(args->level); - msglen = snprintf(buffer, SYSLOG_CONF_BUFSIZE + 23, - "#[%u.%u:%u=%s] %s:", - NETWORK_ADDR_NET(NET_LOCAL_ADDRESS), NETWORK_ADDR_HOST(NET_LOCAL_ADDRESS), - args->level, strlevel, args->module - ); - } + if(args->message[0] != '\t') { + const char *strlevel = syslog_leveltostring(args->level); + msglen = snprintf(buffer, SYSLOG_CONF_BUFSIZE + 23, + "#[%u.%u:%u=%s] %s:", + NETWORK_ADDR_NET(NET_LOCAL_ADDRESS), NETWORK_ADDR_HOST(NET_LOCAL_ADDRESS), + args->level, strlevel, args->module + ); + } - msglen += snprintf(buffer + msglen, SYSLOG_CONF_BUFSIZE + 23 - msglen, "%s", args->message); - buffer[msglen++] = '\n'; - buffer[msglen] = '\0'; + msglen += snprintf(buffer + msglen, SYSLOG_CONF_BUFSIZE + 23 - msglen, "%s", args->message); + buffer[msglen++] = '\n'; + buffer[msglen] = '\0'; - args->message = buffer; - if( chainlink != NULL && chainlink->fpout != NULL ) - chainlink->fpout(args, chainlink->next); + args->message = buffer; + + if(chainlink != NULL && chainlink->fpout != NULL) { + chainlink->fpout(args, chainlink->next); + } } /*-----------------------------------------------------------------------------------*/ -void -syslog_format_xml(struct syslog_args* args, struct syslog_chainlink* chainlink) +void syslog_format_xml(struct syslog_args *args, struct syslog_chainlink *chainlink) { - const size_t bufsize = SYSLOG_CONF_BUFSIZE + 80; - char buffer[bufsize]; - char tbuf[20]; - int msglen = 0; + const size_t bufsize = SYSLOG_CONF_BUFSIZE + 80; + char buffer[bufsize]; + char tbuf[20]; + int msglen = 0; - #if FEUERWARE_CONF_CORE_SUPPORTS_TIME - time_get_string(tbuf, sizeof(tbuf)); - #else - sprintf(tbuf, "%lu", clock_time(NULL)); - #endif +#if FEUERWARE_CONF_CORE_SUPPORTS_TIME + time_get_string(tbuf, sizeof(tbuf)); +#else + sprintf(tbuf, "%lu", clock_time(NULL)); +#endif - msglen = snprintf(buffer, bufsize, - "%s\n", - args->level, NETWORK_ADDR_NET(NET_LOCAL_ADDRESS), NETWORK_ADDR_HOST(NET_LOCAL_ADDRESS), - args->msgnum, tbuf, args->module, args->message - ); + msglen = snprintf(buffer, bufsize, + "%s\n", + args->level, NETWORK_ADDR_NET(NET_LOCAL_ADDRESS), NETWORK_ADDR_HOST(NET_LOCAL_ADDRESS), + args->msgnum, tbuf, args->module, args->message + ); - args->message = buffer; - if( chainlink != NULL && chainlink->fpout != NULL ) - chainlink->fpout(args, chainlink->next); + args->message = buffer; + + if(chainlink != NULL && chainlink->fpout != NULL) { + chainlink->fpout(args, chainlink->next); + } } /*-----------------------------------------------------------------------------------*/ -void -syslog_copy_stdout(struct syslog_args* args, struct syslog_chainlink* chainlink) +void syslog_copy_stdout(struct syslog_args *args, struct syslog_chainlink *chainlink) { - if( args->message[0] != '\t' ) { - const char* strlevel = syslog_leveltostring(args->level); - printf("#[%u.%u:%u=%s] %s:", - NETWORK_ADDR_NET(NET_LOCAL_ADDRESS), NETWORK_ADDR_HOST(NET_LOCAL_ADDRESS), - args->level, strlevel, args->module - ); - } - printf("%s\n", args->message); + if(args->message[0] != '\t') { + const char *strlevel = syslog_leveltostring(args->level); + printf("#[%u.%u:%u=%s] %s:", + NETWORK_ADDR_NET(NET_LOCAL_ADDRESS), NETWORK_ADDR_HOST(NET_LOCAL_ADDRESS), + args->level, strlevel, args->module + ); + } - if( chainlink != NULL && chainlink->fpout != NULL ) - chainlink->fpout(args, chainlink->next); + printf("%s\n", args->message); + + if(chainlink != NULL && chainlink->fpout != NULL) { + chainlink->fpout(args, chainlink->next); + } } /*-----------------------------------------------------------------------------------*/ -void -syslog_out_stdout(struct syslog_args* args, struct syslog_chainlink* chainlink) +void syslog_out_stdout(struct syslog_args *args, struct syslog_chainlink *chainlink) { - printf(args->message); + printf(args->message); - if( chainlink != NULL && chainlink->fpout != NULL ) - chainlink->fpout(args, chainlink->next); + if(chainlink != NULL && chainlink->fpout != NULL) { + chainlink->fpout(args, chainlink->next); + } } /*-----------------------------------------------------------------------------------*/ #ifdef MODULE_FAT static int syslog_file = -1; -static int fat_open_logfile(const char* path); -static int fat_open_logfile(const char* path) +static int fat_open_logfile(const char *path); +static int fat_open_logfile(const char *path) { - char t[20]; - int file; + char t[20]; + int file; - file = open(path, O_WRONLY | O_APPEND | O_CREAT); + file = open(path, O_WRONLY | O_APPEND | O_CREAT); - time_get_string(t, sizeof(t)); + time_get_string(t, sizeof(t)); - if( file >= 0 ) { - syslog_notice("sys", "%s log %s opened", t, path); - } else { - syslog_warn("sys", "%s log %s failed", t, path); - } - return file; + if(file >= 0) { + syslog_notice("sys", "%s log %s opened", t, path); + } + else { + syslog_warn("sys", "%s log %s failed", t, path); + } + + return file; } -void syslog_out_file(struct syslog_args* args, struct syslog_chainlink* chainlink) +void syslog_out_file(struct syslog_args *args, struct syslog_chainlink *chainlink) { - if( syslog_file >= 0 ) { - size_t length = (size_t)strlen(args->message); - int ret = write(syslog_file, args->message, length); - if( ret == 1 ) { + if(syslog_file >= 0) { + size_t length = (size_t)strlen(args->message); + int ret = write(syslog_file, args->message, length); + + if(ret == 1) { #ifdef MODULE_TRACELOG - trace_string(TRACELOG_EV_MEMORY, "fat"); + trace_string(TRACELOG_EV_MEMORY, "fat"); #endif - } - } + } + } - if( chainlink != NULL && chainlink->fpout != NULL ) - chainlink->fpout(args, chainlink->next); + if(chainlink != NULL && chainlink->fpout != NULL) { + chainlink->fpout(args, chainlink->next); + } } -bool syslog_open_file(void) { - syslog_file = fat_open_logfile("SYSLOG.LOG"); - return (syslog_file >= 0); +bool syslog_open_file(void) +{ + syslog_file = fat_open_logfile("SYSLOG.LOG"); + return (syslog_file >= 0); } -void syslog_close_file(void) { - close(syslog_file); - syslog_file = -1; +void syslog_close_file(void) +{ + close(syslog_file); + syslog_file = -1; } #endif diff --git a/sys/syslog/syslog.c b/sys/syslog/syslog.c index 7cd0e083c2..bd9f84ad40 100644 --- a/sys/syslog/syslog.c +++ b/sys/syslog/syslog.c @@ -52,7 +52,7 @@ and the mailinglist (subscription via web site) #include "sysmon.h" #include "tracelog.h" -static const char* syslog_level_stringtable = "emergency\0" +static const char *syslog_level_stringtable = "emergency\0" "critical\0" "warn\0" "notice\0" @@ -64,109 +64,108 @@ __attribute__((section(".noinit"))) static volatile unsigned int syslog_msgnum; static unsigned short syslog_flagtolevel(const uint8_t level); -static int find_interface_index_for_name(const char* name); +static int find_interface_index_for_name(const char *name); extern struct syslog_interface syslog_interfaces[]; /*-----------------------------------------------------------------------------------*/ -void -syslog_init(void) +void syslog_init(void) { - if( sysmon_initial_boot() ) - syslog_msgnum = 0; + if(sysmon_initial_boot()) { + syslog_msgnum = 0; + } } /*-----------------------------------------------------------------------------------*/ -static bool -testlevel(uint8_t filter_level, const uint8_t level) { - return ((filter_level & level) != 0); -} -/*-----------------------------------------------------------------------------------*/ -void -vsyslog( - const uint8_t level, - const char (*const strModule), - const char* strFmt, - va_list argp -) { - int i; - struct syslog_interface* slif; // syslog interface - struct syslog_args args; // output function arguments - char message[SYSLOG_CONF_BUFSIZE]; // message buffer - int msglen = 0; - - args.message = NULL; - - //printf("0 %p %p\n", &syslog_interfaces[0], syslog_interfaces[0].chain); - //printf("1 %p %p\n", &syslog_interfaces[1], syslog_interfaces[1].chain); - - // check each syslog interface - for( i = 0; i < SYSLOG_CONF_NUM_INTERFACES; i++) { - slif = &syslog_interfaces[i]; - /* run interface filter */ - //printf("testing %i, %s\n", i, slif->name); - if( slif->name != NULL && testlevel(cfg_feuerware.level[i], level) ) { - /* filter matched, produce output */ - //printf("printing to %s\n", slif->name); - if( args.message == NULL ) { - // initialize structure one time, when actually needed - args.msgnum = syslog_msgnum++; - args.level = syslog_flagtolevel(level); - args.module = strModule; - args.message = message; - msglen = vsnprintf(message, SYSLOG_CONF_BUFSIZE-1, strFmt, argp); - } - //printf("msg %i: %s\n", msglen, message); - args.interface = (const struct syslog_interface*)slif; - - // invoke first link of ouput chain - //printf("invoke on %s: %p %p\n", slif->name, slif, slif->chain); - if( slif->chain->fpout != NULL ) { - slif->chain->fpout(&args, slif->chain->next); - } - } - } -} -/*-----------------------------------------------------------------------------------*/ -void syslog_printlevel(char* buffer, size_t bufsize, uint8_t level) +static bool testlevel(uint8_t filter_level, const uint8_t level) { - uint8_t l = level; - int intlevel; - int bufpos; - int len = 0; - - bufpos = snprintf(buffer, bufsize, "%#.2x=", level); - bufsize -= bufpos; - for( intlevel = 0; intlevel < SYSLOG_LEVELS_COUNT; intlevel++ ) { - if( l & 0x0001 ) { - const char* string = string_table_get(syslog_level_stringtable, intlevel); - if( string ) { - if( bufsize < 0 ) bufsize = 0; - len = snprintf( &buffer[bufpos], bufsize, "%s%s", ((len > 0) ? "|" : ""), (char*)string ); - bufsize -= len; - bufpos += len; - } - } - l >>= 1; - } + return ((filter_level & level) != 0); } /*-----------------------------------------------------------------------------------*/ -uint8_t syslog_set_level(const char* name, uint8_t level) +void vsyslog(const uint8_t level, const char(*const strModule), + const char *strFmt, va_list argp) { - uint8_t result; - int index = find_interface_index_for_name(name); - if( index < 0 ) - return 0; + int i; + struct syslog_interface *slif; // syslog interface + struct syslog_args args; // output function arguments + char message[SYSLOG_CONF_BUFSIZE]; // message buffer + int msglen = 0; - result = cfg_feuerware.level[index]; - cfg_feuerware.level[index] = level; - cfg_feuerware_spec.state->modified = 1; + args.message = NULL; - return result; + /* check each syslog interface */ + for(i = 0; i < SYSLOG_CONF_NUM_INTERFACES; i++) { + slif = &syslog_interfaces[i]; + + /* run interface filter */ + if(slif->name != NULL && testlevel(cfg_feuerware.level[i], level)) { + /* filter matched, produce output */ + if(args.message == NULL) { + /* initialize structure one time, when actually needed */ + args.msgnum = syslog_msgnum++; + args.level = syslog_flagtolevel(level); + args.module = strModule; + args.message = message; + msglen = vsnprintf(message, SYSLOG_CONF_BUFSIZE - 1, strFmt, argp); + } + + args.interface = (const struct syslog_interface *)slif; + + /* invoke first link of ouput chain */ + if(slif->chain->fpout != NULL) { + slif->chain->fpout(&args, slif->chain->next); + } + } + } } /*-----------------------------------------------------------------------------------*/ -const char* -syslog_leveltostring(unsigned int level) { - return string_table_get(syslog_level_stringtable, level); +void syslog_printlevel(char *buffer, size_t bufsize, uint8_t level) +{ + uint8_t l = level; + int intlevel; + int bufpos; + int len = 0; + + bufpos = snprintf(buffer, bufsize, "%#.2x=", level); + bufsize -= bufpos; + + for(intlevel = 0; intlevel < SYSLOG_LEVELS_COUNT; intlevel++) { + if(l & 0x0001) { + const char *string = string_table_get(syslog_level_stringtable, intlevel); + + if(string) { + if(bufsize < 0) { + bufsize = 0; + } + + len = snprintf(&buffer[bufpos], bufsize, "%s%s", ((len > 0) ? "|" : ""), (char *)string); + bufsize -= len; + bufpos += len; + } + } + + l >>= 1; + } +} +/*-----------------------------------------------------------------------------------*/ +uint8_t syslog_set_level(const char *name, uint8_t level) +{ + uint8_t result; + int index = find_interface_index_for_name(name); + + if(index < 0) { + return 0; + } + + result = cfg_feuerware.level[index]; + cfg_feuerware.level[index] = level; + cfg_feuerware_spec.state->modified = 1; + + return result; +} +/*-----------------------------------------------------------------------------------*/ +const char *syslog_leveltostring(unsigned int level) +{ + return string_table_get(syslog_level_stringtable, level); } /*-----------------------------------------------------------------------------------*/ @@ -189,76 +188,82 @@ syslog_leveltostring(unsigned int level) { ASCCMD(syslog, 0, "[interface] [byte val]: syslog-level property"); CMD_FUNCTION(syslog, cmdargs) { - int i; + int i; - if( cmdargs->arg_size > 0 ) { - unsigned int argc; - const char* arg; - const char* name = NULL; - unsigned int value; + if(cmdargs->arg_size > 0) { + unsigned int argc; + const char *arg; + const char *name = NULL; + unsigned int value; - argc = cmd_split_arguments(cmdargs->args); - arg = cmdargs->args; + argc = cmd_split_arguments(cmdargs->args); + arg = cmdargs->args; - if( *arg >= 'A' ) { - // first argument is a string - name = arg; - // move to next argument - arg = cmd_get_next_argument(arg); - } - if( *arg == '\0' ) - return CMD_ERROR; - value = strtoul(arg, NULL, 0); - syslog_set_level(name, value); - } + if(*arg >= 'A') { + // first argument is a string + name = arg; + // move to next argument + arg = cmd_get_next_argument(arg); + } - for( i = 0; i < SYSLOG_CONF_NUM_INTERFACES; i++ ) { - if( syslog_interfaces[i].name != NULL ) { - char buf[SYSLOG_PRINTLEVEL_MAXLEN]; - syslog_printlevel(buf, sizeof(buf), cfg_feuerware.level[i]); - cmdargs->fresponse(cmdargs, - CMD_RESPONSE_MULTILINE, - "%s:%s", - syslog_interfaces[i].name, - buf - ); - } - } - return CMD_SUCCESS; + if(*arg == '\0') { + return CMD_ERROR; + } + + value = strtoul(arg, NULL, 0); + syslog_set_level(name, value); + } + + for(i = 0; i < SYSLOG_CONF_NUM_INTERFACES; i++) { + if(syslog_interfaces[i].name != NULL) { + char buf[SYSLOG_PRINTLEVEL_MAXLEN]; + syslog_printlevel(buf, sizeof(buf), cfg_feuerware.level[i]); + cmdargs->fresponse(cmdargs, + CMD_RESPONSE_MULTILINE, + "%s:%s", + syslog_interfaces[i].name, + buf + ); + } + } + + return CMD_SUCCESS; } #endif /*-----------------------------------------------------------------------------------*/ /** * @brief Convert bit flag to bit number */ -static unsigned short -syslog_flagtolevel(const uint8_t level) +static unsigned short syslog_flagtolevel(const uint8_t level) { - uint8_t l = level; - unsigned short intlevel; + uint8_t l = level; + unsigned short intlevel; - for( intlevel = 0; intlevel < SYSLOG_LEVELS_COUNT; intlevel++ ) { - if( (l & 1) == 1 ) - break; - l >>= 1; - } + for(intlevel = 0; intlevel < SYSLOG_LEVELS_COUNT; intlevel++) { + if((l & 1) == 1) { + break; + } - return intlevel; + l >>= 1; + } + + return intlevel; } /*-----------------------------------------------------------------------------------*/ /** * @brief Find an interface for a given name */ -static int -find_interface_index_for_name(const char* name) +static int find_interface_index_for_name(const char *name) { - int i; + int i; - for( i = 0; i < SYSLOG_CONF_NUM_INTERFACES; i++ ) { - if( strcmp(syslog_interfaces[i].name, name) == 0 ) - return i; - } - return -1; + for(i = 0; i < SYSLOG_CONF_NUM_INTERFACES; i++) { + if(strcmp(syslog_interfaces[i].name, name) == 0) { + return i; + } + } + + return -1; } /** @} */ diff --git a/sys/tracelog/tracelog.c b/sys/tracelog/tracelog.c index 0e539f2b1b..c645cca6ac 100644 --- a/sys/tracelog/tracelog.c +++ b/sys/tracelog/tracelog.c @@ -52,72 +52,76 @@ and the mailinglist (subscription via web site) #include "syslog.h" #if TRACELOG_CONF_NUM_ENTRIES > 0 - __attribute__((section(".noinit"))) - struct tracelog tracelog; +__attribute__((section(".noinit"))) +struct tracelog tracelog; - /// tells if tracelog can accept input - static bool tracelog_initialized = 0; +/// tells if tracelog can accept input +static bool tracelog_initialized = 0; #endif #if defined(SYSLOG_CONF_LEVEL) && ((SYSLOG_CONF_LEVEL & SL_DEBUG) == SL_DEBUG) static const char symon_event_names[] = - "\0" - "start\0" - "exit\0" - "assert\0" - "event\0" - "timer\0" - "irqdis\0" - "irqen\0" - "irq\0" - "switch\0" - "\0" - "memory\0" - "memaccess\0" - "opfault\0" - "panic\0" - "userdef\0" - "\3"; + "\0" + "start\0" + "exit\0" + "assert\0" + "event\0" + "timer\0" + "irqdis\0" + "irqen\0" + "irq\0" + "switch\0" + "\0" + "memory\0" + "memaccess\0" + "opfault\0" + "panic\0" + "userdef\0" + "\3"; #endif /*-----------------------------------------------------------------------------------*/ #if TRACELOG_CONF_NUM_ENTRIES > 0 -static void tracelog_snprint(char* buf, int bufsz, int i) +static void tracelog_snprint(char *buf, int bufsz, int i) { - struct tracelog_entry* trace = &tracelog.traces[i]; - int length = 0; - bufsz -= 1; // save one for zero + struct tracelog_entry *trace = &tracelog.traces[i]; + int length = 0; + bufsz -= 1; // save one for zero - #if (SYSLOG_CONF_LEVEL & SL_DEBUG) == SL_DEBUG - /* when running in debug level, event names are available and can be printed */ - char* name = (char*)string_table_get(symon_event_names, trace->event); - length = snprintf(buf, bufsz, "%#.2x (%s): ", trace->event, name); - #else - length = snprintf(buf, bufsz, "%#.2x: ", trace->event); - #endif - bufsz -= length; - buf += length; +#if (SYSLOG_CONF_LEVEL & SL_DEBUG) == SL_DEBUG + /* when running in debug level, event names are available and can be printed */ + char *name = (char *)string_table_get(symon_event_names, trace->event); + length = snprintf(buf, bufsz, "%#.2x (%s): ", trace->event, name); +#else + length = snprintf(buf, bufsz, "%#.2x: ", trace->event); +#endif + bufsz -= length; + buf += length; - switch( trace->type ) { - case TRACE_NUMBER: { - tracelog_number_t uldata; - memcpy(&uldata, trace->data, sizeof(tracelog_number_t)); - length += snprintf(buf, bufsz, "%#10lx (%lu)", uldata, uldata); - break; - } - case TRACE_POINTER: { - void* uldata; - memcpy(&uldata, trace->data, sizeof(void*)); - length += snprintf(buf, bufsz, "%p", uldata); - break; - } - case TRACE_STRING: - length += snprintf(buf, bufsz, "%.*s", TRACELOG_CONF_ENTRY_SIZE, trace->data); - break; - default: - break; - } - buf[length] = '\0'; + switch(trace->type) { + case TRACE_NUMBER: { + tracelog_number_t uldata; + memcpy(&uldata, trace->data, sizeof(tracelog_number_t)); + length += snprintf(buf, bufsz, "%#10lx (%lu)", uldata, uldata); + break; + } + + case TRACE_POINTER: { + void *uldata; + memcpy(&uldata, trace->data, sizeof(void *)); + length += snprintf(buf, bufsz, "%p", uldata); + break; + } + + case TRACE_STRING: + length += snprintf(buf, bufsz, "%.*s", TRACELOG_CONF_ENTRY_SIZE, trace->data); + break; + + default: + break; + } + + buf[length] = '\0'; } #endif /*-----------------------------------------------------------------------------------*/ @@ -127,50 +131,56 @@ static void tracelog_snprint(char* buf, int bufsz, int i) */ static void trace( - enum tracelog_event event, - const enum tracelog_type t, - const void (* const data), - const int size -) { + enum tracelog_event event, + const enum tracelog_type t, + const void (* const data), + const int size +) +{ #if TRACELOG_CONF_NUM_ENTRIES > 0 - int length = size; + int length = size; - if( tracelog_initialized == false ) - return; + if(tracelog_initialized == false) { + return; + } - struct tracelog_entry* trace = &tracelog.traces[tracelog.tail]; // get current tail element - /* increase tail */ - if( (tracelog.tail + 1) < TRACELOG_CONF_NUM_ENTRIES ) - tracelog.tail++; - else - tracelog.tail = 0; + struct tracelog_entry *trace = &tracelog.traces[tracelog.tail]; // get current tail element - /* fill meta data */ - trace->event = event & 0x7F; - trace->type = t; + /* increase tail */ + if((tracelog.tail + 1) < TRACELOG_CONF_NUM_ENTRIES) { + tracelog.tail++; + } + else { + tracelog.tail = 0; + } - /* calculate size */ - if( length == 0 ) { - if( t == TRACE_STRING ) { - length = strlen((char*)data); - } - } - length = (TRACELOG_CONF_ENTRY_SIZE < length) ? TRACELOG_CONF_ENTRY_SIZE : length; + /* fill meta data */ + trace->event = event & 0x7F; + trace->type = t; - memcpy( trace->data, data, length ); // copy description + /* calculate size */ + if(length == 0) { + if(t == TRACE_STRING) { + length = strlen((char *)data); + } + } + + length = (TRACELOG_CONF_ENTRY_SIZE < length) ? TRACELOG_CONF_ENTRY_SIZE : length; + + memcpy(trace->data, data, length); // copy description #endif } /*-----------------------------------------------------------------------------------*/ void trace_reset(void) { #if TRACELOG_CONF_NUM_ENTRIES > 0 - #if SYSLOG_ISLEVEL(SL_DEBUG) - char buffer[12]; - sysmon_write_reset_info(buffer, 12, sysmon.reset_code); - trace_string(TRACELOG_EV_START, buffer); - #else - trace_number(TRACELOG_EV_START, sysmon.reset_code); - #endif +#if SYSLOG_ISLEVEL(SL_DEBUG) + char buffer[12]; + sysmon_write_reset_info(buffer, 12, sysmon.reset_code); + trace_string(TRACELOG_EV_START, buffer); +#else + trace_number(TRACELOG_EV_START, sysmon.reset_code); +#endif #endif } /*-----------------------------------------------------------------------------------*/ @@ -178,42 +188,50 @@ void tracelog_init(void) { #if TRACELOG_CONF_NUM_ENTRIES > 0 - if( tracelog_initialized != 0 ) - return; - if( sysmon_initial_boot() ) { - memset( &tracelog, 0, sizeof(struct tracelog) ); // clear tracelog buffer on initial boot only - } + if(tracelog_initialized != 0) { + return; + } - tracelog_initialized = true; // accept traces + if(sysmon_initial_boot()) { + memset(&tracelog, 0, sizeof(struct tracelog)); // clear tracelog buffer on initial boot only + } - trace_reset(); // trace reason for last reset + tracelog_initialized = true; // accept traces + + trace_reset(); // trace reason for last reset #endif } void tracelog_dump(void) { - printf("[trace] {\n"); + printf("[trace] {\n"); #if TRACELOG_CONF_NUM_ENTRIES > 0 - char buf[30 + TRACELOG_CONF_ENTRY_SIZE]; - int i = tracelog.tail; // tracelog tail holds next index - do { - i--; - if( i < 0 ) - i = TRACELOG_CONF_NUM_ENTRIES - 1; - tracelog_snprint(buf, sizeof(buf), i); - printf("\t %.2i: %s\n", i, buf); - } while( i != tracelog.tail ); + char buf[30 + TRACELOG_CONF_ENTRY_SIZE]; + int i = tracelog.tail; // tracelog tail holds next index + + do { + i--; + + if(i < 0) { + i = TRACELOG_CONF_NUM_ENTRIES - 1; + } + + tracelog_snprint(buf, sizeof(buf), i); + printf("\t %.2i: %s\n", i, buf); + } + while(i != tracelog.tail); + #endif - printf("}\n"); + printf("}\n"); } /*-----------------------------------------------------------------------------------*/ void trace_event(enum tracelog_event event) { #if TRACELOG_CONF_NUM_ENTRIES > 0 - trace(event, TRACE_NULL, NULL, 0); + trace(event, TRACE_NULL, NULL, 0); #endif } /*-----------------------------------------------------------------------------------*/ @@ -221,23 +239,23 @@ void trace_number(enum tracelog_event event, tracelog_number_t number) { #if TRACELOG_CONF_NUM_ENTRIES > 0 - trace(event, TRACE_NUMBER, &number, sizeof(tracelog_number_t)); + trace(event, TRACE_NUMBER, &number, sizeof(tracelog_number_t)); #endif } /*-----------------------------------------------------------------------------------*/ void -trace_pointer(enum tracelog_event event, void* pointer) +trace_pointer(enum tracelog_event event, void *pointer) { #if TRACELOG_CONF_NUM_ENTRIES > 0 - trace(event, TRACE_POINTER, &pointer, sizeof(void*)); + trace(event, TRACE_POINTER, &pointer, sizeof(void *)); #endif } /*-----------------------------------------------------------------------------------*/ void -trace_string(enum tracelog_event event, char* string) +trace_string(enum tracelog_event event, char *string) { #if TRACELOG_CONF_NUM_ENTRIES > 0 - trace(event, TRACE_STRING, string, strlen(string)); + trace(event, TRACE_STRING, string, strlen(string)); #endif } /*-----------------------------------------------------------------------------------*/ @@ -254,20 +272,23 @@ ASCCMD(trace, CMDFLAG_SERIAL, "[event] [text]: print tracelog / trace event [num CMD_FUNCTION(trace, cmdargs) { #if TRACELOG_CONF_NUM_ENTRIES > 0 - if( cmdargs->arg_size > 0 ) { - enum tracelog_event event; - char* c = (char*)cmdargs->args; - event = (enum tracelog_event)strtoul(c, &c, 0); // read event number - if( event > 0 ) { - c++; // skip expected whitespace - trace_string(event, c); // generate event with argument as text - return true; - } - } -#endif - tracelog_dump(); - return CMD_SUCCESS; + if(cmdargs->arg_size > 0) { + enum tracelog_event event; + char *c = (char *)cmdargs->args; + event = (enum tracelog_event)strtoul(c, &c, 0); // read event number + + if(event > 0) { + c++; // skip expected whitespace + trace_string(event, c); // generate event with argument as text + return true; + } + } + +#endif + tracelog_dump(); + + return CMD_SUCCESS; } #endif /*-----------------------------------------------------------------------------------*/ diff --git a/sys/transceiver/transceiver.c b/sys/transceiver/transceiver.c index aabb237a25..0bef5158b6 100644 --- a/sys/transceiver/transceiver.c +++ b/sys/transceiver/transceiver.c @@ -1,5 +1,5 @@ /** - * Generic transceiver module as an interface to NIC driver. + * Generic transceiver module as an interface to NIC driver. * * Copyright (C) 2013 INRIA. * @@ -30,16 +30,16 @@ #ifdef MODULE_CC110X #include #if (CC1100_MAX_DATA_LENGTH > PAYLOAD_SIZE) - #undef PAYLOAD_SIZE - #define PAYLOAD_SIZE (CC1100_MAX_DATA_LENGTH) +#undef PAYLOAD_SIZE +#define PAYLOAD_SIZE (CC1100_MAX_DATA_LENGTH) #endif #endif #ifdef MODULE_CC110X_NG #include #if (CC1100_MAX_DATA_LENGTH > PAYLOAD_SIZE) - #undef PAYLOAD_SIZE - #define PAYLOAD_SIZE (CC1100_MAX_DATA_LENGTH) +#undef PAYLOAD_SIZE +#define PAYLOAD_SIZE (CC1100_MAX_DATA_LENGTH) #endif #endif @@ -55,7 +55,7 @@ registered_t reg[TRANSCEIVER_MAX_REGISTERED]; /* packet buffers */ radio_packet_t transceiver_buffer[TRANSCEIVER_BUFFER_SIZE]; -uint8_t data_buffer[TRANSCEIVER_BUFFER_SIZE * PAYLOAD_SIZE]; +uint8_t data_buffer[TRANSCEIVER_BUFFER_SIZE *PAYLOAD_SIZE]; /* message buffer */ msg_t msg_buffer[TRANSCEIVER_MSG_BUFFER_SIZE]; @@ -85,7 +85,7 @@ static void receive_packet(uint16_t type, uint8_t pos); #ifdef MODULE_CC110X_NG static void receive_cc110x_packet(radio_packet_t *trans_p); #elif MODULE_CC110X -void cc1100_packet_monitor(void* payload, int payload_size, protocol_t protocol, packet_info_t* packet_info); +void cc1100_packet_monitor(void *payload, int payload_size, protocol_t protocol, packet_info_t *packet_info); void receive_cc1100_packet(radio_packet_t *trans_p); #endif static uint8_t send_packet(transceiver_type_t t, void *pkt); @@ -103,18 +103,20 @@ static void ignore_add(transceiver_type_t t, void *address); /*------------------------------------------------------------------------------------*/ /* Transceiver init */ -void transceiver_init(transceiver_type_t t) { +void transceiver_init(transceiver_type_t t) +{ uint8_t i; /* Initializing transceiver buffer and data buffer */ memset(transceiver_buffer, 0, TRANSCEIVER_BUFFER_SIZE); memset(data_buffer, 0, TRANSCEIVER_BUFFER_SIZE * PAYLOAD_SIZE); - for (i = 0; i < TRANSCEIVER_MAX_REGISTERED; i++) { + for(i = 0; i < TRANSCEIVER_MAX_REGISTERED; i++) { reg[i].transceivers = TRANSCEIVER_NONE; reg[i].pid = 0; } - if (t & TRANSCEIVER_CC1100) { + + if(t & TRANSCEIVER_CC1100) { transceivers |= t; } else { @@ -123,12 +125,14 @@ void transceiver_init(transceiver_type_t t) { } /* Start the transceiver thread */ -int transceiver_start(void) { - transceiver_pid = thread_create(transceiver_stack, TRANSCEIVER_STACK_SIZE, PRIORITY_MAIN-3, CREATE_STACKTEST, run, "Transceiver"); - if (transceiver_pid < 0) { +int transceiver_start(void) +{ + transceiver_pid = thread_create(transceiver_stack, TRANSCEIVER_STACK_SIZE, PRIORITY_MAIN - 3, CREATE_STACKTEST, run, "Transceiver"); + + if(transceiver_pid < 0) { puts("Error creating transceiver thread"); } - else if (transceivers & TRANSCEIVER_CC1100) { + else if(transceivers & TRANSCEIVER_CC1100) { DEBUG("Transceiver started for CC1100\n"); #ifdef MODULE_CC110X_NG cc110x_init(transceiver_pid); @@ -137,25 +141,28 @@ int transceiver_start(void) { cc1100_set_packet_monitor(cc1100_packet_monitor); #endif } + return transceiver_pid; } /* Register an upper layer thread */ -uint8_t transceiver_register(transceiver_type_t t, int pid) { - uint8_t i; - for (i = 0; ((reg[i].pid != pid) && - (i < TRANSCEIVER_MAX_REGISTERED) && - (reg[i].transceivers != TRANSCEIVER_NONE)); i++); +uint8_t transceiver_register(transceiver_type_t t, int pid) +{ + uint8_t i; - if (i >= TRANSCEIVER_MAX_REGISTERED) { - return ENOMEM; - } - else { - reg[i].transceivers |= t; - reg[i].pid = pid; - DEBUG("Thread %i registered for %i\n", reg[i].pid, reg[i].transceivers); - return 1; - } + for(i = 0; ((reg[i].pid != pid) && + (i < TRANSCEIVER_MAX_REGISTERED) && + (reg[i].transceivers != TRANSCEIVER_NONE)); i++); + + if(i >= TRANSCEIVER_MAX_REGISTERED) { + return ENOMEM; + } + else { + reg[i].transceivers |= t; + reg[i].pid = pid; + DEBUG("Thread %i registered for %i\n", reg[i].pid, reg[i].transceivers); + return 1; + } } /*------------------------------------------------------------------------------------*/ @@ -166,58 +173,71 @@ uint8_t transceiver_register(transceiver_type_t t, int pid) { * @brief The main thread run, receiving and processing messages in an infinite * loop */ -void run(void) { +void run(void) +{ msg_t m; transceiver_command_t *cmd; msg_init_queue(msg_buffer, TRANSCEIVER_MSG_BUFFER_SIZE); - while (1) { + + while(1) { DEBUG("Waiting for next message\n"); msg_receive(&m); /* only makes sense for messages for upper layers */ - cmd = (transceiver_command_t*) m.content.ptr; + cmd = (transceiver_command_t *) m.content.ptr; DEBUG("Transceiver: Message received\n"); - switch (m.type) { + + switch(m.type) { case RCV_PKT_CC1020: case RCV_PKT_CC1100: receive_packet(m.type, m.content.value); break; + case SND_PKT: response = send_packet(cmd->transceivers, cmd->data); m.content.value = response; msg_reply(&m, &m); break; + case GET_CHANNEL: - *((int16_t*) cmd->data) = get_channel(cmd->transceivers); + *((int16_t *) cmd->data) = get_channel(cmd->transceivers); msg_reply(&m, &m); break; + case SET_CHANNEL: - *((int16_t*) cmd->data) = set_channel(cmd->transceivers, cmd->data); + *((int16_t *) cmd->data) = set_channel(cmd->transceivers, cmd->data); msg_reply(&m, &m); break; + case GET_ADDRESS: - *((int16_t*) cmd->data) = get_address(cmd->transceivers); + *((int16_t *) cmd->data) = get_address(cmd->transceivers); msg_reply(&m, &m); break; + case SET_ADDRESS: - *((int16_t*) cmd->data) = set_address(cmd->transceivers, cmd->data); + *((int16_t *) cmd->data) = set_address(cmd->transceivers, cmd->data); msg_reply(&m, &m); break; + case SET_MONITOR: set_monitor(cmd->transceivers, cmd->data); break; + case POWERDOWN: powerdown(cmd->transceivers); break; + case SWITCH_RX: switch_to_rx(cmd->transceivers); break; #ifdef DBG_IGNORE + case DBG_IGN: printf("Transceiver PID: %i (%p), rx_buffer_next: %u\n", transceiver_pid, &transceiver_pid, rx_buffer_next); ignore_add(cmd->transceivers, cmd->data); break; #endif + default: DEBUG("Unknown message received\n"); break; @@ -226,7 +246,8 @@ void run(void) { } #ifdef MODULE_CC110X -void cc1100_packet_monitor(void* payload, int payload_size, protocol_t protocol, packet_info_t* packet_info) { +void cc1100_packet_monitor(void *payload, int payload_size, protocol_t protocol, packet_info_t *packet_info) +{ cc1100_payload = payload; cc1100_payload_size = payload_size - 3; cc1100_packet_info = packet_info; @@ -242,33 +263,38 @@ void cc1100_packet_monitor(void* payload, int payload_size, protocol_t protocol, * packet * @param pos The current device driver's buffer position */ -static void receive_packet(uint16_t type, uint8_t pos) { +static void receive_packet(uint16_t type, uint8_t pos) +{ uint8_t i = 0; transceiver_type_t t; rx_buffer_pos = pos; msg_t m; - + DEBUG("Packet received\n"); - switch (type) { + + switch(type) { case RCV_PKT_CC1020: t = TRANSCEIVER_CC1020; break; + case RCV_PKT_CC1100: t = TRANSCEIVER_CC1100; break; + default: t = TRANSCEIVER_NONE; break; } /* search first free position in transceiver buffer */ - for (i = 0; (i < TRANSCEIVER_BUFFER_SIZE) && (transceiver_buffer[transceiver_buffer_pos].processing); i++) { - if (++transceiver_buffer_pos == TRANSCEIVER_BUFFER_SIZE) { + for(i = 0; (i < TRANSCEIVER_BUFFER_SIZE) && (transceiver_buffer[transceiver_buffer_pos].processing); i++) { + if(++transceiver_buffer_pos == TRANSCEIVER_BUFFER_SIZE) { transceiver_buffer_pos = 0; } } + /* no buffer left */ - if (i >= TRANSCEIVER_BUFFER_SIZE) { + if(i >= TRANSCEIVER_BUFFER_SIZE) { /* inform upper layers of lost packet */ m.type = ENOBUFFER; m.content.value = t; @@ -278,9 +304,9 @@ static void receive_packet(uint16_t type, uint8_t pos) { radio_packet_t *trans_p = &(transceiver_buffer[transceiver_buffer_pos]); m.type = PKT_PENDING; - if (type == RCV_PKT_CC1100) { + if(type == RCV_PKT_CC1100) { #ifdef MODULE_CC110X_NG - receive_cc110x_packet(trans_p); + receive_cc110x_packet(trans_p); #else receive_cc1100_packet(trans_p); #endif @@ -294,14 +320,17 @@ static void receive_packet(uint16_t type, uint8_t pos) { /* finally notify waiting upper layers * this is done non-blocking, so packets can get lost */ i = 0; - while (reg[i].transceivers != TRANSCEIVER_NONE) { - if (reg[i].transceivers & t) { - m.content.ptr = (char*) &(transceiver_buffer[transceiver_buffer_pos]); + + while(reg[i].transceivers != TRANSCEIVER_NONE) { + if(reg[i].transceivers & t) { + m.content.ptr = (char *) & (transceiver_buffer[transceiver_buffer_pos]); DEBUG("Notify thread %i\n", reg[i].pid); - if (msg_send(&m, reg[i].pid, false) && (m.type != ENOBUFFER)) { + + if(msg_send(&m, reg[i].pid, false) && (m.type != ENOBUFFER)) { transceiver_buffer[transceiver_buffer_pos].processing++; } } + i++; } } @@ -312,41 +341,43 @@ static void receive_packet(uint16_t type, uint8_t pos) { * * @param trans_p The current entry in the transceiver buffer */ -static void receive_cc110x_packet(radio_packet_t *trans_p) { +static void receive_cc110x_packet(radio_packet_t *trans_p) +{ DEBUG("Handling CC1100 packet\n"); /* disable interrupts while copying packet */ dINT(); cc110x_packet_t p = cc110x_rx_buffer[rx_buffer_pos].packet; - + trans_p->src = p.phy_src; trans_p->dst = p.address; trans_p->rssi = cc110x_rx_buffer[rx_buffer_pos].rssi; trans_p->lqi = cc110x_rx_buffer[rx_buffer_pos].lqi; trans_p->length = p.length - CC1100_HEADER_LENGTH; - memcpy((void*) &(data_buffer[transceiver_buffer_pos * PAYLOAD_SIZE]), p.data, CC1100_MAX_DATA_LENGTH); + memcpy((void *)&(data_buffer[transceiver_buffer_pos * PAYLOAD_SIZE]), p.data, CC1100_MAX_DATA_LENGTH); eINT(); DEBUG("Packet %p was from %hu to %hu, size: %u\n", trans_p, trans_p->src, trans_p->dst, trans_p->length); - trans_p->data = (uint8_t*) &(data_buffer[transceiver_buffer_pos * CC1100_MAX_DATA_LENGTH]); + trans_p->data = (uint8_t *)&(data_buffer[transceiver_buffer_pos * CC1100_MAX_DATA_LENGTH]); } #endif #ifdef MODULE_CC110X -void receive_cc1100_packet(radio_packet_t *trans_p) { +void receive_cc1100_packet(radio_packet_t *trans_p) +{ dINT(); trans_p->src = cc1100_packet_info->source; trans_p->dst = cc1100_packet_info->destination; trans_p->rssi = cc1100_packet_info->rssi; trans_p->lqi = cc1100_packet_info->lqi; trans_p->length = cc1100_payload_size; - memcpy((void*) &(data_buffer[transceiver_buffer_pos * PAYLOAD_SIZE]), cc1100_payload, CC1100_MAX_DATA_LENGTH); + memcpy((void *)&(data_buffer[transceiver_buffer_pos * PAYLOAD_SIZE]), cc1100_payload, CC1100_MAX_DATA_LENGTH); eINT(); - trans_p->data = (uint8_t*) &(data_buffer[transceiver_buffer_pos * CC1100_MAX_DATA_LENGTH]); + trans_p->data = (uint8_t *)&(data_buffer[transceiver_buffer_pos * CC1100_MAX_DATA_LENGTH]); } #endif - + /*------------------------------------------------------------------------------------*/ /* * @brief Sends a radio packet to the receiver @@ -356,18 +387,19 @@ void receive_cc1100_packet(radio_packet_t *trans_p) { * * @return 1 on success, 0 otherwise */ -static uint8_t send_packet(transceiver_type_t t, void *pkt) { +static uint8_t send_packet(transceiver_type_t t, void *pkt) +{ uint8_t res = 0; #ifdef MODULE_CC110X int snd_ret; #endif - radio_packet_t p = *((radio_packet_t*) pkt); - + radio_packet_t p = *((radio_packet_t *)pkt); + #ifdef MODULE_CC110X_NG cc110x_packet_t cc110x_pkt; #endif - switch (t) { + switch(t) { case TRANSCEIVER_CC1100: #ifdef MODULE_CC110X_NG cc110x_pkt.length = p.length + CC1100_HEADER_LENGTH; @@ -377,19 +409,23 @@ static uint8_t send_packet(transceiver_type_t t, void *pkt) { res = cc110x_send(&cc110x_pkt); #else memcpy(cc1100_pkt, p.data, p.length); - if ((snd_ret = cc1100_send_csmaca(p.dst, 4, 0, (char*) cc1100_pkt, p.length)) < 0) { + + if((snd_ret = cc1100_send_csmaca(p.dst, 4, 0, (char *) cc1100_pkt, p.length)) < 0) { DEBUG("snd_ret (%u) = %i\n", p.length, snd_ret); res = 0; } else { res = 1; } + #endif break; + default: puts("Unknown transceiver"); break; } + return res; } @@ -402,15 +438,18 @@ static uint8_t send_packet(transceiver_type_t t, void *pkt) { * * @return The radio channel AFTER calling the set command, -1 on error */ -static int16_t set_channel(transceiver_type_t t, void *channel) { - uint8_t c = *((uint8_t*) channel); - switch (t) { +static int16_t set_channel(transceiver_type_t t, void *channel) +{ + uint8_t c = *((uint8_t *)channel); + + switch(t) { case TRANSCEIVER_CC1100: #ifdef MODULE_CC110X_NG return cc110x_set_channel(c); #else return cc1100_set_channel(c); #endif + default: return -1; } @@ -423,14 +462,16 @@ static int16_t set_channel(transceiver_type_t t, void *channel) { * * @return The current radio channel of the transceiver, -1 on error */ -static int16_t get_channel(transceiver_type_t t) { - switch (t) { +static int16_t get_channel(transceiver_type_t t) +{ + switch(t) { case TRANSCEIVER_CC1100: #ifdef MODULE_CC110X_NG return cc110x_get_channel(); #else return cc1100_get_channel(); #endif + default: return -1; } @@ -443,14 +484,16 @@ static int16_t get_channel(transceiver_type_t t) { * * @return The configured address of the device, -1 on error */ -static int16_t get_address(transceiver_type_t t) { - switch (t) { +static int16_t get_address(transceiver_type_t t) +{ + switch(t) { case TRANSCEIVER_CC1100: #ifdef MODULE_CC110X_NG return cc110x_get_address(); #else return cc1100_get_address(); #endif + default: return -1; } @@ -464,15 +507,18 @@ static int16_t get_address(transceiver_type_t t) { * * @return The new radio address of the device */ -static int16_t set_address(transceiver_type_t t, void *address) { - radio_address_t addr = *((radio_address_t*) address); - switch (t) { +static int16_t set_address(transceiver_type_t t, void *address) +{ + radio_address_t addr = *((radio_address_t *)address); + + switch(t) { case TRANSCEIVER_CC1100: #ifdef MODULE_CC110X_NG return cc110x_set_address(addr); #else return cc1100_set_address(addr); #endif + default: return -1; } @@ -484,50 +530,59 @@ static int16_t set_address(transceiver_type_t t, void *address) { * @param t The transceiver device * @param mode 1 for enabling monitor mode, 0 for enabling address check */ -static void set_monitor(transceiver_type_t t, void *mode) { - switch (t) { +static void set_monitor(transceiver_type_t t, void *mode) +{ + switch(t) { case TRANSCEIVER_CC1100: #ifdef MODULE_CC110X_NG - cc110x_set_monitor(*((uint8_t*) mode)); + cc110x_set_monitor(*((uint8_t *)mode)); #endif break; + default: break; } } /*------------------------------------------------------------------------------------*/ -static void powerdown(transceiver_type_t t) { - switch (t) { +static void powerdown(transceiver_type_t t) +{ + switch(t) { case TRANSCEIVER_CC1100: #ifdef MODULE_CC110X_NG cc110x_switch_to_pwd(); #endif break; + default: break; } } /*------------------------------------------------------------------------------------*/ -static void switch_to_rx(transceiver_type_t t) { - switch (t) { +static void switch_to_rx(transceiver_type_t t) +{ + switch(t) { case TRANSCEIVER_CC1100: #ifdef MODULE_CC110X_NG cc110x_switch_to_rx(); #endif break; + default: break; } } #ifdef DBG_IGNORE -static void ignore_add(transceiver_type_t t, void *address) { - radio_address_t addr = *((radio_address_t*) address); - switch (t) { +static void ignore_add(transceiver_type_t t, void *address) +{ + radio_address_t addr = *((radio_address_t *)address); + + switch(t) { case TRANSCEIVER_CC1100: cc110x_add_ignored(addr); break; + default: break; } diff --git a/sys/uart0/uart0.c b/sys/uart0/uart0.c index 5ba90d98ab..56dc5875a1 100644 --- a/sys/uart0/uart0.c +++ b/sys/uart0/uart0.c @@ -17,33 +17,39 @@ static char buffer[UART0_BUFSIZE]; static char uart0_thread_stack[UART0_STACKSIZE]; -static void uart0_loop(void) { +static void uart0_loop(void) +{ chardev_loop(&uart0_ringbuffer); } -void board_uart0_init(void) { +void board_uart0_init(void) +{ ringbuffer_init(&uart0_ringbuffer, buffer, UART0_BUFSIZE); - int pid = thread_create(uart0_thread_stack, sizeof(uart0_thread_stack), PRIORITY_MAIN-1, CREATE_STACKTEST, uart0_loop, "uart0"); + int pid = thread_create(uart0_thread_stack, sizeof(uart0_thread_stack), PRIORITY_MAIN - 1, CREATE_STACKTEST, uart0_loop, "uart0"); uart0_handler_pid = pid; puts("uart0_init() [OK]"); } -void uart0_handle_incoming(int c) { +void uart0_handle_incoming(int c) +{ rb_add_element(&uart0_ringbuffer, c); } -void uart0_notify_thread(void) { +void uart0_notify_thread(void) +{ msg_t m; m.type = 0; msg_send_int(&m, uart0_handler_pid); } -int uart0_readc(void) { +int uart0_readc(void) +{ char c = 0; posix_read(uart0_handler_pid, &c, 1); return c; } -void uart0_putc(int c) { +void uart0_putc(int c) +{ putchar(c); } diff --git a/sys/vtimer/vtimer.c b/sys/vtimer/vtimer.c index 15c46b368d..332b69d753 100644 --- a/sys/vtimer/vtimer.c +++ b/sys/vtimer/vtimer.c @@ -27,7 +27,7 @@ static int set_longterm(vtimer_t *timer); static int set_shortterm(vtimer_t *timer); #ifdef ENABLE_DEBUG -static void vtimer_print(vtimer_t* t); +static void vtimer_print(vtimer_t *t); #endif static queue_node_t longterm_queue_root; @@ -42,17 +42,20 @@ static uint32_t hwtimer_next_absolute; static uint32_t seconds = 0; -static int set_longterm(vtimer_t *timer) { +static int set_longterm(vtimer_t *timer) +{ timer->queue_entry.priority = timer->absolute.seconds; - queue_priority_add(&longterm_queue_root, (queue_node_t*)timer); + queue_priority_add(&longterm_queue_root, (queue_node_t *)timer); return 0; } -static int update_shortterm(void) { - if (hwtimer_id != -1) { - if (hwtimer_next_absolute != shortterm_queue_root.next->priority) { +static int update_shortterm(void) +{ + if(hwtimer_id != -1) { + if(hwtimer_next_absolute != shortterm_queue_root.next->priority) { hwtimer_remove(hwtimer_id); - } else { + } + else { return 0; } } @@ -62,17 +65,18 @@ static int update_shortterm(void) { unsigned int next = hwtimer_next_absolute + longterm_tick_start; unsigned int now = hwtimer_now(); - if((next - VTIMER_THRESHOLD - now) > MICROSECONDS_PER_TICK ) { + if((next - VTIMER_THRESHOLD - now) > MICROSECONDS_PER_TICK) { next = now + VTIMER_BACKOFF; } - + hwtimer_id = hwtimer_set_absolute(next, vtimer_callback, NULL); DEBUG("update_shortterm: Set hwtimer to %lu (now=%lu)\n", hwtimer_next_absolute + longterm_tick_start, hwtimer_now()); return 0; } -void vtimer_tick(void *ptr) { +void vtimer_tick(void *ptr) +{ DEBUG("vtimer_tick()."); seconds += SECONDS_PER_TICK; @@ -80,12 +84,14 @@ void vtimer_tick(void *ptr) { longterm_tick_timer.absolute.microseconds = longterm_tick_timer.absolute.microseconds + MICROSECONDS_PER_TICK; set_shortterm(&longterm_tick_timer); - while (longterm_queue_root.next) { - vtimer_t *timer = (vtimer_t*) longterm_queue_root.next; - if (timer->absolute.seconds == seconds) { - timer = (vtimer_t*) queue_remove_head(&longterm_queue_root); + while(longterm_queue_root.next) { + vtimer_t *timer = (vtimer_t *) longterm_queue_root.next; + + if(timer->absolute.seconds == seconds) { + timer = (vtimer_t *) queue_remove_head(&longterm_queue_root); set_shortterm(timer); - } else { + } + else { break; } } @@ -93,14 +99,16 @@ void vtimer_tick(void *ptr) { update_shortterm(); } -static int set_shortterm(vtimer_t *timer) { +static int set_shortterm(vtimer_t *timer) +{ DEBUG("set_shortterm(): Absolute: %lu %lu\n", timer->absolute.seconds, timer->absolute.microseconds); timer->queue_entry.priority = timer->absolute.microseconds; - queue_priority_add(&shortterm_queue_root, (queue_node_t*)timer); + queue_priority_add(&shortterm_queue_root, (queue_node_t *)timer); return 1; } -void vtimer_callback(void *ptr) { +void vtimer_callback(void *ptr) +{ vtimer_t *timer; in_callback = true; hwtimer_id = -1; @@ -113,38 +121,44 @@ void vtimer_callback(void *ptr) { DEBUG("vtimer_callback(): Shooting %lu.\n", timer->absolute.microseconds); /* shoot timer */ - if (timer->action == (void*) msg_send_int) { - msg_t msg; + if(timer->action == (void *) msg_send_int) { + msg_t msg; msg.type = MSG_TIMER; msg.content.value = (unsigned int) timer->arg; msg_send_int(&msg, timer->pid); - } else { + } + else { timer->action(timer->arg); - } + } in_callback = false; update_shortterm(); } -void normalize_to_tick(timex_t *time) { +void normalize_to_tick(timex_t *time) +{ DEBUG("Normalizing: %lu %lu\n", time->seconds, time->microseconds); uint32_t seconds_tmp = time->seconds % SECONDS_PER_TICK; time->seconds -= seconds_tmp; uint32_t usecs_tmp = time->microseconds + (seconds_tmp * 1000000); DEBUG("Normalizin2: %lu %lu\n", time->seconds, usecs_tmp); - if (usecs_tmp < time->microseconds) { + + if(usecs_tmp < time->microseconds) { usecs_tmp -= MICROSECONDS_PER_TICK; time->seconds += SECONDS_PER_TICK; } - if (usecs_tmp > MICROSECONDS_PER_TICK) { + + if(usecs_tmp > MICROSECONDS_PER_TICK) { usecs_tmp -= MICROSECONDS_PER_TICK; time->seconds += SECONDS_PER_TICK; } + time->microseconds = usecs_tmp; DEBUG(" Result: %lu %lu\n", time->seconds, time->microseconds); } -static int vtimer_set(vtimer_t *timer) { +static int vtimer_set(vtimer_t *timer) +{ DEBUG("vtimer_set(): New timer. Offset: %lu %lu\n", timer->absolute.seconds, timer->absolute.microseconds); timex_t now; @@ -156,26 +170,28 @@ static int vtimer_set(vtimer_t *timer) { int result = 0; - if (timer->absolute.seconds == 0) { - if (timer->absolute.microseconds > 10) { + if(timer->absolute.seconds == 0) { + if(timer->absolute.microseconds > 10) { timer->absolute.microseconds -= 10; } } int state = disableIRQ(); - if (timer->absolute.seconds != seconds){ + + if(timer->absolute.seconds != seconds) { /* we're long-term */ DEBUG("vtimer_set(): setting long_term\n"); result = set_longterm(timer); } else { DEBUG("vtimer_set(): setting short_term\n"); - if (set_shortterm(timer)) { - /* delay update of next shortterm timer if we + if(set_shortterm(timer)) { + + /* delay update of next shortterm timer if we * are called from within vtimer_callback. */ - - if (!in_callback) { + + if(!in_callback) { result = update_shortterm(); } } @@ -187,19 +203,21 @@ static int vtimer_set(vtimer_t *timer) { return result; } -void vtimer_now(timex_t* out) { - timex_t t = timex_set(seconds, hwtimer_now()-longterm_tick_start); +void vtimer_now(timex_t *out) +{ + timex_t t = timex_set(seconds, hwtimer_now() - longterm_tick_start); memcpy(out, &t, sizeof(timex_t)); } -int vtimer_init() { +int vtimer_init() +{ DEBUG("vtimer_init().\n"); int state = disableIRQ(); seconds = 0; longterm_tick_timer.action = vtimer_tick; longterm_tick_timer.arg = NULL; - + longterm_tick_timer.absolute.seconds = 0; longterm_tick_timer.absolute.microseconds = MICROSECONDS_PER_TICK; @@ -212,22 +230,25 @@ int vtimer_init() { return 0; } -int vtimer_set_wakeup(vtimer_t *t, timex_t interval, int pid) { +int vtimer_set_wakeup(vtimer_t *t, timex_t interval, int pid) +{ int ret; - t->action = (void*) thread_wakeup; - t->arg = (void*) pid; + t->action = (void *) thread_wakeup; + t->arg = (void *) pid; t->absolute = interval; t->pid = 0; ret = vtimer_set(t); return ret; } -int vtimer_usleep(uint32_t usecs) { +int vtimer_usleep(uint32_t usecs) +{ timex_t offset = timex_set(0, usecs); return vtimer_sleep(offset); } -int vtimer_sleep(timex_t time) { +int vtimer_sleep(timex_t time) +{ int ret; vtimer_t t; ret = vtimer_set_wakeup(&t, time, thread_getpid()); @@ -235,32 +256,38 @@ int vtimer_sleep(timex_t time) { return ret; } -int vtimer_remove(vtimer_t *t){ - queue_remove(&shortterm_queue_root, (queue_node_t*)t); - queue_remove(&longterm_queue_root, (queue_node_t*)t); - +int vtimer_remove(vtimer_t *t) +{ + queue_remove(&shortterm_queue_root, (queue_node_t *)t); + queue_remove(&longterm_queue_root, (queue_node_t *)t); + update_shortterm(); - - if (! inISR() ) eINT(); - return 0; + + if(! inISR()) { + eINT(); + } + + return 0; } -int vtimer_set_msg(vtimer_t *t, timex_t interval, unsigned int pid, void *ptr){ - t->action = (void* ) msg_send_int; +int vtimer_set_msg(vtimer_t *t, timex_t interval, unsigned int pid, void *ptr) +{ + t->action = (void *) msg_send_int; t->arg = ptr; t->absolute = interval; - t->pid = pid; + t->pid = pid; vtimer_set(t); return 0; } -void vtimer_print(vtimer_t* t) { +void vtimer_print(vtimer_t *t) +{ printf("Seconds: %u - Microseconds: %u\n \ action: %p\n \ action: %p\n \ pid: %u\n", - t->absolute.seconds, t->absolute.microseconds, - t->action, - t->arg, - t->pid); + t->absolute.seconds, t->absolute.microseconds, + t->action, + t->arg, + t->pid); }