1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

coding conventions for most of system libraries

This commit is contained in:
Oliver Hahm 2013-06-22 05:11:53 +02:00
parent f359453083
commit 5c52e1ce2e
66 changed files with 6664 additions and 5015 deletions

View File

@ -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();

View File

@ -1,5 +1,5 @@
/**
* Character device messaging loop.
* Character device messaging loop.
*
* Copyright (C) 2013, INRIA.
*
@ -28,12 +28,18 @@
//#define ENABLE_DEBUG
#include <debug.h>
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);

View File

@ -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 <oliver.hahm@inria.fr>
* @}
*/

View File

@ -1,5 +1,5 @@
#ifndef __BOARD_UART0_H
#define __BOARD_UART0_H
#define __BOARD_UART0_H
extern int uart0_handler_pid;

View File

@ -1,5 +1,5 @@
#ifndef __CHARDEV_THREAD_H
#define __CHARDEV_THREAD_H
#define __CHARDEV_THREAD_H
#include <ringbuffer.h>

View File

@ -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;

View File

@ -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 */

View File

@ -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 */

View File

@ -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];
/** @} */

View File

@ -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 <hillebra@inf.fu-berlin.de>
* @author Oliver Hahm <oliver.hahm@inria.fr>
* @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_ */

View File

@ -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;
/**

View File

@ -1,5 +1,5 @@
#ifndef __SHELL_COMMANDS_H
#define __SHELL_COMMANDS_H
#define __SHELL_COMMANDS_H
#include <shell.h>

View File

@ -1,5 +1,5 @@
#ifndef __TIMEX_H
#define __TIMEX_H
#define __TIMEX_H
#include <stdint.h>
@ -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);

View File

@ -1,5 +1,5 @@
#ifndef TRANSCEIVER_H
#define TRANSCEIVER_H
#define TRANSCEIVER_H
#include <radio/types.h>
@ -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
**/

View File

@ -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 */

File diff suppressed because it is too large Load Diff

View File

@ -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.

File diff suppressed because it is too large Load Diff

View File

@ -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.

View File

@ -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 <mlenders@inf.fu-berlin.de>
* @author Oliver Hahm <oliver.hahm@inria.fr>
* @}
*/
#include <stdio.h>
#include <string.h>
@ -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);
}

View File

@ -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 <mlenders@inf.fu-berlin.de>
* @author Oliver Hahm <oliver.hahm@inria.fr>
* @}
*/
#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;

View File

@ -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 <mlenders@inf.fu-berlin.de>
* @author Oliver Hahm <oliver.hahm@inria.fr>
* @}
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@ -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);
}
}

View File

@ -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 <mlenders@inf.fu-berlin.de>
* @author Oliver Hahm <oliver.hahm@inria.fr>
* @}
*/
#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;

View File

@ -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 <zeisberg@mi.fu-berlin.de>
* @author Oliver Hahm <oliver.hahm@inria.fr>
* @}
*/
#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);
}

View File

@ -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 <zeisberg@mi.fu-berlin.de>
* @author Oliver Hahm <oliver.hahm@inria.fr>
* @}
*/
#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;

View File

@ -1,6 +1,7 @@
#include "objective_functions.h"
void of0(void){
void of0(void)
{
}

View File

@ -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 <eric.engel@fu-berlin.de>
* @}
*/
#include <string.h>
#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;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,21 @@
/**
* RPL 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 rpl.h
* @brief RPL header
* @author Eric Engel <eric.engel@fu-berlin.de>
* @}
*/
#include <string.h>
#include <stdint.h>
#include <vtimer.h>
#include <mutex.h>
@ -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);

View File

@ -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 <eric.engel@fu-berlin.de>
* @}
*/
#include <string.h>
#include <string.h>
#include <stdio.h>
@ -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;i<RPL_MAX_INSTANCES;i++){
if( instances[i].used && (instances[i].id == instanceid)){
return &instances[i];
}
}
return NULL;
rpl_instance_t *rpl_get_instance(uint8_t instanceid)
{
for(int i = 0; i < RPL_MAX_INSTANCES; i++) {
if(instances[i].used && (instances[i].id == instanceid)) {
return &instances[i];
}
}
return NULL;
}
rpl_instance_t *rpl_get_my_instance(){
for(int i=0;i<RPL_MAX_INSTANCES;i++){
if(instances[i].joined){
return &instances[i];
}
}
return NULL;
rpl_instance_t *rpl_get_my_instance()
{
for(int i = 0; i < RPL_MAX_INSTANCES; i++) {
if(instances[i].joined) {
return &instances[i];
}
}
return NULL;
}
rpl_dodag_t * rpl_new_dodag(uint8_t instanceid, ipv6_addr_t *dodagid){
rpl_instance_t * inst;
inst = rpl_get_instance(instanceid);
if(inst == NULL){
printf("Error - No instance found for id %d. This should not happen\n", instanceid);
return NULL;
}
rpl_dodag_t *rpl_new_dodag(uint8_t instanceid, ipv6_addr_t *dodagid)
{
rpl_instance_t *inst;
inst = rpl_get_instance(instanceid);
rpl_dodag_t *dodag;
rpl_dodag_t *end;
if(inst == NULL) {
printf("Error - No instance found for id %d. This should not happen\n",
instanceid);
return NULL;
}
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 *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;i<RPL_MAX_DODAGS;i++){
if( dodags[i].used && (rpl_equal_id(&dodags[i].dodag_id, id))){
return &dodags[i];
}
}
return NULL;
rpl_dodag_t *rpl_get_dodag(ipv6_addr_t *id)
{
for(int i = 0; i < RPL_MAX_DODAGS; i++) {
if(dodags[i].used && (rpl_equal_id(&dodags[i].dodag_id, id))) {
return &dodags[i];
}
}
return NULL;
}
rpl_dodag_t *rpl_get_my_dodag(){
for(int i=0;i<RPL_MAX_DODAGS;i++){
if( dodags[i].joined){
return &dodags[i];
}
}
return NULL;
rpl_dodag_t *rpl_get_my_dodag()
{
for(int i = 0; i < RPL_MAX_DODAGS; i++) {
if(dodags[i].joined) {
return &dodags[i];
}
}
return NULL;
}
void rpl_del_dodag(rpl_dodag_t *dodag){
memset(dodag, 0, sizeof(*dodag));
void rpl_del_dodag(rpl_dodag_t *dodag)
{
memset(dodag, 0, sizeof(*dodag));
}
void rpl_leave_dodag(rpl_dodag_t * dodag){
dodag->joined = 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<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_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;i<RPL_MAX_PARENTS;i++){
memset(&parents[i],0,sizeof(parents[i]));
}
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; 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;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]);
}
}
}
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;
}

View File

@ -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 <eric.engel@fu-berlin.de>
* @}
*/
#include <string.h>
#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);

View File

@ -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 <eric.engel@fu-berlin.de>
* @}
*/
#include <string.h>
#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) && (RPL_COUNTER_LOWER_REGION + 1 - B + A < RPL_COUNTER_SEQ_WINDOW)) || ((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

View File

@ -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 <eric.engel@fu-berlin.de>
* @}
*/
#include <string.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
@ -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; 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);
}
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);
}
}

View File

@ -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 <eric.engel@fu-berlin.de>
* @}
*/
#include <vtimer.h>
#include <thread.h>
#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);

View File

@ -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 <mlenders@inf.fu-berlin.de>
* @author Oliver Hahm <oliver.hahm@inria.fr>
* @}
*/
#include <mutex.h>
#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;
}

View File

@ -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 <mlenders@inf.fu-berlin.de>
* @author Oliver Hahm <oliver.hahm@inria.fr>
* @}
*/
#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*/

View File

@ -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 <mlenders@inf.fu-berlin.de>
* @author Oliver Hahm <oliver.hahm@inria.fr>
* @}
*/
#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;
}

View File

@ -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 <mlenders@inf.fu-berlin.de>
* @author Oliver Hahm <oliver.hahm@inria.fr>
* @}
*/
#include <stdint.h>
#include <string.h>
#include <stdio.h>
@ -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);
}
}

View File

@ -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 <mlenders@inf.fu-berlin.de>
* @author Oliver Hahm <oliver.hahm@inria.fr>
* @}
*/
/* 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);

View File

@ -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 <zeisberg@mi.fu-berlin.de>
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
* @author Eric Engel <eric.engel@fu-berlin.de>
* @author Oliver Gesch <oliver.gesch@googlemail.com>
* @}
*/
#include <stdio.h>
#include <string.h>
#include <vtimer.h>
@ -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;
}

View File

@ -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 <zeisberg@mi.fu-berlin.de>
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
* @author Eric Engel <eric.engel@fu-berlin.de>
* @author Oliver Gesch <oliver.gesch@googlemail.com>
* @}
*/
/* 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,

View File

@ -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 <zeisberg@mi.fu-berlin.de>
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
* @author Eric Engel <eric.engel@fu-berlin.de>
* @author Oliver Gesch <oliver.gesch@googlemail.com>
* @}
*/
#include <stdlib.h>
#include <string.h>
@ -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;
}

View File

@ -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 <zeisberg@mi.fu-berlin.de>
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
* @author Eric Engel <eric.engel@fu-berlin.de>
* @author Oliver Gesch <oliver.gesch@googlemail.com>
* @}
*/
#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*/

File diff suppressed because it is too large Load Diff

View File

@ -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 <zeisberg@mi.fu-berlin.de>
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
* @author Oliver Gesch <oliver.gesch@googlemail.com>
* @}
*/
#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);

File diff suppressed because it is too large Load Diff

View File

@ -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 <zeisberg@mi.fu-berlin.de>
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
* @author Oliver Gesch <oliver.gesch@googlemail.com>
* @author Eric Engel <eric.engel@fu-berlin.de>
* @}
*/
#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);

View File

@ -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 <kaspar@schleiser.de>
* @}
*/
@ -21,7 +21,8 @@
#include <posix_io.h>
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);
}

View File

@ -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 <kaspar@schleiser.de>
* @}
*/
@ -22,7 +22,7 @@
#include <stdio.h>
/* 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);
}

View File

@ -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 <oliver.hahm@inria.fr>
* @}
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@ -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 <ADDR> <MSG>");
puts("Usage:\ttxtsnd <ADDR> <MSG>");
}
#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!");
}
}

View File

@ -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 <oliver.hahm@inria.fr>
* @}
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -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 <ADDR> <MSG>");
}
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);

View File

@ -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 <oliver.hahm@inria.fr>
* @}
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@ -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 <OFFSET> <LENGTH>\n", DISK_READ_BYTES_CMD);
}

View File

@ -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 <oliver.hahm@inria.fr>
* @}
*/
#include <stdio.h>
#include <string.h>
#include <config.h>
#include <stdlib.h>
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
}
}

View File

@ -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 <oliver.hahm@inria.fr>
* @}
*/
#include <stdio.h>
#include <ltc4150.h>
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();
}

View File

@ -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 <oliver.hahm@inria.fr>
* @}
*/
#include "ps.h"
void _ps_handler(char* unnused) {
void _ps_handler(char *unnused)
{
thread_print_all();
}

View File

@ -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 <oliver.hahm@inria.fr>
* @}
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
@ -5,46 +22,49 @@
#ifdef MODULE_RTC
#include <rtc.h>
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

View File

@ -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 <oliver.hahm@inria.fr>
* @}
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
@ -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 <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 <OFFSET>");
}
else {
sht11_temperature_offset = atoi(offset + 7);
printf("Temperature offset set to %f\n", (double) sht11_temperature_offset);
}
}
#endif

View File

@ -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 <oliver.hahm@inria.fr>
* @}
*/
#include <shell_commands.h>
#include <stdlib.h>
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

View File

@ -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 <stdint.h>
#include <stdlib.h>
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;

View File

@ -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

View File

@ -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,
"<log lvl=%u src=\"%u.%u\" id=%u ts=\"%s\" mod=\"%s\">%s</log>\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,
"<log lvl=%u src=\"%u.%u\" id=%u ts=\"%s\" mod=\"%s\">%s</log>\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

View File

@ -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;
}
/** @} */

View File

@ -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
/*-----------------------------------------------------------------------------------*/

View File

@ -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 <cc1100-interface.h>
#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 <cc110x_ng.h>
#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;
}

View File

@ -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);
}

View File

@ -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);
}