mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
coding conventions for most of system libraries
This commit is contained in:
parent
f359453083
commit
5c52e1ce2e
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Auto initialization for used modules
|
||||
* Auto initialization for used modules
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
@ -27,7 +27,8 @@
|
||||
|
||||
extern int main(void);
|
||||
|
||||
void auto_init(void) {
|
||||
void auto_init(void)
|
||||
{
|
||||
#ifdef MODULE_BOARD_DISPLAY
|
||||
extern void lcd_init();
|
||||
lcd_init();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Character device messaging loop.
|
||||
* Character device messaging loop.
|
||||
*
|
||||
* Copyright (C) 2013, INRIA.
|
||||
*
|
||||
@ -28,12 +28,18 @@
|
||||
//#define ENABLE_DEBUG
|
||||
#include <debug.h>
|
||||
|
||||
static int min(int a, int b) {
|
||||
if (b>a) return a;
|
||||
else return b;
|
||||
static int min(int a, int b)
|
||||
{
|
||||
if(b > a) {
|
||||
return a;
|
||||
}
|
||||
else {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
|
||||
void chardev_loop(ringbuffer_t *rb) {
|
||||
void chardev_loop(ringbuffer_t *rb)
|
||||
{
|
||||
msg_t m;
|
||||
|
||||
int pid = thread_getpid();
|
||||
@ -43,14 +49,15 @@ void chardev_loop(ringbuffer_t *rb) {
|
||||
|
||||
puts("UART0 thread started.");
|
||||
|
||||
while (1) {
|
||||
while(1) {
|
||||
msg_receive(&m);
|
||||
|
||||
if (m.sender_pid != pid) {
|
||||
if(m.sender_pid != pid) {
|
||||
DEBUG("Receiving message from another thread\n");
|
||||
switch (m.type) {
|
||||
|
||||
switch(m.type) {
|
||||
case OPEN:
|
||||
if (reader_pid == -1) {
|
||||
if(reader_pid == -1) {
|
||||
reader_pid = m.sender_pid;
|
||||
/* no error */
|
||||
m.content.value = 0;
|
||||
@ -58,10 +65,12 @@ void chardev_loop(ringbuffer_t *rb) {
|
||||
else {
|
||||
m.content.value = -EBUSY;
|
||||
}
|
||||
msg_reply(&m,&m);
|
||||
|
||||
msg_reply(&m, &m);
|
||||
break;
|
||||
|
||||
case READ:
|
||||
if (m.sender_pid != reader_pid) {
|
||||
if(m.sender_pid != reader_pid) {
|
||||
m.content.value = -EINVAL;
|
||||
r = NULL;
|
||||
msg_reply(&m, &m);
|
||||
@ -69,9 +78,11 @@ void chardev_loop(ringbuffer_t *rb) {
|
||||
else {
|
||||
r = (struct posix_iop_t *)m.content.ptr;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case CLOSE:
|
||||
if (m.sender_pid == reader_pid) {
|
||||
if(m.sender_pid == reader_pid) {
|
||||
DEBUG("uart0_thread: closing file from %i\n", reader_pid);
|
||||
reader_pid = -1;
|
||||
r = NULL;
|
||||
@ -80,15 +91,17 @@ void chardev_loop(ringbuffer_t *rb) {
|
||||
else {
|
||||
m.content.value = -EINVAL;
|
||||
}
|
||||
msg_reply(&m,&m);
|
||||
|
||||
msg_reply(&m, &m);
|
||||
break;
|
||||
|
||||
default:
|
||||
m.content.value = -EINVAL;
|
||||
msg_reply(&m, &m);
|
||||
}
|
||||
}
|
||||
|
||||
if (rb->avail && (r != NULL)) {
|
||||
if(rb->avail && (r != NULL)) {
|
||||
int state = disableIRQ();
|
||||
int nbytes = min(r->nbytes, rb->avail);
|
||||
DEBUG("uart0_thread [%i]: sending %i bytes received from %i to pid %i\n", pid, nbytes, m.sender_pid, reader_pid);
|
||||
@ -97,7 +110,7 @@ void chardev_loop(ringbuffer_t *rb) {
|
||||
|
||||
m.sender_pid = reader_pid;
|
||||
m.type = OPEN;
|
||||
m.content.ptr = (char*)r;
|
||||
m.content.ptr = (char *)r;
|
||||
|
||||
msg_reply(&m, &m);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* System wide configuration struct.
|
||||
* System wide configuration struct.
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
@ -10,7 +10,7 @@
|
||||
* @ingroup config
|
||||
* @{
|
||||
* @file config_c
|
||||
* @brief Provides system configuration struct with default values.
|
||||
* @brief Provides system configuration struct with default values.
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
|
@ -1,5 +1,5 @@
|
||||
#ifndef __BOARD_UART0_H
|
||||
#define __BOARD_UART0_H
|
||||
#define __BOARD_UART0_H
|
||||
|
||||
extern int uart0_handler_pid;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#ifndef __CHARDEV_THREAD_H
|
||||
#define __CHARDEV_THREAD_H
|
||||
#define __CHARDEV_THREAD_H
|
||||
|
||||
#include <ringbuffer.h>
|
||||
|
||||
|
@ -8,18 +8,18 @@ void print_success(void);
|
||||
void print_failed(void);
|
||||
void gpio_n_timer_init(void);
|
||||
void adjust_timer(void);
|
||||
static void ping_handler(void *payload, int payload_size,
|
||||
packet_info_t *packet_info);
|
||||
static void pong_handler(void *payload, int payload_size,
|
||||
packet_info_t *packet_info);
|
||||
static void ping_handler(void *payload, int payload_size,
|
||||
packet_info_t *packet_info);
|
||||
static void pong_handler(void *payload, int payload_size,
|
||||
packet_info_t *packet_info);
|
||||
void pong(uint16_t src);
|
||||
|
||||
typedef struct pong{
|
||||
int hopcount;
|
||||
int ttl;
|
||||
radio_address_t radio_address;
|
||||
typedef struct pong {
|
||||
int hopcount;
|
||||
int ttl;
|
||||
radio_address_t radio_address;
|
||||
} ping_r;
|
||||
|
||||
typedef struct ping_payload{
|
||||
char* payload;
|
||||
typedef struct ping_payload {
|
||||
char *payload;
|
||||
} ping_payload;
|
||||
|
@ -1,5 +1,5 @@
|
||||
#ifndef __READ_H
|
||||
#define __READ_H
|
||||
#define __READ_H
|
||||
|
||||
#define OPEN 0
|
||||
#define CLOSE 1
|
||||
@ -12,8 +12,8 @@ struct posix_iop_t {
|
||||
};
|
||||
|
||||
int posix_open(int pid, int flags);
|
||||
int posix_close(int pid);
|
||||
int posix_read(int pid, char* buffer, int bufsize);
|
||||
int posix_write(int pid, char* buffer, int bufsize);
|
||||
int posix_close(int pid);
|
||||
int posix_read(int pid, char *buffer, int bufsize);
|
||||
int posix_write(int pid, char *buffer, int bufsize);
|
||||
|
||||
#endif /* __READ_H */
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef __PS_H
|
||||
#define __PS_H
|
||||
#define __PS_H
|
||||
|
||||
void thread_print_all(void);
|
||||
void _ps_handler(char*);
|
||||
void _ps_handler(char *);
|
||||
|
||||
#endif /* __PS_H */
|
||||
|
@ -1,28 +1,14 @@
|
||||
/******************************************************************************
|
||||
Copyright 2008-2009 , Freie Universitaet Berlin (FUB). All rights reserved.
|
||||
|
||||
These sources were developed at the Freie Universitaet Berlin, Computer Systems
|
||||
and Telematics group (http://cst.mi.fu-berlin.de).
|
||||
-------------------------------------------------------------------------------
|
||||
This file is part of RIOT.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
RIOT is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see http://www.gnu.org/licenses/ .
|
||||
--------------------------------------------------------------------------------
|
||||
For further information and questions please use the web site
|
||||
http://scatterweb.mi.fu-berlin.de
|
||||
and the mailinglist (subscription via web site)
|
||||
scatterweb@lists.spline.inf.fu-berlin.de
|
||||
*******************************************************************************/
|
||||
/**
|
||||
* Generic radio driver interface
|
||||
*
|
||||
* Copyright (C) 2008-2009 Freie Universitaet Berlin (FUB).
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef RADIO_H_
|
||||
#define RADIO_H_
|
||||
@ -58,41 +44,40 @@ and the mailinglist (subscription via web site)
|
||||
|
||||
#define L1_PROTOCOL_CATCH_ALL (0xff) ///< Catch all protocol ID
|
||||
|
||||
enum layer_1_protocols
|
||||
{
|
||||
LAYER_1_PROTOCOL_LL_ACK = 1, ///< Link-Level Acknowledgement (LL-ACK)
|
||||
LAYER_1_PROTOCOL_MM = 2, ///< Micro Mesh network packet (MM)
|
||||
enum layer_1_protocols {
|
||||
LAYER_1_PROTOCOL_LL_ACK = 1, ///< Link-Level Acknowledgement (LL-ACK)
|
||||
LAYER_1_PROTOCOL_MM = 2, ///< Micro Mesh network packet (MM)
|
||||
};
|
||||
|
||||
/**
|
||||
* Radio/MAC API.
|
||||
*/
|
||||
typedef struct radio {
|
||||
const char* name;
|
||||
const radio_address_t broadcast_address;
|
||||
const uint8_t output_power_max;
|
||||
/**
|
||||
* @return the average transmission duration of one packet
|
||||
* in milliseconds, e.g. till ACK received.
|
||||
*/
|
||||
int (*get_avg_transmission_duration)(void);
|
||||
radio_address_t (*get_address)(void);
|
||||
bool (*set_address)(radio_address_t address);
|
||||
bool (*set_output_power)(uint8_t pa_idx);
|
||||
bool (*set_packet_monitor)(packet_monitor_t monitor);
|
||||
/**
|
||||
* @return -1 if an error occurs (e.g. handler table full) else >= 0.
|
||||
*/
|
||||
int (*set_packet_handler)(protocol_t protocol, packet_handler_t handler);
|
||||
/**
|
||||
* @return A negative value if operation failed; else the number of transmitted bytes.
|
||||
*/
|
||||
int (*send)(radio_address_t address, protocol_t protocol, int priority, char *payload, int payload_len);
|
||||
void (*print_stats)(void);
|
||||
void (*print_config)(void);
|
||||
typedef struct {
|
||||
const char *name;
|
||||
const radio_address_t broadcast_address;
|
||||
const uint8_t output_power_max;
|
||||
/**
|
||||
* @return the average transmission duration of one packet
|
||||
* in milliseconds, e.g. till ACK received.
|
||||
*/
|
||||
int (*get_avg_transmission_duration)(void);
|
||||
radio_address_t (*get_address)(void);
|
||||
bool (*set_address)(radio_address_t address);
|
||||
bool (*set_output_power)(uint8_t pa_idx);
|
||||
bool (*set_packet_monitor)(packet_monitor_t monitor);
|
||||
/**
|
||||
* @return -1 if an error occurs (e.g. handler table full) else >= 0.
|
||||
*/
|
||||
int (*set_packet_handler)(protocol_t protocol, packet_handler_t handler);
|
||||
/**
|
||||
* @return A negative value if operation failed; else the number of transmitted bytes.
|
||||
*/
|
||||
int (*send)(radio_address_t address, protocol_t protocol, int priority, char *payload, int payload_len);
|
||||
void (*print_stats)(void);
|
||||
void (*print_config)(void);
|
||||
} radio_t;
|
||||
|
||||
extern const struct radio* feuerware_radios[FEUERWARE_CONF_NUM_RADIOS];
|
||||
extern const struct radio *feuerware_radios[FEUERWARE_CONF_NUM_RADIOS];
|
||||
|
||||
/** @} */
|
||||
|
||||
|
@ -1,28 +1,14 @@
|
||||
/******************************************************************************
|
||||
Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved.
|
||||
|
||||
These sources were developed at the Freie Universitaet Berlin, Computer Systems
|
||||
and Telematics group (http://cst.mi.fu-berlin.de).
|
||||
-------------------------------------------------------------------------------
|
||||
This file is part of RIOT.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
RIOT is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see http://www.gnu.org/licenses/ .
|
||||
--------------------------------------------------------------------------------
|
||||
For further information and questions please use the web site
|
||||
http://scatterweb.mi.fu-berlin.de
|
||||
and the mailinglist (subscription via web site)
|
||||
scatterweb@lists.spline.inf.fu-berlin.de
|
||||
*******************************************************************************/
|
||||
/**
|
||||
* Generic radio driver interface data structures and prototypes
|
||||
*
|
||||
* Copyright (C) 2009 Freie Universitaet Berlin (FUB).
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef COMMONTYPES_H_
|
||||
#define COMMONTYPES_H_
|
||||
@ -33,6 +19,7 @@ and the mailinglist (subscription via web site)
|
||||
*
|
||||
* @author Freie Universität Berlin, Computer Systems & Telematics
|
||||
* @author Thomas Hillebrandt <hillebra@inf.fu-berlin.de>
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
* @version $Revision: 2061 $
|
||||
*
|
||||
* @note $Id: common-types.h 2061 2010-04-01 12:13:22Z hillebra $
|
||||
@ -50,11 +37,10 @@ typedef uint16_t radio_address_t; ///< Radio layer address type
|
||||
/**
|
||||
* @brief Packet transmission priorities of various layers.
|
||||
*/
|
||||
enum transmission_priorities
|
||||
{
|
||||
PRIORITY_ALARM = 0,
|
||||
PRIORITY_WARNING = 1,
|
||||
PRIORITY_DATA = 2
|
||||
enum transmission_priorities {
|
||||
PRIORITY_ALARM = 0,
|
||||
PRIORITY_WARNING = 1,
|
||||
PRIORITY_DATA = 2
|
||||
};
|
||||
|
||||
/**
|
||||
@ -62,23 +48,23 @@ enum transmission_priorities
|
||||
* This struct is passed along all receive functions of
|
||||
* all layers. Each layers fills in additional information.
|
||||
*/
|
||||
typedef struct __attribute__ ((packed)) packet_info_t
|
||||
{
|
||||
uint16_t source; ///< Net layer: source
|
||||
uint16_t destination; ///< Net layer: destination
|
||||
radio_address_t phy_src; ///< Radio layer: source
|
||||
uint8_t rssi; ///< Radio layer: RSSI
|
||||
uint8_t lqi; ///< Radio layer: LQI
|
||||
uint8_t ttl; ///< Net layer: TTL
|
||||
uint8_t tos; ///< Net layer: TOS
|
||||
bool promiscuous; ///< Radio layer: whether network interface is in promiscuous mode
|
||||
typedef struct __attribute__((packed)) packet_info_t {
|
||||
uint16_t source; ///< Net layer: source
|
||||
uint16_t destination; ///< Net layer: destination
|
||||
radio_address_t phy_src; ///< Radio layer: source
|
||||
uint8_t rssi; ///< Radio layer: RSSI
|
||||
uint8_t lqi; ///< Radio layer: LQI
|
||||
uint8_t ttl; ///< Net layer: TTL
|
||||
uint8_t tos; ///< Net layer: TOS
|
||||
bool promiscuous; ///< Radio layer: whether network interface is in promiscuous mode
|
||||
} packet_info_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief General link layer packet format
|
||||
*/
|
||||
typedef struct __attribute__ ((packed)) {
|
||||
typedef struct __attribute__((packed))
|
||||
{
|
||||
uint8_t processing; ///< internal processing state
|
||||
uint16_t src; ///< Radio source address
|
||||
uint16_t dst; ///< Radio destination address
|
||||
@ -87,7 +73,8 @@ typedef struct __attribute__ ((packed)) {
|
||||
timex_t toa; ///< Time of Arrival
|
||||
uint8_t length; ///< Length of payload
|
||||
uint8_t *data; ///< Payload
|
||||
} radio_packet_t;
|
||||
}
|
||||
radio_packet_t;
|
||||
|
||||
|
||||
/**
|
||||
@ -96,7 +83,7 @@ typedef struct __attribute__ ((packed)) {
|
||||
* @param [in] payload_size Size of the packet payload data in bytes
|
||||
* @param [in/out] packet_info Cross-layer meta data
|
||||
*/
|
||||
typedef void (*packet_handler_t)(void* payload, int payload_size, packet_info_t* packet_info);
|
||||
typedef void (*packet_handler_t)(void *payload, int payload_size, packet_info_t *packet_info);
|
||||
|
||||
/**
|
||||
* Packet monitor of all layers. Normally there can be one packet
|
||||
@ -107,6 +94,6 @@ typedef void (*packet_handler_t)(void* payload, int payload_size, packet_info_t*
|
||||
* @param protocol Protocol type of the packet payload data
|
||||
* @param packet_info Cross-layer meta data
|
||||
*/
|
||||
typedef void (*packet_monitor_t)(void* payload, int payload_size, protocol_t protocol, packet_info_t* packet_info);
|
||||
typedef void (*packet_monitor_t)(void *payload, int payload_size, protocol_t protocol, packet_info_t *packet_info);
|
||||
|
||||
#endif /* COMMONTYPES_H_ */
|
||||
|
@ -25,7 +25,7 @@ and the mailinglist (subscription via web site)
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef __SHELL_H
|
||||
#define __SHELL_H
|
||||
#define __SHELL_H
|
||||
|
||||
/**
|
||||
* @defgroup shell Simple Shell Interpreter
|
||||
@ -35,15 +35,15 @@ and the mailinglist (subscription via web site)
|
||||
//#include "hashtable.h"
|
||||
|
||||
typedef struct shell_command_t {
|
||||
char* name;
|
||||
char* desc;
|
||||
void (*handler)(char*);
|
||||
char *name;
|
||||
char *desc;
|
||||
void (*handler)(char *);
|
||||
} shell_command_t;
|
||||
|
||||
typedef struct shell_t {
|
||||
const shell_command_t *command_list;
|
||||
int (*readchar)(void);
|
||||
void (*put_char)(int);
|
||||
int (*readchar)(void);
|
||||
void (*put_char)(int);
|
||||
} shell_t;
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
#ifndef __SHELL_COMMANDS_H
|
||||
#define __SHELL_COMMANDS_H
|
||||
#define __SHELL_COMMANDS_H
|
||||
|
||||
#include <shell.h>
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#ifndef __TIMEX_H
|
||||
#define __TIMEX_H
|
||||
#define __TIMEX_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
@ -9,7 +9,7 @@ typedef struct timex_t {
|
||||
} timex_t;
|
||||
|
||||
/* a+b */
|
||||
timex_t timex_add(const timex_t a, const timex_t b);
|
||||
timex_t timex_add(const timex_t a, const timex_t b);
|
||||
|
||||
/* a-b*/
|
||||
timex_t timex_sub(const timex_t a, const timex_t b);
|
||||
|
@ -1,5 +1,5 @@
|
||||
#ifndef TRANSCEIVER_H
|
||||
#define TRANSCEIVER_H
|
||||
#define TRANSCEIVER_H
|
||||
|
||||
#include <radio/types.h>
|
||||
|
||||
@ -84,7 +84,7 @@ typedef struct {
|
||||
extern int transceiver_pid;
|
||||
|
||||
/**
|
||||
* @brief Initializes the transceiver module for certain transceiver types
|
||||
* @brief Initializes the transceiver module for certain transceiver types
|
||||
*
|
||||
* @param transceivers Specifies all transceivers to init
|
||||
**/
|
||||
|
@ -17,7 +17,7 @@
|
||||
* Timer library header file.
|
||||
*/
|
||||
#ifndef __VTIMER_H
|
||||
#define __VTIMER_H
|
||||
#define __VTIMER_H
|
||||
|
||||
#include "queue.h"
|
||||
#include "timex.h"
|
||||
@ -34,8 +34,8 @@
|
||||
typedef struct vtimer_t {
|
||||
queue_node_t queue_entry;
|
||||
timex_t absolute;
|
||||
void(*action)(void*);
|
||||
void* arg;
|
||||
void(*action)(void *);
|
||||
void *arg;
|
||||
unsigned int pid;
|
||||
} vtimer_t;
|
||||
|
||||
@ -43,7 +43,7 @@ typedef struct vtimer_t {
|
||||
* @brief Current system time
|
||||
* @return Time as timex_t since system boot
|
||||
*/
|
||||
void vtimer_now(timex_t* out);
|
||||
void vtimer_now(timex_t *out);
|
||||
|
||||
/**
|
||||
* @brief Initializes the vtimer subsystem. To be called once at system initialization. Will be initialized by auto_init.
|
||||
@ -54,7 +54,7 @@ int vtimer_init(void);
|
||||
|
||||
/**
|
||||
* @brief will cause the calling thread to be suspended from excecution until the number of microseconds has elapsed
|
||||
* @param[in] us number of microseconds
|
||||
* @param[in] us number of microseconds
|
||||
* @return 0 on success, < 0 on error
|
||||
*/
|
||||
int vtimer_usleep(uint32_t us);
|
||||
@ -94,6 +94,6 @@ int vtimer_remove(vtimer_t *t);
|
||||
/**
|
||||
* @brief Prints a vtimer_t
|
||||
*/
|
||||
void vtimer_print(vtimer_t* t);
|
||||
void vtimer_print(vtimer_t *t);
|
||||
|
||||
#endif /* __VTIMER_H */
|
||||
|
1184
sys/net/mm/mmr.c
1184
sys/net/mm/mmr.c
File diff suppressed because it is too large
Load Diff
@ -60,13 +60,12 @@ and the mailinglist (subscription via web site)
|
||||
* | Source | Address[1..n] |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
typedef struct __attribute__ ((packed)) mmr_rreq_message_t
|
||||
{
|
||||
uint8_t type; ///< Must be first byte in struct for type detection
|
||||
uint8_t length;
|
||||
uint16_t destination;
|
||||
uint16_t source;
|
||||
uint16_t address[ADDRESS_LIST_SIZE];
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t type; ///< Must be first byte in struct for type detection
|
||||
uint8_t length;
|
||||
uint16_t destination;
|
||||
uint16_t source;
|
||||
uint16_t address[ADDRESS_LIST_SIZE];
|
||||
} mmr_rreq_message_t;
|
||||
|
||||
/**
|
||||
@ -80,13 +79,12 @@ typedef struct __attribute__ ((packed)) mmr_rreq_message_t
|
||||
* | Source | Address[1..n] |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
typedef struct __attribute__ ((packed)) mmr_rrep_message_t
|
||||
{
|
||||
uint8_t type; ///< Must be first byte in struct for type detection
|
||||
uint8_t length;
|
||||
uint16_t destination;
|
||||
uint16_t source;
|
||||
uint16_t address[ADDRESS_LIST_SIZE];
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t type; ///< Must be first byte in struct for type detection
|
||||
uint8_t length;
|
||||
uint16_t destination;
|
||||
uint16_t source;
|
||||
uint16_t address[ADDRESS_LIST_SIZE];
|
||||
} mmr_rrep_message_t;
|
||||
|
||||
/**
|
||||
@ -111,11 +109,10 @@ typedef struct __attribute__ ((packed)) mmr_rrep_message_t
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*
|
||||
*/
|
||||
typedef struct __attribute__ ((packed)) mmr_rerr_message_t
|
||||
{
|
||||
uint8_t type; ///< Must be first byte in struct for type detection
|
||||
uint8_t error_type;
|
||||
uint16_t type_specific_info;
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t type; ///< Must be first byte in struct for type detection
|
||||
uint8_t error_type;
|
||||
uint16_t type_specific_info;
|
||||
} mmr_rerr_message_t;
|
||||
|
||||
/**
|
||||
@ -131,7 +128,7 @@ void mmr_init(void);
|
||||
* @param message incoming packet
|
||||
* @param packet_info Additional packet information
|
||||
*/
|
||||
void mmr_peek(net_message_t* message, packet_info_t* packet_info);
|
||||
void mmr_peek(net_message_t *message, packet_info_t *packet_info);
|
||||
|
||||
/**
|
||||
* Called by the network layer to request transmission of a packet that
|
||||
@ -145,7 +142,7 @@ void mmr_peek(net_message_t* message, packet_info_t* packet_info);
|
||||
* @return true if packet was successfully stored for transmission; false otherwise
|
||||
* (e.g. message queue full).
|
||||
*/
|
||||
bool mmr_send(net_message_t* message);
|
||||
bool mmr_send(net_message_t *message);
|
||||
|
||||
/**
|
||||
* Called by the network layer which forwards notifications of dropped packets
|
||||
@ -155,7 +152,7 @@ bool mmr_send(net_message_t* message);
|
||||
* @param next_hop next hop network address of dropped packet (can be undefined)
|
||||
* @param error Error type which informs about reason
|
||||
*/
|
||||
void mmr_packet_dropped(net_message_t* message, uint16_t next_hop, int error);
|
||||
void mmr_packet_dropped(net_message_t *message, uint16_t next_hop, int error);
|
||||
|
||||
/**
|
||||
* @brief Receive a message from network layer.
|
||||
@ -164,7 +161,7 @@ void mmr_packet_dropped(net_message_t* message, uint16_t next_hop, int error);
|
||||
* @param msg_size Size of received message
|
||||
* @param packet_info Additional packet information
|
||||
*/
|
||||
void mmr_receive(void* msg, int msg_size, packet_info_t* packet_info);
|
||||
void mmr_receive(void *msg, int msg_size, packet_info_t *packet_info);
|
||||
|
||||
/**
|
||||
* @brief Print routing layer statistics.
|
||||
|
1058
sys/net/mm/mmstack.c
1058
sys/net/mm/mmstack.c
File diff suppressed because it is too large
Load Diff
@ -59,7 +59,7 @@ void mms_init(void);
|
||||
* @param rp Routing protocol type identifier.
|
||||
* @param ri Pointer to route interface.
|
||||
*/
|
||||
void mms_initp(protocol_t rp, route_interface_t* ri);
|
||||
void mms_initp(protocol_t rp, route_interface_t *ri);
|
||||
|
||||
/**
|
||||
* @brief Add network interface.
|
||||
@ -70,7 +70,7 @@ void mms_initp(protocol_t rp, route_interface_t* ri);
|
||||
*
|
||||
* @return Interface identifier or -1 if an error occurs.
|
||||
*/
|
||||
int mms_add_interface(const char* name, uint16_t addr, const radio_t* radio);
|
||||
int mms_add_interface(const char *name, uint16_t addr, const radio_t *radio);
|
||||
|
||||
/**
|
||||
* @brief Get the address of the network interface with given id.
|
||||
@ -129,12 +129,14 @@ int mms_connect(int socket, uint16_t dest_addr);
|
||||
/**
|
||||
* @see ::trans_send(int,void*,int,protocol_t,uint8_t)
|
||||
*/
|
||||
int mms_sock_send(int socket, void* buffer, int length, protocol_t protocol, uint8_t priority);
|
||||
int mms_sock_send(int socket, void *buffer, int length, protocol_t protocol,
|
||||
uint8_t priority);
|
||||
|
||||
/**
|
||||
* @see ::trans_sendto(int,void*,int,protocol_t,uint8_t,uint16_t)
|
||||
*/
|
||||
int mms_sock_sendto(int socket, void* buffer, int length, protocol_t protocol, uint8_t priority, uint16_t dest_addr);
|
||||
int mms_sock_sendto(int socket, void *buffer, int length, protocol_t protocol,
|
||||
uint8_t priority, uint16_t dest_addr);
|
||||
|
||||
/**
|
||||
* @brief Convenience function to send a message via UDPL socket.
|
||||
@ -148,7 +150,8 @@ int mms_sock_sendto(int socket, void* buffer, int length, protocol_t protocol, u
|
||||
* @return Upon successful completion, mms_send() returns a value greater zero.
|
||||
* Otherwise, a negative value is returned to indicate the error.
|
||||
*/
|
||||
int mms_send(void* msg, int msg_len, uint16_t dst, protocol_t protocol, uint8_t priority);
|
||||
int mms_send(void *msg, int msg_len, uint16_t dst, protocol_t protocol,
|
||||
uint8_t priority);
|
||||
|
||||
/**
|
||||
* @see ::trans_poll(int)
|
||||
@ -170,7 +173,7 @@ int mms_close(int socket, int how);
|
||||
* @param msg_size Size of incoming packet.
|
||||
* @param packet_info Additional packet information.
|
||||
*/
|
||||
void mms_receive(void* msg, int msg_size, packet_info_t* packet_info);
|
||||
void mms_receive(void *msg, int msg_size, packet_info_t *packet_info);
|
||||
|
||||
/**
|
||||
* @brief Flush kernel route table.
|
||||
@ -188,7 +191,7 @@ void mms_flush_routes(bool flush_static);
|
||||
*
|
||||
* @param format String that contains the text to be written to stdout.
|
||||
*/
|
||||
void mms_net_printf(const char * format);
|
||||
void mms_net_printf(const char *format);
|
||||
|
||||
/**
|
||||
* @brief Print kernel route table.
|
||||
|
@ -1,3 +1,21 @@
|
||||
/**
|
||||
* 6lowpan border router multiplexer
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file bordermultiplex.c
|
||||
* @brief multiplexiing border router information
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -16,158 +34,179 @@
|
||||
#define END_ESC 0xDC
|
||||
#define ESC_ESC 0xDD
|
||||
|
||||
void demultiplex(border_packet_t *packet, int len) {
|
||||
switch (packet->type) {
|
||||
case (BORDER_PACKET_RAW_TYPE):{
|
||||
fputs(((char *)packet) + sizeof (border_packet_t), stdin);
|
||||
void demultiplex(border_packet_t *packet, int len)
|
||||
{
|
||||
switch(packet->type) {
|
||||
case(BORDER_PACKET_RAW_TYPE): {
|
||||
fputs(((char *)packet) + sizeof(border_packet_t), stdin);
|
||||
break;
|
||||
}
|
||||
case (BORDER_PACKET_L3_TYPE):{
|
||||
|
||||
case(BORDER_PACKET_L3_TYPE): {
|
||||
border_l3_header_t *l3_header_buf = (border_l3_header_t *)packet;
|
||||
switch (l3_header_buf->ethertype) {
|
||||
case (BORDER_ETHERTYPE_IPV6):{
|
||||
struct ipv6_hdr_t *ipv6_buf = (struct ipv6_hdr_t *)(((unsigned char *)packet) + sizeof (border_l3_header_t));
|
||||
|
||||
switch(l3_header_buf->ethertype) {
|
||||
case(BORDER_ETHERTYPE_IPV6): {
|
||||
struct ipv6_hdr_t *ipv6_buf = (struct ipv6_hdr_t *)(((unsigned char *)packet) + sizeof(border_l3_header_t));
|
||||
border_send_ipv6_over_lowpan(ipv6_buf, 1, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
printf("ERROR: Unknown ethertype 0x%04x\n", l3_header_buf->ethertype);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case (BORDER_PACKET_CONF_TYPE):{
|
||||
|
||||
case(BORDER_PACKET_CONF_TYPE): {
|
||||
border_conf_header_t *conf_header_buf = (border_conf_header_t *)packet;
|
||||
switch (conf_header_buf->conftype) {
|
||||
case (BORDER_CONF_CONTEXT):{
|
||||
|
||||
switch(conf_header_buf->conftype) {
|
||||
case(BORDER_CONF_CONTEXT): {
|
||||
border_context_packet_t *context = (border_context_packet_t *)packet;
|
||||
ipv6_addr_t target_addr;
|
||||
ipv6_set_all_nds_mcast_addr(&target_addr);
|
||||
mutex_lock(&lowpan_context_mutex);
|
||||
lowpan_context_update(
|
||||
context->context.cid,
|
||||
&context->context.prefix,
|
||||
context->context.length,
|
||||
context->context.comp,
|
||||
context->context.lifetime
|
||||
);
|
||||
mutex_unlock(&lowpan_context_mutex,0);
|
||||
context->context.cid,
|
||||
&context->context.prefix,
|
||||
context->context.length,
|
||||
context->context.comp,
|
||||
context->context.lifetime
|
||||
);
|
||||
mutex_unlock(&lowpan_context_mutex, 0);
|
||||
abr_add_context(context->context.version, &abr_addr, context->context.cid);
|
||||
// Send router advertisement
|
||||
/* Send router advertisement */
|
||||
break;
|
||||
}
|
||||
case (BORDER_CONF_IPADDR):{
|
||||
|
||||
case(BORDER_CONF_IPADDR): {
|
||||
//border_addr_packet_t *addr_packet = (border_addr_packet_t *)packet;
|
||||
// add address
|
||||
/* add address */
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
printf("ERROR: Unknown conftype %02x\n", conf_header_buf->conftype);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
printf("ERROR: Unknown border packet type %02x\n", packet->type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void multiplex_send_ipv6_over_uart(struct ipv6_hdr_t *packet) {
|
||||
void multiplex_send_ipv6_over_uart(struct ipv6_hdr_t *packet)
|
||||
{
|
||||
border_l3_header_t *serial_buf;
|
||||
|
||||
|
||||
serial_buf = (border_l3_header_t *)get_serial_out_buffer(0);
|
||||
serial_buf->empty = 0;
|
||||
serial_buf->type = BORDER_PACKET_L3_TYPE;
|
||||
serial_buf->ethertype = BORDER_ETHERTYPE_IPV6;
|
||||
memcpy(get_serial_in_buffer(0)+sizeof (border_l3_header_t), packet, IPV6_HDR_LEN + packet->length);
|
||||
|
||||
flowcontrol_send_over_uart((border_packet_t *) serial_buf, sizeof (border_l3_header_t));
|
||||
memcpy(get_serial_in_buffer(0) + sizeof(border_l3_header_t), packet, IPV6_HDR_LEN + packet->length);
|
||||
|
||||
flowcontrol_send_over_uart((border_packet_t *) serial_buf, sizeof(border_l3_header_t));
|
||||
}
|
||||
|
||||
void multiplex_send_addr_over_uart(ipv6_addr_t *addr) {
|
||||
void multiplex_send_addr_over_uart(ipv6_addr_t *addr)
|
||||
{
|
||||
border_addr_packet_t *serial_buf;
|
||||
|
||||
|
||||
serial_buf = (border_addr_packet_t *)get_serial_in_buffer(0);
|
||||
serial_buf->empty = 0;
|
||||
serial_buf->type = BORDER_PACKET_CONF_TYPE;
|
||||
serial_buf->conftype = BORDER_CONF_IPADDR;
|
||||
memcpy(&serial_buf->addr, addr, sizeof(ipv6_addr_t));
|
||||
|
||||
flowcontrol_send_over_uart((border_packet_t *) serial_buf, sizeof (border_addr_packet_t));
|
||||
|
||||
flowcontrol_send_over_uart((border_packet_t *) serial_buf, sizeof(border_addr_packet_t));
|
||||
}
|
||||
|
||||
int readpacket(uint8_t *packet_buf, size_t size) {
|
||||
int readpacket(uint8_t *packet_buf, size_t size)
|
||||
{
|
||||
uint8_t *line_buf_ptr = packet_buf;
|
||||
uint8_t byte = END+1;
|
||||
uint8_t byte = END + 1;
|
||||
uint8_t esc = 0;
|
||||
|
||||
while (1) {
|
||||
|
||||
while(1) {
|
||||
byte = uart0_readc();
|
||||
|
||||
if (byte == END) {
|
||||
|
||||
if(byte == END) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ( (line_buf_ptr - packet_buf) >= size-1) {
|
||||
|
||||
if((line_buf_ptr - packet_buf) >= size - 1) {
|
||||
return -SIXLOWERROR_ARRAYFULL;
|
||||
}
|
||||
|
||||
if (esc) {
|
||||
|
||||
if(esc) {
|
||||
esc = 0;
|
||||
switch (byte) {
|
||||
case(END_ESC):{
|
||||
|
||||
switch(byte) {
|
||||
case(END_ESC): {
|
||||
*line_buf_ptr++ = END;
|
||||
continue;
|
||||
}
|
||||
case(ESC_ESC):{
|
||||
|
||||
case(ESC_ESC): {
|
||||
*line_buf_ptr++ = ESC;
|
||||
continue;
|
||||
}
|
||||
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (byte == ESC) {
|
||||
|
||||
if(byte == ESC) {
|
||||
esc = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
*line_buf_ptr++ = byte;
|
||||
}
|
||||
|
||||
|
||||
return (line_buf_ptr - packet_buf - 1);
|
||||
}
|
||||
|
||||
int writepacket(uint8_t *packet_buf, size_t size) {
|
||||
int writepacket(uint8_t *packet_buf, size_t size)
|
||||
{
|
||||
uint8_t *byte_ptr = packet_buf;
|
||||
|
||||
while ((byte_ptr - packet_buf) < size) {
|
||||
if ((byte_ptr - packet_buf) > BORDER_BUFFER_SIZE) {
|
||||
|
||||
while((byte_ptr - packet_buf) < size) {
|
||||
if((byte_ptr - packet_buf) > BORDER_BUFFER_SIZE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (*byte_ptr) {
|
||||
case(END):{
|
||||
|
||||
switch(*byte_ptr) {
|
||||
case(END): {
|
||||
*byte_ptr = END_ESC;
|
||||
uart0_putc(ESC);
|
||||
break;
|
||||
}
|
||||
case(ESC):{
|
||||
|
||||
case(ESC): {
|
||||
*byte_ptr = ESC_ESC;
|
||||
uart0_putc(ESC);
|
||||
break;
|
||||
}
|
||||
default:{
|
||||
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uart0_putc(*byte_ptr);
|
||||
byte_ptr++;
|
||||
}
|
||||
|
||||
|
||||
uart0_putc(END);
|
||||
|
||||
|
||||
return (byte_ptr - packet_buf);
|
||||
}
|
||||
|
@ -1,3 +1,21 @@
|
||||
/**
|
||||
* 6lowpan border router multiplexer
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file bordermultiplex.h
|
||||
* @brief data structs for border router multiplexing
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef BORDERMULTIPLEX_H
|
||||
#define BORDERMULTIPLEX_H
|
||||
|
||||
@ -18,27 +36,27 @@
|
||||
/* ethertypes for L3 packets */
|
||||
#define BORDER_ETHERTYPE_IPV6 0x86DD
|
||||
|
||||
typedef struct __attribute__ ((packed)) border_packet_t {
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t empty;
|
||||
uint8_t type;
|
||||
uint8_t seq_num;
|
||||
} border_packet_t;
|
||||
|
||||
typedef struct __attribute__ ((packed)) border_l3_header_t {
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t empty;
|
||||
uint8_t type;
|
||||
uint8_t seq_num;
|
||||
uint16_t ethertype;
|
||||
} border_l3_header_t;
|
||||
|
||||
typedef struct __attribute__ ((packed)) border_conf_header_t {
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t empty;
|
||||
uint8_t type;
|
||||
uint8_t seq_num;
|
||||
uint8_t conftype;
|
||||
} border_conf_header_t;
|
||||
|
||||
typedef struct __attribute__ ((packed)) border_addr_packet_t {
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t empty;
|
||||
uint8_t type;
|
||||
uint8_t seq_num;
|
||||
@ -47,7 +65,7 @@ typedef struct __attribute__ ((packed)) border_addr_packet_t {
|
||||
ipv6_addr_t addr;
|
||||
} border_addr_packet_t;
|
||||
|
||||
typedef struct __attribute__ ((packed)) border_context_packet_t {
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t empty;
|
||||
uint8_t type;
|
||||
uint8_t seq_num;
|
||||
|
@ -1,3 +1,21 @@
|
||||
/**
|
||||
* 6lowpan border router flow control
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file flowcontrol.c
|
||||
* @brief flowcontrol for constraint node border router implementation
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -20,53 +38,59 @@ flowcontrol_stat_t slwin_stat;
|
||||
sem_t connection_established;
|
||||
int16_t synack_seqnum = -1;
|
||||
|
||||
ipv6_addr_t init_threeway_handshake(void) {
|
||||
ipv6_addr_t init_threeway_handshake(void)
|
||||
{
|
||||
border_syn_packet_t *syn;
|
||||
msg_t m;
|
||||
m.content.ptr = NULL;
|
||||
msg_send(&m,border_get_serial_reader(),1);
|
||||
msg_send(&m, border_get_serial_reader(), 1);
|
||||
msg_receive(&m);
|
||||
|
||||
|
||||
syn = (border_syn_packet_t *)m.content.ptr;
|
||||
border_conf_header_t *synack = (border_conf_header_t *)get_serial_out_buffer(0);
|
||||
ipv6_addr_t addr;
|
||||
memcpy(&addr, &(syn->addr), sizeof (ipv6_addr_t));
|
||||
|
||||
memcpy(&addr, &(syn->addr), sizeof(ipv6_addr_t));
|
||||
|
||||
slwin_stat.next_exp = syn->next_seq_num;
|
||||
slwin_stat.last_frame = syn->next_exp - 1;
|
||||
slwin_stat.last_ack = slwin_stat.last_frame;
|
||||
|
||||
|
||||
synack->empty = 0;
|
||||
synack->type = BORDER_PACKET_CONF_TYPE;
|
||||
synack->conftype = BORDER_CONF_SYNACK;
|
||||
|
||||
sending_slot_pid = thread_create(sending_slot_stack, SENDING_SLOT_STACK_SIZE, PRIORITY_MAIN-1, CREATE_SLEEPING, sending_slot, "sending slot");
|
||||
flowcontrol_send_over_uart((border_packet_t *)synack, sizeof (border_conf_header_t));
|
||||
|
||||
|
||||
sending_slot_pid = thread_create(sending_slot_stack, SENDING_SLOT_STACK_SIZE, PRIORITY_MAIN - 1, CREATE_SLEEPING, sending_slot, "sending slot");
|
||||
flowcontrol_send_over_uart((border_packet_t *)synack, sizeof(border_conf_header_t));
|
||||
|
||||
synack_seqnum = synack->seq_num;
|
||||
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
ipv6_addr_t flowcontrol_init(void) {
|
||||
ipv6_addr_t flowcontrol_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
sem_init(&slwin_stat.send_win_not_full,BORDER_SWS);
|
||||
|
||||
sem_init(&slwin_stat.send_win_not_full, BORDER_SWS);
|
||||
|
||||
for(i = 0; i < BORDER_SWS; i++) {
|
||||
slwin_stat.send_win[i].frame_len = 0;
|
||||
}
|
||||
memset(&slwin_stat.send_win,0, sizeof(struct send_slot) * BORDER_SWS);
|
||||
|
||||
|
||||
memset(&slwin_stat.send_win, 0, sizeof(struct send_slot) * BORDER_SWS);
|
||||
|
||||
for(i = 0; i < BORDER_RWS; i++) {
|
||||
slwin_stat.recv_win[i].received = 0;
|
||||
slwin_stat.recv_win[i].frame_len = 0;
|
||||
}
|
||||
memset(&slwin_stat.recv_win,0, sizeof(struct recv_slot) * BORDER_RWS);
|
||||
|
||||
|
||||
memset(&slwin_stat.recv_win, 0, sizeof(struct recv_slot) * BORDER_RWS);
|
||||
|
||||
return init_threeway_handshake();
|
||||
}
|
||||
|
||||
static void sending_slot(void) {
|
||||
static void sending_slot(void)
|
||||
{
|
||||
msg_t m;
|
||||
uint8_t seq_num;
|
||||
struct send_slot *slot;
|
||||
@ -76,93 +100,104 @@ static void sending_slot(void) {
|
||||
msg_receive(&m);
|
||||
seq_num = *((uint8_t *)m.content.ptr);
|
||||
slot = &(slwin_stat.send_win[seq_num % BORDER_SWS]);
|
||||
tmp = (border_packet_t*) slot->frame;
|
||||
tmp = (border_packet_t *)slot->frame;
|
||||
|
||||
if (seq_num == tmp->seq_num) {
|
||||
writepacket(slot->frame,slot->frame_len);
|
||||
|
||||
if (set_timeout(&slot->timeout, BORDER_SL_TIMEOUT, (void*) m.content.ptr) != 0) {
|
||||
if(seq_num == tmp->seq_num) {
|
||||
writepacket(slot->frame, slot->frame_len);
|
||||
|
||||
if(set_timeout(&slot->timeout, BORDER_SL_TIMEOUT, (void *)m.content.ptr) != 0) {
|
||||
printf("ERROR: Error invoking timeout timer\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int set_timeout(vtimer_t *timeout, long useconds, void *args) {
|
||||
static int set_timeout(vtimer_t *timeout, long useconds, void *args)
|
||||
{
|
||||
timex_t interval;
|
||||
interval.seconds = useconds / 1000000;
|
||||
interval.microseconds = (useconds % 1000000) * 1000;
|
||||
|
||||
|
||||
return vtimer_set_msg(timeout, interval, sending_slot_pid, args);
|
||||
}
|
||||
|
||||
static int in_window(uint8_t seq_num, uint8_t min, uint8_t max) {
|
||||
static int in_window(uint8_t seq_num, uint8_t min, uint8_t max)
|
||||
{
|
||||
uint8_t pos = seq_num - min;
|
||||
uint8_t maxpos = max - min + 1;
|
||||
return pos < maxpos;
|
||||
}
|
||||
|
||||
void flowcontrol_send_over_uart(border_packet_t *packet, int len) {
|
||||
void flowcontrol_send_over_uart(border_packet_t *packet, int len)
|
||||
{
|
||||
struct send_slot *slot;
|
||||
uint8_t args[] = {packet->seq_num};
|
||||
|
||||
|
||||
sem_wait(&(slwin_stat.send_win_not_full));
|
||||
packet->seq_num = ++slwin_stat.last_frame;
|
||||
slot = &(slwin_stat.send_win[packet->seq_num % BORDER_SWS]);
|
||||
memcpy(slot->frame, (uint8_t *)packet, len);
|
||||
slot->frame_len = len;
|
||||
if (set_timeout(&slot->timeout, BORDER_SL_TIMEOUT, (void *)args) != 0) {
|
||||
|
||||
if(set_timeout(&slot->timeout, BORDER_SL_TIMEOUT, (void *)args) != 0) {
|
||||
printf("ERROR: Error invoking timeout timer\n");
|
||||
return;
|
||||
}
|
||||
|
||||
writepacket((uint8_t *)packet, len);
|
||||
}
|
||||
|
||||
void send_ack(uint8_t seq_num) {
|
||||
void send_ack(uint8_t seq_num)
|
||||
{
|
||||
border_packet_t *packet = (border_packet_t *)get_serial_out_buffer(0);
|
||||
packet->empty = 0;
|
||||
packet->type = BORDER_PACKET_ACK_TYPE;
|
||||
packet->seq_num = seq_num;
|
||||
writepacket((uint8_t *)packet, sizeof (border_packet_t));
|
||||
writepacket((uint8_t *)packet, sizeof(border_packet_t));
|
||||
}
|
||||
|
||||
void flowcontrol_deliver_from_uart(border_packet_t *packet, int len) {
|
||||
if (packet->type == BORDER_PACKET_ACK_TYPE) {
|
||||
if (in_window(packet->seq_num, slwin_stat.last_ack+1, slwin_stat.last_frame)) {
|
||||
if (synack_seqnum == packet->seq_num) {
|
||||
void flowcontrol_deliver_from_uart(border_packet_t *packet, int len)
|
||||
{
|
||||
if(packet->type == BORDER_PACKET_ACK_TYPE) {
|
||||
if(in_window(packet->seq_num, slwin_stat.last_ack + 1, slwin_stat.last_frame)) {
|
||||
if(synack_seqnum == packet->seq_num) {
|
||||
synack_seqnum = -1;
|
||||
sem_signal(&connection_established);
|
||||
}
|
||||
|
||||
do {
|
||||
struct send_slot *slot;
|
||||
slot = &(slwin_stat.send_win[++slwin_stat.last_ack % BORDER_SWS]);
|
||||
vtimer_remove(&slot->timeout);
|
||||
memset(&slot->frame,0,BORDER_BUFFER_SIZE);
|
||||
memset(&slot->frame, 0, BORDER_BUFFER_SIZE);
|
||||
sem_signal(&slwin_stat.send_win_not_full);
|
||||
} while (slwin_stat.last_ack != packet->seq_num);
|
||||
}
|
||||
while(slwin_stat.last_ack != packet->seq_num);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
struct recv_slot *slot;
|
||||
|
||||
|
||||
slot = &(slwin_stat.recv_win[packet->seq_num % BORDER_RWS]);
|
||||
if ( !in_window(packet->seq_num,
|
||||
slwin_stat.next_exp,
|
||||
slwin_stat.next_exp + BORDER_RWS - 1)) {
|
||||
|
||||
if(!in_window(packet->seq_num,
|
||||
slwin_stat.next_exp,
|
||||
slwin_stat.next_exp + BORDER_RWS - 1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
memcpy(slot->frame, (uint8_t *)packet, len);
|
||||
slot->received = 1;
|
||||
|
||||
if (packet->seq_num == slwin_stat.next_exp) {
|
||||
while (slot->received) {
|
||||
|
||||
if(packet->seq_num == slwin_stat.next_exp) {
|
||||
while(slot->received) {
|
||||
demultiplex((border_packet_t *)slot->frame, slot->frame_len);
|
||||
memset(&slot->frame,0,BORDER_BUFFER_SIZE);
|
||||
memset(&slot->frame, 0, BORDER_BUFFER_SIZE);
|
||||
slot->received = 0;
|
||||
slot = &slwin_stat.recv_win[++(slwin_stat.next_exp) % BORDER_RWS];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
send_ack(slwin_stat.next_exp - 1);
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,21 @@
|
||||
/**
|
||||
* 6lowpan border router flow control
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file flowcontrol.h
|
||||
* @brief data structs for border router flowcontrol
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef FLOWCONTROL_H
|
||||
#define FLOWCONTROL_H
|
||||
|
||||
@ -22,17 +40,17 @@
|
||||
|
||||
#define SENDING_SLOT_STACK_SIZE (256)
|
||||
|
||||
typedef struct flowcontrol_stat_t {
|
||||
typedef struct {
|
||||
/* Sender state */
|
||||
uint8_t last_ack;
|
||||
uint8_t last_frame;
|
||||
sem_t send_win_not_full;
|
||||
struct send_slot {
|
||||
vtimer_t timeout;
|
||||
vtimer_t timeout;
|
||||
uint8_t frame[BORDER_BUFFER_SIZE];
|
||||
size_t frame_len;
|
||||
} send_win[BORDER_SWS];
|
||||
|
||||
|
||||
/* Receiver state */
|
||||
uint8_t next_exp;
|
||||
struct recv_slot {
|
||||
@ -42,7 +60,7 @@ typedef struct flowcontrol_stat_t {
|
||||
} recv_win[BORDER_RWS];
|
||||
} flowcontrol_stat_t;
|
||||
|
||||
typedef struct __attribute__ ((packed)) border_syn_packet_t {
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t empty;
|
||||
uint8_t type;
|
||||
uint8_t next_seq_num;
|
||||
|
@ -1,80 +1,102 @@
|
||||
/**
|
||||
* implementation for the IEEE 802.15.4 frame format
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file ieee802154_frame.c
|
||||
* @brief IEEE 802.14.4 framing operations
|
||||
* @author Stephan Zeisberg <zeisberg@mi.fu-berlin.de>
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "ieee802154_frame.h"
|
||||
|
||||
//uint8_t mac_buf[IEEE_802154_HDR_LEN + IEEE_802154_PAYLOAD_LEN];
|
||||
|
||||
uint8_t ieee802154_hdr_ptr;
|
||||
uint8_t ieee802154_payload_ptr;
|
||||
uint16_t ieee802154_payload_len;
|
||||
|
||||
uint8_t init_802154_frame(ieee802154_frame_t *frame, uint8_t *buf){
|
||||
uint8_t init_802154_frame(ieee802154_frame_t *frame, uint8_t *buf)
|
||||
{
|
||||
/* Frame Control Field - 802.15.4 - 2006 - 7.2.1.1 */
|
||||
uint8_t index = 0;
|
||||
|
||||
|
||||
buf[index] = ((frame->fcf.frame_type << 5) |
|
||||
(frame->fcf.sec_enb << 4) |
|
||||
(frame->fcf.frame_pend << 3) |
|
||||
(frame->fcf.ack_req << 2) |
|
||||
(frame->fcf.panid_comp << 1));
|
||||
(frame->fcf.sec_enb << 4) |
|
||||
(frame->fcf.frame_pend << 3) |
|
||||
(frame->fcf.ack_req << 2) |
|
||||
(frame->fcf.panid_comp << 1));
|
||||
index++;
|
||||
buf[index] = ((frame->fcf.dest_addr_m << 4) |
|
||||
(frame->fcf.frame_ver << 2) |
|
||||
(frame->fcf.src_addr_m));
|
||||
(frame->fcf.frame_ver << 2) |
|
||||
(frame->fcf.src_addr_m));
|
||||
index++;
|
||||
|
||||
/* Sequence Number - 802.15.4 - 2006 - 7.2.1.2 */
|
||||
buf[index] = frame->seq_nr;
|
||||
buf[index] = frame->seq_nr;
|
||||
index++;
|
||||
|
||||
/* Destination PAN Identifier - 802.15.4 - 2006 - 7.2.1.3 */
|
||||
if(frame->fcf.dest_addr_m == 0x02 || frame->fcf.dest_addr_m == 0x03){
|
||||
if(frame->fcf.dest_addr_m == 0x02 || frame->fcf.dest_addr_m == 0x03) {
|
||||
buf[index] = ((frame->dest_pan_id >> 8) & 0xff);
|
||||
buf[index+1] = (frame->dest_pan_id & 0xff);
|
||||
buf[index + 1] = (frame->dest_pan_id & 0xff);
|
||||
}
|
||||
|
||||
index += 2;
|
||||
|
||||
/* Destination Address - 802.15.4 - 2006 - 7.2.1.4 */
|
||||
if(frame->fcf.dest_addr_m == 0x02){
|
||||
buf[index] = frame->dest_addr[0];
|
||||
buf[index+1] = frame->dest_addr[1];
|
||||
if(frame->fcf.dest_addr_m == 0x02) {
|
||||
buf[index] = frame->dest_addr[0];
|
||||
buf[index + 1] = frame->dest_addr[1];
|
||||
index += 2;
|
||||
} else if(frame->fcf.dest_addr_m == 0x03){
|
||||
buf[index] = frame->dest_addr[0];
|
||||
buf[index+1] = frame->dest_addr[1];
|
||||
buf[index+2] = frame->dest_addr[2];
|
||||
buf[index+3] = frame->dest_addr[3];
|
||||
buf[index+4] = frame->dest_addr[4];
|
||||
buf[index+5] = frame->dest_addr[5];
|
||||
buf[index+6] = frame->dest_addr[6];
|
||||
buf[index+7] = frame->dest_addr[7];
|
||||
}
|
||||
else if(frame->fcf.dest_addr_m == 0x03) {
|
||||
buf[index] = frame->dest_addr[0];
|
||||
buf[index + 1] = frame->dest_addr[1];
|
||||
buf[index + 2] = frame->dest_addr[2];
|
||||
buf[index + 3] = frame->dest_addr[3];
|
||||
buf[index + 4] = frame->dest_addr[4];
|
||||
buf[index + 5] = frame->dest_addr[5];
|
||||
buf[index + 6] = frame->dest_addr[6];
|
||||
buf[index + 7] = frame->dest_addr[7];
|
||||
index += 8;
|
||||
}
|
||||
|
||||
/* Source PAN Identifier - 802.15.4 - 2006 - 7.2.1.5 */
|
||||
if(!(frame->fcf.panid_comp & 0x01)){
|
||||
if(frame->fcf.src_addr_m == 0x02 || frame->fcf.src_addr_m == 0x03){
|
||||
buf[index] = ((frame->src_pan_id >> 8) & 0xff);
|
||||
buf[index+1] = (frame->src_pan_id & 0xff);
|
||||
if(!(frame->fcf.panid_comp & 0x01)) {
|
||||
if(frame->fcf.src_addr_m == 0x02 || frame->fcf.src_addr_m == 0x03) {
|
||||
buf[index] = ((frame->src_pan_id >> 8) & 0xff);
|
||||
buf[index + 1] = (frame->src_pan_id & 0xff);
|
||||
index += 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Source Address field - 802.15.4 - 2006 - 7.2.1.6 */
|
||||
if(frame->fcf.src_addr_m == 0x02){
|
||||
buf[index] = frame->src_addr[0];
|
||||
buf[index+1] = frame->src_addr[1];
|
||||
index += 2;
|
||||
} else if(frame->fcf.src_addr_m == 0x03){
|
||||
buf[index] = frame->src_addr[0];
|
||||
buf[index+1] = frame->src_addr[1];
|
||||
buf[index+2] = frame->src_addr[2];
|
||||
buf[index+3] = frame->src_addr[3];
|
||||
buf[index+4] = frame->src_addr[4];
|
||||
buf[index+5] = frame->src_addr[5];
|
||||
buf[index+6] = frame->src_addr[6];
|
||||
buf[index+7] = frame->src_addr[7];
|
||||
if(frame->fcf.src_addr_m == 0x02) {
|
||||
buf[index] = frame->src_addr[0];
|
||||
buf[index + 1] = frame->src_addr[1];
|
||||
index += 2;
|
||||
}
|
||||
else if(frame->fcf.src_addr_m == 0x03) {
|
||||
buf[index] = frame->src_addr[0];
|
||||
buf[index + 1] = frame->src_addr[1];
|
||||
buf[index + 2] = frame->src_addr[2];
|
||||
buf[index + 3] = frame->src_addr[3];
|
||||
buf[index + 4] = frame->src_addr[4];
|
||||
buf[index + 5] = frame->src_addr[5];
|
||||
buf[index + 6] = frame->src_addr[6];
|
||||
buf[index + 7] = frame->src_addr[7];
|
||||
index += 8;
|
||||
}
|
||||
|
||||
return index;
|
||||
return index;
|
||||
}
|
||||
|
||||
/** 2 1 2 VAR 2 VAR
|
||||
@ -82,39 +104,44 @@ uint8_t init_802154_frame(ieee802154_frame_t *frame, uint8_t *buf){
|
||||
* | FCF | DSN | DPID | DAD | SPID | SAD |
|
||||
* -------------------------------------------
|
||||
*/
|
||||
uint8_t get_802154_hdr_len(ieee802154_frame_t *frame){
|
||||
uint8_t get_802154_hdr_len(ieee802154_frame_t *frame)
|
||||
{
|
||||
uint8_t len = 0;
|
||||
|
||||
if(frame->fcf.dest_addr_m == 0x02){
|
||||
if(frame->fcf.dest_addr_m == 0x02) {
|
||||
len += 2;
|
||||
} else if(frame->fcf.dest_addr_m == 0x03){
|
||||
}
|
||||
else if(frame->fcf.dest_addr_m == 0x03) {
|
||||
len += 8;
|
||||
}
|
||||
|
||||
if(frame->fcf.src_addr_m == 0x02){
|
||||
|
||||
if(frame->fcf.src_addr_m == 0x02) {
|
||||
len += 2;
|
||||
} else if(frame->fcf.src_addr_m == 0x03){
|
||||
}
|
||||
else if(frame->fcf.src_addr_m == 0x03) {
|
||||
len += 8;
|
||||
}
|
||||
|
||||
if((frame->fcf.dest_addr_m == 0x02) || (frame->fcf.dest_addr_m == 0x03)){
|
||||
|
||||
if((frame->fcf.dest_addr_m == 0x02) || (frame->fcf.dest_addr_m == 0x03)) {
|
||||
len += 2;
|
||||
}
|
||||
if((frame->fcf.src_addr_m == 0x02) || (frame->fcf.src_addr_m == 0x03)){
|
||||
|
||||
if((frame->fcf.src_addr_m == 0x02) || (frame->fcf.src_addr_m == 0x03)) {
|
||||
len += 2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* if src pan id == dest pan id set compression bit */
|
||||
if(frame->src_pan_id == frame->dest_pan_id){
|
||||
if(frame->src_pan_id == frame->dest_pan_id) {
|
||||
frame->fcf.panid_comp = 1;
|
||||
len -= 2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* (DPID + DAD + SPID + SAD) + (FCF + DSN) */
|
||||
return (len + 3);
|
||||
}
|
||||
|
||||
uint8_t read_802154_frame(uint8_t *buf, ieee802154_frame_t *frame, uint8_t len){
|
||||
uint8_t read_802154_frame(uint8_t *buf, ieee802154_frame_t *frame, uint8_t len)
|
||||
{
|
||||
uint8_t index = 0;
|
||||
uint8_t hdrlen;
|
||||
|
||||
@ -138,60 +165,64 @@ uint8_t read_802154_frame(uint8_t *buf, ieee802154_frame_t *frame, uint8_t len){
|
||||
|
||||
index++;
|
||||
|
||||
frame->dest_pan_id = (((uint16_t)buf[index]) << 8) | buf[index+1];
|
||||
|
||||
frame->dest_pan_id = (((uint16_t)buf[index]) << 8) | buf[index + 1];
|
||||
|
||||
index += 2;
|
||||
|
||||
switch(frame->fcf.dest_addr_m){
|
||||
case(0):{
|
||||
switch(frame->fcf.dest_addr_m) {
|
||||
case(0): {
|
||||
printf("fcf.dest_addr_m: pan identifier/address fields empty\n");
|
||||
break;
|
||||
}
|
||||
case(2):{
|
||||
|
||||
case(2): {
|
||||
frame->dest_addr[0] = buf[index];
|
||||
frame->dest_addr[1] = buf[index+1];
|
||||
frame->dest_addr[1] = buf[index + 1];
|
||||
index += 2;
|
||||
break;
|
||||
}
|
||||
case(3):{
|
||||
|
||||
case(3): {
|
||||
frame->dest_addr[0] = buf[index];
|
||||
frame->dest_addr[1] = buf[index+1];
|
||||
frame->dest_addr[2] = buf[index+2];
|
||||
frame->dest_addr[3] = buf[index+3];
|
||||
frame->dest_addr[4] = buf[index+4];
|
||||
frame->dest_addr[5] = buf[index+5];
|
||||
frame->dest_addr[6] = buf[index+6];
|
||||
frame->dest_addr[7] = buf[index+7];
|
||||
frame->dest_addr[1] = buf[index + 1];
|
||||
frame->dest_addr[2] = buf[index + 2];
|
||||
frame->dest_addr[3] = buf[index + 3];
|
||||
frame->dest_addr[4] = buf[index + 4];
|
||||
frame->dest_addr[5] = buf[index + 5];
|
||||
frame->dest_addr[6] = buf[index + 6];
|
||||
frame->dest_addr[7] = buf[index + 7];
|
||||
index += 8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!(frame->fcf.panid_comp == 1)){
|
||||
frame->src_pan_id = (((uint16_t)buf[index]) << 8) | buf[index+1];
|
||||
|
||||
if(!(frame->fcf.panid_comp == 1)) {
|
||||
frame->src_pan_id = (((uint16_t)buf[index]) << 8) | buf[index + 1];
|
||||
index += 2;
|
||||
}
|
||||
|
||||
switch(frame->fcf.src_addr_m){
|
||||
case(0):{
|
||||
|
||||
switch(frame->fcf.src_addr_m) {
|
||||
case(0): {
|
||||
printf("fcf.src_addr_m: pan identifier/address fields empty\n");
|
||||
break;
|
||||
}
|
||||
case(2):{
|
||||
|
||||
case(2): {
|
||||
frame->src_addr[0] = buf[index];
|
||||
frame->src_addr[1] = buf[index+1];
|
||||
frame->src_addr[1] = buf[index + 1];
|
||||
index += 2;
|
||||
break;
|
||||
}
|
||||
case(3):{
|
||||
|
||||
case(3): {
|
||||
frame->src_addr[0] = buf[index];
|
||||
frame->src_addr[1] = buf[index+1];
|
||||
frame->src_addr[2] = buf[index+2];
|
||||
frame->src_addr[3] = buf[index+3];
|
||||
frame->src_addr[4] = buf[index+4];
|
||||
frame->src_addr[5] = buf[index+5];
|
||||
frame->src_addr[6] = buf[index+6];
|
||||
frame->src_addr[7] = buf[index+7];
|
||||
frame->src_addr[1] = buf[index + 1];
|
||||
frame->src_addr[2] = buf[index + 2];
|
||||
frame->src_addr[3] = buf[index + 3];
|
||||
frame->src_addr[4] = buf[index + 4];
|
||||
frame->src_addr[5] = buf[index + 5];
|
||||
frame->src_addr[6] = buf[index + 6];
|
||||
frame->src_addr[7] = buf[index + 7];
|
||||
index += 8;
|
||||
break;
|
||||
}
|
||||
@ -200,19 +231,20 @@ uint8_t read_802154_frame(uint8_t *buf, ieee802154_frame_t *frame, uint8_t len){
|
||||
frame->payload = (buf + index);
|
||||
hdrlen = index;
|
||||
frame->payload_len = (len - hdrlen);
|
||||
|
||||
return hdrlen;
|
||||
|
||||
return hdrlen;
|
||||
}
|
||||
|
||||
void print_802154_fcf_frame(ieee802154_frame_t *frame){
|
||||
void print_802154_fcf_frame(ieee802154_frame_t *frame)
|
||||
{
|
||||
printf("frame type: %02x\n"
|
||||
"security enabled: %02x\n"
|
||||
"frame pending: %02x\n"
|
||||
"security enabled: %02x\n"
|
||||
"frame pending: %02x\n"
|
||||
"ack requested: %02x\n"
|
||||
"pan id compression: %02x\n"
|
||||
"destination address mode: %02x\n"
|
||||
"frame version: %02x\n"
|
||||
"source address mode: %02x\n",
|
||||
"source address mode: %02x\n",
|
||||
frame->fcf.frame_type,
|
||||
frame->fcf.sec_enb,
|
||||
frame->fcf.frame_pend,
|
||||
@ -220,5 +252,5 @@ void print_802154_fcf_frame(ieee802154_frame_t *frame){
|
||||
frame->fcf.panid_comp,
|
||||
frame->fcf.dest_addr_m,
|
||||
frame->fcf.frame_ver,
|
||||
frame->fcf.src_addr_m);
|
||||
frame->fcf.src_addr_m);
|
||||
}
|
||||
|
@ -1,3 +1,21 @@
|
||||
/**
|
||||
* Data struct and prototypes for the IEEE 802.15.4 frame format
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file ieee802154_frame.h
|
||||
* @brief IEEE 802.14.4 framing data structs and prototypes
|
||||
* @author Stephan Zeisberg <zeisberg@mi.fu-berlin.de>
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef IEEE802154_FRAME
|
||||
#define IEEE802154_FRAME
|
||||
|
||||
@ -6,7 +24,7 @@
|
||||
|
||||
/* maximum 802.15.4 header length */
|
||||
#define IEEE_802154_MAX_HDR_LEN 23
|
||||
/* mininmum */
|
||||
/* mininmum */
|
||||
#define IEEE_802154_PAYLOAD_LEN 21
|
||||
|
||||
#define IEEE_802154_BEACON_FRAME 0
|
||||
@ -19,7 +37,7 @@
|
||||
|
||||
#define IEEE_802154_PAN_ID 0x1234
|
||||
|
||||
typedef struct __attribute__ ((packed)) {
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t frame_type;
|
||||
uint8_t sec_enb;
|
||||
uint8_t frame_pend;
|
||||
@ -27,10 +45,10 @@ typedef struct __attribute__ ((packed)) {
|
||||
uint8_t panid_comp;
|
||||
uint8_t dest_addr_m;
|
||||
uint8_t frame_ver;
|
||||
uint8_t src_addr_m;
|
||||
uint8_t src_addr_m;
|
||||
} ieee802154_fcf_frame_t;
|
||||
|
||||
typedef struct __attribute__ ((packed)) {
|
||||
typedef struct __attribute__((packed)) {
|
||||
ieee802154_fcf_frame_t fcf;
|
||||
uint8_t seq_nr;
|
||||
uint16_t dest_pan_id;
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "objective_functions.h"
|
||||
|
||||
void of0(void){
|
||||
void of0(void)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,52 +1,79 @@
|
||||
/**
|
||||
* Objective function 0 for RPL implementation
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup rpl
|
||||
* @{
|
||||
* @file of0.c
|
||||
* @brief RPL objective function 0
|
||||
* @author Eric Engel <eric.engel@fu-berlin.de>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "of0.h"
|
||||
|
||||
rpl_of_t rpl_of0 = {
|
||||
0x0,
|
||||
calc_rank,
|
||||
which_parent,
|
||||
which_dodag,
|
||||
reset,
|
||||
NULL
|
||||
0x0,
|
||||
calc_rank,
|
||||
which_parent,
|
||||
which_dodag,
|
||||
reset,
|
||||
NULL
|
||||
};
|
||||
|
||||
rpl_of_t *rpl_get_of0(void){
|
||||
return &rpl_of0;
|
||||
rpl_of_t *rpl_get_of0(void)
|
||||
{
|
||||
return &rpl_of0;
|
||||
}
|
||||
|
||||
void reset(rpl_dodag_t *dodag){
|
||||
//Nothing to do in OF0
|
||||
void reset(rpl_dodag_t *dodag)
|
||||
{
|
||||
/* Nothing to do in OF0 */
|
||||
}
|
||||
|
||||
uint16_t calc_rank(rpl_parent_t * parent, uint16_t base_rank){
|
||||
if(base_rank == 0) {
|
||||
if(parent == NULL) {
|
||||
return INFINITE_RANK;
|
||||
}
|
||||
base_rank = parent->rank;
|
||||
}
|
||||
uint16_t calc_rank(rpl_parent_t *parent, uint16_t base_rank)
|
||||
{
|
||||
if(base_rank == 0) {
|
||||
if(parent == NULL) {
|
||||
return INFINITE_RANK;
|
||||
}
|
||||
|
||||
uint16_t add;
|
||||
if(parent != NULL){
|
||||
add = parent->dodag->minhoprankincrease;
|
||||
}
|
||||
else{
|
||||
add = DEFAULT_MIN_HOP_RANK_INCREASE;
|
||||
}
|
||||
if( base_rank + add < base_rank ){
|
||||
return INFINITE_RANK;
|
||||
}
|
||||
return base_rank + add;
|
||||
base_rank = parent->rank;
|
||||
}
|
||||
|
||||
uint16_t add;
|
||||
|
||||
if(parent != NULL) {
|
||||
add = parent->dodag->minhoprankincrease;
|
||||
}
|
||||
else {
|
||||
add = DEFAULT_MIN_HOP_RANK_INCREASE;
|
||||
}
|
||||
|
||||
if(base_rank + add < base_rank) {
|
||||
return INFINITE_RANK;
|
||||
}
|
||||
|
||||
return base_rank + add;
|
||||
}
|
||||
|
||||
//We simply return the Parent with lower rank
|
||||
rpl_parent_t * which_parent(rpl_parent_t *p1, rpl_parent_t *p2){
|
||||
if(p1->rank < p2->rank){
|
||||
return p1;
|
||||
}
|
||||
return p2;
|
||||
/* We simply return the Parent with lower rank */
|
||||
rpl_parent_t *which_parent(rpl_parent_t *p1, rpl_parent_t *p2)
|
||||
{
|
||||
if(p1->rank < p2->rank) {
|
||||
return p1;
|
||||
}
|
||||
|
||||
return p2;
|
||||
}
|
||||
|
||||
rpl_dodag_t * which_dodag(rpl_dodag_t *d1, rpl_dodag_t *d2){
|
||||
return d1;
|
||||
rpl_dodag_t *which_dodag(rpl_dodag_t *d1, rpl_dodag_t *d2)
|
||||
{
|
||||
return d1;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,3 +1,21 @@
|
||||
/**
|
||||
* RPL constants and prototypes
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup rpl
|
||||
* @{
|
||||
* @file rpl.h
|
||||
* @brief RPL header
|
||||
* @author Eric Engel <eric.engel@fu-berlin.de>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <vtimer.h>
|
||||
#include <mutex.h>
|
||||
@ -22,9 +40,9 @@ void recv_rpl_dis(void);
|
||||
void recv_rpl_dao(void);
|
||||
void recv_rpl_dao_ack(void);
|
||||
void rpl_send(ipv6_addr_t *destination, uint8_t *payload, uint16_t p_len, uint8_t next_header, void *tcp_socket);
|
||||
ipv6_addr_t *rpl_get_next_hop(ipv6_addr_t * addr);
|
||||
ipv6_addr_t *rpl_get_next_hop(ipv6_addr_t *addr);
|
||||
void rpl_add_routing_entry(ipv6_addr_t *addr, ipv6_addr_t *next_hop, uint16_t lifetime);
|
||||
void rpl_del_routing_entry(ipv6_addr_t *addr);
|
||||
rpl_routing_entry_t * rpl_find_routing_entry(ipv6_addr_t *addr);
|
||||
rpl_routing_entry_t *rpl_find_routing_entry(ipv6_addr_t *addr);
|
||||
void rpl_clear_routing_table(void);
|
||||
rpl_routing_entry_t *rpl_get_routing_table(void);
|
||||
|
@ -1,3 +1,21 @@
|
||||
/**
|
||||
* RPL dodag implementation
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup rpl
|
||||
* @{
|
||||
* @file rpl_dodag.c
|
||||
* @brief RPL dodag functions
|
||||
* @author Eric Engel <eric.engel@fu-berlin.de>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@ -9,307 +27,365 @@ rpl_instance_t instances[RPL_MAX_INSTANCES];
|
||||
rpl_dodag_t dodags[RPL_MAX_DODAGS];
|
||||
rpl_parent_t parents[RPL_MAX_PARENTS];
|
||||
|
||||
rpl_instance_t *rpl_new_instance(uint8_t instanceid){
|
||||
rpl_instance_t *inst;
|
||||
rpl_instance_t *end ;
|
||||
for(inst=&instances[0], end = inst+RPL_MAX_INSTANCES; inst < end;inst++){
|
||||
if(inst->used == 0){
|
||||
memset(inst, 0, sizeof(*inst));
|
||||
inst->used = 1;
|
||||
inst->id = instanceid;
|
||||
return inst;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
rpl_instance_t *rpl_new_instance(uint8_t instanceid)
|
||||
{
|
||||
rpl_instance_t *inst;
|
||||
rpl_instance_t *end ;
|
||||
|
||||
for(inst = &instances[0], end = inst + RPL_MAX_INSTANCES; inst < end; inst++) {
|
||||
if(inst->used == 0) {
|
||||
memset(inst, 0, sizeof(*inst));
|
||||
inst->used = 1;
|
||||
inst->id = instanceid;
|
||||
return inst;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
rpl_instance_t *rpl_get_instance(uint8_t instanceid){
|
||||
for(int i=0;i<RPL_MAX_INSTANCES;i++){
|
||||
if( instances[i].used && (instances[i].id == instanceid)){
|
||||
return &instances[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
rpl_instance_t *rpl_get_instance(uint8_t instanceid)
|
||||
{
|
||||
for(int i = 0; i < RPL_MAX_INSTANCES; i++) {
|
||||
if(instances[i].used && (instances[i].id == instanceid)) {
|
||||
return &instances[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rpl_instance_t *rpl_get_my_instance(){
|
||||
for(int i=0;i<RPL_MAX_INSTANCES;i++){
|
||||
if(instances[i].joined){
|
||||
return &instances[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
rpl_instance_t *rpl_get_my_instance()
|
||||
{
|
||||
for(int i = 0; i < RPL_MAX_INSTANCES; i++) {
|
||||
if(instances[i].joined) {
|
||||
return &instances[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rpl_dodag_t * rpl_new_dodag(uint8_t instanceid, ipv6_addr_t *dodagid){
|
||||
rpl_instance_t * inst;
|
||||
inst = rpl_get_instance(instanceid);
|
||||
if(inst == NULL){
|
||||
printf("Error - No instance found for id %d. This should not happen\n", instanceid);
|
||||
return NULL;
|
||||
}
|
||||
rpl_dodag_t *rpl_new_dodag(uint8_t instanceid, ipv6_addr_t *dodagid)
|
||||
{
|
||||
rpl_instance_t *inst;
|
||||
inst = rpl_get_instance(instanceid);
|
||||
|
||||
rpl_dodag_t *dodag;
|
||||
rpl_dodag_t *end;
|
||||
if(inst == NULL) {
|
||||
printf("Error - No instance found for id %d. This should not happen\n",
|
||||
instanceid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for(dodag= &dodags[0], end=dodag+RPL_MAX_DODAGS; dodag < end; dodag++){
|
||||
if( dodag->used == 0){
|
||||
memset(dodag, 0,sizeof(*dodag));
|
||||
dodag->instance = inst;
|
||||
dodag->my_rank = INFINITE_RANK;
|
||||
dodag->used = 1;
|
||||
memcpy(&dodag->dodag_id,dodagid,sizeof(*dodagid));
|
||||
return dodag;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
rpl_dodag_t *dodag;
|
||||
rpl_dodag_t *end;
|
||||
|
||||
for(dodag = &dodags[0], end = dodag + RPL_MAX_DODAGS; dodag < end; dodag++) {
|
||||
if(dodag->used == 0) {
|
||||
memset(dodag, 0, sizeof(*dodag));
|
||||
dodag->instance = inst;
|
||||
dodag->my_rank = INFINITE_RANK;
|
||||
dodag->used = 1;
|
||||
memcpy(&dodag->dodag_id, dodagid, sizeof(*dodagid));
|
||||
return dodag;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
rpl_dodag_t *rpl_get_dodag(ipv6_addr_t *id){
|
||||
for(int i=0;i<RPL_MAX_DODAGS;i++){
|
||||
if( dodags[i].used && (rpl_equal_id(&dodags[i].dodag_id, id))){
|
||||
return &dodags[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
rpl_dodag_t *rpl_get_dodag(ipv6_addr_t *id)
|
||||
{
|
||||
for(int i = 0; i < RPL_MAX_DODAGS; i++) {
|
||||
if(dodags[i].used && (rpl_equal_id(&dodags[i].dodag_id, id))) {
|
||||
return &dodags[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
rpl_dodag_t *rpl_get_my_dodag(){
|
||||
for(int i=0;i<RPL_MAX_DODAGS;i++){
|
||||
if( dodags[i].joined){
|
||||
return &dodags[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
rpl_dodag_t *rpl_get_my_dodag()
|
||||
{
|
||||
for(int i = 0; i < RPL_MAX_DODAGS; i++) {
|
||||
if(dodags[i].joined) {
|
||||
return &dodags[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
void rpl_del_dodag(rpl_dodag_t *dodag){
|
||||
memset(dodag, 0, sizeof(*dodag));
|
||||
void rpl_del_dodag(rpl_dodag_t *dodag)
|
||||
{
|
||||
memset(dodag, 0, sizeof(*dodag));
|
||||
}
|
||||
|
||||
void rpl_leave_dodag(rpl_dodag_t * dodag){
|
||||
dodag->joined = 0;
|
||||
dodag->my_preferred_parent = NULL;
|
||||
rpl_delete_all_parents();
|
||||
void rpl_leave_dodag(rpl_dodag_t *dodag)
|
||||
{
|
||||
dodag->joined = 0;
|
||||
dodag->my_preferred_parent = NULL;
|
||||
rpl_delete_all_parents();
|
||||
}
|
||||
|
||||
bool rpl_equal_id(ipv6_addr_t *id1, ipv6_addr_t *id2){
|
||||
for(uint8_t i=0;i<4;i++){
|
||||
if(id1->uint32[i] != id2->uint32[i]){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
bool rpl_equal_id(ipv6_addr_t *id1, ipv6_addr_t *id2)
|
||||
{
|
||||
for(uint8_t i = 0; i < 4; i++) {
|
||||
if(id1->uint32[i] != id2->uint32[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
rpl_parent_t *rpl_new_parent(rpl_dodag_t *dodag, ipv6_addr_t *address, uint16_t rank){
|
||||
rpl_parent_t *parent;
|
||||
rpl_parent_t *end;
|
||||
rpl_parent_t *rpl_new_parent(rpl_dodag_t *dodag, ipv6_addr_t *address, uint16_t rank)
|
||||
{
|
||||
rpl_parent_t *parent;
|
||||
rpl_parent_t *end;
|
||||
|
||||
for(parent= &parents[0], end=parents+RPL_MAX_PARENTS; parent < end; parent++){
|
||||
if(parent->used == 0){
|
||||
memset(parent, 0, sizeof(*parent));
|
||||
parent->used = 1;
|
||||
parent->addr = *address;
|
||||
parent->rank = rank;
|
||||
parent->dodag = dodag;
|
||||
//dtsn is set at the end of recv_dio function
|
||||
parent->dtsn = 0;
|
||||
return parent;
|
||||
}
|
||||
}
|
||||
rpl_delete_worst_parent();
|
||||
return rpl_new_parent(dodag, address, rank);
|
||||
for(parent = &parents[0], end = parents + RPL_MAX_PARENTS; parent < end; parent++) {
|
||||
if(parent->used == 0) {
|
||||
memset(parent, 0, sizeof(*parent));
|
||||
parent->used = 1;
|
||||
parent->addr = *address;
|
||||
parent->rank = rank;
|
||||
parent->dodag = dodag;
|
||||
/* dtsn is set at the end of recv_dio function */
|
||||
parent->dtsn = 0;
|
||||
return parent;
|
||||
}
|
||||
}
|
||||
|
||||
rpl_delete_worst_parent();
|
||||
return rpl_new_parent(dodag, address, rank);
|
||||
}
|
||||
|
||||
rpl_parent_t *rpl_find_parent(ipv6_addr_t *address){
|
||||
rpl_parent_t *parent;
|
||||
rpl_parent_t *end;
|
||||
rpl_parent_t *rpl_find_parent(ipv6_addr_t *address)
|
||||
{
|
||||
rpl_parent_t *parent;
|
||||
rpl_parent_t *end;
|
||||
|
||||
for(parent= &parents[0], end=parents+RPL_MAX_PARENTS; parent < end; parent++){
|
||||
if( (parent->used) && (rpl_equal_id(address, &parent->addr)) ){
|
||||
return parent;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
for(parent = &parents[0], end = parents + RPL_MAX_PARENTS; parent < end; parent++) {
|
||||
if((parent->used) && (rpl_equal_id(address, &parent->addr))) {
|
||||
return parent;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void rpl_delete_parent(rpl_parent_t * parent){
|
||||
rpl_dodag_t * my_dodag = rpl_get_my_dodag();
|
||||
if( (my_dodag != NULL) && rpl_equal_id(&my_dodag->my_preferred_parent->addr, &parent->addr) ){
|
||||
my_dodag->my_preferred_parent = NULL;
|
||||
}
|
||||
memset(parent,0,sizeof(*parent));
|
||||
void rpl_delete_parent(rpl_parent_t *parent)
|
||||
{
|
||||
rpl_dodag_t *my_dodag = rpl_get_my_dodag();
|
||||
|
||||
if((my_dodag != NULL) && rpl_equal_id(&my_dodag->my_preferred_parent->addr,
|
||||
&parent->addr)) {
|
||||
my_dodag->my_preferred_parent = NULL;
|
||||
}
|
||||
|
||||
memset(parent, 0, sizeof(*parent));
|
||||
}
|
||||
|
||||
void rpl_delete_worst_parent(void){
|
||||
uint8_t worst = 0xFF;
|
||||
uint16_t max_rank = 0x0000;
|
||||
for(int i=0;i<RPL_MAX_PARENTS;i++){
|
||||
if(parents[i].rank > max_rank){
|
||||
worst = i;
|
||||
max_rank = parents[i].rank;
|
||||
}
|
||||
}
|
||||
if(worst == 0xFF){
|
||||
//Fehler, keine parents -> sollte nicht passieren
|
||||
return;
|
||||
}
|
||||
rpl_delete_parent(&parents[worst]);
|
||||
void rpl_delete_worst_parent(void)
|
||||
{
|
||||
uint8_t worst = 0xFF;
|
||||
uint16_t max_rank = 0x0000;
|
||||
|
||||
for(int i = 0; i < RPL_MAX_PARENTS; i++) {
|
||||
if(parents[i].rank > max_rank) {
|
||||
worst = i;
|
||||
max_rank = parents[i].rank;
|
||||
}
|
||||
}
|
||||
|
||||
if(worst == 0xFF) {
|
||||
/* Fehler, keine parents -> sollte nicht passieren */
|
||||
return;
|
||||
}
|
||||
|
||||
rpl_delete_parent(&parents[worst]);
|
||||
|
||||
}
|
||||
|
||||
void rpl_delete_all_parents(void){
|
||||
rpl_dodag_t * my_dodag = rpl_get_my_dodag();
|
||||
my_dodag->my_preferred_parent = NULL;
|
||||
for(int i=0;i<RPL_MAX_PARENTS;i++){
|
||||
memset(&parents[i],0,sizeof(parents[i]));
|
||||
}
|
||||
void rpl_delete_all_parents(void)
|
||||
{
|
||||
rpl_dodag_t *my_dodag = rpl_get_my_dodag();
|
||||
my_dodag->my_preferred_parent = NULL;
|
||||
|
||||
for(int i = 0; i < RPL_MAX_PARENTS; i++) {
|
||||
memset(&parents[i], 0, sizeof(parents[i]));
|
||||
}
|
||||
}
|
||||
|
||||
rpl_parent_t * rpl_find_preferred_parent(void){
|
||||
rpl_parent_t * best = NULL;
|
||||
rpl_dodag_t * my_dodag = rpl_get_my_dodag();
|
||||
rpl_parent_t *rpl_find_preferred_parent(void)
|
||||
{
|
||||
rpl_parent_t *best = NULL;
|
||||
rpl_dodag_t *my_dodag = rpl_get_my_dodag();
|
||||
|
||||
for(uint8_t i=0;i<RPL_MAX_PARENTS;i++){
|
||||
if(parents[i].used){
|
||||
if((parents[i].rank == INFINITE_RANK) || (parents[i].lifetime <= 1)){
|
||||
puts("bad parent");
|
||||
continue;
|
||||
}
|
||||
else if(best == NULL){
|
||||
puts("parent");
|
||||
best = &parents[i];
|
||||
} else{
|
||||
best = my_dodag->of->which_parent(best, &parents[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
for(uint8_t i = 0; i < RPL_MAX_PARENTS; i++) {
|
||||
if(parents[i].used) {
|
||||
if((parents[i].rank == INFINITE_RANK) || (parents[i].lifetime <= 1)) {
|
||||
puts("bad parent");
|
||||
continue;
|
||||
}
|
||||
else if(best == NULL) {
|
||||
puts("parent");
|
||||
best = &parents[i];
|
||||
}
|
||||
else {
|
||||
best = my_dodag->of->which_parent(best, &parents[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(best == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(best == NULL){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!rpl_equal_id(&my_dodag->my_preferred_parent->addr, &best->addr)){
|
||||
if(my_dodag->mop != NO_DOWNWARD_ROUTES){
|
||||
//send DAO with ZERO_LIFETIME to old parent
|
||||
send_DAO(&my_dodag->my_preferred_parent->addr, 0, false, 0);
|
||||
}
|
||||
my_dodag->my_preferred_parent = best;
|
||||
if(my_dodag->mop != NO_DOWNWARD_ROUTES){
|
||||
delay_dao();
|
||||
}
|
||||
reset_trickletimer();
|
||||
}
|
||||
|
||||
return best;
|
||||
if(!rpl_equal_id(&my_dodag->my_preferred_parent->addr, &best->addr)) {
|
||||
if(my_dodag->mop != NO_DOWNWARD_ROUTES) {
|
||||
/* send DAO with ZERO_LIFETIME to old parent */
|
||||
send_DAO(&my_dodag->my_preferred_parent->addr, 0, false, 0);
|
||||
}
|
||||
|
||||
my_dodag->my_preferred_parent = best;
|
||||
|
||||
if(my_dodag->mop != NO_DOWNWARD_ROUTES) {
|
||||
delay_dao();
|
||||
}
|
||||
|
||||
reset_trickletimer();
|
||||
}
|
||||
|
||||
return best;
|
||||
}
|
||||
|
||||
void rpl_parent_update(rpl_parent_t * parent){
|
||||
rpl_dodag_t * my_dodag = rpl_get_my_dodag();
|
||||
uint16_t old_rank = my_dodag->my_rank;
|
||||
|
||||
//update Parent lifetime
|
||||
if(parent != NULL){
|
||||
parent->lifetime = my_dodag->default_lifetime * my_dodag->lifetime_unit;
|
||||
}
|
||||
void rpl_parent_update(rpl_parent_t *parent)
|
||||
{
|
||||
rpl_dodag_t *my_dodag = rpl_get_my_dodag();
|
||||
uint16_t old_rank = my_dodag->my_rank;
|
||||
|
||||
if(rpl_find_preferred_parent() == NULL){
|
||||
rpl_local_repair();
|
||||
}
|
||||
|
||||
if(rpl_calc_rank(old_rank, my_dodag->minhoprankincrease) != rpl_calc_rank(my_dodag->my_rank, my_dodag->minhoprankincrease)){
|
||||
if(my_dodag->my_rank < my_dodag->min_rank){
|
||||
my_dodag->min_rank = my_dodag->my_rank;
|
||||
}
|
||||
reset_trickletimer();
|
||||
}
|
||||
/* update Parent lifetime */
|
||||
if(parent != NULL) {
|
||||
parent->lifetime = my_dodag->default_lifetime * my_dodag->lifetime_unit;
|
||||
}
|
||||
|
||||
if(rpl_find_preferred_parent() == NULL) {
|
||||
rpl_local_repair();
|
||||
}
|
||||
|
||||
if(rpl_calc_rank(old_rank, my_dodag->minhoprankincrease) !=
|
||||
rpl_calc_rank(my_dodag->my_rank, my_dodag->minhoprankincrease)) {
|
||||
if(my_dodag->my_rank < my_dodag->min_rank) {
|
||||
my_dodag->min_rank = my_dodag->my_rank;
|
||||
}
|
||||
|
||||
reset_trickletimer();
|
||||
}
|
||||
}
|
||||
|
||||
void rpl_join_dodag(rpl_dodag_t *dodag, ipv6_addr_t *parent, uint16_t parent_rank){
|
||||
rpl_dodag_t *my_dodag;
|
||||
rpl_parent_t *preferred_parent;
|
||||
my_dodag = rpl_new_dodag(dodag->instance->id, &dodag->dodag_id);
|
||||
if(my_dodag == NULL){
|
||||
return;
|
||||
}
|
||||
preferred_parent = rpl_new_parent(my_dodag, parent, parent_rank);
|
||||
if(preferred_parent == NULL){
|
||||
rpl_del_dodag(my_dodag);
|
||||
return;
|
||||
}
|
||||
my_dodag->instance->joined = 1;
|
||||
my_dodag->of = dodag->of;
|
||||
my_dodag->mop = dodag->mop;
|
||||
my_dodag->dtsn = dodag->dtsn;
|
||||
my_dodag->prf = dodag->prf;
|
||||
my_dodag->dio_interval_doubling = dodag->dio_interval_doubling;
|
||||
my_dodag->dio_min = dodag->dio_min;
|
||||
my_dodag->dio_redundancy = dodag->dio_redundancy;
|
||||
my_dodag->maxrankincrease = dodag->maxrankincrease;
|
||||
my_dodag->minhoprankincrease = dodag->minhoprankincrease;
|
||||
my_dodag->default_lifetime = dodag->default_lifetime;
|
||||
my_dodag->lifetime_unit = dodag->lifetime_unit;
|
||||
my_dodag->version = dodag->version;
|
||||
my_dodag->grounded = dodag->grounded;
|
||||
my_dodag->joined = 1;
|
||||
my_dodag->my_preferred_parent = preferred_parent;
|
||||
my_dodag->my_rank = dodag->of->calc_rank(preferred_parent, dodag->my_rank);
|
||||
my_dodag->dao_seq = RPL_COUNTER_INIT;
|
||||
my_dodag->min_rank = my_dodag->my_rank;
|
||||
|
||||
start_trickle(my_dodag->dio_min, my_dodag->dio_interval_doubling, my_dodag->dio_redundancy);
|
||||
delay_dao();
|
||||
void rpl_join_dodag(rpl_dodag_t *dodag, ipv6_addr_t *parent, uint16_t parent_rank)
|
||||
{
|
||||
rpl_dodag_t *my_dodag;
|
||||
rpl_parent_t *preferred_parent;
|
||||
my_dodag = rpl_new_dodag(dodag->instance->id, &dodag->dodag_id);
|
||||
|
||||
if(my_dodag == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
preferred_parent = rpl_new_parent(my_dodag, parent, parent_rank);
|
||||
|
||||
if(preferred_parent == NULL) {
|
||||
rpl_del_dodag(my_dodag);
|
||||
return;
|
||||
}
|
||||
|
||||
my_dodag->instance->joined = 1;
|
||||
my_dodag->of = dodag->of;
|
||||
my_dodag->mop = dodag->mop;
|
||||
my_dodag->dtsn = dodag->dtsn;
|
||||
my_dodag->prf = dodag->prf;
|
||||
my_dodag->dio_interval_doubling = dodag->dio_interval_doubling;
|
||||
my_dodag->dio_min = dodag->dio_min;
|
||||
my_dodag->dio_redundancy = dodag->dio_redundancy;
|
||||
my_dodag->maxrankincrease = dodag->maxrankincrease;
|
||||
my_dodag->minhoprankincrease = dodag->minhoprankincrease;
|
||||
my_dodag->default_lifetime = dodag->default_lifetime;
|
||||
my_dodag->lifetime_unit = dodag->lifetime_unit;
|
||||
my_dodag->version = dodag->version;
|
||||
my_dodag->grounded = dodag->grounded;
|
||||
my_dodag->joined = 1;
|
||||
my_dodag->my_preferred_parent = preferred_parent;
|
||||
my_dodag->my_rank = dodag->of->calc_rank(preferred_parent, dodag->my_rank);
|
||||
my_dodag->dao_seq = RPL_COUNTER_INIT;
|
||||
my_dodag->min_rank = my_dodag->my_rank;
|
||||
|
||||
start_trickle(my_dodag->dio_min, my_dodag->dio_interval_doubling, my_dodag->dio_redundancy);
|
||||
delay_dao();
|
||||
}
|
||||
|
||||
void rpl_global_repair(rpl_dodag_t *dodag, ipv6_addr_t * p_addr, uint16_t rank){
|
||||
puts("[INFO] Global repair started");
|
||||
rpl_dodag_t * my_dodag = rpl_get_my_dodag();
|
||||
if(my_dodag == NULL){
|
||||
printf("[Error] - no global repair possible, if not part of a DODAG\n");
|
||||
return;
|
||||
}
|
||||
rpl_delete_all_parents();
|
||||
my_dodag->version = dodag->version;
|
||||
my_dodag->dtsn++;
|
||||
my_dodag->my_preferred_parent = rpl_new_parent(my_dodag, p_addr, rank);
|
||||
if(my_dodag->my_preferred_parent == NULL){
|
||||
printf("[Error] no more parent after global repair\n");
|
||||
my_dodag->my_rank = INFINITE_RANK;
|
||||
}else{
|
||||
//Calc new Rank
|
||||
my_dodag->my_rank = my_dodag->of->calc_rank(my_dodag->my_preferred_parent, my_dodag->my_rank);
|
||||
my_dodag->min_rank = my_dodag->my_rank;
|
||||
reset_trickletimer();
|
||||
delay_dao();
|
||||
}
|
||||
printf("Migrated to DODAG Version %d. My new Rank: %d\n", my_dodag->version, my_dodag->my_rank);
|
||||
void rpl_global_repair(rpl_dodag_t *dodag, ipv6_addr_t *p_addr, uint16_t rank)
|
||||
{
|
||||
puts("[INFO] Global repair started");
|
||||
rpl_dodag_t *my_dodag = rpl_get_my_dodag();
|
||||
|
||||
|
||||
if(my_dodag == NULL) {
|
||||
printf("[Error] - no global repair possible, if not part of a DODAG\n");
|
||||
return;
|
||||
}
|
||||
|
||||
rpl_delete_all_parents();
|
||||
my_dodag->version = dodag->version;
|
||||
my_dodag->dtsn++;
|
||||
my_dodag->my_preferred_parent = rpl_new_parent(my_dodag, p_addr, rank);
|
||||
|
||||
if(my_dodag->my_preferred_parent == NULL) {
|
||||
printf("[Error] no more parent after global repair\n");
|
||||
my_dodag->my_rank = INFINITE_RANK;
|
||||
}
|
||||
else {
|
||||
/* Calc new Rank */
|
||||
my_dodag->my_rank = my_dodag->of->calc_rank(my_dodag->my_preferred_parent,
|
||||
my_dodag->my_rank);
|
||||
my_dodag->min_rank = my_dodag->my_rank;
|
||||
reset_trickletimer();
|
||||
delay_dao();
|
||||
}
|
||||
|
||||
printf("Migrated to DODAG Version %d. My new Rank: %d\n", my_dodag->version,
|
||||
my_dodag->my_rank);
|
||||
}
|
||||
|
||||
void rpl_local_repair(void){
|
||||
puts("[INFO] Local Repair started");
|
||||
rpl_dodag_t * my_dodag = rpl_get_my_dodag();
|
||||
if(my_dodag == NULL){
|
||||
printf("[Error] - no local repair possible, if not part of a DODAG\n");
|
||||
return;
|
||||
}
|
||||
my_dodag->my_rank = INFINITE_RANK;
|
||||
my_dodag->dtsn++;
|
||||
rpl_delete_all_parents();
|
||||
reset_trickletimer();
|
||||
void rpl_local_repair(void)
|
||||
{
|
||||
puts("[INFO] Local Repair started");
|
||||
rpl_dodag_t *my_dodag = rpl_get_my_dodag();
|
||||
|
||||
if(my_dodag == NULL) {
|
||||
printf("[Error] - no local repair possible, if not part of a DODAG\n");
|
||||
return;
|
||||
}
|
||||
|
||||
my_dodag->my_rank = INFINITE_RANK;
|
||||
my_dodag->dtsn++;
|
||||
rpl_delete_all_parents();
|
||||
reset_trickletimer();
|
||||
|
||||
}
|
||||
|
||||
ipv6_addr_t *rpl_get_my_preferred_parent(){
|
||||
rpl_dodag_t * my_dodag = rpl_get_my_dodag();
|
||||
if(my_dodag == NULL){
|
||||
return NULL;
|
||||
}
|
||||
return &my_dodag->my_preferred_parent->addr;
|
||||
ipv6_addr_t *rpl_get_my_preferred_parent()
|
||||
{
|
||||
rpl_dodag_t *my_dodag = rpl_get_my_dodag();
|
||||
|
||||
if(my_dodag == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &my_dodag->my_preferred_parent->addr;
|
||||
}
|
||||
|
||||
uint16_t rpl_calc_rank(uint16_t abs_rank, uint16_t minhoprankincrease){
|
||||
return abs_rank / minhoprankincrease;
|
||||
uint16_t rpl_calc_rank(uint16_t abs_rank, uint16_t minhoprankincrease)
|
||||
{
|
||||
return abs_rank / minhoprankincrease;
|
||||
}
|
||||
|
@ -1,5 +1,22 @@
|
||||
/**
|
||||
* RPL dodag prototypes
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup rpl
|
||||
* @{
|
||||
* @file rpl_dodag.h
|
||||
* @brief RPL dodag header
|
||||
* @author Eric Engel <eric.engel@fu-berlin.de>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "rpl_structs.h"
|
||||
//#include "of0.h"
|
||||
|
||||
rpl_instance_t *rpl_new_instance(uint8_t instanceid);
|
||||
rpl_instance_t *rpl_get_instance(uint8_t instanceid);
|
||||
@ -11,14 +28,14 @@ void rpl_join_dodag(rpl_dodag_t *dodag, ipv6_addr_t *parent, uint16_t parent_ran
|
||||
void rpl_del_dodag(rpl_dodag_t *dodag);
|
||||
rpl_parent_t *rpl_new_parent(rpl_dodag_t *dodag, ipv6_addr_t *address, uint16_t rank);
|
||||
rpl_parent_t *rpl_find_parent(ipv6_addr_t *address);
|
||||
void rpl_leave_dodag(rpl_dodag_t * dodag);
|
||||
void rpl_leave_dodag(rpl_dodag_t *dodag);
|
||||
bool rpl_equal_id(ipv6_addr_t *id1, ipv6_addr_t *id2);
|
||||
ipv6_addr_t *rpl_get_my_preferred_parent(void);
|
||||
void rpl_delete_parent(rpl_parent_t *parent);
|
||||
void rpl_delete_worst_parent(void);
|
||||
void rpl_delete_all_parents(void);
|
||||
rpl_parent_t * rpl_find_preferred_parent(void);
|
||||
void rpl_parent_update(rpl_parent_t * parent);
|
||||
void rpl_global_repair(rpl_dodag_t *dodag, ipv6_addr_t * p_addr, uint16_t rank);
|
||||
rpl_parent_t *rpl_find_preferred_parent(void);
|
||||
void rpl_parent_update(rpl_parent_t *parent);
|
||||
void rpl_global_repair(rpl_dodag_t *dodag, ipv6_addr_t *p_addr, uint16_t rank);
|
||||
void rpl_local_repair(void);
|
||||
uint16_t rpl_calc_rank(uint16_t abs_rank, uint16_t minhoprankincrease);
|
||||
|
@ -1,22 +1,40 @@
|
||||
/**
|
||||
* RPL data structs
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup rpl
|
||||
* @{
|
||||
* @file rpl_structs.h
|
||||
* @brief RPL data structs
|
||||
* @author Eric Engel <eric.engel@fu-berlin.de>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "sys/net/sixlowpan/sixlowip.h"
|
||||
|
||||
#ifndef RPL_STRUCTS_H_INCLUDED
|
||||
#define RPL_STRUCTS_H_INCLUDED
|
||||
// Modes of Operation
|
||||
/* Modes of Operation */
|
||||
|
||||
#define NO_DOWNWARD_ROUTES 0x00
|
||||
#define NON_STORING_MODE 0x01
|
||||
#define STORING_MODE_NO_MC 0x02
|
||||
#define STORING_MODE_MC 0x03
|
||||
|
||||
//ICMP type
|
||||
/* ICMP type */
|
||||
#define ICMP_RPL_CONTROL 155
|
||||
#define RPL_SEQUENCE_WINDOW 16
|
||||
#define ICMP_CODE_DIS 0x00
|
||||
#define ICMP_CODE_DIO 0x01
|
||||
#define ICMP_CODE_DAO 0x02
|
||||
#define ICMP_CODE_DAO_ACK 0x03
|
||||
//packet base lengths
|
||||
/* packet base lengths */
|
||||
#define DIO_BASE_LEN 24
|
||||
#define DIS_BASE_LEN 2
|
||||
#define DAO_BASE_LEN 4
|
||||
@ -30,7 +48,7 @@
|
||||
#define RPL_OPT_TARGET_LEN 18
|
||||
#define RPL_OPT_TRANSIT_LEN 4
|
||||
|
||||
//message options
|
||||
/* message options */
|
||||
#define RPL_OPT_PAD1 0
|
||||
#define RPL_OPT_PADN 1
|
||||
#define RPL_OPT_DAG_METRIC_CONTAINER 2
|
||||
@ -42,7 +60,7 @@
|
||||
#define RPL_OPT_PREFIX_INFO 8
|
||||
#define RPL_OPT_TARGET_DESC 9
|
||||
|
||||
//Counters
|
||||
/* Counters */
|
||||
#define RPL_COUNTER_MAX 255
|
||||
#define RPL_COUNTER_LOWER_REGION 127
|
||||
#define RPL_COUNTER_SEQ_WINDOW 16
|
||||
@ -52,11 +70,11 @@
|
||||
#define RPL_COUNTER_GREATER_THAN_LOCAL(A,B) (((A<B) && (RPL_COUNTER_LOWER_REGION + 1 - B + A < RPL_COUNTER_SEQ_WINDOW)) || ((A > B) && (A-B < RPL_COUNTER_SEQ_WINDOW)))
|
||||
#define RPL_COUNTER_GREATER_THAN(A,B) ((A>RPL_COUNTER_LOWER_REGION) ? ((B > RPL_COUNTER_LOWER_REGION ) ? RPL_COUNTER_GREATER_THAN_LOCAL(A,B) : 0): (( B>RPL_COUNTER_LOWER_REGION ) ? 1: RPL_COUNTER_GREATER_THAN_LOCAL(A,B)))
|
||||
|
||||
// Default values
|
||||
/* Default values */
|
||||
|
||||
#define RPL_DEFAULT_MOP STORING_MODE_NO_MC
|
||||
|
||||
// RPL Constants and Variables
|
||||
/* RPL Constants and Variables */
|
||||
|
||||
#define BASE_RANK 0
|
||||
#define ROOT_RANK 1
|
||||
@ -64,21 +82,21 @@
|
||||
#define RPL_DEFAULT_INSTANCE 0
|
||||
#define DEFAULT_PATH_CONTROL_SIZE 0
|
||||
#define DEFAULT_DIO_INTERVAL_MIN 11
|
||||
//standard value:
|
||||
//#define DEFAULT_DIO_INTERVAL_MIN 3
|
||||
/* standard value: */
|
||||
/* #define DEFAULT_DIO_INTERVAL_MIN 3 */
|
||||
#define DEFAULT_DIO_INTERVAL_DOUBLINGS 7
|
||||
//standard value:
|
||||
//#define DEFAULT_DIO_INTERVAL_DOUBLINGS 20
|
||||
/* standard value: */
|
||||
/* #define DEFAULT_DIO_INTERVAL_DOUBLINGS 20 */
|
||||
#define DEFAULT_DIO_REDUNDANCY_CONSTANT 10
|
||||
#define DEFAULT_MIN_HOP_RANK_INCREASE 256
|
||||
//DAO_DELAY is in seconds
|
||||
/* DAO_DELAY is in seconds */
|
||||
#define DEFAULT_DAO_DELAY 3
|
||||
#define REGULAR_DAO_INTERVAL 300
|
||||
#define DAO_SEND_RETRIES 4
|
||||
#define DEFAULT_WAIT_FOR_DAO_ACK 15
|
||||
#define RPL_DODAG_ID_LEN 16
|
||||
|
||||
//others
|
||||
/* others */
|
||||
|
||||
#define NUMBER_IMPLEMENTED_OFS 1
|
||||
#define RPL_MAX_DODAGS 3
|
||||
@ -98,46 +116,47 @@
|
||||
#define RPL_GROUNDED_SHIFT 7
|
||||
#define RPL_DEFAULT_OCP 0
|
||||
|
||||
struct __attribute__((packed)) rpl_dio_t{
|
||||
struct __attribute__((packed)) rpl_dio_t {
|
||||
uint8_t rpl_instanceid;
|
||||
uint8_t version_number;
|
||||
uint16_t rank;
|
||||
uint8_t g_mop_prf;
|
||||
uint8_t dtsn;
|
||||
uint8_t flags;
|
||||
uint8_t flags;
|
||||
uint8_t reserved;
|
||||
ipv6_addr_t dodagid;
|
||||
};
|
||||
|
||||
struct __attribute__((packed)) rpl_dis_t{
|
||||
struct __attribute__((packed)) rpl_dis_t {
|
||||
uint8_t flags;
|
||||
uint8_t reserved;
|
||||
};
|
||||
|
||||
struct __attribute__((packed)) rpl_dao_t{
|
||||
struct __attribute__((packed)) rpl_dao_t {
|
||||
uint8_t rpl_instanceid;
|
||||
uint8_t k_d_flags;
|
||||
uint8_t reserved;
|
||||
uint8_t dao_sequence;
|
||||
};
|
||||
|
||||
struct __attribute__((packed)) rpl_dao_ack_t{
|
||||
struct __attribute__((packed)) rpl_dao_ack_t {
|
||||
uint8_t rpl_instanceid;
|
||||
uint8_t d_reserved;
|
||||
uint8_t dao_sequence;
|
||||
uint8_t status;
|
||||
};
|
||||
|
||||
//may be present in dao or dao_ack packets
|
||||
struct __attribute__((packed)) dodag_id_t{
|
||||
/* may be present in dao or dao_ack packets */
|
||||
struct __attribute__((packed)) dodag_id_t {
|
||||
ipv6_addr_t dodagid;
|
||||
};
|
||||
typedef struct __attribute__((packed)) rpl_opt_t {
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
} rpl_opt_t;
|
||||
|
||||
typedef struct __attribute__((packed)) rpl_opt_dodag_conf_t {
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
uint8_t flags_a_pcs;
|
||||
@ -152,80 +171,78 @@ typedef struct __attribute__((packed)) rpl_opt_dodag_conf_t {
|
||||
uint16_t lifetime_unit;
|
||||
} rpl_opt_dodag_conf_t;
|
||||
|
||||
typedef struct __attribute__((packed)) rpl_opt_solicited_t {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
uint8_t rplinstanceid;
|
||||
uint8_t VID_Flags;
|
||||
ipv6_addr_t dodagid;
|
||||
uint8_t version;
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
uint8_t rplinstanceid;
|
||||
uint8_t VID_Flags;
|
||||
ipv6_addr_t dodagid;
|
||||
uint8_t version;
|
||||
} rpl_opt_solicited_t;
|
||||
|
||||
//ipv6_addr_t target may be replaced by a target prefix of variable length
|
||||
typedef struct __attribute__((packed)) rpl_opt_target_t {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
uint8_t flags;
|
||||
uint8_t prefix_length;
|
||||
ipv6_addr_t target;
|
||||
/* ipv6_addr_t target may be replaced by a target prefix of variable length */
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
uint8_t flags;
|
||||
uint8_t prefix_length;
|
||||
ipv6_addr_t target;
|
||||
} rpl_opt_target_t;
|
||||
|
||||
typedef struct __attribute__((packed)) rpl_opt_transit_t {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
uint8_t e_flags;
|
||||
uint8_t path_control;
|
||||
uint8_t path_sequence;
|
||||
uint8_t path_lifetime;
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
uint8_t e_flags;
|
||||
uint8_t path_control;
|
||||
uint8_t path_sequence;
|
||||
uint8_t path_lifetime;
|
||||
} rpl_opt_transit_t;
|
||||
|
||||
struct rpl_dodag_t;
|
||||
|
||||
typedef struct rpl_parent_t {
|
||||
typedef struct {
|
||||
ipv6_addr_t addr;
|
||||
uint16_t rank;
|
||||
uint8_t dtsn;
|
||||
uint8_t dtsn;
|
||||
struct rpl_dodag_t *dodag;
|
||||
uint16_t lifetime;
|
||||
uint8_t used;
|
||||
uint16_t lifetime;
|
||||
uint8_t used;
|
||||
} rpl_parent_t;
|
||||
|
||||
struct rpl_of_t;
|
||||
|
||||
typedef struct rpl_instance_t {
|
||||
//struct rpl_dodag_t *current_dodoag;
|
||||
typedef struct {
|
||||
uint8_t id;
|
||||
uint8_t used;
|
||||
uint8_t joined;
|
||||
uint8_t joined;
|
||||
|
||||
} rpl_instance_t;
|
||||
|
||||
typedef struct rpl_dodag_t {
|
||||
typedef struct {
|
||||
rpl_instance_t *instance;
|
||||
ipv6_addr_t dodag_id;
|
||||
uint8_t used;
|
||||
uint8_t mop;
|
||||
uint8_t dtsn;
|
||||
uint8_t prf;
|
||||
uint8_t prf;
|
||||
uint8_t dio_interval_doubling;
|
||||
uint8_t dio_min;
|
||||
uint8_t dio_redundancy;
|
||||
uint16_t maxrankincrease;
|
||||
uint16_t minhoprankincrease;
|
||||
uint8_t default_lifetime;
|
||||
uint16_t lifetime_unit;
|
||||
uint16_t lifetime_unit;
|
||||
uint8_t version;
|
||||
uint8_t grounded;
|
||||
uint16_t my_rank;
|
||||
uint8_t dao_seq;
|
||||
uint16_t min_rank;
|
||||
uint8_t dao_seq;
|
||||
uint16_t min_rank;
|
||||
uint8_t joined;
|
||||
rpl_parent_t *my_preferred_parent;
|
||||
struct rpl_of_t *of;
|
||||
|
||||
struct rpl_of_t *of;
|
||||
} rpl_dodag_t;
|
||||
|
||||
typedef struct rpl_of_t {
|
||||
typedef struct {
|
||||
uint16_t ocp;
|
||||
uint16_t (*calc_rank)(rpl_parent_t *, uint16_t);
|
||||
rpl_parent_t *(*which_parent)(rpl_parent_t *, rpl_parent_t *);
|
||||
@ -234,12 +251,12 @@ typedef struct rpl_of_t {
|
||||
void (*parent_state_callback)(rpl_parent_t *, int, int);
|
||||
} rpl_of_t;
|
||||
|
||||
typedef struct rpl_routing_entry_t {
|
||||
uint8_t used;
|
||||
ipv6_addr_t address;
|
||||
ipv6_addr_t next_hop;
|
||||
uint16_t lifetime;
|
||||
|
||||
typedef struct {
|
||||
uint8_t used;
|
||||
ipv6_addr_t address;
|
||||
ipv6_addr_t next_hop;
|
||||
uint16_t lifetime;
|
||||
|
||||
} rpl_routing_entry_t;
|
||||
|
||||
#endif
|
||||
|
@ -1,3 +1,21 @@
|
||||
/**
|
||||
* Trickle implementation
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup rpl
|
||||
* @{
|
||||
* @file trickle.c
|
||||
* @brief Trickle implementation
|
||||
* @author Eric Engel <eric.engel@fu-berlin.de>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -32,180 +50,202 @@ timex_t I_time;
|
||||
timex_t dao_time;
|
||||
timex_t rt_time;
|
||||
|
||||
//struct für trickle parameter??
|
||||
void reset_trickletimer(void){
|
||||
I = Imin;
|
||||
c = 0;
|
||||
//start timer
|
||||
t = (I/2) + ( rand() % ( I - (I/2) + 1 ) );
|
||||
t_time = timex_set(0,t*1000);
|
||||
I_time = timex_set(0,I*1000);
|
||||
timex_normalize(&t_time);
|
||||
timex_normalize(&I_time);
|
||||
vtimer_remove(&trickle_t_timer);
|
||||
vtimer_remove(&trickle_I_timer);
|
||||
vtimer_set_wakeup(&trickle_t_timer, t_time, timer_over_pid);
|
||||
vtimer_set_wakeup(&trickle_I_timer, I_time, interval_over_pid);
|
||||
void reset_trickletimer(void)
|
||||
{
|
||||
I = Imin;
|
||||
c = 0;
|
||||
/* start timer */
|
||||
t = (I / 2) + (rand() % (I - (I / 2) + 1));
|
||||
t_time = timex_set(0, t * 1000);
|
||||
I_time = timex_set(0, I * 1000);
|
||||
timex_normalize(&t_time);
|
||||
timex_normalize(&I_time);
|
||||
vtimer_remove(&trickle_t_timer);
|
||||
vtimer_remove(&trickle_I_timer);
|
||||
vtimer_set_wakeup(&trickle_t_timer, t_time, timer_over_pid);
|
||||
vtimer_set_wakeup(&trickle_I_timer, I_time, interval_over_pid);
|
||||
|
||||
}
|
||||
|
||||
void init_trickle(void){
|
||||
//Create threads
|
||||
ack_received = true;
|
||||
timer_over_pid = thread_create(timer_over_buf, TRICKLE_TIMER_STACKSIZE,
|
||||
PRIORITY_MAIN-1,CREATE_STACKTEST,
|
||||
trickle_timer_over, "trickle_timer_over");
|
||||
void init_trickle(void)
|
||||
{
|
||||
/* Create threads */
|
||||
ack_received = true;
|
||||
timer_over_pid = thread_create(timer_over_buf, TRICKLE_TIMER_STACKSIZE,
|
||||
PRIORITY_MAIN - 1, CREATE_STACKTEST,
|
||||
trickle_timer_over, "trickle_timer_over");
|
||||
|
||||
interval_over_pid = thread_create(interval_over_buf, TRICKLE_INTERVAL_STACKSIZE,
|
||||
PRIORITY_MAIN-1, CREATE_STACKTEST,
|
||||
trickle_interval_over, "trickle_interval_over");
|
||||
dao_delay_over_pid = thread_create(dao_delay_over_buf, DAO_DELAY_STACKSIZE,
|
||||
PRIORITY_MAIN-1, CREATE_STACKTEST,
|
||||
dao_delay_over, "dao_delay_over");
|
||||
rt_timer_over_pid = thread_create(routing_table_buf, RT_STACKSIZE,
|
||||
PRIORITY_MAIN-1, CREATE_STACKTEST,
|
||||
rt_timer_over, "rt_timer_over");
|
||||
|
||||
}
|
||||
|
||||
void start_trickle(uint8_t DIOIntMin, uint8_t DIOIntDoubl, uint8_t DIORedundancyConstant){
|
||||
c = 0;
|
||||
k = DIORedundancyConstant;
|
||||
Imin = pow(2, DIOIntMin);
|
||||
Imax = DIOIntDoubl;
|
||||
//Eigentlich laut Spezifikation erste Bestimmung von I wie auskommentiert:
|
||||
//I = Imin + ( rand() % ( (Imin << Imax) - Imin + 1 ) );
|
||||
I = Imin + ( rand() % (4*Imin) ) ;
|
||||
|
||||
t = (I/2) + ( rand() % ( I - (I/2) + 1 ) );
|
||||
t_time = timex_set(0,t*1000);
|
||||
timex_normalize(&t_time);
|
||||
I_time = timex_set(0,I*1000);
|
||||
timex_normalize(&I_time);
|
||||
vtimer_remove(&trickle_t_timer);
|
||||
vtimer_remove(&trickle_I_timer);
|
||||
vtimer_set_wakeup(&trickle_t_timer, t_time, timer_over_pid);
|
||||
vtimer_set_wakeup(&trickle_I_timer, I_time, interval_over_pid);
|
||||
interval_over_pid = thread_create(interval_over_buf, TRICKLE_INTERVAL_STACKSIZE,
|
||||
PRIORITY_MAIN - 1, CREATE_STACKTEST,
|
||||
trickle_interval_over, "trickle_interval_over");
|
||||
dao_delay_over_pid = thread_create(dao_delay_over_buf, DAO_DELAY_STACKSIZE,
|
||||
PRIORITY_MAIN - 1, CREATE_STACKTEST,
|
||||
dao_delay_over, "dao_delay_over");
|
||||
rt_timer_over_pid = thread_create(routing_table_buf, RT_STACKSIZE,
|
||||
PRIORITY_MAIN - 1, CREATE_STACKTEST,
|
||||
rt_timer_over, "rt_timer_over");
|
||||
|
||||
}
|
||||
|
||||
void trickle_increment_counter(void){
|
||||
//call this function, when received DIO message
|
||||
void start_trickle(uint8_t DIOIntMin, uint8_t DIOIntDoubl,
|
||||
uint8_t DIORedundancyConstant)
|
||||
{
|
||||
c = 0;
|
||||
k = DIORedundancyConstant;
|
||||
Imin = pow(2, DIOIntMin);
|
||||
Imax = DIOIntDoubl;
|
||||
/* Eigentlich laut Spezifikation erste Bestimmung von I wie auskommentiert: */
|
||||
/* I = Imin + ( rand() % ( (Imin << Imax) - Imin + 1 ) ); */
|
||||
I = Imin + (rand() % (4 * Imin)) ;
|
||||
|
||||
t = (I / 2) + (rand() % (I - (I / 2) + 1));
|
||||
t_time = timex_set(0, t * 1000);
|
||||
timex_normalize(&t_time);
|
||||
I_time = timex_set(0, I * 1000);
|
||||
timex_normalize(&I_time);
|
||||
vtimer_remove(&trickle_t_timer);
|
||||
vtimer_remove(&trickle_I_timer);
|
||||
vtimer_set_wakeup(&trickle_t_timer, t_time, timer_over_pid);
|
||||
vtimer_set_wakeup(&trickle_I_timer, I_time, interval_over_pid);
|
||||
}
|
||||
|
||||
void trickle_increment_counter(void)
|
||||
{
|
||||
/* call this function, when received DIO message */
|
||||
c++;
|
||||
}
|
||||
|
||||
void trickle_timer_over(void)
|
||||
{
|
||||
ipv6_addr_t mcast;
|
||||
ipv6_set_all_nds_mcast_addr(&mcast);
|
||||
while(1){
|
||||
thread_sleep();
|
||||
//Laut RPL Spezifikation soll k=0 wie k= Unendlich behandelt werden, also immer gesendet werden
|
||||
if( (c < k) || (k == 0)){
|
||||
send_DIO(&mcast);
|
||||
}
|
||||
}
|
||||
ipv6_addr_t mcast;
|
||||
ipv6_set_all_nds_mcast_addr(&mcast);
|
||||
|
||||
while(1) {
|
||||
thread_sleep();
|
||||
|
||||
/* Laut RPL Spezifikation soll k=0 wie k= Unendlich behandelt werden, also immer gesendet werden */
|
||||
if((c < k) || (k == 0)) {
|
||||
send_DIO(&mcast);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void trickle_interval_over(void){
|
||||
while(1){
|
||||
thread_sleep();
|
||||
I = I*2;
|
||||
printf("TRICKLE new Interval %u\n",I);
|
||||
if( I == 0 ){
|
||||
puts("[WARNING] Interval was 0");
|
||||
if( Imax == 0){
|
||||
puts("[WARNING] Imax == 0");
|
||||
}
|
||||
I = (Imin << Imax);
|
||||
}
|
||||
if(I > (Imin << Imax)){
|
||||
I=(Imin << Imax);
|
||||
}
|
||||
c=0;
|
||||
t = (I/2) + ( rand() % ( I - (I/2) + 1 ) );
|
||||
//start timer
|
||||
t_time = timex_set(0,t*1000);
|
||||
timex_normalize(&t_time);
|
||||
I_time = timex_set(0,I*1000);
|
||||
timex_normalize(&I_time);
|
||||
//vtimer_remove(&trickle_t_timer);
|
||||
//vtimer_remove(&trickle_I_timer);
|
||||
if(vtimer_set_wakeup(&trickle_t_timer, t_time, timer_over_pid) != 0){
|
||||
puts("[ERROR] setting Wakeup");
|
||||
}
|
||||
if(vtimer_set_wakeup(&trickle_I_timer, I_time, interval_over_pid) != 0){
|
||||
puts("[ERROR] setting Wakeup");
|
||||
}
|
||||
}
|
||||
void trickle_interval_over(void)
|
||||
{
|
||||
while(1) {
|
||||
thread_sleep();
|
||||
I = I * 2;
|
||||
printf("TRICKLE new Interval %u\n", I);
|
||||
|
||||
if(I == 0) {
|
||||
puts("[WARNING] Interval was 0");
|
||||
|
||||
if(Imax == 0) {
|
||||
puts("[WARNING] Imax == 0");
|
||||
}
|
||||
|
||||
I = (Imin << Imax);
|
||||
}
|
||||
|
||||
if(I > (Imin << Imax)) {
|
||||
I = (Imin << Imax);
|
||||
}
|
||||
|
||||
c = 0;
|
||||
t = (I / 2) + (rand() % (I - (I / 2) + 1));
|
||||
/* start timer */
|
||||
t_time = timex_set(0, t * 1000);
|
||||
timex_normalize(&t_time);
|
||||
I_time = timex_set(0, I * 1000);
|
||||
timex_normalize(&I_time);
|
||||
|
||||
if(vtimer_set_wakeup(&trickle_t_timer, t_time, timer_over_pid) != 0) {
|
||||
puts("[ERROR] setting Wakeup");
|
||||
}
|
||||
|
||||
if(vtimer_set_wakeup(&trickle_I_timer, I_time, interval_over_pid) != 0) {
|
||||
puts("[ERROR] setting Wakeup");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void delay_dao(void){
|
||||
dao_time = timex_set(DEFAULT_DAO_DELAY,0);
|
||||
dao_counter = 0;
|
||||
ack_received = false;
|
||||
vtimer_remove(&dao_timer);
|
||||
vtimer_set_wakeup(&dao_timer, dao_time, dao_delay_over_pid);
|
||||
void delay_dao(void)
|
||||
{
|
||||
dao_time = timex_set(DEFAULT_DAO_DELAY, 0);
|
||||
dao_counter = 0;
|
||||
ack_received = false;
|
||||
vtimer_remove(&dao_timer);
|
||||
vtimer_set_wakeup(&dao_timer, dao_time, dao_delay_over_pid);
|
||||
}
|
||||
|
||||
//This function is used for regular update of the routes. The Timer can be overwritten, as the normal delay_dao function gets called
|
||||
void long_delay_dao(void){
|
||||
dao_time = timex_set(REGULAR_DAO_INTERVAL,0);
|
||||
dao_counter = 0;
|
||||
ack_received = false;
|
||||
vtimer_remove(&dao_timer);
|
||||
vtimer_set_wakeup(&dao_timer, dao_time, dao_delay_over_pid);
|
||||
/* This function is used for regular update of the routes. The Timer can be overwritten, as the normal delay_dao function gets called */
|
||||
void long_delay_dao(void)
|
||||
{
|
||||
dao_time = timex_set(REGULAR_DAO_INTERVAL, 0);
|
||||
dao_counter = 0;
|
||||
ack_received = false;
|
||||
vtimer_remove(&dao_timer);
|
||||
vtimer_set_wakeup(&dao_timer, dao_time, dao_delay_over_pid);
|
||||
}
|
||||
|
||||
void dao_delay_over(void){
|
||||
while(1){
|
||||
thread_sleep();
|
||||
if((ack_received == false) && (dao_counter < DAO_SEND_RETRIES)){
|
||||
dao_counter++;
|
||||
send_DAO(NULL, 0, true, 0);
|
||||
dao_time = timex_set(DEFAULT_WAIT_FOR_DAO_ACK,0);
|
||||
vtimer_set_wakeup(&dao_timer, dao_time, dao_delay_over_pid);
|
||||
}
|
||||
else if(ack_received == false){
|
||||
long_delay_dao();
|
||||
}
|
||||
}
|
||||
void dao_delay_over(void)
|
||||
{
|
||||
while(1) {
|
||||
thread_sleep();
|
||||
|
||||
if((ack_received == false) && (dao_counter < DAO_SEND_RETRIES)) {
|
||||
dao_counter++;
|
||||
send_DAO(NULL, 0, true, 0);
|
||||
dao_time = timex_set(DEFAULT_WAIT_FOR_DAO_ACK, 0);
|
||||
vtimer_set_wakeup(&dao_timer, dao_time, dao_delay_over_pid);
|
||||
}
|
||||
else if(ack_received == false) {
|
||||
long_delay_dao();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dao_ack_received(){
|
||||
ack_received = true;
|
||||
long_delay_dao();
|
||||
void dao_ack_received()
|
||||
{
|
||||
ack_received = true;
|
||||
long_delay_dao();
|
||||
}
|
||||
|
||||
void rt_timer_over(void){
|
||||
rpl_routing_entry_t * rt;
|
||||
while(1){
|
||||
rpl_dodag_t * my_dodag = rpl_get_my_dodag();
|
||||
if(my_dodag != NULL){
|
||||
rt = rpl_get_routing_table();
|
||||
for(uint8_t i=0; i<RPL_MAX_ROUTING_ENTRIES;i++){
|
||||
if(rt[i].used){
|
||||
if(rt[i].lifetime <= 1){
|
||||
memset(&rt[i], 0,sizeof(rt[i]));
|
||||
}
|
||||
else{
|
||||
rt[i].lifetime--;
|
||||
}
|
||||
}
|
||||
}
|
||||
//Parent is NULL for root too
|
||||
if(my_dodag->my_preferred_parent != NULL){
|
||||
if(my_dodag->my_preferred_parent->lifetime <= 1){
|
||||
puts("parent lifetime timeout");
|
||||
rpl_parent_update(NULL);
|
||||
}
|
||||
else{
|
||||
my_dodag->my_preferred_parent->lifetime--;
|
||||
}
|
||||
}
|
||||
}
|
||||
//Wake up every second
|
||||
vtimer_usleep(1000000);
|
||||
}
|
||||
void rt_timer_over(void)
|
||||
{
|
||||
rpl_routing_entry_t *rt;
|
||||
|
||||
while(1) {
|
||||
rpl_dodag_t *my_dodag = rpl_get_my_dodag();
|
||||
|
||||
if(my_dodag != NULL) {
|
||||
rt = rpl_get_routing_table();
|
||||
|
||||
for(uint8_t i = 0; i < RPL_MAX_ROUTING_ENTRIES; i++) {
|
||||
if(rt[i].used) {
|
||||
if(rt[i].lifetime <= 1) {
|
||||
memset(&rt[i], 0, sizeof(rt[i]));
|
||||
}
|
||||
else {
|
||||
rt[i].lifetime--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Parent is NULL for root too */
|
||||
if(my_dodag->my_preferred_parent != NULL) {
|
||||
if(my_dodag->my_preferred_parent->lifetime <= 1) {
|
||||
puts("parent lifetime timeout");
|
||||
rpl_parent_update(NULL);
|
||||
}
|
||||
else {
|
||||
my_dodag->my_preferred_parent->lifetime--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Wake up every second */
|
||||
vtimer_usleep(1000000);
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,26 @@
|
||||
/**
|
||||
* Trickle constants and prototypes
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup rpl
|
||||
* @{
|
||||
* @file trickle.h
|
||||
* @brief Trickle
|
||||
* @author Eric Engel <eric.engel@fu-berlin.de>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <vtimer.h>
|
||||
#include <thread.h>
|
||||
|
||||
#define TRICKLE_TIMER_STACKSIZE 3072
|
||||
//#define TRICKLE_TIMER_STACKSIZE 4096
|
||||
#define TRICKLE_TIMER_STACKSIZE 3072
|
||||
#define TRICKLE_INTERVAL_STACKSIZE 3072
|
||||
//#define DAO_DELAY_STACKSIZE 2048
|
||||
#define DAO_DELAY_STACKSIZE 3072
|
||||
//#define DAO_DELAY_STACKSIZE 4096
|
||||
#define RT_STACKSIZE 512
|
||||
|
||||
void reset_trickletimer(void);
|
||||
|
@ -1,31 +1,54 @@
|
||||
/**
|
||||
* Semaphore implemenation
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file semaphore.c
|
||||
* @brief Implemntation of semaphores using mutexes
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <mutex.h>
|
||||
|
||||
#include "semaphore.h"
|
||||
|
||||
void sem_init(sem_t *sem, int8_t value) {
|
||||
void sem_init(sem_t *sem, int8_t value)
|
||||
{
|
||||
sem->value = value;
|
||||
mutex_init(&sem->mutex);
|
||||
sem->locked = 0;
|
||||
}
|
||||
|
||||
int sem_wait(sem_t *sem) {
|
||||
int sem_wait(sem_t *sem)
|
||||
{
|
||||
int res;
|
||||
|
||||
if(--(sem->value) <= 0 && !sem->locked) {
|
||||
sem->locked = !(sem->locked);
|
||||
res = mutex_lock(&(sem->mutex));
|
||||
if (res < 0) {
|
||||
|
||||
if(res < 0) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sem_signal(sem_t *sem) {
|
||||
if (++(sem->value) > 0 && sem->locked) {
|
||||
int sem_signal(sem_t *sem)
|
||||
{
|
||||
if(++(sem->value) > 0 && sem->locked) {
|
||||
sem->locked = !(sem->locked);
|
||||
mutex_unlock(&(sem->mutex),0);
|
||||
mutex_unlock(&(sem->mutex), 0);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,3 +1,21 @@
|
||||
/**
|
||||
* Semaphore data struct and prototypes
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file semaphore.h
|
||||
* @brief data struct and prototypes for semaphores
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef SEMAPHORE_H
|
||||
#define SEMAPHORE_H
|
||||
|
||||
@ -13,5 +31,5 @@ typedef struct sem_t {
|
||||
void sem_init(sem_t *sem, int8_t value);
|
||||
int sem_wait(sem_t *sem);
|
||||
int sem_signal(sem_t *sem);
|
||||
|
||||
|
||||
#endif /* SEMAPHORE_H*/
|
||||
|
@ -1,58 +1,101 @@
|
||||
/**
|
||||
* serial number arithmetics (corresponding RFC1982) for version field in ABRO
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file serialnumber.c
|
||||
* @brief serial number arithmetics (corresponding RFC1982) for version field in ABRO
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
#include "serialnumber.h"
|
||||
|
||||
int serial_add8(uint8_t s, uint8_t n) {
|
||||
if (n > 127)
|
||||
int serial_add8(uint8_t s, uint8_t n)
|
||||
{
|
||||
if(n > 127) {
|
||||
return -1;
|
||||
uint16_t sum = s+n;
|
||||
return (uint8_t)(sum%256);
|
||||
}
|
||||
|
||||
uint16_t sum = s + n;
|
||||
return (uint8_t)(sum % 256);
|
||||
}
|
||||
|
||||
int serial_add16(uint16_t s, uint16_t n) {
|
||||
if (n > 32767)
|
||||
int serial_add16(uint16_t s, uint16_t n)
|
||||
{
|
||||
if(n > 32767) {
|
||||
return -1;
|
||||
uint32_t sum = s+n;
|
||||
return (uint16_t)(sum%65536);
|
||||
}
|
||||
|
||||
uint32_t sum = s + n;
|
||||
return (uint16_t)(sum % 65536);
|
||||
}
|
||||
|
||||
int serial_add32(uint32_t s, uint32_t n) {
|
||||
if (n > 2147483647)
|
||||
int serial_add32(uint32_t s, uint32_t n)
|
||||
{
|
||||
if(n > 2147483647) {
|
||||
return -1;
|
||||
uint64_t sum = s+n;
|
||||
return (uint32_t)(sum%4294967296);
|
||||
}
|
||||
|
||||
uint64_t sum = s + n;
|
||||
return (uint32_t)(sum % 4294967296);
|
||||
}
|
||||
|
||||
serial_comp_res_t serial_comp8(uint8_t s1, uint8_t s2) {
|
||||
if (s1 == s2)
|
||||
serial_comp_res_t serial_comp8(uint8_t s1, uint8_t s2)
|
||||
{
|
||||
if(s1 == s2) {
|
||||
return EQUAL;
|
||||
if ((s1 < s2 && s1 - s2 < 128) || (s1 > s2 && s1 - s2 > 128)) {
|
||||
}
|
||||
|
||||
if((s1 < s2 && s1 - s2 < 128) || (s1 > s2 && s1 - s2 > 128)) {
|
||||
return LESS;
|
||||
}
|
||||
if ((s1 < s2 && s1 - s2 > 128) || (s1 > s2 && s1 - s2 < 128)) {
|
||||
|
||||
if((s1 < s2 && s1 - s2 > 128) || (s1 > s2 && s1 - s2 < 128)) {
|
||||
return GREATER;
|
||||
}
|
||||
|
||||
return UNDEF;
|
||||
}
|
||||
|
||||
serial_comp_res_t serial_comp16(uint16_t s1, uint16_t s2) {
|
||||
if (s1 == s2)
|
||||
serial_comp_res_t serial_comp16(uint16_t s1, uint16_t s2)
|
||||
{
|
||||
if(s1 == s2) {
|
||||
return EQUAL;
|
||||
if ((s1 < s2 && s1 - s2 < 32768) || (s1 > s2 && s1 - s2 > 32768)) {
|
||||
}
|
||||
|
||||
if((s1 < s2 && s1 - s2 < 32768) || (s1 > s2 && s1 - s2 > 32768)) {
|
||||
return LESS;
|
||||
}
|
||||
if ((s1 < s2 && s1 - s2 > 32768) || (s1 > s2 && s1 - s2 < 32768)) {
|
||||
|
||||
if((s1 < s2 && s1 - s2 > 32768) || (s1 > s2 && s1 - s2 < 32768)) {
|
||||
return GREATER;
|
||||
}
|
||||
|
||||
return UNDEF;
|
||||
}
|
||||
|
||||
serial_comp_res_t serial_comp32(uint32_t s1, uint32_t s2) {
|
||||
if (s1 == s2)
|
||||
serial_comp_res_t serial_comp32(uint32_t s1, uint32_t s2)
|
||||
{
|
||||
if(s1 == s2) {
|
||||
return EQUAL;
|
||||
if ((s1 < s2 && s1 - s2 < 2147483648) || (s1 > s2 && s1 - s2 > 2147483648)) {
|
||||
}
|
||||
|
||||
if((s1 < s2 && s1 - s2 < 2147483648) || (s1 > s2 && s1 - s2 > 2147483648)) {
|
||||
return LESS;
|
||||
}
|
||||
if ((s1 < s2 && s1 - s2 > 2147483648) || (s1 > s2 && s1 - s2 < 2147483648)) {
|
||||
|
||||
if((s1 < s2 && s1 - s2 > 2147483648) || (s1 > s2 && s1 - s2 < 2147483648)) {
|
||||
return GREATER;
|
||||
}
|
||||
|
||||
return UNDEF;
|
||||
}
|
||||
|
@ -1,3 +1,21 @@
|
||||
/**
|
||||
* 6lowpan border router implementation
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file sixlowborder.c
|
||||
* @brief constraint node implementation for a 6lowpan border router
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
@ -28,140 +46,156 @@ uint16_t serial_reader_pid;
|
||||
uint8_t serial_out_buf[BORDER_BUFFER_SIZE];
|
||||
uint8_t serial_in_buf[BORDER_BUFFER_SIZE];
|
||||
|
||||
uint8_t *get_serial_out_buffer(int offset) {
|
||||
if (offset > BUFFER_SIZE) {
|
||||
uint8_t *get_serial_out_buffer(int offset)
|
||||
{
|
||||
if(offset > BUFFER_SIZE) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
return &(serial_out_buf[offset]);
|
||||
}
|
||||
|
||||
uint8_t *get_serial_in_buffer(int offset) {
|
||||
if (offset > BUFFER_SIZE) {
|
||||
uint8_t *get_serial_in_buffer(int offset)
|
||||
{
|
||||
if(offset > BUFFER_SIZE) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
return &(serial_in_buf[offset]);
|
||||
}
|
||||
|
||||
uint16_t border_get_serial_reader() {
|
||||
uint16_t border_get_serial_reader()
|
||||
{
|
||||
return serial_reader_pid;
|
||||
}
|
||||
|
||||
void serial_reader_f(void) {
|
||||
void serial_reader_f(void)
|
||||
{
|
||||
int main_pid = 0;
|
||||
int bytes;
|
||||
msg_t m;
|
||||
border_packet_t *uart_buf;
|
||||
|
||||
|
||||
posix_open(uart0_handler_pid, 0);
|
||||
|
||||
|
||||
msg_receive(&m);
|
||||
main_pid = m.sender_pid;
|
||||
|
||||
|
||||
while(1) {
|
||||
posix_open(uart0_handler_pid, 0);
|
||||
bytes = readpacket(get_serial_in_buffer(0), BORDER_BUFFER_SIZE);
|
||||
if (bytes < 0) {
|
||||
switch (bytes) {
|
||||
case (-SIXLOWERROR_ARRAYFULL):{
|
||||
|
||||
if(bytes < 0) {
|
||||
switch(bytes) {
|
||||
case(-SIXLOWERROR_ARRAYFULL): {
|
||||
printf("ERROR: Array was full\n");
|
||||
break;
|
||||
}
|
||||
default:{
|
||||
|
||||
default: {
|
||||
printf("ERROR: unknown\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
uart_buf = (border_packet_t*)get_serial_in_buffer(0);
|
||||
if (uart_buf->empty == 0) {
|
||||
if (uart_buf->type == BORDER_PACKET_CONF_TYPE) {
|
||||
border_conf_header_t *conf_packet = (border_conf_header_t*)uart_buf;
|
||||
if (conf_packet->conftype == BORDER_CONF_SYN) {
|
||||
|
||||
uart_buf = (border_packet_t *)get_serial_in_buffer(0);
|
||||
|
||||
if(uart_buf->empty == 0) {
|
||||
if(uart_buf->type == BORDER_PACKET_CONF_TYPE) {
|
||||
border_conf_header_t *conf_packet = (border_conf_header_t *)uart_buf;
|
||||
|
||||
if(conf_packet->conftype == BORDER_CONF_SYN) {
|
||||
m.content.ptr = (char *)conf_packet;
|
||||
msg_send(&m, main_pid, 1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
flowcontrol_deliver_from_uart(uart_buf, bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t border_initialize(transceiver_type_t trans,ipv6_addr_t *border_router_addr) {
|
||||
uint8_t border_initialize(transceiver_type_t trans, ipv6_addr_t *border_router_addr)
|
||||
{
|
||||
ipv6_addr_t addr;
|
||||
|
||||
|
||||
serial_reader_pid = thread_create(
|
||||
serial_reader_stack, READER_STACK_SIZE,
|
||||
PRIORITY_MAIN-1, CREATE_STACKTEST,
|
||||
serial_reader_f, "serial_reader");
|
||||
|
||||
if (border_router_addr == NULL) {
|
||||
serial_reader_stack, READER_STACK_SIZE,
|
||||
PRIORITY_MAIN - 1, CREATE_STACKTEST,
|
||||
serial_reader_f, "serial_reader");
|
||||
|
||||
if(border_router_addr == NULL) {
|
||||
border_router_addr = &addr;
|
||||
|
||||
|
||||
addr = flowcontrol_init();
|
||||
}
|
||||
|
||||
/* only allow addresses generated accoding to
|
||||
* RFC 4944 (Section 6) & RFC 2464 (Section 4) from short address
|
||||
|
||||
/* only allow addresses generated accoding to
|
||||
* RFC 4944 (Section 6) & RFC 2464 (Section 4) from short address
|
||||
* -- for now
|
||||
*/
|
||||
if ( border_router_addr->uint16[4] != HTONS(IEEE_802154_PAN_ID ^ 0x0200) ||
|
||||
border_router_addr->uint16[5] != HTONS(0x00FF) ||
|
||||
border_router_addr->uint16[6] != HTONS(0xFE00)
|
||||
) {
|
||||
if(border_router_addr->uint16[4] != HTONS(IEEE_802154_PAN_ID ^ 0x0200) ||
|
||||
border_router_addr->uint16[5] != HTONS(0x00FF) ||
|
||||
border_router_addr->uint16[6] != HTONS(0xFE00)
|
||||
) {
|
||||
return SIXLOWERROR_ADDRESS;
|
||||
}
|
||||
|
||||
// radio-address is 8-bit so this must be tested extra
|
||||
if (border_router_addr->uint8[14] != 0) {
|
||||
|
||||
/* radio-address is 8-bit so this must be tested extra */
|
||||
if(border_router_addr->uint8[14] != 0) {
|
||||
return SIXLOWERROR_ADDRESS;
|
||||
}
|
||||
|
||||
memcpy(&(abr_addr.uint8[0]),&(border_router_addr->uint8[0]),16);
|
||||
|
||||
sixlowpan_init(trans,border_router_addr->uint8[15],1);
|
||||
|
||||
|
||||
memcpy(&(abr_addr.uint8[0]), &(border_router_addr->uint8[0]), 16);
|
||||
|
||||
sixlowpan_init(trans, border_router_addr->uint8[15], 1);
|
||||
|
||||
ipv6_init_iface_as_router();
|
||||
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
void border_send_ipv6_over_lowpan(struct ipv6_hdr_t *packet, uint8_t aro_flag, uint8_t sixco_flag) {
|
||||
uint16_t offset = IPV6_HDR_LEN+HTONS(packet->length);
|
||||
|
||||
void border_send_ipv6_over_lowpan(struct ipv6_hdr_t *packet, uint8_t aro_flag, uint8_t sixco_flag)
|
||||
{
|
||||
uint16_t offset = IPV6_HDR_LEN + HTONS(packet->length);
|
||||
|
||||
packet->flowlabel = HTONS(packet->flowlabel);
|
||||
packet->length = HTONS(packet->length);
|
||||
|
||||
|
||||
memset(buffer, 0, BUFFER_SIZE);
|
||||
memcpy(buffer+LL_HDR_LEN, packet, offset);
|
||||
|
||||
lowpan_init((ieee_802154_long_t*)&(packet->destaddr.uint16[4]), (uint8_t*)packet);
|
||||
memcpy(buffer + LL_HDR_LEN, packet, offset);
|
||||
|
||||
lowpan_init((ieee_802154_long_t *)&(packet->destaddr.uint16[4]), (uint8_t *)packet);
|
||||
}
|
||||
|
||||
void border_process_lowpan(void) {
|
||||
void border_process_lowpan(void)
|
||||
{
|
||||
msg_t m;
|
||||
struct ipv6_hdr_t *ipv6_buf;
|
||||
|
||||
|
||||
while(1) {
|
||||
msg_receive(&m);
|
||||
ipv6_buf = (struct ipv6_hdr_t *)m.content.ptr;
|
||||
|
||||
if (ipv6_buf->nextheader == PROTO_NUM_ICMPV6) {
|
||||
|
||||
if(ipv6_buf->nextheader == PROTO_NUM_ICMPV6) {
|
||||
struct icmpv6_hdr_t *icmp_buf = (struct icmpv6_hdr_t *)(((uint8_t *)ipv6_buf) + IPV6_HDR_LEN);
|
||||
if (icmp_buf->type == ICMP_REDIRECT) {
|
||||
|
||||
if(icmp_buf->type == ICMP_REDIRECT) {
|
||||
continue;
|
||||
}
|
||||
if (icmpv6_demultiplex(icmp_buf) == 0) {
|
||||
|
||||
if(icmpv6_demultiplex(icmp_buf) == 0) {
|
||||
continue;
|
||||
}
|
||||
// Here, other ICMPv6 message types for ND may follow.
|
||||
|
||||
/* Here, other ICMPv6 message types for ND may follow. */
|
||||
}
|
||||
|
||||
// TODO: Bei ICMPv6-Paketen entsprechende LoWPAN-Optionen verarbeiten und entfernen
|
||||
|
||||
/* TODO: Bei ICMPv6-Paketen entsprechende LoWPAN-Optionen verarbeiten und entfernen */
|
||||
multiplex_send_ipv6_over_uart(ipv6_buf);
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,21 @@
|
||||
/**
|
||||
* 6lowpan border router prototypes
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file sixlowborder.h
|
||||
* @brief header for 6lowpan border router
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* 6LoWPAN Border Router header file */
|
||||
|
||||
#ifndef SIXLOWBORDER_H
|
||||
@ -17,7 +35,7 @@ uint16_t border_get_serial_reader(void);
|
||||
uint8_t *get_serial_out_buffer(int offset);
|
||||
uint8_t *get_serial_in_buffer(int offset);
|
||||
|
||||
uint8_t border_initialize(transceiver_type_t trans,ipv6_addr_t *border_router_addr);
|
||||
uint8_t border_initialize(transceiver_type_t trans, ipv6_addr_t *border_router_addr);
|
||||
void border_send_ipv6_over_lowpan(struct ipv6_hdr_t *packet, uint8_t aro_flag, uint8_t sixco_flag);
|
||||
void border_process_lowpan(void);
|
||||
|
||||
|
@ -1,3 +1,23 @@
|
||||
/**
|
||||
* IPv6 implementation
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file sixlowip.c
|
||||
* @brief 6lowpan IP layer functions
|
||||
* @author Stephan Zeisberg <zeisberg@mi.fu-berlin.de>
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Eric Engel <eric.engel@fu-berlin.de>
|
||||
* @author Oliver Gesch <oliver.gesch@googlemail.com>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <vtimer.h>
|
||||
@ -16,8 +36,8 @@
|
||||
uint8_t ip_send_buffer[BUFFER_SIZE];
|
||||
uint8_t buffer[BUFFER_SIZE];
|
||||
msg_t msg_queue[IP_PKT_RECV_BUF_SIZE];
|
||||
struct ipv6_hdr_t* ipv6_buf;
|
||||
struct icmpv6_hdr_t* icmp_buf;
|
||||
struct ipv6_hdr_t *ipv6_buf;
|
||||
struct icmpv6_hdr_t *icmp_buf;
|
||||
uint8_t ipv6_ext_hdr_len;
|
||||
uint8_t *nextheader;
|
||||
iface_t iface;
|
||||
@ -26,43 +46,51 @@ int udp_packet_handler_pid = 0;
|
||||
int tcp_packet_handler_pid = 0;
|
||||
int rpl_process_pid = 0;
|
||||
|
||||
struct ipv6_hdr_t* get_ipv6_buf_send(void){
|
||||
return ((struct ipv6_hdr_t*)&(ip_send_buffer[LL_HDR_LEN]));
|
||||
struct ipv6_hdr_t *get_ipv6_buf_send(void)
|
||||
{
|
||||
return ((struct ipv6_hdr_t *) & (ip_send_buffer[LL_HDR_LEN]));
|
||||
}
|
||||
|
||||
uint8_t * get_payload_buf_send(uint8_t ext_len){
|
||||
uint8_t *get_payload_buf_send(uint8_t ext_len)
|
||||
{
|
||||
return &(ip_send_buffer[LLHDR_IPV6HDR_LEN + ext_len]);
|
||||
}
|
||||
|
||||
struct ipv6_hdr_t* get_ipv6_buf(void){
|
||||
return ((struct ipv6_hdr_t*)&(buffer[LL_HDR_LEN]));
|
||||
struct ipv6_hdr_t *get_ipv6_buf(void)
|
||||
{
|
||||
return ((struct ipv6_hdr_t *) & (buffer[LL_HDR_LEN]));
|
||||
}
|
||||
|
||||
struct icmpv6_hdr_t* get_icmpv6_buf(uint8_t ext_len){
|
||||
return ((struct icmpv6_hdr_t*)&(buffer[LLHDR_IPV6HDR_LEN + ext_len]));
|
||||
struct icmpv6_hdr_t *get_icmpv6_buf(uint8_t ext_len)
|
||||
{
|
||||
return ((struct icmpv6_hdr_t *) & (buffer[LLHDR_IPV6HDR_LEN + ext_len]));
|
||||
}
|
||||
|
||||
uint8_t * get_payload_buf(uint8_t ext_len){
|
||||
uint8_t *get_payload_buf(uint8_t ext_len)
|
||||
{
|
||||
return &(buffer[LLHDR_IPV6HDR_LEN + ext_len]);
|
||||
}
|
||||
|
||||
void sixlowpan_bootstrapping(void){
|
||||
|
||||
void sixlowpan_bootstrapping(void)
|
||||
{
|
||||
|
||||
init_rtr_sol(OPT_SLLAO);
|
||||
}
|
||||
|
||||
void sixlowpan_send(ipv6_addr_t *addr, uint8_t *payload, uint16_t p_len, uint8_t next_header){
|
||||
uint8_t *p_ptr;
|
||||
if (next_header == IPPROTO_TCP)
|
||||
{
|
||||
p_ptr = get_payload_buf_send(ipv6_ext_hdr_len);
|
||||
ipv6_buf = get_ipv6_buf_send();
|
||||
}
|
||||
else
|
||||
{
|
||||
ipv6_buf = get_ipv6_buf();
|
||||
p_ptr = get_payload_buf(ipv6_ext_hdr_len);
|
||||
}
|
||||
void sixlowpan_send(ipv6_addr_t *addr, uint8_t *payload, uint16_t p_len,
|
||||
uint8_t next_header)
|
||||
{
|
||||
uint8_t *p_ptr;
|
||||
|
||||
if(next_header == IPPROTO_TCP) {
|
||||
p_ptr = get_payload_buf_send(ipv6_ext_hdr_len);
|
||||
ipv6_buf = get_ipv6_buf_send();
|
||||
}
|
||||
else {
|
||||
ipv6_buf = get_ipv6_buf();
|
||||
p_ptr = get_payload_buf(ipv6_ext_hdr_len);
|
||||
}
|
||||
|
||||
icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len);
|
||||
packet_length = 0;
|
||||
|
||||
@ -71,143 +99,161 @@ void sixlowpan_send(ipv6_addr_t *addr, uint8_t *payload, uint16_t p_len, uint8_t
|
||||
ipv6_buf->flowlabel = 0;
|
||||
ipv6_buf->nextheader = next_header;
|
||||
ipv6_buf->hoplimit = MULTIHOP_HOPLIMIT;
|
||||
ipv6_buf->length = p_len;
|
||||
ipv6_buf->length = p_len;
|
||||
|
||||
memcpy(&(ipv6_buf->destaddr), addr, 16);
|
||||
ipv6_get_saddr(&(ipv6_buf->srcaddr), &(ipv6_buf->destaddr));
|
||||
|
||||
memcpy(p_ptr,payload,p_len);
|
||||
memcpy(p_ptr, payload, p_len);
|
||||
|
||||
packet_length = IPV6_HDR_LEN + p_len;
|
||||
|
||||
lowpan_init((ieee_802154_long_t*)&(ipv6_buf->destaddr.uint16[4]),(uint8_t*)ipv6_buf);
|
||||
lowpan_init((ieee_802154_long_t *)&(ipv6_buf->destaddr.uint16[4]),
|
||||
(uint8_t *)ipv6_buf);
|
||||
}
|
||||
|
||||
int icmpv6_demultiplex(const struct icmpv6_hdr_t *hdr) {
|
||||
int icmpv6_demultiplex(const struct icmpv6_hdr_t *hdr)
|
||||
{
|
||||
switch(hdr->type) {
|
||||
case(ICMP_RTR_SOL):{
|
||||
case(ICMP_RTR_SOL): {
|
||||
puts("INFO: packet type: icmp router solicitation");
|
||||
/* processing router solicitation */
|
||||
recv_rtr_sol();
|
||||
/* init solicited router advertisment*/
|
||||
break;
|
||||
}
|
||||
case(ICMP_RTR_ADV):{
|
||||
|
||||
case(ICMP_RTR_ADV): {
|
||||
puts("INFO: packet type: icmp router advertisment");
|
||||
/* processing router advertisment */
|
||||
recv_rtr_adv();
|
||||
/* init neighbor solicitation */
|
||||
break;
|
||||
}
|
||||
case(ICMP_NBR_SOL):{
|
||||
|
||||
case(ICMP_NBR_SOL): {
|
||||
puts("INFO: packet type: icmp neighbor solicitation");
|
||||
recv_nbr_sol();
|
||||
break;
|
||||
}
|
||||
case(ICMP_NBR_ADV):{
|
||||
|
||||
case(ICMP_NBR_ADV): {
|
||||
puts("INFO: packet type: icmp neighbor advertisment");
|
||||
recv_nbr_adv();
|
||||
break;
|
||||
}
|
||||
case(ICMP_RPL_CONTROL):{
|
||||
puts("INFO: packet type: RPL message");
|
||||
if(rpl_process_pid != 0){
|
||||
msg_t m_send;
|
||||
m_send.content.ptr = (char*) &hdr->code;
|
||||
msg_send(&m_send, rpl_process_pid, 1);
|
||||
}
|
||||
else{
|
||||
puts("INFO: no RPL handler registered");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case(ICMP_RPL_CONTROL): {
|
||||
puts("INFO: packet type: RPL message");
|
||||
|
||||
if(rpl_process_pid != 0) {
|
||||
msg_t m_send;
|
||||
m_send.content.ptr = (char *) &hdr->code;
|
||||
msg_send(&m_send, rpl_process_pid, 1);
|
||||
}
|
||||
else {
|
||||
puts("INFO: no RPL handler registered");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ipv6_process(void){
|
||||
msg_t m_recv_lowpan, m_send_lowpan;
|
||||
msg_t m_recv, m_send;
|
||||
ipv6_addr_t myaddr;
|
||||
ipv6_init_address(&myaddr, 0xabcd, 0x0, 0x0, 0x0, 0x3612, 0x00ff, 0xfe00, get_radio_address());
|
||||
|
||||
while(1){
|
||||
void ipv6_process(void)
|
||||
{
|
||||
msg_t m_recv_lowpan, m_send_lowpan;
|
||||
msg_t m_recv, m_send;
|
||||
ipv6_addr_t myaddr;
|
||||
ipv6_init_address(&myaddr, 0xabcd, 0x0, 0x0, 0x0, 0x3612, 0x00ff, 0xfe00,
|
||||
get_radio_address());
|
||||
|
||||
while(1) {
|
||||
msg_receive(&m_recv_lowpan);
|
||||
|
||||
ipv6_buf = (struct ipv6_hdr_t*) m_recv_lowpan.content.ptr;
|
||||
ipv6_buf = (struct ipv6_hdr_t *) m_recv_lowpan.content.ptr;
|
||||
|
||||
/* identifiy packet */
|
||||
nextheader = &ipv6_buf->nextheader;
|
||||
|
||||
if ((ipv6_get_addr_match(&myaddr, &ipv6_buf->destaddr) >= 112) && (ipv6_buf->destaddr.uint8[15] != myaddr.uint8[15]))
|
||||
{
|
||||
memcpy(get_ipv6_buf_send(), get_ipv6_buf(), IPV6_HDR_LEN+ipv6_buf->length);
|
||||
lowpan_init((ieee_802154_long_t*)&(ipv6_buf->destaddr.uint16[4]),(uint8_t*)get_ipv6_buf_send());
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(*nextheader) {
|
||||
case(PROTO_NUM_ICMPV6):{
|
||||
/* checksum test*/
|
||||
if(icmpv6_csum(PROTO_NUM_ICMPV6) != 0xffff){
|
||||
printf("ERROR: wrong checksum\n");
|
||||
}
|
||||
icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len);
|
||||
icmpv6_demultiplex(icmp_buf);
|
||||
break;
|
||||
}
|
||||
case(IPPROTO_TCP):
|
||||
{
|
||||
if (tcp_packet_handler_pid != 0)
|
||||
{
|
||||
m_send.content.ptr = (char*) ipv6_buf;
|
||||
msg_send_receive(&m_send, &m_recv, tcp_packet_handler_pid);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("INFO: No TCP handler registered.\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case(IPPROTO_UDP):
|
||||
{
|
||||
if (udp_packet_handler_pid != 0)
|
||||
{
|
||||
m_send.content.ptr = (char*) ipv6_buf;
|
||||
msg_send_receive(&m_send, &m_recv, udp_packet_handler_pid);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("INFO: No UDP handler registered.\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case(PROTO_NUM_NONE):
|
||||
{
|
||||
printf("INFO: Packet with no Header following the IPv6 Header received.\n");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if((ipv6_get_addr_match(&myaddr, &ipv6_buf->destaddr) >= 112) &&
|
||||
(ipv6_buf->destaddr.uint8[15] != myaddr.uint8[15])) {
|
||||
memcpy(get_ipv6_buf_send(), get_ipv6_buf(),
|
||||
IPV6_HDR_LEN + ipv6_buf->length);
|
||||
lowpan_init((ieee_802154_long_t *)&(ipv6_buf->destaddr.uint16[4]),
|
||||
(uint8_t *)get_ipv6_buf_send());
|
||||
}
|
||||
else {
|
||||
switch(*nextheader) {
|
||||
case(PROTO_NUM_ICMPV6): {
|
||||
/* checksum test*/
|
||||
if(icmpv6_csum(PROTO_NUM_ICMPV6) != 0xffff) {
|
||||
printf("ERROR: wrong checksum\n");
|
||||
}
|
||||
|
||||
icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len);
|
||||
icmpv6_demultiplex(icmp_buf);
|
||||
break;
|
||||
}
|
||||
|
||||
case(IPPROTO_TCP): {
|
||||
if(tcp_packet_handler_pid != 0) {
|
||||
m_send.content.ptr = (char *) ipv6_buf;
|
||||
msg_send_receive(&m_send, &m_recv, tcp_packet_handler_pid);
|
||||
}
|
||||
else {
|
||||
printf("INFO: No TCP handler registered.\n");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case(IPPROTO_UDP): {
|
||||
if(udp_packet_handler_pid != 0) {
|
||||
m_send.content.ptr = (char *) ipv6_buf;
|
||||
msg_send_receive(&m_send, &m_recv, udp_packet_handler_pid);
|
||||
}
|
||||
else {
|
||||
printf("INFO: No UDP handler registered.\n");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case(PROTO_NUM_NONE): {
|
||||
printf("INFO: Packet with no Header following the IPv6 Header received.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
msg_reply(&m_recv_lowpan, &m_send_lowpan);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ipv6_iface_add_addr(ipv6_addr_t *addr, uint8_t state, uint32_t val_ltime, uint32_t pref_ltime, uint8_t type){
|
||||
if(ipv6_addr_unspec_match(addr) == 128){
|
||||
void ipv6_iface_add_addr(ipv6_addr_t *addr, uint8_t state, uint32_t val_ltime,
|
||||
uint32_t pref_ltime, uint8_t type)
|
||||
{
|
||||
if(ipv6_addr_unspec_match(addr) == 128) {
|
||||
printf("ERROR: unspecified address (::) can't be assigned to interface.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(ipv6_iface_addr_match(addr) != 0) {
|
||||
return;
|
||||
}
|
||||
if(iface_addr_list_count < IFACE_ADDR_LIST_LEN){
|
||||
memcpy(&(iface.addr_list[iface_addr_list_count].addr.uint8[0]), &(addr->uint8[0]), 16);
|
||||
|
||||
if(iface_addr_list_count < IFACE_ADDR_LIST_LEN) {
|
||||
memcpy(&(iface.addr_list[iface_addr_list_count].addr.uint8[0]),
|
||||
&(addr->uint8[0]), 16);
|
||||
iface.addr_list[iface_addr_list_count].state = state;
|
||||
timex_t valtime = {val_ltime, 0};
|
||||
timex_t preftime = {pref_ltime, 0};
|
||||
@ -217,56 +263,67 @@ void ipv6_iface_add_addr(ipv6_addr_t *addr, uint8_t state, uint32_t val_ltime, u
|
||||
iface.addr_list[iface_addr_list_count].pref_ltime = timex_add(now, preftime);
|
||||
iface.addr_list[iface_addr_list_count].type = type;
|
||||
iface_addr_list_count++;
|
||||
// Register to Solicited-Node multicast address according to RFC 4291
|
||||
if (type == ADDR_TYPE_ANYCAST || type == ADDR_TYPE_LINK_LOCAL ||
|
||||
type == ADDR_TYPE_GLOBAL || type == ADDR_TYPE_UNICAST) {
|
||||
|
||||
/* Register to Solicited-Node multicast address according to RFC 4291 */
|
||||
if(type == ADDR_TYPE_ANYCAST || type == ADDR_TYPE_LINK_LOCAL ||
|
||||
type == ADDR_TYPE_GLOBAL || type == ADDR_TYPE_UNICAST) {
|
||||
ipv6_addr_t sol_node_mcast_addr;
|
||||
ipv6_set_sol_node_mcast_addr(addr, &sol_node_mcast_addr);
|
||||
if (ipv6_iface_addr_match(&sol_node_mcast_addr) == NULL) {
|
||||
|
||||
if(ipv6_iface_addr_match(&sol_node_mcast_addr) == NULL) {
|
||||
ipv6_iface_add_addr(&sol_node_mcast_addr, state, val_ltime, pref_ltime, ADDR_TYPE_SOL_NODE_MCAST);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addr_list_t * ipv6_iface_addr_match(ipv6_addr_t *addr){
|
||||
addr_list_t *ipv6_iface_addr_match(ipv6_addr_t *addr)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < iface_addr_list_count; i++){
|
||||
|
||||
for(i = 0; i < iface_addr_list_count; i++) {
|
||||
if(memcmp(&(iface.addr_list[i].addr.uint8[0]),
|
||||
&(addr->uint8[0]),16) == 0){
|
||||
&(addr->uint8[0]), 16) == 0) {
|
||||
return &(iface.addr_list[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
addr_list_t * ipv6_iface_addr_prefix_eq(ipv6_addr_t *addr){
|
||||
addr_list_t *ipv6_iface_addr_prefix_eq(ipv6_addr_t *addr)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < iface_addr_list_count; i++){
|
||||
|
||||
for(i = 0; i < iface_addr_list_count; i++) {
|
||||
if(memcmp(&(iface.addr_list[i].addr.uint8[0]),
|
||||
&(addr->uint8[0]), 8) == 0){
|
||||
&(addr->uint8[0]), 8) == 0) {
|
||||
return &(iface.addr_list[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ipv6_iface_print_addrs(void){
|
||||
for(int i = 0; i < iface_addr_list_count; i++){
|
||||
void ipv6_iface_print_addrs(void)
|
||||
{
|
||||
for(int i = 0; i < iface_addr_list_count; i++) {
|
||||
ipv6_print_addr(&(iface.addr_list[i].addr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ipv6_init_addr_prefix(ipv6_addr_t *inout, ipv6_addr_t *prefix){
|
||||
void ipv6_init_addr_prefix(ipv6_addr_t *inout, ipv6_addr_t *prefix)
|
||||
{
|
||||
inout->uint16[0] = prefix->uint16[0];
|
||||
inout->uint16[1] = prefix->uint16[1];
|
||||
inout->uint16[2] = prefix->uint16[2];
|
||||
inout->uint16[3] = prefix->uint16[3];
|
||||
|
||||
memcpy(&(inout->uint8[8]),&(iface.laddr.uint8[0]), 8);
|
||||
memcpy(&(inout->uint8[8]), &(iface.laddr.uint8[0]), 8);
|
||||
}
|
||||
|
||||
void ipv6_set_prefix(ipv6_addr_t *inout, ipv6_addr_t *prefix){
|
||||
void ipv6_set_prefix(ipv6_addr_t *inout, ipv6_addr_t *prefix)
|
||||
{
|
||||
inout->uint16[0] = prefix->uint16[0];
|
||||
inout->uint16[1] = prefix->uint16[1];
|
||||
inout->uint16[2] = prefix->uint16[2];
|
||||
@ -277,7 +334,8 @@ void ipv6_set_prefix(ipv6_addr_t *inout, ipv6_addr_t *prefix){
|
||||
inout->uint16[7] = 0;
|
||||
}
|
||||
|
||||
void ipv6_set_all_rtrs_mcast_addr(ipv6_addr_t *ipaddr){
|
||||
void ipv6_set_all_rtrs_mcast_addr(ipv6_addr_t *ipaddr)
|
||||
{
|
||||
ipaddr->uint16[0] = HTONS(0xff02);
|
||||
ipaddr->uint16[1] = 0;
|
||||
ipaddr->uint16[2] = 0;
|
||||
@ -288,7 +346,8 @@ void ipv6_set_all_rtrs_mcast_addr(ipv6_addr_t *ipaddr){
|
||||
ipaddr->uint16[7] = HTONS(0x0002);
|
||||
}
|
||||
|
||||
void ipv6_set_all_nds_mcast_addr(ipv6_addr_t *ipaddr){
|
||||
void ipv6_set_all_nds_mcast_addr(ipv6_addr_t *ipaddr)
|
||||
{
|
||||
ipaddr->uint16[0] = HTONS(0xff02);
|
||||
ipaddr->uint16[1] = 0;
|
||||
ipaddr->uint16[2] = 0;
|
||||
@ -299,7 +358,8 @@ void ipv6_set_all_nds_mcast_addr(ipv6_addr_t *ipaddr){
|
||||
ipaddr->uint16[7] = HTONS(0x0001);
|
||||
}
|
||||
|
||||
void ipv6_set_loaddr(ipv6_addr_t *ipaddr){
|
||||
void ipv6_set_loaddr(ipv6_addr_t *ipaddr)
|
||||
{
|
||||
ipaddr->uint16[0] = 0;
|
||||
ipaddr->uint16[1] = 0;
|
||||
ipaddr->uint16[2] = 0;
|
||||
@ -310,63 +370,74 @@ void ipv6_set_loaddr(ipv6_addr_t *ipaddr){
|
||||
ipaddr->uint16[7] = HTONS(0x0001);
|
||||
}
|
||||
|
||||
void ipv6_get_saddr(ipv6_addr_t *src, ipv6_addr_t *dst){
|
||||
void ipv6_get_saddr(ipv6_addr_t *src, ipv6_addr_t *dst)
|
||||
{
|
||||
/* try to find best match if dest is not mcast or link local */
|
||||
int8_t itmp = -1;
|
||||
uint8_t tmp = 0;
|
||||
uint8_t bmatch = 0;
|
||||
uint8_t tmp = 0;
|
||||
uint8_t bmatch = 0;
|
||||
|
||||
if(!(ipv6_prefix_ll_match(dst)) && !(ipv6_prefix_mcast_match(dst))){
|
||||
for(int i = 0; i < IFACE_ADDR_LIST_LEN; i++){
|
||||
if(iface.addr_list[i].state == ADDR_STATE_PREFERRED){
|
||||
if(!(ipv6_prefix_ll_match(&(iface.addr_list[i].addr)))){
|
||||
if(!(ipv6_prefix_ll_match(dst)) && !(ipv6_prefix_mcast_match(dst))) {
|
||||
for(int i = 0; i < IFACE_ADDR_LIST_LEN; i++) {
|
||||
if(iface.addr_list[i].state == ADDR_STATE_PREFERRED) {
|
||||
if(!(ipv6_prefix_ll_match(&(iface.addr_list[i].addr)))) {
|
||||
tmp = ipv6_get_addr_match(dst, &(iface.addr_list[i].addr));
|
||||
if(tmp >= bmatch){
|
||||
|
||||
if(tmp >= bmatch) {
|
||||
bmatch = tmp;
|
||||
itmp = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for(int j=0; j < IFACE_ADDR_LIST_LEN; j++){
|
||||
}
|
||||
else {
|
||||
for(int j = 0; j < IFACE_ADDR_LIST_LEN; j++) {
|
||||
if((iface.addr_list[j].state == ADDR_STATE_PREFERRED) &&
|
||||
ipv6_prefix_ll_match(&(iface.addr_list[j].addr))){
|
||||
itmp = j;
|
||||
}
|
||||
ipv6_prefix_ll_match(&(iface.addr_list[j].addr))) {
|
||||
itmp = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(itmp == -1){
|
||||
if(itmp == -1) {
|
||||
memset(src, 0, 16);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
memcpy(src, &(iface.addr_list[itmp].addr), 16);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ipv6_get_addr_match(ipv6_addr_t *src, ipv6_addr_t *dst){
|
||||
uint8_t ipv6_get_addr_match(ipv6_addr_t *src, ipv6_addr_t *dst)
|
||||
{
|
||||
uint8_t val = 0, xor;
|
||||
for(int i = 0; i < 16; i++){
|
||||
|
||||
for(int i = 0; i < 16; i++) {
|
||||
/* if bytes are equal add 8 */
|
||||
if(src->uint8[i] == dst->uint8[i]){
|
||||
val += 8;
|
||||
} else {
|
||||
if(src->uint8[i] == dst->uint8[i]) {
|
||||
val += 8;
|
||||
}
|
||||
else {
|
||||
xor = src->uint8[i] ^ dst->uint8[i];
|
||||
|
||||
/* while bits from byte equal add 1 */
|
||||
for(int j = 0; j < 8; j++){
|
||||
if((xor & 0x80) == 0){
|
||||
for(int j = 0; j < 8; j++) {
|
||||
if((xor & 0x80) == 0) {
|
||||
val++;
|
||||
xor = xor << 1;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void ipv6_set_ll_prefix(ipv6_addr_t *ipaddr){
|
||||
void ipv6_set_ll_prefix(ipv6_addr_t *ipaddr)
|
||||
{
|
||||
ipaddr->uint16[0] = HTONS(0xfe80);
|
||||
ipaddr->uint16[1] = 0;
|
||||
ipaddr->uint16[2] = 0;
|
||||
@ -375,7 +446,8 @@ void ipv6_set_ll_prefix(ipv6_addr_t *ipaddr){
|
||||
|
||||
void ipv6_init_address(ipv6_addr_t *addr, uint16_t addr0, uint16_t addr1,
|
||||
uint16_t addr2, uint16_t addr3, uint16_t addr4,
|
||||
uint16_t addr5, uint16_t addr6, uint16_t addr7){
|
||||
uint16_t addr5, uint16_t addr6, uint16_t addr7)
|
||||
{
|
||||
addr->uint16[0] = HTONS(addr0);
|
||||
addr->uint16[1] = HTONS(addr1);
|
||||
addr->uint16[2] = HTONS(addr2);
|
||||
@ -386,43 +458,52 @@ void ipv6_init_address(ipv6_addr_t *addr, uint16_t addr0, uint16_t addr1,
|
||||
addr->uint16[7] = HTONS(addr7);
|
||||
}
|
||||
|
||||
uint8_t ipv6_prefix_ll_match(ipv6_addr_t *addr){
|
||||
if(addr->uint8[0] == 0xfe && addr->uint8[1] == 0x80){
|
||||
uint8_t ipv6_prefix_ll_match(ipv6_addr_t *addr)
|
||||
{
|
||||
if(addr->uint8[0] == 0xfe && addr->uint8[1] == 0x80) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t ipv6_prefix_mcast_match(ipv6_addr_t *addr){
|
||||
if(addr->uint8[0] == 0xff && addr->uint8[1] == 0x02){
|
||||
uint8_t ipv6_prefix_mcast_match(ipv6_addr_t *addr)
|
||||
{
|
||||
if(addr->uint8[0] == 0xff && addr->uint8[1] == 0x02) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t ipv6_addr_unspec_match(ipv6_addr_t *addr){
|
||||
if((addr->uint16[0] == 0) && (addr->uint16[1] == 0) &&
|
||||
uint8_t ipv6_addr_unspec_match(ipv6_addr_t *addr)
|
||||
{
|
||||
if((addr->uint16[0] == 0) && (addr->uint16[1] == 0) &&
|
||||
(addr->uint16[2] == 0) && (addr->uint16[3] == 0) &&
|
||||
(addr->uint16[4] == 0) && (addr->uint16[5] == 0) &&
|
||||
(addr->uint16[6] == 0) && (addr->uint16[7] == 0)){
|
||||
(addr->uint16[6] == 0) && (addr->uint16[7] == 0)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t ipv6_addr_sol_node_mcast_match(ipv6_addr_t *addr){
|
||||
uint8_t ipv6_addr_sol_node_mcast_match(ipv6_addr_t *addr)
|
||||
{
|
||||
/* note: cool if-condition*/
|
||||
if((addr->uint8[0] == 0xFF) && (addr->uint8[1] == 0x02) &&
|
||||
(addr->uint16[1] == 0x00) && (addr->uint16[2] == 0x00) &&
|
||||
(addr->uint16[3] == 0x00) && (addr->uint16[4] == 0x00) &&
|
||||
(addr->uint8[10] == 0x00) && (addr->uint8[11] == 0x01) &&
|
||||
(addr->uint8[12] == 0xFF)){
|
||||
(addr->uint8[12] == 0xFF)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ipv6_set_sol_node_mcast_addr(ipv6_addr_t *addr_in, ipv6_addr_t *addr_out){
|
||||
void ipv6_set_sol_node_mcast_addr(ipv6_addr_t *addr_in, ipv6_addr_t *addr_out)
|
||||
{
|
||||
/* copy only the last 24-bit of the ip-address that is beeing resolved */
|
||||
addr_out->uint16[0] = HTONS(0xff02);
|
||||
addr_out->uint16[1] = 0;
|
||||
@ -435,30 +516,34 @@ void ipv6_set_sol_node_mcast_addr(ipv6_addr_t *addr_in, ipv6_addr_t *addr_out){
|
||||
addr_out->uint16[7] = addr_in->uint16[7];
|
||||
}
|
||||
|
||||
void ipv6_print_addr(ipv6_addr_t *ipaddr){
|
||||
void ipv6_print_addr(ipv6_addr_t *ipaddr)
|
||||
{
|
||||
printf("%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
|
||||
((uint8_t *)ipaddr)[0], ((uint8_t *)ipaddr)[1], ((uint8_t *)ipaddr)[2],
|
||||
((uint8_t *)ipaddr)[3], ((uint8_t *)ipaddr)[4], ((uint8_t *)ipaddr)[5],
|
||||
((uint8_t *)ipaddr)[6], ((uint8_t *)ipaddr)[7], ((uint8_t *)ipaddr)[8],
|
||||
((uint8_t *)ipaddr)[9], ((uint8_t *)ipaddr)[10], ((uint8_t *)ipaddr)[11],
|
||||
((uint8_t *)ipaddr)[12], ((uint8_t *)ipaddr)[13], ((uint8_t *)ipaddr)[14],
|
||||
((uint8_t *)ipaddr)[15]);
|
||||
((uint8_t *)ipaddr)[0], ((uint8_t *)ipaddr)[1], ((uint8_t *)ipaddr)[2],
|
||||
((uint8_t *)ipaddr)[3], ((uint8_t *)ipaddr)[4], ((uint8_t *)ipaddr)[5],
|
||||
((uint8_t *)ipaddr)[6], ((uint8_t *)ipaddr)[7], ((uint8_t *)ipaddr)[8],
|
||||
((uint8_t *)ipaddr)[9], ((uint8_t *)ipaddr)[10], ((uint8_t *)ipaddr)[11],
|
||||
((uint8_t *)ipaddr)[12], ((uint8_t *)ipaddr)[13], ((uint8_t *)ipaddr)[14],
|
||||
((uint8_t *)ipaddr)[15]);
|
||||
}
|
||||
|
||||
uint8_t ipv6_next_hdr_unknown(uint8_t next_hdr) {
|
||||
uint8_t ipv6_next_hdr_unknown(uint8_t next_hdr)
|
||||
{
|
||||
return next_hdr == PROTO_NUM_ICMPV6 ||
|
||||
next_hdr == PROTO_NUM_NONE;
|
||||
}
|
||||
|
||||
|
||||
uint32_t get_remaining_time(timex_t *t){
|
||||
uint32_t get_remaining_time(timex_t *t)
|
||||
{
|
||||
timex_t now;
|
||||
vtimer_now(&now);
|
||||
|
||||
|
||||
return (timex_sub(*t, now).seconds);
|
||||
}
|
||||
|
||||
void set_remaining_time(timex_t *t, uint32_t time){
|
||||
void set_remaining_time(timex_t *t, uint32_t time)
|
||||
{
|
||||
timex_t tmp = {time, 0};
|
||||
|
||||
timex_t now;
|
||||
@ -466,33 +551,39 @@ void set_remaining_time(timex_t *t, uint32_t time){
|
||||
*t = timex_add(now, tmp);
|
||||
}
|
||||
|
||||
void ipv6_init_iface_as_router(void) {
|
||||
void ipv6_init_iface_as_router(void)
|
||||
{
|
||||
ipv6_addr_t addr;
|
||||
|
||||
|
||||
ipv6_set_all_rtrs_mcast_addr(&addr);
|
||||
ipv6_iface_add_addr(&addr,ADDR_STATE_PREFERRED,0,0,ADDR_TYPE_MULTICAST);
|
||||
ipv6_iface_add_addr(&addr, ADDR_STATE_PREFERRED, 0, 0, ADDR_TYPE_MULTICAST);
|
||||
}
|
||||
|
||||
|
||||
uint8_t ipv6_is_router(void) {
|
||||
uint8_t ipv6_is_router(void)
|
||||
{
|
||||
ipv6_addr_t addr;
|
||||
|
||||
|
||||
ipv6_set_all_rtrs_mcast_addr(&addr);
|
||||
if (ipv6_iface_addr_match(&addr) != NULL) {
|
||||
|
||||
if(ipv6_iface_addr_match(&addr) != NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void set_tcp_packet_handler_pid(int pid) {
|
||||
tcp_packet_handler_pid = pid;
|
||||
void set_tcp_packet_handler_pid(int pid)
|
||||
{
|
||||
tcp_packet_handler_pid = pid;
|
||||
}
|
||||
|
||||
void set_udp_packet_handler_pid(int pid) {
|
||||
udp_packet_handler_pid = pid;
|
||||
void set_udp_packet_handler_pid(int pid)
|
||||
{
|
||||
udp_packet_handler_pid = pid;
|
||||
}
|
||||
|
||||
void set_rpl_process_pid(int pid){
|
||||
rpl_process_pid = pid;
|
||||
void set_rpl_process_pid(int pid)
|
||||
{
|
||||
rpl_process_pid = pid;
|
||||
}
|
||||
|
@ -1,3 +1,23 @@
|
||||
/**
|
||||
* IPv6 constants, data structs, and prototypes
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file sixlowip.h
|
||||
* @brief 6lowpan IP layer header
|
||||
* @author Stephan Zeisberg <zeisberg@mi.fu-berlin.de>
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Eric Engel <eric.engel@fu-berlin.de>
|
||||
* @author Oliver Gesch <oliver.gesch@googlemail.com>
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* 6LoWPAN IP header file */
|
||||
|
||||
#ifndef SIXLOWIP_H
|
||||
@ -9,12 +29,12 @@
|
||||
|
||||
/* set maximum transmission unit */
|
||||
#define MTU 256
|
||||
/* IPv6 field values */
|
||||
/* IPv6 field values */
|
||||
#define IPV6_VER 0x60
|
||||
#define PROTO_NUM_ICMPV6 58
|
||||
#define PROTO_NUM_NONE 59
|
||||
#define ND_HOPLIMIT 0xFF
|
||||
#define SIXLOWPAN_IPV6_LL_ADDR_LEN 8
|
||||
#define SIXLOWPAN_IPV6_LL_ADDR_LEN 8
|
||||
/* size of global buffer */
|
||||
#define BUFFER_SIZE (LL_HDR_LEN + MTU)
|
||||
|
||||
@ -36,7 +56,7 @@ extern double start;
|
||||
/* base header lengths */
|
||||
#define LL_HDR_LEN 0x4
|
||||
#define ICMPV6_HDR_LEN 0x4
|
||||
#define IPV6_HDR_LEN 0x28
|
||||
#define IPV6_HDR_LEN 0x28
|
||||
#define LLHDR_IPV6HDR_LEN (LL_HDR_LEN + IPV6_HDR_LEN)
|
||||
#define LLHDR_ICMPV6HDR_LEN (LL_HDR_LEN + IPV6_HDR_LEN + ICMPV6_HDR_LEN)
|
||||
#define IPV6HDR_ICMPV6HDR_LEN (IPV6_HDR_LEN + ipv6_ext_hdr_len + ICMPV6_HDR_LEN)
|
||||
@ -46,7 +66,7 @@ extern double start;
|
||||
#define ADDR_STATE_TENTATIVE 0
|
||||
#define ADDR_STATE_PREFERRED 1
|
||||
#define ADDR_STATE_DEPRECATED 2
|
||||
/* addresses with this state are always permitted */
|
||||
/* addresses with this state are always permitted */
|
||||
#define ADDR_STATE_ANY 4
|
||||
/* how the address is configured */
|
||||
#define ADDR_CONFIGURED_AUTO 1
|
||||
@ -64,7 +84,7 @@ extern double start;
|
||||
#define DISPATCH_TYPE_IPV6 0x41
|
||||
#define DISPATCH_TYPE_LOWPAN_HC1 0x42
|
||||
/* compression types */
|
||||
#define COMPRESSION_TYPE_NONE
|
||||
#define COMPRESSION_TYPE_NONE
|
||||
|
||||
/* buffer */
|
||||
extern uint8_t buffer[BUFFER_SIZE];
|
||||
@ -72,19 +92,19 @@ extern uint8_t buffer[BUFFER_SIZE];
|
||||
|
||||
/* ipv6 extension header length */
|
||||
|
||||
typedef union __attribute__ ((packed)) ipv6_addr_t{
|
||||
typedef union __attribute__((packed)) {
|
||||
uint8_t uint8[16];
|
||||
uint16_t uint16[8];
|
||||
uint32_t uint32[4];
|
||||
} ipv6_addr_t;
|
||||
|
||||
struct __attribute__ ((packed)) icmpv6_hdr_t{
|
||||
struct __attribute__((packed)) icmpv6_hdr_t {
|
||||
uint8_t type;
|
||||
uint8_t code;
|
||||
uint16_t checksum;
|
||||
};
|
||||
|
||||
typedef struct __attribute__ ((packed)) ipv6_hdr_t{
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t version_trafficclass;
|
||||
uint8_t trafficclass_flowlabel;
|
||||
uint16_t flowlabel;
|
||||
@ -96,17 +116,17 @@ typedef struct __attribute__ ((packed)) ipv6_hdr_t{
|
||||
} ipv6_hdr_t;
|
||||
|
||||
/* link layer addressing */
|
||||
typedef union __attribute__ ((packed)) ieee_802154_long_t {
|
||||
typedef union __attribute__((packed)) {
|
||||
uint8_t uint8[8];
|
||||
uint16_t uint16[4];
|
||||
uint16_t uint16[4];
|
||||
} ieee_802154_long_t;
|
||||
|
||||
typedef union __attribute__ ((packed)) ieee_802154_short_t {
|
||||
typedef union __attribute__((packed)) {
|
||||
uint8_t uint8[2];
|
||||
uint16_t uint16[1];
|
||||
} ieee_802154_short_t;
|
||||
|
||||
typedef struct __attribute__ ((packed)) addr_list_t {
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t state;
|
||||
timex_t val_ltime;
|
||||
timex_t pref_ltime;
|
||||
@ -114,7 +134,7 @@ typedef struct __attribute__ ((packed)) addr_list_t {
|
||||
ipv6_addr_t addr;
|
||||
} addr_list_t;
|
||||
|
||||
typedef struct __attribute__ ((packed)) iface_t {
|
||||
typedef struct __attribute__((packed)) {
|
||||
ieee_802154_short_t saddr;
|
||||
ieee_802154_long_t laddr;
|
||||
addr_list_t addr_list[IFACE_ADDR_LIST_LEN];
|
||||
@ -126,10 +146,10 @@ typedef struct __attribute__ ((packed)) iface_t {
|
||||
extern iface_t iface;
|
||||
|
||||
/* function prototypes */
|
||||
struct icmpv6_hdr_t* get_icmpv6_buf(uint8_t ext_len);
|
||||
struct ipv6_hdr_t* get_ipv6_buf(void);
|
||||
uint8_t * get_payload_buf(uint8_t ext_len);
|
||||
uint8_t * get_payload_buf_send(uint8_t ext_len);
|
||||
struct icmpv6_hdr_t *get_icmpv6_buf(uint8_t ext_len);
|
||||
struct ipv6_hdr_t *get_ipv6_buf(void);
|
||||
uint8_t *get_payload_buf(uint8_t ext_len);
|
||||
uint8_t *get_payload_buf_send(uint8_t ext_len);
|
||||
|
||||
int icmpv6_demultiplex(const struct icmpv6_hdr_t *hdr);
|
||||
void ipv6_init_iface_as_router(void);
|
||||
@ -147,10 +167,10 @@ void ipv6_get_saddr(ipv6_addr_t *src, ipv6_addr_t *dst);
|
||||
uint8_t ipv6_get_addr_match(ipv6_addr_t *src, ipv6_addr_t *dst);
|
||||
uint8_t ipv6_prefix_mcast_match(ipv6_addr_t *addr);
|
||||
uint8_t ipv6_prefix_ll_match(ipv6_addr_t *addr);
|
||||
void ipv6_iface_add_addr(ipv6_addr_t* addr, uint8_t state, uint32_t val_ltime,
|
||||
void ipv6_iface_add_addr(ipv6_addr_t *addr, uint8_t state, uint32_t val_ltime,
|
||||
uint32_t pref_ltime, uint8_t type);
|
||||
addr_list_t * ipv6_iface_addr_prefix_eq(ipv6_addr_t *addr);
|
||||
addr_list_t * ipv6_iface_addr_match(ipv6_addr_t *addr);
|
||||
addr_list_t *ipv6_iface_addr_prefix_eq(ipv6_addr_t *addr);
|
||||
addr_list_t *ipv6_iface_addr_match(ipv6_addr_t *addr);
|
||||
void ipv6_iface_print_addrs(void);
|
||||
void ipv6_init_addr_prefix(ipv6_addr_t *inout, ipv6_addr_t *prefix);
|
||||
void ipv6_init_address(ipv6_addr_t *addr, uint16_t addr0, uint16_t addr1,
|
||||
|
@ -1,4 +1,23 @@
|
||||
/* 6LoWPAN MAC - layer 2 implementations */
|
||||
/*
|
||||
* 6LoWPAN MAC - layer 2 implementations
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file sixlowmac.c
|
||||
* @brief 6lowpan link layer functions
|
||||
* @author Stephan Zeisberg <zeisberg@mi.fu-berlin.de>
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Eric Engel <eric.engel@fu-berlin.de>
|
||||
* @author Oliver Gesch <oliver.gesch@googlemail.com>
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -24,7 +43,6 @@ static uint8_t r_src_addr;
|
||||
uint8_t buf[PAYLOAD_SIZE];
|
||||
uint16_t packet_length;
|
||||
static uint8_t macdsn;
|
||||
//static uint8_t macbsn;
|
||||
|
||||
mutex_t buf_mutex;
|
||||
|
||||
@ -34,58 +52,65 @@ int transceiver_type;
|
||||
static transceiver_command_t tcmd;
|
||||
uint16_t fragmentcounter = 0;
|
||||
|
||||
uint8_t get_radio_address(void){
|
||||
uint8_t get_radio_address(void)
|
||||
{
|
||||
int16_t address;
|
||||
|
||||
tcmd.transceivers = transceiver_type;
|
||||
tcmd.data = &address;
|
||||
mesg.content.ptr = (char*)&tcmd;
|
||||
mesg.content.ptr = (char *)&tcmd;
|
||||
mesg.type = GET_ADDRESS;
|
||||
msg_send_receive(&mesg,&mesg,transceiver_pid);
|
||||
|
||||
msg_send_receive(&mesg, &mesg, transceiver_pid);
|
||||
|
||||
return (uint8_t)address;
|
||||
}
|
||||
|
||||
void set_radio_address(uint8_t addr){
|
||||
void set_radio_address(uint8_t addr)
|
||||
{
|
||||
int16_t address = (int16_t)addr;
|
||||
|
||||
|
||||
tcmd.transceivers = transceiver_type;
|
||||
tcmd.data = &address;
|
||||
mesg.content.ptr = (char*)&tcmd;
|
||||
mesg.content.ptr = (char *)&tcmd;
|
||||
mesg.type = SET_ADDRESS;
|
||||
msg_send_receive(&mesg, &mesg, transceiver_pid);
|
||||
}
|
||||
|
||||
void set_radio_channel(uint8_t channel){
|
||||
void set_radio_channel(uint8_t channel)
|
||||
{
|
||||
int16_t chan = (int16_t)channel;
|
||||
|
||||
|
||||
tcmd.transceivers = transceiver_type;
|
||||
tcmd.data = &chan;
|
||||
mesg.content.ptr = (char*)&tcmd;
|
||||
mesg.content.ptr = (char *)&tcmd;
|
||||
mesg.type = SET_CHANNEL;
|
||||
msg_send_receive(&mesg,&mesg,transceiver_pid);
|
||||
msg_send_receive(&mesg, &mesg, transceiver_pid);
|
||||
}
|
||||
|
||||
void switch_to_rx(void){
|
||||
void switch_to_rx(void)
|
||||
{
|
||||
mesg.type = SWITCH_RX;
|
||||
mesg.content.ptr = (char*) &tcmd;
|
||||
mesg.content.ptr = (char *) &tcmd;
|
||||
tcmd.transceivers = TRANSCEIVER_CC1100;
|
||||
msg_send(&mesg, transceiver_pid, 1);
|
||||
}
|
||||
|
||||
void init_802154_short_addr(ieee_802154_short_t *saddr){
|
||||
void init_802154_short_addr(ieee_802154_short_t *saddr)
|
||||
{
|
||||
saddr->uint8[0] = 0;
|
||||
saddr->uint8[1] = get_radio_address();
|
||||
}
|
||||
|
||||
ieee_802154_long_t* mac_get_eui(ipv6_addr_t *ipaddr){
|
||||
return ((ieee_802154_long_t *) &(ipaddr->uint8[8]));
|
||||
ieee_802154_long_t *mac_get_eui(ipv6_addr_t *ipaddr)
|
||||
{
|
||||
return ((ieee_802154_long_t *) & (ipaddr->uint8[8]));
|
||||
}
|
||||
|
||||
void init_802154_long_addr(ieee_802154_long_t *laddr){
|
||||
void init_802154_long_addr(ieee_802154_long_t *laddr)
|
||||
{
|
||||
// 16bit Pan-ID:16-zero-bits:16-bit-short-addr = 48bit
|
||||
laddr->uint16[0] = IEEE_802154_PAN_ID;
|
||||
|
||||
|
||||
/* RFC 4944 Section 6 / RFC 2464 Section 4 */
|
||||
laddr->uint8[0] ^= 0x02;
|
||||
laddr->uint8[2] = 0;
|
||||
@ -96,30 +121,32 @@ void init_802154_long_addr(ieee_802154_long_t *laddr){
|
||||
laddr->uint8[7] = get_radio_address();
|
||||
}
|
||||
|
||||
void recv_ieee802154_frame(void){
|
||||
void recv_ieee802154_frame(void)
|
||||
{
|
||||
msg_t m;
|
||||
radio_packet_t *p;
|
||||
uint8_t hdrlen, length;
|
||||
ieee802154_frame_t frame;
|
||||
|
||||
|
||||
msg_init_queue(msg_q, RADIO_RCV_BUF_SIZE);
|
||||
|
||||
while (1) {
|
||||
while(1) {
|
||||
msg_receive(&m);
|
||||
if (m.type == PKT_PENDING) {
|
||||
|
||||
p = (radio_packet_t*) m.content.ptr;
|
||||
if(m.type == PKT_PENDING) {
|
||||
|
||||
p = (radio_packet_t *) m.content.ptr;
|
||||
hdrlen = read_802154_frame(p->data, &frame, p->length);
|
||||
length = p->length - hdrlen;
|
||||
|
||||
/* deliver packet to network(6lowpan)-layer */
|
||||
fragmentcounter++;
|
||||
lowpan_read(frame.payload, length, (ieee_802154_long_t*)&frame.src_addr,
|
||||
(ieee_802154_long_t*)&frame.dest_addr);
|
||||
fragmentcounter++;
|
||||
lowpan_read(frame.payload, length, (ieee_802154_long_t *)&frame.src_addr,
|
||||
(ieee_802154_long_t *)&frame.dest_addr);
|
||||
|
||||
p->processing--;
|
||||
}
|
||||
else if (m.type == ENOBUFFER) {
|
||||
else if(m.type == ENOBUFFER) {
|
||||
puts("Transceiver buffer full");
|
||||
}
|
||||
else {
|
||||
@ -129,7 +156,8 @@ void recv_ieee802154_frame(void){
|
||||
}
|
||||
|
||||
void set_ieee802154_fcf_values(ieee802154_frame_t *frame, uint8_t dest_mode,
|
||||
uint8_t src_mode){
|
||||
uint8_t src_mode)
|
||||
{
|
||||
frame->fcf.frame_type = IEEE_802154_DATA_FRAME;
|
||||
frame->fcf.sec_enb = 0;
|
||||
frame->fcf.frame_pend = 0;
|
||||
@ -140,7 +168,8 @@ void set_ieee802154_fcf_values(ieee802154_frame_t *frame, uint8_t dest_mode,
|
||||
frame->fcf.dest_addr_m = dest_mode;
|
||||
}
|
||||
|
||||
void set_ieee802154_frame_values(ieee802154_frame_t *frame){
|
||||
void set_ieee802154_frame_values(ieee802154_frame_t *frame)
|
||||
{
|
||||
// TODO: addresse aus ip paket auslesen und in frame einfuegen
|
||||
frame->dest_pan_id = IEEE_802154_PAN_ID;
|
||||
frame->src_pan_id = IEEE_802154_PAN_ID;
|
||||
@ -148,25 +177,26 @@ void set_ieee802154_frame_values(ieee802154_frame_t *frame){
|
||||
macdsn++;
|
||||
}
|
||||
|
||||
void send_ieee802154_frame(ieee_802154_long_t *addr, uint8_t *payload,
|
||||
uint8_t length, uint8_t mcast){
|
||||
void send_ieee802154_frame(ieee_802154_long_t *addr, uint8_t *payload,
|
||||
uint8_t length, uint8_t mcast)
|
||||
{
|
||||
uint16_t daddr;
|
||||
/* TODO: check if dedicated response struct is necessary */
|
||||
msg_t transceiver_rsp;
|
||||
r_src_addr = local_address;
|
||||
mesg.type = SND_PKT;
|
||||
mesg.content.ptr = (char*) &tcmd;
|
||||
mesg.content.ptr = (char *) &tcmd;
|
||||
|
||||
tcmd.transceivers = transceiver_type;
|
||||
tcmd.data = &p;
|
||||
|
||||
ieee802154_frame_t frame;
|
||||
|
||||
|
||||
ieee802154_frame_t frame;
|
||||
|
||||
memset(&frame, 0, sizeof(frame));
|
||||
set_ieee802154_fcf_values(&frame, IEEE_802154_LONG_ADDR_M,
|
||||
set_ieee802154_fcf_values(&frame, IEEE_802154_LONG_ADDR_M,
|
||||
IEEE_802154_LONG_ADDR_M);
|
||||
set_ieee802154_frame_values(&frame);
|
||||
|
||||
set_ieee802154_frame_values(&frame);
|
||||
|
||||
memcpy(&(frame.dest_addr[0]), &(addr->uint8[0]), 8);
|
||||
memcpy(&(frame.src_addr[0]), &(iface.laddr.uint8[0]), 8);
|
||||
|
||||
@ -174,18 +204,20 @@ void send_ieee802154_frame(ieee_802154_long_t *addr, uint8_t *payload,
|
||||
frame.payload = payload;
|
||||
frame.payload_len = length;
|
||||
uint8_t hdrlen = get_802154_hdr_len(&frame);
|
||||
|
||||
memset(&buf,0,PAYLOAD_SIZE);
|
||||
init_802154_frame(&frame,(uint8_t*)&buf);
|
||||
memcpy(&buf[hdrlen],frame.payload,frame.payload_len);
|
||||
|
||||
|
||||
memset(&buf, 0, PAYLOAD_SIZE);
|
||||
init_802154_frame(&frame, (uint8_t *)&buf);
|
||||
memcpy(&buf[hdrlen], frame.payload, frame.payload_len);
|
||||
|
||||
/* mutex unlock */
|
||||
mutex_unlock(&buf_mutex, 0);
|
||||
|
||||
|
||||
p.length = hdrlen + frame.payload_len;
|
||||
if(mcast == 0){
|
||||
|
||||
if(mcast == 0) {
|
||||
p.dst = daddr;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
p.dst = 0;
|
||||
}
|
||||
|
||||
@ -196,14 +228,14 @@ void send_ieee802154_frame(ieee_802154_long_t *addr, uint8_t *payload,
|
||||
hwtimer_wait(5000);
|
||||
}
|
||||
|
||||
void sixlowmac_init(transceiver_type_t type){
|
||||
int recv_pid = thread_create(radio_stack_buffer, RADIO_STACK_SIZE,
|
||||
PRIORITY_MAIN-2, CREATE_STACKTEST, recv_ieee802154_frame , "radio");
|
||||
// hwtimer_init();
|
||||
void sixlowmac_init(transceiver_type_t type)
|
||||
{
|
||||
int recv_pid = thread_create(radio_stack_buffer, RADIO_STACK_SIZE,
|
||||
PRIORITY_MAIN - 2, CREATE_STACKTEST, recv_ieee802154_frame , "radio");
|
||||
transceiver_type = type;
|
||||
transceiver_init(transceiver_type);
|
||||
transceiver_start();
|
||||
transceiver_register(type, recv_pid);
|
||||
|
||||
macdsn = rand() % 256;
|
||||
macdsn = rand() % 256;
|
||||
}
|
||||
|
@ -1,4 +1,22 @@
|
||||
/* 6LoWPAN MAC header file */
|
||||
/*
|
||||
* 6LoWPAN MAC - layer 2 prototypes
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file sixlowmac.h
|
||||
* @brief 6lowpan link layer functions
|
||||
* @author Stephan Zeisberg <zeisberg@mi.fu-berlin.de>
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Eric Engel <eric.engel@fu-berlin.de>
|
||||
* @author Oliver Gesch <oliver.gesch@googlemail.com>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef SIXLOWMAC_H
|
||||
#define SIXLOWMAC_H
|
||||
@ -18,11 +36,11 @@ extern uint16_t fragmentcounter;
|
||||
|
||||
uint8_t get_radio_address(void);
|
||||
void set_radio_address(uint8_t addr);
|
||||
void send_ieee802154_frame(ieee_802154_long_t *addr, uint8_t *payload,
|
||||
void send_ieee802154_frame(ieee_802154_long_t *addr, uint8_t *payload,
|
||||
uint8_t length, uint8_t mcast);
|
||||
void init_802154_long_addr(ieee_802154_long_t *laddr);
|
||||
void init_802154_short_addr(ieee_802154_short_t *saddr);
|
||||
void sixlowmac_init(transceiver_type_t type);
|
||||
ieee_802154_long_t* mac_get_eui(ipv6_addr_t *ipaddr);
|
||||
ieee_802154_long_t *mac_get_eui(ipv6_addr_t *ipaddr);
|
||||
|
||||
#endif /* SIXLOWMAC_H*/
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,21 @@
|
||||
/* 6LoWPAN ND header file */
|
||||
/*
|
||||
* 6lowpan neighbor discovery
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file sixlownd.h
|
||||
* @brief 6lowpan neighbor discovery constants, data structs, and prototypes
|
||||
* @author Stephan Zeisberg <zeisberg@mi.fu-berlin.de>
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Oliver Gesch <oliver.gesch@googlemail.com>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef SIXLOWND_H
|
||||
#define SIXLOWND_H
|
||||
@ -31,19 +48,19 @@
|
||||
#define NBR_ADV_FLAG_S 0x40
|
||||
#define NBR_ADV_FLAG_O 0x20
|
||||
/* icmp message types rfc4443 */
|
||||
#define ICMP_PARA_PROB 4
|
||||
#define ICMP_PARA_PROB 4
|
||||
/* icmp message types rfc4861 4.*/
|
||||
#define ICMP_RTR_ADV 134
|
||||
#define ICMP_RTR_SOL 133
|
||||
#define ICMP_NBR_ADV 136
|
||||
#define ICMP_NBR_SOL 135
|
||||
#define ICMP_REDIRECT 137 // will be filtered out by the border router
|
||||
#define ICMP_NBR_SOL 135
|
||||
#define ICMP_REDIRECT 137 /* will be filtered out by the border router */
|
||||
/* stllao option rfc4861 4.6.1 */
|
||||
#define OPT_STLLAO_MIN_LEN 8
|
||||
#define OPT_STLLAO_MAX_LEN 16
|
||||
#define OPT_SLLAO_TYPE 1
|
||||
#define OPT_TLLAO_TYPE 2
|
||||
/* prefix info option rfc 4.6.2 */
|
||||
#define OPT_TLLAO_TYPE 2
|
||||
/* prefix info option rfc 4.6.2 */
|
||||
#define OPT_PI_LIST_LEN 5 //TODO: initalwert suchen
|
||||
#define OPT_PI_TYPE 3
|
||||
#define OPT_PI_LEN 4
|
||||
@ -56,10 +73,10 @@
|
||||
#define OPT_MTU_LEN 1
|
||||
#define OPT_MTU_HDR_LEN 8
|
||||
/* aro - address registration option draft-ietf-6lowpan-nd-14 4.2 */
|
||||
#define OPT_ARO_TYPE 31 // TBD1
|
||||
#define OPT_ARO_TYPE 31 /* TBD1 */
|
||||
#define OPT_ARO_LEN 2
|
||||
#define OPT_ARO_HDR_LEN 16
|
||||
#define OPT_ARO_LTIME 300 // geeigneten wert finden
|
||||
#define OPT_ARO_LTIME 300 /* geeigneten wert finden */
|
||||
#define OPT_ARO_STATE_SUCCESS 0
|
||||
#define OPT_ARO_STATE_DUP_ADDR 1
|
||||
#define OPT_ARO_STATE_NBR_CACHE_FULL 2
|
||||
@ -68,7 +85,7 @@
|
||||
#define OPT_6CO_MIN_LEN 2
|
||||
#define OPT_6CO_MAX_LEN 3
|
||||
#define OPT_6CO_HDR_LEN 8
|
||||
#define OPT_6CO_LTIME 5 // geeigneten Wert finden
|
||||
#define OPT_6CO_LTIME 5 /* geeigneten Wert finden */
|
||||
#define OPT_6CO_FLAG_C 0x10
|
||||
#define OPT_6CO_FLAG_CID 0x0F
|
||||
#define OPT_6CO_FLAG_C_VALUE_SET 1
|
||||
@ -84,7 +101,7 @@
|
||||
#define NBR_CACHE_TYPE_GC 1
|
||||
#define NBR_CACHE_TYPE_REG 2
|
||||
#define NBR_CACHE_TYPE_TEN 3
|
||||
#define NBR_CACHE_LTIME_TEN 20
|
||||
#define NBR_CACHE_LTIME_TEN 20
|
||||
/* neighbor status values */
|
||||
#define NBR_STATUS_INCOMPLETE 0
|
||||
#define NBR_STATUS_REACHABLE 1
|
||||
@ -92,7 +109,7 @@
|
||||
#define NBR_STATUS_DELAY 3
|
||||
#define NBR_STATUS_PROBE 4
|
||||
/* default router list size */
|
||||
#define DEF_RTR_LST_SIZE 3 // geeigneten wert finden
|
||||
#define DEF_RTR_LST_SIZE 3 /* geeigneten wert finden */
|
||||
|
||||
extern unsigned int nd_nbr_cache_rem_pid;
|
||||
|
||||
@ -105,27 +122,27 @@ enum option_types_t {
|
||||
OPT_6CO,
|
||||
OPT_ABRO,
|
||||
OPT_DAR,
|
||||
OPT_DAC,
|
||||
OPT_DAC,
|
||||
};
|
||||
|
||||
typedef struct __attribute__ ((packed)) opt_buf_t {
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
uint8_t length;
|
||||
} opt_buf_t;
|
||||
|
||||
typedef struct __attribute__ ((packed)) opt_stllao_t {
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
} opt_stllao_t;
|
||||
|
||||
typedef struct __attribute__ ((packed)) opt_mtu_t {
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
uint16_t reserved;
|
||||
uint32_t mtu;
|
||||
} opt_mtu_t;
|
||||
|
||||
typedef struct __attribute__ ((packed)) opt_pi_t {
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
uint8_t prefix_length;
|
||||
@ -133,10 +150,10 @@ typedef struct __attribute__ ((packed)) opt_pi_t {
|
||||
uint32_t val_ltime;
|
||||
uint32_t pref_ltime;
|
||||
uint32_t reserved2;
|
||||
ipv6_addr_t addr;
|
||||
ipv6_addr_t addr;
|
||||
} opt_pi_t;
|
||||
|
||||
typedef struct __attribute__ ((packed)) opt_aro_t {
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
uint8_t status;
|
||||
@ -146,7 +163,7 @@ typedef struct __attribute__ ((packed)) opt_aro_t {
|
||||
ieee_802154_long_t eui64;
|
||||
} opt_aro_t;
|
||||
|
||||
typedef struct __attribute__ ((packed)) opt_6co_hdr_t {
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
uint8_t c_length;
|
||||
@ -155,7 +172,7 @@ typedef struct __attribute__ ((packed)) opt_6co_hdr_t {
|
||||
uint16_t val_ltime;
|
||||
} opt_6co_hdr_t;
|
||||
|
||||
typedef struct __attribute__ ((packed)) opt_abro_t {
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
uint16_t version;
|
||||
@ -163,8 +180,8 @@ typedef struct __attribute__ ((packed)) opt_abro_t {
|
||||
ipv6_addr_t addr;
|
||||
} opt_abro_t;
|
||||
|
||||
typedef struct __attribute__ ((packed)) plist_t {
|
||||
uint8_t inuse;
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t inuse;
|
||||
uint8_t adv;
|
||||
ipv6_addr_t addr;
|
||||
uint8_t length;
|
||||
@ -174,7 +191,7 @@ typedef struct __attribute__ ((packed)) plist_t {
|
||||
uint8_t infinite;
|
||||
} plist_t;
|
||||
|
||||
struct __attribute__ ((packed)) rtr_adv_t {
|
||||
struct __attribute__((packed)) rtr_adv_t {
|
||||
uint8_t hoplimit;
|
||||
uint8_t autoconfig_flags;
|
||||
uint16_t router_lifetime;
|
||||
@ -182,18 +199,18 @@ struct __attribute__ ((packed)) rtr_adv_t {
|
||||
uint32_t retrans_timer;
|
||||
};
|
||||
|
||||
struct __attribute__ ((packed)) nbr_sol_t {
|
||||
struct __attribute__((packed)) nbr_sol_t {
|
||||
uint32_t reserved;
|
||||
ipv6_addr_t tgtaddr;
|
||||
ipv6_addr_t tgtaddr;
|
||||
};
|
||||
|
||||
struct __attribute__ ((packed)) nbr_adv_t {
|
||||
struct __attribute__((packed)) nbr_adv_t {
|
||||
uint8_t rso;
|
||||
uint8_t reserved[3];
|
||||
ipv6_addr_t tgtaddr;
|
||||
ipv6_addr_t tgtaddr;
|
||||
};
|
||||
|
||||
struct __attribute__ ((packed)) para_prob_t {
|
||||
struct __attribute__((packed)) para_prob_t {
|
||||
uint8_t pointer;
|
||||
};
|
||||
|
||||
@ -205,7 +222,7 @@ typedef struct __attribute__((packed)) abr_cache_t {
|
||||
} abr_cache_t;
|
||||
|
||||
/* neighbor cache - rfc4861 5.1. */
|
||||
typedef struct __attribute__ ((packed)) nbr_cache_t {
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t type;
|
||||
uint8_t state;
|
||||
uint8_t isrouter;
|
||||
@ -216,7 +233,7 @@ typedef struct __attribute__ ((packed)) nbr_cache_t {
|
||||
} nbr_cache_t;
|
||||
|
||||
/* default router list - rfc4861 5.1. */
|
||||
typedef struct __attribute__ ((packed)) def_rtr_lst_t {
|
||||
typedef struct __attribute__((packed)) {
|
||||
ipv6_addr_t addr;
|
||||
timex_t inval_time;
|
||||
} def_rtr_lst_t;
|
||||
@ -224,33 +241,34 @@ typedef struct __attribute__ ((packed)) def_rtr_lst_t {
|
||||
void init_rtr_sol(uint8_t sllao);
|
||||
void recv_rtr_sol(void);
|
||||
void recv_rtr_adv(void);
|
||||
void init_rtr_adv(ipv6_addr_t *addr, uint8_t sllao, uint8_t mtu, uint8_t pi,
|
||||
void init_rtr_adv(ipv6_addr_t *addr, uint8_t sllao, uint8_t mtu, uint8_t pi,
|
||||
uint8_t sixco, uint8_t abro);
|
||||
uint8_t plist_search(ipv6_addr_t *addr);
|
||||
uint8_t plist_cmp(ipv6_addr_t *addr1, ipv6_addr_t *addr2);
|
||||
int8_t plist_add(ipv6_addr_t *addr, uint8_t size, uint32_t val_ltime,
|
||||
uint32_t pref_ltime, uint8_t adv_opt, uint8_t l_a_reserved1);
|
||||
uint32_t pref_ltime, uint8_t adv_opt, uint8_t l_a_reserved1);
|
||||
void set_llao(opt_stllao_t *sllao, uint8_t type, uint8_t length);
|
||||
|
||||
abr_cache_t *abr_get_version(uint16_t version, ipv6_addr_t *abr_addr);
|
||||
abr_cache_t *abr_add_context( uint16_t version, ipv6_addr_t *abr_addr,
|
||||
uint8_t cid);
|
||||
abr_cache_t *abr_add_context(uint16_t version, ipv6_addr_t *abr_addr,
|
||||
uint8_t cid);
|
||||
void abr_remove_context(uint8_t cid);
|
||||
|
||||
nbr_cache_t * nbr_cache_search(ipv6_addr_t *ipaddr);
|
||||
nbr_cache_t *nbr_cache_search(ipv6_addr_t *ipaddr);
|
||||
uint8_t nbr_cache_add(ipv6_addr_t *ipaddr, ieee_802154_long_t *laddr,
|
||||
uint8_t isrouter, uint8_t state, uint8_t type,
|
||||
uint16_t ltime, ieee_802154_short_t *saddr);
|
||||
uint8_t isrouter, uint8_t state, uint8_t type,
|
||||
uint16_t ltime, ieee_802154_short_t *saddr);
|
||||
void nbr_cache_auto_rem(void);
|
||||
void nbr_cache_rem(ipv6_addr_t *addr);
|
||||
uint16_t icmpv6_csum(uint8_t proto);
|
||||
def_rtr_lst_t * def_rtr_lst_search(ipv6_addr_t *ipaddr);
|
||||
def_rtr_lst_t *def_rtr_lst_search(ipv6_addr_t *ipaddr);
|
||||
void def_rtr_lst_add(ipv6_addr_t *ipaddr, uint32_t rtr_ltime);
|
||||
void def_rtr_lst_rem(def_rtr_lst_t *entry);
|
||||
void init_para_prob(ipv6_addr_t *src, ipv6_addr_t *dest, uint8_t code, uint32_t pointer, uint8_t *packet, uint8_t packet_len);
|
||||
void init_para_prob(ipv6_addr_t *src, ipv6_addr_t *dest, uint8_t code,
|
||||
uint32_t pointer, uint8_t *packet, uint8_t packet_len);
|
||||
void init_nbr_sol(ipv6_addr_t *src, ipv6_addr_t *dest, ipv6_addr_t *targ,
|
||||
uint8_t slloa, uint8_t aro);
|
||||
void init_nbr_adv(ipv6_addr_t *src, ipv6_addr_t *dst, ipv6_addr_t *tgt,
|
||||
void init_nbr_adv(ipv6_addr_t *src, ipv6_addr_t *dst, ipv6_addr_t *tgt,
|
||||
uint8_t rso, uint8_t sllao, uint8_t aro, uint8_t aro_state);
|
||||
void recv_nbr_adv(void);
|
||||
void recv_nbr_sol(void);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,10 +1,30 @@
|
||||
/*
|
||||
* 6lowpan constants, data structs, and prototypes
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file sixlowpan.h
|
||||
* @brief 6lowpan header
|
||||
* @author Stephan Zeisberg <zeisberg@mi.fu-berlin.de>
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Oliver Gesch <oliver.gesch@googlemail.com>
|
||||
* @author Eric Engel <eric.engel@fu-berlin.de>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef SIXLOWPAN_H
|
||||
#define SIXLOWPAN_H
|
||||
|
||||
#define IP_PROCESS_STACKSIZE 3072
|
||||
#define NC_STACKSIZE 512
|
||||
#define CON_STACKSIZE 512
|
||||
#define LOWPAN_TRANSFER_BUF_STACKSIZE 512
|
||||
#define IP_PROCESS_STACKSIZE 3072
|
||||
#define NC_STACKSIZE 512
|
||||
#define CON_STACKSIZE 512
|
||||
#define LOWPAN_TRANSFER_BUF_STACKSIZE 512
|
||||
|
||||
/* fragment size in bytes*/
|
||||
#define FRAG_PART_ONE_HDR_LEN 4
|
||||
@ -23,7 +43,7 @@
|
||||
#define LOWPAN_IPV6_DISPATCH 0x41
|
||||
#define LOWPAN_CONTEXT_MAX 16
|
||||
|
||||
#define LOWPAN_REAS_BUF_TIMEOUT 15 * 1000 * 1000 // TODO: Set back to 3 * 1000 * 1000
|
||||
#define LOWPAN_REAS_BUF_TIMEOUT 15 * 1000 * 1000 /* TODO: Set back to 3 * 1000 * 1000 */
|
||||
|
||||
#include "transceiver.h"
|
||||
#include "sixlowip.h"
|
||||
@ -44,43 +64,53 @@ typedef struct lowpan_context_t {
|
||||
} lowpan_context_t;
|
||||
|
||||
typedef struct lowpan_interval_list_t {
|
||||
uint8_t start;
|
||||
uint8_t end;
|
||||
struct lowpan_interval_list_t *next;
|
||||
uint8_t start;
|
||||
uint8_t end;
|
||||
struct lowpan_interval_list_t *next;
|
||||
} lowpan_interval_list_t;
|
||||
|
||||
typedef struct lowpan_reas_buf_t {
|
||||
ieee_802154_long_t s_laddr; // Source Address
|
||||
ieee_802154_long_t d_laddr; // Destination Address
|
||||
uint16_t ident_no; // Identification Number
|
||||
long timestamp; // Timestamp of last packet fragment
|
||||
uint16_t packet_size; // Size of reassembled packet with possible IPHC header
|
||||
uint16_t current_packet_size; // Additive size of currently already received fragments
|
||||
uint8_t *packet; // Pointer to allocated memory for reassembled packet + 6LoWPAN Dispatch Byte
|
||||
lowpan_interval_list_t *interval_list_head; // Pointer to list of intervals of received packet fragments (if any)
|
||||
struct lowpan_reas_buf_t *next; // Pointer to next reassembly buffer (if any)
|
||||
/* Source Address */
|
||||
ieee_802154_long_t s_laddr;
|
||||
/* Destination Address */
|
||||
ieee_802154_long_t d_laddr;
|
||||
/* Identification Number */
|
||||
uint16_t ident_no;
|
||||
/* Timestamp of last packet fragment */
|
||||
long timestamp;
|
||||
/* Size of reassembled packet with possible IPHC header */
|
||||
uint16_t packet_size;
|
||||
/* Additive size of currently already received fragments */
|
||||
uint16_t current_packet_size;
|
||||
/* Pointer to allocated memory for reassembled packet + 6LoWPAN Dispatch Byte */
|
||||
uint8_t *packet;
|
||||
/* Pointer to list of intervals of received packet fragments (if any) */
|
||||
lowpan_interval_list_t *interval_list_head;
|
||||
/* Pointer to next reassembly buffer (if any) */
|
||||
struct lowpan_reas_buf_t *next;
|
||||
} lowpan_reas_buf_t;
|
||||
|
||||
extern lowpan_reas_buf_t *head;
|
||||
|
||||
void sixlowpan_init(transceiver_type_t trans, uint8_t r_addr, int as_border);
|
||||
void sixlowpan_adhoc_init(transceiver_type_t trans, ipv6_addr_t *prefix, uint8_t r_addr);
|
||||
void sixlowpan_adhoc_init(transceiver_type_t trans, ipv6_addr_t *prefix,
|
||||
uint8_t r_addr);
|
||||
void lowpan_init(ieee_802154_long_t *addr, uint8_t *data);
|
||||
void lowpan_read(uint8_t *data, uint8_t length, ieee_802154_long_t *s_laddr,
|
||||
ieee_802154_long_t *d_laddr);
|
||||
void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra, uint8_t * ptr);
|
||||
ieee_802154_long_t *d_laddr);
|
||||
void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra, uint8_t *ptr);
|
||||
void lowpan_iphc_decoding(uint8_t *data, uint8_t length,
|
||||
ieee_802154_long_t *s_laddr,
|
||||
ieee_802154_long_t *d_laddr);
|
||||
uint8_t lowpan_context_len(void);
|
||||
void add_fifo_packet(lowpan_reas_buf_t *current_packet);
|
||||
lowpan_context_t * lowpan_context_update(
|
||||
uint8_t num, const ipv6_addr_t *prefix,
|
||||
uint8_t length, uint8_t comp,
|
||||
uint16_t lifetime);
|
||||
lowpan_context_t * lowpan_context_get(void);
|
||||
lowpan_context_t * lowpan_context_lookup(ipv6_addr_t *addr);
|
||||
lowpan_context_t * lowpan_context_num_lookup(uint8_t num);
|
||||
lowpan_context_t *lowpan_context_update(
|
||||
uint8_t num, const ipv6_addr_t *prefix,
|
||||
uint8_t length, uint8_t comp,
|
||||
uint16_t lifetime);
|
||||
lowpan_context_t *lowpan_context_get(void);
|
||||
lowpan_context_t *lowpan_context_lookup(ipv6_addr_t *addr);
|
||||
lowpan_context_t *lowpan_context_num_lookup(uint8_t num);
|
||||
lowpan_reas_buf_t *collect_garbage_fifo(lowpan_reas_buf_t *current_buf);
|
||||
lowpan_reas_buf_t *collect_garbage(lowpan_reas_buf_t *current_buf);
|
||||
void check_timeout(void);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* POSIX implementation of basic IO operations.
|
||||
* POSIX implementation of basic IO operations.
|
||||
*
|
||||
* Copyright (C) 2013, INRIA.
|
||||
*
|
||||
@ -10,7 +10,7 @@
|
||||
* @ingroup posix
|
||||
* @{
|
||||
* @file posix_io.c
|
||||
* @brief Implementation of basic POSIX IO functionality.
|
||||
* @brief Implementation of basic POSIX IO functionality.
|
||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||
* @}
|
||||
*/
|
||||
@ -21,7 +21,8 @@
|
||||
#include <posix_io.h>
|
||||
|
||||
|
||||
static int _posix_fileop(int pid, int op, int flags) {
|
||||
static int _posix_fileop(int pid, int op, int flags)
|
||||
{
|
||||
msg_t m;
|
||||
m.type = op;
|
||||
m.content.value = flags;
|
||||
@ -29,32 +30,37 @@ static int _posix_fileop(int pid, int op, int flags) {
|
||||
return m.content.value;
|
||||
}
|
||||
|
||||
static int _posix_fileop_data(int pid, int op, char* buffer, int nbytes) {
|
||||
static int _posix_fileop_data(int pid, int op, char *buffer, int nbytes)
|
||||
{
|
||||
struct posix_iop_t r;
|
||||
r.nbytes = nbytes;
|
||||
r.buffer = buffer;
|
||||
|
||||
msg_t m;
|
||||
m.type = op;
|
||||
m.content.ptr = (char*) &r;
|
||||
m.content.ptr = (char *) &r;
|
||||
|
||||
msg_send_receive(&m, &m, pid);
|
||||
|
||||
return r.nbytes;
|
||||
}
|
||||
|
||||
int posix_open(int pid, int flags) {
|
||||
return _posix_fileop(pid, OPEN, flags);
|
||||
int posix_open(int pid, int flags)
|
||||
{
|
||||
return _posix_fileop(pid, OPEN, flags);
|
||||
}
|
||||
|
||||
int posix_close(int pid) {
|
||||
return _posix_fileop(pid, CLOSE, 0);
|
||||
int posix_close(int pid)
|
||||
{
|
||||
return _posix_fileop(pid, CLOSE, 0);
|
||||
}
|
||||
|
||||
int posix_read(int pid, char* buffer, int bufsize) {
|
||||
int posix_read(int pid, char *buffer, int bufsize)
|
||||
{
|
||||
return _posix_fileop_data(pid, READ, buffer, bufsize);
|
||||
}
|
||||
|
||||
int posix_write(int pid, char* buffer, int bufsize) {
|
||||
int posix_write(int pid, char *buffer, int bufsize)
|
||||
{
|
||||
return _posix_fileop_data(pid, WRITE, buffer, bufsize);
|
||||
}
|
||||
|
25
sys/ps/ps.c
25
sys/ps/ps.c
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Print thread information.
|
||||
* Print thread information.
|
||||
*
|
||||
* Copyright (C) 2013, INRIA.
|
||||
*
|
||||
@ -10,7 +10,7 @@
|
||||
* @ingroup ps
|
||||
* @{
|
||||
* @file ps.c
|
||||
* @brief UNIX like ps command
|
||||
* @brief UNIX like ps command
|
||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||
* @}
|
||||
*/
|
||||
@ -22,7 +22,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
/* list of states copied from tcb.h */
|
||||
const char *state_names[] = {
|
||||
const char *state_names[] = {
|
||||
"running",
|
||||
"pending",
|
||||
"stopped",
|
||||
@ -36,23 +36,25 @@ const char *state_names[] = {
|
||||
/**
|
||||
* @brief Prints a list of running threads including stack usage to stdout.
|
||||
*/
|
||||
void thread_print_all(void) {
|
||||
void thread_print_all(void)
|
||||
{
|
||||
extern unsigned long hwtimer_now(void);
|
||||
const char queued_name[] = {'_', 'Q'};
|
||||
int i;
|
||||
int overall_stacksz = 0;
|
||||
|
||||
printf("\tpid | %-21s| %-9sQ | pri | stack ( used) location | runtime | switches \n", "name", "state");
|
||||
for( i = 0; i < MAXTHREADS; i++ ) {
|
||||
tcb_t* p = (tcb_t*)sched_threads[i];
|
||||
|
||||
if( p != NULL ) {
|
||||
for(i = 0; i < MAXTHREADS; i++) {
|
||||
tcb_t *p = (tcb_t *)sched_threads[i];
|
||||
|
||||
if(p != NULL) {
|
||||
int state = p->status; // copy state
|
||||
int statebit = number_of_highest_bit(state >> 1); // get state index
|
||||
const char* sname = state_names[statebit]; // get state name
|
||||
const char* queued = queued_name + (state & BIT0); // get queued flag
|
||||
const char *sname = state_names[statebit]; // get state name
|
||||
const char *queued = queued_name + (state & BIT0); // get queued flag
|
||||
int stacksz = p->stack_size; // get max used stack
|
||||
double runtime = 0/0.0;
|
||||
double runtime = 0 / 0.0;
|
||||
int switches = -1;
|
||||
#if SCHEDSTATISTICS
|
||||
runtime = pidlist[i].runtime / (double) hwtimer_now() * 100;
|
||||
@ -61,8 +63,9 @@ void thread_print_all(void) {
|
||||
overall_stacksz += stacksz;
|
||||
stacksz -= thread_measure_stack_usage(p->stack_start);
|
||||
printf("\t%3u | %-21s| %-8s %.1s | %3i | %5i (%5i) %p | %6.3f%% | %8i\n",
|
||||
p->pid, p->name, sname, queued, p->priority, p->stack_size, stacksz, p->stack_start, runtime, switches);
|
||||
p->pid, p->name, sname, queued, p->priority, p->stack_size, stacksz, p->stack_start, runtime, switches);
|
||||
}
|
||||
}
|
||||
|
||||
printf("\t%5s %-21s|%13s%6s %5i\n", "|", "SUM", "|", "|", overall_stacksz);
|
||||
}
|
||||
|
@ -1,3 +1,20 @@
|
||||
/**
|
||||
* Shell commands for cc110x driver
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup shell_commands
|
||||
* @{
|
||||
* @file sc_cc1100.c
|
||||
* @brief provides shell commands to configure cc110x driver
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
@ -14,43 +31,50 @@ char text_msg[TEXT_SIZE];
|
||||
msg_t mesg;
|
||||
transceiver_command_t tcmd;
|
||||
|
||||
void _cc1100_get_set_address_handler(char *addr) {
|
||||
void _cc1100_get_set_address_handler(char *addr)
|
||||
{
|
||||
int16_t a;
|
||||
|
||||
tcmd.transceivers = TRANSCEIVER_CC1100;
|
||||
tcmd.data = &a;
|
||||
mesg.content.ptr = (char*) &tcmd;
|
||||
a = atoi(addr+5);
|
||||
if (strlen(addr) > 5) {
|
||||
mesg.content.ptr = (char *) &tcmd;
|
||||
a = atoi(addr + 5);
|
||||
|
||||
if(strlen(addr) > 5) {
|
||||
printf("[cc110x] Trying to set address %i\n", a);
|
||||
mesg.type = SET_ADDRESS;
|
||||
}
|
||||
else {
|
||||
mesg.type = GET_ADDRESS;
|
||||
}
|
||||
|
||||
msg_send_receive(&mesg, &mesg, transceiver_pid);
|
||||
printf("[cc110x] Got address: %i\n", a);
|
||||
}
|
||||
|
||||
void _cc1100_get_set_channel_handler(char *chan) {
|
||||
void _cc1100_get_set_channel_handler(char *chan)
|
||||
{
|
||||
int16_t c;
|
||||
|
||||
tcmd.transceivers = TRANSCEIVER_CC1100;
|
||||
tcmd.data = &c;
|
||||
mesg.content.ptr = (char*) &tcmd;
|
||||
c = atoi(chan+5);
|
||||
if (strlen(chan) > 5) {
|
||||
mesg.content.ptr = (char *) &tcmd;
|
||||
c = atoi(chan + 5);
|
||||
|
||||
if(strlen(chan) > 5) {
|
||||
printf("[cc110x] Trying to set channel %i\n", c);
|
||||
mesg.type = SET_CHANNEL;
|
||||
}
|
||||
else {
|
||||
mesg.type = GET_CHANNEL;
|
||||
}
|
||||
|
||||
msg_send_receive(&mesg, &mesg, transceiver_pid);
|
||||
printf("[cc110x] Got channel: %i\n", c);
|
||||
}
|
||||
|
||||
void _cc1100_send_handler(char *pkt) {
|
||||
void _cc1100_send_handler(char *pkt)
|
||||
{
|
||||
radio_packet_t p;
|
||||
uint32_t response;
|
||||
uint16_t addr;
|
||||
@ -59,40 +83,47 @@ void _cc1100_send_handler(char *pkt) {
|
||||
tcmd.transceivers = TRANSCEIVER_CC1100;
|
||||
tcmd.data = &p;
|
||||
|
||||
tok = strtok(pkt+7, " ");
|
||||
if (tok) {
|
||||
tok = strtok(pkt + 7, " ");
|
||||
|
||||
if(tok) {
|
||||
addr = atoi(tok);
|
||||
tok = strtok(NULL, " ");
|
||||
if (tok) {
|
||||
|
||||
if(tok) {
|
||||
memset(text_msg, 0, TEXT_SIZE);
|
||||
memcpy(text_msg, tok, strlen(tok));
|
||||
/* if (sscanf(pkt, "txtsnd %hu %s", &(addr), text_msg) == 2) {*/
|
||||
p.data = (uint8_t*) text_msg;
|
||||
p.data = (uint8_t *) text_msg;
|
||||
p.length = strlen(text_msg) + 1;
|
||||
p.dst = addr;
|
||||
mesg.type = SND_PKT;
|
||||
mesg.content.ptr = (char*) &tcmd;
|
||||
printf("[cc110x] Sending packet of length %u to %hu: %s\n", p.length, p.dst, (char*) p.data);
|
||||
mesg.content.ptr = (char *) &tcmd;
|
||||
printf("[cc110x] Sending packet of length %u to %hu: %s\n", p.length, p.dst, (char *) p.data);
|
||||
msg_send_receive(&mesg, &mesg, transceiver_pid);
|
||||
response = mesg.content.value;
|
||||
printf("[cc110x] Packet sent: %lu\n", response);
|
||||
return;
|
||||
}
|
||||
}
|
||||
puts("Usage:\ttxtsnd <ADDR> <MSG>");
|
||||
|
||||
puts("Usage:\ttxtsnd <ADDR> <MSG>");
|
||||
}
|
||||
|
||||
#else
|
||||
void _cc110x_get_set_address_handler(char *addr) {
|
||||
void _cc110x_get_set_address_handler(char *addr)
|
||||
{
|
||||
int16_t a;
|
||||
|
||||
a = atoi(addr+5);
|
||||
if (strlen(addr) > 5) {
|
||||
a = atoi(addr + 5);
|
||||
|
||||
if(strlen(addr) > 5) {
|
||||
printf("[cc110x] Setting address %i ... ", a);
|
||||
cc1100_set_address((radio_address_t)a);
|
||||
if (cc1100_get_address() == (radio_address_t)a) {
|
||||
|
||||
if(cc1100_get_address() == (radio_address_t)a) {
|
||||
puts("[OK]");
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
puts("Error!");
|
||||
}
|
||||
}
|
||||
@ -101,16 +132,20 @@ void _cc110x_get_set_address_handler(char *addr) {
|
||||
}
|
||||
}
|
||||
|
||||
void _cc110x_get_set_channel_handler(char *addr) {
|
||||
void _cc110x_get_set_channel_handler(char *addr)
|
||||
{
|
||||
int16_t a;
|
||||
|
||||
a = atoi(addr+5);
|
||||
if (strlen(addr) > 5) {
|
||||
a = atoi(addr + 5);
|
||||
|
||||
if(strlen(addr) > 5) {
|
||||
printf("[cc110x] Setting channel %i...", a);
|
||||
cc1100_set_channel(a);
|
||||
if (cc1100_get_channel() == a) {
|
||||
|
||||
if(cc1100_get_channel() == a) {
|
||||
puts("OK");
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
puts("Error!");
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,20 @@
|
||||
/**
|
||||
* Shell commands for cc110x_ng driver
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup shell_commands
|
||||
* @{
|
||||
* @file sc_cc110x_ng.c
|
||||
* @brief provides shell commands to configure cc110x_ng driver
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -12,43 +29,50 @@ char text_msg[TEXT_SIZE];
|
||||
msg_t mesg;
|
||||
transceiver_command_t tcmd;
|
||||
|
||||
void _cc110x_ng_get_set_address_handler(char *addr) {
|
||||
void _cc110x_ng_get_set_address_handler(char *addr)
|
||||
{
|
||||
int16_t a;
|
||||
|
||||
tcmd.transceivers = TRANSCEIVER_CC1100;
|
||||
tcmd.data = &a;
|
||||
mesg.content.ptr = (char*) &tcmd;
|
||||
a = atoi(addr+5);
|
||||
if (strlen(addr) > 5) {
|
||||
mesg.content.ptr = (char *) &tcmd;
|
||||
a = atoi(addr + 5);
|
||||
|
||||
if(strlen(addr) > 5) {
|
||||
printf("[cc110x] Trying to set address %i\n", a);
|
||||
mesg.type = SET_ADDRESS;
|
||||
}
|
||||
else {
|
||||
mesg.type = GET_ADDRESS;
|
||||
}
|
||||
|
||||
msg_send_receive(&mesg, &mesg, transceiver_pid);
|
||||
printf("[cc110x] Got address: %i\n", a);
|
||||
}
|
||||
|
||||
void _cc110x_ng_get_set_channel_handler(char *chan) {
|
||||
void _cc110x_ng_get_set_channel_handler(char *chan)
|
||||
{
|
||||
int16_t c;
|
||||
|
||||
tcmd.transceivers = TRANSCEIVER_CC1100;
|
||||
tcmd.data = &c;
|
||||
mesg.content.ptr = (char*) &tcmd;
|
||||
c = atoi(chan+5);
|
||||
if (strlen(chan) > 5) {
|
||||
mesg.content.ptr = (char *) &tcmd;
|
||||
c = atoi(chan + 5);
|
||||
|
||||
if(strlen(chan) > 5) {
|
||||
printf("[cc110x] Trying to set channel %i\n", c);
|
||||
mesg.type = SET_CHANNEL;
|
||||
}
|
||||
else {
|
||||
mesg.type = GET_CHANNEL;
|
||||
}
|
||||
|
||||
msg_send_receive(&mesg, &mesg, transceiver_pid);
|
||||
printf("[cc110x] Got channel: %i\n", c);
|
||||
}
|
||||
|
||||
void _cc110x_ng_send_handler(char *pkt) {
|
||||
void _cc110x_ng_send_handler(char *pkt)
|
||||
{
|
||||
radio_packet_t p;
|
||||
uint32_t response;
|
||||
uint16_t addr;
|
||||
@ -57,37 +81,41 @@ void _cc110x_ng_send_handler(char *pkt) {
|
||||
tcmd.transceivers = TRANSCEIVER_CC1100;
|
||||
tcmd.data = &p;
|
||||
|
||||
tok = strtok(pkt+7, " ");
|
||||
if (tok) {
|
||||
tok = strtok(pkt + 7, " ");
|
||||
|
||||
if(tok) {
|
||||
addr = atoi(tok);
|
||||
tok = strtok(NULL, " ");
|
||||
if (tok) {
|
||||
|
||||
if(tok) {
|
||||
memset(text_msg, 0, TEXT_SIZE);
|
||||
memcpy(text_msg, tok, strlen(tok));
|
||||
/* if (sscanf(pkt, "txtsnd %hu %s", &(addr), text_msg) == 2) {*/
|
||||
p.data = (uint8_t*) text_msg;
|
||||
p.data = (uint8_t *) text_msg;
|
||||
p.length = strlen(text_msg) + 1;
|
||||
p.dst = addr;
|
||||
mesg.type = SND_PKT;
|
||||
mesg.content.ptr = (char*) &tcmd;
|
||||
printf("[cc110x] Sending packet of length %u to %hu: %s\n", p.length, p.dst, (char*) p.data);
|
||||
mesg.content.ptr = (char *) &tcmd;
|
||||
printf("[cc110x] Sending packet of length %u to %hu: %s\n", p.length, p.dst, (char *) p.data);
|
||||
msg_send_receive(&mesg, &mesg, transceiver_pid);
|
||||
response = mesg.content.value;
|
||||
printf("[cc110x] Packet sent: %" PRIu32 "\n", response);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
puts("Usage:\ttxtsnd <ADDR> <MSG>");
|
||||
}
|
||||
|
||||
void _cc110x_ng_monitor_handler(char *mode) {
|
||||
void _cc110x_ng_monitor_handler(char *mode)
|
||||
{
|
||||
unsigned int m;
|
||||
|
||||
tcmd.transceivers = TRANSCEIVER_CC1100;
|
||||
tcmd.data = &m;
|
||||
mesg.content.ptr = (char*) &tcmd;
|
||||
m = atoi(mode+8);
|
||||
if (strlen(mode) > 8) {
|
||||
mesg.content.ptr = (char *) &tcmd;
|
||||
m = atoi(mode + 8);
|
||||
|
||||
if(strlen(mode) > 8) {
|
||||
printf("Setting monitor mode: %u\n", m);
|
||||
mesg.type = SET_MONITOR;
|
||||
msg_send(&mesg, transceiver_pid, 1);
|
||||
|
@ -1,3 +1,20 @@
|
||||
/**
|
||||
* Shell commands for accessing storage
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup shell_commands
|
||||
* @{
|
||||
* @file sc_disk.c
|
||||
* @brief provides shell commands to access storage (like mmc)
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
@ -5,25 +22,33 @@
|
||||
#include "shell_commands.h"
|
||||
#include "diskio.h"
|
||||
|
||||
static inline uint8_t sector_read(unsigned char *read_buf, unsigned long sector, unsigned long length, unsigned long offset) {
|
||||
static inline uint8_t sector_read(unsigned char *read_buf, unsigned long sector, unsigned long length, unsigned long offset)
|
||||
{
|
||||
unsigned long i;
|
||||
if (MCI_read(read_buf, sector, 1) == RES_OK) {
|
||||
|
||||
if(MCI_read(read_buf, sector, 1) == RES_OK) {
|
||||
printf("[disk] Read sector %lu (%lu):\n", sector, offset);
|
||||
for (i = offset + 1; i <= offset + length; i++) {
|
||||
printf(" %u", read_buf[i-1]);
|
||||
if (!(i % 16)) {
|
||||
|
||||
for(i = offset + 1; i <= offset + length; i++) {
|
||||
printf(" %u", read_buf[i - 1]);
|
||||
|
||||
if(!(i % 16)) {
|
||||
puts("");
|
||||
}
|
||||
}
|
||||
|
||||
puts("");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void _get_sectorsize(char *unused) {
|
||||
void _get_sectorsize(char *unused)
|
||||
{
|
||||
unsigned short ssize;
|
||||
if (MCI_ioctl(GET_SECTOR_SIZE, &ssize) == RES_OK) {
|
||||
|
||||
if(MCI_ioctl(GET_SECTOR_SIZE, &ssize) == RES_OK) {
|
||||
printf("[disk] sector size is %u\n", ssize);
|
||||
}
|
||||
else {
|
||||
@ -31,9 +56,11 @@ void _get_sectorsize(char *unused) {
|
||||
}
|
||||
}
|
||||
|
||||
void _get_blocksize(char *unused) {
|
||||
void _get_blocksize(char *unused)
|
||||
{
|
||||
unsigned long bsize;
|
||||
if (MCI_ioctl(GET_BLOCK_SIZE, &bsize) == RES_OK) {
|
||||
|
||||
if(MCI_ioctl(GET_BLOCK_SIZE, &bsize) == RES_OK) {
|
||||
printf("[disk] block size is %lu\n", bsize);
|
||||
}
|
||||
else {
|
||||
@ -41,9 +68,11 @@ void _get_blocksize(char *unused) {
|
||||
}
|
||||
}
|
||||
|
||||
void _get_sectorcount(char *unused) {
|
||||
void _get_sectorcount(char *unused)
|
||||
{
|
||||
unsigned long scount;
|
||||
if (MCI_ioctl(GET_SECTOR_COUNT, &scount) == RES_OK) {
|
||||
|
||||
if(MCI_ioctl(GET_SECTOR_COUNT, &scount) == RES_OK) {
|
||||
printf("[disk] sector count is %lu\n", scount);
|
||||
}
|
||||
else {
|
||||
@ -51,19 +80,23 @@ void _get_sectorcount(char *unused) {
|
||||
}
|
||||
}
|
||||
|
||||
void _read_sector(char *sector) {
|
||||
void _read_sector(char *sector)
|
||||
{
|
||||
unsigned long sectornr, scount;
|
||||
unsigned short ssize;
|
||||
|
||||
if (strlen(sector) > strlen(DISK_READ_SECTOR_CMD) + 1) {
|
||||
if(strlen(sector) > strlen(DISK_READ_SECTOR_CMD) + 1) {
|
||||
|
||||
sectornr = atol(sector + strlen(DISK_READ_SECTOR_CMD) + 1);
|
||||
if ((MCI_ioctl(GET_SECTOR_COUNT, &scount) == RES_OK) && (MCI_ioctl(GET_SECTOR_SIZE, &ssize) == RES_OK)) {
|
||||
|
||||
if((MCI_ioctl(GET_SECTOR_COUNT, &scount) == RES_OK) && (MCI_ioctl(GET_SECTOR_SIZE, &ssize) == RES_OK)) {
|
||||
unsigned char read_buf[ssize];
|
||||
if (sector_read(read_buf, sectornr, ssize, 0)) {
|
||||
return;
|
||||
|
||||
if(sector_read(read_buf, sectornr, ssize, 0)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
printf("[disk] Error while reading sector %lu\n", sectornr);
|
||||
}
|
||||
else {
|
||||
@ -72,33 +105,39 @@ void _read_sector(char *sector) {
|
||||
}
|
||||
}
|
||||
|
||||
void _read_bytes(char *bytes) {
|
||||
void _read_bytes(char *bytes)
|
||||
{
|
||||
unsigned long sector = 1, scount, offset;
|
||||
unsigned short ssize, length;
|
||||
char *tok;
|
||||
|
||||
/* tokenize user input */
|
||||
tok = strtok(bytes + strlen(DISK_READ_BYTES_CMD) + 1, " ");
|
||||
if (tok) {
|
||||
|
||||
if(tok) {
|
||||
offset = atol(tok);
|
||||
tok = strtok(NULL, " ");
|
||||
if (tok) {
|
||||
|
||||
if(tok) {
|
||||
length = atoi(tok);
|
||||
if (length) {
|
||||
|
||||
if(length) {
|
||||
/* get card info */
|
||||
if ((MCI_ioctl(GET_SECTOR_COUNT, &scount) == RES_OK) && (MCI_ioctl(GET_SECTOR_SIZE, &ssize) == RES_OK)) {
|
||||
if((MCI_ioctl(GET_SECTOR_COUNT, &scount) == RES_OK) && (MCI_ioctl(GET_SECTOR_SIZE, &ssize) == RES_OK)) {
|
||||
/* calculate sector and offset position */
|
||||
sector = (offset / ssize) + 1;
|
||||
offset = (offset % ssize);
|
||||
/* preapre buffer (size must be a multiple of sector size) */
|
||||
unsigned char read_buf[((length / ssize) + 1) * 512];
|
||||
|
||||
/* read from several sectors */
|
||||
if (length > (ssize - offset)) {
|
||||
if(length > (ssize - offset)) {
|
||||
/* buffer offset */
|
||||
unsigned long j = 0;
|
||||
/* chunk from current sector */
|
||||
unsigned short tmp = ssize - offset;
|
||||
while (length) {
|
||||
|
||||
while(length) {
|
||||
sector_read(read_buf + j, sector++, tmp, offset);
|
||||
/* decrease length and recalculate chunk */
|
||||
length -= tmp;
|
||||
@ -109,15 +148,17 @@ void _read_bytes(char *bytes) {
|
||||
} /* length > (ssize - offset) */
|
||||
/* read only one sector */
|
||||
else {
|
||||
if (sector_read(read_buf, sector, length, offset)) {
|
||||
if(sector_read(read_buf, sector, length, offset)) {
|
||||
return;
|
||||
}
|
||||
} /* length < (ssize - offset) */
|
||||
} /* ioctl */
|
||||
|
||||
printf("[disk] Error while reading sector %lu\n", sector);
|
||||
return;
|
||||
} /* length */
|
||||
} /* strtok #2 */
|
||||
} /* strtok #1 */
|
||||
|
||||
printf("[disk] Usage:\n%s <OFFSET> <LENGTH>\n", DISK_READ_BYTES_CMD);
|
||||
}
|
||||
|
@ -1,13 +1,32 @@
|
||||
/**
|
||||
* Shell commands for configuring the node id
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup shell_commands
|
||||
* @{
|
||||
* @file sc_id.c
|
||||
* @brief provides shell commands to configure node id
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <config.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void _id_handler(char *id) {
|
||||
void _id_handler(char *id)
|
||||
{
|
||||
long newid;
|
||||
|
||||
newid = atoi(id+3);
|
||||
if (strlen(id) < 3) {
|
||||
newid = atoi(id + 3);
|
||||
|
||||
if(strlen(id) < 3) {
|
||||
#ifdef MODULE_CONFIG
|
||||
printf("Current id: %u\n", sysconfig.id);
|
||||
#endif
|
||||
@ -16,9 +35,11 @@ void _id_handler(char *id) {
|
||||
printf("Setting new id %lu\n", newid);
|
||||
#ifdef MODULE_CONFIG
|
||||
sysconfig.id = newid;
|
||||
if (!config_save()) {
|
||||
|
||||
if(!config_save()) {
|
||||
puts("ERROR setting new id");
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,29 @@
|
||||
/**
|
||||
* Shell commands for coulomb counter
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup shell_commands
|
||||
* @{
|
||||
* @file sc_ltc4150.c
|
||||
* @brief provides shell commands to access ltc4150
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ltc4150.h>
|
||||
|
||||
void _get_current_handler(char* unused) {
|
||||
printf("Power usage: %.4f mA (%.4f mA avg/ %.4f mAh total / %i usec)\n", ltc4150_get_current_mA(), ltc4150_get_avg_mA(), ltc4150_get_total_mAh(), ltc4150_get_interval());
|
||||
void _get_current_handler(char *unused)
|
||||
{
|
||||
printf("Power usage: %.4f mA (%.4f mA avg/ %.4f mAh total / %i usec)\n", ltc4150_get_current_mA(), ltc4150_get_avg_mA(), ltc4150_get_total_mAh(), ltc4150_get_interval());
|
||||
}
|
||||
|
||||
void _reset_current_handler(char* unused) {
|
||||
ltc4150_start();
|
||||
void _reset_current_handler(char *unused)
|
||||
{
|
||||
ltc4150_start();
|
||||
}
|
||||
|
@ -1,6 +1,24 @@
|
||||
/**
|
||||
* Shell commands for ps
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup shell_commands
|
||||
* @{
|
||||
* @file sc_ps.c
|
||||
* @brief shows all thread information
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "ps.h"
|
||||
|
||||
void _ps_handler(char* unnused) {
|
||||
void _ps_handler(char *unnused)
|
||||
{
|
||||
thread_print_all();
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,20 @@
|
||||
/**
|
||||
* Shell commands for real time clock
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup shell_commands
|
||||
* @{
|
||||
* @file sc_rtc.c
|
||||
* @brief provides shell commands to access the rtc
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
@ -5,46 +22,49 @@
|
||||
#ifdef MODULE_RTC
|
||||
#include <rtc.h>
|
||||
|
||||
void _gettime_handler(void) {
|
||||
void _gettime_handler(void)
|
||||
{
|
||||
struct tm now;
|
||||
rtc_get_localtime(&now);
|
||||
|
||||
printf("%s", asctime(&now));
|
||||
}
|
||||
|
||||
void _settime_handler(char* c) {
|
||||
void _settime_handler(char *c)
|
||||
{
|
||||
struct tm now;
|
||||
int res;
|
||||
uint16_t month, epoch_year;
|
||||
|
||||
res = sscanf(c, "date %hu-%hu-%u %u:%u:%u",
|
||||
&epoch_year,
|
||||
&month,
|
||||
(unsigned int*) &(now.tm_mday),
|
||||
(unsigned int*) &(now.tm_hour),
|
||||
(unsigned int*) &(now.tm_min),
|
||||
(unsigned int*) &(now.tm_sec));
|
||||
|
||||
if (res < 6) {
|
||||
&epoch_year,
|
||||
&month,
|
||||
(unsigned int *) & (now.tm_mday),
|
||||
(unsigned int *) & (now.tm_hour),
|
||||
(unsigned int *) & (now.tm_min),
|
||||
(unsigned int *) & (now.tm_sec));
|
||||
|
||||
if(res < 6) {
|
||||
printf("Usage: date YYYY-MM-DD hh:mm:ss\n");
|
||||
return;
|
||||
}
|
||||
else {
|
||||
puts("OK");
|
||||
}
|
||||
|
||||
|
||||
now.tm_year = epoch_year - 1900;
|
||||
now.tm_mon = month - 1;
|
||||
rtc_set_localtime(&now);
|
||||
}
|
||||
|
||||
void _date_handler(char* c) {
|
||||
if (strlen(c) == 4) {
|
||||
_gettime_handler();
|
||||
}
|
||||
else {
|
||||
_settime_handler(c);
|
||||
}
|
||||
void _date_handler(char *c)
|
||||
{
|
||||
if(strlen(c) == 4) {
|
||||
_gettime_handler();
|
||||
}
|
||||
else {
|
||||
_settime_handler(c);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,3 +1,20 @@
|
||||
/**
|
||||
* Shell commands for temperature and humidity sensor
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup shell_commands
|
||||
* @{
|
||||
* @file sc_sht11.c
|
||||
* @brief provides shell commands to poll sht11 sensor
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
@ -8,51 +25,58 @@
|
||||
|
||||
extern float sht11_temperature_offset;
|
||||
|
||||
void _get_humidity_handler(char* unused) {
|
||||
void _get_humidity_handler(char *unused)
|
||||
{
|
||||
uint8_t success;
|
||||
sht11_val_t sht11_val;
|
||||
success = sht11_read_sensor(&sht11_val, HUMIDITY|TEMPERATURE);
|
||||
if (!success) {
|
||||
success = sht11_read_sensor(&sht11_val, HUMIDITY | TEMPERATURE);
|
||||
|
||||
if(!success) {
|
||||
printf("Error reading SHT11\n");
|
||||
}
|
||||
else {
|
||||
printf("Relative humidity: %5.2f%% / Temperature compensated humidity; %5.2f%%\n",
|
||||
(double) sht11_val.relhum, (double) sht11_val.relhum_temp);
|
||||
(double) sht11_val.relhum, (double) sht11_val.relhum_temp);
|
||||
}
|
||||
}
|
||||
void _get_temperature_handler(char* unused) {
|
||||
void _get_temperature_handler(char *unused)
|
||||
{
|
||||
uint8_t success;
|
||||
sht11_val_t sht11_val;
|
||||
success = sht11_read_sensor(&sht11_val, TEMPERATURE);
|
||||
if (!success) {
|
||||
|
||||
if(!success) {
|
||||
printf("Error reading SHT11\n");
|
||||
}
|
||||
else {
|
||||
printf("Temperature: %-6.2f°C\n", (double) sht11_val.temperature);
|
||||
}
|
||||
}
|
||||
void _get_weather_handler(char* unused) {
|
||||
void _get_weather_handler(char *unused)
|
||||
{
|
||||
uint8_t success;
|
||||
sht11_val_t sht11_val;
|
||||
success = sht11_read_sensor(&sht11_val, HUMIDITY|TEMPERATURE);
|
||||
if (!success) {
|
||||
success = sht11_read_sensor(&sht11_val, HUMIDITY | TEMPERATURE);
|
||||
|
||||
if(!success) {
|
||||
printf("Error reading SHT11\n");
|
||||
}
|
||||
else {
|
||||
printf("Relative humidity: %5.2f%% / Temperature compensated humidity; %5.2f%% ",
|
||||
(double) sht11_val.relhum, (double) sht11_val.relhum_temp);
|
||||
(double) sht11_val.relhum, (double) sht11_val.relhum_temp);
|
||||
printf("Temperature: %-6.2f°C\n", (double) sht11_val.temperature);
|
||||
}
|
||||
}
|
||||
|
||||
void _set_offset_handler(char* offset) {
|
||||
if (strlen(offset) == 6) {
|
||||
puts("Usage: offset <OFFSET>");
|
||||
}
|
||||
else {
|
||||
sht11_temperature_offset = atoi(offset+7);
|
||||
printf("Temperature offset set to %f\n", (double) sht11_temperature_offset);
|
||||
}
|
||||
void _set_offset_handler(char *offset)
|
||||
{
|
||||
if(strlen(offset) == 6) {
|
||||
puts("Usage: offset <OFFSET>");
|
||||
}
|
||||
else {
|
||||
sht11_temperature_offset = atoi(offset + 7);
|
||||
printf("Temperature offset set to %f\n", (double) sht11_temperature_offset);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,26 +1,43 @@
|
||||
/**
|
||||
* Provides prototypes for available shell commands
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup shell_commands
|
||||
* @{
|
||||
* @file shell_commands.c
|
||||
* @brief sets up the system shell command struct
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <shell_commands.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
extern void _id_handler(char* id);
|
||||
extern void _id_handler(char *id);
|
||||
|
||||
#ifdef MODULE_PS
|
||||
extern void _ps_handler(char* unused);
|
||||
extern void _ps_handler(char *unused);
|
||||
#endif
|
||||
|
||||
#ifdef MODULE_RTC
|
||||
extern void _date_handler(char* now);
|
||||
extern void _date_handler(char *now);
|
||||
#endif
|
||||
|
||||
#ifdef MODULE_SHT11
|
||||
extern void _get_temperature_handler(char* unused);
|
||||
extern void _get_humidity_handler(char* unused);
|
||||
extern void _get_weather_handler(char* unused);
|
||||
extern void _set_offset_handler(char* offset);
|
||||
extern void _get_temperature_handler(char *unused);
|
||||
extern void _get_humidity_handler(char *unused);
|
||||
extern void _get_weather_handler(char *unused);
|
||||
extern void _set_offset_handler(char *offset);
|
||||
#endif
|
||||
|
||||
#ifdef MODULE_LTC4150
|
||||
extern void _get_current_handler(char* unused);
|
||||
extern void _reset_current_handler(char* unused);
|
||||
extern void _get_current_handler(char *unused);
|
||||
extern void _reset_current_handler(char *unused);
|
||||
#endif
|
||||
|
||||
#ifdef MODULE_CC110X
|
||||
@ -45,10 +62,10 @@ extern void _cc110x_ng_monitor_handler(char *mode);
|
||||
|
||||
#ifdef MODULE_MCI
|
||||
extern void _get_sectorsize(char *unused);
|
||||
extern void _get_blocksize(char* unused);
|
||||
extern void _get_sectorcount(char* unused);
|
||||
extern void _read_sector(char* sector);
|
||||
extern void _read_bytes(char* bytes);
|
||||
extern void _get_blocksize(char *unused);
|
||||
extern void _get_sectorcount(char *unused);
|
||||
extern void _read_sector(char *sector);
|
||||
extern void _read_bytes(char *bytes);
|
||||
#endif
|
||||
|
||||
const shell_command_t _shell_command_list[] = {
|
||||
@ -63,11 +80,11 @@ const shell_command_t _shell_command_list[] = {
|
||||
{"temp", "Prints measured temperature.", _get_temperature_handler},
|
||||
{"hum", "Prints measured humidity.", _get_humidity_handler},
|
||||
{"weather", "Prints measured humidity and temperature.", _get_weather_handler},
|
||||
{"offset", "Set temperature offset.", _set_offset_handler},
|
||||
{"offset", "Set temperature offset.", _set_offset_handler},
|
||||
#endif
|
||||
#ifdef MODULE_LTC4150
|
||||
{"cur", "Prints current and average power consumption.", _get_current_handler},
|
||||
{"rstcur", "Resets coulomb counter.", _reset_current_handler},
|
||||
{"cur", "Prints current and average power consumption.", _get_current_handler},
|
||||
{"rstcur", "Resets coulomb counter.", _reset_current_handler},
|
||||
#endif
|
||||
#ifdef MODULE_CC110X
|
||||
#ifdef MODULE_TRANSCEIVER
|
||||
|
@ -1,28 +1,13 @@
|
||||
/******************************************************************************
|
||||
Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved.
|
||||
|
||||
These sources were developed at the Freie Universitaet Berlin, Computer Systems
|
||||
and Telematics group (http://cst.mi.fu-berlin.de).
|
||||
-------------------------------------------------------------------------------
|
||||
This file is part of RIOT.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
RIOT is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see http://www.gnu.org/licenses/ .
|
||||
--------------------------------------------------------------------------------
|
||||
For further information and questions please use the web site
|
||||
http://scatterweb.mi.fu-berlin.de
|
||||
and the mailinglist (subscription via web site)
|
||||
scatterweb@lists.spline.inf.fu-berlin.de
|
||||
*******************************************************************************/
|
||||
/**
|
||||
* Shell interpreter
|
||||
*
|
||||
* Copyright (C) 2009, Freie Universitaet Berlin (FUB).
|
||||
* Copyright (C) 2013, INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup shell
|
||||
@ -49,68 +34,81 @@ and the mailinglist (subscription via web site)
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static void(*find_handler(const shell_command_t *command_list, char *command))(char*) {
|
||||
const shell_command_t* entry = command_list;
|
||||
if (entry) {
|
||||
while (entry->name != NULL) {
|
||||
if ( strcmp(entry->name, command) == 0) {
|
||||
return entry->handler;
|
||||
} else {
|
||||
entry++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void(*find_handler(const shell_command_t *command_list, char *command))(char *)
|
||||
{
|
||||
const shell_command_t *entry = command_list;
|
||||
|
||||
if(entry) {
|
||||
while(entry->name != NULL) {
|
||||
if(strcmp(entry->name, command) == 0) {
|
||||
return entry->handler;
|
||||
}
|
||||
else {
|
||||
entry++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MODULE_SHELL_COMMANDS
|
||||
entry = _shell_command_list;
|
||||
while (entry->name != NULL) {
|
||||
if ( strcmp(entry->name, command) == 0) {
|
||||
|
||||
while(entry->name != NULL) {
|
||||
if(strcmp(entry->name, command) == 0) {
|
||||
return entry->handler;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
entry++;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void print_help(const shell_command_t *command_list) {
|
||||
static void print_help(const shell_command_t *command_list)
|
||||
{
|
||||
const shell_command_t *entry = command_list;
|
||||
|
||||
printf("%-20s %s\n", "Command", "Description");
|
||||
puts("---------------------------------------");
|
||||
|
||||
if (entry) {
|
||||
while (entry->name != NULL) {
|
||||
printf("%-20s %s\n", entry->name, entry->desc);
|
||||
entry++;
|
||||
}
|
||||
}
|
||||
|
||||
if(entry) {
|
||||
while(entry->name != NULL) {
|
||||
printf("%-20s %s\n", entry->name, entry->desc);
|
||||
entry++;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MODULE_SHELL_COMMANDS
|
||||
entry = _shell_command_list;
|
||||
while (entry->name != NULL) {
|
||||
|
||||
while(entry->name != NULL) {
|
||||
printf("%-20s %s\n", entry->name, entry->desc);
|
||||
entry++;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
static void handle_input_line(shell_t *shell, char* line) {
|
||||
char* saveptr;
|
||||
char* linedup = strdup(line);
|
||||
char* command = strtok_r(linedup, " ", &saveptr);
|
||||
static void handle_input_line(shell_t *shell, char *line)
|
||||
{
|
||||
char *saveptr;
|
||||
char *linedup = strdup(line);
|
||||
char *command = strtok_r(linedup, " ", &saveptr);
|
||||
|
||||
void (*handler)(char*) = NULL;
|
||||
|
||||
if (command) {
|
||||
void (*handler)(char *) = NULL;
|
||||
|
||||
if(command) {
|
||||
handler = find_handler(shell->command_list, command);
|
||||
if (handler != NULL) {
|
||||
|
||||
if(handler != NULL) {
|
||||
handler(line);
|
||||
} else {
|
||||
if ( strcmp("help", command) == 0) {
|
||||
}
|
||||
else {
|
||||
if(strcmp("help", command) == 0) {
|
||||
print_help(shell->command_list);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
puts("shell: command not found.");
|
||||
}
|
||||
}
|
||||
@ -119,21 +117,24 @@ static void handle_input_line(shell_t *shell, char* line) {
|
||||
free(linedup);
|
||||
}
|
||||
|
||||
static int readline(shell_t *shell, char* buf, size_t size) {
|
||||
static int readline(shell_t *shell, char *buf, size_t size)
|
||||
{
|
||||
char *line_buf_ptr = buf;
|
||||
int c;
|
||||
|
||||
while (1) {
|
||||
if ( (line_buf_ptr - buf) >= ((int) size)-1) {
|
||||
while(1) {
|
||||
if((line_buf_ptr - buf) >= ((int) size) - 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
c = shell->readchar();
|
||||
shell->put_char(c);
|
||||
|
||||
if (c == 13) continue;
|
||||
if(c == 13) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == 10) {
|
||||
if(c == 10) {
|
||||
*line_buf_ptr = '\0';
|
||||
return 0;
|
||||
}
|
||||
@ -141,6 +142,7 @@ static int readline(shell_t *shell, char* buf, size_t size) {
|
||||
*line_buf_ptr++ = c;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -151,22 +153,27 @@ static inline void print_prompt(shell_t *shell)
|
||||
return;
|
||||
}
|
||||
|
||||
void shell_run(shell_t *shell) {
|
||||
void shell_run(shell_t *shell)
|
||||
{
|
||||
char line_buf[255];
|
||||
|
||||
print_prompt(shell);
|
||||
|
||||
while(1) {
|
||||
int res = readline(shell, line_buf, sizeof(line_buf));
|
||||
if (! res ) {
|
||||
char* line_copy = strdup(line_buf);
|
||||
|
||||
if(! res) {
|
||||
char *line_copy = strdup(line_buf);
|
||||
handle_input_line(shell, line_copy);
|
||||
free(line_copy);
|
||||
}
|
||||
|
||||
print_prompt(shell);
|
||||
}
|
||||
}
|
||||
|
||||
void shell_init(shell_t *shell, const shell_command_t *shell_commands, int(*readchar)(void), void(*put_char)(int)) {
|
||||
void shell_init(shell_t *shell, const shell_command_t *shell_commands, int(*readchar)(void), void(*put_char)(int))
|
||||
{
|
||||
shell->command_list = shell_commands;
|
||||
shell->readchar = readchar;
|
||||
shell->put_char = put_char;
|
||||
|
@ -32,81 +32,78 @@ and the mailinglist (subscription via web site)
|
||||
#define VSYSLOG(level, strModule, strFmt, argp) vsyslog(level, strModule, strFmt, argp)
|
||||
|
||||
void
|
||||
syslog(
|
||||
const uint8_t level,
|
||||
const char (*const strModule),
|
||||
const char* strFmt, ...
|
||||
) {
|
||||
va_list argp;
|
||||
syslog(const uint8_t level, const char(*const strModule), const char *strFmt, ...)
|
||||
{
|
||||
va_list argp;
|
||||
|
||||
va_start(argp, strFmt);
|
||||
VSYSLOG(level, strModule, strFmt, argp);
|
||||
va_end(argp);
|
||||
va_start(argp, strFmt);
|
||||
VSYSLOG(level, strModule, strFmt, argp);
|
||||
va_end(argp);
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
#if (SYSLOG_CONF_LEVEL & SL_EMERGENCY) == SL_EMERGENCY
|
||||
void syslog_emergency(const char (*const mod), const char* strFmt, ...)
|
||||
void syslog_emergency(const char(*const mod), const char *strFmt, ...)
|
||||
{
|
||||
va_list argp;
|
||||
va_list argp;
|
||||
|
||||
va_start(argp, strFmt);
|
||||
VSYSLOG(SL_EMERGENCY, mod, strFmt, argp);
|
||||
va_end(argp);
|
||||
va_start(argp, strFmt);
|
||||
VSYSLOG(SL_EMERGENCY, mod, strFmt, argp);
|
||||
va_end(argp);
|
||||
}
|
||||
#endif
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
#if (SYSLOG_CONF_LEVEL & SL_CRITICAL) == SL_CRITICAL
|
||||
void syslog_critical(const char (*const mod), const char* strFmt, ...)
|
||||
void syslog_critical(const char(*const mod), const char *strFmt, ...)
|
||||
{
|
||||
va_list argp;
|
||||
va_list argp;
|
||||
|
||||
va_start(argp, strFmt);
|
||||
VSYSLOG(SL_CRITICAL, mod, strFmt, argp);
|
||||
va_end(argp);
|
||||
va_start(argp, strFmt);
|
||||
VSYSLOG(SL_CRITICAL, mod, strFmt, argp);
|
||||
va_end(argp);
|
||||
}
|
||||
#endif
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
#if (SYSLOG_CONF_LEVEL & SL_WARN) == SL_WARN
|
||||
void syslog_warn(const char (*const mod), const char* strFmt, ...)
|
||||
void syslog_warn(const char(*const mod), const char *strFmt, ...)
|
||||
{
|
||||
va_list argp;
|
||||
va_list argp;
|
||||
|
||||
va_start(argp, strFmt);
|
||||
VSYSLOG(SL_WARN, mod, strFmt, argp);
|
||||
va_end(argp);
|
||||
va_start(argp, strFmt);
|
||||
VSYSLOG(SL_WARN, mod, strFmt, argp);
|
||||
va_end(argp);
|
||||
}
|
||||
#endif
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
#if (SYSLOG_CONF_LEVEL & SL_NOTICE) == SL_NOTICE
|
||||
void syslog_notice(const char (*const mod), const char* strFmt, ...)
|
||||
void syslog_notice(const char(*const mod), const char *strFmt, ...)
|
||||
{
|
||||
va_list argp;
|
||||
va_list argp;
|
||||
|
||||
va_start(argp, strFmt);
|
||||
VSYSLOG(SL_NOTICE, mod, strFmt, argp);
|
||||
va_end(argp);
|
||||
va_start(argp, strFmt);
|
||||
VSYSLOG(SL_NOTICE, mod, strFmt, argp);
|
||||
va_end(argp);
|
||||
}
|
||||
#endif
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
#if (SYSLOG_CONF_LEVEL & SL_INFO) == SL_INFO
|
||||
void syslog_info(const char (*const mod), const char* strFmt, ...)
|
||||
void syslog_info(const char(*const mod), const char *strFmt, ...)
|
||||
{
|
||||
va_list argp;
|
||||
va_list argp;
|
||||
|
||||
va_start(argp, strFmt);
|
||||
VSYSLOG(SL_INFO, mod, strFmt, argp);
|
||||
va_end(argp);
|
||||
va_start(argp, strFmt);
|
||||
VSYSLOG(SL_INFO, mod, strFmt, argp);
|
||||
va_end(argp);
|
||||
}
|
||||
#endif
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
#if SYSLOG_ISLEVEL(SL_DEBUG)
|
||||
void syslog_debug(const char (*const mod), const char* strFmt, ...)
|
||||
void syslog_debug(const char(*const mod), const char *strFmt, ...)
|
||||
{
|
||||
va_list argp;
|
||||
va_list argp;
|
||||
|
||||
va_start(argp, strFmt);
|
||||
VSYSLOG(SL_DEBUG, mod, strFmt, argp);
|
||||
va_end(argp);
|
||||
va_start(argp, strFmt);
|
||||
VSYSLOG(SL_DEBUG, mod, strFmt, argp);
|
||||
va_end(argp);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -57,123 +57,132 @@ and the mailinglist (subscription via web site)
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
syslog_format_ascii(struct syslog_args* args, struct syslog_chainlink* chainlink)
|
||||
void syslog_format_ascii(struct syslog_args *args, struct syslog_chainlink *chainlink)
|
||||
{
|
||||
char buffer[SYSLOG_CONF_BUFSIZE + 25];
|
||||
int msglen = 0;
|
||||
char buffer[SYSLOG_CONF_BUFSIZE + 25];
|
||||
int msglen = 0;
|
||||
|
||||
if( args->message[0] != '\t' ) {
|
||||
const char* strlevel = syslog_leveltostring(args->level);
|
||||
msglen = snprintf(buffer, SYSLOG_CONF_BUFSIZE + 23,
|
||||
"#[%u.%u:%u=%s] %s:",
|
||||
NETWORK_ADDR_NET(NET_LOCAL_ADDRESS), NETWORK_ADDR_HOST(NET_LOCAL_ADDRESS),
|
||||
args->level, strlevel, args->module
|
||||
);
|
||||
}
|
||||
if(args->message[0] != '\t') {
|
||||
const char *strlevel = syslog_leveltostring(args->level);
|
||||
msglen = snprintf(buffer, SYSLOG_CONF_BUFSIZE + 23,
|
||||
"#[%u.%u:%u=%s] %s:",
|
||||
NETWORK_ADDR_NET(NET_LOCAL_ADDRESS), NETWORK_ADDR_HOST(NET_LOCAL_ADDRESS),
|
||||
args->level, strlevel, args->module
|
||||
);
|
||||
}
|
||||
|
||||
msglen += snprintf(buffer + msglen, SYSLOG_CONF_BUFSIZE + 23 - msglen, "%s", args->message);
|
||||
buffer[msglen++] = '\n';
|
||||
buffer[msglen] = '\0';
|
||||
msglen += snprintf(buffer + msglen, SYSLOG_CONF_BUFSIZE + 23 - msglen, "%s", args->message);
|
||||
buffer[msglen++] = '\n';
|
||||
buffer[msglen] = '\0';
|
||||
|
||||
args->message = buffer;
|
||||
if( chainlink != NULL && chainlink->fpout != NULL )
|
||||
chainlink->fpout(args, chainlink->next);
|
||||
args->message = buffer;
|
||||
|
||||
if(chainlink != NULL && chainlink->fpout != NULL) {
|
||||
chainlink->fpout(args, chainlink->next);
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
syslog_format_xml(struct syslog_args* args, struct syslog_chainlink* chainlink)
|
||||
void syslog_format_xml(struct syslog_args *args, struct syslog_chainlink *chainlink)
|
||||
{
|
||||
const size_t bufsize = SYSLOG_CONF_BUFSIZE + 80;
|
||||
char buffer[bufsize];
|
||||
char tbuf[20];
|
||||
int msglen = 0;
|
||||
const size_t bufsize = SYSLOG_CONF_BUFSIZE + 80;
|
||||
char buffer[bufsize];
|
||||
char tbuf[20];
|
||||
int msglen = 0;
|
||||
|
||||
#if FEUERWARE_CONF_CORE_SUPPORTS_TIME
|
||||
time_get_string(tbuf, sizeof(tbuf));
|
||||
#else
|
||||
sprintf(tbuf, "%lu", clock_time(NULL));
|
||||
#endif
|
||||
#if FEUERWARE_CONF_CORE_SUPPORTS_TIME
|
||||
time_get_string(tbuf, sizeof(tbuf));
|
||||
#else
|
||||
sprintf(tbuf, "%lu", clock_time(NULL));
|
||||
#endif
|
||||
|
||||
msglen = snprintf(buffer, bufsize,
|
||||
"<log lvl=%u src=\"%u.%u\" id=%u ts=\"%s\" mod=\"%s\">%s</log>\n",
|
||||
args->level, NETWORK_ADDR_NET(NET_LOCAL_ADDRESS), NETWORK_ADDR_HOST(NET_LOCAL_ADDRESS),
|
||||
args->msgnum, tbuf, args->module, args->message
|
||||
);
|
||||
msglen = snprintf(buffer, bufsize,
|
||||
"<log lvl=%u src=\"%u.%u\" id=%u ts=\"%s\" mod=\"%s\">%s</log>\n",
|
||||
args->level, NETWORK_ADDR_NET(NET_LOCAL_ADDRESS), NETWORK_ADDR_HOST(NET_LOCAL_ADDRESS),
|
||||
args->msgnum, tbuf, args->module, args->message
|
||||
);
|
||||
|
||||
args->message = buffer;
|
||||
if( chainlink != NULL && chainlink->fpout != NULL )
|
||||
chainlink->fpout(args, chainlink->next);
|
||||
args->message = buffer;
|
||||
|
||||
if(chainlink != NULL && chainlink->fpout != NULL) {
|
||||
chainlink->fpout(args, chainlink->next);
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
syslog_copy_stdout(struct syslog_args* args, struct syslog_chainlink* chainlink)
|
||||
void syslog_copy_stdout(struct syslog_args *args, struct syslog_chainlink *chainlink)
|
||||
{
|
||||
if( args->message[0] != '\t' ) {
|
||||
const char* strlevel = syslog_leveltostring(args->level);
|
||||
printf("#[%u.%u:%u=%s] %s:",
|
||||
NETWORK_ADDR_NET(NET_LOCAL_ADDRESS), NETWORK_ADDR_HOST(NET_LOCAL_ADDRESS),
|
||||
args->level, strlevel, args->module
|
||||
);
|
||||
}
|
||||
printf("%s\n", args->message);
|
||||
if(args->message[0] != '\t') {
|
||||
const char *strlevel = syslog_leveltostring(args->level);
|
||||
printf("#[%u.%u:%u=%s] %s:",
|
||||
NETWORK_ADDR_NET(NET_LOCAL_ADDRESS), NETWORK_ADDR_HOST(NET_LOCAL_ADDRESS),
|
||||
args->level, strlevel, args->module
|
||||
);
|
||||
}
|
||||
|
||||
if( chainlink != NULL && chainlink->fpout != NULL )
|
||||
chainlink->fpout(args, chainlink->next);
|
||||
printf("%s\n", args->message);
|
||||
|
||||
if(chainlink != NULL && chainlink->fpout != NULL) {
|
||||
chainlink->fpout(args, chainlink->next);
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
syslog_out_stdout(struct syslog_args* args, struct syslog_chainlink* chainlink)
|
||||
void syslog_out_stdout(struct syslog_args *args, struct syslog_chainlink *chainlink)
|
||||
{
|
||||
printf(args->message);
|
||||
printf(args->message);
|
||||
|
||||
if( chainlink != NULL && chainlink->fpout != NULL )
|
||||
chainlink->fpout(args, chainlink->next);
|
||||
if(chainlink != NULL && chainlink->fpout != NULL) {
|
||||
chainlink->fpout(args, chainlink->next);
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
#ifdef MODULE_FAT
|
||||
static int syslog_file = -1;
|
||||
|
||||
static int fat_open_logfile(const char* path);
|
||||
static int fat_open_logfile(const char* path)
|
||||
static int fat_open_logfile(const char *path);
|
||||
static int fat_open_logfile(const char *path)
|
||||
{
|
||||
char t[20];
|
||||
int file;
|
||||
char t[20];
|
||||
int file;
|
||||
|
||||
file = open(path, O_WRONLY | O_APPEND | O_CREAT);
|
||||
file = open(path, O_WRONLY | O_APPEND | O_CREAT);
|
||||
|
||||
time_get_string(t, sizeof(t));
|
||||
time_get_string(t, sizeof(t));
|
||||
|
||||
if( file >= 0 ) {
|
||||
syslog_notice("sys", "%s log %s opened", t, path);
|
||||
} else {
|
||||
syslog_warn("sys", "%s log %s failed", t, path);
|
||||
}
|
||||
return file;
|
||||
if(file >= 0) {
|
||||
syslog_notice("sys", "%s log %s opened", t, path);
|
||||
}
|
||||
else {
|
||||
syslog_warn("sys", "%s log %s failed", t, path);
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
void syslog_out_file(struct syslog_args* args, struct syslog_chainlink* chainlink)
|
||||
void syslog_out_file(struct syslog_args *args, struct syslog_chainlink *chainlink)
|
||||
{
|
||||
if( syslog_file >= 0 ) {
|
||||
size_t length = (size_t)strlen(args->message);
|
||||
int ret = write(syslog_file, args->message, length);
|
||||
if( ret == 1 ) {
|
||||
if(syslog_file >= 0) {
|
||||
size_t length = (size_t)strlen(args->message);
|
||||
int ret = write(syslog_file, args->message, length);
|
||||
|
||||
if(ret == 1) {
|
||||
#ifdef MODULE_TRACELOG
|
||||
trace_string(TRACELOG_EV_MEMORY, "fat");
|
||||
trace_string(TRACELOG_EV_MEMORY, "fat");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( chainlink != NULL && chainlink->fpout != NULL )
|
||||
chainlink->fpout(args, chainlink->next);
|
||||
if(chainlink != NULL && chainlink->fpout != NULL) {
|
||||
chainlink->fpout(args, chainlink->next);
|
||||
}
|
||||
}
|
||||
|
||||
bool syslog_open_file(void) {
|
||||
syslog_file = fat_open_logfile("SYSLOG.LOG");
|
||||
return (syslog_file >= 0);
|
||||
bool syslog_open_file(void)
|
||||
{
|
||||
syslog_file = fat_open_logfile("SYSLOG.LOG");
|
||||
return (syslog_file >= 0);
|
||||
}
|
||||
void syslog_close_file(void) {
|
||||
close(syslog_file);
|
||||
syslog_file = -1;
|
||||
void syslog_close_file(void)
|
||||
{
|
||||
close(syslog_file);
|
||||
syslog_file = -1;
|
||||
}
|
||||
#endif
|
||||
|
@ -52,7 +52,7 @@ and the mailinglist (subscription via web site)
|
||||
#include "sysmon.h"
|
||||
#include "tracelog.h"
|
||||
|
||||
static const char* syslog_level_stringtable = "emergency\0"
|
||||
static const char *syslog_level_stringtable = "emergency\0"
|
||||
"critical\0"
|
||||
"warn\0"
|
||||
"notice\0"
|
||||
@ -64,109 +64,108 @@ __attribute__((section(".noinit")))
|
||||
static volatile unsigned int syslog_msgnum;
|
||||
|
||||
static unsigned short syslog_flagtolevel(const uint8_t level);
|
||||
static int find_interface_index_for_name(const char* name);
|
||||
static int find_interface_index_for_name(const char *name);
|
||||
|
||||
extern struct syslog_interface syslog_interfaces[];
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
syslog_init(void)
|
||||
void syslog_init(void)
|
||||
{
|
||||
if( sysmon_initial_boot() )
|
||||
syslog_msgnum = 0;
|
||||
if(sysmon_initial_boot()) {
|
||||
syslog_msgnum = 0;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
static bool
|
||||
testlevel(uint8_t filter_level, const uint8_t level) {
|
||||
return ((filter_level & level) != 0);
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
vsyslog(
|
||||
const uint8_t level,
|
||||
const char (*const strModule),
|
||||
const char* strFmt,
|
||||
va_list argp
|
||||
) {
|
||||
int i;
|
||||
struct syslog_interface* slif; // syslog interface
|
||||
struct syslog_args args; // output function arguments
|
||||
char message[SYSLOG_CONF_BUFSIZE]; // message buffer
|
||||
int msglen = 0;
|
||||
|
||||
args.message = NULL;
|
||||
|
||||
//printf("0 %p %p\n", &syslog_interfaces[0], syslog_interfaces[0].chain);
|
||||
//printf("1 %p %p\n", &syslog_interfaces[1], syslog_interfaces[1].chain);
|
||||
|
||||
// check each syslog interface
|
||||
for( i = 0; i < SYSLOG_CONF_NUM_INTERFACES; i++) {
|
||||
slif = &syslog_interfaces[i];
|
||||
/* run interface filter */
|
||||
//printf("testing %i, %s\n", i, slif->name);
|
||||
if( slif->name != NULL && testlevel(cfg_feuerware.level[i], level) ) {
|
||||
/* filter matched, produce output */
|
||||
//printf("printing to %s\n", slif->name);
|
||||
if( args.message == NULL ) {
|
||||
// initialize structure one time, when actually needed
|
||||
args.msgnum = syslog_msgnum++;
|
||||
args.level = syslog_flagtolevel(level);
|
||||
args.module = strModule;
|
||||
args.message = message;
|
||||
msglen = vsnprintf(message, SYSLOG_CONF_BUFSIZE-1, strFmt, argp);
|
||||
}
|
||||
//printf("msg %i: %s\n", msglen, message);
|
||||
args.interface = (const struct syslog_interface*)slif;
|
||||
|
||||
// invoke first link of ouput chain
|
||||
//printf("invoke on %s: %p %p\n", slif->name, slif, slif->chain);
|
||||
if( slif->chain->fpout != NULL ) {
|
||||
slif->chain->fpout(&args, slif->chain->next);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void syslog_printlevel(char* buffer, size_t bufsize, uint8_t level)
|
||||
static bool testlevel(uint8_t filter_level, const uint8_t level)
|
||||
{
|
||||
uint8_t l = level;
|
||||
int intlevel;
|
||||
int bufpos;
|
||||
int len = 0;
|
||||
|
||||
bufpos = snprintf(buffer, bufsize, "%#.2x=", level);
|
||||
bufsize -= bufpos;
|
||||
for( intlevel = 0; intlevel < SYSLOG_LEVELS_COUNT; intlevel++ ) {
|
||||
if( l & 0x0001 ) {
|
||||
const char* string = string_table_get(syslog_level_stringtable, intlevel);
|
||||
if( string ) {
|
||||
if( bufsize < 0 ) bufsize = 0;
|
||||
len = snprintf( &buffer[bufpos], bufsize, "%s%s", ((len > 0) ? "|" : ""), (char*)string );
|
||||
bufsize -= len;
|
||||
bufpos += len;
|
||||
}
|
||||
}
|
||||
l >>= 1;
|
||||
}
|
||||
return ((filter_level & level) != 0);
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
uint8_t syslog_set_level(const char* name, uint8_t level)
|
||||
void vsyslog(const uint8_t level, const char(*const strModule),
|
||||
const char *strFmt, va_list argp)
|
||||
{
|
||||
uint8_t result;
|
||||
int index = find_interface_index_for_name(name);
|
||||
if( index < 0 )
|
||||
return 0;
|
||||
int i;
|
||||
struct syslog_interface *slif; // syslog interface
|
||||
struct syslog_args args; // output function arguments
|
||||
char message[SYSLOG_CONF_BUFSIZE]; // message buffer
|
||||
int msglen = 0;
|
||||
|
||||
result = cfg_feuerware.level[index];
|
||||
cfg_feuerware.level[index] = level;
|
||||
cfg_feuerware_spec.state->modified = 1;
|
||||
args.message = NULL;
|
||||
|
||||
return result;
|
||||
/* check each syslog interface */
|
||||
for(i = 0; i < SYSLOG_CONF_NUM_INTERFACES; i++) {
|
||||
slif = &syslog_interfaces[i];
|
||||
|
||||
/* run interface filter */
|
||||
if(slif->name != NULL && testlevel(cfg_feuerware.level[i], level)) {
|
||||
/* filter matched, produce output */
|
||||
if(args.message == NULL) {
|
||||
/* initialize structure one time, when actually needed */
|
||||
args.msgnum = syslog_msgnum++;
|
||||
args.level = syslog_flagtolevel(level);
|
||||
args.module = strModule;
|
||||
args.message = message;
|
||||
msglen = vsnprintf(message, SYSLOG_CONF_BUFSIZE - 1, strFmt, argp);
|
||||
}
|
||||
|
||||
args.interface = (const struct syslog_interface *)slif;
|
||||
|
||||
/* invoke first link of ouput chain */
|
||||
if(slif->chain->fpout != NULL) {
|
||||
slif->chain->fpout(&args, slif->chain->next);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
const char*
|
||||
syslog_leveltostring(unsigned int level) {
|
||||
return string_table_get(syslog_level_stringtable, level);
|
||||
void syslog_printlevel(char *buffer, size_t bufsize, uint8_t level)
|
||||
{
|
||||
uint8_t l = level;
|
||||
int intlevel;
|
||||
int bufpos;
|
||||
int len = 0;
|
||||
|
||||
bufpos = snprintf(buffer, bufsize, "%#.2x=", level);
|
||||
bufsize -= bufpos;
|
||||
|
||||
for(intlevel = 0; intlevel < SYSLOG_LEVELS_COUNT; intlevel++) {
|
||||
if(l & 0x0001) {
|
||||
const char *string = string_table_get(syslog_level_stringtable, intlevel);
|
||||
|
||||
if(string) {
|
||||
if(bufsize < 0) {
|
||||
bufsize = 0;
|
||||
}
|
||||
|
||||
len = snprintf(&buffer[bufpos], bufsize, "%s%s", ((len > 0) ? "|" : ""), (char *)string);
|
||||
bufsize -= len;
|
||||
bufpos += len;
|
||||
}
|
||||
}
|
||||
|
||||
l >>= 1;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
uint8_t syslog_set_level(const char *name, uint8_t level)
|
||||
{
|
||||
uint8_t result;
|
||||
int index = find_interface_index_for_name(name);
|
||||
|
||||
if(index < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
result = cfg_feuerware.level[index];
|
||||
cfg_feuerware.level[index] = level;
|
||||
cfg_feuerware_spec.state->modified = 1;
|
||||
|
||||
return result;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
const char *syslog_leveltostring(unsigned int level)
|
||||
{
|
||||
return string_table_get(syslog_level_stringtable, level);
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
@ -189,76 +188,82 @@ syslog_leveltostring(unsigned int level) {
|
||||
ASCCMD(syslog, 0, "[interface] [byte val]: syslog-level property");
|
||||
CMD_FUNCTION(syslog, cmdargs)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
if( cmdargs->arg_size > 0 ) {
|
||||
unsigned int argc;
|
||||
const char* arg;
|
||||
const char* name = NULL;
|
||||
unsigned int value;
|
||||
if(cmdargs->arg_size > 0) {
|
||||
unsigned int argc;
|
||||
const char *arg;
|
||||
const char *name = NULL;
|
||||
unsigned int value;
|
||||
|
||||
argc = cmd_split_arguments(cmdargs->args);
|
||||
arg = cmdargs->args;
|
||||
argc = cmd_split_arguments(cmdargs->args);
|
||||
arg = cmdargs->args;
|
||||
|
||||
if( *arg >= 'A' ) {
|
||||
// first argument is a string
|
||||
name = arg;
|
||||
// move to next argument
|
||||
arg = cmd_get_next_argument(arg);
|
||||
}
|
||||
if( *arg == '\0' )
|
||||
return CMD_ERROR;
|
||||
value = strtoul(arg, NULL, 0);
|
||||
syslog_set_level(name, value);
|
||||
}
|
||||
if(*arg >= 'A') {
|
||||
// first argument is a string
|
||||
name = arg;
|
||||
// move to next argument
|
||||
arg = cmd_get_next_argument(arg);
|
||||
}
|
||||
|
||||
for( i = 0; i < SYSLOG_CONF_NUM_INTERFACES; i++ ) {
|
||||
if( syslog_interfaces[i].name != NULL ) {
|
||||
char buf[SYSLOG_PRINTLEVEL_MAXLEN];
|
||||
syslog_printlevel(buf, sizeof(buf), cfg_feuerware.level[i]);
|
||||
cmdargs->fresponse(cmdargs,
|
||||
CMD_RESPONSE_MULTILINE,
|
||||
"%s:%s",
|
||||
syslog_interfaces[i].name,
|
||||
buf
|
||||
);
|
||||
}
|
||||
}
|
||||
return CMD_SUCCESS;
|
||||
if(*arg == '\0') {
|
||||
return CMD_ERROR;
|
||||
}
|
||||
|
||||
value = strtoul(arg, NULL, 0);
|
||||
syslog_set_level(name, value);
|
||||
}
|
||||
|
||||
for(i = 0; i < SYSLOG_CONF_NUM_INTERFACES; i++) {
|
||||
if(syslog_interfaces[i].name != NULL) {
|
||||
char buf[SYSLOG_PRINTLEVEL_MAXLEN];
|
||||
syslog_printlevel(buf, sizeof(buf), cfg_feuerware.level[i]);
|
||||
cmdargs->fresponse(cmdargs,
|
||||
CMD_RESPONSE_MULTILINE,
|
||||
"%s:%s",
|
||||
syslog_interfaces[i].name,
|
||||
buf
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Convert bit flag to bit number
|
||||
*/
|
||||
static unsigned short
|
||||
syslog_flagtolevel(const uint8_t level)
|
||||
static unsigned short syslog_flagtolevel(const uint8_t level)
|
||||
{
|
||||
uint8_t l = level;
|
||||
unsigned short intlevel;
|
||||
uint8_t l = level;
|
||||
unsigned short intlevel;
|
||||
|
||||
for( intlevel = 0; intlevel < SYSLOG_LEVELS_COUNT; intlevel++ ) {
|
||||
if( (l & 1) == 1 )
|
||||
break;
|
||||
l >>= 1;
|
||||
}
|
||||
for(intlevel = 0; intlevel < SYSLOG_LEVELS_COUNT; intlevel++) {
|
||||
if((l & 1) == 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
return intlevel;
|
||||
l >>= 1;
|
||||
}
|
||||
|
||||
return intlevel;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Find an interface for a given name
|
||||
*/
|
||||
static int
|
||||
find_interface_index_for_name(const char* name)
|
||||
static int find_interface_index_for_name(const char *name)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
for( i = 0; i < SYSLOG_CONF_NUM_INTERFACES; i++ ) {
|
||||
if( strcmp(syslog_interfaces[i].name, name) == 0 )
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
for(i = 0; i < SYSLOG_CONF_NUM_INTERFACES; i++) {
|
||||
if(strcmp(syslog_interfaces[i].name, name) == 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
@ -52,72 +52,76 @@ and the mailinglist (subscription via web site)
|
||||
#include "syslog.h"
|
||||
|
||||
#if TRACELOG_CONF_NUM_ENTRIES > 0
|
||||
__attribute__((section(".noinit")))
|
||||
struct tracelog tracelog;
|
||||
__attribute__((section(".noinit")))
|
||||
struct tracelog tracelog;
|
||||
|
||||
/// tells if tracelog can accept input
|
||||
static bool tracelog_initialized = 0;
|
||||
/// tells if tracelog can accept input
|
||||
static bool tracelog_initialized = 0;
|
||||
#endif
|
||||
|
||||
#if defined(SYSLOG_CONF_LEVEL) && ((SYSLOG_CONF_LEVEL & SL_DEBUG) == SL_DEBUG)
|
||||
static const char symon_event_names[] =
|
||||
"\0"
|
||||
"start\0"
|
||||
"exit\0"
|
||||
"assert\0"
|
||||
"event\0"
|
||||
"timer\0"
|
||||
"irqdis\0"
|
||||
"irqen\0"
|
||||
"irq\0"
|
||||
"switch\0"
|
||||
"\0"
|
||||
"memory\0"
|
||||
"memaccess\0"
|
||||
"opfault\0"
|
||||
"panic\0"
|
||||
"userdef\0"
|
||||
"\3";
|
||||
"\0"
|
||||
"start\0"
|
||||
"exit\0"
|
||||
"assert\0"
|
||||
"event\0"
|
||||
"timer\0"
|
||||
"irqdis\0"
|
||||
"irqen\0"
|
||||
"irq\0"
|
||||
"switch\0"
|
||||
"\0"
|
||||
"memory\0"
|
||||
"memaccess\0"
|
||||
"opfault\0"
|
||||
"panic\0"
|
||||
"userdef\0"
|
||||
"\3";
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
#if TRACELOG_CONF_NUM_ENTRIES > 0
|
||||
static void tracelog_snprint(char* buf, int bufsz, int i)
|
||||
static void tracelog_snprint(char *buf, int bufsz, int i)
|
||||
{
|
||||
struct tracelog_entry* trace = &tracelog.traces[i];
|
||||
int length = 0;
|
||||
bufsz -= 1; // save one for zero
|
||||
struct tracelog_entry *trace = &tracelog.traces[i];
|
||||
int length = 0;
|
||||
bufsz -= 1; // save one for zero
|
||||
|
||||
#if (SYSLOG_CONF_LEVEL & SL_DEBUG) == SL_DEBUG
|
||||
/* when running in debug level, event names are available and can be printed */
|
||||
char* name = (char*)string_table_get(symon_event_names, trace->event);
|
||||
length = snprintf(buf, bufsz, "%#.2x (%s): ", trace->event, name);
|
||||
#else
|
||||
length = snprintf(buf, bufsz, "%#.2x: ", trace->event);
|
||||
#endif
|
||||
bufsz -= length;
|
||||
buf += length;
|
||||
#if (SYSLOG_CONF_LEVEL & SL_DEBUG) == SL_DEBUG
|
||||
/* when running in debug level, event names are available and can be printed */
|
||||
char *name = (char *)string_table_get(symon_event_names, trace->event);
|
||||
length = snprintf(buf, bufsz, "%#.2x (%s): ", trace->event, name);
|
||||
#else
|
||||
length = snprintf(buf, bufsz, "%#.2x: ", trace->event);
|
||||
#endif
|
||||
bufsz -= length;
|
||||
buf += length;
|
||||
|
||||
switch( trace->type ) {
|
||||
case TRACE_NUMBER: {
|
||||
tracelog_number_t uldata;
|
||||
memcpy(&uldata, trace->data, sizeof(tracelog_number_t));
|
||||
length += snprintf(buf, bufsz, "%#10lx (%lu)", uldata, uldata);
|
||||
break;
|
||||
}
|
||||
case TRACE_POINTER: {
|
||||
void* uldata;
|
||||
memcpy(&uldata, trace->data, sizeof(void*));
|
||||
length += snprintf(buf, bufsz, "%p", uldata);
|
||||
break;
|
||||
}
|
||||
case TRACE_STRING:
|
||||
length += snprintf(buf, bufsz, "%.*s", TRACELOG_CONF_ENTRY_SIZE, trace->data);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
buf[length] = '\0';
|
||||
switch(trace->type) {
|
||||
case TRACE_NUMBER: {
|
||||
tracelog_number_t uldata;
|
||||
memcpy(&uldata, trace->data, sizeof(tracelog_number_t));
|
||||
length += snprintf(buf, bufsz, "%#10lx (%lu)", uldata, uldata);
|
||||
break;
|
||||
}
|
||||
|
||||
case TRACE_POINTER: {
|
||||
void *uldata;
|
||||
memcpy(&uldata, trace->data, sizeof(void *));
|
||||
length += snprintf(buf, bufsz, "%p", uldata);
|
||||
break;
|
||||
}
|
||||
|
||||
case TRACE_STRING:
|
||||
length += snprintf(buf, bufsz, "%.*s", TRACELOG_CONF_ENTRY_SIZE, trace->data);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
buf[length] = '\0';
|
||||
}
|
||||
#endif
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
@ -127,50 +131,56 @@ static void tracelog_snprint(char* buf, int bufsz, int i)
|
||||
*/
|
||||
static void
|
||||
trace(
|
||||
enum tracelog_event event,
|
||||
const enum tracelog_type t,
|
||||
const void (* const data),
|
||||
const int size
|
||||
) {
|
||||
enum tracelog_event event,
|
||||
const enum tracelog_type t,
|
||||
const void (* const data),
|
||||
const int size
|
||||
)
|
||||
{
|
||||
#if TRACELOG_CONF_NUM_ENTRIES > 0
|
||||
int length = size;
|
||||
int length = size;
|
||||
|
||||
if( tracelog_initialized == false )
|
||||
return;
|
||||
if(tracelog_initialized == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct tracelog_entry* trace = &tracelog.traces[tracelog.tail]; // get current tail element
|
||||
/* increase tail */
|
||||
if( (tracelog.tail + 1) < TRACELOG_CONF_NUM_ENTRIES )
|
||||
tracelog.tail++;
|
||||
else
|
||||
tracelog.tail = 0;
|
||||
struct tracelog_entry *trace = &tracelog.traces[tracelog.tail]; // get current tail element
|
||||
|
||||
/* fill meta data */
|
||||
trace->event = event & 0x7F;
|
||||
trace->type = t;
|
||||
/* increase tail */
|
||||
if((tracelog.tail + 1) < TRACELOG_CONF_NUM_ENTRIES) {
|
||||
tracelog.tail++;
|
||||
}
|
||||
else {
|
||||
tracelog.tail = 0;
|
||||
}
|
||||
|
||||
/* calculate size */
|
||||
if( length == 0 ) {
|
||||
if( t == TRACE_STRING ) {
|
||||
length = strlen((char*)data);
|
||||
}
|
||||
}
|
||||
length = (TRACELOG_CONF_ENTRY_SIZE < length) ? TRACELOG_CONF_ENTRY_SIZE : length;
|
||||
/* fill meta data */
|
||||
trace->event = event & 0x7F;
|
||||
trace->type = t;
|
||||
|
||||
memcpy( trace->data, data, length ); // copy description
|
||||
/* calculate size */
|
||||
if(length == 0) {
|
||||
if(t == TRACE_STRING) {
|
||||
length = strlen((char *)data);
|
||||
}
|
||||
}
|
||||
|
||||
length = (TRACELOG_CONF_ENTRY_SIZE < length) ? TRACELOG_CONF_ENTRY_SIZE : length;
|
||||
|
||||
memcpy(trace->data, data, length); // copy description
|
||||
#endif
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void trace_reset(void)
|
||||
{
|
||||
#if TRACELOG_CONF_NUM_ENTRIES > 0
|
||||
#if SYSLOG_ISLEVEL(SL_DEBUG)
|
||||
char buffer[12];
|
||||
sysmon_write_reset_info(buffer, 12, sysmon.reset_code);
|
||||
trace_string(TRACELOG_EV_START, buffer);
|
||||
#else
|
||||
trace_number(TRACELOG_EV_START, sysmon.reset_code);
|
||||
#endif
|
||||
#if SYSLOG_ISLEVEL(SL_DEBUG)
|
||||
char buffer[12];
|
||||
sysmon_write_reset_info(buffer, 12, sysmon.reset_code);
|
||||
trace_string(TRACELOG_EV_START, buffer);
|
||||
#else
|
||||
trace_number(TRACELOG_EV_START, sysmon.reset_code);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
@ -178,42 +188,50 @@ void
|
||||
tracelog_init(void)
|
||||
{
|
||||
#if TRACELOG_CONF_NUM_ENTRIES > 0
|
||||
if( tracelog_initialized != 0 )
|
||||
return;
|
||||
|
||||
if( sysmon_initial_boot() ) {
|
||||
memset( &tracelog, 0, sizeof(struct tracelog) ); // clear tracelog buffer on initial boot only
|
||||
}
|
||||
if(tracelog_initialized != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
tracelog_initialized = true; // accept traces
|
||||
if(sysmon_initial_boot()) {
|
||||
memset(&tracelog, 0, sizeof(struct tracelog)); // clear tracelog buffer on initial boot only
|
||||
}
|
||||
|
||||
trace_reset(); // trace reason for last reset
|
||||
tracelog_initialized = true; // accept traces
|
||||
|
||||
trace_reset(); // trace reason for last reset
|
||||
#endif
|
||||
}
|
||||
void
|
||||
tracelog_dump(void)
|
||||
{
|
||||
printf("[trace] {\n");
|
||||
printf("[trace] {\n");
|
||||
#if TRACELOG_CONF_NUM_ENTRIES > 0
|
||||
char buf[30 + TRACELOG_CONF_ENTRY_SIZE];
|
||||
int i = tracelog.tail; // tracelog tail holds next index
|
||||
do {
|
||||
i--;
|
||||
if( i < 0 )
|
||||
i = TRACELOG_CONF_NUM_ENTRIES - 1;
|
||||
tracelog_snprint(buf, sizeof(buf), i);
|
||||
printf("\t %.2i: %s\n", i, buf);
|
||||
} while( i != tracelog.tail );
|
||||
char buf[30 + TRACELOG_CONF_ENTRY_SIZE];
|
||||
int i = tracelog.tail; // tracelog tail holds next index
|
||||
|
||||
do {
|
||||
i--;
|
||||
|
||||
if(i < 0) {
|
||||
i = TRACELOG_CONF_NUM_ENTRIES - 1;
|
||||
}
|
||||
|
||||
tracelog_snprint(buf, sizeof(buf), i);
|
||||
printf("\t %.2i: %s\n", i, buf);
|
||||
}
|
||||
while(i != tracelog.tail);
|
||||
|
||||
#endif
|
||||
|
||||
printf("}\n");
|
||||
printf("}\n");
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
trace_event(enum tracelog_event event)
|
||||
{
|
||||
#if TRACELOG_CONF_NUM_ENTRIES > 0
|
||||
trace(event, TRACE_NULL, NULL, 0);
|
||||
trace(event, TRACE_NULL, NULL, 0);
|
||||
#endif
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
@ -221,23 +239,23 @@ void
|
||||
trace_number(enum tracelog_event event, tracelog_number_t number)
|
||||
{
|
||||
#if TRACELOG_CONF_NUM_ENTRIES > 0
|
||||
trace(event, TRACE_NUMBER, &number, sizeof(tracelog_number_t));
|
||||
trace(event, TRACE_NUMBER, &number, sizeof(tracelog_number_t));
|
||||
#endif
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
trace_pointer(enum tracelog_event event, void* pointer)
|
||||
trace_pointer(enum tracelog_event event, void *pointer)
|
||||
{
|
||||
#if TRACELOG_CONF_NUM_ENTRIES > 0
|
||||
trace(event, TRACE_POINTER, &pointer, sizeof(void*));
|
||||
trace(event, TRACE_POINTER, &pointer, sizeof(void *));
|
||||
#endif
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
trace_string(enum tracelog_event event, char* string)
|
||||
trace_string(enum tracelog_event event, char *string)
|
||||
{
|
||||
#if TRACELOG_CONF_NUM_ENTRIES > 0
|
||||
trace(event, TRACE_STRING, string, strlen(string));
|
||||
trace(event, TRACE_STRING, string, strlen(string));
|
||||
#endif
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
@ -254,20 +272,23 @@ ASCCMD(trace, CMDFLAG_SERIAL, "[event] [text]: print tracelog / trace event [num
|
||||
CMD_FUNCTION(trace, cmdargs)
|
||||
{
|
||||
#if TRACELOG_CONF_NUM_ENTRIES > 0
|
||||
if( cmdargs->arg_size > 0 ) {
|
||||
enum tracelog_event event;
|
||||
char* c = (char*)cmdargs->args;
|
||||
event = (enum tracelog_event)strtoul(c, &c, 0); // read event number
|
||||
if( event > 0 ) {
|
||||
c++; // skip expected whitespace
|
||||
trace_string(event, c); // generate event with argument as text
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
tracelog_dump();
|
||||
|
||||
return CMD_SUCCESS;
|
||||
if(cmdargs->arg_size > 0) {
|
||||
enum tracelog_event event;
|
||||
char *c = (char *)cmdargs->args;
|
||||
event = (enum tracelog_event)strtoul(c, &c, 0); // read event number
|
||||
|
||||
if(event > 0) {
|
||||
c++; // skip expected whitespace
|
||||
trace_string(event, c); // generate event with argument as text
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
tracelog_dump();
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Generic transceiver module as an interface to NIC driver.
|
||||
* Generic transceiver module as an interface to NIC driver.
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
@ -30,16 +30,16 @@
|
||||
#ifdef MODULE_CC110X
|
||||
#include <cc1100-interface.h>
|
||||
#if (CC1100_MAX_DATA_LENGTH > PAYLOAD_SIZE)
|
||||
#undef PAYLOAD_SIZE
|
||||
#define PAYLOAD_SIZE (CC1100_MAX_DATA_LENGTH)
|
||||
#undef PAYLOAD_SIZE
|
||||
#define PAYLOAD_SIZE (CC1100_MAX_DATA_LENGTH)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef MODULE_CC110X_NG
|
||||
#include <cc110x_ng.h>
|
||||
#if (CC1100_MAX_DATA_LENGTH > PAYLOAD_SIZE)
|
||||
#undef PAYLOAD_SIZE
|
||||
#define PAYLOAD_SIZE (CC1100_MAX_DATA_LENGTH)
|
||||
#undef PAYLOAD_SIZE
|
||||
#define PAYLOAD_SIZE (CC1100_MAX_DATA_LENGTH)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -55,7 +55,7 @@ registered_t reg[TRANSCEIVER_MAX_REGISTERED];
|
||||
|
||||
/* packet buffers */
|
||||
radio_packet_t transceiver_buffer[TRANSCEIVER_BUFFER_SIZE];
|
||||
uint8_t data_buffer[TRANSCEIVER_BUFFER_SIZE * PAYLOAD_SIZE];
|
||||
uint8_t data_buffer[TRANSCEIVER_BUFFER_SIZE *PAYLOAD_SIZE];
|
||||
|
||||
/* message buffer */
|
||||
msg_t msg_buffer[TRANSCEIVER_MSG_BUFFER_SIZE];
|
||||
@ -85,7 +85,7 @@ static void receive_packet(uint16_t type, uint8_t pos);
|
||||
#ifdef MODULE_CC110X_NG
|
||||
static void receive_cc110x_packet(radio_packet_t *trans_p);
|
||||
#elif MODULE_CC110X
|
||||
void cc1100_packet_monitor(void* payload, int payload_size, protocol_t protocol, packet_info_t* packet_info);
|
||||
void cc1100_packet_monitor(void *payload, int payload_size, protocol_t protocol, packet_info_t *packet_info);
|
||||
void receive_cc1100_packet(radio_packet_t *trans_p);
|
||||
#endif
|
||||
static uint8_t send_packet(transceiver_type_t t, void *pkt);
|
||||
@ -103,18 +103,20 @@ static void ignore_add(transceiver_type_t t, void *address);
|
||||
|
||||
/*------------------------------------------------------------------------------------*/
|
||||
/* Transceiver init */
|
||||
void transceiver_init(transceiver_type_t t) {
|
||||
void transceiver_init(transceiver_type_t t)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
/* Initializing transceiver buffer and data buffer */
|
||||
memset(transceiver_buffer, 0, TRANSCEIVER_BUFFER_SIZE);
|
||||
memset(data_buffer, 0, TRANSCEIVER_BUFFER_SIZE * PAYLOAD_SIZE);
|
||||
|
||||
for (i = 0; i < TRANSCEIVER_MAX_REGISTERED; i++) {
|
||||
for(i = 0; i < TRANSCEIVER_MAX_REGISTERED; i++) {
|
||||
reg[i].transceivers = TRANSCEIVER_NONE;
|
||||
reg[i].pid = 0;
|
||||
}
|
||||
if (t & TRANSCEIVER_CC1100) {
|
||||
|
||||
if(t & TRANSCEIVER_CC1100) {
|
||||
transceivers |= t;
|
||||
}
|
||||
else {
|
||||
@ -123,12 +125,14 @@ void transceiver_init(transceiver_type_t t) {
|
||||
}
|
||||
|
||||
/* Start the transceiver thread */
|
||||
int transceiver_start(void) {
|
||||
transceiver_pid = thread_create(transceiver_stack, TRANSCEIVER_STACK_SIZE, PRIORITY_MAIN-3, CREATE_STACKTEST, run, "Transceiver");
|
||||
if (transceiver_pid < 0) {
|
||||
int transceiver_start(void)
|
||||
{
|
||||
transceiver_pid = thread_create(transceiver_stack, TRANSCEIVER_STACK_SIZE, PRIORITY_MAIN - 3, CREATE_STACKTEST, run, "Transceiver");
|
||||
|
||||
if(transceiver_pid < 0) {
|
||||
puts("Error creating transceiver thread");
|
||||
}
|
||||
else if (transceivers & TRANSCEIVER_CC1100) {
|
||||
else if(transceivers & TRANSCEIVER_CC1100) {
|
||||
DEBUG("Transceiver started for CC1100\n");
|
||||
#ifdef MODULE_CC110X_NG
|
||||
cc110x_init(transceiver_pid);
|
||||
@ -137,25 +141,28 @@ int transceiver_start(void) {
|
||||
cc1100_set_packet_monitor(cc1100_packet_monitor);
|
||||
#endif
|
||||
}
|
||||
|
||||
return transceiver_pid;
|
||||
}
|
||||
|
||||
/* Register an upper layer thread */
|
||||
uint8_t transceiver_register(transceiver_type_t t, int pid) {
|
||||
uint8_t i;
|
||||
for (i = 0; ((reg[i].pid != pid) &&
|
||||
(i < TRANSCEIVER_MAX_REGISTERED) &&
|
||||
(reg[i].transceivers != TRANSCEIVER_NONE)); i++);
|
||||
uint8_t transceiver_register(transceiver_type_t t, int pid)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
if (i >= TRANSCEIVER_MAX_REGISTERED) {
|
||||
return ENOMEM;
|
||||
}
|
||||
else {
|
||||
reg[i].transceivers |= t;
|
||||
reg[i].pid = pid;
|
||||
DEBUG("Thread %i registered for %i\n", reg[i].pid, reg[i].transceivers);
|
||||
return 1;
|
||||
}
|
||||
for(i = 0; ((reg[i].pid != pid) &&
|
||||
(i < TRANSCEIVER_MAX_REGISTERED) &&
|
||||
(reg[i].transceivers != TRANSCEIVER_NONE)); i++);
|
||||
|
||||
if(i >= TRANSCEIVER_MAX_REGISTERED) {
|
||||
return ENOMEM;
|
||||
}
|
||||
else {
|
||||
reg[i].transceivers |= t;
|
||||
reg[i].pid = pid;
|
||||
DEBUG("Thread %i registered for %i\n", reg[i].pid, reg[i].transceivers);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------------*/
|
||||
@ -166,58 +173,71 @@ uint8_t transceiver_register(transceiver_type_t t, int pid) {
|
||||
* @brief The main thread run, receiving and processing messages in an infinite
|
||||
* loop
|
||||
*/
|
||||
void run(void) {
|
||||
void run(void)
|
||||
{
|
||||
msg_t m;
|
||||
transceiver_command_t *cmd;
|
||||
|
||||
msg_init_queue(msg_buffer, TRANSCEIVER_MSG_BUFFER_SIZE);
|
||||
while (1) {
|
||||
|
||||
while(1) {
|
||||
DEBUG("Waiting for next message\n");
|
||||
msg_receive(&m);
|
||||
/* only makes sense for messages for upper layers */
|
||||
cmd = (transceiver_command_t*) m.content.ptr;
|
||||
cmd = (transceiver_command_t *) m.content.ptr;
|
||||
DEBUG("Transceiver: Message received\n");
|
||||
switch (m.type) {
|
||||
|
||||
switch(m.type) {
|
||||
case RCV_PKT_CC1020:
|
||||
case RCV_PKT_CC1100:
|
||||
receive_packet(m.type, m.content.value);
|
||||
break;
|
||||
|
||||
case SND_PKT:
|
||||
response = send_packet(cmd->transceivers, cmd->data);
|
||||
m.content.value = response;
|
||||
msg_reply(&m, &m);
|
||||
break;
|
||||
|
||||
case GET_CHANNEL:
|
||||
*((int16_t*) cmd->data) = get_channel(cmd->transceivers);
|
||||
*((int16_t *) cmd->data) = get_channel(cmd->transceivers);
|
||||
msg_reply(&m, &m);
|
||||
break;
|
||||
|
||||
case SET_CHANNEL:
|
||||
*((int16_t*) cmd->data) = set_channel(cmd->transceivers, cmd->data);
|
||||
*((int16_t *) cmd->data) = set_channel(cmd->transceivers, cmd->data);
|
||||
msg_reply(&m, &m);
|
||||
break;
|
||||
|
||||
case GET_ADDRESS:
|
||||
*((int16_t*) cmd->data) = get_address(cmd->transceivers);
|
||||
*((int16_t *) cmd->data) = get_address(cmd->transceivers);
|
||||
msg_reply(&m, &m);
|
||||
break;
|
||||
|
||||
case SET_ADDRESS:
|
||||
*((int16_t*) cmd->data) = set_address(cmd->transceivers, cmd->data);
|
||||
*((int16_t *) cmd->data) = set_address(cmd->transceivers, cmd->data);
|
||||
msg_reply(&m, &m);
|
||||
break;
|
||||
|
||||
case SET_MONITOR:
|
||||
set_monitor(cmd->transceivers, cmd->data);
|
||||
break;
|
||||
|
||||
case POWERDOWN:
|
||||
powerdown(cmd->transceivers);
|
||||
break;
|
||||
|
||||
case SWITCH_RX:
|
||||
switch_to_rx(cmd->transceivers);
|
||||
break;
|
||||
#ifdef DBG_IGNORE
|
||||
|
||||
case DBG_IGN:
|
||||
printf("Transceiver PID: %i (%p), rx_buffer_next: %u\n", transceiver_pid, &transceiver_pid, rx_buffer_next);
|
||||
ignore_add(cmd->transceivers, cmd->data);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
DEBUG("Unknown message received\n");
|
||||
break;
|
||||
@ -226,7 +246,8 @@ void run(void) {
|
||||
}
|
||||
|
||||
#ifdef MODULE_CC110X
|
||||
void cc1100_packet_monitor(void* payload, int payload_size, protocol_t protocol, packet_info_t* packet_info) {
|
||||
void cc1100_packet_monitor(void *payload, int payload_size, protocol_t protocol, packet_info_t *packet_info)
|
||||
{
|
||||
cc1100_payload = payload;
|
||||
cc1100_payload_size = payload_size - 3;
|
||||
cc1100_packet_info = packet_info;
|
||||
@ -242,33 +263,38 @@ void cc1100_packet_monitor(void* payload, int payload_size, protocol_t protocol,
|
||||
* packet
|
||||
* @param pos The current device driver's buffer position
|
||||
*/
|
||||
static void receive_packet(uint16_t type, uint8_t pos) {
|
||||
static void receive_packet(uint16_t type, uint8_t pos)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
transceiver_type_t t;
|
||||
rx_buffer_pos = pos;
|
||||
msg_t m;
|
||||
|
||||
|
||||
DEBUG("Packet received\n");
|
||||
switch (type) {
|
||||
|
||||
switch(type) {
|
||||
case RCV_PKT_CC1020:
|
||||
t = TRANSCEIVER_CC1020;
|
||||
break;
|
||||
|
||||
case RCV_PKT_CC1100:
|
||||
t = TRANSCEIVER_CC1100;
|
||||
break;
|
||||
|
||||
default:
|
||||
t = TRANSCEIVER_NONE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* search first free position in transceiver buffer */
|
||||
for (i = 0; (i < TRANSCEIVER_BUFFER_SIZE) && (transceiver_buffer[transceiver_buffer_pos].processing); i++) {
|
||||
if (++transceiver_buffer_pos == TRANSCEIVER_BUFFER_SIZE) {
|
||||
for(i = 0; (i < TRANSCEIVER_BUFFER_SIZE) && (transceiver_buffer[transceiver_buffer_pos].processing); i++) {
|
||||
if(++transceiver_buffer_pos == TRANSCEIVER_BUFFER_SIZE) {
|
||||
transceiver_buffer_pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* no buffer left */
|
||||
if (i >= TRANSCEIVER_BUFFER_SIZE) {
|
||||
if(i >= TRANSCEIVER_BUFFER_SIZE) {
|
||||
/* inform upper layers of lost packet */
|
||||
m.type = ENOBUFFER;
|
||||
m.content.value = t;
|
||||
@ -278,9 +304,9 @@ static void receive_packet(uint16_t type, uint8_t pos) {
|
||||
radio_packet_t *trans_p = &(transceiver_buffer[transceiver_buffer_pos]);
|
||||
m.type = PKT_PENDING;
|
||||
|
||||
if (type == RCV_PKT_CC1100) {
|
||||
if(type == RCV_PKT_CC1100) {
|
||||
#ifdef MODULE_CC110X_NG
|
||||
receive_cc110x_packet(trans_p);
|
||||
receive_cc110x_packet(trans_p);
|
||||
#else
|
||||
receive_cc1100_packet(trans_p);
|
||||
#endif
|
||||
@ -294,14 +320,17 @@ static void receive_packet(uint16_t type, uint8_t pos) {
|
||||
/* finally notify waiting upper layers
|
||||
* this is done non-blocking, so packets can get lost */
|
||||
i = 0;
|
||||
while (reg[i].transceivers != TRANSCEIVER_NONE) {
|
||||
if (reg[i].transceivers & t) {
|
||||
m.content.ptr = (char*) &(transceiver_buffer[transceiver_buffer_pos]);
|
||||
|
||||
while(reg[i].transceivers != TRANSCEIVER_NONE) {
|
||||
if(reg[i].transceivers & t) {
|
||||
m.content.ptr = (char *) & (transceiver_buffer[transceiver_buffer_pos]);
|
||||
DEBUG("Notify thread %i\n", reg[i].pid);
|
||||
if (msg_send(&m, reg[i].pid, false) && (m.type != ENOBUFFER)) {
|
||||
|
||||
if(msg_send(&m, reg[i].pid, false) && (m.type != ENOBUFFER)) {
|
||||
transceiver_buffer[transceiver_buffer_pos].processing++;
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
@ -312,41 +341,43 @@ static void receive_packet(uint16_t type, uint8_t pos) {
|
||||
*
|
||||
* @param trans_p The current entry in the transceiver buffer
|
||||
*/
|
||||
static void receive_cc110x_packet(radio_packet_t *trans_p) {
|
||||
static void receive_cc110x_packet(radio_packet_t *trans_p)
|
||||
{
|
||||
DEBUG("Handling CC1100 packet\n");
|
||||
/* disable interrupts while copying packet */
|
||||
dINT();
|
||||
cc110x_packet_t p = cc110x_rx_buffer[rx_buffer_pos].packet;
|
||||
|
||||
|
||||
trans_p->src = p.phy_src;
|
||||
trans_p->dst = p.address;
|
||||
trans_p->rssi = cc110x_rx_buffer[rx_buffer_pos].rssi;
|
||||
trans_p->lqi = cc110x_rx_buffer[rx_buffer_pos].lqi;
|
||||
trans_p->length = p.length - CC1100_HEADER_LENGTH;
|
||||
memcpy((void*) &(data_buffer[transceiver_buffer_pos * PAYLOAD_SIZE]), p.data, CC1100_MAX_DATA_LENGTH);
|
||||
memcpy((void *)&(data_buffer[transceiver_buffer_pos * PAYLOAD_SIZE]), p.data, CC1100_MAX_DATA_LENGTH);
|
||||
eINT();
|
||||
|
||||
DEBUG("Packet %p was from %hu to %hu, size: %u\n", trans_p, trans_p->src, trans_p->dst, trans_p->length);
|
||||
trans_p->data = (uint8_t*) &(data_buffer[transceiver_buffer_pos * CC1100_MAX_DATA_LENGTH]);
|
||||
trans_p->data = (uint8_t *)&(data_buffer[transceiver_buffer_pos * CC1100_MAX_DATA_LENGTH]);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MODULE_CC110X
|
||||
void receive_cc1100_packet(radio_packet_t *trans_p) {
|
||||
void receive_cc1100_packet(radio_packet_t *trans_p)
|
||||
{
|
||||
dINT();
|
||||
trans_p->src = cc1100_packet_info->source;
|
||||
trans_p->dst = cc1100_packet_info->destination;
|
||||
trans_p->rssi = cc1100_packet_info->rssi;
|
||||
trans_p->lqi = cc1100_packet_info->lqi;
|
||||
trans_p->length = cc1100_payload_size;
|
||||
memcpy((void*) &(data_buffer[transceiver_buffer_pos * PAYLOAD_SIZE]), cc1100_payload, CC1100_MAX_DATA_LENGTH);
|
||||
memcpy((void *)&(data_buffer[transceiver_buffer_pos * PAYLOAD_SIZE]), cc1100_payload, CC1100_MAX_DATA_LENGTH);
|
||||
eINT();
|
||||
|
||||
trans_p->data = (uint8_t*) &(data_buffer[transceiver_buffer_pos * CC1100_MAX_DATA_LENGTH]);
|
||||
trans_p->data = (uint8_t *)&(data_buffer[transceiver_buffer_pos * CC1100_MAX_DATA_LENGTH]);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------------*/
|
||||
/*
|
||||
* @brief Sends a radio packet to the receiver
|
||||
@ -356,18 +387,19 @@ void receive_cc1100_packet(radio_packet_t *trans_p) {
|
||||
*
|
||||
* @return 1 on success, 0 otherwise
|
||||
*/
|
||||
static uint8_t send_packet(transceiver_type_t t, void *pkt) {
|
||||
static uint8_t send_packet(transceiver_type_t t, void *pkt)
|
||||
{
|
||||
uint8_t res = 0;
|
||||
#ifdef MODULE_CC110X
|
||||
int snd_ret;
|
||||
#endif
|
||||
radio_packet_t p = *((radio_packet_t*) pkt);
|
||||
|
||||
radio_packet_t p = *((radio_packet_t *)pkt);
|
||||
|
||||
#ifdef MODULE_CC110X_NG
|
||||
cc110x_packet_t cc110x_pkt;
|
||||
#endif
|
||||
|
||||
switch (t) {
|
||||
switch(t) {
|
||||
case TRANSCEIVER_CC1100:
|
||||
#ifdef MODULE_CC110X_NG
|
||||
cc110x_pkt.length = p.length + CC1100_HEADER_LENGTH;
|
||||
@ -377,19 +409,23 @@ static uint8_t send_packet(transceiver_type_t t, void *pkt) {
|
||||
res = cc110x_send(&cc110x_pkt);
|
||||
#else
|
||||
memcpy(cc1100_pkt, p.data, p.length);
|
||||
if ((snd_ret = cc1100_send_csmaca(p.dst, 4, 0, (char*) cc1100_pkt, p.length)) < 0) {
|
||||
|
||||
if((snd_ret = cc1100_send_csmaca(p.dst, 4, 0, (char *) cc1100_pkt, p.length)) < 0) {
|
||||
DEBUG("snd_ret (%u) = %i\n", p.length, snd_ret);
|
||||
res = 0;
|
||||
}
|
||||
else {
|
||||
res = 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
puts("Unknown transceiver");
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -402,15 +438,18 @@ static uint8_t send_packet(transceiver_type_t t, void *pkt) {
|
||||
*
|
||||
* @return The radio channel AFTER calling the set command, -1 on error
|
||||
*/
|
||||
static int16_t set_channel(transceiver_type_t t, void *channel) {
|
||||
uint8_t c = *((uint8_t*) channel);
|
||||
switch (t) {
|
||||
static int16_t set_channel(transceiver_type_t t, void *channel)
|
||||
{
|
||||
uint8_t c = *((uint8_t *)channel);
|
||||
|
||||
switch(t) {
|
||||
case TRANSCEIVER_CC1100:
|
||||
#ifdef MODULE_CC110X_NG
|
||||
return cc110x_set_channel(c);
|
||||
#else
|
||||
return cc1100_set_channel(c);
|
||||
#endif
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
@ -423,14 +462,16 @@ static int16_t set_channel(transceiver_type_t t, void *channel) {
|
||||
*
|
||||
* @return The current radio channel of the transceiver, -1 on error
|
||||
*/
|
||||
static int16_t get_channel(transceiver_type_t t) {
|
||||
switch (t) {
|
||||
static int16_t get_channel(transceiver_type_t t)
|
||||
{
|
||||
switch(t) {
|
||||
case TRANSCEIVER_CC1100:
|
||||
#ifdef MODULE_CC110X_NG
|
||||
return cc110x_get_channel();
|
||||
#else
|
||||
return cc1100_get_channel();
|
||||
#endif
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
@ -443,14 +484,16 @@ static int16_t get_channel(transceiver_type_t t) {
|
||||
*
|
||||
* @return The configured address of the device, -1 on error
|
||||
*/
|
||||
static int16_t get_address(transceiver_type_t t) {
|
||||
switch (t) {
|
||||
static int16_t get_address(transceiver_type_t t)
|
||||
{
|
||||
switch(t) {
|
||||
case TRANSCEIVER_CC1100:
|
||||
#ifdef MODULE_CC110X_NG
|
||||
return cc110x_get_address();
|
||||
#else
|
||||
return cc1100_get_address();
|
||||
#endif
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
@ -464,15 +507,18 @@ static int16_t get_address(transceiver_type_t t) {
|
||||
*
|
||||
* @return The new radio address of the device
|
||||
*/
|
||||
static int16_t set_address(transceiver_type_t t, void *address) {
|
||||
radio_address_t addr = *((radio_address_t*) address);
|
||||
switch (t) {
|
||||
static int16_t set_address(transceiver_type_t t, void *address)
|
||||
{
|
||||
radio_address_t addr = *((radio_address_t *)address);
|
||||
|
||||
switch(t) {
|
||||
case TRANSCEIVER_CC1100:
|
||||
#ifdef MODULE_CC110X_NG
|
||||
return cc110x_set_address(addr);
|
||||
#else
|
||||
return cc1100_set_address(addr);
|
||||
#endif
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
@ -484,50 +530,59 @@ static int16_t set_address(transceiver_type_t t, void *address) {
|
||||
* @param t The transceiver device
|
||||
* @param mode 1 for enabling monitor mode, 0 for enabling address check
|
||||
*/
|
||||
static void set_monitor(transceiver_type_t t, void *mode) {
|
||||
switch (t) {
|
||||
static void set_monitor(transceiver_type_t t, void *mode)
|
||||
{
|
||||
switch(t) {
|
||||
case TRANSCEIVER_CC1100:
|
||||
#ifdef MODULE_CC110X_NG
|
||||
cc110x_set_monitor(*((uint8_t*) mode));
|
||||
cc110x_set_monitor(*((uint8_t *)mode));
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*------------------------------------------------------------------------------------*/
|
||||
static void powerdown(transceiver_type_t t) {
|
||||
switch (t) {
|
||||
static void powerdown(transceiver_type_t t)
|
||||
{
|
||||
switch(t) {
|
||||
case TRANSCEIVER_CC1100:
|
||||
#ifdef MODULE_CC110X_NG
|
||||
cc110x_switch_to_pwd();
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------------*/
|
||||
static void switch_to_rx(transceiver_type_t t) {
|
||||
switch (t) {
|
||||
static void switch_to_rx(transceiver_type_t t)
|
||||
{
|
||||
switch(t) {
|
||||
case TRANSCEIVER_CC1100:
|
||||
#ifdef MODULE_CC110X_NG
|
||||
cc110x_switch_to_rx();
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DBG_IGNORE
|
||||
static void ignore_add(transceiver_type_t t, void *address) {
|
||||
radio_address_t addr = *((radio_address_t*) address);
|
||||
switch (t) {
|
||||
static void ignore_add(transceiver_type_t t, void *address)
|
||||
{
|
||||
radio_address_t addr = *((radio_address_t *)address);
|
||||
|
||||
switch(t) {
|
||||
case TRANSCEIVER_CC1100:
|
||||
cc110x_add_ignored(addr);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -17,33 +17,39 @@ static char buffer[UART0_BUFSIZE];
|
||||
|
||||
static char uart0_thread_stack[UART0_STACKSIZE];
|
||||
|
||||
static void uart0_loop(void) {
|
||||
static void uart0_loop(void)
|
||||
{
|
||||
chardev_loop(&uart0_ringbuffer);
|
||||
}
|
||||
|
||||
void board_uart0_init(void) {
|
||||
void board_uart0_init(void)
|
||||
{
|
||||
ringbuffer_init(&uart0_ringbuffer, buffer, UART0_BUFSIZE);
|
||||
int pid = thread_create(uart0_thread_stack, sizeof(uart0_thread_stack), PRIORITY_MAIN-1, CREATE_STACKTEST, uart0_loop, "uart0");
|
||||
int pid = thread_create(uart0_thread_stack, sizeof(uart0_thread_stack), PRIORITY_MAIN - 1, CREATE_STACKTEST, uart0_loop, "uart0");
|
||||
uart0_handler_pid = pid;
|
||||
puts("uart0_init() [OK]");
|
||||
}
|
||||
|
||||
void uart0_handle_incoming(int c) {
|
||||
void uart0_handle_incoming(int c)
|
||||
{
|
||||
rb_add_element(&uart0_ringbuffer, c);
|
||||
}
|
||||
|
||||
void uart0_notify_thread(void) {
|
||||
void uart0_notify_thread(void)
|
||||
{
|
||||
msg_t m;
|
||||
m.type = 0;
|
||||
msg_send_int(&m, uart0_handler_pid);
|
||||
}
|
||||
|
||||
int uart0_readc(void) {
|
||||
int uart0_readc(void)
|
||||
{
|
||||
char c = 0;
|
||||
posix_read(uart0_handler_pid, &c, 1);
|
||||
return c;
|
||||
}
|
||||
|
||||
void uart0_putc(int c) {
|
||||
void uart0_putc(int c)
|
||||
{
|
||||
putchar(c);
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ static int set_longterm(vtimer_t *timer);
|
||||
static int set_shortterm(vtimer_t *timer);
|
||||
|
||||
#ifdef ENABLE_DEBUG
|
||||
static void vtimer_print(vtimer_t* t);
|
||||
static void vtimer_print(vtimer_t *t);
|
||||
#endif
|
||||
|
||||
static queue_node_t longterm_queue_root;
|
||||
@ -42,17 +42,20 @@ static uint32_t hwtimer_next_absolute;
|
||||
|
||||
static uint32_t seconds = 0;
|
||||
|
||||
static int set_longterm(vtimer_t *timer) {
|
||||
static int set_longterm(vtimer_t *timer)
|
||||
{
|
||||
timer->queue_entry.priority = timer->absolute.seconds;
|
||||
queue_priority_add(&longterm_queue_root, (queue_node_t*)timer);
|
||||
queue_priority_add(&longterm_queue_root, (queue_node_t *)timer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int update_shortterm(void) {
|
||||
if (hwtimer_id != -1) {
|
||||
if (hwtimer_next_absolute != shortterm_queue_root.next->priority) {
|
||||
static int update_shortterm(void)
|
||||
{
|
||||
if(hwtimer_id != -1) {
|
||||
if(hwtimer_next_absolute != shortterm_queue_root.next->priority) {
|
||||
hwtimer_remove(hwtimer_id);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -62,17 +65,18 @@ static int update_shortterm(void) {
|
||||
unsigned int next = hwtimer_next_absolute + longterm_tick_start;
|
||||
unsigned int now = hwtimer_now();
|
||||
|
||||
if((next - VTIMER_THRESHOLD - now) > MICROSECONDS_PER_TICK ) {
|
||||
if((next - VTIMER_THRESHOLD - now) > MICROSECONDS_PER_TICK) {
|
||||
next = now + VTIMER_BACKOFF;
|
||||
}
|
||||
|
||||
|
||||
hwtimer_id = hwtimer_set_absolute(next, vtimer_callback, NULL);
|
||||
|
||||
DEBUG("update_shortterm: Set hwtimer to %lu (now=%lu)\n", hwtimer_next_absolute + longterm_tick_start, hwtimer_now());
|
||||
return 0;
|
||||
}
|
||||
|
||||
void vtimer_tick(void *ptr) {
|
||||
void vtimer_tick(void *ptr)
|
||||
{
|
||||
DEBUG("vtimer_tick().");
|
||||
seconds += SECONDS_PER_TICK;
|
||||
|
||||
@ -80,12 +84,14 @@ void vtimer_tick(void *ptr) {
|
||||
longterm_tick_timer.absolute.microseconds = longterm_tick_timer.absolute.microseconds + MICROSECONDS_PER_TICK;
|
||||
set_shortterm(&longterm_tick_timer);
|
||||
|
||||
while (longterm_queue_root.next) {
|
||||
vtimer_t *timer = (vtimer_t*) longterm_queue_root.next;
|
||||
if (timer->absolute.seconds == seconds) {
|
||||
timer = (vtimer_t*) queue_remove_head(&longterm_queue_root);
|
||||
while(longterm_queue_root.next) {
|
||||
vtimer_t *timer = (vtimer_t *) longterm_queue_root.next;
|
||||
|
||||
if(timer->absolute.seconds == seconds) {
|
||||
timer = (vtimer_t *) queue_remove_head(&longterm_queue_root);
|
||||
set_shortterm(timer);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -93,14 +99,16 @@ void vtimer_tick(void *ptr) {
|
||||
update_shortterm();
|
||||
}
|
||||
|
||||
static int set_shortterm(vtimer_t *timer) {
|
||||
static int set_shortterm(vtimer_t *timer)
|
||||
{
|
||||
DEBUG("set_shortterm(): Absolute: %lu %lu\n", timer->absolute.seconds, timer->absolute.microseconds);
|
||||
timer->queue_entry.priority = timer->absolute.microseconds;
|
||||
queue_priority_add(&shortterm_queue_root, (queue_node_t*)timer);
|
||||
queue_priority_add(&shortterm_queue_root, (queue_node_t *)timer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void vtimer_callback(void *ptr) {
|
||||
void vtimer_callback(void *ptr)
|
||||
{
|
||||
vtimer_t *timer;
|
||||
in_callback = true;
|
||||
hwtimer_id = -1;
|
||||
@ -113,38 +121,44 @@ void vtimer_callback(void *ptr) {
|
||||
DEBUG("vtimer_callback(): Shooting %lu.\n", timer->absolute.microseconds);
|
||||
|
||||
/* shoot timer */
|
||||
if (timer->action == (void*) msg_send_int) {
|
||||
msg_t msg;
|
||||
if(timer->action == (void *) msg_send_int) {
|
||||
msg_t msg;
|
||||
msg.type = MSG_TIMER;
|
||||
msg.content.value = (unsigned int) timer->arg;
|
||||
msg_send_int(&msg, timer->pid);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
timer->action(timer->arg);
|
||||
}
|
||||
}
|
||||
|
||||
in_callback = false;
|
||||
update_shortterm();
|
||||
}
|
||||
|
||||
void normalize_to_tick(timex_t *time) {
|
||||
void normalize_to_tick(timex_t *time)
|
||||
{
|
||||
DEBUG("Normalizing: %lu %lu\n", time->seconds, time->microseconds);
|
||||
uint32_t seconds_tmp = time->seconds % SECONDS_PER_TICK;
|
||||
time->seconds -= seconds_tmp;
|
||||
uint32_t usecs_tmp = time->microseconds + (seconds_tmp * 1000000);
|
||||
DEBUG("Normalizin2: %lu %lu\n", time->seconds, usecs_tmp);
|
||||
if (usecs_tmp < time->microseconds) {
|
||||
|
||||
if(usecs_tmp < time->microseconds) {
|
||||
usecs_tmp -= MICROSECONDS_PER_TICK;
|
||||
time->seconds += SECONDS_PER_TICK;
|
||||
}
|
||||
if (usecs_tmp > MICROSECONDS_PER_TICK) {
|
||||
|
||||
if(usecs_tmp > MICROSECONDS_PER_TICK) {
|
||||
usecs_tmp -= MICROSECONDS_PER_TICK;
|
||||
time->seconds += SECONDS_PER_TICK;
|
||||
}
|
||||
|
||||
time->microseconds = usecs_tmp;
|
||||
DEBUG(" Result: %lu %lu\n", time->seconds, time->microseconds);
|
||||
}
|
||||
|
||||
static int vtimer_set(vtimer_t *timer) {
|
||||
static int vtimer_set(vtimer_t *timer)
|
||||
{
|
||||
DEBUG("vtimer_set(): New timer. Offset: %lu %lu\n", timer->absolute.seconds, timer->absolute.microseconds);
|
||||
|
||||
timex_t now;
|
||||
@ -156,26 +170,28 @@ static int vtimer_set(vtimer_t *timer) {
|
||||
|
||||
int result = 0;
|
||||
|
||||
if (timer->absolute.seconds == 0) {
|
||||
if (timer->absolute.microseconds > 10) {
|
||||
if(timer->absolute.seconds == 0) {
|
||||
if(timer->absolute.microseconds > 10) {
|
||||
timer->absolute.microseconds -= 10;
|
||||
}
|
||||
}
|
||||
|
||||
int state = disableIRQ();
|
||||
if (timer->absolute.seconds != seconds){
|
||||
|
||||
if(timer->absolute.seconds != seconds) {
|
||||
/* we're long-term */
|
||||
DEBUG("vtimer_set(): setting long_term\n");
|
||||
result = set_longterm(timer);
|
||||
}
|
||||
else {
|
||||
DEBUG("vtimer_set(): setting short_term\n");
|
||||
if (set_shortterm(timer)) {
|
||||
|
||||
/* delay update of next shortterm timer if we
|
||||
if(set_shortterm(timer)) {
|
||||
|
||||
/* delay update of next shortterm timer if we
|
||||
* are called from within vtimer_callback. */
|
||||
|
||||
if (!in_callback) {
|
||||
|
||||
if(!in_callback) {
|
||||
result = update_shortterm();
|
||||
}
|
||||
}
|
||||
@ -187,19 +203,21 @@ static int vtimer_set(vtimer_t *timer) {
|
||||
return result;
|
||||
}
|
||||
|
||||
void vtimer_now(timex_t* out) {
|
||||
timex_t t = timex_set(seconds, hwtimer_now()-longterm_tick_start);
|
||||
void vtimer_now(timex_t *out)
|
||||
{
|
||||
timex_t t = timex_set(seconds, hwtimer_now() - longterm_tick_start);
|
||||
memcpy(out, &t, sizeof(timex_t));
|
||||
}
|
||||
|
||||
int vtimer_init() {
|
||||
int vtimer_init()
|
||||
{
|
||||
DEBUG("vtimer_init().\n");
|
||||
int state = disableIRQ();
|
||||
seconds = 0;
|
||||
|
||||
longterm_tick_timer.action = vtimer_tick;
|
||||
longterm_tick_timer.arg = NULL;
|
||||
|
||||
|
||||
longterm_tick_timer.absolute.seconds = 0;
|
||||
longterm_tick_timer.absolute.microseconds = MICROSECONDS_PER_TICK;
|
||||
|
||||
@ -212,22 +230,25 @@ int vtimer_init() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vtimer_set_wakeup(vtimer_t *t, timex_t interval, int pid) {
|
||||
int vtimer_set_wakeup(vtimer_t *t, timex_t interval, int pid)
|
||||
{
|
||||
int ret;
|
||||
t->action = (void*) thread_wakeup;
|
||||
t->arg = (void*) pid;
|
||||
t->action = (void *) thread_wakeup;
|
||||
t->arg = (void *) pid;
|
||||
t->absolute = interval;
|
||||
t->pid = 0;
|
||||
ret = vtimer_set(t);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int vtimer_usleep(uint32_t usecs) {
|
||||
int vtimer_usleep(uint32_t usecs)
|
||||
{
|
||||
timex_t offset = timex_set(0, usecs);
|
||||
return vtimer_sleep(offset);
|
||||
}
|
||||
|
||||
int vtimer_sleep(timex_t time) {
|
||||
int vtimer_sleep(timex_t time)
|
||||
{
|
||||
int ret;
|
||||
vtimer_t t;
|
||||
ret = vtimer_set_wakeup(&t, time, thread_getpid());
|
||||
@ -235,32 +256,38 @@ int vtimer_sleep(timex_t time) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int vtimer_remove(vtimer_t *t){
|
||||
queue_remove(&shortterm_queue_root, (queue_node_t*)t);
|
||||
queue_remove(&longterm_queue_root, (queue_node_t*)t);
|
||||
|
||||
int vtimer_remove(vtimer_t *t)
|
||||
{
|
||||
queue_remove(&shortterm_queue_root, (queue_node_t *)t);
|
||||
queue_remove(&longterm_queue_root, (queue_node_t *)t);
|
||||
|
||||
update_shortterm();
|
||||
|
||||
if (! inISR() ) eINT();
|
||||
return 0;
|
||||
|
||||
if(! inISR()) {
|
||||
eINT();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vtimer_set_msg(vtimer_t *t, timex_t interval, unsigned int pid, void *ptr){
|
||||
t->action = (void* ) msg_send_int;
|
||||
int vtimer_set_msg(vtimer_t *t, timex_t interval, unsigned int pid, void *ptr)
|
||||
{
|
||||
t->action = (void *) msg_send_int;
|
||||
t->arg = ptr;
|
||||
t->absolute = interval;
|
||||
t->pid = pid;
|
||||
t->pid = pid;
|
||||
vtimer_set(t);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void vtimer_print(vtimer_t* t) {
|
||||
void vtimer_print(vtimer_t *t)
|
||||
{
|
||||
printf("Seconds: %u - Microseconds: %u\n \
|
||||
action: %p\n \
|
||||
action: %p\n \
|
||||
pid: %u\n",
|
||||
t->absolute.seconds, t->absolute.microseconds,
|
||||
t->action,
|
||||
t->arg,
|
||||
t->pid);
|
||||
t->absolute.seconds, t->absolute.microseconds,
|
||||
t->action,
|
||||
t->arg,
|
||||
t->pid);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user