1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-01-18 12:52:44 +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

@ -27,7 +27,8 @@
extern int main(void); extern int main(void);
void auto_init(void) { void auto_init(void)
{
#ifdef MODULE_BOARD_DISPLAY #ifdef MODULE_BOARD_DISPLAY
extern void lcd_init(); extern void lcd_init();
lcd_init(); lcd_init();

View File

@ -28,12 +28,18 @@
//#define ENABLE_DEBUG //#define ENABLE_DEBUG
#include <debug.h> #include <debug.h>
static int min(int a, int b) { static int min(int a, int b)
if (b>a) return a; {
else return b; if(b > a) {
return a;
}
else {
return b;
}
} }
void chardev_loop(ringbuffer_t *rb) { void chardev_loop(ringbuffer_t *rb)
{
msg_t m; msg_t m;
int pid = thread_getpid(); int pid = thread_getpid();
@ -43,14 +49,15 @@ void chardev_loop(ringbuffer_t *rb) {
puts("UART0 thread started."); puts("UART0 thread started.");
while (1) { while(1) {
msg_receive(&m); msg_receive(&m);
if (m.sender_pid != pid) { if(m.sender_pid != pid) {
DEBUG("Receiving message from another thread\n"); DEBUG("Receiving message from another thread\n");
switch (m.type) {
switch(m.type) {
case OPEN: case OPEN:
if (reader_pid == -1) { if(reader_pid == -1) {
reader_pid = m.sender_pid; reader_pid = m.sender_pid;
/* no error */ /* no error */
m.content.value = 0; m.content.value = 0;
@ -58,10 +65,12 @@ void chardev_loop(ringbuffer_t *rb) {
else { else {
m.content.value = -EBUSY; m.content.value = -EBUSY;
} }
msg_reply(&m,&m);
msg_reply(&m, &m);
break; break;
case READ: case READ:
if (m.sender_pid != reader_pid) { if(m.sender_pid != reader_pid) {
m.content.value = -EINVAL; m.content.value = -EINVAL;
r = NULL; r = NULL;
msg_reply(&m, &m); msg_reply(&m, &m);
@ -69,9 +78,11 @@ void chardev_loop(ringbuffer_t *rb) {
else { else {
r = (struct posix_iop_t *)m.content.ptr; r = (struct posix_iop_t *)m.content.ptr;
} }
break; break;
case CLOSE: case CLOSE:
if (m.sender_pid == reader_pid) { if(m.sender_pid == reader_pid) {
DEBUG("uart0_thread: closing file from %i\n", reader_pid); DEBUG("uart0_thread: closing file from %i\n", reader_pid);
reader_pid = -1; reader_pid = -1;
r = NULL; r = NULL;
@ -80,15 +91,17 @@ void chardev_loop(ringbuffer_t *rb) {
else { else {
m.content.value = -EINVAL; m.content.value = -EINVAL;
} }
msg_reply(&m,&m);
msg_reply(&m, &m);
break; break;
default: default:
m.content.value = -EINVAL; m.content.value = -EINVAL;
msg_reply(&m, &m); msg_reply(&m, &m);
} }
} }
if (rb->avail && (r != NULL)) { if(rb->avail && (r != NULL)) {
int state = disableIRQ(); int state = disableIRQ();
int nbytes = min(r->nbytes, rb->avail); 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); 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.sender_pid = reader_pid;
m.type = OPEN; m.type = OPEN;
m.content.ptr = (char*)r; m.content.ptr = (char *)r;
msg_reply(&m, &m); msg_reply(&m, &m);

View File

@ -14,12 +14,12 @@ static void pong_handler(void *payload, int payload_size,
packet_info_t *packet_info); packet_info_t *packet_info);
void pong(uint16_t src); void pong(uint16_t src);
typedef struct pong{ typedef struct pong {
int hopcount; int hopcount;
int ttl; int ttl;
radio_address_t radio_address; radio_address_t radio_address;
} ping_r; } ping_r;
typedef struct ping_payload{ typedef struct ping_payload {
char* payload; char *payload;
} ping_payload; } ping_payload;

View File

@ -13,7 +13,7 @@ struct posix_iop_t {
int posix_open(int pid, int flags); int posix_open(int pid, int flags);
int posix_close(int pid); int posix_close(int pid);
int posix_read(int pid, char* buffer, int bufsize); int posix_read(int pid, char *buffer, int bufsize);
int posix_write(int pid, char* buffer, int bufsize); int posix_write(int pid, char *buffer, int bufsize);
#endif /* __READ_H */ #endif /* __READ_H */

View File

@ -2,6 +2,6 @@
#define __PS_H #define __PS_H
void thread_print_all(void); void thread_print_all(void);
void _ps_handler(char*); void _ps_handler(char *);
#endif /* __PS_H */ #endif /* __PS_H */

View File

@ -1,28 +1,14 @@
/****************************************************************************** /**
Copyright 2008-2009 , Freie Universitaet Berlin (FUB). All rights reserved. * Generic radio driver interface
*
These sources were developed at the Freie Universitaet Berlin, Computer Systems * Copyright (C) 2008-2009 Freie Universitaet Berlin (FUB).
and Telematics group (http://cst.mi.fu-berlin.de). * Copyright (C) 2013 INRIA.
------------------------------------------------------------------------------- *
This file is part of RIOT. * 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
This program is free software: you can redistribute it and/or modify it under * details.
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
*******************************************************************************/
#ifndef RADIO_H_ #ifndef RADIO_H_
#define RADIO_H_ #define RADIO_H_
@ -58,8 +44,7 @@ and the mailinglist (subscription via web site)
#define L1_PROTOCOL_CATCH_ALL (0xff) ///< Catch all protocol ID #define L1_PROTOCOL_CATCH_ALL (0xff) ///< Catch all protocol ID
enum layer_1_protocols enum layer_1_protocols {
{
LAYER_1_PROTOCOL_LL_ACK = 1, ///< Link-Level Acknowledgement (LL-ACK) LAYER_1_PROTOCOL_LL_ACK = 1, ///< Link-Level Acknowledgement (LL-ACK)
LAYER_1_PROTOCOL_MM = 2, ///< Micro Mesh network packet (MM) LAYER_1_PROTOCOL_MM = 2, ///< Micro Mesh network packet (MM)
}; };
@ -67,8 +52,8 @@ enum layer_1_protocols
/** /**
* Radio/MAC API. * Radio/MAC API.
*/ */
typedef struct radio { typedef struct {
const char* name; const char *name;
const radio_address_t broadcast_address; const radio_address_t broadcast_address;
const uint8_t output_power_max; const uint8_t output_power_max;
/** /**
@ -92,7 +77,7 @@ typedef struct radio {
void (*print_config)(void); void (*print_config)(void);
} radio_t; } 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. * Generic radio driver interface data structures and prototypes
*
These sources were developed at the Freie Universitaet Berlin, Computer Systems * Copyright (C) 2009 Freie Universitaet Berlin (FUB).
and Telematics group (http://cst.mi.fu-berlin.de). * Copyright (C) 2013 INRIA.
------------------------------------------------------------------------------- *
This file is part of RIOT. * 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
This program is free software: you can redistribute it and/or modify it under * details.
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
*******************************************************************************/
#ifndef COMMONTYPES_H_ #ifndef COMMONTYPES_H_
#define 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 Freie Universität Berlin, Computer Systems & Telematics
* @author Thomas Hillebrandt <hillebra@inf.fu-berlin.de> * @author Thomas Hillebrandt <hillebra@inf.fu-berlin.de>
* @author Oliver Hahm <oliver.hahm@inria.fr>
* @version $Revision: 2061 $ * @version $Revision: 2061 $
* *
* @note $Id: common-types.h 2061 2010-04-01 12:13:22Z hillebra $ * @note $Id: common-types.h 2061 2010-04-01 12:13:22Z hillebra $
@ -50,8 +37,7 @@ typedef uint16_t radio_address_t; ///< Radio layer address type
/** /**
* @brief Packet transmission priorities of various layers. * @brief Packet transmission priorities of various layers.
*/ */
enum transmission_priorities enum transmission_priorities {
{
PRIORITY_ALARM = 0, PRIORITY_ALARM = 0,
PRIORITY_WARNING = 1, PRIORITY_WARNING = 1,
PRIORITY_DATA = 2 PRIORITY_DATA = 2
@ -62,8 +48,7 @@ enum transmission_priorities
* This struct is passed along all receive functions of * This struct is passed along all receive functions of
* all layers. Each layers fills in additional information. * all layers. Each layers fills in additional information.
*/ */
typedef struct __attribute__ ((packed)) packet_info_t typedef struct __attribute__((packed)) packet_info_t {
{
uint16_t source; ///< Net layer: source uint16_t source; ///< Net layer: source
uint16_t destination; ///< Net layer: destination uint16_t destination; ///< Net layer: destination
radio_address_t phy_src; ///< Radio layer: source radio_address_t phy_src; ///< Radio layer: source
@ -78,7 +63,8 @@ typedef struct __attribute__ ((packed)) packet_info_t
/** /**
* @brief General link layer packet format * @brief General link layer packet format
*/ */
typedef struct __attribute__ ((packed)) { typedef struct __attribute__((packed))
{
uint8_t processing; ///< internal processing state uint8_t processing; ///< internal processing state
uint16_t src; ///< Radio source address uint16_t src; ///< Radio source address
uint16_t dst; ///< Radio destination address uint16_t dst; ///< Radio destination address
@ -87,7 +73,8 @@ typedef struct __attribute__ ((packed)) {
timex_t toa; ///< Time of Arrival timex_t toa; ///< Time of Arrival
uint8_t length; ///< Length of payload uint8_t length; ///< Length of payload
uint8_t *data; ///< 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] payload_size Size of the packet payload data in bytes
* @param [in/out] packet_info Cross-layer meta data * @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 * 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 protocol Protocol type of the packet payload data
* @param packet_info Cross-layer meta 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_ */ #endif /* COMMONTYPES_H_ */

View File

@ -35,9 +35,9 @@ and the mailinglist (subscription via web site)
//#include "hashtable.h" //#include "hashtable.h"
typedef struct shell_command_t { typedef struct shell_command_t {
char* name; char *name;
char* desc; char *desc;
void (*handler)(char*); void (*handler)(char *);
} shell_command_t; } shell_command_t;
typedef struct shell_t { typedef struct shell_t {

View File

@ -34,8 +34,8 @@
typedef struct vtimer_t { typedef struct vtimer_t {
queue_node_t queue_entry; queue_node_t queue_entry;
timex_t absolute; timex_t absolute;
void(*action)(void*); void(*action)(void *);
void* arg; void *arg;
unsigned int pid; unsigned int pid;
} vtimer_t; } vtimer_t;
@ -43,7 +43,7 @@ typedef struct vtimer_t {
* @brief Current system time * @brief Current system time
* @return Time as timex_t since system boot * @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. * @brief Initializes the vtimer subsystem. To be called once at system initialization. Will be initialized by auto_init.
@ -94,6 +94,6 @@ int vtimer_remove(vtimer_t *t);
/** /**
* @brief Prints a vtimer_t * @brief Prints a vtimer_t
*/ */
void vtimer_print(vtimer_t* t); void vtimer_print(vtimer_t *t);
#endif /* __VTIMER_H */ #endif /* __VTIMER_H */

File diff suppressed because it is too large Load Diff

View File

@ -60,8 +60,7 @@ and the mailinglist (subscription via web site)
* | Source | Address[1..n] | * | Source | Address[1..n] |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/ */
typedef struct __attribute__ ((packed)) mmr_rreq_message_t typedef struct __attribute__((packed)) {
{
uint8_t type; ///< Must be first byte in struct for type detection uint8_t type; ///< Must be first byte in struct for type detection
uint8_t length; uint8_t length;
uint16_t destination; uint16_t destination;
@ -80,8 +79,7 @@ typedef struct __attribute__ ((packed)) mmr_rreq_message_t
* | Source | Address[1..n] | * | Source | Address[1..n] |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/ */
typedef struct __attribute__ ((packed)) mmr_rrep_message_t typedef struct __attribute__((packed)) {
{
uint8_t type; ///< Must be first byte in struct for type detection uint8_t type; ///< Must be first byte in struct for type detection
uint8_t length; uint8_t length;
uint16_t destination; uint16_t destination;
@ -111,8 +109,7 @@ typedef struct __attribute__ ((packed)) mmr_rrep_message_t
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* *
*/ */
typedef struct __attribute__ ((packed)) mmr_rerr_message_t typedef struct __attribute__((packed)) {
{
uint8_t type; ///< Must be first byte in struct for type detection uint8_t type; ///< Must be first byte in struct for type detection
uint8_t error_type; uint8_t error_type;
uint16_t type_specific_info; uint16_t type_specific_info;
@ -131,7 +128,7 @@ void mmr_init(void);
* @param message incoming packet * @param message incoming packet
* @param packet_info Additional packet information * @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 * 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 * @return true if packet was successfully stored for transmission; false otherwise
* (e.g. message queue full). * (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 * 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 next_hop next hop network address of dropped packet (can be undefined)
* @param error Error type which informs about reason * @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. * @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 msg_size Size of received message
* @param packet_info Additional packet information * @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. * @brief Print routing layer statistics.

View File

@ -71,8 +71,7 @@ and the mailinglist (subscription via web site)
* | Timestamp | * | Timestamp |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/ */
typedef struct __attribute__ ((packed)) mms_ping_message_t typedef struct __attribute__((packed)) {
{
uint8_t type; ///< Type of ping message (request or reply) uint8_t type; ///< Type of ping message (request or reply)
uint8_t identifier; ///< Unique identifier for ping process uint8_t identifier; ///< Unique identifier for ping process
uint16_t seq_num; ///< Sequence number (increasing number within that process) uint16_t seq_num; ///< Sequence number (increasing number within that process)
@ -94,7 +93,7 @@ static uint8_t mms_ping_packets; ///< Number of ping replies received
static int mms_ping_dups; ///< Duplicates static int mms_ping_dups; ///< Duplicates
static bool ping_bc_mode; ///< If option -b is set and address is BC static bool ping_bc_mode; ///< If option -b is set and address is BC
static bool ping_silent_mode; ///< If option -s is set static bool ping_silent_mode; ///< If option -s is set
static bool* dups; ///< Helper buffer to check for DUPs static bool *dups; ///< Helper buffer to check for DUPs
static float rtt_min; ///< Min. RTT static float rtt_min; ///< Min. RTT
static float rtt_max; ///< Max. RTT static float rtt_max; ///< Max. RTT
static float rtt_avg; ///< Avg. RTT static float rtt_avg; ///< Avg. RTT
@ -123,8 +122,7 @@ static uint16_t mms_ping_pid; ///< Process ID of process ping is running withi
* | Type | | * | Type | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/ */
typedef struct __attribute__ ((packed)) mms_ssh_message_t typedef struct __attribute__((packed)) {
{
uint8_t type; ///< Type of SSH message uint8_t type; ///< Type of SSH message
} mms_ssh_message_t; } mms_ssh_message_t;
@ -137,8 +135,7 @@ typedef struct __attribute__ ((packed)) mms_ssh_message_t
* | Type | Data | * | Type | Data |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/ */
typedef struct __attribute__ ((packed)) mms_ssh_data_message_t typedef struct __attribute__((packed)) {
{
uint8_t type; ///< Type of SSH message uint8_t type; ///< Type of SSH message
uint8_t data[MMS_SSH_DATA_MAX]; ///< Message information uint8_t data[MMS_SSH_DATA_MAX]; ///< Message information
} mms_ssh_data_message_t; } mms_ssh_data_message_t;
@ -191,60 +188,76 @@ static route_interface_t r_iface = {
ASCCMD(route, CMDFLAG_SERIAL, "[-adfFg] print kernel route table"); ASCCMD(route, CMDFLAG_SERIAL, "[-adfFg] print kernel route table");
CMD_FUNCTION(route, cmdargs) CMD_FUNCTION(route, cmdargs)
{ {
if (cmdargs->arg_size > 0) if(cmdargs->arg_size > 0) {
{ char *msg = (char *)cmdargs->args;
char* msg = (char*)cmdargs->args;
while (*msg == ' ') msg++; while(*msg == ' ') {
if (*msg == '-' && *(msg+1) == 'f') msg++;
{ }
if(*msg == '-' && *(msg + 1) == 'f') {
mms_flush_routes(false); mms_flush_routes(false);
printf("Kernel route table flushed (non-static)!\n"); printf("Kernel route table flushed (non-static)!\n");
return CMD_SUCCESS; return CMD_SUCCESS;
} }
else if (*msg == '-' && *(msg+1) == 'F') else if(*msg == '-' && *(msg + 1) == 'F') {
{
mms_flush_routes(true); mms_flush_routes(true);
printf("Kernel route table flushed (static)!\n"); printf("Kernel route table flushed (static)!\n");
return CMD_SUCCESS; return CMD_SUCCESS;
} }
else if (*msg == '-' && *(msg+1) == 'd') else if(*msg == '-' && *(msg + 1) == 'd') {
{ msg++;
msg++; msg++; msg++;
while (*msg == ' ') msg++;
while(*msg == ' ') {
msg++;
}
uint16_t address = net_strtoaddr(msg, &msg); uint16_t address = net_strtoaddr(msg, &msg);
if (rt_remove_static_route(address)) {
if(rt_remove_static_route(address)) {
printf("Static route deleted successfully!\n"); printf("Static route deleted successfully!\n");
return CMD_SUCCESS; return CMD_SUCCESS;
} }
return CMD_ERROR; return CMD_ERROR;
} }
else if (*msg == '-' && *(msg+1) == 'g') else if(*msg == '-' && *(msg + 1) == 'g') {
{ msg++;
msg++; msg++; msg++;
while (*msg == ' ') msg++;
while(*msg == ' ') {
msg++;
}
uint16_t address = net_strtoaddr(msg, &msg); uint16_t address = net_strtoaddr(msg, &msg);
int c = rt_remove_static_gateway_routes(address); int c = rt_remove_static_gateway_routes(address);
printf("%u static route(s) deleted!\n", c); printf("%u static route(s) deleted!\n", c);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
else if (*msg == '-' && *(msg+1) == 'a') else if(*msg == '-' && *(msg + 1) == 'a') {
{ msg++;
msg++; msg++; msg++;
while (*msg == ' ') msg++;
while(*msg == ' ') {
msg++;
}
uint16_t address = net_strtoaddr(msg, &msg); uint16_t address = net_strtoaddr(msg, &msg);
uint16_t gateway = net_strtoaddr(msg, &msg); uint16_t gateway = net_strtoaddr(msg, &msg);
int metric = (int)strtoul(msg, &msg, 0); int metric = (int)strtoul(msg, &msg, 0);
int iface = (int)strtoul(msg, &msg, 0); int iface = (int)strtoul(msg, &msg, 0);
if (address != 0 && gateway != 0) {
if (rt_add_static_route(address, gateway, metric, iface)) { if(address != 0 && gateway != 0) {
if(rt_add_static_route(address, gateway, metric, iface)) {
printf("Static route added successfully!\n"); printf("Static route added successfully!\n");
return CMD_SUCCESS; return CMD_SUCCESS;
} }
} }
return CMD_ERROR; return CMD_ERROR;
} }
else else {
{
printf("Usage: route [-adfFg] print kernel route table\n\n"); printf("Usage: route [-adfFg] print kernel route table\n\n");
printf(" -a <DST> <GW> <M> <IFACE>, add static route to kernel route table\n"); printf(" -a <DST> <GW> <M> <IFACE>, add static route to kernel route table\n");
printf(" -d <DST>, delete static route out of kernel route table\n"); printf(" -d <DST>, delete static route out of kernel route table\n");
@ -259,8 +272,7 @@ CMD_FUNCTION(route, cmdargs)
return CMD_ERROR; return CMD_ERROR;
} }
} }
else else {
{
mms_print_routes(); mms_print_routes();
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@ -269,62 +281,70 @@ CMD_FUNCTION(route, cmdargs)
ASCCMD(ifconfig, CMDFLAG_SERIAL, "[IFACE]: print interface configuration"); ASCCMD(ifconfig, CMDFLAG_SERIAL, "[IFACE]: print interface configuration");
CMD_FUNCTION(ifconfig, cmdargs) CMD_FUNCTION(ifconfig, cmdargs)
{ {
if (cmdargs->arg_size > 0) if(cmdargs->arg_size > 0) {
{ char *msg;
char* msg;
int iface = (int)strtoul(cmdargs->args, &msg, 0); int iface = (int)strtoul(cmdargs->args, &msg, 0);
if (cmdargs->arg_size > 1)
{ if(cmdargs->arg_size > 1) {
while (*msg == ' ') msg++; while(*msg == ' ') {
if (*msg == '-' && (*(msg+1) == 'P' || *(msg+1) == 'p')) msg++;
{ }
msg++; msg++;
if(*msg == '-' && (*(msg + 1) == 'P' || *(msg + 1) == 'p')) {
msg++;
msg++;
uint8_t power = (uint8_t)strtoul(msg, &msg, 0); uint8_t power = (uint8_t)strtoul(msg, &msg, 0);
if (*msg != '\0') return CMD_ERROR;
if (mms_set_output_power(iface, power)) if(*msg != '\0') {
{ return CMD_ERROR;
}
if(mms_set_output_power(iface, power)) {
printf("Output power set!\n"); printf("Output power set!\n");
return CMD_SUCCESS; return CMD_SUCCESS;
} }
return CMD_ERROR; return CMD_ERROR;
} }
else if (*msg == '-' && (*(msg+1) == 'A' || *(msg+1) == 'a')) else if(*msg == '-' && (*(msg + 1) == 'A' || *(msg + 1) == 'a')) {
{ msg++;
msg++; msg++; msg++;
while (*msg == ' ') msg++;
while(*msg == ' ') {
msg++;
}
uint16_t address = net_strtoaddr(msg, &msg); uint16_t address = net_strtoaddr(msg, &msg);
if (mms_set_interface_address(iface, address))
{ if(mms_set_interface_address(iface, address)) {
printf("Interface address set!\n"); printf("Interface address set!\n");
return CMD_SUCCESS; return CMD_SUCCESS;
} }
return CMD_ERROR; return CMD_ERROR;
} }
else else {
{
printf("Usage: ifconfig [IFACE] [-AP] print interface configuration\n\n"); printf("Usage: ifconfig [IFACE] [-AP] print interface configuration\n\n");
printf(" -A <ADDR>, set interface address, e.g. ifconfig 0 -A 1.1\n"); printf(" -A <ADDR>, set interface address, e.g. ifconfig 0 -A 1.1\n");
printf(" -P <POWER>, set output power on interface\n\n"); printf(" -P <POWER>, set output power on interface\n\n");
return CMD_ERROR; return CMD_ERROR;
} }
} }
else else {
{
mms_print_ifconfig(iface); mms_print_ifconfig(iface);
} }
} }
else else {
{
mms_print_ifconfig(-1); mms_print_ifconfig(-1);
} }
return CMD_SUCCESS; return CMD_SUCCESS;
} }
ASCCMD(ping, CMDFLAG_SERIAL, "ping [-bchpstw] destination"); ASCCMD(ping, CMDFLAG_SERIAL, "ping [-bchpstw] destination");
CMD_FUNCTION(ping, cmdargs) CMD_FUNCTION(ping, cmdargs)
{ {
if (cmdargs->arg_size > 0) if(cmdargs->arg_size > 0) {
{
int i; int i;
msg m; msg m;
uint8_t count = MMS_PING_PACKETS; uint8_t count = MMS_PING_PACKETS;
@ -335,24 +355,37 @@ CMD_FUNCTION(ping, cmdargs)
int ttl = 10; int ttl = 10;
long timeout = 3; long timeout = 3;
char adrbuf[10]; char adrbuf[10];
const char* msg = cmdargs->args; const char *msg = cmdargs->args;
read_ping_cmd: read_ping_cmd:
while (*msg == ' ') msg++;
if (*msg == '-' && (*(msg+1) == 'B' || *(msg+1) == 'b')) { while(*msg == ' ') {
msg++;
}
if(*msg == '-' && (*(msg + 1) == 'B' || *(msg + 1) == 'b')) {
bc = true; bc = true;
msg++; msg++; msg++;
msg++;
goto read_ping_cmd; goto read_ping_cmd;
} else if (*msg == '-' && (*(msg+1) == 'C' || *(msg+1) == 'c')) { }
msg++; msg++; else if(*msg == '-' && (*(msg + 1) == 'C' || *(msg + 1) == 'c')) {
unsigned long tc = strtoul(msg, (char**)&msg, 0); msg++;
if (tc == 0) return CMD_ERROR; msg++;
if (tc > 255) { unsigned long tc = strtoul(msg, (char **)&msg, 0);
if(tc == 0) {
return CMD_ERROR;
}
if(tc > 255) {
puts("Not more than 255 ping messages allowed!"); puts("Not more than 255 ping messages allowed!");
return CMD_ERROR; return CMD_ERROR;
} }
count = (uint8_t) tc; count = (uint8_t) tc;
goto read_ping_cmd; goto read_ping_cmd;
} else if (*msg == '-' && (*(msg+1) == 'H' || *(msg+1) == 'h')) { }
else if(*msg == '-' && (*(msg + 1) == 'H' || *(msg + 1) == 'h')) {
printf("Usage: ping [-bchpstw] destination\n\n"); printf("Usage: ping [-bchpstw] destination\n\n");
printf(" -b, do a broadcast ping\n"); printf(" -b, do a broadcast ping\n");
printf(" -c <COUNT>, set number of ping messages\n"); printf(" -c <COUNT>, set number of ping messages\n");
@ -365,51 +398,91 @@ CMD_FUNCTION(ping, cmdargs)
printf(" -t <TTL>, TTL value of ping messages (default: 10)\n"); printf(" -t <TTL>, TTL value of ping messages (default: 10)\n");
printf(" -w <WAIT>, time to wait for a response, in seconds (default: 3)\n\n"); printf(" -w <WAIT>, time to wait for a response, in seconds (default: 3)\n\n");
return CMD_SUCCESS; return CMD_SUCCESS;
} else if (*msg == '-' && (*(msg+1) == 'p' || *(msg+1) == 'P')) { }
msg++; msg++; else if(*msg == '-' && (*(msg + 1) == 'p' || *(msg + 1) == 'P')) {
unsigned long tp = strtoul(msg, (char**)&msg, 0); msg++;
if (tp == 0) return CMD_ERROR; msg++;
if (tp == 1) prio = 0; unsigned long tp = strtoul(msg, (char **)&msg, 0);
else if (tp == 2) prio = 1;
else prio = 2; if(tp == 0) {
return CMD_ERROR;
}
if(tp == 1) {
prio = 0;
}
else if(tp == 2) {
prio = 1;
}
else {
prio = 2;
}
goto read_ping_cmd; goto read_ping_cmd;
} else if (*msg == '-' && (*(msg+1) == 's' || *(msg+1) == 'S')) { }
else if(*msg == '-' && (*(msg + 1) == 's' || *(msg + 1) == 'S')) {
ping_silent_mode = true; ping_silent_mode = true;
msg++; msg++; msg++;
msg++;
goto read_ping_cmd; goto read_ping_cmd;
} else if (*msg == '-' && (*(msg+1) == 't' || *(msg+1) == 'T')) { }
msg++; msg++; else if(*msg == '-' && (*(msg + 1) == 't' || *(msg + 1) == 'T')) {
unsigned long to = strtoul(msg, (char**)&msg, 0); msg++;
if (to == 0 || to > 255) return CMD_ERROR; msg++;
unsigned long to = strtoul(msg, (char **)&msg, 0);
if(to == 0 || to > 255) {
return CMD_ERROR;
}
ttl = to; ttl = to;
goto read_ping_cmd; goto read_ping_cmd;
} else if (*msg == '-' && (*(msg+1) == 'w' || *(msg+1) == 'W')) { }
msg++; msg++; else if(*msg == '-' && (*(msg + 1) == 'w' || *(msg + 1) == 'W')) {
unsigned long to = strtoul(msg, (char**)&msg, 0); msg++;
if (to == 0) return CMD_ERROR; msg++;
unsigned long to = strtoul(msg, (char **)&msg, 0);
if(to == 0) {
return CMD_ERROR;
}
timeout = to; timeout = to;
goto read_ping_cmd; goto read_ping_cmd;
} }
uint16_t address = net_strtoaddr((char*)msg, (char**)&msg);
if (address == 0) return CMD_ERROR; uint16_t address = net_strtoaddr((char *)msg, (char **)&msg);
if(address == 0) {
return CMD_ERROR;
}
int iface_addr = net_get_address_in_subnet(address); int iface_addr = net_get_address_in_subnet(address);
// No ping to unsupported network or own address
if (iface_addr == 0 || iface_addr == address) return CMD_ERROR; /* No ping to unsupported network or own address */
// If broadcast destination address, limit TTL to one hop if(iface_addr == 0 || iface_addr == address) {
if (address == NETWORK_ADDR_BC(address)) { return CMD_ERROR;
if (!bc) { }
/* If broadcast destination address, limit TTL to one hop */
if(address == NETWORK_ADDR_BC(address)) {
if(!bc) {
puts("Do you want to ping broadcast? Then -b"); puts("Do you want to ping broadcast? Then -b");
return CMD_ERROR; return CMD_ERROR;
} }
ttl = 1; ttl = 1;
ping_bc_mode = true; ping_bc_mode = true;
} }
// Try to malloc duplicate detection buffer
dups = (bool*) malloc(count * sizeof(bool)); /* Try to malloc duplicate detection buffer */
if (dups == NULL) { dups = (bool *) malloc(count * sizeof(bool));
if(dups == NULL) {
puts("Not enough system memory to fulfill your request!"); puts("Not enough system memory to fulfill your request!");
return CMD_ERROR; return CMD_ERROR;
} }
net_addrtostr(address, adrbuf, sizeof(adrbuf)); net_addrtostr(address, adrbuf, sizeof(adrbuf));
printf("PING %s %lu bytes of data.\n", adrbuf, sizeof(mms_ping_message_t)); printf("PING %s %lu bytes of data.\n", adrbuf, sizeof(mms_ping_message_t));
mms_ping_packets = 0; mms_ping_packets = 0;
@ -420,80 +493,105 @@ CMD_FUNCTION(ping, cmdargs)
rtt_avg = 0x00000000; rtt_avg = 0x00000000;
mms_ping_pid = fk_thread->pid; mms_ping_pid = fk_thread->pid;
long ts_start = (uint32_t)clock_get_systemtime(); long ts_start = (uint32_t)clock_get_systemtime();
for (i = 1; i <= count; i++)
{ for(i = 1; i <= count; i++) {
// No duplicate for this sequence number possible /* No duplicate for this sequence number possible */
dups[i-1] = false; dups[i - 1] = false;
// Send ping echo request to destination /* Send ping echo request to destination */
mms_ping(address, i, prio, ttl); mms_ping(address, i, prio, ttl);
// Set timeout for next ping echo request packet to ::timeout seconds /* Set timeout for next ping echo request packet to ::timeout seconds */
utimer_set_wpid(&mms_ping_utimer, timeout, mms_ping_pid, NULL); utimer_set_wpid(&mms_ping_utimer, timeout, mms_ping_pid, NULL);
// Wait for ping echo reply or timeout /* Wait for ping echo reply or timeout */
msg_receive(&m); msg_receive(&m);
// Remove user timer because maybe woken up by ping response /* Remove user timer because maybe woken up by ping response */
utimer_remove(&mms_ping_utimer); utimer_remove(&mms_ping_utimer);
} }
ts_start = (uint32_t)clock_get_systemtime() - ts_start; ts_start = (uint32_t)clock_get_systemtime() - ts_start;
printf("--- %s ping statistics ---\n", adrbuf); printf("--- %s ping statistics ---\n", adrbuf);
if (mms_ping_dups == 0) {
if(mms_ping_dups == 0) {
printf("%u packets transmitted, %u received, %u%% packet loss, time %lu ms\n", count, printf("%u packets transmitted, %u received, %u%% packet loss, time %lu ms\n", count,
mms_ping_packets, ((count-mms_ping_packets)*100)/count, ts_start); mms_ping_packets, ((count - mms_ping_packets) * 100) / count, ts_start);
} else { }
else {
printf("%u packets transmitted, %u received, +%i duplicates, %u%% packet loss, time %lu ms\n", count, printf("%u packets transmitted, %u received, +%i duplicates, %u%% packet loss, time %lu ms\n", count,
mms_ping_packets, mms_ping_dups, ((count-mms_ping_packets)*100)/count, ts_start); mms_ping_packets, mms_ping_dups, ((count - mms_ping_packets) * 100) / count, ts_start);
} }
if (mms_ping_packets > 0)
{ if(mms_ping_packets > 0) {
printf("rtt min/avg/max = %.2f/%.2f/%.2f ms\n", rtt_min, rtt_avg/(mms_ping_packets+mms_ping_dups), rtt_max); printf("rtt min/avg/max = %.2f/%.2f/%.2f ms\n", rtt_min, rtt_avg / (mms_ping_packets + mms_ping_dups), rtt_max);
} }
if (!ping_bc_mode && mms_ping_packets == count) {
// Calculate approximate throughput if(!ping_bc_mode && mms_ping_packets == count) {
/* Calculate approximate throughput */
printf("--- %s throughput statistics ---\n", adrbuf); printf("--- %s throughput statistics ---\n", adrbuf);
float bw = (count * (8+4+62+2) * 1000) / (float)ts_start; // for CC1100 float bw = (count * (8 + 4 + 62 + 2) * 1000) / (float)ts_start; /* for CC1100 */
printf("approximate throughput (air): %.2f byte/sec\n", 2*bw); printf("approximate throughput (air): %.2f byte/sec\n", 2 * bw);
bw = (count * 58 * 1000) / (float)ts_start; // for CC1100 bw = (count * 58 * 1000) / (float)ts_start; /* for CC1100 */
printf("approximate throughput (dll): %.2f byte/sec\n", 2*bw); printf("approximate throughput (dll): %.2f byte/sec\n", 2 * bw);
bw = (count * NET_MESSAGE_PAYLOAD_LENGTH * 1000) / (float)ts_start; bw = (count * NET_MESSAGE_PAYLOAD_LENGTH * 1000) / (float)ts_start;
printf("approximate throughput (net): %.2f byte/sec\n", 2*bw); printf("approximate throughput (net): %.2f byte/sec\n", 2 * bw);
bw = (count * UDPL_MESSAGE_LENGTH * 1000) / (float)ts_start; bw = (count * UDPL_MESSAGE_LENGTH * 1000) / (float)ts_start;
printf("approximate throughput (trans/UDPL): %.2f byte/sec\n", 2*bw); printf("approximate throughput (trans/UDPL): %.2f byte/sec\n", 2 * bw);
bw = (count * TCPL_MESSAGE_LENGTH * 1000) / (float)ts_start; bw = (count * TCPL_MESSAGE_LENGTH * 1000) / (float)ts_start;
printf("approximate throughput (trans/TCPL): %.2f byte/sec\n", bw); printf("approximate throughput (trans/TCPL): %.2f byte/sec\n", bw);
} }
// Ping is over, clear random ping process id and buffer
/* Ping is over, clear random ping process id and buffer */
mms_ping_last_proc_id = 0; mms_ping_last_proc_id = 0;
free(dups); free(dups);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
return CMD_ERROR; return CMD_ERROR;
} }
ASCCMD(ssh, CMDFLAG_SERIAL, "Usage: ssh [-q] destination"); ASCCMD(ssh, CMDFLAG_SERIAL, "Usage: ssh [-q] destination");
CMD_FUNCTION(ssh, cmdargs) CMD_FUNCTION(ssh, cmdargs)
{ {
if (cmdargs->arg_size > 0) { if(cmdargs->arg_size > 0) {
bool quit = false; bool quit = false;
const char* msg = cmdargs->args; const char *msg = cmdargs->args;
while (*msg == ' ') msg++;
if (*msg == '-' && (*(msg+1) == 'Q' || *(msg+1) == 'q')) while(*msg == ' ') {
{ msg++;
quit = true;
msg++; msg++;
} }
uint16_t address = net_strtoaddr((char*)msg, (char**)&msg);
if (address == 0) return CMD_ERROR; if(*msg == '-' && (*(msg + 1) == 'Q' || *(msg + 1) == 'q')) {
quit = true;
msg++;
msg++;
}
uint16_t address = net_strtoaddr((char *)msg, (char **)&msg);
if(address == 0) {
return CMD_ERROR;
}
int iface_addr = net_get_address_in_subnet(address); int iface_addr = net_get_address_in_subnet(address);
// No ssh to unsupported network or own address
if (iface_addr == 0 || iface_addr == address) return CMD_ERROR; /* No ssh to unsupported network or own address */
// If broadcast destination address, also exit here if(iface_addr == 0 || iface_addr == address) {
if (address == NETWORK_ADDR_BC(address)) return CMD_ERROR; return CMD_ERROR;
if (!quit) { }
/* If broadcast destination address, also exit here */
if(address == NETWORK_ADDR_BC(address)) {
return CMD_ERROR;
}
if(!quit) {
mms_ssh_connect(address); mms_ssh_connect(address);
} else { }
else {
mms_ssh_close(address); mms_ssh_close(address);
} }
return CMD_SUCCESS; return CMD_SUCCESS;
} }
return CMD_ERROR; return CMD_ERROR;
} }
//#endif //#endif
@ -502,49 +600,60 @@ CMD_FUNCTION(ssh, cmdargs)
// Ping message handler and send function // Ping message handler and send function
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static void mms_ping_handler(void* message, int message_size, packet_info_t* packet_info) static void mms_ping_handler(void *message, int message_size,
packet_info_t *packet_info)
{ {
mms_ping_message_t* ping = (mms_ping_message_t*)message; mms_ping_message_t *ping = (mms_ping_message_t *)message;
if (ping->type == MMS_PING_ECHO_REQUEST)
{ if(ping->type == MMS_PING_ECHO_REQUEST) {
ping->type = MMS_PING_ECHO_REPLY; ping->type = MMS_PING_ECHO_REPLY;
net_send((void*)ping, sizeof(mms_ping_message_t), packet_info->source, net_send((void *)ping, sizeof(mms_ping_message_t), packet_info->source,
LAYER_2_PROTOCOL_PING, packet_info->tos, 10); LAYER_2_PROTOCOL_PING, packet_info->tos, 10);
} }
else if (ping->type == MMS_PING_ECHO_REPLY) else if(ping->type == MMS_PING_ECHO_REPLY) {
{ if(ping->identifier == mms_ping_last_proc_id) {
if (ping->identifier == mms_ping_last_proc_id)
{
msg m; msg m;
bool wasDup = false; bool wasDup = false;
char* msgDup; char *msgDup;
char buf[10]; char buf[10];
if (dups[ping->seq_num-1]) { if(dups[ping->seq_num - 1]) {
wasDup = true; wasDup = true;
mms_ping_dups++; mms_ping_dups++;
msgDup = "(DUP!)"; msgDup = "(DUP!)";
} else { }
else {
mms_ping_packets++; mms_ping_packets++;
dups[ping->seq_num-1] = true; dups[ping->seq_num - 1] = true;
msgDup = ""; msgDup = "";
} }
if (!ping_bc_mode && !wasDup) { if(!ping_bc_mode && !wasDup) {
utimer_remove(&mms_ping_utimer); // Stop timeout timer utimer_remove(&mms_ping_utimer); /* Stop timeout timer */
} }
float ms = ((uint32_t)clock_get_systemtime() - ping->timestamp); float ms = ((uint32_t)clock_get_systemtime() - ping->timestamp);
if (ms < rtt_min) rtt_min = ms;
if (ms > rtt_max) rtt_max = ms; if(ms < rtt_min) {
rtt_min = ms;
}
if(ms > rtt_max) {
rtt_max = ms;
}
rtt_avg += ms; rtt_avg += ms;
if (!ping_silent_mode) {
if(!ping_silent_mode) {
net_addrtostr(packet_info->source, buf, sizeof(buf)); net_addrtostr(packet_info->source, buf, sizeof(buf));
printf("%lu bytes from %s: seq=%u ttl=%u time=%.2f ms %s\n", printf("%lu bytes from %s: seq=%u ttl=%u time=%.2f ms %s\n",
sizeof(mms_ping_message_t), buf, sizeof(mms_ping_message_t), buf,
ping->seq_num, *packet_info->ttl_ptr, ms, msgDup); ping->seq_num, *packet_info->ttl_ptr, ms, msgDup);
} }
if (!ping_bc_mode && !wasDup) msg_send(&m, mms_ping_pid, false);
if(!ping_bc_mode && !wasDup) {
msg_send(&m, mms_ping_pid, false);
}
} }
} }
} }
@ -557,7 +666,7 @@ static void mms_ping(uint16_t destination, uint8_t seq, uint8_t prio, int ttl)
ping_request.identifier = mms_ping_last_proc_id; ping_request.identifier = mms_ping_last_proc_id;
ping_request.seq_num = seq; ping_request.seq_num = seq;
ping_request.timestamp = (uint32_t)clock_get_systemtime(); ping_request.timestamp = (uint32_t)clock_get_systemtime();
net_send((void*)&ping_request, sizeof(mms_ping_message_t), net_send((void *)&ping_request, sizeof(mms_ping_message_t),
destination, LAYER_2_PROTOCOL_PING, prio, ttl); destination, LAYER_2_PROTOCOL_PING, prio, ttl);
} }
@ -569,7 +678,7 @@ static void mms_ssh_connect(uint16_t destination)
{ {
mms_ssh_message_t ssh; mms_ssh_message_t ssh;
ssh.type = MMS_SSH_CON_REQUEST; ssh.type = MMS_SSH_CON_REQUEST;
mms_send((void*)&ssh, sizeof(mms_ssh_message_t), destination, mms_send((void *)&ssh, sizeof(mms_ssh_message_t), destination,
LAYER_3_PROTOCOL_SSH, PRIORITY_DATA); LAYER_3_PROTOCOL_SSH, PRIORITY_DATA);
} }
@ -577,7 +686,7 @@ static void mms_ssh_reply_connect(uint16_t destination, int socket, bool accept)
{ {
mms_ssh_message_t ssh; mms_ssh_message_t ssh;
ssh.type = accept ? MMS_SSH_CON_ACCEPT : MMS_SSH_CON_REJECT; ssh.type = accept ? MMS_SSH_CON_ACCEPT : MMS_SSH_CON_REJECT;
trans_sendto(socket, (void*)&ssh, sizeof(mms_ssh_message_t), trans_sendto(socket, (void *)&ssh, sizeof(mms_ssh_message_t),
LAYER_3_PROTOCOL_SSH, PRIORITY_DATA, destination); LAYER_3_PROTOCOL_SSH, PRIORITY_DATA, destination);
} }
@ -585,65 +694,81 @@ static void mms_ssh_close(uint16_t destination)
{ {
mms_ssh_message_t ssh; mms_ssh_message_t ssh;
ssh.type = MMS_SSH_CON_CLOSE; ssh.type = MMS_SSH_CON_CLOSE;
mms_send((void*)&ssh, sizeof(mms_ssh_message_t), destination, mms_send((void *)&ssh, sizeof(mms_ssh_message_t), destination,
LAYER_3_PROTOCOL_SSH, PRIORITY_DATA); LAYER_3_PROTOCOL_SSH, PRIORITY_DATA);
} }
static void mms_ssh_handler(void* message, int message_size, packet_info_t* packet_info) static void mms_ssh_handler(void *message, int message_size,
packet_info_t *packet_info)
{ {
char adrbuf[10]; char adrbuf[10];
mms_ssh_message_t* ssh = (mms_ssh_message_t*)message; mms_ssh_message_t *ssh = (mms_ssh_message_t *)message;
if (ssh->type == MMS_SSH_CON_REQUEST) {
if (ssh_socket > -1) { if(ssh->type == MMS_SSH_CON_REQUEST) {
if(ssh_socket > -1) {
mms_ssh_reply_connect(packet_info->source, -1, false); mms_ssh_reply_connect(packet_info->source, -1, false);
return; return;
} }
ssh_socket = trans_socket(SOCK_TCPL); ssh_socket = trans_socket(SOCK_TCPL);
if (ssh_socket < 0) {
if(ssh_socket < 0) {
mms_ssh_reply_connect(packet_info->source, -1, false); mms_ssh_reply_connect(packet_info->source, -1, false);
return; return;
} }
trans_connect(ssh_socket, packet_info->source); trans_connect(ssh_socket, packet_info->source);
mms_ssh_reply_connect(packet_info->source, ssh_socket, true); mms_ssh_reply_connect(packet_info->source, ssh_socket, true);
} else if (ssh->type == MMS_SSH_CON_ACCEPT) { }
else if(ssh->type == MMS_SSH_CON_ACCEPT) {
net_addrtostr(packet_info->source, adrbuf, sizeof(adrbuf)); net_addrtostr(packet_info->source, adrbuf, sizeof(adrbuf));
printf("SSH connection accepted by %s\n", adrbuf); printf("SSH connection accepted by %s\n", adrbuf);
} else if (ssh->type == MMS_SSH_CON_REJECT) { }
else if(ssh->type == MMS_SSH_CON_REJECT) {
net_addrtostr(packet_info->source, adrbuf, sizeof(adrbuf)); net_addrtostr(packet_info->source, adrbuf, sizeof(adrbuf));
printf("SSH connection rejected by %s\n", adrbuf); printf("SSH connection rejected by %s\n", adrbuf);
} else if (ssh->type == MMS_SSH_CON_CLOSE) { }
if (ssh_socket > -1) { else if(ssh->type == MMS_SSH_CON_CLOSE) {
if(ssh_socket > -1) {
uint16_t peer; uint16_t peer;
trans_getpeername(ssh_socket, &peer); trans_getpeername(ssh_socket, &peer);
if (peer == packet_info->source) {
if (trans_close(ssh_socket, CLOSE_IMMEDIATE) == 1) { if(peer == packet_info->source) {
if(trans_close(ssh_socket, CLOSE_IMMEDIATE) == 1) {
ssh_socket = -1; ssh_socket = -1;
} }
} }
} }
} else if (ssh->type == MMS_SSH_DATA) { }
mms_ssh_data_message_t* ssh_data = (mms_ssh_data_message_t*)message; else if(ssh->type == MMS_SSH_DATA) {
printf((char*)ssh_data->data); mms_ssh_data_message_t *ssh_data = (mms_ssh_data_message_t *)message;
printf((char *)ssh_data->data);
fflush(stderr); fflush(stderr);
} }
} }
void mms_net_printf(const char * format) void mms_net_printf(const char *format)
{ {
if (ssh_socket > -1) { if(ssh_socket > -1) {
mms_ssh_data_message_t ssh_data; mms_ssh_data_message_t ssh_data;
ssh_data.type = MMS_SSH_DATA; ssh_data.type = MMS_SSH_DATA;
int i = 0; int i = 0;
int len = strlen(format); int len = strlen(format);
while (i < len) {
int chunk = len - i > (MMS_SSH_DATA_MAX-1) ? (MMS_SSH_DATA_MAX-1) : len - i; while(i < len) {
int chunk = len - i > (MMS_SSH_DATA_MAX - 1) ? (MMS_SSH_DATA_MAX - 1) : len - i;
memset(ssh_data.data, 0, sizeof(ssh_data.data)); memset(ssh_data.data, 0, sizeof(ssh_data.data));
memcpy(ssh_data.data, format + i, chunk); memcpy(ssh_data.data, format + i, chunk);
if (trans_send(ssh_socket, (void*)&ssh_data, sizeof(mms_ssh_data_message_t),
LAYER_3_PROTOCOL_SSH, PRIORITY_DATA) < 0) break; if(trans_send(ssh_socket, (void *)&ssh_data, sizeof(mms_ssh_data_message_t),
LAYER_3_PROTOCOL_SSH, PRIORITY_DATA) < 0) {
break;
}
i += chunk; i += chunk;
} }
} else { }
else {
printf(format); printf(format);
} }
} }
@ -657,27 +782,27 @@ void mms_init(void)
mms_initp(LAYER_2_PROTOCOL_MMR, &r_iface); mms_initp(LAYER_2_PROTOCOL_MMR, &r_iface);
} }
void mms_initp(protocol_t rp, route_interface_t* ri) void mms_initp(protocol_t rp, route_interface_t *ri)
{ {
// Initialize routing & network layer /* Initialize routing & network layer */
mmr_init(); mmr_init();
net_init(ri); net_init(ri);
// Initialize transport layer /* Initialize transport layer */
trans_init(); trans_init();
// Add routing as protocol handler for given route messages /* Add routing as protocol handler for given route messages */
net_set_protocol_handler(rp, ri->receive); net_set_protocol_handler(rp, ri->receive);
// Add transport as protocol handler for UDPL and TCPL messages /* Add transport as protocol handler for UDPL and TCPL messages */
net_set_protocol_handler(LAYER_2_PROTOCOL_UDPL, trans_receive_udpl); net_set_protocol_handler(LAYER_2_PROTOCOL_UDPL, trans_receive_udpl);
net_set_protocol_handler(LAYER_2_PROTOCOL_TCPL, trans_receive_tcpl); net_set_protocol_handler(LAYER_2_PROTOCOL_TCPL, trans_receive_tcpl);
// Add MMS ping handler /* Add MMS ping handler */
net_set_protocol_handler(LAYER_2_PROTOCOL_PING, mms_ping_handler); net_set_protocol_handler(LAYER_2_PROTOCOL_PING, mms_ping_handler);
// Add SSH handler /* Add SSH handler */
trans_set_protocol_handler(LAYER_3_PROTOCOL_SSH, mms_ssh_handler); trans_set_protocol_handler(LAYER_3_PROTOCOL_SSH, mms_ssh_handler);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
int mms_add_interface(const char* name, uint16_t addr, const radio_t* radio) int mms_add_interface(const char *name, uint16_t addr, const radio_t *radio)
{ {
return net_add_interface(name, addr, radio); return net_add_interface(name, addr, radio);
} }
@ -712,7 +837,7 @@ int mms_set_protocol_handler(protocol_t protocol, packet_handler_t handler)
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void mms_receive(void* msg, int msg_size, packet_info_t* packet_info) void mms_receive(void *msg, int msg_size, packet_info_t *packet_info)
{ {
net_receive(msg, msg_size, packet_info); net_receive(msg, msg_size, packet_info);
} }
@ -733,21 +858,24 @@ int mms_connect(int socket, uint16_t dest_addr)
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
int mms_sock_send(int socket, void* buffer, int length, protocol_t protocol, uint8_t priority) int mms_sock_send(int socket, void *buffer, int length, protocol_t protocol,
uint8_t priority)
{ {
return trans_send(socket, buffer, length, protocol, priority); return trans_send(socket, buffer, length, protocol, priority);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
int mms_sock_sendto(int socket, void* buffer, int length, protocol_t protocol, uint8_t priority, uint16_t dest_addr) int mms_sock_sendto(int socket, void *buffer, int length, protocol_t protocol,
uint8_t priority, uint16_t dest_addr)
{ {
return trans_sendto(socket, buffer, length, protocol, priority, dest_addr); return trans_sendto(socket, buffer, length, protocol, priority, dest_addr);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
int mms_send(void* msg, int msg_len, uint16_t dst, protocol_t protocol, uint8_t priority) int mms_send(void *msg, int msg_len, uint16_t dst, protocol_t protocol,
uint8_t priority)
{ {
return trans_sendto(-1, msg, msg_len, protocol, priority, dst); return trans_sendto(-1, msg, msg_len, protocol, priority, dst);
} }

View File

@ -59,7 +59,7 @@ void mms_init(void);
* @param rp Routing protocol type identifier. * @param rp Routing protocol type identifier.
* @param ri Pointer to route interface. * @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. * @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. * @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. * @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) * @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) * @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. * @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. * @return Upon successful completion, mms_send() returns a value greater zero.
* Otherwise, a negative value is returned to indicate the error. * 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) * @see ::trans_poll(int)
@ -170,7 +173,7 @@ int mms_close(int socket, int how);
* @param msg_size Size of incoming packet. * @param msg_size Size of incoming packet.
* @param packet_info Additional packet information. * @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. * @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. * @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. * @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 <stdio.h>
#include <string.h> #include <string.h>
@ -16,30 +34,37 @@
#define END_ESC 0xDC #define END_ESC 0xDC
#define ESC_ESC 0xDD #define ESC_ESC 0xDD
void demultiplex(border_packet_t *packet, int len) { void demultiplex(border_packet_t *packet, int len)
switch (packet->type) { {
case (BORDER_PACKET_RAW_TYPE):{ switch(packet->type) {
fputs(((char *)packet) + sizeof (border_packet_t), stdin); case(BORDER_PACKET_RAW_TYPE): {
fputs(((char *)packet) + sizeof(border_packet_t), stdin);
break; break;
} }
case (BORDER_PACKET_L3_TYPE):{
case(BORDER_PACKET_L3_TYPE): {
border_l3_header_t *l3_header_buf = (border_l3_header_t *)packet; border_l3_header_t *l3_header_buf = (border_l3_header_t *)packet;
switch (l3_header_buf->ethertype) {
case (BORDER_ETHERTYPE_IPV6):{ switch(l3_header_buf->ethertype) {
struct ipv6_hdr_t *ipv6_buf = (struct ipv6_hdr_t *)(((unsigned char *)packet) + sizeof (border_l3_header_t)); 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); border_send_ipv6_over_lowpan(ipv6_buf, 1, 1);
break; break;
} }
default: default:
printf("ERROR: Unknown ethertype 0x%04x\n", l3_header_buf->ethertype); printf("ERROR: Unknown ethertype 0x%04x\n", l3_header_buf->ethertype);
break; break;
} }
break; break;
} }
case (BORDER_PACKET_CONF_TYPE):{
case(BORDER_PACKET_CONF_TYPE): {
border_conf_header_t *conf_header_buf = (border_conf_header_t *)packet; 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; border_context_packet_t *context = (border_context_packet_t *)packet;
ipv6_addr_t target_addr; ipv6_addr_t target_addr;
ipv6_set_all_nds_mcast_addr(&target_addr); ipv6_set_all_nds_mcast_addr(&target_addr);
@ -51,41 +76,47 @@ void demultiplex(border_packet_t *packet, int len) {
context->context.comp, context->context.comp,
context->context.lifetime context->context.lifetime
); );
mutex_unlock(&lowpan_context_mutex,0); mutex_unlock(&lowpan_context_mutex, 0);
abr_add_context(context->context.version, &abr_addr, context->context.cid); abr_add_context(context->context.version, &abr_addr, context->context.cid);
// Send router advertisement /* Send router advertisement */
break; break;
} }
case (BORDER_CONF_IPADDR):{
case(BORDER_CONF_IPADDR): {
//border_addr_packet_t *addr_packet = (border_addr_packet_t *)packet; //border_addr_packet_t *addr_packet = (border_addr_packet_t *)packet;
// add address /* add address */
break; break;
} }
default: default:
printf("ERROR: Unknown conftype %02x\n", conf_header_buf->conftype); printf("ERROR: Unknown conftype %02x\n", conf_header_buf->conftype);
break; break;
} }
break; break;
} }
default: default:
printf("ERROR: Unknown border packet type %02x\n", packet->type); printf("ERROR: Unknown border packet type %02x\n", packet->type);
break; 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; border_l3_header_t *serial_buf;
serial_buf = (border_l3_header_t *)get_serial_out_buffer(0); serial_buf = (border_l3_header_t *)get_serial_out_buffer(0);
serial_buf->empty = 0; serial_buf->empty = 0;
serial_buf->type = BORDER_PACKET_L3_TYPE; serial_buf->type = BORDER_PACKET_L3_TYPE;
serial_buf->ethertype = BORDER_ETHERTYPE_IPV6; serial_buf->ethertype = BORDER_ETHERTYPE_IPV6;
memcpy(get_serial_in_buffer(0)+sizeof (border_l3_header_t), packet, IPV6_HDR_LEN + packet->length); 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)); 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; border_addr_packet_t *serial_buf;
serial_buf = (border_addr_packet_t *)get_serial_in_buffer(0); serial_buf = (border_addr_packet_t *)get_serial_in_buffer(0);
@ -94,42 +125,46 @@ void multiplex_send_addr_over_uart(ipv6_addr_t *addr) {
serial_buf->conftype = BORDER_CONF_IPADDR; serial_buf->conftype = BORDER_CONF_IPADDR;
memcpy(&serial_buf->addr, addr, sizeof(ipv6_addr_t)); 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 *line_buf_ptr = packet_buf;
uint8_t byte = END+1; uint8_t byte = END + 1;
uint8_t esc = 0; uint8_t esc = 0;
while (1) { while(1) {
byte = uart0_readc(); byte = uart0_readc();
if (byte == END) { if(byte == END) {
break; break;
} }
if ( (line_buf_ptr - packet_buf) >= size-1) { if((line_buf_ptr - packet_buf) >= size - 1) {
return -SIXLOWERROR_ARRAYFULL; return -SIXLOWERROR_ARRAYFULL;
} }
if (esc) { if(esc) {
esc = 0; esc = 0;
switch (byte) {
case(END_ESC):{ switch(byte) {
case(END_ESC): {
*line_buf_ptr++ = END; *line_buf_ptr++ = END;
continue; continue;
} }
case(ESC_ESC):{
case(ESC_ESC): {
*line_buf_ptr++ = ESC; *line_buf_ptr++ = ESC;
continue; continue;
} }
default: default:
continue; continue;
} }
} }
if (byte == ESC) { if(byte == ESC) {
esc = 1; esc = 1;
continue; continue;
} }
@ -140,29 +175,33 @@ int readpacket(uint8_t *packet_buf, size_t size) {
return (line_buf_ptr - packet_buf - 1); 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; uint8_t *byte_ptr = packet_buf;
while ((byte_ptr - packet_buf) < size) { while((byte_ptr - packet_buf) < size) {
if ((byte_ptr - packet_buf) > BORDER_BUFFER_SIZE) { if((byte_ptr - packet_buf) > BORDER_BUFFER_SIZE) {
return -1; return -1;
} }
switch (*byte_ptr) { switch(*byte_ptr) {
case(END):{ case(END): {
*byte_ptr = END_ESC; *byte_ptr = END_ESC;
uart0_putc(ESC); uart0_putc(ESC);
break; break;
} }
case(ESC):{
case(ESC): {
*byte_ptr = ESC_ESC; *byte_ptr = ESC_ESC;
uart0_putc(ESC); uart0_putc(ESC);
break; break;
} }
default:{
default: {
break; break;
} }
} }
uart0_putc(*byte_ptr); uart0_putc(*byte_ptr);
byte_ptr++; byte_ptr++;
} }

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 #ifndef BORDERMULTIPLEX_H
#define BORDERMULTIPLEX_H #define BORDERMULTIPLEX_H
@ -18,27 +36,27 @@
/* ethertypes for L3 packets */ /* ethertypes for L3 packets */
#define BORDER_ETHERTYPE_IPV6 0x86DD #define BORDER_ETHERTYPE_IPV6 0x86DD
typedef struct __attribute__ ((packed)) border_packet_t { typedef struct __attribute__((packed)) {
uint8_t empty; uint8_t empty;
uint8_t type; uint8_t type;
uint8_t seq_num; uint8_t seq_num;
} border_packet_t; } border_packet_t;
typedef struct __attribute__ ((packed)) border_l3_header_t { typedef struct __attribute__((packed)) {
uint8_t empty; uint8_t empty;
uint8_t type; uint8_t type;
uint8_t seq_num; uint8_t seq_num;
uint16_t ethertype; uint16_t ethertype;
} border_l3_header_t; } border_l3_header_t;
typedef struct __attribute__ ((packed)) border_conf_header_t { typedef struct __attribute__((packed)) {
uint8_t empty; uint8_t empty;
uint8_t type; uint8_t type;
uint8_t seq_num; uint8_t seq_num;
uint8_t conftype; uint8_t conftype;
} border_conf_header_t; } border_conf_header_t;
typedef struct __attribute__ ((packed)) border_addr_packet_t { typedef struct __attribute__((packed)) {
uint8_t empty; uint8_t empty;
uint8_t type; uint8_t type;
uint8_t seq_num; uint8_t seq_num;
@ -47,7 +65,7 @@ typedef struct __attribute__ ((packed)) border_addr_packet_t {
ipv6_addr_t addr; ipv6_addr_t addr;
} border_addr_packet_t; } border_addr_packet_t;
typedef struct __attribute__ ((packed)) border_context_packet_t { typedef struct __attribute__((packed)) {
uint8_t empty; uint8_t empty;
uint8_t type; uint8_t type;
uint8_t seq_num; 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 <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -20,17 +38,18 @@ flowcontrol_stat_t slwin_stat;
sem_t connection_established; sem_t connection_established;
int16_t synack_seqnum = -1; int16_t synack_seqnum = -1;
ipv6_addr_t init_threeway_handshake(void) { ipv6_addr_t init_threeway_handshake(void)
{
border_syn_packet_t *syn; border_syn_packet_t *syn;
msg_t m; msg_t m;
m.content.ptr = NULL; m.content.ptr = NULL;
msg_send(&m,border_get_serial_reader(),1); msg_send(&m, border_get_serial_reader(), 1);
msg_receive(&m); msg_receive(&m);
syn = (border_syn_packet_t *)m.content.ptr; syn = (border_syn_packet_t *)m.content.ptr;
border_conf_header_t *synack = (border_conf_header_t *)get_serial_out_buffer(0); border_conf_header_t *synack = (border_conf_header_t *)get_serial_out_buffer(0);
ipv6_addr_t addr; 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.next_exp = syn->next_seq_num;
slwin_stat.last_frame = syn->next_exp - 1; slwin_stat.last_frame = syn->next_exp - 1;
@ -40,33 +59,38 @@ ipv6_addr_t init_threeway_handshake(void) {
synack->type = BORDER_PACKET_CONF_TYPE; synack->type = BORDER_PACKET_CONF_TYPE;
synack->conftype = BORDER_CONF_SYNACK; 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"); 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)); flowcontrol_send_over_uart((border_packet_t *)synack, sizeof(border_conf_header_t));
synack_seqnum = synack->seq_num; synack_seqnum = synack->seq_num;
return addr; return addr;
} }
ipv6_addr_t flowcontrol_init(void) { ipv6_addr_t flowcontrol_init(void)
{
int i; 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++) { for(i = 0; i < BORDER_SWS; i++) {
slwin_stat.send_win[i].frame_len = 0; 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++) { for(i = 0; i < BORDER_RWS; i++) {
slwin_stat.recv_win[i].received = 0; slwin_stat.recv_win[i].received = 0;
slwin_stat.recv_win[i].frame_len = 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(); return init_threeway_handshake();
} }
static void sending_slot(void) { static void sending_slot(void)
{
msg_t m; msg_t m;
uint8_t seq_num; uint8_t seq_num;
struct send_slot *slot; struct send_slot *slot;
@ -76,19 +100,20 @@ static void sending_slot(void) {
msg_receive(&m); msg_receive(&m);
seq_num = *((uint8_t *)m.content.ptr); seq_num = *((uint8_t *)m.content.ptr);
slot = &(slwin_stat.send_win[seq_num % BORDER_SWS]); 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) { if(seq_num == tmp->seq_num) {
writepacket(slot->frame,slot->frame_len); writepacket(slot->frame, slot->frame_len);
if (set_timeout(&slot->timeout, BORDER_SL_TIMEOUT, (void*) m.content.ptr) != 0) { if(set_timeout(&slot->timeout, BORDER_SL_TIMEOUT, (void *)m.content.ptr) != 0) {
printf("ERROR: Error invoking timeout timer\n"); 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; timex_t interval;
interval.seconds = useconds / 1000000; interval.seconds = useconds / 1000000;
interval.microseconds = (useconds % 1000000) * 1000; interval.microseconds = (useconds % 1000000) * 1000;
@ -96,13 +121,15 @@ static int set_timeout(vtimer_t *timeout, long useconds, void *args) {
return vtimer_set_msg(timeout, interval, sending_slot_pid, args); 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 pos = seq_num - min;
uint8_t maxpos = max - min + 1; uint8_t maxpos = max - min + 1;
return pos < maxpos; 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; struct send_slot *slot;
uint8_t args[] = {packet->seq_num}; uint8_t args[] = {packet->seq_num};
@ -111,41 +138,49 @@ void flowcontrol_send_over_uart(border_packet_t *packet, int len) {
slot = &(slwin_stat.send_win[packet->seq_num % BORDER_SWS]); slot = &(slwin_stat.send_win[packet->seq_num % BORDER_SWS]);
memcpy(slot->frame, (uint8_t *)packet, len); memcpy(slot->frame, (uint8_t *)packet, len);
slot->frame_len = 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"); printf("ERROR: Error invoking timeout timer\n");
return; return;
} }
writepacket((uint8_t *)packet, len); 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); border_packet_t *packet = (border_packet_t *)get_serial_out_buffer(0);
packet->empty = 0; packet->empty = 0;
packet->type = BORDER_PACKET_ACK_TYPE; packet->type = BORDER_PACKET_ACK_TYPE;
packet->seq_num = seq_num; 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) { 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(packet->type == BORDER_PACKET_ACK_TYPE) {
if (synack_seqnum == packet->seq_num) { if(in_window(packet->seq_num, slwin_stat.last_ack + 1, slwin_stat.last_frame)) {
if(synack_seqnum == packet->seq_num) {
synack_seqnum = -1; synack_seqnum = -1;
sem_signal(&connection_established); sem_signal(&connection_established);
} }
do { do {
struct send_slot *slot; struct send_slot *slot;
slot = &(slwin_stat.send_win[++slwin_stat.last_ack % BORDER_SWS]); slot = &(slwin_stat.send_win[++slwin_stat.last_ack % BORDER_SWS]);
vtimer_remove(&slot->timeout); 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); sem_signal(&slwin_stat.send_win_not_full);
} while (slwin_stat.last_ack != packet->seq_num);
} }
} else { while(slwin_stat.last_ack != packet->seq_num);
}
}
else {
struct recv_slot *slot; struct recv_slot *slot;
slot = &(slwin_stat.recv_win[packet->seq_num % BORDER_RWS]); slot = &(slwin_stat.recv_win[packet->seq_num % BORDER_RWS]);
if ( !in_window(packet->seq_num,
if(!in_window(packet->seq_num,
slwin_stat.next_exp, slwin_stat.next_exp,
slwin_stat.next_exp + BORDER_RWS - 1)) { slwin_stat.next_exp + BORDER_RWS - 1)) {
return; return;
@ -154,10 +189,10 @@ void flowcontrol_deliver_from_uart(border_packet_t *packet, int len) {
memcpy(slot->frame, (uint8_t *)packet, len); memcpy(slot->frame, (uint8_t *)packet, len);
slot->received = 1; slot->received = 1;
if (packet->seq_num == slwin_stat.next_exp) { if(packet->seq_num == slwin_stat.next_exp) {
while (slot->received) { while(slot->received) {
demultiplex((border_packet_t *)slot->frame, slot->frame_len); 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->received = 0;
slot = &slwin_stat.recv_win[++(slwin_stat.next_exp) % BORDER_RWS]; slot = &slwin_stat.recv_win[++(slwin_stat.next_exp) % BORDER_RWS];
} }

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 #ifndef FLOWCONTROL_H
#define FLOWCONTROL_H #define FLOWCONTROL_H
@ -22,7 +40,7 @@
#define SENDING_SLOT_STACK_SIZE (256) #define SENDING_SLOT_STACK_SIZE (256)
typedef struct flowcontrol_stat_t { typedef struct {
/* Sender state */ /* Sender state */
uint8_t last_ack; uint8_t last_ack;
uint8_t last_frame; uint8_t last_frame;
@ -42,7 +60,7 @@ typedef struct flowcontrol_stat_t {
} recv_win[BORDER_RWS]; } recv_win[BORDER_RWS];
} flowcontrol_stat_t; } flowcontrol_stat_t;
typedef struct __attribute__ ((packed)) border_syn_packet_t { typedef struct __attribute__((packed)) {
uint8_t empty; uint8_t empty;
uint8_t type; uint8_t type;
uint8_t next_seq_num; uint8_t next_seq_num;

View File

@ -1,12 +1,30 @@
/**
* 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" #include "ieee802154_frame.h"
//uint8_t mac_buf[IEEE_802154_HDR_LEN + IEEE_802154_PAYLOAD_LEN];
uint8_t ieee802154_hdr_ptr; uint8_t ieee802154_hdr_ptr;
uint8_t ieee802154_payload_ptr; uint8_t ieee802154_payload_ptr;
uint16_t ieee802154_payload_len; 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 */ /* Frame Control Field - 802.15.4 - 2006 - 7.2.1.1 */
uint8_t index = 0; uint8_t index = 0;
@ -26,51 +44,55 @@ uint8_t init_802154_frame(ieee802154_frame_t *frame, uint8_t *buf){
index++; index++;
/* Destination PAN Identifier - 802.15.4 - 2006 - 7.2.1.3 */ /* 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] = ((frame->dest_pan_id >> 8) & 0xff);
buf[index+1] = (frame->dest_pan_id & 0xff); buf[index + 1] = (frame->dest_pan_id & 0xff);
} }
index += 2; index += 2;
/* Destination Address - 802.15.4 - 2006 - 7.2.1.4 */ /* Destination Address - 802.15.4 - 2006 - 7.2.1.4 */
if(frame->fcf.dest_addr_m == 0x02){ if(frame->fcf.dest_addr_m == 0x02) {
buf[index] = frame->dest_addr[0]; buf[index] = frame->dest_addr[0];
buf[index+1] = frame->dest_addr[1]; buf[index + 1] = frame->dest_addr[1];
index += 2; index += 2;
} else if(frame->fcf.dest_addr_m == 0x03){ }
else if(frame->fcf.dest_addr_m == 0x03) {
buf[index] = frame->dest_addr[0]; buf[index] = frame->dest_addr[0];
buf[index+1] = frame->dest_addr[1]; buf[index + 1] = frame->dest_addr[1];
buf[index+2] = frame->dest_addr[2]; buf[index + 2] = frame->dest_addr[2];
buf[index+3] = frame->dest_addr[3]; buf[index + 3] = frame->dest_addr[3];
buf[index+4] = frame->dest_addr[4]; buf[index + 4] = frame->dest_addr[4];
buf[index+5] = frame->dest_addr[5]; buf[index + 5] = frame->dest_addr[5];
buf[index+6] = frame->dest_addr[6]; buf[index + 6] = frame->dest_addr[6];
buf[index+7] = frame->dest_addr[7]; buf[index + 7] = frame->dest_addr[7];
index += 8; index += 8;
} }
/* Source PAN Identifier - 802.15.4 - 2006 - 7.2.1.5 */ /* Source PAN Identifier - 802.15.4 - 2006 - 7.2.1.5 */
if(!(frame->fcf.panid_comp & 0x01)){ if(!(frame->fcf.panid_comp & 0x01)) {
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) {
buf[index] = ((frame->src_pan_id >> 8) & 0xff); buf[index] = ((frame->src_pan_id >> 8) & 0xff);
buf[index+1] = (frame->src_pan_id & 0xff); buf[index + 1] = (frame->src_pan_id & 0xff);
index += 2; index += 2;
} }
} }
/* Source Address field - 802.15.4 - 2006 - 7.2.1.6 */ /* Source Address field - 802.15.4 - 2006 - 7.2.1.6 */
if(frame->fcf.src_addr_m == 0x02){ if(frame->fcf.src_addr_m == 0x02) {
buf[index] = frame->src_addr[0]; buf[index] = frame->src_addr[0];
buf[index+1] = frame->src_addr[1]; buf[index + 1] = frame->src_addr[1];
index += 2; index += 2;
} else if(frame->fcf.src_addr_m == 0x03){ }
else if(frame->fcf.src_addr_m == 0x03) {
buf[index] = frame->src_addr[0]; buf[index] = frame->src_addr[0];
buf[index+1] = frame->src_addr[1]; buf[index + 1] = frame->src_addr[1];
buf[index+2] = frame->src_addr[2]; buf[index + 2] = frame->src_addr[2];
buf[index+3] = frame->src_addr[3]; buf[index + 3] = frame->src_addr[3];
buf[index+4] = frame->src_addr[4]; buf[index + 4] = frame->src_addr[4];
buf[index+5] = frame->src_addr[5]; buf[index + 5] = frame->src_addr[5];
buf[index+6] = frame->src_addr[6]; buf[index + 6] = frame->src_addr[6];
buf[index+7] = frame->src_addr[7]; buf[index + 7] = frame->src_addr[7];
index += 8; index += 8;
} }
@ -82,30 +104,34 @@ uint8_t init_802154_frame(ieee802154_frame_t *frame, uint8_t *buf){
* | FCF | DSN | DPID | DAD | SPID | SAD | * | 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; uint8_t len = 0;
if(frame->fcf.dest_addr_m == 0x02){ if(frame->fcf.dest_addr_m == 0x02) {
len += 2; len += 2;
} else if(frame->fcf.dest_addr_m == 0x03){ }
else if(frame->fcf.dest_addr_m == 0x03) {
len += 8; len += 8;
} }
if(frame->fcf.src_addr_m == 0x02){ if(frame->fcf.src_addr_m == 0x02) {
len += 2; len += 2;
} else if(frame->fcf.src_addr_m == 0x03){ }
else if(frame->fcf.src_addr_m == 0x03) {
len += 8; 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; 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; len += 2;
} }
/* if src pan id == dest pan id set compression bit */ /* 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; frame->fcf.panid_comp = 1;
len -= 2; len -= 2;
} }
@ -114,7 +140,8 @@ uint8_t get_802154_hdr_len(ieee802154_frame_t *frame){
return (len + 3); 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 index = 0;
uint8_t hdrlen; uint8_t hdrlen;
@ -138,60 +165,64 @@ uint8_t read_802154_frame(uint8_t *buf, ieee802154_frame_t *frame, uint8_t len){
index++; 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; index += 2;
switch(frame->fcf.dest_addr_m){ switch(frame->fcf.dest_addr_m) {
case(0):{ case(0): {
printf("fcf.dest_addr_m: pan identifier/address fields empty\n"); printf("fcf.dest_addr_m: pan identifier/address fields empty\n");
break; break;
} }
case(2):{
case(2): {
frame->dest_addr[0] = buf[index]; frame->dest_addr[0] = buf[index];
frame->dest_addr[1] = buf[index+1]; frame->dest_addr[1] = buf[index + 1];
index += 2; index += 2;
break; break;
} }
case(3):{
case(3): {
frame->dest_addr[0] = buf[index]; frame->dest_addr[0] = buf[index];
frame->dest_addr[1] = buf[index+1]; frame->dest_addr[1] = buf[index + 1];
frame->dest_addr[2] = buf[index+2]; frame->dest_addr[2] = buf[index + 2];
frame->dest_addr[3] = buf[index+3]; frame->dest_addr[3] = buf[index + 3];
frame->dest_addr[4] = buf[index+4]; frame->dest_addr[4] = buf[index + 4];
frame->dest_addr[5] = buf[index+5]; frame->dest_addr[5] = buf[index + 5];
frame->dest_addr[6] = buf[index+6]; frame->dest_addr[6] = buf[index + 6];
frame->dest_addr[7] = buf[index+7]; frame->dest_addr[7] = buf[index + 7];
index += 8; index += 8;
break; break;
} }
} }
if(!(frame->fcf.panid_comp == 1)){ if(!(frame->fcf.panid_comp == 1)) {
frame->src_pan_id = (((uint16_t)buf[index]) << 8) | buf[index+1]; frame->src_pan_id = (((uint16_t)buf[index]) << 8) | buf[index + 1];
index += 2; index += 2;
} }
switch(frame->fcf.src_addr_m){ switch(frame->fcf.src_addr_m) {
case(0):{ case(0): {
printf("fcf.src_addr_m: pan identifier/address fields empty\n"); printf("fcf.src_addr_m: pan identifier/address fields empty\n");
break; break;
} }
case(2):{
case(2): {
frame->src_addr[0] = buf[index]; frame->src_addr[0] = buf[index];
frame->src_addr[1] = buf[index+1]; frame->src_addr[1] = buf[index + 1];
index += 2; index += 2;
break; break;
} }
case(3):{
case(3): {
frame->src_addr[0] = buf[index]; frame->src_addr[0] = buf[index];
frame->src_addr[1] = buf[index+1]; frame->src_addr[1] = buf[index + 1];
frame->src_addr[2] = buf[index+2]; frame->src_addr[2] = buf[index + 2];
frame->src_addr[3] = buf[index+3]; frame->src_addr[3] = buf[index + 3];
frame->src_addr[4] = buf[index+4]; frame->src_addr[4] = buf[index + 4];
frame->src_addr[5] = buf[index+5]; frame->src_addr[5] = buf[index + 5];
frame->src_addr[6] = buf[index+6]; frame->src_addr[6] = buf[index + 6];
frame->src_addr[7] = buf[index+7]; frame->src_addr[7] = buf[index + 7];
index += 8; index += 8;
break; break;
} }
@ -204,7 +235,8 @@ uint8_t read_802154_frame(uint8_t *buf, ieee802154_frame_t *frame, uint8_t len){
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" printf("frame type: %02x\n"
"security enabled: %02x\n" "security enabled: %02x\n"
"frame pending: %02x\n" "frame pending: %02x\n"

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 #ifndef IEEE802154_FRAME
#define IEEE802154_FRAME #define IEEE802154_FRAME
@ -19,7 +37,7 @@
#define IEEE_802154_PAN_ID 0x1234 #define IEEE_802154_PAN_ID 0x1234
typedef struct __attribute__ ((packed)) { typedef struct __attribute__((packed)) {
uint8_t frame_type; uint8_t frame_type;
uint8_t sec_enb; uint8_t sec_enb;
uint8_t frame_pend; uint8_t frame_pend;
@ -30,7 +48,7 @@ typedef struct __attribute__ ((packed)) {
uint8_t src_addr_m; uint8_t src_addr_m;
} ieee802154_fcf_frame_t; } ieee802154_fcf_frame_t;
typedef struct __attribute__ ((packed)) { typedef struct __attribute__((packed)) {
ieee802154_fcf_frame_t fcf; ieee802154_fcf_frame_t fcf;
uint8_t seq_nr; uint8_t seq_nr;
uint16_t dest_pan_id; uint16_t dest_pan_id;

View File

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

View File

@ -1,3 +1,20 @@
/**
* 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 <string.h>
#include "of0.h" #include "of0.h"
@ -10,43 +27,53 @@ rpl_of_t rpl_of0 = {
NULL NULL
}; };
rpl_of_t *rpl_get_of0(void){ rpl_of_t *rpl_get_of0(void)
{
return &rpl_of0; return &rpl_of0;
} }
void reset(rpl_dodag_t *dodag){ void reset(rpl_dodag_t *dodag)
//Nothing to do in OF0 {
/* Nothing to do in OF0 */
} }
uint16_t calc_rank(rpl_parent_t * parent, uint16_t base_rank){ uint16_t calc_rank(rpl_parent_t *parent, uint16_t base_rank)
{
if(base_rank == 0) { if(base_rank == 0) {
if(parent == NULL) { if(parent == NULL) {
return INFINITE_RANK; return INFINITE_RANK;
} }
base_rank = parent->rank; base_rank = parent->rank;
} }
uint16_t add; uint16_t add;
if(parent != NULL){
if(parent != NULL) {
add = parent->dodag->minhoprankincrease; add = parent->dodag->minhoprankincrease;
} }
else{ else {
add = DEFAULT_MIN_HOP_RANK_INCREASE; add = DEFAULT_MIN_HOP_RANK_INCREASE;
} }
if( base_rank + add < base_rank ){
if(base_rank + add < base_rank) {
return INFINITE_RANK; return INFINITE_RANK;
} }
return base_rank + add; return base_rank + add;
} }
//We simply return the Parent with lower rank /* We simply return the Parent with lower rank */
rpl_parent_t * which_parent(rpl_parent_t *p1, rpl_parent_t *p2){ rpl_parent_t *which_parent(rpl_parent_t *p1, rpl_parent_t *p2)
if(p1->rank < p2->rank){ {
if(p1->rank < p2->rank) {
return p1; return p1;
} }
return p2; return p2;
} }
rpl_dodag_t * which_dodag(rpl_dodag_t *d1, rpl_dodag_t *d2){ rpl_dodag_t *which_dodag(rpl_dodag_t *d1, rpl_dodag_t *d2)
{
return d1; 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 <stdint.h>
#include <vtimer.h> #include <vtimer.h>
#include <mutex.h> #include <mutex.h>
@ -22,9 +40,9 @@ void recv_rpl_dis(void);
void recv_rpl_dao(void); void recv_rpl_dao(void);
void recv_rpl_dao_ack(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); 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_add_routing_entry(ipv6_addr_t *addr, ipv6_addr_t *next_hop, uint16_t lifetime);
void rpl_del_routing_entry(ipv6_addr_t *addr); 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); void rpl_clear_routing_table(void);
rpl_routing_entry_t *rpl_get_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 <string.h>
#include <stdio.h> #include <stdio.h>
@ -9,235 +27,280 @@ rpl_instance_t instances[RPL_MAX_INSTANCES];
rpl_dodag_t dodags[RPL_MAX_DODAGS]; rpl_dodag_t dodags[RPL_MAX_DODAGS];
rpl_parent_t parents[RPL_MAX_PARENTS]; rpl_parent_t parents[RPL_MAX_PARENTS];
rpl_instance_t *rpl_new_instance(uint8_t instanceid){ rpl_instance_t *rpl_new_instance(uint8_t instanceid)
{
rpl_instance_t *inst; rpl_instance_t *inst;
rpl_instance_t *end ; rpl_instance_t *end ;
for(inst=&instances[0], end = inst+RPL_MAX_INSTANCES; inst < end;inst++){
if(inst->used == 0){ for(inst = &instances[0], end = inst + RPL_MAX_INSTANCES; inst < end; inst++) {
if(inst->used == 0) {
memset(inst, 0, sizeof(*inst)); memset(inst, 0, sizeof(*inst));
inst->used = 1; inst->used = 1;
inst->id = instanceid; inst->id = instanceid;
return inst; return inst;
} }
} }
return NULL; return NULL;
} }
rpl_instance_t *rpl_get_instance(uint8_t instanceid){ 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)){ for(int i = 0; i < RPL_MAX_INSTANCES; i++) {
if(instances[i].used && (instances[i].id == instanceid)) {
return &instances[i]; return &instances[i];
} }
} }
return NULL; return NULL;
} }
rpl_instance_t *rpl_get_my_instance(){ rpl_instance_t *rpl_get_my_instance()
for(int i=0;i<RPL_MAX_INSTANCES;i++){ {
if(instances[i].joined){ for(int i = 0; i < RPL_MAX_INSTANCES; i++) {
if(instances[i].joined) {
return &instances[i]; return &instances[i];
} }
} }
return NULL; return NULL;
} }
rpl_dodag_t * rpl_new_dodag(uint8_t instanceid, ipv6_addr_t *dodagid){ rpl_dodag_t *rpl_new_dodag(uint8_t instanceid, ipv6_addr_t *dodagid)
rpl_instance_t * inst; {
rpl_instance_t *inst;
inst = rpl_get_instance(instanceid); inst = rpl_get_instance(instanceid);
if(inst == NULL){
printf("Error - No instance found for id %d. This should not happen\n", instanceid); if(inst == NULL) {
printf("Error - No instance found for id %d. This should not happen\n",
instanceid);
return NULL; return NULL;
} }
rpl_dodag_t *dodag; rpl_dodag_t *dodag;
rpl_dodag_t *end; rpl_dodag_t *end;
for(dodag= &dodags[0], end=dodag+RPL_MAX_DODAGS; dodag < end; dodag++){ for(dodag = &dodags[0], end = dodag + RPL_MAX_DODAGS; dodag < end; dodag++) {
if( dodag->used == 0){ if(dodag->used == 0) {
memset(dodag, 0,sizeof(*dodag)); memset(dodag, 0, sizeof(*dodag));
dodag->instance = inst; dodag->instance = inst;
dodag->my_rank = INFINITE_RANK; dodag->my_rank = INFINITE_RANK;
dodag->used = 1; dodag->used = 1;
memcpy(&dodag->dodag_id,dodagid,sizeof(*dodagid)); memcpy(&dodag->dodag_id, dodagid, sizeof(*dodagid));
return dodag; return dodag;
} }
} }
return NULL; return NULL;
} }
rpl_dodag_t *rpl_get_dodag(ipv6_addr_t *id){ 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))){ 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 &dodags[i];
} }
} }
return NULL; return NULL;
} }
rpl_dodag_t *rpl_get_my_dodag(){ rpl_dodag_t *rpl_get_my_dodag()
for(int i=0;i<RPL_MAX_DODAGS;i++){ {
if( dodags[i].joined){ for(int i = 0; i < RPL_MAX_DODAGS; i++) {
if(dodags[i].joined) {
return &dodags[i]; return &dodags[i];
} }
} }
return NULL; return NULL;
} }
void rpl_del_dodag(rpl_dodag_t *dodag){ void rpl_del_dodag(rpl_dodag_t *dodag)
{
memset(dodag, 0, sizeof(*dodag)); memset(dodag, 0, sizeof(*dodag));
} }
void rpl_leave_dodag(rpl_dodag_t * dodag){ void rpl_leave_dodag(rpl_dodag_t *dodag)
{
dodag->joined = 0; dodag->joined = 0;
dodag->my_preferred_parent = NULL; dodag->my_preferred_parent = NULL;
rpl_delete_all_parents(); rpl_delete_all_parents();
} }
bool rpl_equal_id(ipv6_addr_t *id1, ipv6_addr_t *id2){ 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]){ for(uint8_t i = 0; i < 4; i++) {
if(id1->uint32[i] != id2->uint32[i]) {
return false; return false;
} }
} }
return true; return true;
} }
rpl_parent_t *rpl_new_parent(rpl_dodag_t *dodag, ipv6_addr_t *address, uint16_t rank){ rpl_parent_t *rpl_new_parent(rpl_dodag_t *dodag, ipv6_addr_t *address, uint16_t rank)
{
rpl_parent_t *parent; rpl_parent_t *parent;
rpl_parent_t *end; rpl_parent_t *end;
for(parent= &parents[0], end=parents+RPL_MAX_PARENTS; parent < end; parent++){ for(parent = &parents[0], end = parents + RPL_MAX_PARENTS; parent < end; parent++) {
if(parent->used == 0){ if(parent->used == 0) {
memset(parent, 0, sizeof(*parent)); memset(parent, 0, sizeof(*parent));
parent->used = 1; parent->used = 1;
parent->addr = *address; parent->addr = *address;
parent->rank = rank; parent->rank = rank;
parent->dodag = dodag; parent->dodag = dodag;
//dtsn is set at the end of recv_dio function /* dtsn is set at the end of recv_dio function */
parent->dtsn = 0; parent->dtsn = 0;
return parent; return parent;
} }
} }
rpl_delete_worst_parent(); rpl_delete_worst_parent();
return rpl_new_parent(dodag, address, rank); return rpl_new_parent(dodag, address, rank);
} }
rpl_parent_t *rpl_find_parent(ipv6_addr_t *address){ rpl_parent_t *rpl_find_parent(ipv6_addr_t *address)
{
rpl_parent_t *parent; rpl_parent_t *parent;
rpl_parent_t *end; rpl_parent_t *end;
for(parent= &parents[0], end=parents+RPL_MAX_PARENTS; parent < end; parent++){ for(parent = &parents[0], end = parents + RPL_MAX_PARENTS; parent < end; parent++) {
if( (parent->used) && (rpl_equal_id(address, &parent->addr)) ){ if((parent->used) && (rpl_equal_id(address, &parent->addr))) {
return parent; return parent;
} }
} }
return NULL; return NULL;
} }
void rpl_delete_parent(rpl_parent_t * 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) ){ 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; my_dodag->my_preferred_parent = NULL;
} }
memset(parent,0,sizeof(*parent));
memset(parent, 0, sizeof(*parent));
} }
void rpl_delete_worst_parent(void){ void rpl_delete_worst_parent(void)
{
uint8_t worst = 0xFF; uint8_t worst = 0xFF;
uint16_t max_rank = 0x0000; uint16_t max_rank = 0x0000;
for(int i=0;i<RPL_MAX_PARENTS;i++){
if(parents[i].rank > max_rank){ for(int i = 0; i < RPL_MAX_PARENTS; i++) {
if(parents[i].rank > max_rank) {
worst = i; worst = i;
max_rank = parents[i].rank; max_rank = parents[i].rank;
} }
} }
if(worst == 0xFF){
//Fehler, keine parents -> sollte nicht passieren if(worst == 0xFF) {
/* Fehler, keine parents -> sollte nicht passieren */
return; return;
} }
rpl_delete_parent(&parents[worst]); rpl_delete_parent(&parents[worst]);
} }
void rpl_delete_all_parents(void){ void rpl_delete_all_parents(void)
rpl_dodag_t * my_dodag = rpl_get_my_dodag(); {
rpl_dodag_t *my_dodag = rpl_get_my_dodag();
my_dodag->my_preferred_parent = NULL; my_dodag->my_preferred_parent = NULL;
for(int i=0;i<RPL_MAX_PARENTS;i++){
memset(&parents[i],0,sizeof(parents[i])); 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 *rpl_find_preferred_parent(void)
rpl_parent_t * best = NULL; {
rpl_dodag_t * my_dodag = rpl_get_my_dodag(); rpl_parent_t *best = NULL;
rpl_dodag_t *my_dodag = rpl_get_my_dodag();
for(uint8_t i=0;i<RPL_MAX_PARENTS;i++){ for(uint8_t i = 0; i < RPL_MAX_PARENTS; i++) {
if(parents[i].used){ if(parents[i].used) {
if((parents[i].rank == INFINITE_RANK) || (parents[i].lifetime <= 1)){ if((parents[i].rank == INFINITE_RANK) || (parents[i].lifetime <= 1)) {
puts("bad parent"); puts("bad parent");
continue; continue;
} }
else if(best == NULL){ else if(best == NULL) {
puts("parent"); puts("parent");
best = &parents[i]; best = &parents[i];
} else{ }
else {
best = my_dodag->of->which_parent(best, &parents[i]); best = my_dodag->of->which_parent(best, &parents[i]);
} }
} }
} }
if(best == NULL) {
if(best == NULL){
return NULL; return NULL;
} }
if(!rpl_equal_id(&my_dodag->my_preferred_parent->addr, &best->addr)){ if(!rpl_equal_id(&my_dodag->my_preferred_parent->addr, &best->addr)) {
if(my_dodag->mop != NO_DOWNWARD_ROUTES){ if(my_dodag->mop != NO_DOWNWARD_ROUTES) {
//send DAO with ZERO_LIFETIME to old parent /* send DAO with ZERO_LIFETIME to old parent */
send_DAO(&my_dodag->my_preferred_parent->addr, 0, false, 0); send_DAO(&my_dodag->my_preferred_parent->addr, 0, false, 0);
} }
my_dodag->my_preferred_parent = best; my_dodag->my_preferred_parent = best;
if(my_dodag->mop != NO_DOWNWARD_ROUTES){
if(my_dodag->mop != NO_DOWNWARD_ROUTES) {
delay_dao(); delay_dao();
} }
reset_trickletimer(); reset_trickletimer();
} }
return best; return best;
} }
void rpl_parent_update(rpl_parent_t * parent){ void rpl_parent_update(rpl_parent_t *parent)
rpl_dodag_t * my_dodag = rpl_get_my_dodag(); {
rpl_dodag_t *my_dodag = rpl_get_my_dodag();
uint16_t old_rank = my_dodag->my_rank; uint16_t old_rank = my_dodag->my_rank;
//update Parent lifetime /* update Parent lifetime */
if(parent != NULL){ if(parent != NULL) {
parent->lifetime = my_dodag->default_lifetime * my_dodag->lifetime_unit; parent->lifetime = my_dodag->default_lifetime * my_dodag->lifetime_unit;
} }
if(rpl_find_preferred_parent() == NULL){ if(rpl_find_preferred_parent() == NULL) {
rpl_local_repair(); rpl_local_repair();
} }
if(rpl_calc_rank(old_rank, my_dodag->minhoprankincrease) != rpl_calc_rank(my_dodag->my_rank, my_dodag->minhoprankincrease)){ if(rpl_calc_rank(old_rank, my_dodag->minhoprankincrease) !=
if(my_dodag->my_rank < my_dodag->min_rank){ 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; my_dodag->min_rank = my_dodag->my_rank;
} }
reset_trickletimer(); reset_trickletimer();
} }
} }
void rpl_join_dodag(rpl_dodag_t *dodag, ipv6_addr_t *parent, uint16_t parent_rank){ void rpl_join_dodag(rpl_dodag_t *dodag, ipv6_addr_t *parent, uint16_t parent_rank)
{
rpl_dodag_t *my_dodag; rpl_dodag_t *my_dodag;
rpl_parent_t *preferred_parent; rpl_parent_t *preferred_parent;
my_dodag = rpl_new_dodag(dodag->instance->id, &dodag->dodag_id); my_dodag = rpl_new_dodag(dodag->instance->id, &dodag->dodag_id);
if(my_dodag == NULL){
if(my_dodag == NULL) {
return; return;
} }
preferred_parent = rpl_new_parent(my_dodag, parent, parent_rank); preferred_parent = rpl_new_parent(my_dodag, parent, parent_rank);
if(preferred_parent == NULL){
if(preferred_parent == NULL) {
rpl_del_dodag(my_dodag); rpl_del_dodag(my_dodag);
return; return;
} }
my_dodag->instance->joined = 1; my_dodag->instance->joined = 1;
my_dodag->of = dodag->of; my_dodag->of = dodag->of;
my_dodag->mop = dodag->mop; my_dodag->mop = dodag->mop;
@ -262,39 +325,48 @@ void rpl_join_dodag(rpl_dodag_t *dodag, ipv6_addr_t *parent, uint16_t parent_ran
delay_dao(); delay_dao();
} }
void rpl_global_repair(rpl_dodag_t *dodag, ipv6_addr_t * p_addr, uint16_t rank){ void rpl_global_repair(rpl_dodag_t *dodag, ipv6_addr_t *p_addr, uint16_t rank)
{
puts("[INFO] Global repair started"); puts("[INFO] Global repair started");
rpl_dodag_t * my_dodag = rpl_get_my_dodag(); rpl_dodag_t *my_dodag = rpl_get_my_dodag();
if(my_dodag == NULL){
if(my_dodag == NULL) {
printf("[Error] - no global repair possible, if not part of a DODAG\n"); printf("[Error] - no global repair possible, if not part of a DODAG\n");
return; return;
} }
rpl_delete_all_parents(); rpl_delete_all_parents();
my_dodag->version = dodag->version; my_dodag->version = dodag->version;
my_dodag->dtsn++; my_dodag->dtsn++;
my_dodag->my_preferred_parent = rpl_new_parent(my_dodag, p_addr, rank); my_dodag->my_preferred_parent = rpl_new_parent(my_dodag, p_addr, rank);
if(my_dodag->my_preferred_parent == NULL){
if(my_dodag->my_preferred_parent == NULL) {
printf("[Error] no more parent after global repair\n"); printf("[Error] no more parent after global repair\n");
my_dodag->my_rank = INFINITE_RANK; my_dodag->my_rank = INFINITE_RANK;
}else{ }
//Calc new Rank else {
my_dodag->my_rank = my_dodag->of->calc_rank(my_dodag->my_preferred_parent, my_dodag->my_rank); /* 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; my_dodag->min_rank = my_dodag->my_rank;
reset_trickletimer(); reset_trickletimer();
delay_dao(); delay_dao();
} }
printf("Migrated to DODAG Version %d. My new Rank: %d\n", my_dodag->version, my_dodag->my_rank);
printf("Migrated to DODAG Version %d. My new Rank: %d\n", my_dodag->version,
my_dodag->my_rank);
} }
void rpl_local_repair(void){ void rpl_local_repair(void)
{
puts("[INFO] Local Repair started"); puts("[INFO] Local Repair started");
rpl_dodag_t * my_dodag = rpl_get_my_dodag(); rpl_dodag_t *my_dodag = rpl_get_my_dodag();
if(my_dodag == NULL){
if(my_dodag == NULL) {
printf("[Error] - no local repair possible, if not part of a DODAG\n"); printf("[Error] - no local repair possible, if not part of a DODAG\n");
return; return;
} }
my_dodag->my_rank = INFINITE_RANK; my_dodag->my_rank = INFINITE_RANK;
my_dodag->dtsn++; my_dodag->dtsn++;
rpl_delete_all_parents(); rpl_delete_all_parents();
@ -302,14 +374,18 @@ void rpl_local_repair(void){
} }
ipv6_addr_t *rpl_get_my_preferred_parent(){ ipv6_addr_t *rpl_get_my_preferred_parent()
rpl_dodag_t * my_dodag = rpl_get_my_dodag(); {
if(my_dodag == NULL){ rpl_dodag_t *my_dodag = rpl_get_my_dodag();
if(my_dodag == NULL) {
return NULL; return NULL;
} }
return &my_dodag->my_preferred_parent->addr; return &my_dodag->my_preferred_parent->addr;
} }
uint16_t rpl_calc_rank(uint16_t abs_rank, uint16_t minhoprankincrease){ uint16_t rpl_calc_rank(uint16_t abs_rank, uint16_t minhoprankincrease)
{
return abs_rank / 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 "rpl_structs.h"
//#include "of0.h"
rpl_instance_t *rpl_new_instance(uint8_t instanceid); rpl_instance_t *rpl_new_instance(uint8_t instanceid);
rpl_instance_t *rpl_get_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); 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_new_parent(rpl_dodag_t *dodag, ipv6_addr_t *address, uint16_t rank);
rpl_parent_t *rpl_find_parent(ipv6_addr_t *address); 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); bool rpl_equal_id(ipv6_addr_t *id1, ipv6_addr_t *id2);
ipv6_addr_t *rpl_get_my_preferred_parent(void); ipv6_addr_t *rpl_get_my_preferred_parent(void);
void rpl_delete_parent(rpl_parent_t *parent); void rpl_delete_parent(rpl_parent_t *parent);
void rpl_delete_worst_parent(void); void rpl_delete_worst_parent(void);
void rpl_delete_all_parents(void); void rpl_delete_all_parents(void);
rpl_parent_t * rpl_find_preferred_parent(void); rpl_parent_t *rpl_find_preferred_parent(void);
void rpl_parent_update(rpl_parent_t * parent); 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_global_repair(rpl_dodag_t *dodag, ipv6_addr_t *p_addr, uint16_t rank);
void rpl_local_repair(void); void rpl_local_repair(void);
uint16_t rpl_calc_rank(uint16_t abs_rank, uint16_t minhoprankincrease); 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" #include "sys/net/sixlowpan/sixlowip.h"
#ifndef RPL_STRUCTS_H_INCLUDED #ifndef RPL_STRUCTS_H_INCLUDED
#define RPL_STRUCTS_H_INCLUDED #define RPL_STRUCTS_H_INCLUDED
// Modes of Operation /* Modes of Operation */
#define NO_DOWNWARD_ROUTES 0x00 #define NO_DOWNWARD_ROUTES 0x00
#define NON_STORING_MODE 0x01 #define NON_STORING_MODE 0x01
#define STORING_MODE_NO_MC 0x02 #define STORING_MODE_NO_MC 0x02
#define STORING_MODE_MC 0x03 #define STORING_MODE_MC 0x03
//ICMP type /* ICMP type */
#define ICMP_RPL_CONTROL 155 #define ICMP_RPL_CONTROL 155
#define RPL_SEQUENCE_WINDOW 16 #define RPL_SEQUENCE_WINDOW 16
#define ICMP_CODE_DIS 0x00 #define ICMP_CODE_DIS 0x00
#define ICMP_CODE_DIO 0x01 #define ICMP_CODE_DIO 0x01
#define ICMP_CODE_DAO 0x02 #define ICMP_CODE_DAO 0x02
#define ICMP_CODE_DAO_ACK 0x03 #define ICMP_CODE_DAO_ACK 0x03
//packet base lengths /* packet base lengths */
#define DIO_BASE_LEN 24 #define DIO_BASE_LEN 24
#define DIS_BASE_LEN 2 #define DIS_BASE_LEN 2
#define DAO_BASE_LEN 4 #define DAO_BASE_LEN 4
@ -30,7 +48,7 @@
#define RPL_OPT_TARGET_LEN 18 #define RPL_OPT_TARGET_LEN 18
#define RPL_OPT_TRANSIT_LEN 4 #define RPL_OPT_TRANSIT_LEN 4
//message options /* message options */
#define RPL_OPT_PAD1 0 #define RPL_OPT_PAD1 0
#define RPL_OPT_PADN 1 #define RPL_OPT_PADN 1
#define RPL_OPT_DAG_METRIC_CONTAINER 2 #define RPL_OPT_DAG_METRIC_CONTAINER 2
@ -42,7 +60,7 @@
#define RPL_OPT_PREFIX_INFO 8 #define RPL_OPT_PREFIX_INFO 8
#define RPL_OPT_TARGET_DESC 9 #define RPL_OPT_TARGET_DESC 9
//Counters /* Counters */
#define RPL_COUNTER_MAX 255 #define RPL_COUNTER_MAX 255
#define RPL_COUNTER_LOWER_REGION 127 #define RPL_COUNTER_LOWER_REGION 127
#define RPL_COUNTER_SEQ_WINDOW 16 #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_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))) #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 #define RPL_DEFAULT_MOP STORING_MODE_NO_MC
// RPL Constants and Variables /* RPL Constants and Variables */
#define BASE_RANK 0 #define BASE_RANK 0
#define ROOT_RANK 1 #define ROOT_RANK 1
@ -64,21 +82,21 @@
#define RPL_DEFAULT_INSTANCE 0 #define RPL_DEFAULT_INSTANCE 0
#define DEFAULT_PATH_CONTROL_SIZE 0 #define DEFAULT_PATH_CONTROL_SIZE 0
#define DEFAULT_DIO_INTERVAL_MIN 11 #define DEFAULT_DIO_INTERVAL_MIN 11
//standard value: /* standard value: */
//#define DEFAULT_DIO_INTERVAL_MIN 3 /* #define DEFAULT_DIO_INTERVAL_MIN 3 */
#define DEFAULT_DIO_INTERVAL_DOUBLINGS 7 #define DEFAULT_DIO_INTERVAL_DOUBLINGS 7
//standard value: /* standard value: */
//#define DEFAULT_DIO_INTERVAL_DOUBLINGS 20 /* #define DEFAULT_DIO_INTERVAL_DOUBLINGS 20 */
#define DEFAULT_DIO_REDUNDANCY_CONSTANT 10 #define DEFAULT_DIO_REDUNDANCY_CONSTANT 10
#define DEFAULT_MIN_HOP_RANK_INCREASE 256 #define DEFAULT_MIN_HOP_RANK_INCREASE 256
//DAO_DELAY is in seconds /* DAO_DELAY is in seconds */
#define DEFAULT_DAO_DELAY 3 #define DEFAULT_DAO_DELAY 3
#define REGULAR_DAO_INTERVAL 300 #define REGULAR_DAO_INTERVAL 300
#define DAO_SEND_RETRIES 4 #define DAO_SEND_RETRIES 4
#define DEFAULT_WAIT_FOR_DAO_ACK 15 #define DEFAULT_WAIT_FOR_DAO_ACK 15
#define RPL_DODAG_ID_LEN 16 #define RPL_DODAG_ID_LEN 16
//others /* others */
#define NUMBER_IMPLEMENTED_OFS 1 #define NUMBER_IMPLEMENTED_OFS 1
#define RPL_MAX_DODAGS 3 #define RPL_MAX_DODAGS 3
@ -98,7 +116,7 @@
#define RPL_GROUNDED_SHIFT 7 #define RPL_GROUNDED_SHIFT 7
#define RPL_DEFAULT_OCP 0 #define RPL_DEFAULT_OCP 0
struct __attribute__((packed)) rpl_dio_t{ struct __attribute__((packed)) rpl_dio_t {
uint8_t rpl_instanceid; uint8_t rpl_instanceid;
uint8_t version_number; uint8_t version_number;
uint16_t rank; uint16_t rank;
@ -109,35 +127,36 @@ struct __attribute__((packed)) rpl_dio_t{
ipv6_addr_t dodagid; ipv6_addr_t dodagid;
}; };
struct __attribute__((packed)) rpl_dis_t{ struct __attribute__((packed)) rpl_dis_t {
uint8_t flags; uint8_t flags;
uint8_t reserved; uint8_t reserved;
}; };
struct __attribute__((packed)) rpl_dao_t{ struct __attribute__((packed)) rpl_dao_t {
uint8_t rpl_instanceid; uint8_t rpl_instanceid;
uint8_t k_d_flags; uint8_t k_d_flags;
uint8_t reserved; uint8_t reserved;
uint8_t dao_sequence; uint8_t dao_sequence;
}; };
struct __attribute__((packed)) rpl_dao_ack_t{ struct __attribute__((packed)) rpl_dao_ack_t {
uint8_t rpl_instanceid; uint8_t rpl_instanceid;
uint8_t d_reserved; uint8_t d_reserved;
uint8_t dao_sequence; uint8_t dao_sequence;
uint8_t status; uint8_t status;
}; };
//may be present in dao or dao_ack packets /* may be present in dao or dao_ack packets */
struct __attribute__((packed)) dodag_id_t{ struct __attribute__((packed)) dodag_id_t {
ipv6_addr_t dodagid; ipv6_addr_t dodagid;
}; };
typedef struct __attribute__((packed)) rpl_opt_t {
typedef struct __attribute__((packed)) {
uint8_t type; uint8_t type;
uint8_t length; uint8_t length;
} rpl_opt_t; } rpl_opt_t;
typedef struct __attribute__((packed)) rpl_opt_dodag_conf_t { typedef struct __attribute__((packed)) {
uint8_t type; uint8_t type;
uint8_t length; uint8_t length;
uint8_t flags_a_pcs; uint8_t flags_a_pcs;
@ -152,7 +171,7 @@ typedef struct __attribute__((packed)) rpl_opt_dodag_conf_t {
uint16_t lifetime_unit; uint16_t lifetime_unit;
} rpl_opt_dodag_conf_t; } rpl_opt_dodag_conf_t;
typedef struct __attribute__((packed)) rpl_opt_solicited_t { typedef struct __attribute__((packed)) {
uint8_t type; uint8_t type;
uint8_t length; uint8_t length;
uint8_t rplinstanceid; uint8_t rplinstanceid;
@ -161,8 +180,8 @@ typedef struct __attribute__((packed)) rpl_opt_solicited_t {
uint8_t version; uint8_t version;
} rpl_opt_solicited_t; } rpl_opt_solicited_t;
//ipv6_addr_t target may be replaced by a target prefix of variable length /* ipv6_addr_t target may be replaced by a target prefix of variable length */
typedef struct __attribute__((packed)) rpl_opt_target_t { typedef struct __attribute__((packed)) {
uint8_t type; uint8_t type;
uint8_t length; uint8_t length;
uint8_t flags; uint8_t flags;
@ -170,7 +189,7 @@ typedef struct __attribute__((packed)) rpl_opt_target_t {
ipv6_addr_t target; ipv6_addr_t target;
} rpl_opt_target_t; } rpl_opt_target_t;
typedef struct __attribute__((packed)) rpl_opt_transit_t { typedef struct __attribute__((packed)) {
uint8_t type; uint8_t type;
uint8_t length; uint8_t length;
uint8_t e_flags; uint8_t e_flags;
@ -181,7 +200,7 @@ typedef struct __attribute__((packed)) rpl_opt_transit_t {
struct rpl_dodag_t; struct rpl_dodag_t;
typedef struct rpl_parent_t { typedef struct {
ipv6_addr_t addr; ipv6_addr_t addr;
uint16_t rank; uint16_t rank;
uint8_t dtsn; uint8_t dtsn;
@ -192,15 +211,14 @@ typedef struct rpl_parent_t {
struct rpl_of_t; struct rpl_of_t;
typedef struct rpl_instance_t { typedef struct {
//struct rpl_dodag_t *current_dodoag;
uint8_t id; uint8_t id;
uint8_t used; uint8_t used;
uint8_t joined; uint8_t joined;
} rpl_instance_t; } rpl_instance_t;
typedef struct rpl_dodag_t { typedef struct {
rpl_instance_t *instance; rpl_instance_t *instance;
ipv6_addr_t dodag_id; ipv6_addr_t dodag_id;
uint8_t used; uint8_t used;
@ -222,10 +240,9 @@ typedef struct rpl_dodag_t {
uint8_t joined; uint8_t joined;
rpl_parent_t *my_preferred_parent; rpl_parent_t *my_preferred_parent;
struct rpl_of_t *of; struct rpl_of_t *of;
} rpl_dodag_t; } rpl_dodag_t;
typedef struct rpl_of_t { typedef struct {
uint16_t ocp; uint16_t ocp;
uint16_t (*calc_rank)(rpl_parent_t *, uint16_t); uint16_t (*calc_rank)(rpl_parent_t *, uint16_t);
rpl_parent_t *(*which_parent)(rpl_parent_t *, rpl_parent_t *); rpl_parent_t *(*which_parent)(rpl_parent_t *, rpl_parent_t *);
@ -234,7 +251,7 @@ typedef struct rpl_of_t {
void (*parent_state_callback)(rpl_parent_t *, int, int); void (*parent_state_callback)(rpl_parent_t *, int, int);
} rpl_of_t; } rpl_of_t;
typedef struct rpl_routing_entry_t { typedef struct {
uint8_t used; uint8_t used;
ipv6_addr_t address; ipv6_addr_t address;
ipv6_addr_t next_hop; ipv6_addr_t next_hop;

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 <string.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -32,14 +50,14 @@ timex_t I_time;
timex_t dao_time; timex_t dao_time;
timex_t rt_time; timex_t rt_time;
//struct für trickle parameter?? void reset_trickletimer(void)
void reset_trickletimer(void){ {
I = Imin; I = Imin;
c = 0; c = 0;
//start timer /* start timer */
t = (I/2) + ( rand() % ( I - (I/2) + 1 ) ); t = (I / 2) + (rand() % (I - (I / 2) + 1));
t_time = timex_set(0,t*1000); t_time = timex_set(0, t * 1000);
I_time = timex_set(0,I*1000); I_time = timex_set(0, I * 1000);
timex_normalize(&t_time); timex_normalize(&t_time);
timex_normalize(&I_time); timex_normalize(&I_time);
vtimer_remove(&trickle_t_timer); vtimer_remove(&trickle_t_timer);
@ -49,48 +67,51 @@ void reset_trickletimer(void){
} }
void init_trickle(void){ void init_trickle(void)
//Create threads {
/* Create threads */
ack_received = true; ack_received = true;
timer_over_pid = thread_create(timer_over_buf, TRICKLE_TIMER_STACKSIZE, timer_over_pid = thread_create(timer_over_buf, TRICKLE_TIMER_STACKSIZE,
PRIORITY_MAIN-1,CREATE_STACKTEST, PRIORITY_MAIN - 1, CREATE_STACKTEST,
trickle_timer_over, "trickle_timer_over"); trickle_timer_over, "trickle_timer_over");
interval_over_pid = thread_create(interval_over_buf, TRICKLE_INTERVAL_STACKSIZE, interval_over_pid = thread_create(interval_over_buf, TRICKLE_INTERVAL_STACKSIZE,
PRIORITY_MAIN-1, CREATE_STACKTEST, PRIORITY_MAIN - 1, CREATE_STACKTEST,
trickle_interval_over, "trickle_interval_over"); trickle_interval_over, "trickle_interval_over");
dao_delay_over_pid = thread_create(dao_delay_over_buf, DAO_DELAY_STACKSIZE, dao_delay_over_pid = thread_create(dao_delay_over_buf, DAO_DELAY_STACKSIZE,
PRIORITY_MAIN-1, CREATE_STACKTEST, PRIORITY_MAIN - 1, CREATE_STACKTEST,
dao_delay_over, "dao_delay_over"); dao_delay_over, "dao_delay_over");
rt_timer_over_pid = thread_create(routing_table_buf, RT_STACKSIZE, rt_timer_over_pid = thread_create(routing_table_buf, RT_STACKSIZE,
PRIORITY_MAIN-1, CREATE_STACKTEST, PRIORITY_MAIN - 1, CREATE_STACKTEST,
rt_timer_over, "rt_timer_over"); rt_timer_over, "rt_timer_over");
} }
void start_trickle(uint8_t DIOIntMin, uint8_t DIOIntDoubl, uint8_t DIORedundancyConstant){ void start_trickle(uint8_t DIOIntMin, uint8_t DIOIntDoubl,
uint8_t DIORedundancyConstant)
{
c = 0; c = 0;
k = DIORedundancyConstant; k = DIORedundancyConstant;
Imin = pow(2, DIOIntMin); Imin = pow(2, DIOIntMin);
Imax = DIOIntDoubl; Imax = DIOIntDoubl;
//Eigentlich laut Spezifikation erste Bestimmung von I wie auskommentiert: /* Eigentlich laut Spezifikation erste Bestimmung von I wie auskommentiert: */
//I = Imin + ( rand() % ( (Imin << Imax) - Imin + 1 ) ); /* I = Imin + ( rand() % ( (Imin << Imax) - Imin + 1 ) ); */
I = Imin + ( rand() % (4*Imin) ) ; I = Imin + (rand() % (4 * Imin)) ;
t = (I/2) + ( rand() % ( I - (I/2) + 1 ) ); t = (I / 2) + (rand() % (I - (I / 2) + 1));
t_time = timex_set(0,t*1000); t_time = timex_set(0, t * 1000);
timex_normalize(&t_time); timex_normalize(&t_time);
I_time = timex_set(0,I*1000); I_time = timex_set(0, I * 1000);
timex_normalize(&I_time); timex_normalize(&I_time);
vtimer_remove(&trickle_t_timer); vtimer_remove(&trickle_t_timer);
vtimer_remove(&trickle_I_timer); vtimer_remove(&trickle_I_timer);
vtimer_set_wakeup(&trickle_t_timer, t_time, timer_over_pid); vtimer_set_wakeup(&trickle_t_timer, t_time, timer_over_pid);
vtimer_set_wakeup(&trickle_I_timer, I_time, interval_over_pid); vtimer_set_wakeup(&trickle_I_timer, I_time, interval_over_pid);
} }
void trickle_increment_counter(void){ void trickle_increment_counter(void)
//call this function, when received DIO message {
/* call this function, when received DIO message */
c++; c++;
} }
@ -98,114 +119,133 @@ void trickle_timer_over(void)
{ {
ipv6_addr_t mcast; ipv6_addr_t mcast;
ipv6_set_all_nds_mcast_addr(&mcast); ipv6_set_all_nds_mcast_addr(&mcast);
while(1){
while(1) {
thread_sleep(); thread_sleep();
//Laut RPL Spezifikation soll k=0 wie k= Unendlich behandelt werden, also immer gesendet werden
if( (c < k) || (k == 0)){ /* Laut RPL Spezifikation soll k=0 wie k= Unendlich behandelt werden, also immer gesendet werden */
if((c < k) || (k == 0)) {
send_DIO(&mcast); send_DIO(&mcast);
} }
} }
} }
void trickle_interval_over(void){ void trickle_interval_over(void)
while(1){ {
while(1) {
thread_sleep(); thread_sleep();
I = I*2; I = I * 2;
printf("TRICKLE new Interval %u\n",I); printf("TRICKLE new Interval %u\n", I);
if( I == 0 ){
if(I == 0) {
puts("[WARNING] Interval was 0"); puts("[WARNING] Interval was 0");
if( Imax == 0){
if(Imax == 0) {
puts("[WARNING] Imax == 0"); puts("[WARNING] Imax == 0");
} }
I = (Imin << Imax); I = (Imin << Imax);
} }
if(I > (Imin << Imax)){
I=(Imin << Imax); if(I > (Imin << Imax)) {
I = (Imin << Imax);
} }
c=0;
t = (I/2) + ( rand() % ( I - (I/2) + 1 ) ); c = 0;
//start timer t = (I / 2) + (rand() % (I - (I / 2) + 1));
t_time = timex_set(0,t*1000); /* start timer */
t_time = timex_set(0, t * 1000);
timex_normalize(&t_time); timex_normalize(&t_time);
I_time = timex_set(0,I*1000); I_time = timex_set(0, I * 1000);
timex_normalize(&I_time); 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) {
if(vtimer_set_wakeup(&trickle_t_timer, t_time, timer_over_pid) != 0){
puts("[ERROR] setting Wakeup"); puts("[ERROR] setting Wakeup");
} }
if(vtimer_set_wakeup(&trickle_I_timer, I_time, interval_over_pid) != 0){
if(vtimer_set_wakeup(&trickle_I_timer, I_time, interval_over_pid) != 0) {
puts("[ERROR] setting Wakeup"); puts("[ERROR] setting Wakeup");
} }
} }
} }
void delay_dao(void){ void delay_dao(void)
dao_time = timex_set(DEFAULT_DAO_DELAY,0); {
dao_time = timex_set(DEFAULT_DAO_DELAY, 0);
dao_counter = 0; dao_counter = 0;
ack_received = false; ack_received = false;
vtimer_remove(&dao_timer); vtimer_remove(&dao_timer);
vtimer_set_wakeup(&dao_timer, dao_time, dao_delay_over_pid); 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 /* 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){ void long_delay_dao(void)
dao_time = timex_set(REGULAR_DAO_INTERVAL,0); {
dao_time = timex_set(REGULAR_DAO_INTERVAL, 0);
dao_counter = 0; dao_counter = 0;
ack_received = false; ack_received = false;
vtimer_remove(&dao_timer); vtimer_remove(&dao_timer);
vtimer_set_wakeup(&dao_timer, dao_time, dao_delay_over_pid); vtimer_set_wakeup(&dao_timer, dao_time, dao_delay_over_pid);
} }
void dao_delay_over(void){ void dao_delay_over(void)
while(1){ {
while(1) {
thread_sleep(); thread_sleep();
if((ack_received == false) && (dao_counter < DAO_SEND_RETRIES)){
if((ack_received == false) && (dao_counter < DAO_SEND_RETRIES)) {
dao_counter++; dao_counter++;
send_DAO(NULL, 0, true, 0); send_DAO(NULL, 0, true, 0);
dao_time = timex_set(DEFAULT_WAIT_FOR_DAO_ACK,0); dao_time = timex_set(DEFAULT_WAIT_FOR_DAO_ACK, 0);
vtimer_set_wakeup(&dao_timer, dao_time, dao_delay_over_pid); vtimer_set_wakeup(&dao_timer, dao_time, dao_delay_over_pid);
} }
else if(ack_received == false){ else if(ack_received == false) {
long_delay_dao(); long_delay_dao();
} }
} }
} }
void dao_ack_received(){ void dao_ack_received()
{
ack_received = true; ack_received = true;
long_delay_dao(); long_delay_dao();
} }
void rt_timer_over(void){ void rt_timer_over(void)
rpl_routing_entry_t * rt; {
while(1){ rpl_routing_entry_t *rt;
rpl_dodag_t * my_dodag = rpl_get_my_dodag();
if(my_dodag != NULL){ while(1) {
rpl_dodag_t *my_dodag = rpl_get_my_dodag();
if(my_dodag != NULL) {
rt = rpl_get_routing_table(); rt = rpl_get_routing_table();
for(uint8_t i=0; i<RPL_MAX_ROUTING_ENTRIES;i++){
if(rt[i].used){ for(uint8_t i = 0; i < RPL_MAX_ROUTING_ENTRIES; i++) {
if(rt[i].lifetime <= 1){ if(rt[i].used) {
memset(&rt[i], 0,sizeof(rt[i])); if(rt[i].lifetime <= 1) {
memset(&rt[i], 0, sizeof(rt[i]));
} }
else{ else {
rt[i].lifetime--; rt[i].lifetime--;
} }
} }
} }
//Parent is NULL for root too
if(my_dodag->my_preferred_parent != NULL){ /* Parent is NULL for root too */
if(my_dodag->my_preferred_parent->lifetime <= 1){ if(my_dodag->my_preferred_parent != NULL) {
if(my_dodag->my_preferred_parent->lifetime <= 1) {
puts("parent lifetime timeout"); puts("parent lifetime timeout");
rpl_parent_update(NULL); rpl_parent_update(NULL);
} }
else{ else {
my_dodag->my_preferred_parent->lifetime--; my_dodag->my_preferred_parent->lifetime--;
} }
} }
} }
//Wake up every second
/* Wake up every second */
vtimer_usleep(1000000); 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 <vtimer.h>
#include <thread.h> #include <thread.h>
#define TRICKLE_TIMER_STACKSIZE 3072 #define TRICKLE_TIMER_STACKSIZE 3072
//#define TRICKLE_TIMER_STACKSIZE 4096
#define TRICKLE_INTERVAL_STACKSIZE 3072 #define TRICKLE_INTERVAL_STACKSIZE 3072
//#define DAO_DELAY_STACKSIZE 2048
#define DAO_DELAY_STACKSIZE 3072 #define DAO_DELAY_STACKSIZE 3072
//#define DAO_DELAY_STACKSIZE 4096
#define RT_STACKSIZE 512 #define RT_STACKSIZE 512
void reset_trickletimer(void); void reset_trickletimer(void);

View File

@ -1,19 +1,41 @@
/**
* 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 <mutex.h>
#include "semaphore.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; sem->value = value;
mutex_init(&sem->mutex); mutex_init(&sem->mutex);
sem->locked = 0; sem->locked = 0;
} }
int sem_wait(sem_t *sem) { int sem_wait(sem_t *sem)
{
int res; int res;
if(--(sem->value) <= 0 && !sem->locked) { if(--(sem->value) <= 0 && !sem->locked) {
sem->locked = !(sem->locked); sem->locked = !(sem->locked);
res = mutex_lock(&(sem->mutex)); res = mutex_lock(&(sem->mutex));
if (res < 0) {
if(res < 0) {
return res; return res;
} }
} }
@ -21,10 +43,11 @@ int sem_wait(sem_t *sem) {
return 0; return 0;
} }
int sem_signal(sem_t *sem) { int sem_signal(sem_t *sem)
if (++(sem->value) > 0 && sem->locked) { {
if(++(sem->value) > 0 && sem->locked) {
sem->locked = !(sem->locked); sem->locked = !(sem->locked);
mutex_unlock(&(sem->mutex),0); mutex_unlock(&(sem->mutex), 0);
} }
return 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 #ifndef SEMAPHORE_H
#define SEMAPHORE_H #define 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" #include "serialnumber.h"
int serial_add8(uint8_t s, uint8_t n) { int serial_add8(uint8_t s, uint8_t n)
if (n > 127) {
if(n > 127) {
return -1; 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) { int serial_add16(uint16_t s, uint16_t n)
if (n > 32767) {
if(n > 32767) {
return -1; 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) { int serial_add32(uint32_t s, uint32_t n)
if (n > 2147483647) {
if(n > 2147483647) {
return -1; 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) { serial_comp_res_t serial_comp8(uint8_t s1, uint8_t s2)
if (s1 == s2) {
if(s1 == s2) {
return EQUAL; 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; 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 GREATER;
} }
return UNDEF; return UNDEF;
} }
serial_comp_res_t serial_comp16(uint16_t s1, uint16_t s2) { serial_comp_res_t serial_comp16(uint16_t s1, uint16_t s2)
if (s1 == s2) {
if(s1 == s2) {
return EQUAL; 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; 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 GREATER;
} }
return UNDEF; return UNDEF;
} }
serial_comp_res_t serial_comp32(uint32_t s1, uint32_t s2) { serial_comp_res_t serial_comp32(uint32_t s1, uint32_t s2)
if (s1 == s2) {
if(s1 == s2) {
return EQUAL; 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; 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 GREATER;
} }
return UNDEF; 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 <stdint.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
@ -28,27 +46,31 @@ uint16_t serial_reader_pid;
uint8_t serial_out_buf[BORDER_BUFFER_SIZE]; uint8_t serial_out_buf[BORDER_BUFFER_SIZE];
uint8_t serial_in_buf[BORDER_BUFFER_SIZE]; uint8_t serial_in_buf[BORDER_BUFFER_SIZE];
uint8_t *get_serial_out_buffer(int offset) { uint8_t *get_serial_out_buffer(int offset)
if (offset > BUFFER_SIZE) { {
if(offset > BUFFER_SIZE) {
return NULL; return NULL;
} }
return &(serial_out_buf[offset]); return &(serial_out_buf[offset]);
} }
uint8_t *get_serial_in_buffer(int offset) { uint8_t *get_serial_in_buffer(int offset)
if (offset > BUFFER_SIZE) { {
if(offset > BUFFER_SIZE) {
return NULL; return NULL;
} }
return &(serial_in_buf[offset]); return &(serial_in_buf[offset]);
} }
uint16_t border_get_serial_reader() { uint16_t border_get_serial_reader()
{
return serial_reader_pid; return serial_reader_pid;
} }
void serial_reader_f(void) { void serial_reader_f(void)
{
int main_pid = 0; int main_pid = 0;
int bytes; int bytes;
msg_t m; msg_t m;
@ -62,44 +84,51 @@ void serial_reader_f(void) {
while(1) { while(1) {
posix_open(uart0_handler_pid, 0); posix_open(uart0_handler_pid, 0);
bytes = readpacket(get_serial_in_buffer(0), BORDER_BUFFER_SIZE); bytes = readpacket(get_serial_in_buffer(0), BORDER_BUFFER_SIZE);
if (bytes < 0) {
switch (bytes) { if(bytes < 0) {
case (-SIXLOWERROR_ARRAYFULL):{ switch(bytes) {
case(-SIXLOWERROR_ARRAYFULL): {
printf("ERROR: Array was full\n"); printf("ERROR: Array was full\n");
break; break;
} }
default:{
default: {
printf("ERROR: unknown\n"); printf("ERROR: unknown\n");
break; break;
} }
} }
continue; continue;
} }
uart_buf = (border_packet_t*)get_serial_in_buffer(0); uart_buf = (border_packet_t *)get_serial_in_buffer(0);
if (uart_buf->empty == 0) {
if (uart_buf->type == BORDER_PACKET_CONF_TYPE) { if(uart_buf->empty == 0) {
border_conf_header_t *conf_packet = (border_conf_header_t*)uart_buf; if(uart_buf->type == BORDER_PACKET_CONF_TYPE) {
if (conf_packet->conftype == BORDER_CONF_SYN) { 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; m.content.ptr = (char *)conf_packet;
msg_send(&m, main_pid, 1); msg_send(&m, main_pid, 1);
continue; continue;
} }
} }
flowcontrol_deliver_from_uart(uart_buf, bytes); 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; ipv6_addr_t addr;
serial_reader_pid = thread_create( serial_reader_pid = thread_create(
serial_reader_stack, READER_STACK_SIZE, serial_reader_stack, READER_STACK_SIZE,
PRIORITY_MAIN-1, CREATE_STACKTEST, PRIORITY_MAIN - 1, CREATE_STACKTEST,
serial_reader_f, "serial_reader"); serial_reader_f, "serial_reader");
if (border_router_addr == NULL) { if(border_router_addr == NULL) {
border_router_addr = &addr; border_router_addr = &addr;
addr = flowcontrol_init(); addr = flowcontrol_init();
@ -109,40 +138,42 @@ uint8_t border_initialize(transceiver_type_t trans,ipv6_addr_t *border_router_ad
* RFC 4944 (Section 6) & RFC 2464 (Section 4) from short address * RFC 4944 (Section 6) & RFC 2464 (Section 4) from short address
* -- for now * -- for now
*/ */
if ( border_router_addr->uint16[4] != HTONS(IEEE_802154_PAN_ID ^ 0x0200) || if(border_router_addr->uint16[4] != HTONS(IEEE_802154_PAN_ID ^ 0x0200) ||
border_router_addr->uint16[5] != HTONS(0x00FF) || border_router_addr->uint16[5] != HTONS(0x00FF) ||
border_router_addr->uint16[6] != HTONS(0xFE00) border_router_addr->uint16[6] != HTONS(0xFE00)
) { ) {
return SIXLOWERROR_ADDRESS; return SIXLOWERROR_ADDRESS;
} }
// radio-address is 8-bit so this must be tested extra /* radio-address is 8-bit so this must be tested extra */
if (border_router_addr->uint8[14] != 0) { if(border_router_addr->uint8[14] != 0) {
return SIXLOWERROR_ADDRESS; return SIXLOWERROR_ADDRESS;
} }
memcpy(&(abr_addr.uint8[0]),&(border_router_addr->uint8[0]),16); memcpy(&(abr_addr.uint8[0]), &(border_router_addr->uint8[0]), 16);
sixlowpan_init(trans,border_router_addr->uint8[15],1); sixlowpan_init(trans, border_router_addr->uint8[15], 1);
ipv6_init_iface_as_router(); ipv6_init_iface_as_router();
return SUCCESS; return SUCCESS;
} }
void border_send_ipv6_over_lowpan(struct ipv6_hdr_t *packet, uint8_t aro_flag, uint8_t sixco_flag) { 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); {
uint16_t offset = IPV6_HDR_LEN + HTONS(packet->length);
packet->flowlabel = HTONS(packet->flowlabel); packet->flowlabel = HTONS(packet->flowlabel);
packet->length = HTONS(packet->length); packet->length = HTONS(packet->length);
memset(buffer, 0, BUFFER_SIZE); memset(buffer, 0, BUFFER_SIZE);
memcpy(buffer+LL_HDR_LEN, packet, offset); memcpy(buffer + LL_HDR_LEN, packet, offset);
lowpan_init((ieee_802154_long_t*)&(packet->destaddr.uint16[4]), (uint8_t*)packet); 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; msg_t m;
struct ipv6_hdr_t *ipv6_buf; struct ipv6_hdr_t *ipv6_buf;
@ -150,18 +181,21 @@ void border_process_lowpan(void) {
msg_receive(&m); msg_receive(&m);
ipv6_buf = (struct ipv6_hdr_t *)m.content.ptr; 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); 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; continue;
} }
if (icmpv6_demultiplex(icmp_buf) == 0) {
continue;
}
// Here, other ICMPv6 message types for ND may follow.
}
// TODO: Bei ICMPv6-Paketen entsprechende LoWPAN-Optionen verarbeiten und entfernen if(icmpv6_demultiplex(icmp_buf) == 0) {
continue;
}
/* Here, other ICMPv6 message types for ND may follow. */
}
/* TODO: Bei ICMPv6-Paketen entsprechende LoWPAN-Optionen verarbeiten und entfernen */
multiplex_send_ipv6_over_uart(ipv6_buf); 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 */ /* 6LoWPAN Border Router header file */
#ifndef SIXLOWBORDER_H #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_out_buffer(int offset);
uint8_t *get_serial_in_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_send_ipv6_over_lowpan(struct ipv6_hdr_t *packet, uint8_t aro_flag, uint8_t sixco_flag);
void border_process_lowpan(void); 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 <stdio.h>
#include <string.h> #include <string.h>
#include <vtimer.h> #include <vtimer.h>
@ -16,8 +36,8 @@
uint8_t ip_send_buffer[BUFFER_SIZE]; uint8_t ip_send_buffer[BUFFER_SIZE];
uint8_t buffer[BUFFER_SIZE]; uint8_t buffer[BUFFER_SIZE];
msg_t msg_queue[IP_PKT_RECV_BUF_SIZE]; msg_t msg_queue[IP_PKT_RECV_BUF_SIZE];
struct ipv6_hdr_t* ipv6_buf; struct ipv6_hdr_t *ipv6_buf;
struct icmpv6_hdr_t* icmp_buf; struct icmpv6_hdr_t *icmp_buf;
uint8_t ipv6_ext_hdr_len; uint8_t ipv6_ext_hdr_len;
uint8_t *nextheader; uint8_t *nextheader;
iface_t iface; iface_t iface;
@ -26,43 +46,51 @@ int udp_packet_handler_pid = 0;
int tcp_packet_handler_pid = 0; int tcp_packet_handler_pid = 0;
int rpl_process_pid = 0; int rpl_process_pid = 0;
struct ipv6_hdr_t* get_ipv6_buf_send(void){ struct ipv6_hdr_t *get_ipv6_buf_send(void)
return ((struct ipv6_hdr_t*)&(ip_send_buffer[LL_HDR_LEN])); {
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]); return &(ip_send_buffer[LLHDR_IPV6HDR_LEN + ext_len]);
} }
struct ipv6_hdr_t* get_ipv6_buf(void){ struct ipv6_hdr_t *get_ipv6_buf(void)
return ((struct ipv6_hdr_t*)&(buffer[LL_HDR_LEN])); {
return ((struct ipv6_hdr_t *) & (buffer[LL_HDR_LEN]));
} }
struct icmpv6_hdr_t* get_icmpv6_buf(uint8_t ext_len){ struct icmpv6_hdr_t *get_icmpv6_buf(uint8_t ext_len)
return ((struct icmpv6_hdr_t*)&(buffer[LLHDR_IPV6HDR_LEN + 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]); return &(buffer[LLHDR_IPV6HDR_LEN + ext_len]);
} }
void sixlowpan_bootstrapping(void){ void sixlowpan_bootstrapping(void)
{
init_rtr_sol(OPT_SLLAO); init_rtr_sol(OPT_SLLAO);
} }
void sixlowpan_send(ipv6_addr_t *addr, uint8_t *payload, uint16_t p_len, uint8_t next_header){ void sixlowpan_send(ipv6_addr_t *addr, uint8_t *payload, uint16_t p_len,
uint8_t next_header)
{
uint8_t *p_ptr; uint8_t *p_ptr;
if (next_header == IPPROTO_TCP)
{ if(next_header == IPPROTO_TCP) {
p_ptr = get_payload_buf_send(ipv6_ext_hdr_len); p_ptr = get_payload_buf_send(ipv6_ext_hdr_len);
ipv6_buf = get_ipv6_buf_send(); ipv6_buf = get_ipv6_buf_send();
} }
else else {
{
ipv6_buf = get_ipv6_buf(); ipv6_buf = get_ipv6_buf();
p_ptr = get_payload_buf(ipv6_ext_hdr_len); p_ptr = get_payload_buf(ipv6_ext_hdr_len);
} }
icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len); icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len);
packet_length = 0; packet_length = 0;
@ -76,51 +104,60 @@ void sixlowpan_send(ipv6_addr_t *addr, uint8_t *payload, uint16_t p_len, uint8_t
memcpy(&(ipv6_buf->destaddr), addr, 16); memcpy(&(ipv6_buf->destaddr), addr, 16);
ipv6_get_saddr(&(ipv6_buf->srcaddr), &(ipv6_buf->destaddr)); 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; 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) { switch(hdr->type) {
case(ICMP_RTR_SOL):{ case(ICMP_RTR_SOL): {
puts("INFO: packet type: icmp router solicitation"); puts("INFO: packet type: icmp router solicitation");
/* processing router solicitation */ /* processing router solicitation */
recv_rtr_sol(); recv_rtr_sol();
/* init solicited router advertisment*/ /* init solicited router advertisment*/
break; break;
} }
case(ICMP_RTR_ADV):{
case(ICMP_RTR_ADV): {
puts("INFO: packet type: icmp router advertisment"); puts("INFO: packet type: icmp router advertisment");
/* processing router advertisment */ /* processing router advertisment */
recv_rtr_adv(); recv_rtr_adv();
/* init neighbor solicitation */ /* init neighbor solicitation */
break; break;
} }
case(ICMP_NBR_SOL):{
case(ICMP_NBR_SOL): {
puts("INFO: packet type: icmp neighbor solicitation"); puts("INFO: packet type: icmp neighbor solicitation");
recv_nbr_sol(); recv_nbr_sol();
break; break;
} }
case(ICMP_NBR_ADV):{
case(ICMP_NBR_ADV): {
puts("INFO: packet type: icmp neighbor advertisment"); puts("INFO: packet type: icmp neighbor advertisment");
recv_nbr_adv(); recv_nbr_adv();
break; break;
} }
case(ICMP_RPL_CONTROL):{
case(ICMP_RPL_CONTROL): {
puts("INFO: packet type: RPL message"); puts("INFO: packet type: RPL message");
if(rpl_process_pid != 0){
if(rpl_process_pid != 0) {
msg_t m_send; msg_t m_send;
m_send.content.ptr = (char*) &hdr->code; m_send.content.ptr = (char *) &hdr->code;
msg_send(&m_send, rpl_process_pid, 1); msg_send(&m_send, rpl_process_pid, 1);
} }
else{ else {
puts("INFO: no RPL handler registered"); puts("INFO: no RPL handler registered");
} }
break; break;
} }
default: default:
return -1; return -1;
} }
@ -128,86 +165,95 @@ int icmpv6_demultiplex(const struct icmpv6_hdr_t *hdr) {
return 0; return 0;
} }
void ipv6_process(void){ void ipv6_process(void)
{
msg_t m_recv_lowpan, m_send_lowpan; msg_t m_recv_lowpan, m_send_lowpan;
msg_t m_recv, m_send; msg_t m_recv, m_send;
ipv6_addr_t myaddr; ipv6_addr_t myaddr;
ipv6_init_address(&myaddr, 0xabcd, 0x0, 0x0, 0x0, 0x3612, 0x00ff, 0xfe00, get_radio_address()); ipv6_init_address(&myaddr, 0xabcd, 0x0, 0x0, 0x0, 0x3612, 0x00ff, 0xfe00,
get_radio_address());
while(1){ while(1) {
msg_receive(&m_recv_lowpan); 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 */ /* identifiy packet */
nextheader = &ipv6_buf->nextheader; nextheader = &ipv6_buf->nextheader;
if ((ipv6_get_addr_match(&myaddr, &ipv6_buf->destaddr) >= 112) && (ipv6_buf->destaddr.uint8[15] != myaddr.uint8[15])) 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); memcpy(get_ipv6_buf_send(), get_ipv6_buf(),
lowpan_init((ieee_802154_long_t*)&(ipv6_buf->destaddr.uint16[4]),(uint8_t*)get_ipv6_buf_send()); IPV6_HDR_LEN + ipv6_buf->length);
lowpan_init((ieee_802154_long_t *)&(ipv6_buf->destaddr.uint16[4]),
(uint8_t *)get_ipv6_buf_send());
} }
else else {
{
switch(*nextheader) { switch(*nextheader) {
case(PROTO_NUM_ICMPV6):{ case(PROTO_NUM_ICMPV6): {
/* checksum test*/ /* checksum test*/
if(icmpv6_csum(PROTO_NUM_ICMPV6) != 0xffff){ if(icmpv6_csum(PROTO_NUM_ICMPV6) != 0xffff) {
printf("ERROR: wrong checksum\n"); printf("ERROR: wrong checksum\n");
} }
icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len); icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len);
icmpv6_demultiplex(icmp_buf); icmpv6_demultiplex(icmp_buf);
break; break;
} }
case(IPPROTO_TCP):
{ case(IPPROTO_TCP): {
if (tcp_packet_handler_pid != 0) if(tcp_packet_handler_pid != 0) {
{ m_send.content.ptr = (char *) ipv6_buf;
m_send.content.ptr = (char*) ipv6_buf;
msg_send_receive(&m_send, &m_recv, tcp_packet_handler_pid); msg_send_receive(&m_send, &m_recv, tcp_packet_handler_pid);
} }
else else {
{
printf("INFO: No TCP handler registered.\n"); printf("INFO: No TCP handler registered.\n");
} }
break; break;
} }
case(IPPROTO_UDP):
{ case(IPPROTO_UDP): {
if (udp_packet_handler_pid != 0) if(udp_packet_handler_pid != 0) {
{ m_send.content.ptr = (char *) ipv6_buf;
m_send.content.ptr = (char*) ipv6_buf;
msg_send_receive(&m_send, &m_recv, udp_packet_handler_pid); msg_send_receive(&m_send, &m_recv, udp_packet_handler_pid);
} }
else else {
{
printf("INFO: No UDP handler registered.\n"); printf("INFO: No UDP handler registered.\n");
} }
break; break;
} }
case(PROTO_NUM_NONE):
{ case(PROTO_NUM_NONE): {
printf("INFO: Packet with no Header following the IPv6 Header received.\n"); printf("INFO: Packet with no Header following the IPv6 Header received.\n");
break; break;
} }
default: default:
break; break;
} }
} }
msg_reply(&m_recv_lowpan, &m_send_lowpan); 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){ void ipv6_iface_add_addr(ipv6_addr_t *addr, uint8_t state, uint32_t val_ltime,
if(ipv6_addr_unspec_match(addr) == 128){ 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"); printf("ERROR: unspecified address (::) can't be assigned to interface.\n");
return; return;
} }
if(ipv6_iface_addr_match(addr) != 0) { if(ipv6_iface_addr_match(addr) != 0) {
return; 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; iface.addr_list[iface_addr_list_count].state = state;
timex_t valtime = {val_ltime, 0}; timex_t valtime = {val_ltime, 0};
timex_t preftime = {pref_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].pref_ltime = timex_add(now, preftime);
iface.addr_list[iface_addr_list_count].type = type; iface.addr_list[iface_addr_list_count].type = type;
iface_addr_list_count++; iface_addr_list_count++;
// Register to Solicited-Node multicast address according to RFC 4291
if (type == ADDR_TYPE_ANYCAST || type == ADDR_TYPE_LINK_LOCAL || /* 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) { type == ADDR_TYPE_GLOBAL || type == ADDR_TYPE_UNICAST) {
ipv6_addr_t sol_node_mcast_addr; ipv6_addr_t sol_node_mcast_addr;
ipv6_set_sol_node_mcast_addr(addr, &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); 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; 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]), 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 &(iface.addr_list[i]);
} }
} }
return NULL; 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; 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]), 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 &(iface.addr_list[i]);
} }
} }
return NULL; return NULL;
} }
void ipv6_iface_print_addrs(void){ void ipv6_iface_print_addrs(void)
for(int i = 0; i < iface_addr_list_count; i++){ {
for(int i = 0; i < iface_addr_list_count; i++) {
ipv6_print_addr(&(iface.addr_list[i].addr)); 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[0] = prefix->uint16[0];
inout->uint16[1] = prefix->uint16[1]; inout->uint16[1] = prefix->uint16[1];
inout->uint16[2] = prefix->uint16[2]; inout->uint16[2] = prefix->uint16[2];
inout->uint16[3] = prefix->uint16[3]; 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[0] = prefix->uint16[0];
inout->uint16[1] = prefix->uint16[1]; inout->uint16[1] = prefix->uint16[1];
inout->uint16[2] = prefix->uint16[2]; 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; 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[0] = HTONS(0xff02);
ipaddr->uint16[1] = 0; ipaddr->uint16[1] = 0;
ipaddr->uint16[2] = 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); 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[0] = HTONS(0xff02);
ipaddr->uint16[1] = 0; ipaddr->uint16[1] = 0;
ipaddr->uint16[2] = 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); 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[0] = 0;
ipaddr->uint16[1] = 0; ipaddr->uint16[1] = 0;
ipaddr->uint16[2] = 0; ipaddr->uint16[2] = 0;
@ -310,63 +370,74 @@ void ipv6_set_loaddr(ipv6_addr_t *ipaddr){
ipaddr->uint16[7] = HTONS(0x0001); 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 */ /* try to find best match if dest is not mcast or link local */
int8_t itmp = -1; int8_t itmp = -1;
uint8_t tmp = 0; uint8_t tmp = 0;
uint8_t bmatch = 0; uint8_t bmatch = 0;
if(!(ipv6_prefix_ll_match(dst)) && !(ipv6_prefix_mcast_match(dst))){ if(!(ipv6_prefix_ll_match(dst)) && !(ipv6_prefix_mcast_match(dst))) {
for(int i = 0; i < IFACE_ADDR_LIST_LEN; i++){ for(int i = 0; i < IFACE_ADDR_LIST_LEN; i++) {
if(iface.addr_list[i].state == ADDR_STATE_PREFERRED){ if(iface.addr_list[i].state == ADDR_STATE_PREFERRED) {
if(!(ipv6_prefix_ll_match(&(iface.addr_list[i].addr)))){ if(!(ipv6_prefix_ll_match(&(iface.addr_list[i].addr)))) {
tmp = ipv6_get_addr_match(dst, &(iface.addr_list[i].addr)); tmp = ipv6_get_addr_match(dst, &(iface.addr_list[i].addr));
if(tmp >= bmatch){
if(tmp >= bmatch) {
bmatch = tmp; bmatch = tmp;
itmp = i; 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) && if((iface.addr_list[j].state == ADDR_STATE_PREFERRED) &&
ipv6_prefix_ll_match(&(iface.addr_list[j].addr))){ ipv6_prefix_ll_match(&(iface.addr_list[j].addr))) {
itmp = j; itmp = j;
} }
} }
} }
if(itmp == -1){ if(itmp == -1) {
memset(src, 0, 16); memset(src, 0, 16);
} else { }
else {
memcpy(src, &(iface.addr_list[itmp].addr), 16); 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; 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 bytes are equal add 8 */
if(src->uint8[i] == dst->uint8[i]){ if(src->uint8[i] == dst->uint8[i]) {
val += 8; val += 8;
} else { }
else {
xor = src->uint8[i] ^ dst->uint8[i]; xor = src->uint8[i] ^ dst->uint8[i];
/* while bits from byte equal add 1 */ /* while bits from byte equal add 1 */
for(int j = 0; j < 8; j++){ for(int j = 0; j < 8; j++) {
if((xor & 0x80) == 0){ if((xor & 0x80) == 0) {
val++; val++;
xor = xor << 1; xor = xor << 1;
} else { }
else {
break; break;
} }
} }
} }
} }
return val; 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[0] = HTONS(0xfe80);
ipaddr->uint16[1] = 0; ipaddr->uint16[1] = 0;
ipaddr->uint16[2] = 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, 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 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[0] = HTONS(addr0);
addr->uint16[1] = HTONS(addr1); addr->uint16[1] = HTONS(addr1);
addr->uint16[2] = HTONS(addr2); 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); addr->uint16[7] = HTONS(addr7);
} }
uint8_t ipv6_prefix_ll_match(ipv6_addr_t *addr){ uint8_t ipv6_prefix_ll_match(ipv6_addr_t *addr)
if(addr->uint8[0] == 0xfe && addr->uint8[1] == 0x80){ {
if(addr->uint8[0] == 0xfe && addr->uint8[1] == 0x80) {
return 1; return 1;
} }
return 0; return 0;
} }
uint8_t ipv6_prefix_mcast_match(ipv6_addr_t *addr){ uint8_t ipv6_prefix_mcast_match(ipv6_addr_t *addr)
if(addr->uint8[0] == 0xff && addr->uint8[1] == 0x02){ {
if(addr->uint8[0] == 0xff && addr->uint8[1] == 0x02) {
return 1; return 1;
} }
return 0; return 0;
} }
uint8_t ipv6_addr_unspec_match(ipv6_addr_t *addr){ uint8_t ipv6_addr_unspec_match(ipv6_addr_t *addr)
{
if((addr->uint16[0] == 0) && (addr->uint16[1] == 0) && if((addr->uint16[0] == 0) && (addr->uint16[1] == 0) &&
(addr->uint16[2] == 0) && (addr->uint16[3] == 0) && (addr->uint16[2] == 0) && (addr->uint16[3] == 0) &&
(addr->uint16[4] == 0) && (addr->uint16[5] == 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 1;
} }
return 0; 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*/ /* note: cool if-condition*/
if((addr->uint8[0] == 0xFF) && (addr->uint8[1] == 0x02) && if((addr->uint8[0] == 0xFF) && (addr->uint8[1] == 0x02) &&
(addr->uint16[1] == 0x00) && (addr->uint16[2] == 0x00) && (addr->uint16[1] == 0x00) && (addr->uint16[2] == 0x00) &&
(addr->uint16[3] == 0x00) && (addr->uint16[4] == 0x00) && (addr->uint16[3] == 0x00) && (addr->uint16[4] == 0x00) &&
(addr->uint8[10] == 0x00) && (addr->uint8[11] == 0x01) && (addr->uint8[10] == 0x00) && (addr->uint8[11] == 0x01) &&
(addr->uint8[12] == 0xFF)){ (addr->uint8[12] == 0xFF)) {
return 1; return 1;
} }
return 0; 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 */ /* copy only the last 24-bit of the ip-address that is beeing resolved */
addr_out->uint16[0] = HTONS(0xff02); addr_out->uint16[0] = HTONS(0xff02);
addr_out->uint16[1] = 0; addr_out->uint16[1] = 0;
@ -435,7 +516,8 @@ 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]; 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", 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)[0], ((uint8_t *)ipaddr)[1], ((uint8_t *)ipaddr)[2],
((uint8_t *)ipaddr)[3], ((uint8_t *)ipaddr)[4], ((uint8_t *)ipaddr)[5], ((uint8_t *)ipaddr)[3], ((uint8_t *)ipaddr)[4], ((uint8_t *)ipaddr)[5],
@ -445,20 +527,23 @@ void ipv6_print_addr(ipv6_addr_t *ipaddr){
((uint8_t *)ipaddr)[15]); ((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 || return next_hdr == PROTO_NUM_ICMPV6 ||
next_hdr == PROTO_NUM_NONE; next_hdr == PROTO_NUM_NONE;
} }
uint32_t get_remaining_time(timex_t *t){ uint32_t get_remaining_time(timex_t *t)
{
timex_t now; timex_t now;
vtimer_now(&now); vtimer_now(&now);
return (timex_sub(*t, now).seconds); 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 tmp = {time, 0};
timex_t now; timex_t now;
@ -466,33 +551,39 @@ void set_remaining_time(timex_t *t, uint32_t time){
*t = timex_add(now, tmp); *t = timex_add(now, tmp);
} }
void ipv6_init_iface_as_router(void) { void ipv6_init_iface_as_router(void)
{
ipv6_addr_t addr; ipv6_addr_t addr;
ipv6_set_all_rtrs_mcast_addr(&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_addr_t addr;
ipv6_set_all_rtrs_mcast_addr(&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 1;
} }
return 0; return 0;
} }
void set_tcp_packet_handler_pid(int pid) { void set_tcp_packet_handler_pid(int pid)
{
tcp_packet_handler_pid = pid; tcp_packet_handler_pid = pid;
} }
void set_udp_packet_handler_pid(int pid) { void set_udp_packet_handler_pid(int pid)
{
udp_packet_handler_pid = pid; udp_packet_handler_pid = pid;
} }
void set_rpl_process_pid(int pid){ void set_rpl_process_pid(int pid)
{
rpl_process_pid = 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 */ /* 6LoWPAN IP header file */
#ifndef SIXLOWIP_H #ifndef SIXLOWIP_H
@ -72,19 +92,19 @@ extern uint8_t buffer[BUFFER_SIZE];
/* ipv6 extension header length */ /* ipv6 extension header length */
typedef union __attribute__ ((packed)) ipv6_addr_t{ typedef union __attribute__((packed)) {
uint8_t uint8[16]; uint8_t uint8[16];
uint16_t uint16[8]; uint16_t uint16[8];
uint32_t uint32[4]; uint32_t uint32[4];
} ipv6_addr_t; } ipv6_addr_t;
struct __attribute__ ((packed)) icmpv6_hdr_t{ struct __attribute__((packed)) icmpv6_hdr_t {
uint8_t type; uint8_t type;
uint8_t code; uint8_t code;
uint16_t checksum; uint16_t checksum;
}; };
typedef struct __attribute__ ((packed)) ipv6_hdr_t{ typedef struct __attribute__((packed)) {
uint8_t version_trafficclass; uint8_t version_trafficclass;
uint8_t trafficclass_flowlabel; uint8_t trafficclass_flowlabel;
uint16_t flowlabel; uint16_t flowlabel;
@ -96,17 +116,17 @@ typedef struct __attribute__ ((packed)) ipv6_hdr_t{
} ipv6_hdr_t; } ipv6_hdr_t;
/* link layer addressing */ /* link layer addressing */
typedef union __attribute__ ((packed)) ieee_802154_long_t { typedef union __attribute__((packed)) {
uint8_t uint8[8]; uint8_t uint8[8];
uint16_t uint16[4]; uint16_t uint16[4];
} ieee_802154_long_t; } ieee_802154_long_t;
typedef union __attribute__ ((packed)) ieee_802154_short_t { typedef union __attribute__((packed)) {
uint8_t uint8[2]; uint8_t uint8[2];
uint16_t uint16[1]; uint16_t uint16[1];
} ieee_802154_short_t; } ieee_802154_short_t;
typedef struct __attribute__ ((packed)) addr_list_t { typedef struct __attribute__((packed)) {
uint8_t state; uint8_t state;
timex_t val_ltime; timex_t val_ltime;
timex_t pref_ltime; timex_t pref_ltime;
@ -114,7 +134,7 @@ typedef struct __attribute__ ((packed)) addr_list_t {
ipv6_addr_t addr; ipv6_addr_t addr;
} addr_list_t; } addr_list_t;
typedef struct __attribute__ ((packed)) iface_t { typedef struct __attribute__((packed)) {
ieee_802154_short_t saddr; ieee_802154_short_t saddr;
ieee_802154_long_t laddr; ieee_802154_long_t laddr;
addr_list_t addr_list[IFACE_ADDR_LIST_LEN]; addr_list_t addr_list[IFACE_ADDR_LIST_LEN];
@ -126,10 +146,10 @@ typedef struct __attribute__ ((packed)) iface_t {
extern iface_t iface; extern iface_t iface;
/* function prototypes */ /* function prototypes */
struct icmpv6_hdr_t* get_icmpv6_buf(uint8_t ext_len); struct icmpv6_hdr_t *get_icmpv6_buf(uint8_t ext_len);
struct ipv6_hdr_t* get_ipv6_buf(void); struct ipv6_hdr_t *get_ipv6_buf(void);
uint8_t * get_payload_buf(uint8_t ext_len); uint8_t *get_payload_buf(uint8_t ext_len);
uint8_t * get_payload_buf_send(uint8_t ext_len); uint8_t *get_payload_buf_send(uint8_t ext_len);
int icmpv6_demultiplex(const struct icmpv6_hdr_t *hdr); int icmpv6_demultiplex(const struct icmpv6_hdr_t *hdr);
void ipv6_init_iface_as_router(void); 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_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_mcast_match(ipv6_addr_t *addr);
uint8_t ipv6_prefix_ll_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); 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_prefix_eq(ipv6_addr_t *addr);
addr_list_t * ipv6_iface_addr_match(ipv6_addr_t *addr); addr_list_t *ipv6_iface_addr_match(ipv6_addr_t *addr);
void ipv6_iface_print_addrs(void); void ipv6_iface_print_addrs(void);
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);
void ipv6_init_address(ipv6_addr_t *addr, uint16_t addr0, uint16_t addr1, 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 <stdlib.h>
#include <string.h> #include <string.h>
@ -24,7 +43,6 @@ static uint8_t r_src_addr;
uint8_t buf[PAYLOAD_SIZE]; uint8_t buf[PAYLOAD_SIZE];
uint16_t packet_length; uint16_t packet_length;
static uint8_t macdsn; static uint8_t macdsn;
//static uint8_t macbsn;
mutex_t buf_mutex; mutex_t buf_mutex;
@ -34,55 +52,62 @@ int transceiver_type;
static transceiver_command_t tcmd; static transceiver_command_t tcmd;
uint16_t fragmentcounter = 0; uint16_t fragmentcounter = 0;
uint8_t get_radio_address(void){ uint8_t get_radio_address(void)
{
int16_t address; int16_t address;
tcmd.transceivers = transceiver_type; tcmd.transceivers = transceiver_type;
tcmd.data = &address; tcmd.data = &address;
mesg.content.ptr = (char*)&tcmd; mesg.content.ptr = (char *)&tcmd;
mesg.type = GET_ADDRESS; mesg.type = GET_ADDRESS;
msg_send_receive(&mesg,&mesg,transceiver_pid); msg_send_receive(&mesg, &mesg, transceiver_pid);
return (uint8_t)address; return (uint8_t)address;
} }
void set_radio_address(uint8_t addr){ void set_radio_address(uint8_t addr)
{
int16_t address = (int16_t)addr; int16_t address = (int16_t)addr;
tcmd.transceivers = transceiver_type; tcmd.transceivers = transceiver_type;
tcmd.data = &address; tcmd.data = &address;
mesg.content.ptr = (char*)&tcmd; mesg.content.ptr = (char *)&tcmd;
mesg.type = SET_ADDRESS; mesg.type = SET_ADDRESS;
msg_send_receive(&mesg, &mesg, transceiver_pid); 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; int16_t chan = (int16_t)channel;
tcmd.transceivers = transceiver_type; tcmd.transceivers = transceiver_type;
tcmd.data = &chan; tcmd.data = &chan;
mesg.content.ptr = (char*)&tcmd; mesg.content.ptr = (char *)&tcmd;
mesg.type = SET_CHANNEL; 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.type = SWITCH_RX;
mesg.content.ptr = (char*) &tcmd; mesg.content.ptr = (char *) &tcmd;
tcmd.transceivers = TRANSCEIVER_CC1100; tcmd.transceivers = TRANSCEIVER_CC1100;
msg_send(&mesg, transceiver_pid, 1); 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[0] = 0;
saddr->uint8[1] = get_radio_address(); saddr->uint8[1] = get_radio_address();
} }
ieee_802154_long_t* mac_get_eui(ipv6_addr_t *ipaddr){ ieee_802154_long_t *mac_get_eui(ipv6_addr_t *ipaddr)
return ((ieee_802154_long_t *) &(ipaddr->uint8[8])); {
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 // 16bit Pan-ID:16-zero-bits:16-bit-short-addr = 48bit
laddr->uint16[0] = IEEE_802154_PAN_ID; laddr->uint16[0] = IEEE_802154_PAN_ID;
@ -96,7 +121,8 @@ void init_802154_long_addr(ieee_802154_long_t *laddr){
laddr->uint8[7] = get_radio_address(); laddr->uint8[7] = get_radio_address();
} }
void recv_ieee802154_frame(void){ void recv_ieee802154_frame(void)
{
msg_t m; msg_t m;
radio_packet_t *p; radio_packet_t *p;
uint8_t hdrlen, length; uint8_t hdrlen, length;
@ -104,22 +130,23 @@ void recv_ieee802154_frame(void){
msg_init_queue(msg_q, RADIO_RCV_BUF_SIZE); msg_init_queue(msg_q, RADIO_RCV_BUF_SIZE);
while (1) { while(1) {
msg_receive(&m); 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); hdrlen = read_802154_frame(p->data, &frame, p->length);
length = p->length - hdrlen; length = p->length - hdrlen;
/* deliver packet to network(6lowpan)-layer */ /* deliver packet to network(6lowpan)-layer */
fragmentcounter++; fragmentcounter++;
lowpan_read(frame.payload, length, (ieee_802154_long_t*)&frame.src_addr, lowpan_read(frame.payload, length, (ieee_802154_long_t *)&frame.src_addr,
(ieee_802154_long_t*)&frame.dest_addr); (ieee_802154_long_t *)&frame.dest_addr);
p->processing--; p->processing--;
} }
else if (m.type == ENOBUFFER) { else if(m.type == ENOBUFFER) {
puts("Transceiver buffer full"); puts("Transceiver buffer full");
} }
else { else {
@ -129,7 +156,8 @@ void recv_ieee802154_frame(void){
} }
void set_ieee802154_fcf_values(ieee802154_frame_t *frame, uint8_t dest_mode, 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.frame_type = IEEE_802154_DATA_FRAME;
frame->fcf.sec_enb = 0; frame->fcf.sec_enb = 0;
frame->fcf.frame_pend = 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; 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 // TODO: addresse aus ip paket auslesen und in frame einfuegen
frame->dest_pan_id = IEEE_802154_PAN_ID; frame->dest_pan_id = IEEE_802154_PAN_ID;
frame->src_pan_id = IEEE_802154_PAN_ID; frame->src_pan_id = IEEE_802154_PAN_ID;
@ -149,13 +178,14 @@ void set_ieee802154_frame_values(ieee802154_frame_t *frame){
} }
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){ uint8_t length, uint8_t mcast)
{
uint16_t daddr; uint16_t daddr;
/* TODO: check if dedicated response struct is necessary */ /* TODO: check if dedicated response struct is necessary */
msg_t transceiver_rsp; msg_t transceiver_rsp;
r_src_addr = local_address; r_src_addr = local_address;
mesg.type = SND_PKT; mesg.type = SND_PKT;
mesg.content.ptr = (char*) &tcmd; mesg.content.ptr = (char *) &tcmd;
tcmd.transceivers = transceiver_type; tcmd.transceivers = transceiver_type;
tcmd.data = &p; tcmd.data = &p;
@ -175,17 +205,19 @@ void send_ieee802154_frame(ieee_802154_long_t *addr, uint8_t *payload,
frame.payload_len = length; frame.payload_len = length;
uint8_t hdrlen = get_802154_hdr_len(&frame); uint8_t hdrlen = get_802154_hdr_len(&frame);
memset(&buf,0,PAYLOAD_SIZE); memset(&buf, 0, PAYLOAD_SIZE);
init_802154_frame(&frame,(uint8_t*)&buf); init_802154_frame(&frame, (uint8_t *)&buf);
memcpy(&buf[hdrlen],frame.payload,frame.payload_len); memcpy(&buf[hdrlen], frame.payload, frame.payload_len);
/* mutex unlock */ /* mutex unlock */
mutex_unlock(&buf_mutex, 0); mutex_unlock(&buf_mutex, 0);
p.length = hdrlen + frame.payload_len; p.length = hdrlen + frame.payload_len;
if(mcast == 0){
if(mcast == 0) {
p.dst = daddr; p.dst = daddr;
} else { }
else {
p.dst = 0; p.dst = 0;
} }
@ -196,10 +228,10 @@ void send_ieee802154_frame(ieee_802154_long_t *addr, uint8_t *payload,
hwtimer_wait(5000); hwtimer_wait(5000);
} }
void sixlowmac_init(transceiver_type_t type){ void sixlowmac_init(transceiver_type_t type)
{
int recv_pid = thread_create(radio_stack_buffer, RADIO_STACK_SIZE, int recv_pid = thread_create(radio_stack_buffer, RADIO_STACK_SIZE,
PRIORITY_MAIN-2, CREATE_STACKTEST, recv_ieee802154_frame , "radio"); PRIORITY_MAIN - 2, CREATE_STACKTEST, recv_ieee802154_frame , "radio");
// hwtimer_init();
transceiver_type = type; transceiver_type = type;
transceiver_init(transceiver_type); transceiver_init(transceiver_type);
transceiver_start(); transceiver_start();

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 #ifndef SIXLOWMAC_H
#define SIXLOWMAC_H #define SIXLOWMAC_H
@ -23,6 +41,6 @@ void send_ieee802154_frame(ieee_802154_long_t *addr, uint8_t *payload,
void init_802154_long_addr(ieee_802154_long_t *laddr); void init_802154_long_addr(ieee_802154_long_t *laddr);
void init_802154_short_addr(ieee_802154_short_t *saddr); void init_802154_short_addr(ieee_802154_short_t *saddr);
void sixlowmac_init(transceiver_type_t type); 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*/ #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 #ifndef SIXLOWND_H
#define SIXLOWND_H #define SIXLOWND_H
@ -37,7 +54,7 @@
#define ICMP_RTR_SOL 133 #define ICMP_RTR_SOL 133
#define ICMP_NBR_ADV 136 #define ICMP_NBR_ADV 136
#define ICMP_NBR_SOL 135 #define ICMP_NBR_SOL 135
#define ICMP_REDIRECT 137 // will be filtered out by the border router #define ICMP_REDIRECT 137 /* will be filtered out by the border router */
/* stllao option rfc4861 4.6.1 */ /* stllao option rfc4861 4.6.1 */
#define OPT_STLLAO_MIN_LEN 8 #define OPT_STLLAO_MIN_LEN 8
#define OPT_STLLAO_MAX_LEN 16 #define OPT_STLLAO_MAX_LEN 16
@ -56,10 +73,10 @@
#define OPT_MTU_LEN 1 #define OPT_MTU_LEN 1
#define OPT_MTU_HDR_LEN 8 #define OPT_MTU_HDR_LEN 8
/* aro - address registration option draft-ietf-6lowpan-nd-14 4.2 */ /* 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_LEN 2
#define OPT_ARO_HDR_LEN 16 #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_SUCCESS 0
#define OPT_ARO_STATE_DUP_ADDR 1 #define OPT_ARO_STATE_DUP_ADDR 1
#define OPT_ARO_STATE_NBR_CACHE_FULL 2 #define OPT_ARO_STATE_NBR_CACHE_FULL 2
@ -68,7 +85,7 @@
#define OPT_6CO_MIN_LEN 2 #define OPT_6CO_MIN_LEN 2
#define OPT_6CO_MAX_LEN 3 #define OPT_6CO_MAX_LEN 3
#define OPT_6CO_HDR_LEN 8 #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_C 0x10
#define OPT_6CO_FLAG_CID 0x0F #define OPT_6CO_FLAG_CID 0x0F
#define OPT_6CO_FLAG_C_VALUE_SET 1 #define OPT_6CO_FLAG_C_VALUE_SET 1
@ -92,7 +109,7 @@
#define NBR_STATUS_DELAY 3 #define NBR_STATUS_DELAY 3
#define NBR_STATUS_PROBE 4 #define NBR_STATUS_PROBE 4
/* default router list size */ /* 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; extern unsigned int nd_nbr_cache_rem_pid;
@ -108,24 +125,24 @@ enum option_types_t {
OPT_DAC, OPT_DAC,
}; };
typedef struct __attribute__ ((packed)) opt_buf_t { typedef struct __attribute__((packed)) {
uint8_t type; uint8_t type;
uint8_t length; uint8_t length;
} opt_buf_t; } opt_buf_t;
typedef struct __attribute__ ((packed)) opt_stllao_t { typedef struct __attribute__((packed)) {
uint8_t type; uint8_t type;
uint8_t length; uint8_t length;
} opt_stllao_t; } opt_stllao_t;
typedef struct __attribute__ ((packed)) opt_mtu_t { typedef struct __attribute__((packed)) {
uint8_t type; uint8_t type;
uint8_t length; uint8_t length;
uint16_t reserved; uint16_t reserved;
uint32_t mtu; uint32_t mtu;
} opt_mtu_t; } opt_mtu_t;
typedef struct __attribute__ ((packed)) opt_pi_t { typedef struct __attribute__((packed)) {
uint8_t type; uint8_t type;
uint8_t length; uint8_t length;
uint8_t prefix_length; uint8_t prefix_length;
@ -136,7 +153,7 @@ typedef struct __attribute__ ((packed)) opt_pi_t {
ipv6_addr_t addr; ipv6_addr_t addr;
} opt_pi_t; } opt_pi_t;
typedef struct __attribute__ ((packed)) opt_aro_t { typedef struct __attribute__((packed)) {
uint8_t type; uint8_t type;
uint8_t length; uint8_t length;
uint8_t status; uint8_t status;
@ -146,7 +163,7 @@ typedef struct __attribute__ ((packed)) opt_aro_t {
ieee_802154_long_t eui64; ieee_802154_long_t eui64;
} opt_aro_t; } opt_aro_t;
typedef struct __attribute__ ((packed)) opt_6co_hdr_t { typedef struct __attribute__((packed)) {
uint8_t type; uint8_t type;
uint8_t length; uint8_t length;
uint8_t c_length; uint8_t c_length;
@ -155,7 +172,7 @@ typedef struct __attribute__ ((packed)) opt_6co_hdr_t {
uint16_t val_ltime; uint16_t val_ltime;
} opt_6co_hdr_t; } opt_6co_hdr_t;
typedef struct __attribute__ ((packed)) opt_abro_t { typedef struct __attribute__((packed)) {
uint8_t type; uint8_t type;
uint8_t length; uint8_t length;
uint16_t version; uint16_t version;
@ -163,7 +180,7 @@ typedef struct __attribute__ ((packed)) opt_abro_t {
ipv6_addr_t addr; ipv6_addr_t addr;
} opt_abro_t; } opt_abro_t;
typedef struct __attribute__ ((packed)) plist_t { typedef struct __attribute__((packed)) {
uint8_t inuse; uint8_t inuse;
uint8_t adv; uint8_t adv;
ipv6_addr_t addr; ipv6_addr_t addr;
@ -174,7 +191,7 @@ typedef struct __attribute__ ((packed)) plist_t {
uint8_t infinite; uint8_t infinite;
} plist_t; } plist_t;
struct __attribute__ ((packed)) rtr_adv_t { struct __attribute__((packed)) rtr_adv_t {
uint8_t hoplimit; uint8_t hoplimit;
uint8_t autoconfig_flags; uint8_t autoconfig_flags;
uint16_t router_lifetime; uint16_t router_lifetime;
@ -182,18 +199,18 @@ struct __attribute__ ((packed)) rtr_adv_t {
uint32_t retrans_timer; uint32_t retrans_timer;
}; };
struct __attribute__ ((packed)) nbr_sol_t { struct __attribute__((packed)) nbr_sol_t {
uint32_t reserved; 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 rso;
uint8_t reserved[3]; 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; uint8_t pointer;
}; };
@ -205,7 +222,7 @@ typedef struct __attribute__((packed)) abr_cache_t {
} abr_cache_t; } abr_cache_t;
/* neighbor cache - rfc4861 5.1. */ /* neighbor cache - rfc4861 5.1. */
typedef struct __attribute__ ((packed)) nbr_cache_t { typedef struct __attribute__((packed)) {
uint8_t type; uint8_t type;
uint8_t state; uint8_t state;
uint8_t isrouter; uint8_t isrouter;
@ -216,7 +233,7 @@ typedef struct __attribute__ ((packed)) nbr_cache_t {
} nbr_cache_t; } nbr_cache_t;
/* default router list - rfc4861 5.1. */ /* default router list - rfc4861 5.1. */
typedef struct __attribute__ ((packed)) def_rtr_lst_t { typedef struct __attribute__((packed)) {
ipv6_addr_t addr; ipv6_addr_t addr;
timex_t inval_time; timex_t inval_time;
} def_rtr_lst_t; } def_rtr_lst_t;
@ -233,21 +250,22 @@ int8_t plist_add(ipv6_addr_t *addr, uint8_t size, uint32_t val_ltime,
void set_llao(opt_stllao_t *sllao, uint8_t type, uint8_t length); void set_llao(opt_stllao_t *sllao, uint8_t type, uint8_t length);
abr_cache_t *abr_get_version(uint16_t version, ipv6_addr_t *abr_addr); abr_cache_t *abr_get_version(uint16_t version, ipv6_addr_t *abr_addr);
abr_cache_t *abr_add_context( 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); uint8_t cid);
void abr_remove_context(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 nbr_cache_add(ipv6_addr_t *ipaddr, ieee_802154_long_t *laddr,
uint8_t isrouter, uint8_t state, uint8_t type, uint8_t isrouter, uint8_t state, uint8_t type,
uint16_t ltime, ieee_802154_short_t *saddr); uint16_t ltime, ieee_802154_short_t *saddr);
void nbr_cache_auto_rem(void); void nbr_cache_auto_rem(void);
void nbr_cache_rem(ipv6_addr_t *addr); void nbr_cache_rem(ipv6_addr_t *addr);
uint16_t icmpv6_csum(uint8_t proto); 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_add(ipv6_addr_t *ipaddr, uint32_t rtr_ltime);
void def_rtr_lst_rem(def_rtr_lst_t *entry); 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, void init_nbr_sol(ipv6_addr_t *src, ipv6_addr_t *dest, ipv6_addr_t *targ,
uint8_t slloa, uint8_t aro); 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,

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,23 @@
/*
* 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 #ifndef SIXLOWPAN_H
#define SIXLOWPAN_H #define SIXLOWPAN_H
@ -23,7 +43,7 @@
#define LOWPAN_IPV6_DISPATCH 0x41 #define LOWPAN_IPV6_DISPATCH 0x41
#define LOWPAN_CONTEXT_MAX 16 #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 "transceiver.h"
#include "sixlowip.h" #include "sixlowip.h"
@ -50,37 +70,47 @@ typedef struct lowpan_interval_list_t {
} lowpan_interval_list_t; } lowpan_interval_list_t;
typedef struct lowpan_reas_buf_t { typedef struct lowpan_reas_buf_t {
ieee_802154_long_t s_laddr; // Source Address /* Source Address */
ieee_802154_long_t d_laddr; // Destination Address ieee_802154_long_t s_laddr;
uint16_t ident_no; // Identification Number /* Destination Address */
long timestamp; // Timestamp of last packet fragment ieee_802154_long_t d_laddr;
uint16_t packet_size; // Size of reassembled packet with possible IPHC header /* Identification Number */
uint16_t current_packet_size; // Additive size of currently already received fragments uint16_t ident_no;
uint8_t *packet; // Pointer to allocated memory for reassembled packet + 6LoWPAN Dispatch Byte /* Timestamp of last packet fragment */
lowpan_interval_list_t *interval_list_head; // Pointer to list of intervals of received packet fragments (if any) long timestamp;
struct lowpan_reas_buf_t *next; // Pointer to next reassembly buffer (if any) /* 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; } lowpan_reas_buf_t;
extern lowpan_reas_buf_t *head; extern lowpan_reas_buf_t *head;
void sixlowpan_init(transceiver_type_t trans, uint8_t r_addr, int as_border); void sixlowpan_init(transceiver_type_t trans, uint8_t r_addr, int as_border);
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_init(ieee_802154_long_t *addr, uint8_t *data);
void lowpan_read(uint8_t *data, uint8_t length, ieee_802154_long_t *s_laddr, void lowpan_read(uint8_t *data, uint8_t length, ieee_802154_long_t *s_laddr,
ieee_802154_long_t *d_laddr); ieee_802154_long_t *d_laddr);
void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra, uint8_t * ptr); 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, void lowpan_iphc_decoding(uint8_t *data, uint8_t length,
ieee_802154_long_t *s_laddr, ieee_802154_long_t *s_laddr,
ieee_802154_long_t *d_laddr); ieee_802154_long_t *d_laddr);
uint8_t lowpan_context_len(void); uint8_t lowpan_context_len(void);
void add_fifo_packet(lowpan_reas_buf_t *current_packet); void add_fifo_packet(lowpan_reas_buf_t *current_packet);
lowpan_context_t * lowpan_context_update( lowpan_context_t *lowpan_context_update(
uint8_t num, const ipv6_addr_t *prefix, uint8_t num, const ipv6_addr_t *prefix,
uint8_t length, uint8_t comp, uint8_t length, uint8_t comp,
uint16_t lifetime); uint16_t lifetime);
lowpan_context_t * lowpan_context_get(void); lowpan_context_t *lowpan_context_get(void);
lowpan_context_t * lowpan_context_lookup(ipv6_addr_t *addr); 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_num_lookup(uint8_t num);
lowpan_reas_buf_t *collect_garbage_fifo(lowpan_reas_buf_t *current_buf); 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); lowpan_reas_buf_t *collect_garbage(lowpan_reas_buf_t *current_buf);
void check_timeout(void); void check_timeout(void);

View File

@ -21,7 +21,8 @@
#include <posix_io.h> #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; msg_t m;
m.type = op; m.type = op;
m.content.value = flags; m.content.value = flags;
@ -29,32 +30,37 @@ static int _posix_fileop(int pid, int op, int flags) {
return m.content.value; 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; struct posix_iop_t r;
r.nbytes = nbytes; r.nbytes = nbytes;
r.buffer = buffer; r.buffer = buffer;
msg_t m; msg_t m;
m.type = op; m.type = op;
m.content.ptr = (char*) &r; m.content.ptr = (char *) &r;
msg_send_receive(&m, &m, pid); msg_send_receive(&m, &m, pid);
return r.nbytes; return r.nbytes;
} }
int posix_open(int pid, int flags) { int posix_open(int pid, int flags)
{
return _posix_fileop(pid, OPEN, flags); return _posix_fileop(pid, OPEN, flags);
} }
int posix_close(int pid) { int posix_close(int pid)
{
return _posix_fileop(pid, CLOSE, 0); 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); 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); return _posix_fileop_data(pid, WRITE, buffer, bufsize);
} }

View File

@ -36,23 +36,25 @@ const char *state_names[] = {
/** /**
* @brief Prints a list of running threads including stack usage to stdout. * @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); extern unsigned long hwtimer_now(void);
const char queued_name[] = {'_', 'Q'}; const char queued_name[] = {'_', 'Q'};
int i; int i;
int overall_stacksz = 0; int overall_stacksz = 0;
printf("\tpid | %-21s| %-9sQ | pri | stack ( used) location | runtime | switches \n", "name", "state"); 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 state = p->status; // copy state
int statebit = number_of_highest_bit(state >> 1); // get state index int statebit = number_of_highest_bit(state >> 1); // get state index
const char* sname = state_names[statebit]; // get state name const char *sname = state_names[statebit]; // get state name
const char* queued = queued_name + (state & BIT0); // get queued flag const char *queued = queued_name + (state & BIT0); // get queued flag
int stacksz = p->stack_size; // get max used stack int stacksz = p->stack_size; // get max used stack
double runtime = 0/0.0; double runtime = 0 / 0.0;
int switches = -1; int switches = -1;
#if SCHEDSTATISTICS #if SCHEDSTATISTICS
runtime = pidlist[i].runtime / (double) hwtimer_now() * 100; runtime = pidlist[i].runtime / (double) hwtimer_now() * 100;
@ -64,5 +66,6 @@ void thread_print_all(void) {
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); 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 <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
@ -14,43 +31,50 @@ char text_msg[TEXT_SIZE];
msg_t mesg; msg_t mesg;
transceiver_command_t tcmd; transceiver_command_t tcmd;
void _cc1100_get_set_address_handler(char *addr) { void _cc1100_get_set_address_handler(char *addr)
{
int16_t a; int16_t a;
tcmd.transceivers = TRANSCEIVER_CC1100; tcmd.transceivers = TRANSCEIVER_CC1100;
tcmd.data = &a; tcmd.data = &a;
mesg.content.ptr = (char*) &tcmd; mesg.content.ptr = (char *) &tcmd;
a = atoi(addr+5); a = atoi(addr + 5);
if (strlen(addr) > 5) {
if(strlen(addr) > 5) {
printf("[cc110x] Trying to set address %i\n", a); printf("[cc110x] Trying to set address %i\n", a);
mesg.type = SET_ADDRESS; mesg.type = SET_ADDRESS;
} }
else { else {
mesg.type = GET_ADDRESS; mesg.type = GET_ADDRESS;
} }
msg_send_receive(&mesg, &mesg, transceiver_pid); msg_send_receive(&mesg, &mesg, transceiver_pid);
printf("[cc110x] Got address: %i\n", a); 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; int16_t c;
tcmd.transceivers = TRANSCEIVER_CC1100; tcmd.transceivers = TRANSCEIVER_CC1100;
tcmd.data = &c; tcmd.data = &c;
mesg.content.ptr = (char*) &tcmd; mesg.content.ptr = (char *) &tcmd;
c = atoi(chan+5); c = atoi(chan + 5);
if (strlen(chan) > 5) {
if(strlen(chan) > 5) {
printf("[cc110x] Trying to set channel %i\n", c); printf("[cc110x] Trying to set channel %i\n", c);
mesg.type = SET_CHANNEL; mesg.type = SET_CHANNEL;
} }
else { else {
mesg.type = GET_CHANNEL; mesg.type = GET_CHANNEL;
} }
msg_send_receive(&mesg, &mesg, transceiver_pid); msg_send_receive(&mesg, &mesg, transceiver_pid);
printf("[cc110x] Got channel: %i\n", c); printf("[cc110x] Got channel: %i\n", c);
} }
void _cc1100_send_handler(char *pkt) { void _cc1100_send_handler(char *pkt)
{
radio_packet_t p; radio_packet_t p;
uint32_t response; uint32_t response;
uint16_t addr; uint16_t addr;
@ -59,40 +83,47 @@ void _cc1100_send_handler(char *pkt) {
tcmd.transceivers = TRANSCEIVER_CC1100; tcmd.transceivers = TRANSCEIVER_CC1100;
tcmd.data = &p; tcmd.data = &p;
tok = strtok(pkt+7, " "); tok = strtok(pkt + 7, " ");
if (tok) {
if(tok) {
addr = atoi(tok); addr = atoi(tok);
tok = strtok(NULL, " "); tok = strtok(NULL, " ");
if (tok) {
if(tok) {
memset(text_msg, 0, TEXT_SIZE); memset(text_msg, 0, TEXT_SIZE);
memcpy(text_msg, tok, strlen(tok)); memcpy(text_msg, tok, strlen(tok));
/* if (sscanf(pkt, "txtsnd %hu %s", &(addr), text_msg) == 2) {*/ /* 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.length = strlen(text_msg) + 1;
p.dst = addr; p.dst = addr;
mesg.type = SND_PKT; mesg.type = SND_PKT;
mesg.content.ptr = (char*) &tcmd; mesg.content.ptr = (char *) &tcmd;
printf("[cc110x] Sending packet of length %u to %hu: %s\n", p.length, p.dst, (char*) p.data); 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); msg_send_receive(&mesg, &mesg, transceiver_pid);
response = mesg.content.value; response = mesg.content.value;
printf("[cc110x] Packet sent: %lu\n", response); printf("[cc110x] Packet sent: %lu\n", response);
return; return;
} }
} }
puts("Usage:\ttxtsnd <ADDR> <MSG>"); puts("Usage:\ttxtsnd <ADDR> <MSG>");
} }
#else #else
void _cc110x_get_set_address_handler(char *addr) { void _cc110x_get_set_address_handler(char *addr)
{
int16_t a; int16_t a;
a = atoi(addr+5); a = atoi(addr + 5);
if (strlen(addr) > 5) {
if(strlen(addr) > 5) {
printf("[cc110x] Setting address %i ... ", a); printf("[cc110x] Setting address %i ... ", a);
cc1100_set_address((radio_address_t)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]"); puts("[OK]");
} else { }
else {
puts("Error!"); 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; int16_t a;
a = atoi(addr+5); a = atoi(addr + 5);
if (strlen(addr) > 5) {
if(strlen(addr) > 5) {
printf("[cc110x] Setting channel %i...", a); printf("[cc110x] Setting channel %i...", a);
cc1100_set_channel(a); cc1100_set_channel(a);
if (cc1100_get_channel() == a) {
if(cc1100_get_channel() == a) {
puts("OK"); puts("OK");
} else { }
else {
puts("Error!"); 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 <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -12,43 +29,50 @@ char text_msg[TEXT_SIZE];
msg_t mesg; msg_t mesg;
transceiver_command_t tcmd; 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; int16_t a;
tcmd.transceivers = TRANSCEIVER_CC1100; tcmd.transceivers = TRANSCEIVER_CC1100;
tcmd.data = &a; tcmd.data = &a;
mesg.content.ptr = (char*) &tcmd; mesg.content.ptr = (char *) &tcmd;
a = atoi(addr+5); a = atoi(addr + 5);
if (strlen(addr) > 5) {
if(strlen(addr) > 5) {
printf("[cc110x] Trying to set address %i\n", a); printf("[cc110x] Trying to set address %i\n", a);
mesg.type = SET_ADDRESS; mesg.type = SET_ADDRESS;
} }
else { else {
mesg.type = GET_ADDRESS; mesg.type = GET_ADDRESS;
} }
msg_send_receive(&mesg, &mesg, transceiver_pid); msg_send_receive(&mesg, &mesg, transceiver_pid);
printf("[cc110x] Got address: %i\n", a); 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; int16_t c;
tcmd.transceivers = TRANSCEIVER_CC1100; tcmd.transceivers = TRANSCEIVER_CC1100;
tcmd.data = &c; tcmd.data = &c;
mesg.content.ptr = (char*) &tcmd; mesg.content.ptr = (char *) &tcmd;
c = atoi(chan+5); c = atoi(chan + 5);
if (strlen(chan) > 5) {
if(strlen(chan) > 5) {
printf("[cc110x] Trying to set channel %i\n", c); printf("[cc110x] Trying to set channel %i\n", c);
mesg.type = SET_CHANNEL; mesg.type = SET_CHANNEL;
} }
else { else {
mesg.type = GET_CHANNEL; mesg.type = GET_CHANNEL;
} }
msg_send_receive(&mesg, &mesg, transceiver_pid); msg_send_receive(&mesg, &mesg, transceiver_pid);
printf("[cc110x] Got channel: %i\n", c); 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; radio_packet_t p;
uint32_t response; uint32_t response;
uint16_t addr; uint16_t addr;
@ -57,37 +81,41 @@ void _cc110x_ng_send_handler(char *pkt) {
tcmd.transceivers = TRANSCEIVER_CC1100; tcmd.transceivers = TRANSCEIVER_CC1100;
tcmd.data = &p; tcmd.data = &p;
tok = strtok(pkt+7, " "); tok = strtok(pkt + 7, " ");
if (tok) {
if(tok) {
addr = atoi(tok); addr = atoi(tok);
tok = strtok(NULL, " "); tok = strtok(NULL, " ");
if (tok) {
if(tok) {
memset(text_msg, 0, TEXT_SIZE); memset(text_msg, 0, TEXT_SIZE);
memcpy(text_msg, tok, strlen(tok)); 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.length = strlen(text_msg) + 1;
p.dst = addr; p.dst = addr;
mesg.type = SND_PKT; mesg.type = SND_PKT;
mesg.content.ptr = (char*) &tcmd; mesg.content.ptr = (char *) &tcmd;
printf("[cc110x] Sending packet of length %u to %hu: %s\n", p.length, p.dst, (char*) p.data); 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); msg_send_receive(&mesg, &mesg, transceiver_pid);
response = mesg.content.value; response = mesg.content.value;
printf("[cc110x] Packet sent: %" PRIu32 "\n", response); printf("[cc110x] Packet sent: %" PRIu32 "\n", response);
return; return;
} }
} }
puts("Usage:\ttxtsnd <ADDR> <MSG>"); puts("Usage:\ttxtsnd <ADDR> <MSG>");
} }
void _cc110x_ng_monitor_handler(char *mode) { void _cc110x_ng_monitor_handler(char *mode)
{
unsigned int m; unsigned int m;
tcmd.transceivers = TRANSCEIVER_CC1100; tcmd.transceivers = TRANSCEIVER_CC1100;
tcmd.data = &m; tcmd.data = &m;
mesg.content.ptr = (char*) &tcmd; mesg.content.ptr = (char *) &tcmd;
m = atoi(mode+8); m = atoi(mode + 8);
if (strlen(mode) > 8) {
if(strlen(mode) > 8) {
printf("Setting monitor mode: %u\n", m); printf("Setting monitor mode: %u\n", m);
mesg.type = SET_MONITOR; mesg.type = SET_MONITOR;
msg_send(&mesg, transceiver_pid, 1); 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 <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
@ -5,25 +22,33 @@
#include "shell_commands.h" #include "shell_commands.h"
#include "diskio.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; 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); printf("[disk] Read sector %lu (%lu):\n", sector, offset);
for (i = offset + 1; i <= offset + length; i++) {
printf(" %u", read_buf[i-1]); for(i = offset + 1; i <= offset + length; i++) {
if (!(i % 16)) { printf(" %u", read_buf[i - 1]);
if(!(i % 16)) {
puts(""); puts("");
} }
} }
puts(""); puts("");
return 1; return 1;
} }
return 0; return 0;
} }
void _get_sectorsize(char *unused) { void _get_sectorsize(char *unused)
{
unsigned short ssize; 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); printf("[disk] sector size is %u\n", ssize);
} }
else { else {
@ -31,9 +56,11 @@ void _get_sectorsize(char *unused) {
} }
} }
void _get_blocksize(char *unused) { void _get_blocksize(char *unused)
{
unsigned long bsize; 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); printf("[disk] block size is %lu\n", bsize);
} }
else { else {
@ -41,9 +68,11 @@ void _get_blocksize(char *unused) {
} }
} }
void _get_sectorcount(char *unused) { void _get_sectorcount(char *unused)
{
unsigned long scount; 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); printf("[disk] sector count is %lu\n", scount);
} }
else { 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 long sectornr, scount;
unsigned short ssize; 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); 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]; unsigned char read_buf[ssize];
if (sector_read(read_buf, sectornr, ssize, 0)) {
if(sector_read(read_buf, sectornr, ssize, 0)) {
return; return;
} }
} }
printf("[disk] Error while reading sector %lu\n", sectornr); printf("[disk] Error while reading sector %lu\n", sectornr);
} }
else { 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 long sector = 1, scount, offset;
unsigned short ssize, length; unsigned short ssize, length;
char *tok; char *tok;
/* tokenize user input */ /* tokenize user input */
tok = strtok(bytes + strlen(DISK_READ_BYTES_CMD) + 1, " "); tok = strtok(bytes + strlen(DISK_READ_BYTES_CMD) + 1, " ");
if (tok) {
if(tok) {
offset = atol(tok); offset = atol(tok);
tok = strtok(NULL, " "); tok = strtok(NULL, " ");
if (tok) {
if(tok) {
length = atoi(tok); length = atoi(tok);
if (length) {
if(length) {
/* get card info */ /* 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 */ /* calculate sector and offset position */
sector = (offset / ssize) + 1; sector = (offset / ssize) + 1;
offset = (offset % ssize); offset = (offset % ssize);
/* preapre buffer (size must be a multiple of sector size) */ /* preapre buffer (size must be a multiple of sector size) */
unsigned char read_buf[((length / ssize) + 1) * 512]; unsigned char read_buf[((length / ssize) + 1) * 512];
/* read from several sectors */ /* read from several sectors */
if (length > (ssize - offset)) { if(length > (ssize - offset)) {
/* buffer offset */ /* buffer offset */
unsigned long j = 0; unsigned long j = 0;
/* chunk from current sector */ /* chunk from current sector */
unsigned short tmp = ssize - offset; unsigned short tmp = ssize - offset;
while (length) {
while(length) {
sector_read(read_buf + j, sector++, tmp, offset); sector_read(read_buf + j, sector++, tmp, offset);
/* decrease length and recalculate chunk */ /* decrease length and recalculate chunk */
length -= tmp; length -= tmp;
@ -109,15 +148,17 @@ void _read_bytes(char *bytes) {
} /* length > (ssize - offset) */ } /* length > (ssize - offset) */
/* read only one sector */ /* read only one sector */
else { else {
if (sector_read(read_buf, sector, length, offset)) { if(sector_read(read_buf, sector, length, offset)) {
return; return;
} }
} /* length < (ssize - offset) */ } /* length < (ssize - offset) */
} /* ioctl */ } /* ioctl */
printf("[disk] Error while reading sector %lu\n", sector); printf("[disk] Error while reading sector %lu\n", sector);
return; return;
} /* length */ } /* length */
} /* strtok #2 */ } /* strtok #2 */
} /* strtok #1 */ } /* strtok #1 */
printf("[disk] Usage:\n%s <OFFSET> <LENGTH>\n", DISK_READ_BYTES_CMD); 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 <stdio.h>
#include <string.h> #include <string.h>
#include <config.h> #include <config.h>
#include <stdlib.h> #include <stdlib.h>
void _id_handler(char *id) { void _id_handler(char *id)
{
long newid; long newid;
newid = atoi(id+3); newid = atoi(id + 3);
if (strlen(id) < 3) {
if(strlen(id) < 3) {
#ifdef MODULE_CONFIG #ifdef MODULE_CONFIG
printf("Current id: %u\n", sysconfig.id); printf("Current id: %u\n", sysconfig.id);
#endif #endif
@ -16,9 +35,11 @@ void _id_handler(char *id) {
printf("Setting new id %lu\n", newid); printf("Setting new id %lu\n", newid);
#ifdef MODULE_CONFIG #ifdef MODULE_CONFIG
sysconfig.id = newid; sysconfig.id = newid;
if (!config_save()) {
if(!config_save()) {
puts("ERROR setting new id"); puts("ERROR setting new id");
} }
#endif #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 <stdio.h>
#include <ltc4150.h> #include <ltc4150.h>
void _get_current_handler(char* unused) { 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()); 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) { void _reset_current_handler(char *unused)
{
ltc4150_start(); 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" #include "ps.h"
void _ps_handler(char* unnused) { void _ps_handler(char *unnused)
{
thread_print_all(); 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 <stdio.h>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
@ -5,14 +22,16 @@
#ifdef MODULE_RTC #ifdef MODULE_RTC
#include <rtc.h> #include <rtc.h>
void _gettime_handler(void) { void _gettime_handler(void)
{
struct tm now; struct tm now;
rtc_get_localtime(&now); rtc_get_localtime(&now);
printf("%s", asctime(&now)); printf("%s", asctime(&now));
} }
void _settime_handler(char* c) { void _settime_handler(char *c)
{
struct tm now; struct tm now;
int res; int res;
uint16_t month, epoch_year; uint16_t month, epoch_year;
@ -20,12 +39,12 @@ void _settime_handler(char* c) {
res = sscanf(c, "date %hu-%hu-%u %u:%u:%u", res = sscanf(c, "date %hu-%hu-%u %u:%u:%u",
&epoch_year, &epoch_year,
&month, &month,
(unsigned int*) &(now.tm_mday), (unsigned int *) & (now.tm_mday),
(unsigned int*) &(now.tm_hour), (unsigned int *) & (now.tm_hour),
(unsigned int*) &(now.tm_min), (unsigned int *) & (now.tm_min),
(unsigned int*) &(now.tm_sec)); (unsigned int *) & (now.tm_sec));
if (res < 6) { if(res < 6) {
printf("Usage: date YYYY-MM-DD hh:mm:ss\n"); printf("Usage: date YYYY-MM-DD hh:mm:ss\n");
return; return;
} }
@ -38,8 +57,9 @@ void _settime_handler(char* c) {
rtc_set_localtime(&now); rtc_set_localtime(&now);
} }
void _date_handler(char* c) { void _date_handler(char *c)
if (strlen(c) == 4) { {
if(strlen(c) == 4) {
_gettime_handler(); _gettime_handler();
} }
else { else {

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 <stdio.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
@ -8,11 +25,13 @@
extern float sht11_temperature_offset; extern float sht11_temperature_offset;
void _get_humidity_handler(char* unused) { void _get_humidity_handler(char *unused)
{
uint8_t success; uint8_t success;
sht11_val_t sht11_val; sht11_val_t sht11_val;
success = sht11_read_sensor(&sht11_val, HUMIDITY|TEMPERATURE); success = sht11_read_sensor(&sht11_val, HUMIDITY | TEMPERATURE);
if (!success) {
if(!success) {
printf("Error reading SHT11\n"); printf("Error reading SHT11\n");
} }
else { else {
@ -20,22 +39,26 @@ void _get_humidity_handler(char* unused) {
(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; uint8_t success;
sht11_val_t sht11_val; sht11_val_t sht11_val;
success = sht11_read_sensor(&sht11_val, TEMPERATURE); success = sht11_read_sensor(&sht11_val, TEMPERATURE);
if (!success) {
if(!success) {
printf("Error reading SHT11\n"); printf("Error reading SHT11\n");
} }
else { else {
printf("Temperature: %-6.2f°C\n", (double) sht11_val.temperature); 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; uint8_t success;
sht11_val_t sht11_val; sht11_val_t sht11_val;
success = sht11_read_sensor(&sht11_val, HUMIDITY|TEMPERATURE); success = sht11_read_sensor(&sht11_val, HUMIDITY | TEMPERATURE);
if (!success) {
if(!success) {
printf("Error reading SHT11\n"); printf("Error reading SHT11\n");
} }
else { else {
@ -45,12 +68,13 @@ void _get_weather_handler(char* unused) {
} }
} }
void _set_offset_handler(char* offset) { void _set_offset_handler(char *offset)
if (strlen(offset) == 6) { {
if(strlen(offset) == 6) {
puts("Usage: offset <OFFSET>"); puts("Usage: offset <OFFSET>");
} }
else { else {
sht11_temperature_offset = atoi(offset+7); sht11_temperature_offset = atoi(offset + 7);
printf("Temperature offset set to %f\n", (double) sht11_temperature_offset); printf("Temperature offset set to %f\n", (double) sht11_temperature_offset);
} }
} }

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 <shell_commands.h>
#include <stdlib.h> #include <stdlib.h>
extern void _id_handler(char* id); extern void _id_handler(char *id);
#ifdef MODULE_PS #ifdef MODULE_PS
extern void _ps_handler(char* unused); extern void _ps_handler(char *unused);
#endif #endif
#ifdef MODULE_RTC #ifdef MODULE_RTC
extern void _date_handler(char* now); extern void _date_handler(char *now);
#endif #endif
#ifdef MODULE_SHT11 #ifdef MODULE_SHT11
extern void _get_temperature_handler(char* unused); extern void _get_temperature_handler(char *unused);
extern void _get_humidity_handler(char* unused); extern void _get_humidity_handler(char *unused);
extern void _get_weather_handler(char* unused); extern void _get_weather_handler(char *unused);
extern void _set_offset_handler(char* offset); extern void _set_offset_handler(char *offset);
#endif #endif
#ifdef MODULE_LTC4150 #ifdef MODULE_LTC4150
extern void _get_current_handler(char* unused); extern void _get_current_handler(char *unused);
extern void _reset_current_handler(char* unused); extern void _reset_current_handler(char *unused);
#endif #endif
#ifdef MODULE_CC110X #ifdef MODULE_CC110X
@ -45,10 +62,10 @@ extern void _cc110x_ng_monitor_handler(char *mode);
#ifdef MODULE_MCI #ifdef MODULE_MCI
extern void _get_sectorsize(char *unused); extern void _get_sectorsize(char *unused);
extern void _get_blocksize(char* unused); extern void _get_blocksize(char *unused);
extern void _get_sectorcount(char* unused); extern void _get_sectorcount(char *unused);
extern void _read_sector(char* sector); extern void _read_sector(char *sector);
extern void _read_bytes(char* bytes); extern void _read_bytes(char *bytes);
#endif #endif
const shell_command_t _shell_command_list[] = { const shell_command_t _shell_command_list[] = {

View File

@ -1,28 +1,13 @@
/****************************************************************************** /**
Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved. * Shell interpreter
*
These sources were developed at the Freie Universitaet Berlin, Computer Systems * Copyright (C) 2009, Freie Universitaet Berlin (FUB).
and Telematics group (http://cst.mi.fu-berlin.de). * Copyright (C) 2013, INRIA.
------------------------------------------------------------------------------- *
This file is part of RIOT. * 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
This program is free software: you can redistribute it and/or modify it under * details.
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
*******************************************************************************/
/** /**
* @ingroup shell * @ingroup shell
@ -49,13 +34,16 @@ and the mailinglist (subscription via web site)
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
static void(*find_handler(const shell_command_t *command_list, char *command))(char*) { static void(*find_handler(const shell_command_t *command_list, char *command))(char *)
const shell_command_t* entry = command_list; {
if (entry) { const shell_command_t *entry = command_list;
while (entry->name != NULL) {
if ( strcmp(entry->name, command) == 0) { if(entry) {
while(entry->name != NULL) {
if(strcmp(entry->name, command) == 0) {
return entry->handler; return entry->handler;
} else { }
else {
entry++; entry++;
} }
} }
@ -63,25 +51,29 @@ static void(*find_handler(const shell_command_t *command_list, char *command))(c
#ifdef MODULE_SHELL_COMMANDS #ifdef MODULE_SHELL_COMMANDS
entry = _shell_command_list; 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; return entry->handler;
} else { }
else {
entry++; entry++;
} }
} }
#endif #endif
return NULL; 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; const shell_command_t *entry = command_list;
printf("%-20s %s\n", "Command", "Description"); printf("%-20s %s\n", "Command", "Description");
puts("---------------------------------------"); puts("---------------------------------------");
if (entry) { if(entry) {
while (entry->name != NULL) { while(entry->name != NULL) {
printf("%-20s %s\n", entry->name, entry->desc); printf("%-20s %s\n", entry->name, entry->desc);
entry++; entry++;
} }
@ -89,28 +81,34 @@ static void print_help(const shell_command_t *command_list) {
#ifdef MODULE_SHELL_COMMANDS #ifdef MODULE_SHELL_COMMANDS
entry = _shell_command_list; entry = _shell_command_list;
while (entry->name != NULL) {
while(entry->name != NULL) {
printf("%-20s %s\n", entry->name, entry->desc); printf("%-20s %s\n", entry->name, entry->desc);
entry++; entry++;
} }
#endif #endif
} }
static void handle_input_line(shell_t *shell, char* line) { static void handle_input_line(shell_t *shell, char *line)
char* saveptr; {
char* linedup = strdup(line); char *saveptr;
char* command = strtok_r(linedup, " ", &saveptr); char *linedup = strdup(line);
char *command = strtok_r(linedup, " ", &saveptr);
void (*handler)(char*) = NULL; void (*handler)(char *) = NULL;
if (command) { if(command) {
handler = find_handler(shell->command_list, command); handler = find_handler(shell->command_list, command);
if (handler != NULL) {
if(handler != NULL) {
handler(line); handler(line);
} else { }
if ( strcmp("help", command) == 0) { else {
if(strcmp("help", command) == 0) {
print_help(shell->command_list); print_help(shell->command_list);
} else { }
else {
puts("shell: command not found."); puts("shell: command not found.");
} }
} }
@ -119,21 +117,24 @@ static void handle_input_line(shell_t *shell, char* line) {
free(linedup); 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; char *line_buf_ptr = buf;
int c; int c;
while (1) { while(1) {
if ( (line_buf_ptr - buf) >= ((int) size)-1) { if((line_buf_ptr - buf) >= ((int) size) - 1) {
return -1; return -1;
} }
c = shell->readchar(); c = shell->readchar();
shell->put_char(c); shell->put_char(c);
if (c == 13) continue; if(c == 13) {
continue;
}
if (c == 10) { if(c == 10) {
*line_buf_ptr = '\0'; *line_buf_ptr = '\0';
return 0; return 0;
} }
@ -141,6 +142,7 @@ static int readline(shell_t *shell, char* buf, size_t size) {
*line_buf_ptr++ = c; *line_buf_ptr++ = c;
} }
} }
return 1; return 1;
} }
@ -151,22 +153,27 @@ static inline void print_prompt(shell_t *shell)
return; return;
} }
void shell_run(shell_t *shell) { void shell_run(shell_t *shell)
{
char line_buf[255]; char line_buf[255];
print_prompt(shell); print_prompt(shell);
while(1) { while(1) {
int res = readline(shell, line_buf, sizeof(line_buf)); 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); handle_input_line(shell, line_copy);
free(line_copy); free(line_copy);
} }
print_prompt(shell); 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->command_list = shell_commands;
shell->readchar = readchar; shell->readchar = readchar;
shell->put_char = put_char; shell->put_char = put_char;

View File

@ -32,11 +32,8 @@ and the mailinglist (subscription via web site)
#define VSYSLOG(level, strModule, strFmt, argp) vsyslog(level, strModule, strFmt, argp) #define VSYSLOG(level, strModule, strFmt, argp) vsyslog(level, strModule, strFmt, argp)
void void
syslog( syslog(const uint8_t level, const char(*const strModule), const char *strFmt, ...)
const uint8_t level, {
const char (*const strModule),
const char* strFmt, ...
) {
va_list argp; va_list argp;
va_start(argp, strFmt); va_start(argp, strFmt);
@ -45,7 +42,7 @@ syslog(
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
#if (SYSLOG_CONF_LEVEL & SL_EMERGENCY) == SL_EMERGENCY #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;
@ -56,7 +53,7 @@ void syslog_emergency(const char (*const mod), const char* strFmt, ...)
#endif #endif
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
#if (SYSLOG_CONF_LEVEL & SL_CRITICAL) == SL_CRITICAL #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;
@ -67,7 +64,7 @@ void syslog_critical(const char (*const mod), const char* strFmt, ...)
#endif #endif
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
#if (SYSLOG_CONF_LEVEL & SL_WARN) == SL_WARN #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;
@ -78,7 +75,7 @@ void syslog_warn(const char (*const mod), const char* strFmt, ...)
#endif #endif
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
#if (SYSLOG_CONF_LEVEL & SL_NOTICE) == SL_NOTICE #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;
@ -89,7 +86,7 @@ void syslog_notice(const char (*const mod), const char* strFmt, ...)
#endif #endif
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
#if (SYSLOG_CONF_LEVEL & SL_INFO) == SL_INFO #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;
@ -100,7 +97,7 @@ void syslog_info(const char (*const mod), const char* strFmt, ...)
#endif #endif
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
#if SYSLOG_ISLEVEL(SL_DEBUG) #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;

View File

@ -57,14 +57,13 @@ and the mailinglist (subscription via web site)
#endif #endif
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void void syslog_format_ascii(struct syslog_args *args, struct syslog_chainlink *chainlink)
syslog_format_ascii(struct syslog_args* args, struct syslog_chainlink* chainlink)
{ {
char buffer[SYSLOG_CONF_BUFSIZE + 25]; char buffer[SYSLOG_CONF_BUFSIZE + 25];
int msglen = 0; int msglen = 0;
if( args->message[0] != '\t' ) { if(args->message[0] != '\t') {
const char* strlevel = syslog_leveltostring(args->level); const char *strlevel = syslog_leveltostring(args->level);
msglen = snprintf(buffer, SYSLOG_CONF_BUFSIZE + 23, msglen = snprintf(buffer, SYSLOG_CONF_BUFSIZE + 23,
"#[%u.%u:%u=%s] %s:", "#[%u.%u:%u=%s] %s:",
NETWORK_ADDR_NET(NET_LOCAL_ADDRESS), NETWORK_ADDR_HOST(NET_LOCAL_ADDRESS), NETWORK_ADDR_NET(NET_LOCAL_ADDRESS), NETWORK_ADDR_HOST(NET_LOCAL_ADDRESS),
@ -77,23 +76,24 @@ syslog_format_ascii(struct syslog_args* args, struct syslog_chainlink* chainlink
buffer[msglen] = '\0'; buffer[msglen] = '\0';
args->message = buffer; args->message = buffer;
if( chainlink != NULL && chainlink->fpout != NULL )
if(chainlink != NULL && chainlink->fpout != NULL) {
chainlink->fpout(args, chainlink->next); chainlink->fpout(args, chainlink->next);
}
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void void syslog_format_xml(struct syslog_args *args, struct syslog_chainlink *chainlink)
syslog_format_xml(struct syslog_args* args, struct syslog_chainlink* chainlink)
{ {
const size_t bufsize = SYSLOG_CONF_BUFSIZE + 80; const size_t bufsize = SYSLOG_CONF_BUFSIZE + 80;
char buffer[bufsize]; char buffer[bufsize];
char tbuf[20]; char tbuf[20];
int msglen = 0; int msglen = 0;
#if FEUERWARE_CONF_CORE_SUPPORTS_TIME #if FEUERWARE_CONF_CORE_SUPPORTS_TIME
time_get_string(tbuf, sizeof(tbuf)); time_get_string(tbuf, sizeof(tbuf));
#else #else
sprintf(tbuf, "%lu", clock_time(NULL)); sprintf(tbuf, "%lu", clock_time(NULL));
#endif #endif
msglen = snprintf(buffer, bufsize, msglen = snprintf(buffer, bufsize,
"<log lvl=%u src=\"%u.%u\" id=%u ts=\"%s\" mod=\"%s\">%s</log>\n", "<log lvl=%u src=\"%u.%u\" id=%u ts=\"%s\" mod=\"%s\">%s</log>\n",
@ -102,40 +102,43 @@ syslog_format_xml(struct syslog_args* args, struct syslog_chainlink* chainlink)
); );
args->message = buffer; args->message = buffer;
if( chainlink != NULL && chainlink->fpout != NULL )
if(chainlink != NULL && chainlink->fpout != NULL) {
chainlink->fpout(args, chainlink->next); chainlink->fpout(args, chainlink->next);
}
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void void syslog_copy_stdout(struct syslog_args *args, struct syslog_chainlink *chainlink)
syslog_copy_stdout(struct syslog_args* args, struct syslog_chainlink* chainlink)
{ {
if( args->message[0] != '\t' ) { if(args->message[0] != '\t') {
const char* strlevel = syslog_leveltostring(args->level); const char *strlevel = syslog_leveltostring(args->level);
printf("#[%u.%u:%u=%s] %s:", printf("#[%u.%u:%u=%s] %s:",
NETWORK_ADDR_NET(NET_LOCAL_ADDRESS), NETWORK_ADDR_HOST(NET_LOCAL_ADDRESS), NETWORK_ADDR_NET(NET_LOCAL_ADDRESS), NETWORK_ADDR_HOST(NET_LOCAL_ADDRESS),
args->level, strlevel, args->module args->level, strlevel, args->module
); );
} }
printf("%s\n", args->message); printf("%s\n", args->message);
if( chainlink != NULL && chainlink->fpout != NULL ) if(chainlink != NULL && chainlink->fpout != NULL) {
chainlink->fpout(args, chainlink->next); chainlink->fpout(args, chainlink->next);
}
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void void syslog_out_stdout(struct syslog_args *args, struct syslog_chainlink *chainlink)
syslog_out_stdout(struct syslog_args* args, struct syslog_chainlink* chainlink)
{ {
printf(args->message); printf(args->message);
if( chainlink != NULL && chainlink->fpout != NULL ) if(chainlink != NULL && chainlink->fpout != NULL) {
chainlink->fpout(args, chainlink->next); chainlink->fpout(args, chainlink->next);
}
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
#ifdef MODULE_FAT #ifdef MODULE_FAT
static int syslog_file = -1; 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]; char t[20];
int file; int file;
@ -144,35 +147,41 @@ static int fat_open_logfile(const char* path)
time_get_string(t, sizeof(t)); time_get_string(t, sizeof(t));
if( file >= 0 ) { if(file >= 0) {
syslog_notice("sys", "%s log %s opened", t, path); syslog_notice("sys", "%s log %s opened", t, path);
} else { }
else {
syslog_warn("sys", "%s log %s failed", t, path); syslog_warn("sys", "%s log %s failed", t, path);
} }
return file; 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 ) { if(syslog_file >= 0) {
size_t length = (size_t)strlen(args->message); size_t length = (size_t)strlen(args->message);
int ret = write(syslog_file, args->message, length); int ret = write(syslog_file, args->message, length);
if( ret == 1 ) {
if(ret == 1) {
#ifdef MODULE_TRACELOG #ifdef MODULE_TRACELOG
trace_string(TRACELOG_EV_MEMORY, "fat"); trace_string(TRACELOG_EV_MEMORY, "fat");
#endif #endif
} }
} }
if( chainlink != NULL && chainlink->fpout != NULL ) if(chainlink != NULL && chainlink->fpout != NULL) {
chainlink->fpout(args, chainlink->next); chainlink->fpout(args, chainlink->next);
}
} }
bool syslog_open_file(void) { bool syslog_open_file(void)
{
syslog_file = fat_open_logfile("SYSLOG.LOG"); syslog_file = fat_open_logfile("SYSLOG.LOG");
return (syslog_file >= 0); return (syslog_file >= 0);
} }
void syslog_close_file(void) { void syslog_close_file(void)
{
close(syslog_file); close(syslog_file);
syslog_file = -1; syslog_file = -1;
} }

View File

@ -52,7 +52,7 @@ and the mailinglist (subscription via web site)
#include "sysmon.h" #include "sysmon.h"
#include "tracelog.h" #include "tracelog.h"
static const char* syslog_level_stringtable = "emergency\0" static const char *syslog_level_stringtable = "emergency\0"
"critical\0" "critical\0"
"warn\0" "warn\0"
"notice\0" "notice\0"
@ -64,70 +64,61 @@ __attribute__((section(".noinit")))
static volatile unsigned int syslog_msgnum; static volatile unsigned int syslog_msgnum;
static unsigned short syslog_flagtolevel(const uint8_t level); 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[]; extern struct syslog_interface syslog_interfaces[];
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void void syslog_init(void)
syslog_init(void)
{ {
if( sysmon_initial_boot() ) if(sysmon_initial_boot()) {
syslog_msgnum = 0; syslog_msgnum = 0;
}
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
static bool static bool testlevel(uint8_t filter_level, const uint8_t level)
testlevel(uint8_t filter_level, const uint8_t level) { {
return ((filter_level & level) != 0); return ((filter_level & level) != 0);
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void void vsyslog(const uint8_t level, const char(*const strModule),
vsyslog( const char *strFmt, va_list argp)
const uint8_t level, {
const char (*const strModule),
const char* strFmt,
va_list argp
) {
int i; int i;
struct syslog_interface* slif; // syslog interface struct syslog_interface *slif; // syslog interface
struct syslog_args args; // output function arguments struct syslog_args args; // output function arguments
char message[SYSLOG_CONF_BUFSIZE]; // message buffer char message[SYSLOG_CONF_BUFSIZE]; // message buffer
int msglen = 0; int msglen = 0;
args.message = NULL; args.message = NULL;
//printf("0 %p %p\n", &syslog_interfaces[0], syslog_interfaces[0].chain); /* check each syslog interface */
//printf("1 %p %p\n", &syslog_interfaces[1], syslog_interfaces[1].chain); for(i = 0; i < SYSLOG_CONF_NUM_INTERFACES; i++) {
// check each syslog interface
for( i = 0; i < SYSLOG_CONF_NUM_INTERFACES; i++) {
slif = &syslog_interfaces[i]; slif = &syslog_interfaces[i];
/* run interface filter */ /* run interface filter */
//printf("testing %i, %s\n", i, slif->name); if(slif->name != NULL && testlevel(cfg_feuerware.level[i], level)) {
if( slif->name != NULL && testlevel(cfg_feuerware.level[i], level) ) {
/* filter matched, produce output */ /* filter matched, produce output */
//printf("printing to %s\n", slif->name); if(args.message == NULL) {
if( args.message == NULL ) { /* initialize structure one time, when actually needed */
// initialize structure one time, when actually needed
args.msgnum = syslog_msgnum++; args.msgnum = syslog_msgnum++;
args.level = syslog_flagtolevel(level); args.level = syslog_flagtolevel(level);
args.module = strModule; args.module = strModule;
args.message = message; args.message = message;
msglen = vsnprintf(message, SYSLOG_CONF_BUFSIZE-1, strFmt, argp); 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 args.interface = (const struct syslog_interface *)slif;
//printf("invoke on %s: %p %p\n", slif->name, slif, slif->chain);
if( slif->chain->fpout != NULL ) { /* invoke first link of ouput chain */
if(slif->chain->fpout != NULL) {
slif->chain->fpout(&args, slif->chain->next); slif->chain->fpout(&args, slif->chain->next);
} }
} }
} }
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void syslog_printlevel(char* buffer, size_t bufsize, uint8_t level) void syslog_printlevel(char *buffer, size_t bufsize, uint8_t level)
{ {
uint8_t l = level; uint8_t l = level;
int intlevel; int intlevel;
@ -136,26 +127,34 @@ void syslog_printlevel(char* buffer, size_t bufsize, uint8_t level)
bufpos = snprintf(buffer, bufsize, "%#.2x=", level); bufpos = snprintf(buffer, bufsize, "%#.2x=", level);
bufsize -= bufpos; bufsize -= bufpos;
for( intlevel = 0; intlevel < SYSLOG_LEVELS_COUNT; intlevel++ ) {
if( l & 0x0001 ) { for(intlevel = 0; intlevel < SYSLOG_LEVELS_COUNT; intlevel++) {
const char* string = string_table_get(syslog_level_stringtable, intlevel); if(l & 0x0001) {
if( string ) { const char *string = string_table_get(syslog_level_stringtable, intlevel);
if( bufsize < 0 ) bufsize = 0;
len = snprintf( &buffer[bufpos], bufsize, "%s%s", ((len > 0) ? "|" : ""), (char*)string ); if(string) {
if(bufsize < 0) {
bufsize = 0;
}
len = snprintf(&buffer[bufpos], bufsize, "%s%s", ((len > 0) ? "|" : ""), (char *)string);
bufsize -= len; bufsize -= len;
bufpos += len; bufpos += len;
} }
} }
l >>= 1; l >>= 1;
} }
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
uint8_t syslog_set_level(const char* name, uint8_t level) uint8_t syslog_set_level(const char *name, uint8_t level)
{ {
uint8_t result; uint8_t result;
int index = find_interface_index_for_name(name); int index = find_interface_index_for_name(name);
if( index < 0 )
if(index < 0) {
return 0; return 0;
}
result = cfg_feuerware.level[index]; result = cfg_feuerware.level[index];
cfg_feuerware.level[index] = level; cfg_feuerware.level[index] = level;
@ -164,8 +163,8 @@ uint8_t syslog_set_level(const char* name, uint8_t level)
return result; return result;
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
const char* const char *syslog_leveltostring(unsigned int level)
syslog_leveltostring(unsigned int level) { {
return string_table_get(syslog_level_stringtable, level); return string_table_get(syslog_level_stringtable, level);
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -191,29 +190,32 @@ CMD_FUNCTION(syslog, cmdargs)
{ {
int i; int i;
if( cmdargs->arg_size > 0 ) { if(cmdargs->arg_size > 0) {
unsigned int argc; unsigned int argc;
const char* arg; const char *arg;
const char* name = NULL; const char *name = NULL;
unsigned int value; unsigned int value;
argc = cmd_split_arguments(cmdargs->args); argc = cmd_split_arguments(cmdargs->args);
arg = cmdargs->args; arg = cmdargs->args;
if( *arg >= 'A' ) { if(*arg >= 'A') {
// first argument is a string // first argument is a string
name = arg; name = arg;
// move to next argument // move to next argument
arg = cmd_get_next_argument(arg); arg = cmd_get_next_argument(arg);
} }
if( *arg == '\0' )
if(*arg == '\0') {
return CMD_ERROR; return CMD_ERROR;
}
value = strtoul(arg, NULL, 0); value = strtoul(arg, NULL, 0);
syslog_set_level(name, value); syslog_set_level(name, value);
} }
for( i = 0; i < SYSLOG_CONF_NUM_INTERFACES; i++ ) { for(i = 0; i < SYSLOG_CONF_NUM_INTERFACES; i++) {
if( syslog_interfaces[i].name != NULL ) { if(syslog_interfaces[i].name != NULL) {
char buf[SYSLOG_PRINTLEVEL_MAXLEN]; char buf[SYSLOG_PRINTLEVEL_MAXLEN];
syslog_printlevel(buf, sizeof(buf), cfg_feuerware.level[i]); syslog_printlevel(buf, sizeof(buf), cfg_feuerware.level[i]);
cmdargs->fresponse(cmdargs, cmdargs->fresponse(cmdargs,
@ -224,6 +226,7 @@ CMD_FUNCTION(syslog, cmdargs)
); );
} }
} }
return CMD_SUCCESS; return CMD_SUCCESS;
} }
#endif #endif
@ -231,15 +234,16 @@ CMD_FUNCTION(syslog, cmdargs)
/** /**
* @brief Convert bit flag to bit number * @brief Convert bit flag to bit number
*/ */
static unsigned short static unsigned short syslog_flagtolevel(const uint8_t level)
syslog_flagtolevel(const uint8_t level)
{ {
uint8_t l = level; uint8_t l = level;
unsigned short intlevel; unsigned short intlevel;
for( intlevel = 0; intlevel < SYSLOG_LEVELS_COUNT; intlevel++ ) { for(intlevel = 0; intlevel < SYSLOG_LEVELS_COUNT; intlevel++) {
if( (l & 1) == 1 ) if((l & 1) == 1) {
break; break;
}
l >>= 1; l >>= 1;
} }
@ -249,15 +253,16 @@ syslog_flagtolevel(const uint8_t level)
/** /**
* @brief Find an interface for a given name * @brief Find an interface for a given name
*/ */
static int static int find_interface_index_for_name(const char *name)
find_interface_index_for_name(const char* name)
{ {
int i; int i;
for( i = 0; i < SYSLOG_CONF_NUM_INTERFACES; i++ ) { for(i = 0; i < SYSLOG_CONF_NUM_INTERFACES; i++) {
if( strcmp(syslog_interfaces[i].name, name) == 0 ) if(strcmp(syslog_interfaces[i].name, name) == 0) {
return i; return i;
} }
}
return -1; return -1;
} }

View File

@ -52,11 +52,11 @@ and the mailinglist (subscription via web site)
#include "syslog.h" #include "syslog.h"
#if TRACELOG_CONF_NUM_ENTRIES > 0 #if TRACELOG_CONF_NUM_ENTRIES > 0
__attribute__((section(".noinit"))) __attribute__((section(".noinit")))
struct tracelog tracelog; struct tracelog tracelog;
/// tells if tracelog can accept input /// tells if tracelog can accept input
static bool tracelog_initialized = 0; static bool tracelog_initialized = 0;
#endif #endif
#if defined(SYSLOG_CONF_LEVEL) && ((SYSLOG_CONF_LEVEL & SL_DEBUG) == SL_DEBUG) #if defined(SYSLOG_CONF_LEVEL) && ((SYSLOG_CONF_LEVEL & SL_DEBUG) == SL_DEBUG)
@ -82,41 +82,45 @@ static const char symon_event_names[] =
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
#if TRACELOG_CONF_NUM_ENTRIES > 0 #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]; struct tracelog_entry *trace = &tracelog.traces[i];
int length = 0; int length = 0;
bufsz -= 1; // save one for zero bufsz -= 1; // save one for zero
#if (SYSLOG_CONF_LEVEL & SL_DEBUG) == SL_DEBUG #if (SYSLOG_CONF_LEVEL & SL_DEBUG) == SL_DEBUG
/* when running in debug level, event names are available and can be printed */ /* when running in debug level, event names are available and can be printed */
char* name = (char*)string_table_get(symon_event_names, trace->event); char *name = (char *)string_table_get(symon_event_names, trace->event);
length = snprintf(buf, bufsz, "%#.2x (%s): ", trace->event, name); length = snprintf(buf, bufsz, "%#.2x (%s): ", trace->event, name);
#else #else
length = snprintf(buf, bufsz, "%#.2x: ", trace->event); length = snprintf(buf, bufsz, "%#.2x: ", trace->event);
#endif #endif
bufsz -= length; bufsz -= length;
buf += length; buf += length;
switch( trace->type ) { switch(trace->type) {
case TRACE_NUMBER: { case TRACE_NUMBER: {
tracelog_number_t uldata; tracelog_number_t uldata;
memcpy(&uldata, trace->data, sizeof(tracelog_number_t)); memcpy(&uldata, trace->data, sizeof(tracelog_number_t));
length += snprintf(buf, bufsz, "%#10lx (%lu)", uldata, uldata); length += snprintf(buf, bufsz, "%#10lx (%lu)", uldata, uldata);
break; break;
} }
case TRACE_POINTER: { case TRACE_POINTER: {
void* uldata; void *uldata;
memcpy(&uldata, trace->data, sizeof(void*)); memcpy(&uldata, trace->data, sizeof(void *));
length += snprintf(buf, bufsz, "%p", uldata); length += snprintf(buf, bufsz, "%p", uldata);
break; break;
} }
case TRACE_STRING: case TRACE_STRING:
length += snprintf(buf, bufsz, "%.*s", TRACELOG_CONF_ENTRY_SIZE, trace->data); length += snprintf(buf, bufsz, "%.*s", TRACELOG_CONF_ENTRY_SIZE, trace->data);
break; break;
default: default:
break; break;
} }
buf[length] = '\0'; buf[length] = '\0';
} }
#endif #endif
@ -131,46 +135,52 @@ trace(
const enum tracelog_type t, const enum tracelog_type t,
const void (* const data), const void (* const data),
const int size const int size
) { )
{
#if TRACELOG_CONF_NUM_ENTRIES > 0 #if TRACELOG_CONF_NUM_ENTRIES > 0
int length = size; int length = size;
if( tracelog_initialized == false ) if(tracelog_initialized == false) {
return; return;
}
struct tracelog_entry *trace = &tracelog.traces[tracelog.tail]; // get current tail element
struct tracelog_entry* trace = &tracelog.traces[tracelog.tail]; // get current tail element
/* increase tail */ /* increase tail */
if( (tracelog.tail + 1) < TRACELOG_CONF_NUM_ENTRIES ) if((tracelog.tail + 1) < TRACELOG_CONF_NUM_ENTRIES) {
tracelog.tail++; tracelog.tail++;
else }
else {
tracelog.tail = 0; tracelog.tail = 0;
}
/* fill meta data */ /* fill meta data */
trace->event = event & 0x7F; trace->event = event & 0x7F;
trace->type = t; trace->type = t;
/* calculate size */ /* calculate size */
if( length == 0 ) { if(length == 0) {
if( t == TRACE_STRING ) { if(t == TRACE_STRING) {
length = strlen((char*)data); length = strlen((char *)data);
} }
} }
length = (TRACELOG_CONF_ENTRY_SIZE < length) ? TRACELOG_CONF_ENTRY_SIZE : length; length = (TRACELOG_CONF_ENTRY_SIZE < length) ? TRACELOG_CONF_ENTRY_SIZE : length;
memcpy( trace->data, data, length ); // copy description memcpy(trace->data, data, length); // copy description
#endif #endif
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void trace_reset(void) void trace_reset(void)
{ {
#if TRACELOG_CONF_NUM_ENTRIES > 0 #if TRACELOG_CONF_NUM_ENTRIES > 0
#if SYSLOG_ISLEVEL(SL_DEBUG) #if SYSLOG_ISLEVEL(SL_DEBUG)
char buffer[12]; char buffer[12];
sysmon_write_reset_info(buffer, 12, sysmon.reset_code); sysmon_write_reset_info(buffer, 12, sysmon.reset_code);
trace_string(TRACELOG_EV_START, buffer); trace_string(TRACELOG_EV_START, buffer);
#else #else
trace_number(TRACELOG_EV_START, sysmon.reset_code); trace_number(TRACELOG_EV_START, sysmon.reset_code);
#endif #endif
#endif #endif
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -178,11 +188,13 @@ void
tracelog_init(void) tracelog_init(void)
{ {
#if TRACELOG_CONF_NUM_ENTRIES > 0 #if TRACELOG_CONF_NUM_ENTRIES > 0
if( tracelog_initialized != 0 )
return;
if( sysmon_initial_boot() ) { if(tracelog_initialized != 0) {
memset( &tracelog, 0, sizeof(struct tracelog) ); // clear tracelog buffer on initial boot only return;
}
if(sysmon_initial_boot()) {
memset(&tracelog, 0, sizeof(struct tracelog)); // clear tracelog buffer on initial boot only
} }
tracelog_initialized = true; // accept traces tracelog_initialized = true; // accept traces
@ -197,13 +209,19 @@ tracelog_dump(void)
#if TRACELOG_CONF_NUM_ENTRIES > 0 #if TRACELOG_CONF_NUM_ENTRIES > 0
char buf[30 + TRACELOG_CONF_ENTRY_SIZE]; char buf[30 + TRACELOG_CONF_ENTRY_SIZE];
int i = tracelog.tail; // tracelog tail holds next index int i = tracelog.tail; // tracelog tail holds next index
do { do {
i--; i--;
if( i < 0 )
if(i < 0) {
i = TRACELOG_CONF_NUM_ENTRIES - 1; i = TRACELOG_CONF_NUM_ENTRIES - 1;
}
tracelog_snprint(buf, sizeof(buf), i); tracelog_snprint(buf, sizeof(buf), i);
printf("\t %.2i: %s\n", i, buf); printf("\t %.2i: %s\n", i, buf);
} while( i != tracelog.tail ); }
while(i != tracelog.tail);
#endif #endif
printf("}\n"); printf("}\n");
@ -226,15 +244,15 @@ trace_number(enum tracelog_event event, tracelog_number_t number)
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void void
trace_pointer(enum tracelog_event event, void* pointer) trace_pointer(enum tracelog_event event, void *pointer)
{ {
#if TRACELOG_CONF_NUM_ENTRIES > 0 #if TRACELOG_CONF_NUM_ENTRIES > 0
trace(event, TRACE_POINTER, &pointer, sizeof(void*)); trace(event, TRACE_POINTER, &pointer, sizeof(void *));
#endif #endif
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void void
trace_string(enum tracelog_event event, char* string) trace_string(enum tracelog_event event, char *string)
{ {
#if TRACELOG_CONF_NUM_ENTRIES > 0 #if TRACELOG_CONF_NUM_ENTRIES > 0
trace(event, TRACE_STRING, string, strlen(string)); trace(event, TRACE_STRING, string, strlen(string));
@ -254,16 +272,19 @@ ASCCMD(trace, CMDFLAG_SERIAL, "[event] [text]: print tracelog / trace event [num
CMD_FUNCTION(trace, cmdargs) CMD_FUNCTION(trace, cmdargs)
{ {
#if TRACELOG_CONF_NUM_ENTRIES > 0 #if TRACELOG_CONF_NUM_ENTRIES > 0
if( cmdargs->arg_size > 0 ) {
if(cmdargs->arg_size > 0) {
enum tracelog_event event; enum tracelog_event event;
char* c = (char*)cmdargs->args; char *c = (char *)cmdargs->args;
event = (enum tracelog_event)strtoul(c, &c, 0); // read event number event = (enum tracelog_event)strtoul(c, &c, 0); // read event number
if( event > 0 ) {
if(event > 0) {
c++; // skip expected whitespace c++; // skip expected whitespace
trace_string(event, c); // generate event with argument as text trace_string(event, c); // generate event with argument as text
return true; return true;
} }
} }
#endif #endif
tracelog_dump(); tracelog_dump();

View File

@ -30,16 +30,16 @@
#ifdef MODULE_CC110X #ifdef MODULE_CC110X
#include <cc1100-interface.h> #include <cc1100-interface.h>
#if (CC1100_MAX_DATA_LENGTH > PAYLOAD_SIZE) #if (CC1100_MAX_DATA_LENGTH > PAYLOAD_SIZE)
#undef PAYLOAD_SIZE #undef PAYLOAD_SIZE
#define PAYLOAD_SIZE (CC1100_MAX_DATA_LENGTH) #define PAYLOAD_SIZE (CC1100_MAX_DATA_LENGTH)
#endif #endif
#endif #endif
#ifdef MODULE_CC110X_NG #ifdef MODULE_CC110X_NG
#include <cc110x_ng.h> #include <cc110x_ng.h>
#if (CC1100_MAX_DATA_LENGTH > PAYLOAD_SIZE) #if (CC1100_MAX_DATA_LENGTH > PAYLOAD_SIZE)
#undef PAYLOAD_SIZE #undef PAYLOAD_SIZE
#define PAYLOAD_SIZE (CC1100_MAX_DATA_LENGTH) #define PAYLOAD_SIZE (CC1100_MAX_DATA_LENGTH)
#endif #endif
#endif #endif
@ -55,7 +55,7 @@ registered_t reg[TRANSCEIVER_MAX_REGISTERED];
/* packet buffers */ /* packet buffers */
radio_packet_t transceiver_buffer[TRANSCEIVER_BUFFER_SIZE]; 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 */ /* message buffer */
msg_t msg_buffer[TRANSCEIVER_MSG_BUFFER_SIZE]; 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 #ifdef MODULE_CC110X_NG
static void receive_cc110x_packet(radio_packet_t *trans_p); static void receive_cc110x_packet(radio_packet_t *trans_p);
#elif MODULE_CC110X #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); void receive_cc1100_packet(radio_packet_t *trans_p);
#endif #endif
static uint8_t send_packet(transceiver_type_t t, void *pkt); 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 */ /* Transceiver init */
void transceiver_init(transceiver_type_t t) { void transceiver_init(transceiver_type_t t)
{
uint8_t i; uint8_t i;
/* Initializing transceiver buffer and data buffer */ /* Initializing transceiver buffer and data buffer */
memset(transceiver_buffer, 0, TRANSCEIVER_BUFFER_SIZE); memset(transceiver_buffer, 0, TRANSCEIVER_BUFFER_SIZE);
memset(data_buffer, 0, TRANSCEIVER_BUFFER_SIZE * PAYLOAD_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].transceivers = TRANSCEIVER_NONE;
reg[i].pid = 0; reg[i].pid = 0;
} }
if (t & TRANSCEIVER_CC1100) {
if(t & TRANSCEIVER_CC1100) {
transceivers |= t; transceivers |= t;
} }
else { else {
@ -123,12 +125,14 @@ void transceiver_init(transceiver_type_t t) {
} }
/* Start the transceiver thread */ /* Start the transceiver thread */
int transceiver_start(void) { int transceiver_start(void)
transceiver_pid = thread_create(transceiver_stack, TRANSCEIVER_STACK_SIZE, PRIORITY_MAIN-3, CREATE_STACKTEST, run, "Transceiver"); {
if (transceiver_pid < 0) { 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"); puts("Error creating transceiver thread");
} }
else if (transceivers & TRANSCEIVER_CC1100) { else if(transceivers & TRANSCEIVER_CC1100) {
DEBUG("Transceiver started for CC1100\n"); DEBUG("Transceiver started for CC1100\n");
#ifdef MODULE_CC110X_NG #ifdef MODULE_CC110X_NG
cc110x_init(transceiver_pid); cc110x_init(transceiver_pid);
@ -137,17 +141,20 @@ int transceiver_start(void) {
cc1100_set_packet_monitor(cc1100_packet_monitor); cc1100_set_packet_monitor(cc1100_packet_monitor);
#endif #endif
} }
return transceiver_pid; return transceiver_pid;
} }
/* Register an upper layer thread */ /* Register an upper layer thread */
uint8_t transceiver_register(transceiver_type_t t, int pid) { uint8_t transceiver_register(transceiver_type_t t, int pid)
{
uint8_t i; uint8_t i;
for (i = 0; ((reg[i].pid != pid) &&
for(i = 0; ((reg[i].pid != pid) &&
(i < TRANSCEIVER_MAX_REGISTERED) && (i < TRANSCEIVER_MAX_REGISTERED) &&
(reg[i].transceivers != TRANSCEIVER_NONE)); i++); (reg[i].transceivers != TRANSCEIVER_NONE)); i++);
if (i >= TRANSCEIVER_MAX_REGISTERED) { if(i >= TRANSCEIVER_MAX_REGISTERED) {
return ENOMEM; return ENOMEM;
} }
else { else {
@ -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 * @brief The main thread run, receiving and processing messages in an infinite
* loop * loop
*/ */
void run(void) { void run(void)
{
msg_t m; msg_t m;
transceiver_command_t *cmd; transceiver_command_t *cmd;
msg_init_queue(msg_buffer, TRANSCEIVER_MSG_BUFFER_SIZE); msg_init_queue(msg_buffer, TRANSCEIVER_MSG_BUFFER_SIZE);
while (1) {
while(1) {
DEBUG("Waiting for next message\n"); DEBUG("Waiting for next message\n");
msg_receive(&m); msg_receive(&m);
/* only makes sense for messages for upper layers */ /* 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"); DEBUG("Transceiver: Message received\n");
switch (m.type) {
switch(m.type) {
case RCV_PKT_CC1020: case RCV_PKT_CC1020:
case RCV_PKT_CC1100: case RCV_PKT_CC1100:
receive_packet(m.type, m.content.value); receive_packet(m.type, m.content.value);
break; break;
case SND_PKT: case SND_PKT:
response = send_packet(cmd->transceivers, cmd->data); response = send_packet(cmd->transceivers, cmd->data);
m.content.value = response; m.content.value = response;
msg_reply(&m, &m); msg_reply(&m, &m);
break; break;
case GET_CHANNEL: case GET_CHANNEL:
*((int16_t*) cmd->data) = get_channel(cmd->transceivers); *((int16_t *) cmd->data) = get_channel(cmd->transceivers);
msg_reply(&m, &m); msg_reply(&m, &m);
break; break;
case SET_CHANNEL: 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); msg_reply(&m, &m);
break; break;
case GET_ADDRESS: case GET_ADDRESS:
*((int16_t*) cmd->data) = get_address(cmd->transceivers); *((int16_t *) cmd->data) = get_address(cmd->transceivers);
msg_reply(&m, &m); msg_reply(&m, &m);
break; break;
case SET_ADDRESS: 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); msg_reply(&m, &m);
break; break;
case SET_MONITOR: case SET_MONITOR:
set_monitor(cmd->transceivers, cmd->data); set_monitor(cmd->transceivers, cmd->data);
break; break;
case POWERDOWN: case POWERDOWN:
powerdown(cmd->transceivers); powerdown(cmd->transceivers);
break; break;
case SWITCH_RX: case SWITCH_RX:
switch_to_rx(cmd->transceivers); switch_to_rx(cmd->transceivers);
break; break;
#ifdef DBG_IGNORE #ifdef DBG_IGNORE
case DBG_IGN: case DBG_IGN:
printf("Transceiver PID: %i (%p), rx_buffer_next: %u\n", transceiver_pid, &transceiver_pid, rx_buffer_next); printf("Transceiver PID: %i (%p), rx_buffer_next: %u\n", transceiver_pid, &transceiver_pid, rx_buffer_next);
ignore_add(cmd->transceivers, cmd->data); ignore_add(cmd->transceivers, cmd->data);
break; break;
#endif #endif
default: default:
DEBUG("Unknown message received\n"); DEBUG("Unknown message received\n");
break; break;
@ -226,7 +246,8 @@ void run(void) {
} }
#ifdef MODULE_CC110X #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 = payload;
cc1100_payload_size = payload_size - 3; cc1100_payload_size = payload_size - 3;
cc1100_packet_info = packet_info; cc1100_packet_info = packet_info;
@ -242,33 +263,38 @@ void cc1100_packet_monitor(void* payload, int payload_size, protocol_t protocol,
* packet * packet
* @param pos The current device driver's buffer position * @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; uint8_t i = 0;
transceiver_type_t t; transceiver_type_t t;
rx_buffer_pos = pos; rx_buffer_pos = pos;
msg_t m; msg_t m;
DEBUG("Packet received\n"); DEBUG("Packet received\n");
switch (type) {
switch(type) {
case RCV_PKT_CC1020: case RCV_PKT_CC1020:
t = TRANSCEIVER_CC1020; t = TRANSCEIVER_CC1020;
break; break;
case RCV_PKT_CC1100: case RCV_PKT_CC1100:
t = TRANSCEIVER_CC1100; t = TRANSCEIVER_CC1100;
break; break;
default: default:
t = TRANSCEIVER_NONE; t = TRANSCEIVER_NONE;
break; break;
} }
/* search first free position in transceiver buffer */ /* search first free position in transceiver buffer */
for (i = 0; (i < TRANSCEIVER_BUFFER_SIZE) && (transceiver_buffer[transceiver_buffer_pos].processing); i++) { for(i = 0; (i < TRANSCEIVER_BUFFER_SIZE) && (transceiver_buffer[transceiver_buffer_pos].processing); i++) {
if (++transceiver_buffer_pos == TRANSCEIVER_BUFFER_SIZE) { if(++transceiver_buffer_pos == TRANSCEIVER_BUFFER_SIZE) {
transceiver_buffer_pos = 0; transceiver_buffer_pos = 0;
} }
} }
/* no buffer left */ /* no buffer left */
if (i >= TRANSCEIVER_BUFFER_SIZE) { if(i >= TRANSCEIVER_BUFFER_SIZE) {
/* inform upper layers of lost packet */ /* inform upper layers of lost packet */
m.type = ENOBUFFER; m.type = ENOBUFFER;
m.content.value = t; m.content.value = t;
@ -278,7 +304,7 @@ static void receive_packet(uint16_t type, uint8_t pos) {
radio_packet_t *trans_p = &(transceiver_buffer[transceiver_buffer_pos]); radio_packet_t *trans_p = &(transceiver_buffer[transceiver_buffer_pos]);
m.type = PKT_PENDING; m.type = PKT_PENDING;
if (type == RCV_PKT_CC1100) { if(type == RCV_PKT_CC1100) {
#ifdef MODULE_CC110X_NG #ifdef MODULE_CC110X_NG
receive_cc110x_packet(trans_p); receive_cc110x_packet(trans_p);
#else #else
@ -294,14 +320,17 @@ static void receive_packet(uint16_t type, uint8_t pos) {
/* finally notify waiting upper layers /* finally notify waiting upper layers
* this is done non-blocking, so packets can get lost */ * this is done non-blocking, so packets can get lost */
i = 0; i = 0;
while (reg[i].transceivers != TRANSCEIVER_NONE) {
if (reg[i].transceivers & t) { while(reg[i].transceivers != TRANSCEIVER_NONE) {
m.content.ptr = (char*) &(transceiver_buffer[transceiver_buffer_pos]); if(reg[i].transceivers & t) {
m.content.ptr = (char *) & (transceiver_buffer[transceiver_buffer_pos]);
DEBUG("Notify thread %i\n", reg[i].pid); 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++; transceiver_buffer[transceiver_buffer_pos].processing++;
} }
} }
i++; i++;
} }
} }
@ -312,7 +341,8 @@ static void receive_packet(uint16_t type, uint8_t pos) {
* *
* @param trans_p The current entry in the transceiver buffer * @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"); DEBUG("Handling CC1100 packet\n");
/* disable interrupts while copying packet */ /* disable interrupts while copying packet */
dINT(); dINT();
@ -323,26 +353,27 @@ static void receive_cc110x_packet(radio_packet_t *trans_p) {
trans_p->rssi = cc110x_rx_buffer[rx_buffer_pos].rssi; trans_p->rssi = cc110x_rx_buffer[rx_buffer_pos].rssi;
trans_p->lqi = cc110x_rx_buffer[rx_buffer_pos].lqi; trans_p->lqi = cc110x_rx_buffer[rx_buffer_pos].lqi;
trans_p->length = p.length - CC1100_HEADER_LENGTH; 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(); eINT();
DEBUG("Packet %p was from %hu to %hu, size: %u\n", trans_p, trans_p->src, trans_p->dst, trans_p->length); 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 #endif
#ifdef MODULE_CC110X #ifdef MODULE_CC110X
void receive_cc1100_packet(radio_packet_t *trans_p) { void receive_cc1100_packet(radio_packet_t *trans_p)
{
dINT(); dINT();
trans_p->src = cc1100_packet_info->source; trans_p->src = cc1100_packet_info->source;
trans_p->dst = cc1100_packet_info->destination; trans_p->dst = cc1100_packet_info->destination;
trans_p->rssi = cc1100_packet_info->rssi; trans_p->rssi = cc1100_packet_info->rssi;
trans_p->lqi = cc1100_packet_info->lqi; trans_p->lqi = cc1100_packet_info->lqi;
trans_p->length = cc1100_payload_size; 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(); 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 #endif
@ -356,18 +387,19 @@ void receive_cc1100_packet(radio_packet_t *trans_p) {
* *
* @return 1 on success, 0 otherwise * @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; uint8_t res = 0;
#ifdef MODULE_CC110X #ifdef MODULE_CC110X
int snd_ret; int snd_ret;
#endif #endif
radio_packet_t p = *((radio_packet_t*) pkt); radio_packet_t p = *((radio_packet_t *)pkt);
#ifdef MODULE_CC110X_NG #ifdef MODULE_CC110X_NG
cc110x_packet_t cc110x_pkt; cc110x_packet_t cc110x_pkt;
#endif #endif
switch (t) { switch(t) {
case TRANSCEIVER_CC1100: case TRANSCEIVER_CC1100:
#ifdef MODULE_CC110X_NG #ifdef MODULE_CC110X_NG
cc110x_pkt.length = p.length + CC1100_HEADER_LENGTH; 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); res = cc110x_send(&cc110x_pkt);
#else #else
memcpy(cc1100_pkt, p.data, p.length); 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); DEBUG("snd_ret (%u) = %i\n", p.length, snd_ret);
res = 0; res = 0;
} }
else { else {
res = 1; res = 1;
} }
#endif #endif
break; break;
default: default:
puts("Unknown transceiver"); puts("Unknown transceiver");
break; break;
} }
return res; 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 * @return The radio channel AFTER calling the set command, -1 on error
*/ */
static int16_t set_channel(transceiver_type_t t, void *channel) { static int16_t set_channel(transceiver_type_t t, void *channel)
uint8_t c = *((uint8_t*) channel); {
switch (t) { uint8_t c = *((uint8_t *)channel);
switch(t) {
case TRANSCEIVER_CC1100: case TRANSCEIVER_CC1100:
#ifdef MODULE_CC110X_NG #ifdef MODULE_CC110X_NG
return cc110x_set_channel(c); return cc110x_set_channel(c);
#else #else
return cc1100_set_channel(c); return cc1100_set_channel(c);
#endif #endif
default: default:
return -1; 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 * @return The current radio channel of the transceiver, -1 on error
*/ */
static int16_t get_channel(transceiver_type_t t) { static int16_t get_channel(transceiver_type_t t)
switch (t) { {
switch(t) {
case TRANSCEIVER_CC1100: case TRANSCEIVER_CC1100:
#ifdef MODULE_CC110X_NG #ifdef MODULE_CC110X_NG
return cc110x_get_channel(); return cc110x_get_channel();
#else #else
return cc1100_get_channel(); return cc1100_get_channel();
#endif #endif
default: default:
return -1; 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 * @return The configured address of the device, -1 on error
*/ */
static int16_t get_address(transceiver_type_t t) { static int16_t get_address(transceiver_type_t t)
switch (t) { {
switch(t) {
case TRANSCEIVER_CC1100: case TRANSCEIVER_CC1100:
#ifdef MODULE_CC110X_NG #ifdef MODULE_CC110X_NG
return cc110x_get_address(); return cc110x_get_address();
#else #else
return cc1100_get_address(); return cc1100_get_address();
#endif #endif
default: default:
return -1; return -1;
} }
@ -464,15 +507,18 @@ static int16_t get_address(transceiver_type_t t) {
* *
* @return The new radio address of the device * @return The new radio address of the device
*/ */
static int16_t set_address(transceiver_type_t t, void *address) { static int16_t set_address(transceiver_type_t t, void *address)
radio_address_t addr = *((radio_address_t*) address); {
switch (t) { radio_address_t addr = *((radio_address_t *)address);
switch(t) {
case TRANSCEIVER_CC1100: case TRANSCEIVER_CC1100:
#ifdef MODULE_CC110X_NG #ifdef MODULE_CC110X_NG
return cc110x_set_address(addr); return cc110x_set_address(addr);
#else #else
return cc1100_set_address(addr); return cc1100_set_address(addr);
#endif #endif
default: default:
return -1; return -1;
} }
@ -484,50 +530,59 @@ static int16_t set_address(transceiver_type_t t, void *address) {
* @param t The transceiver device * @param t The transceiver device
* @param mode 1 for enabling monitor mode, 0 for enabling address check * @param mode 1 for enabling monitor mode, 0 for enabling address check
*/ */
static void set_monitor(transceiver_type_t t, void *mode) { static void set_monitor(transceiver_type_t t, void *mode)
switch (t) { {
switch(t) {
case TRANSCEIVER_CC1100: case TRANSCEIVER_CC1100:
#ifdef MODULE_CC110X_NG #ifdef MODULE_CC110X_NG
cc110x_set_monitor(*((uint8_t*) mode)); cc110x_set_monitor(*((uint8_t *)mode));
#endif #endif
break; break;
default: default:
break; break;
} }
} }
/*------------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------------*/
static void powerdown(transceiver_type_t t) { static void powerdown(transceiver_type_t t)
switch (t) { {
switch(t) {
case TRANSCEIVER_CC1100: case TRANSCEIVER_CC1100:
#ifdef MODULE_CC110X_NG #ifdef MODULE_CC110X_NG
cc110x_switch_to_pwd(); cc110x_switch_to_pwd();
#endif #endif
break; break;
default: default:
break; break;
} }
} }
/*------------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------------*/
static void switch_to_rx(transceiver_type_t t) { static void switch_to_rx(transceiver_type_t t)
switch (t) { {
switch(t) {
case TRANSCEIVER_CC1100: case TRANSCEIVER_CC1100:
#ifdef MODULE_CC110X_NG #ifdef MODULE_CC110X_NG
cc110x_switch_to_rx(); cc110x_switch_to_rx();
#endif #endif
break; break;
default: default:
break; break;
} }
} }
#ifdef DBG_IGNORE #ifdef DBG_IGNORE
static void ignore_add(transceiver_type_t t, void *address) { static void ignore_add(transceiver_type_t t, void *address)
radio_address_t addr = *((radio_address_t*) address); {
switch (t) { radio_address_t addr = *((radio_address_t *)address);
switch(t) {
case TRANSCEIVER_CC1100: case TRANSCEIVER_CC1100:
cc110x_add_ignored(addr); cc110x_add_ignored(addr);
break; break;
default: default:
break; break;
} }

View File

@ -17,33 +17,39 @@ static char buffer[UART0_BUFSIZE];
static char uart0_thread_stack[UART0_STACKSIZE]; static char uart0_thread_stack[UART0_STACKSIZE];
static void uart0_loop(void) { static void uart0_loop(void)
{
chardev_loop(&uart0_ringbuffer); chardev_loop(&uart0_ringbuffer);
} }
void board_uart0_init(void) { void board_uart0_init(void)
{
ringbuffer_init(&uart0_ringbuffer, buffer, UART0_BUFSIZE); 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; uart0_handler_pid = pid;
puts("uart0_init() [OK]"); puts("uart0_init() [OK]");
} }
void uart0_handle_incoming(int c) { void uart0_handle_incoming(int c)
{
rb_add_element(&uart0_ringbuffer, c); rb_add_element(&uart0_ringbuffer, c);
} }
void uart0_notify_thread(void) { void uart0_notify_thread(void)
{
msg_t m; msg_t m;
m.type = 0; m.type = 0;
msg_send_int(&m, uart0_handler_pid); msg_send_int(&m, uart0_handler_pid);
} }
int uart0_readc(void) { int uart0_readc(void)
{
char c = 0; char c = 0;
posix_read(uart0_handler_pid, &c, 1); posix_read(uart0_handler_pid, &c, 1);
return c; return c;
} }
void uart0_putc(int c) { void uart0_putc(int c)
{
putchar(c); putchar(c);
} }

View File

@ -27,7 +27,7 @@ static int set_longterm(vtimer_t *timer);
static int set_shortterm(vtimer_t *timer); static int set_shortterm(vtimer_t *timer);
#ifdef ENABLE_DEBUG #ifdef ENABLE_DEBUG
static void vtimer_print(vtimer_t* t); static void vtimer_print(vtimer_t *t);
#endif #endif
static queue_node_t longterm_queue_root; static queue_node_t longterm_queue_root;
@ -42,17 +42,20 @@ static uint32_t hwtimer_next_absolute;
static uint32_t seconds = 0; 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; 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; return 0;
} }
static int update_shortterm(void) { static int update_shortterm(void)
if (hwtimer_id != -1) { {
if (hwtimer_next_absolute != shortterm_queue_root.next->priority) { if(hwtimer_id != -1) {
if(hwtimer_next_absolute != shortterm_queue_root.next->priority) {
hwtimer_remove(hwtimer_id); hwtimer_remove(hwtimer_id);
} else { }
else {
return 0; return 0;
} }
} }
@ -62,7 +65,7 @@ static int update_shortterm(void) {
unsigned int next = hwtimer_next_absolute + longterm_tick_start; unsigned int next = hwtimer_next_absolute + longterm_tick_start;
unsigned int now = hwtimer_now(); 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; next = now + VTIMER_BACKOFF;
} }
@ -72,7 +75,8 @@ static int update_shortterm(void) {
return 0; return 0;
} }
void vtimer_tick(void *ptr) { void vtimer_tick(void *ptr)
{
DEBUG("vtimer_tick()."); DEBUG("vtimer_tick().");
seconds += SECONDS_PER_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; longterm_tick_timer.absolute.microseconds = longterm_tick_timer.absolute.microseconds + MICROSECONDS_PER_TICK;
set_shortterm(&longterm_tick_timer); set_shortterm(&longterm_tick_timer);
while (longterm_queue_root.next) { while(longterm_queue_root.next) {
vtimer_t *timer = (vtimer_t*) 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); if(timer->absolute.seconds == seconds) {
timer = (vtimer_t *) queue_remove_head(&longterm_queue_root);
set_shortterm(timer); set_shortterm(timer);
} else { }
else {
break; break;
} }
} }
@ -93,14 +99,16 @@ void vtimer_tick(void *ptr) {
update_shortterm(); 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); DEBUG("set_shortterm(): Absolute: %lu %lu\n", timer->absolute.seconds, timer->absolute.microseconds);
timer->queue_entry.priority = 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; return 1;
} }
void vtimer_callback(void *ptr) { void vtimer_callback(void *ptr)
{
vtimer_t *timer; vtimer_t *timer;
in_callback = true; in_callback = true;
hwtimer_id = -1; hwtimer_id = -1;
@ -113,12 +121,13 @@ void vtimer_callback(void *ptr) {
DEBUG("vtimer_callback(): Shooting %lu.\n", timer->absolute.microseconds); DEBUG("vtimer_callback(): Shooting %lu.\n", timer->absolute.microseconds);
/* shoot timer */ /* shoot timer */
if (timer->action == (void*) msg_send_int) { if(timer->action == (void *) msg_send_int) {
msg_t msg; msg_t msg;
msg.type = MSG_TIMER; msg.type = MSG_TIMER;
msg.content.value = (unsigned int) timer->arg; msg.content.value = (unsigned int) timer->arg;
msg_send_int(&msg, timer->pid); msg_send_int(&msg, timer->pid);
} else { }
else {
timer->action(timer->arg); timer->action(timer->arg);
} }
@ -126,25 +135,30 @@ void vtimer_callback(void *ptr) {
update_shortterm(); 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); DEBUG("Normalizing: %lu %lu\n", time->seconds, time->microseconds);
uint32_t seconds_tmp = time->seconds % SECONDS_PER_TICK; uint32_t seconds_tmp = time->seconds % SECONDS_PER_TICK;
time->seconds -= seconds_tmp; time->seconds -= seconds_tmp;
uint32_t usecs_tmp = time->microseconds + (seconds_tmp * 1000000); uint32_t usecs_tmp = time->microseconds + (seconds_tmp * 1000000);
DEBUG("Normalizin2: %lu %lu\n", time->seconds, usecs_tmp); DEBUG("Normalizin2: %lu %lu\n", time->seconds, usecs_tmp);
if (usecs_tmp < time->microseconds) {
if(usecs_tmp < time->microseconds) {
usecs_tmp -= MICROSECONDS_PER_TICK; usecs_tmp -= MICROSECONDS_PER_TICK;
time->seconds += SECONDS_PER_TICK; time->seconds += SECONDS_PER_TICK;
} }
if (usecs_tmp > MICROSECONDS_PER_TICK) {
if(usecs_tmp > MICROSECONDS_PER_TICK) {
usecs_tmp -= MICROSECONDS_PER_TICK; usecs_tmp -= MICROSECONDS_PER_TICK;
time->seconds += SECONDS_PER_TICK; time->seconds += SECONDS_PER_TICK;
} }
time->microseconds = usecs_tmp; time->microseconds = usecs_tmp;
DEBUG(" Result: %lu %lu\n", time->seconds, time->microseconds); 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); DEBUG("vtimer_set(): New timer. Offset: %lu %lu\n", timer->absolute.seconds, timer->absolute.microseconds);
timex_t now; timex_t now;
@ -156,26 +170,28 @@ static int vtimer_set(vtimer_t *timer) {
int result = 0; int result = 0;
if (timer->absolute.seconds == 0) { if(timer->absolute.seconds == 0) {
if (timer->absolute.microseconds > 10) { if(timer->absolute.microseconds > 10) {
timer->absolute.microseconds -= 10; timer->absolute.microseconds -= 10;
} }
} }
int state = disableIRQ(); int state = disableIRQ();
if (timer->absolute.seconds != seconds){
if(timer->absolute.seconds != seconds) {
/* we're long-term */ /* we're long-term */
DEBUG("vtimer_set(): setting long_term\n"); DEBUG("vtimer_set(): setting long_term\n");
result = set_longterm(timer); result = set_longterm(timer);
} }
else { else {
DEBUG("vtimer_set(): setting short_term\n"); DEBUG("vtimer_set(): setting short_term\n");
if (set_shortterm(timer)) {
if(set_shortterm(timer)) {
/* delay update of next shortterm timer if we /* delay update of next shortterm timer if we
* are called from within vtimer_callback. */ * are called from within vtimer_callback. */
if (!in_callback) { if(!in_callback) {
result = update_shortterm(); result = update_shortterm();
} }
} }
@ -187,12 +203,14 @@ static int vtimer_set(vtimer_t *timer) {
return result; return result;
} }
void vtimer_now(timex_t* out) { void vtimer_now(timex_t *out)
timex_t t = timex_set(seconds, hwtimer_now()-longterm_tick_start); {
timex_t t = timex_set(seconds, hwtimer_now() - longterm_tick_start);
memcpy(out, &t, sizeof(timex_t)); memcpy(out, &t, sizeof(timex_t));
} }
int vtimer_init() { int vtimer_init()
{
DEBUG("vtimer_init().\n"); DEBUG("vtimer_init().\n");
int state = disableIRQ(); int state = disableIRQ();
seconds = 0; seconds = 0;
@ -212,22 +230,25 @@ int vtimer_init() {
return 0; 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; int ret;
t->action = (void*) thread_wakeup; t->action = (void *) thread_wakeup;
t->arg = (void*) pid; t->arg = (void *) pid;
t->absolute = interval; t->absolute = interval;
t->pid = 0; t->pid = 0;
ret = vtimer_set(t); ret = vtimer_set(t);
return ret; return ret;
} }
int vtimer_usleep(uint32_t usecs) { int vtimer_usleep(uint32_t usecs)
{
timex_t offset = timex_set(0, usecs); timex_t offset = timex_set(0, usecs);
return vtimer_sleep(offset); return vtimer_sleep(offset);
} }
int vtimer_sleep(timex_t time) { int vtimer_sleep(timex_t time)
{
int ret; int ret;
vtimer_t t; vtimer_t t;
ret = vtimer_set_wakeup(&t, time, thread_getpid()); ret = vtimer_set_wakeup(&t, time, thread_getpid());
@ -235,18 +256,23 @@ int vtimer_sleep(timex_t time) {
return ret; return ret;
} }
int vtimer_remove(vtimer_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); queue_remove(&shortterm_queue_root, (queue_node_t *)t);
queue_remove(&longterm_queue_root, (queue_node_t *)t);
update_shortterm(); update_shortterm();
if (! inISR() ) eINT(); if(! inISR()) {
eINT();
}
return 0; return 0;
} }
int vtimer_set_msg(vtimer_t *t, timex_t interval, unsigned int pid, void *ptr){ int vtimer_set_msg(vtimer_t *t, timex_t interval, unsigned int pid, void *ptr)
t->action = (void* ) msg_send_int; {
t->action = (void *) msg_send_int;
t->arg = ptr; t->arg = ptr;
t->absolute = interval; t->absolute = interval;
t->pid = pid; t->pid = pid;
@ -254,7 +280,8 @@ int vtimer_set_msg(vtimer_t *t, timex_t interval, unsigned int pid, void *ptr){
return 0; return 0;
} }
void vtimer_print(vtimer_t* t) { void vtimer_print(vtimer_t *t)
{
printf("Seconds: %u - Microseconds: %u\n \ printf("Seconds: %u - Microseconds: %u\n \
action: %p\n \ action: %p\n \
action: %p\n \ action: %p\n \