1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-12-24 22:13:52 +01:00

Merge pull request #108 from OlegHahm/unmaintained_libs

removed unmaintained code
This commit is contained in:
Oleg Hahm 2013-08-13 00:44:25 -07:00
commit 88b8ccf3e8
28 changed files with 0 additions and 4267 deletions

View File

@ -2,10 +2,6 @@ ifeq ($(CPU),lpc2387)
DIRS = arm_common lpc_common lpc2387
endif
ifeq ($(CPU),lpc214x)
DIRS = arm_common lpc_common lpc214x
endif
ifeq ($(CPU),mc1322x)
DIRS = arm_common mc1322x
endif

View File

@ -3,11 +3,6 @@ ifeq ($(CPU),lpc2387)
INCLUDES += -I$(MAKEBASE)/cpu/lpc_common/include/
INCLUDES += -I$(MAKEBASE)/cpu/lpc2387/include
endif
ifeq ($(CPU),lpc214x)
INCLUDES += -I$(MAKEBASE)/cpu/arm_common/include/
INCLUDES += -I$(MAKEBASE)/cpu/lpc_common/include/
INCLUDES += -I$(MAKEBASE)/cpu/lpc214x/include
endif
ifeq ($(CPU),mc1322x)
INCLUDES += -I$(MAKEBASE)/cpu/arm_common/include/
INCLUDES += -I$(MAKEBASE)/cpu/mc1322x/include

View File

@ -5,12 +5,6 @@ ifeq ($(CPU),lpc2387)
export INCLUDES += -I$(RIOTCPU)/arm_common/include
export INCLUDES += -I$(RIOTCPU)/lpc_common/include
endif
ifeq ($(CPU),lpc214x)
export USEMODULE += arm_common lpc_common
export UNDEF += $(BINDIR)syscalls.o $(BINDIR)lpc_syscalls.o
export INCLUDES += -I$(RIOTCPU)/arm_common/include
export INCLUDES += -I$(RIOTCPU)/lpc_common/include
endif
ifeq ($(CPU),mc1322x)
export USEMODULE += arm_common
export UNDEF += $(BINDIR)syscalls.o

View File

@ -139,10 +139,6 @@ arm_irq_handler:
/* jump into vic interrupt */
mov r0, #0xffffff00 /* lpc23xx */
.ifdef lpc214x
sub r0, r0, #0xed0 /* lpc214x won't accept non-8bit aligned constant... */
.endif
ldr r0, [r0]
add lr,pc,#4
mov pc, r0

View File

@ -67,10 +67,6 @@ extern uintptr_t __heap3_max; ///< maximum for end of heap memory space
/*-----------------------------------------------------------------------------------*/
void __assert_func(const char *file, int line, const char *func, const char *failedexpr)
{
#if SYSLOG_CONF_ASSERT
trace_number(TRACELOG_EV_ASSERTION, line);
syslog(SL_EMERGENCY, "assert", "%s() in %s:%u\n", func, file, line);
#endif
printf("#!assertion %s failed\n\t%s() in %s:%u\n", failedexpr, func, file, line);
_exit(3);
}
@ -253,9 +249,6 @@ int _unlink_r(struct _reent *r, char *path)
/*---------------------------------------------------------------------------*/
void _exit(int n)
{
#ifdef MODULE_TRACELOG
trace_number(TRACELOG_EV_EXIT, n);
#endif
printf("#!exit %i: resetting\n", n);
stdio_flush();

View File

@ -1,32 +0,0 @@
SRC = blocklist.c kernel_init.c msg.c scheduler.c blocklist_malloc.c ktimer.c mutex.c thread.c clist.c queue.c
OBJ = $(SRC:%.c=../bin/%.o)
INCLUDES = -Iinclude/ -I../sys/include -I../sys/lib -I../sys/drivers/include -I../cpu/$(CPU)/include/
ifeq ($(CPU),lpc2387)
INCLUDES += -I../cpu/arm_common/include/
CPUINCLUDE = -includecpu-conf.h
endif
ifeq ($(CPU),lpc214x)
INCLUDES += -I../cpu/arm_common/include/
endif
../bin/core.a: $(OBJ)
$(AR) rcs ../bin/core.a $(OBJ)
# pull in dependency info for *existing* .o files
-include $(OBJ:.o=.d)
# compile and generate dependency info
../bin/%.o: %.c
$(CC) $(CFLAGS) $(INCLUDES) $(CPUINCLUDE) -c $*.c -o ../bin/$*.o
$(CC) $(CFLAGS) $(INCLUDES) $(CPUINCLUDE) -MM $*.c > ../bin/$*.d
@printf "../bin/"|cat - ../bin/$*.d > /tmp/fw_out && mv /tmp/fw_out ../bin/$*.d
# remove compilation products
clean:
rm -f ../bin/core.a ../bin/*.o ../bin/*.d

View File

@ -1,41 +0,0 @@
#include "cpu.h"
#include "bits.h"
#include "VIC.h"
void cpu_clock_scale(uint32_t source, uint32_t target, uint32_t *prescale)
{
*prescale = source / PCLK_DIV / target;
}
/******************************************************************************
** Function name: install_irq
**
** Descriptions: Install interrupt handler
** parameters: Interrupt number, interrupt handler address,
** interrupt priority
** Returned value: true or false, return false if IntNum is out of range
**
******************************************************************************/
#define VIC_BASE_ADDR 0xFFFFF000
bool cpu_install_irq(int IntNumber, void *HandlerAddr, int Priority)
{
int *vect_addr;
int *vect_cntl;
VICIntEnClear = 1 << IntNumber; /* Disable Interrupt */
if (IntNumber >= VIC_SIZE) {
return (false);
}
else {
/* find first un-assigned VIC address for the handler */
vect_addr = (int *)(VIC_BASE_ADDR + VECT_ADDR_INDEX + Priority * 4);
vect_cntl = (int *)(VIC_BASE_ADDR + VECT_CNTL_INDEX + Priority * 4);
*vect_addr = (int)HandlerAddr; /* set interrupt vector */
*vect_cntl = IntNumber + BIT5;
VICIntEnable = 1 << IntNumber; /* Enable Interrupt */
return(true);
}
}

View File

@ -1,19 +0,0 @@
/******************************************************************************
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 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 __CPU_H
#define __CPU_H
#include "arm_cpu.h"
#include "lpc2148.h"
#endif /* __CPU_H */

View File

@ -1,24 +0,0 @@
/*
* lpc2148.h
*
* Copyright (C) 2009 Kaspar Schleiser <kaspar@schleiser.de>
*
* Parts taken from FeuerWhere-Project, lpc2148.h.
*/
#ifndef __LPC2148_H
#define __LPC2148_H
#include "lpc214x.h"
#define F_CCO 240000000
#define CL_CPU_DIV 4 ///< CPU clock divider
#define F_CPU (F_CCO / CL_CPU_DIV) ///< CPU target speed in Hz
#define F_RC_OSCILLATOR 12000000 ///< Frequency of internal RC oscillator
#define F_RTC_OSCILLATOR 32767 ///< Frequency of RTC oscillator
#define PCLK_DIV 0x2 ///< PCLK clock divider, F_CPU/PCLK_DIV=PCLK
#define VIC_SIZE 16
#endif // __LPC2148_H

View File

@ -1,428 +0,0 @@
/* Copyright (C) 2005, 2006, 2007, 2008 by Thomas Hillebrandt and Heiko Will
This file is part of RIOT.
This file subject to the terms and conditions of the GNU Lesser General
Public License. See the file LICENSE in the top level directory for more
details.
*/
/* As a special exception, if you include this header file into source
files compiled by GCC, this header file does not by itself cause
the resulting executable to be covered by the GNU Lesser General Public
License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU Lesser General
Public License. */
#ifndef __LPC214x_H
#define __LPC214x_H
#define BIT0 0x00000001
#define BIT1 0x00000002
#define BIT2 0x00000004
#define BIT3 0x00000008
#define BIT4 0x00000010
#define BIT5 0x00000020
#define BIT6 0x00000040
#define BIT7 0x00000080
#define BIT8 0x00000100
#define BIT9 0x00000200
#define BIT10 0x00000400
#define BIT11 0x00000800
#define BIT12 0x00001000
#define BIT13 0x00002000
#define BIT14 0x00004000
#define BIT15 0x00008000
#define BIT16 0x00010000
#define BIT17 0x00020000
#define BIT18 0x00040000
#define BIT19 0x00080000
#define BIT20 0x00100000
#define BIT21 0x00200000
#define BIT22 0x00400000
#define BIT23 0x00800000
#define BIT24 0x01000000
#define BIT25 0x02000000
#define BIT26 0x04000000
#define BIT27 0x08000000
#define BIT28 0x10000000
#define BIT29 0x20000000
#define BIT30 0x40000000
#define BIT31 0x80000000
/* Vectored Interrupt Controller (VIC) */
#define VICIRQStatus (*((volatile unsigned long *) 0xFFFFF000))
#define VICFIQStatus (*((volatile unsigned long *) 0xFFFFF004))
#define VICRawIntr (*((volatile unsigned long *) 0xFFFFF008))
#define VICIntSelect (*((volatile unsigned long *) 0xFFFFF00C))
#define VICIntEnable (*((volatile unsigned long *) 0xFFFFF010))
#define VICIntEnClr (*((volatile unsigned long *) 0xFFFFF014))
#define VICIntEnClear (*((volatile unsigned long *) 0xFFFFF014))
#define VICSoftInt (*((volatile unsigned long *) 0xFFFFF018))
#define VICSoftIntClr (*((volatile unsigned long *) 0xFFFFF01C))
#define VICProtection (*((volatile unsigned long *) 0xFFFFF020))
#define VICVectAddr (*((volatile unsigned long *) 0xFFFFF030))
#define VICDefVectAddr (*((volatile unsigned long *) 0xFFFFF034))
#define VICVectAddr0 (*((volatile unsigned long *) 0xFFFFF100))
#define VICVectAddr1 (*((volatile unsigned long *) 0xFFFFF104))
#define VICVectAddr2 (*((volatile unsigned long *) 0xFFFFF108))
#define VICVectAddr3 (*((volatile unsigned long *) 0xFFFFF10C))
#define VICVectAddr4 (*((volatile unsigned long *) 0xFFFFF110))
#define VICVectAddr5 (*((volatile unsigned long *) 0xFFFFF114))
#define VICVectAddr6 (*((volatile unsigned long *) 0xFFFFF118))
#define VICVectAddr7 (*((volatile unsigned long *) 0xFFFFF11C))
#define VICVectAddr8 (*((volatile unsigned long *) 0xFFFFF120))
#define VICVectAddr9 (*((volatile unsigned long *) 0xFFFFF124))
#define VICVectAddr10 (*((volatile unsigned long *) 0xFFFFF128))
#define VICVectAddr11 (*((volatile unsigned long *) 0xFFFFF12C))
#define VICVectAddr12 (*((volatile unsigned long *) 0xFFFFF130))
#define VICVectAddr13 (*((volatile unsigned long *) 0xFFFFF134))
#define VICVectAddr14 (*((volatile unsigned long *) 0xFFFFF138))
#define VICVectAddr15 (*((volatile unsigned long *) 0xFFFFF13C))
#define VICVectCntl0 (*((volatile unsigned long *) 0xFFFFF200))
#define VICVectCntl1 (*((volatile unsigned long *) 0xFFFFF204))
#define VICVectCntl2 (*((volatile unsigned long *) 0xFFFFF208))
#define VICVectCntl3 (*((volatile unsigned long *) 0xFFFFF20C))
#define VICVectCntl4 (*((volatile unsigned long *) 0xFFFFF210))
#define VICVectCntl5 (*((volatile unsigned long *) 0xFFFFF214))
#define VICVectCntl6 (*((volatile unsigned long *) 0xFFFFF218))
#define VICVectCntl7 (*((volatile unsigned long *) 0xFFFFF21C))
#define VICVectCntl8 (*((volatile unsigned long *) 0xFFFFF220))
#define VICVectCntl9 (*((volatile unsigned long *) 0xFFFFF224))
#define VICVectCntl10 (*((volatile unsigned long *) 0xFFFFF228))
#define VICVectCntl11 (*((volatile unsigned long *) 0xFFFFF22C))
#define VICVectCntl12 (*((volatile unsigned long *) 0xFFFFF230))
#define VICVectCntl13 (*((volatile unsigned long *) 0xFFFFF234))
#define VICVectCntl14 (*((volatile unsigned long *) 0xFFFFF238))
#define VICVectCntl15 (*((volatile unsigned long *) 0xFFFFF23C))
/* Pin Connect Block */
#define PINSEL0 (*((volatile unsigned long *) 0xE002C000))
#define PINSEL1 (*((volatile unsigned long *) 0xE002C004))
#define PINSEL2 (*((volatile unsigned long *) 0xE002C014))
/* General Purpose Input/Output (GPIO) */
#define IOPIN0 (*((volatile unsigned long *) 0xE0028000))
#define IOSET0 (*((volatile unsigned long *) 0xE0028004))
#define IODIR0 (*((volatile unsigned long *) 0xE0028008))
#define IOCLR0 (*((volatile unsigned long *) 0xE002800C))
#define IOPIN1 (*((volatile unsigned long *) 0xE0028010))
#define IOSET1 (*((volatile unsigned long *) 0xE0028014))
#define IODIR1 (*((volatile unsigned long *) 0xE0028018))
#define IOCLR1 (*((volatile unsigned long *) 0xE002801C))
#define IO0PIN (*((volatile unsigned long *) 0xE0028000))
#define IO0SET (*((volatile unsigned long *) 0xE0028004))
#define IO0DIR (*((volatile unsigned long *) 0xE0028008))
#define IO0CLR (*((volatile unsigned long *) 0xE002800C))
#define IO1PIN (*((volatile unsigned long *) 0xE0028010))
#define IO1SET (*((volatile unsigned long *) 0xE0028014))
#define IO1DIR (*((volatile unsigned long *) 0xE0028018))
#define IO1CLR (*((volatile unsigned long *) 0xE002801C))
#define FIO0DIR (*((volatile unsigned long *) 0x3FFFC000))
#define FIO0MASK (*((volatile unsigned long *) 0x3FFFC010))
#define FIO0PIN (*((volatile unsigned long *) 0x3FFFC014))
#define FIO0SET (*((volatile unsigned long *) 0x3FFFC018))
#define FIO0CLR (*((volatile unsigned long *) 0x3FFFC01C))
#define FIO1DIR (*((volatile unsigned long *) 0x3FFFC020))
#define FIO1MASK (*((volatile unsigned long *) 0x3FFFC030))
#define FIO1PIN (*((volatile unsigned long *) 0x3FFFC034))
#define FIO1SET (*((volatile unsigned long *) 0x3FFFC038))
#define FIO1CLR (*((volatile unsigned long *) 0x3FFFC03C))
/* Memory Accelerator Module (MAM) */
#define MAMCR (*((volatile unsigned char *) 0xE01FC000))
#define MAMTIM (*((volatile unsigned char *) 0xE01FC004))
#define MEMMAP (*((volatile unsigned char *) 0xE01FC040))
/* Phase Locked Loop 0 (PLL0) */
#define PLL0CON (*((volatile unsigned char *) 0xE01FC080))
#define PLL0CFG (*((volatile unsigned char *) 0xE01FC084))
#define PLL0STAT (*((volatile unsigned short*) 0xE01FC088))
#define PLL0FEED (*((volatile unsigned char *) 0xE01FC08C))
/* Phase Locked Loop 1 (PLL1) */
#define PLL1CON (*((volatile unsigned char *) 0xE01FC0A0))
#define PLL1CFG (*((volatile unsigned char *) 0xE01FC0A4))
#define PLL1STAT (*((volatile unsigned short*) 0xE01FC0A8))
#define PLL1FEED (*((volatile unsigned char *) 0xE01FC0AC))
/* VPB Divider */
#define VPBDIV (*((volatile unsigned char *) 0xE01FC100))
/* Power Control */
#define PCON (*((volatile unsigned char *) 0xE01FC0C0))
#define PCONP (*((volatile unsigned long *) 0xE01FC0C4))
/* External Interrupts */
#define EXTINT (*((volatile unsigned char *) 0xE01FC140))
#define INTWAKE (*((volatile unsigned short*) 0xE01FC144))
#define EXTMODE (*((volatile unsigned char *) 0xE01FC148))
#define EXTPOLAR (*((volatile unsigned char *) 0xE01FC14C))
/* Reset */
#define RSID (*((volatile unsigned char *) 0xE01FC180))
/* Code Security / Debugging */
#define CSPR (*((volatile unsigned char *) 0xE01FC184))
/* System Control Miscellaneous */
#define SCS (*((volatile unsigned long *) 0xE01FC1A0))
/* Timer 0 */
#define TMR0_BASE_ADDR 0xE0004000
#define T0IR (*((volatile unsigned long *) 0xE0004000))
#define T0TCR (*((volatile unsigned long *) 0xE0004004))
#define T0TC (*((volatile unsigned long *) 0xE0004008))
#define T0PR (*((volatile unsigned long *) 0xE000400C))
#define T0PC (*((volatile unsigned long *) 0xE0004010))
#define T0MCR (*((volatile unsigned long *) 0xE0004014))
#define T0MR0 (*((volatile unsigned long *) 0xE0004018))
#define T0MR1 (*((volatile unsigned long *) 0xE000401C))
#define T0MR2 (*((volatile unsigned long *) 0xE0004020))
#define T0MR3 (*((volatile unsigned long *) 0xE0004024))
#define T0CCR (*((volatile unsigned long *) 0xE0004028))
#define T0CR0 (*((volatile unsigned long *) 0xE000402C))
#define T0CR1 (*((volatile unsigned long *) 0xE0004030))
#define T0CR2 (*((volatile unsigned long *) 0xE0004034))
#define T0CR3 (*((volatile unsigned long *) 0xE0004038))
#define T0EMR (*((volatile unsigned long *) 0xE000403C))
#define T0CTCR (*((volatile unsigned long *) 0xE0004070))
/* Timer 1 */
#define TMR1_BASE_ADDR 0xE0008000
#define T1IR (*((volatile unsigned long *) 0xE0008000))
#define T1TCR (*((volatile unsigned long *) 0xE0008004))
#define T1TC (*((volatile unsigned long *) 0xE0008008))
#define T1PR (*((volatile unsigned long *) 0xE000800C))
#define T1PC (*((volatile unsigned long *) 0xE0008010))
#define T1MCR (*((volatile unsigned long *) 0xE0008014))
#define T1MR0 (*((volatile unsigned long *) 0xE0008018))
#define T1MR1 (*((volatile unsigned long *) 0xE000801C))
#define T1MR2 (*((volatile unsigned long *) 0xE0008020))
#define T1MR3 (*((volatile unsigned long *) 0xE0008024))
#define T1CCR (*((volatile unsigned long *) 0xE0008028))
#define T1CR0 (*((volatile unsigned long *) 0xE000802C))
#define T1CR1 (*((volatile unsigned long *) 0xE0008030))
#define T1CR2 (*((volatile unsigned long *) 0xE0008034))
#define T1CR3 (*((volatile unsigned long *) 0xE0008038))
#define T1EMR (*((volatile unsigned long *) 0xE000803C))
#define T1CTCR (*((volatile unsigned long *) 0xE0008070))
/* Pulse Width Modulator (PWM) */
#define PWMIR (*((volatile unsigned long *) 0xE0014000))
#define PWMTCR (*((volatile unsigned long *) 0xE0014004))
#define PWMTC (*((volatile unsigned long *) 0xE0014008))
#define PWMPR (*((volatile unsigned long *) 0xE001400C))
#define PWMPC (*((volatile unsigned long *) 0xE0014010))
#define PWMMCR (*((volatile unsigned long *) 0xE0014014))
#define PWMMR0 (*((volatile unsigned long *) 0xE0014018))
#define PWMMR1 (*((volatile unsigned long *) 0xE001401C))
#define PWMMR2 (*((volatile unsigned long *) 0xE0014020))
#define PWMMR3 (*((volatile unsigned long *) 0xE0014024))
#define PWMMR4 (*((volatile unsigned long *) 0xE0014040))
#define PWMMR5 (*((volatile unsigned long *) 0xE0014044))
#define PWMMR6 (*((volatile unsigned long *) 0xE0014048))
#define PWMPCR (*((volatile unsigned long *) 0xE001404C))
#define PWMLER (*((volatile unsigned long *) 0xE0014050))
/* Universal Asynchronous Receiver Transmitter 0 (UART0) */
#define U0RBR (*((volatile unsigned char *) 0xE000C000))
#define U0THR (*((volatile unsigned char *) 0xE000C000))
#define U0IER (*((volatile unsigned long *) 0xE000C004))
#define U0IIR (*((volatile unsigned long *) 0xE000C008))
#define U0FCR (*((volatile unsigned char *) 0xE000C008))
#define U0LCR (*((volatile unsigned char *) 0xE000C00C))
#define U0MCR (*((volatile unsigned char *) 0xE000C010))
#define U0LSR (*((volatile unsigned char *) 0xE000C014))
#define U0MSR (*((volatile unsigned char *) 0xE000C018))
#define U0SCR (*((volatile unsigned char *) 0xE000C01C))
#define U0DLL (*((volatile unsigned char *) 0xE000C000))
#define U0DLM (*((volatile unsigned char *) 0xE000C004))
#define U0ACR (*((volatile unsigned long *) 0xE000C020))
#define U0FDR (*((volatile unsigned long *) 0xE000C028))
#define U0TER (*((volatile unsigned char *) 0xE000C030))
/* Universal Asynchronous Receiver Transmitter 1 (UART1) */
#define U1RBR (*((volatile unsigned char *) 0xE0010000))
#define U1THR (*((volatile unsigned char *) 0xE0010000))
#define U1IER (*((volatile unsigned long *) 0xE0010004))
#define U1IIR (*((volatile unsigned long *) 0xE0010008))
#define U1FCR (*((volatile unsigned char *) 0xE0010008))
#define U1LCR (*((volatile unsigned char *) 0xE001000C))
#define U1MCR (*((volatile unsigned char *) 0xE0010010))
#define U1LSR (*((volatile unsigned char *) 0xE0010014))
#define U1MSR (*((volatile unsigned char *) 0xE0010018))
#define U1SCR (*((volatile unsigned char *) 0xE001001C))
#define U1DLL (*((volatile unsigned char *) 0xE0010000))
#define U1DLM (*((volatile unsigned char *) 0xE0010004))
#define U1ACR (*((volatile unsigned long *) 0xE0010020))
#define U1FDR (*((volatile unsigned long *) 0xE0010028))
#define U1TER (*((volatile unsigned char *) 0xE0010030))
/* I2C Interface 0 */
#define I2C0CONSET (*((volatile unsigned char *) 0xE001C000))
#define I2C0STAT (*((volatile unsigned char *) 0xE001C004))
#define I2C0DAT (*((volatile unsigned char *) 0xE001C008))
#define I2C0ADR (*((volatile unsigned char *) 0xE001C00C))
#define I2C0SCLH (*((volatile unsigned short*) 0xE001C010))
#define I2C0SCLL (*((volatile unsigned short*) 0xE001C014))
#define I2C0CONCLR (*((volatile unsigned char *) 0xE001C018))
/* I2C Interface 1 */
#define I2C1CONSET (*((volatile unsigned char *) 0xE005C000))
#define I2C1STAT (*((volatile unsigned char *) 0xE005C004))
#define I2C1DAT (*((volatile unsigned char *) 0xE005C008))
#define I2C1ADR (*((volatile unsigned char *) 0xE005C00C))
#define I2C1SCLH (*((volatile unsigned short*) 0xE005C010))
#define I2C1SCLL (*((volatile unsigned short*) 0xE005C014))
#define I2C1CONCLR (*((volatile unsigned char *) 0xE005C018))
/* SPI0 (Serial Peripheral Interface 0) */
#define S0SPCR (*((volatile unsigned short*) 0xE0020000))
#define S0SPSR (*((volatile unsigned char *) 0xE0020004))
#define S0SPDR (*((volatile unsigned short*) 0xE0020008))
#define S0SPCCR (*((volatile unsigned char *) 0xE002000C))
#define S0SPINT (*((volatile unsigned char *) 0xE002001C))
/* SSP Controller (SPI1) */
#define SSPCR0 (*((volatile unsigned short*) 0xE0068000))
#define SSPCR1 (*((volatile unsigned char *) 0xE0068004))
#define SSPDR (*((volatile unsigned short*) 0xE0068008))
#define SSPSR (*((volatile unsigned char *) 0xE006800C))
#define SSPCPSR (*((volatile unsigned char *) 0xE0068010))
#define SSPIMSC (*((volatile unsigned char *) 0xE0068014))
#define SSPRIS (*((volatile unsigned char *) 0xE0068018))
#define SSPMIS (*((volatile unsigned char *) 0xE006801C))
#define SSPICR (*((volatile unsigned char *) 0xE0068020))
/* Real Time Clock */
#define ILR (*((volatile unsigned char *) 0xE0024000))
#define CTC (*((volatile unsigned short*) 0xE0024004))
#define CCR (*((volatile unsigned char *) 0xE0024008))
#define CIIR (*((volatile unsigned char *) 0xE002400C))
#define AMR (*((volatile unsigned char *) 0xE0024010))
#define CTIME0 (*((volatile unsigned long *) 0xE0024014))
#define CTIME1 (*((volatile unsigned long *) 0xE0024018))
#define CTIME2 (*((volatile unsigned long *) 0xE002401C))
#define SEC (*((volatile unsigned char *) 0xE0024020))
#define MINUTE (*((volatile unsigned char *) 0xE0024024))
#define HOUR (*((volatile unsigned char *) 0xE0024028))
#define DOM (*((volatile unsigned char *) 0xE002402C))
#define DOW (*((volatile unsigned char *) 0xE0024030))
#define DOY (*((volatile unsigned short*) 0xE0024034))
#define MONTH (*((volatile unsigned char *) 0xE0024038))
#define YEAR (*((volatile unsigned short*) 0xE002403C))
#define ALSEC (*((volatile unsigned char *) 0xE0024060))
#define ALMIN (*((volatile unsigned char *) 0xE0024064))
#define ALHOUR (*((volatile unsigned char *) 0xE0024068))
#define ALDOM (*((volatile unsigned char *) 0xE002406C))
#define ALDOW (*((volatile unsigned char *) 0xE0024070))
#define ALDOY (*((volatile unsigned short*) 0xE0024074))
#define ALMON (*((volatile unsigned char *) 0xE0024078))
#define ALYEAR (*((volatile unsigned short*) 0xE002407C))
#define PREINT (*((volatile unsigned short*) 0xE0024080))
#define PREFRAC (*((volatile unsigned short*) 0xE0024084))
/* A/D Converter 0 (AD0) */
#define AD0CR (*((volatile unsigned long *) 0xE0034000))
#define AD0GDR (*((volatile unsigned long *) 0xE0034004))
#define AD0STAT (*((volatile unsigned long *) 0xE0034030))
#define AD0INTEN (*((volatile unsigned long *) 0xE003400C))
#define AD0DR0 (*((volatile unsigned long *) 0xE0034010))
#define AD0DR1 (*((volatile unsigned long *) 0xE0034014))
#define AD0DR2 (*((volatile unsigned long *) 0xE0034018))
#define AD0DR3 (*((volatile unsigned long *) 0xE003401C))
#define AD0DR4 (*((volatile unsigned long *) 0xE0034020))
#define AD0DR5 (*((volatile unsigned long *) 0xE0034024))
#define AD0DR6 (*((volatile unsigned long *) 0xE0034028))
#define AD0DR7 (*((volatile unsigned long *) 0xE003402C))
/* A/D Converter 1 (AD1) */
#define AD1CR (*((volatile unsigned long *) 0xE0060000))
#define AD1GDR (*((volatile unsigned long *) 0xE0060004))
#define AD1STAT (*((volatile unsigned long *) 0xE0060030))
#define AD1INTEN (*((volatile unsigned long *) 0xE006000C))
#define AD1DR0 (*((volatile unsigned long *) 0xE0060010))
#define AD1DR1 (*((volatile unsigned long *) 0xE0060014))
#define AD1DR2 (*((volatile unsigned long *) 0xE0060018))
#define AD1DR3 (*((volatile unsigned long *) 0xE006001C))
#define AD1DR4 (*((volatile unsigned long *) 0xE0060020))
#define AD1DR5 (*((volatile unsigned long *) 0xE0060024))
#define AD1DR6 (*((volatile unsigned long *) 0xE0060028))
#define AD1DR7 (*((volatile unsigned long *) 0xE006002C))
/* A/D Converter Global */
#define ADGSR (*((volatile unsigned long *) 0xE0034008))
/* D/A Converter */
#define DACR (*((volatile unsigned long *) 0xE006C000))
/* Watchdog */
#define WDMOD (*((volatile unsigned char *) 0xE0000000))
#define WDTC (*((volatile unsigned long *) 0xE0000004))
#define WDFEED (*((volatile unsigned char *) 0xE0000008))
#define WDTV (*((volatile unsigned long *) 0xE000000C))
/* USB Controller */
#define USBIntSt (*((volatile unsigned long *) 0xE01FC1C0))
#define USBDevIntSt (*((volatile unsigned long *) 0xE0090000))
#define USBDevIntEn (*((volatile unsigned long *) 0xE0090004))
#define USBDevIntClr (*((volatile unsigned long *) 0xE0090008))
#define USBDevIntSet (*((volatile unsigned long *) 0xE009000C))
#define USBDevIntPri (*((volatile unsigned char *) 0xE009002C))
#define USBEpIntSt (*((volatile unsigned long *) 0xE0090030))
#define USBEpIntEn (*((volatile unsigned long *) 0xE0090034))
#define USBEpIntClr (*((volatile unsigned long *) 0xE0090038))
#define USBEpIntSet (*((volatile unsigned long *) 0xE009003C))
#define USBEpIntPri (*((volatile unsigned long *) 0xE0090040))
#define USBReEp (*((volatile unsigned long *) 0xE0090044))
#define USBEpInd (*((volatile unsigned long *) 0xE0090048))
#define USBMaxPSize (*((volatile unsigned long *) 0xE009004C))
#define USBRxData (*((volatile unsigned long *) 0xE0090018))
#define USBRxPLen (*((volatile unsigned long *) 0xE0090020))
#define USBTxData (*((volatile unsigned long *) 0xE009001C))
#define USBTxPLen (*((volatile unsigned long *) 0xE0090024))
#define USBCtrl (*((volatile unsigned long *) 0xE0090028))
#define USBCmdCode (*((volatile unsigned long *) 0xE0090010))
#define USBCmdData (*((volatile unsigned long *) 0xE0090014))
#define USBDMARSt (*((volatile unsigned long *) 0xE0090050))
#define USBDMARClr (*((volatile unsigned long *) 0xE0090054))
#define USBDMARSet (*((volatile unsigned long *) 0xE0090058))
#define USBUDCAH (*((volatile unsigned long *) 0xE0090080))
#define USBEpDMASt (*((volatile unsigned long *) 0xE0090084))
#define USBEpDMAEn (*((volatile unsigned long *) 0xE0090088))
#define USBEpDMADis (*((volatile unsigned long *) 0xE009008C))
#define USBDMAIntSt (*((volatile unsigned long *) 0xE0090090))
#define USBDMAIntEn (*((volatile unsigned long *) 0xE0090094))
#define USBEoTIntSt (*((volatile unsigned long *) 0xE00900A0))
#define USBEoTIntClr (*((volatile unsigned long *) 0xE00900A4))
#define USBEoTIntSet (*((volatile unsigned long *) 0xE00900A8))
#define USBNDDRIntSt (*((volatile unsigned long *) 0xE00900AC))
#define USBNDDRIntClr (*((volatile unsigned long *) 0xE00900B0))
#define USBNDDRIntSet (*((volatile unsigned long *) 0xE00900B4))
#define USBSysErrIntSt (*((volatile unsigned long *) 0xE00900B8))
#define USBSysErrIntClr (*((volatile unsigned long *) 0xE00900BC))
#define USBSysErrIntSet (*((volatile unsigned long *) 0xE00900C0))
// Pheripherals
#define PCTIM0 BIT1
#define PCTIM1 BIT2
#define PCUART0 BIT3
#define PCUART1 BIT4
#define PCPWM0 BIT5
#define PCI2C0 BIT7
#define PCSPI0 BIT8
#define PCRTC BIT9
#define PCSPI1 BIT10
#define PCAD0 BIT12
#define PCI2C1 BIT19
#define PCAD1 BIT20
#define PUSB BIT31
//inline void TurOffPeripheral(int p);
//inline void TurOnPeripheral(int p);
#endif

View File

@ -1,197 +0,0 @@
/* ****************************************************************************************************** */
/* demo2148_blink_flash.cmd LINKER SCRIPT */
/* */
/* */
/* The Linker Script defines how the code and data emitted by the GNU C compiler and assembler are */
/* to be loaded into memory (code goes into FLASH, variables go into RAM). */
/* */
/* Any symbols defined in the Linker Script are automatically global and available to the rest of the */
/* program. */
/* */
/* To force the linker to use this LINKER SCRIPT, just add the -T demo2148_blink_flash.cmd directive */
/* to the linker flags in the makefile. */
/* */
/* LFLAGS = -Map main.map -nostartfiles -T demo2148_blink_flash.cmd */
/* */
/* */
/* The Philips boot loader supports the ISP (In System Programming) via the serial port and the IAP */
/* (In Application Programming) for flash programming from within your application. */
/* */
/* The boot loader uses RAM memory and we MUST NOT load variables or code in these areas. */
/* */
/* RAM used by boot loader: 0x40000120 - 0x400001FF (223 bytes) for ISP variables */
/* 0x40007FE0 - 0x4000FFFF (32 bytes) for ISP and IAP variables */
/* 0x40007EE0 - 0x40007FE0 (256 bytes) stack for ISP and IAP */
/* */
/* */
/* MEMORY MAP */
/* | |0x40008000 */
/* .-------->|---------------------------------| */
/* . | variables and stack |0x40007FFF */
/* ram_isp_high | for Philips boot loader | */
/* . | 32 + 256 = 288 bytes | */
/* . | | */
/* . | Do not put anything here |0x40007EE0 */
/* .-------->|---------------------------------| */
/* | UDF Stack 4 bytes |0x40007EDC <---------- _stack_end */
/* .-------->|---------------------------------| */
/* | ABT Stack 4 bytes |0x40007ED8 */
/* .-------->|---------------------------------| */
/* | FIQ Stack 4 bytes |0x40007ED4 */
/* .-------->|---------------------------------| */
/* | IRQ Stack 4 bytes |0x40007ED0 */
/* .-------->|---------------------------------| */
/* | SVC Stack 4 bytes |0x40007ECC */
/* .-------->|---------------------------------| */
/* . | |0x40007EC8 */
/* . | stack area for user program | */
/* . | | | */
/* . | | | */
/* . | | | */
/* . | V | */
/* . | | */
/* . | | */
/* . | | */
/* . | free ram | */
/* ram | | */
/* . | | */
/* . | | */
/* . |.................................|0x40000234 <---------- _bss_end */
/* . | | */
/* . | .bss uninitialized variables | */
/* . |.................................|0x40000218 <---------- _bss_start, _edata */
/* . | | */
/* . | .data initialized variables | */
/* . | |0x40000200 <---------- _data */
/* .-------->|---------------------------------| */
/* . | variables used by |0x400001FF */
/* ram_isp_low | Philips boot loader | */
/* . | 223 bytes |0x40000120 */
/* .-------->|---------------------------------| */
/* . | |0x4000011F */
/* ram_vectors | free ram | */
/* . |---------------------------------|0x40000040 */
/* . | |0x4000003F */
/* . | Interrupt Vectors (re-mapped) | */
/* . | 64 bytes |0x40000000 */
/* .-------->|---------------------------------| */
/* | | */
/* */
/* */
/* */
/* | | */
/* .--------> |---------------------------------| */
/* . | |0x0001FFFF */
/* . | | */
/* . | | */
/* . | | */
/* . | | */
/* . | | */
/* . | unused flash eprom | */
/* . | | */
/* . |.................................|0x0000032c */
/* . | | */
/* . | copy of .data area | */
/* flash | | */
/* . |---------------------------------|0x00000314 <----------- _etext */
/* . | | */
/* . | |0x00000180 main */
/* . | |0x00000278 feed */
/* . | main() |0x000002c4 FIQ_Routine */
/* . | |0x000002d8 SWI_Routine */
/* . | |0x000002ec UNDEF_Routine */
/* . | |0x000002b0 IRQ_routine */
/* . |---------------------------------|0x000001cc initialize */
/* . | |0x000000D4 */
/* . | Startup Code | */
/* . | (assembler) | */
/* . | | */
/* . |---------------------------------|0x00000040 Reset_Handler */
/* . | |0x0000003F */
/* . | Interrupt Vector Table (unused) | */
/* . | 64 bytes | */
/* .--------->|---------------------------------|0x00000000 _startup *
/* */
/* */
/* The easy way to prevent the linker from loading anything into a memory area is to define */
/* a MEMORY region for it and then avoid assigning any .text, .data or .bss sections into it. */
/* */
/* */
/* MEMORY */
/* { */
/* ram_isp_low(A) : ORIGIN = 0x40000120, LENGTH = 223 */
/* */
/* } */
/* */
/* */
/* Author: James P. Lynch */
/* */
/* ****************************************************************************************************** */
/* identify the Entry Point */
ENTRY(_startup)
/* STARTUP(bin/startup.o)*/
/* specify the LPC2148 memory areas */
MEMORY
{
flash : ORIGIN = 0, LENGTH = 512K /* FLASH ROM */
ram_isp_low(A) : ORIGIN = 0x40000120, LENGTH = 223 /* variables used by Philips ISP bootloader */
ram : ORIGIN = 0x40000200, LENGTH = 32513 /* free RAM area */
ram_isp_high(A) : ORIGIN = 0x40007FE0, LENGTH = 32 /* variables used by Philips ISP bootloader */
ram_usb_dma : ORIGIN = 0x7FD00000, LENGTH = 8192 /* on-chip USB DMA RAM area (not used) */
}
/* define a global symbol _stack_end */
_stack_end = 0x40007EDC;
/* now define the output sections */
SECTIONS
{
. = 0; /* set location counter to address zero */
.text : /* collect all sections that should go into FLASH after startup */
{
*(.vectors) /* Exception Vectors and branch table >= 64 bytes */
. = ALIGN(64);
*(.init)
*(.text) /* all .text sections (code) */
*(.rodata) /* all .rodata sections (constants, strings, etc.) */
*(.rodata*) /* all .rodata* sections (constants, strings, etc.) */
*(.glue_7) /* all .glue_7 sections (no idea what these are) */
*(.glue_7t) /* all .glue_7t sections (no idea what these are) */
_etext = .; /* define a global symbol _etext just after the last code byte */
} >flash /* put all the above into FLASH */
.data : /* collect all initialized .data sections that go into RAM */
{
_data = .; /* create a global symbol marking the start of the .data section */
*(.data) /* all .data sections */
_edata = .; /* define a global symbol marking the end of the .data section */
} >ram AT >flash /* put all the above into RAM (but load the LMA copy into FLASH) */
.bss : /* collect all uninitialized .bss sections that go into RAM */
{
_bss_start = .; /* define a global symbol marking the start of the .bss section */
*(.bss) /* all .bss sections */
} >ram /* put all the above in RAM (it will be cleared in the startup code */
. = ALIGN(4); /* advance location counter to the next 32-bit boundary */
_bss_end = . ; /* define a global symbol marking the end of the .bss section */
}
_end = .; /* define a global symbol marking the end of application RAM */
PROVIDE(end = .);

View File

@ -1,112 +0,0 @@
/* ***************************************************************************************************************
crt.s STARTUP ASSEMBLY CODE
-----------------------
Module includes the interrupt vectors and start-up code.
*************************************************************************************************************** */
/* Stack Sizes */
.set UND_STACK_SIZE, 0x00000040 /* stack for "undefined instruction" interrupts */
.set ABT_STACK_SIZE, 0x00000040 /* stack for "abort" interrupts */
.set FIQ_STACK_SIZE, 0x00000040 /* stack for "FIQ" interrupts */
.set IRQ_STACK_SIZE, 0X00000100 /* stack for "IRQ" normal interrupts */
.set SVC_STACK_SIZE, 0x00000400 /* stack for "SVC" supervisor mode */
/* Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs (program status registers) */
.set MODE_USR, 0x10 /* Normal User Mode */
.set MODE_FIQ, 0x11 /* FIQ Processing Fast Interrupts Mode */
.set MODE_IRQ, 0x12 /* IRQ Processing Standard Interrupts Mode */
.set MODE_SVC, 0x13 /* Supervisor Processing Software Interrupts Mode */
.set MODE_ABT, 0x17 /* Abort Processing memory Faults Mode */
.set MODE_UND, 0x1B /* Undefined Processing Undefined Instructions Mode */
.set MODE_SYS, 0x1F /* System Running Priviledged Operating System Tasks Mode */
.set I_BIT, 0x80 /* when I bit is set, IRQ is disabled (program status registers) */
.set F_BIT, 0x40 /* when F bit is set, FIQ is disabled (program status registers) */
.text
.arm
.global Reset_Handler
.global _startup
.func _startup
_startup:
# Exception Vectors
_vectors: ldr PC, Reset_Addr
ldr PC, Undef_Addr
ldr PC, SWI_Addr
ldr PC, PAbt_Addr
ldr PC, DAbt_Addr
nop /* Reserved Vector (holds Philips ISP checksum) */
ldr PC, IRQ_Addr /* see page 71 of "Insiders Guide to the Philips ARM7-Based Microcontrollers" by Trevor Martin */
ldr PC, FIQ_Addr
Reset_Addr: .word Reset_Handler /* defined in this module below */
Undef_Addr: .word UNDEF_Routine /* defined in main.c */
SWI_Addr: .word ctx_switch /* defined in main.c */
PAbt_Addr: .word UNDEF_Routine /* defined in main.c */
DAbt_Addr: .word UNDEF_Routine /* defined in main.c */
IRQ_Addr: .word arm_irq_handler /* defined in main.c */
FIQ_Addr: .word FIQ_Routine /* defined in main.c */
.word 0 /* rounds the vectors and ISR addresses to 64 bytes total */
# Reset Handler
Reset_Handler:
/* Setup a stack for each mode - note that this only sets up a usable stack
for User mode. Also each mode is setup with interrupts initially disabled. */
ldr r0, =_stack_end
msr CPSR_c, #MODE_UND|I_BIT|F_BIT /* Undefined Instruction Mode */
mov sp, r0
sub r0, r0, #UND_STACK_SIZE
msr CPSR_c, #MODE_ABT|I_BIT|F_BIT /* Abort Mode */
mov sp, r0
sub r0, r0, #ABT_STACK_SIZE
msr CPSR_c, #MODE_FIQ|I_BIT|F_BIT /* FIQ Mode */
mov sp, r0
sub r0, r0, #FIQ_STACK_SIZE
msr CPSR_c, #MODE_IRQ|I_BIT|F_BIT /* IRQ Mode */
mov sp, r0
sub r0, r0, #IRQ_STACK_SIZE
msr CPSR_c, #MODE_SVC|I_BIT|F_BIT /* Supervisor Mode */
mov sp, r0
sub r0, r0, #SVC_STACK_SIZE
msr CPSR_c, #MODE_SYS|I_BIT|F_BIT /* User Mode */
mov sp, r0
/* copy .data section (Copy from ROM to RAM) */
ldr R1, =_etext
ldr R2, =_data
ldr R3, =_edata
1: cmp R2, R3
ldrlo R0, [R1], #4
strlo R0, [R2], #4
blo 1b
/* Clear .bss section (Zero init) */
mov R0, #0
ldr R1, =_bss_start
ldr R2, =_bss_end
2: cmp R1, R2
strlo R0, [R1], #4
blo 2b
/* Enter the C code */
bl bootloader
b kernel_init
.endfunc
.end

View File

@ -54,14 +54,8 @@ caddr_t _sbrk_r(struct _reent *r, size_t incr)
for (volatile uint8_t iUsedHeap = 0; iUsedHeap < NUM_HEAPS; iUsedHeap++ ) {
caddr_t new_heap = heap[iUsedHeap] + incr;
#ifdef MODULE_TRACELOG
trace_pointer(TRACELOG_EV_MEMORY, heap[iUsedHeap]);
#endif
if( new_heap <= heap_max[iUsedHeap] ) {
caddr_t prev_heap = heap[iUsedHeap];
#ifdef MODULE_TRACELOG
trace_pointer(TRACELOG_EV_MEMORY, new_heap);
#endif
heap[iUsedHeap] = new_heap;
r->_errno = 0;
@ -70,9 +64,6 @@ caddr_t _sbrk_r(struct _reent *r, size_t incr)
}
}
restoreIRQ(cpsr);
#ifdef MODULE_TRACELOG
trace_string(TRACELOG_EV_MEMORY, "heap!"); // heap full
#endif
r->_errno = ENOMEM;
return NULL;

View File

@ -32,14 +32,8 @@ caddr_t _sbrk_r(struct _reent *r, size_t incr)
/* check all heaps for a chunk of the requested size */
caddr_t new_heap = heap + incr;
#ifdef MODULE_TRACELOG
trace_pointer(TRACELOG_EV_MEMORY, heap);
#endif
if( new_heap <= heap_max ) {
caddr_t prev_heap = heap;
#ifdef MODULE_TRACELOG
trace_pointer(TRACELOG_EV_MEMORY, new_heap);
#endif
heap = new_heap;
r->_errno = 0;
@ -47,9 +41,6 @@ caddr_t _sbrk_r(struct _reent *r, size_t incr)
return prev_heap;
}
restoreIRQ(cpsr);
#ifdef MODULE_TRACELOG
trace_string(TRACELOG_EV_MEMORY, "heap!"); // heap full
#endif
r->_errno = ENOMEM;
return NULL;

View File

@ -10,9 +10,6 @@ endif
ifneq (,$(findstring lib,$(USEMODULE)))
DIRS += lib
endif
ifneq (,$(findstring logd,$(USEMODULE)))
DIRS += logd
endif
ifneq (,$(findstring cmdd,$(USEMODULE)))
DIRS += cmdd
endif
@ -28,9 +25,6 @@ endif
ifneq (,$(findstring sync_read,$(USEMODULE)))
DIRS += sync_read
endif
ifneq (,$(findstring syslog,$(USEMODULE)))
DIRS += syslog
endif
ifneq (,$(findstring sysmon,$(USEMODULE)))
DIRS += sysmon
endif
@ -49,9 +43,6 @@ endif
ifneq (,$(findstring timex,$(USEMODULE)))
DIRS += timex
endif
ifneq (,$(findstring tracelog,$(USEMODULE)))
DIRS += tracelog
endif
ifneq (,$(findstring transceiver,$(USEMODULE)))
DIRS += transceiver
endif

View File

@ -1,6 +0,0 @@
INCLUDES = -I../include -I../drivers/include -I../lib -I$(RIOTCPU)/$(CPU)/include -I../net -I../../core/include
MODULE =logd
include $(MAKEBASE)/Makefile.base

View File

@ -1,207 +0,0 @@
/**
* Logging daemon
*
* Copyright (C) 2009-2013 Freie Universitaet Berlin
*
* 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.
*/
/**
* @file logd.c
* @brief Simple logging demon implementation
*
* @author Freie Universität Berlin, Computer Systems & Telematics
* @author Thomas Hillebrandt <hillebra@inf.fu-berlin.de>
* @version $Revision: 3854 $
*
* @note $Id: logd.c 3854 2011-12-06 15:27:01Z hwill $
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
/* core */
#include "msg.h"
#include "flags.h"
#include "mutex.h"
#include "thread.h"
#include "kernel.h"
/* system */
#include "logd.h"
#include "list.h"
typedef struct {
list_node_t listnode;
char *str;
int str_len;
} log_queue_t;
static volatile int log_pid = -1;
static int logd_stack_size = LOGD_STACK_SIZE_NORMAL;
static FILE *fh = NULL;
static int log_count = 0;
static mutex_t log_mutex;
static list_t log_msg_queue;
static volatile bool exit_flag = false;
static volatile bool echo_on = false;
/*---------------------------------------------------------------------------*/
static void close_file_handle(void)
{
if (fh != NULL) {
fclose(fh);
fh = NULL;
}
}
static void write_to_file(char *str, int str_len)
{
if (fh != NULL && str_len > 0) {
if (fwrite(str, sizeof(char), str_len, fh) != str_len) {
if (echo_on && logd_stack_size >= LOGD_STACK_SIZE_CONSOLE) {
printf("LOGD [WARN]: file write failed, closing file\n");
}
close_file_handle();
return;
}
if (fflush(fh) == EOF) {
if (echo_on && logd_stack_size >= LOGD_STACK_SIZE_CONSOLE) {
printf("LOGD [WARN]: file write failed, closing file\n");
}
close_file_handle();
return;
}
}
else {
fh = fopen("/LOGD.LOG", "w");
if (!fh) {
if (echo_on && logd_stack_size >= LOGD_STACK_SIZE_CONSOLE) {
printf("LOGD [WARN]: file reopen failed, damn!\n");
}
}
else {
write_to_file(str, str_len);
}
}
}
static void logd_process(void)
{
msg m;
log_queue_t *node;
do {
if (!exit_flag) {
msg_receive(&m);
}
mutex_lock(&log_mutex);
while ((node = (log_queue_t *) list_remove_head(&log_msg_queue)) != NULL) {
write_to_file(node->str, node->str_len);
if (echo_on && logd_stack_size >= LOGD_STACK_SIZE_CONSOLE) {
printf("%s", node->str);
}
log_count++;
free(node->str);
free(node);
}
mutex_unlock(&log_mutex);
}
while (m.type != MSG_EXIT && !exit_flag);
/* Logging thread is terminating, close log file */
close_file_handle();
}
/*---------------------------------------------------------------------------*/
static void logd_init0(void)
{
fh = fopen("/LOGD.LOG", "w");
if (!fh) {
return;
}
log_pid = thread_create(logd_stack_size, PRIORITY_LOGD, CREATE_STACKTEST, logd_process, "logd");
}
void logd_init(int stack_size)
{
logd_stack_size = stack_size;
mutex_init(&log_mutex);
list_init(&log_msg_queue);
logd_init0();
}
void logd_set_console_enabled(bool enabled)
{
echo_on = enabled;
}
bool logd_log(char *str, int str_len)
{
msg m;
/* Test if logd process was created */
if (log_pid == -1) {
/* no logd created, because fopen() on log file failed. So try again */
logd_init0();
if (log_pid == -1) {
/* Still errors opening log file, exit now */
return false;
}
}
log_queue_t *lq = malloc(sizeof(*lq));
if (lq == NULL) {
return false;
}
lq->str = malloc(sizeof(char) * str_len + 1); /* 1 byte for string termination char */
if (lq->str == NULL) {
free(lq);
return false;
}
strncpy(lq->str, str, str_len);
lq->str_len = str_len;
lq->str[str_len] = '\0'; /* add string termination char at end of buffer */
mutex_lock(&log_mutex);
list_append(&log_msg_queue, (list_node_t *) lq);
mutex_unlock(&log_mutex);
m.type = MSG_POLL;
m.content.ptr = NULL;
msg_send(&m, log_pid, false);
return true;
}
void logd_exit(void)
{
msg m;
/* Test if logd process was created */
if (log_pid == -1) {
return;
}
exit_flag = true;
m.type = MSG_EXIT;
m.content.ptr = NULL;
msg_send(&m, log_pid, false);
}

View File

@ -1,6 +0,0 @@
INCLUDES = -I.. -I../../include -I../../drivers/include -I../../../core/include -I../../lib -I../../lib/cmdengine -I../../../hal/include
MODULE =net_mm
include $(MAKEBASE)/Makefile.base

View File

@ -1,967 +0,0 @@
/******************************************************************************
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
*******************************************************************************/
/**
* @file
* @internal
* @brief Micro Mesh Routing
*
* @author Freie Universität Berlin, Computer Systems & Telematics
* @author Thomas Hillebrandt <hillebra@inf.fu-berlin.de>
* @version $Revision: 3854 $
*
* @note $Id: mmr.c 3854 2011-12-06 15:27:01Z hwill $
*/
#include "configure.h"
#include "mmr.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "net.h"
#include "clock.h"
#include "utimer.h"
#include "kernel.h"
#include "thread.h"
#include "msg.h"
#define LEVEL_INFO 2 ///< All messages are printed
#define LEVEL_WARN 1 ///< Only warnings and error messages are printed
#define LEVEL_ERROR 0 ///< Only error messages are printed
#define MMR_INFO_LEVEL LEVEL_WARN ///< Current information level
#define DEBUG(...)
//#define DEBUG(...) printf(__VA_ARGS__)
#define CONSTANT_SECOND (1)
#define RREQ_ID_SEQUENCE_NUMBER_START (1)
#define RREQ_THRESHOLD (3)
#define RREQ_NONE (0xFF) /* Send no RREQs for these messages, value */
/* must be greater than RREQ_THRESHOLD */
#define TTL_START (1)
#define TTL_THRESHOLD (10)
#define RREQ_TIMEOUT_BASE (2*CONSTANT_SECOND)
#define RREQ_TIMEOUT_PER_TTL (1*CONSTANT_SECOND)
/*---------------------------------------------------------------------------*/
// Message queue data structures
/*---------------------------------------------------------------------------*/
#define MESSAGE_QUEUE_SIZE (20)
typedef struct {
net_message_t message;
volatile uint32_t timestamp;
uint8_t retry_count;
} message_queue_entry_t;
static message_queue_entry_t message_queue[MESSAGE_QUEUE_SIZE];
/*---------------------------------------------------------------------------*/
// RREQ-Timeout data structures
/*---------------------------------------------------------------------------*/
static struct utimer ut;
static volatile bool rreq_to_active = false; /* RREQ timeout active bit */
static const char *rreq_timeout_process_name = "mmrd";
static uint16_t rreq_timeout_process_pid;
static void rreq_timeout_process(void);
static void post_next_rreq_timeout(void);
/*---------------------------------------------------------------------------*/
// Statistic data structures
/*---------------------------------------------------------------------------*/
typedef struct mmr_stat {
uint32_t rreq_originated;
uint32_t rrep_originated;
uint32_t rerr_originated;
uint32_t rreq_received;
uint32_t rrep_received;
uint32_t rerr_received;
uint32_t messages_no_route_found; /* RREQ found no route */
uint32_t messages_no_route_avail_on_forward; /* Forwarding: no route in route table */
uint32_t messages_broken_link_on_forward; /* Forwarding: broken link detected */
uint32_t rreq_duplicated;
} mmr_stat_t;
static mmr_stat_t mmr_stats;
/*---------------------------------------------------------------------------*/
/**
* Returns time of RTC in seconds.
*
* @return Time of RTC in seconds
*/
static uint32_t rtc_now(void)
{
return (uint32_t)(clock_get_systemtime() / 1000);
}
/*---------------------------------------------------------------------------*/
// Routing table management
/*---------------------------------------------------------------------------*/
/**
* @brief Extract route information and store them in route table.
*
* @param local_addr Local network address of this node
* @param length Length of address list
* @param list Address list with route information
*/
static void rt_extract_routes(uint16_t local_addr, uint8_t length, uint16_t *list)
{
DEBUG("call [%u]: rt_extract_routes\n", fk_thread->pid);
uint16_t net_id = NETWORK_ADDR_BC(list[0]); /* BC address of source of RREQ */
route_table_entry_t *rte = rt_lookup_route(net_id); /* Should exist (preconfigured) */
if (rte == NULL) {
DEBUG("exit [%u]: rt_extract_routes\n", fk_thread->pid);
return; /* else exit here */
}
int i = 0;
while (i < length && list[i] != local_addr) {
i++;
}
if (i == length) {
DEBUG("exit [%u]: rt_extract_routes\n", fk_thread->pid);
return;
}
int pos = i;
int leftNeighbour = -1;
int rightNeighbour = -1;
if (pos > 0) {
leftNeighbour = list[pos - 1];
}
if (pos + 1 != length) {
rightNeighbour = list[pos + 1];
}
i = 0;
while (i < length) {
uint16_t next = list[i];
if (local_addr != next) {
int distance = pos - i;
int router = leftNeighbour;
if (distance < 0) {
router = rightNeighbour;
distance *= -1;
}
rt_add_route(next, (uint16_t)router, (uint8_t)distance, rte->interface_id);
}
i++;
}
DEBUG("exit [%u]: rt_extract_routes\n", fk_thread->pid);
}
/*---------------------------------------------------------------------------*/
// Message queue management
/*---------------------------------------------------------------------------*/
/**
* @brief Add a message to the message queue.
*
* @param msg The packet to add to the queue
*
* @return A pointer to a message queue entry or NULL if
* message queue is full.
*/
static message_queue_entry_t *mq_add(net_message_t *msg)
{
DEBUG("call [%u]: mq_add\n", fk_thread->pid);
/* Holds eventually first active RREQ to same destination */
message_queue_entry_t *pFirstFoundDup = NULL;
/* Find the first active RREQ to this destination */
int i;
for (i = 0; i < MESSAGE_QUEUE_SIZE; i++) {
if (message_queue[i].timestamp != 0 &&
message_queue[i].message.destination == msg->destination &&
message_queue[i].retry_count != RREQ_NONE) {
DEBUG("%s FOUND Duplicated Request to %u.%u in route req queue\n",
__FUNCTION__, (0xFF00 & msg->destination) >> 8, (0xFF & msg->destination));
/* Save the first found entry to modify later if insertion was successful */
pFirstFoundDup = &message_queue[i];
break;
}
}
/* If RREQ for same destination found then reset values
* even if the new message will get dropped later on because of
* limited queue space. Route to this destination gets queried
* again for sure so make new RREQ as soon as possible... */
if (pFirstFoundDup != NULL) {
pFirstFoundDup->retry_count = 0;
pFirstFoundDup->timestamp = 1;
mmr_stats.rreq_duplicated++;
}
/* Find free position to insert new message */
for (i = 0; i < MESSAGE_QUEUE_SIZE; i++) {
if (message_queue[i].timestamp == 0) {
/* Free position found, add entry */
message_queue[i].message = *msg;
if (pFirstFoundDup != NULL) {
/* There is already a RREQ for this destination, so don't
* generate a new one */
message_queue[i].retry_count = RREQ_NONE;
}
else {
/* Set initial RREQ retry counter to zero */
message_queue[i].retry_count = 0;
}
message_queue[i].timestamp = 1;
DEBUG("exit [%u]: mq_add\n", fk_thread->pid);
return &message_queue[i];
}
}
DEBUG("exit [%u]: mq_add\n", fk_thread->pid);
return NULL;
}
/**
* @brief Count messages for given destination.
*
* @param dst Destination address
*
* @return The number of messages for the destination.
*/
static int mq_msgs_for_destination(uint16_t dst)
{
DEBUG("call [%u]: mq_msgs_for_destination\n", fk_thread->pid);
int i, dst_count = 0;
for (i = 0; i < MESSAGE_QUEUE_SIZE; i++) {
if (message_queue[i].timestamp != 0 &&
message_queue[i].message.destination == dst) {
dst_count++;
}
}
DEBUG("exit [%u]: mq_msgs_for_destination\n", fk_thread->pid);
return dst_count;
}
/**
* @brief Remove all messages for given destination out of message queue.
*
* @param dst Destination address
*/
static void mq_remove_msgs_for_destination(uint16_t dst)
{
DEBUG("call [%u]: mq_remove_msgs_for_destination\n", fk_thread->pid);
int i;
for (i = 0; i < MESSAGE_QUEUE_SIZE; i++) {
if (message_queue[i].timestamp != 0 &&
message_queue[i].message.destination == dst) {
message_queue[i].timestamp = 0;
}
}
DEBUG("exit [%u]: mq_remove_msgs_for_destination\n", fk_thread->pid);
}
/**
* @brief Send all queued messages for given destination.
*
* @param dst Destination address
*/
static void mq_dequeue_and_send(uint16_t dst)
{
int i;
DEBUG("call [%u]: mq_dequeue_and_send\n", fk_thread->pid);
/* Stop any pending RREQ-Timeout, it's possibly handled now */
rreq_to_active = false;
utimer_remove(&ut);
/* Prioritize packets for given destination, route entry should exist */
route_table_entry_t *rte = rt_lookup_route(dst);
if (rte != NULL) {
for (i = 0; i < MESSAGE_QUEUE_SIZE; i++) {
if (message_queue[i].timestamp != 0 &&
message_queue[i].message.destination == dst) {
bool res = net_enqueue_for_transmission(&message_queue[i].message,
rte->interface_id,
rte->gateway, true);
if (res) {
message_queue[i].timestamp = 0;
}
}
}
}
/* Now all other packets */
for (i = 0; i < MESSAGE_QUEUE_SIZE; i++) {
if (message_queue[i].timestamp != 0 &&
message_queue[i].message.destination != dst) {
route_table_entry_t *rte = rt_lookup_route(message_queue[i].message.destination);
if (rte != NULL) {
bool res = net_enqueue_for_transmission(&message_queue[i].message,
rte->interface_id,
rte->gateway, true);
if (res) {
message_queue[i].timestamp = 0;
}
}
}
}
/* This function was triggered either by RREP packet or RREQ-Timeout. */
/* So update or set new RREQ-Timeout for other packets in queue. */
post_next_rreq_timeout();
DEBUG("exit [%u]: mq_dequeue_and_send\n", fk_thread->pid);
}
/*---------------------------------------------------------------------------*/
// Initialization of MMR layer
/*---------------------------------------------------------------------------*/
void mmr_init(void)
{
rt_init();
memset(message_queue, 0, sizeof(message_queue_entry_t) * MESSAGE_QUEUE_SIZE);
rreq_timeout_process_pid = thread_create(2500, PRIORITY_MMREQ, CREATE_STACKTEST,
rreq_timeout_process, rreq_timeout_process_name);
}
/*---------------------------------------------------------------------------*/
// Send & receive functions
/*---------------------------------------------------------------------------*/
/**
* @brief Tests if the net message contains a RERR.
*
* @param msg The net message to test
*
* @return true if the net message contains a RERR; false otherwise.
*/
static bool is_route_error(net_message_t *msg)
{
if (msg->protocol == LAYER_2_PROTOCOL_MMR) {
/* First byte in {RREQ, RREP, RERR} is always type */
if (msg->payload[0] == MMR_TYPE_RERR) {
return true;
}
}
return false;
}
/**
* @brief Generates a route reply message.
*
* @param rreq_msg Corresponding route request message
*/
static void generate_route_reply_message(mmr_rreq_message_t *rreq_msg)
{
DEBUG("call [%u]: generate_route_reply_message\n", fk_thread->pid);
/* Create RREP message */
mmr_rrep_message_t rrep_msg;
rrep_msg.type = MMR_TYPE_RREP;
rrep_msg.length = rreq_msg->length;
rrep_msg.destination = rreq_msg->source;
rrep_msg.source = rreq_msg->destination;
memcpy(rrep_msg.address, rreq_msg->address, rreq_msg->length * sizeof(uint16_t));
/* Create MMR message containing the RREP message */
net_message_t net_msg;
net_msg.protocol = LAYER_2_PROTOCOL_MMR;
net_msg.flags_tos = PRIORITY_ALARM;
net_msg.seq_clr_id = 0;
net_msg.ttl = TTL_THRESHOLD;
net_msg.source = rrep_msg.source;
net_msg.destination = rrep_msg.destination;
memcpy(net_msg.payload, (void *)&rrep_msg, sizeof(mmr_rrep_message_t));
/* Source address must exist in route table to find correct */
/* interface id and next hop (should be created by RREQ) */
route_table_entry_t *rte = rt_lookup_route(net_msg.destination);
if (rte != NULL) {
/* Send message to next hop */
mmr_stats.rrep_originated++;
net_enqueue_for_transmission(&net_msg, rte->interface_id, rte->gateway, true);
}
DEBUG("exit [%u]: generate_route_reply_message\n", fk_thread->pid);
}
/**
* @brief Generates a route error message.
*
* @param dst Destination address of RERR packet
* @param gateway Next hop network address of RERR packet
* @param intf Interface id of RERR packet
* @param type Error type of RERR packet
* @param type_data Type specific data of RERR packet
*/
static void generate_route_error_message(uint16_t dst, uint16_t gateway, int intf, uint8_t type, uint16_t type_data)
{
DEBUG("call [%u]: generate_route_error_message\n", fk_thread->pid);
/* Define RERR message */
mmr_rerr_message_t rerr_msg;
rerr_msg.type = MMR_TYPE_RERR;
rerr_msg.error_type = type;
rerr_msg.type_specific_info = type_data;
/* Wrap RERR message in net message */
net_message_t net_msg;
net_msg.protocol = LAYER_2_PROTOCOL_MMR;
net_msg.flags_tos = PRIORITY_DATA;
net_msg.seq_clr_id = 0;
net_msg.ttl = TTL_THRESHOLD;
net_msg.source = net_get_address_in_subnet(dst);
net_msg.destination = dst;
memcpy(net_msg.payload, (void *)&rerr_msg, sizeof(mmr_rerr_message_t));
/* Send message to next hop */
mmr_stats.rerr_originated++;
net_enqueue_for_transmission(&net_msg, intf, gateway, true);
DEBUG("exit [%u]: generate_route_error_message\n", fk_thread->pid);
}
/**
* @brief Receive a route request message.
*
* @param msg The route request packet
* @param packet_info Additional packet information
*/
static void receive_route_request_message(mmr_rreq_message_t *msg,
packet_info_t *packet_info)
{
DEBUG("call [%u]: receive_route_request_message\n", fk_thread->pid);
uint16_t my_addr = net_get_address_in_subnet(msg->source);
#if (MMR_INFO_LEVEL >= LEVEL_WARN)
if (my_addr == 0) {
puts("MMR [WARN]: received RREQ with unknown network part of source address");
puts("MMR [WARN]: => can't find own net address in sub net!");
}
#endif
/* If address list of RREQ message has enough space */
if (msg->length < ADDRESS_LIST_SIZE) {
/* append our node id to list */
msg->address[msg->length++] = my_addr;
/* add routes with overhearing */
rt_extract_routes(my_addr, msg->length, msg->address);
}
/* Distance between sender and receiver is too long, discard packet */
else {
/* Drop RREQ packet => set TTL to zero */
*packet_info->ttl_ptr = 0;
DEBUG("exit [%u]: receive_route_request_message\n", fk_thread->pid);
return;
}
/* If RREQ message was send to us, then send RREP message */
if (msg->destination == my_addr) {
/* Don't forward RREQ packet any further => set TTL to zero */
*packet_info->ttl_ptr = 0;
generate_route_reply_message(msg);
}
DEBUG("exit [%u]: receive_route_request_message\n", fk_thread->pid);
}
/**
* @brief Receive a route reply message.
*
* @param msg The route reply packet
* @param packet_info Additional packet information
*/
static void receive_route_reply_message(mmr_rrep_message_t *msg,
packet_info_t *packet_info)
{
DEBUG("call [%u]: receive_route_reply_message\n", fk_thread->pid);
/* RREP received: Send out queued packets for which routes are now known */
mq_dequeue_and_send(msg->source);
DEBUG("exit [%u]: receive_route_reply_message\n", fk_thread->pid);
}
/**
* @brief Receive a route error message.
*
* @param msg The route error packet
* @param packet_info Additional packet information
*/
static void receive_route_error_message(mmr_rerr_message_t *msg,
packet_info_t *packet_info)
{
DEBUG("call [%u]: receive_route_error_message\n", fk_thread->pid);
switch(msg->error_type) {
case RERR_NODE_UNREACHABLE:
rt_remove_route(msg->type_specific_info);
break;
default:
#if (MMR_INFO_LEVEL >= LEVEL_INFO)
puts("MMR [INFO]: RERR error type is unknown");
#endif
break;
}
DEBUG("exit [%u]: receive_route_error_message\n", fk_thread->pid);
}
/**
* @brief Computes the RREQ timeout period, given a
* TTL and destination address value.
*
* @param ttl Time to live
* @param dst Network destination address
*
* @return RREQ timeout period in seconds
*/
static int compute_rreq_timeout(int ttl, uint16_t dst)
{
int t_hop = net_get_interface_transmission_duration(dst);
if (t_hop == -1) {
t_hop = RREQ_TIMEOUT_PER_TTL * ttl;
}
else {
t_hop = (t_hop * ttl + 999) / 1000;
}
return RREQ_TIMEOUT_BASE + 2 * t_hop;
}
/**
* @brief Broadcast a RREQ message.
*
* A single route request can repeatedly broadcast RREQ messages,
* with increasing TTL value, until a route has been found.
*
* @param mq_entry Pointer to a message queue entry (the packet
* for which to find the route)
*/
static void rreq_broadcast(message_queue_entry_t *mq_entry)
{
DEBUG("call [%u]: rreq_broadcast\n", fk_thread->pid);
if (mq_entry->retry_count == RREQ_NONE) {
DEBUG("call [%u]: rreq duplicated do not send\n", fk_thread->pid);
return;
}
/* Create RREQ message */
mmr_rreq_message_t rreq_msg;
rreq_msg.type = MMR_TYPE_RREQ;
rreq_msg.length = 1;
rreq_msg.destination = mq_entry->message.destination;
rreq_msg.source = mq_entry->message.source;
rreq_msg.address[0] = mq_entry->message.source;
/* Wrap RREQ message in net message */
net_message_t net_msg;
net_msg.protocol = LAYER_2_PROTOCOL_MMR;
net_msg.flags_tos = PRIORITY_DATA;
net_msg.seq_clr_id = 0;
net_msg.ttl = mq_entry->retry_count == 0 ? TTL_START : TTL_THRESHOLD;
net_msg.source = rreq_msg.source;
net_msg.destination = NETWORK_ADDR_BC(rreq_msg.destination);
memcpy(net_msg.payload, (void *)&rreq_msg, sizeof(mmr_rreq_message_t));
/* Broadcast the net message */
mq_entry->retry_count++;
mq_entry->timestamp = rtc_now();
/* Find the broadcast route table entry */
route_table_entry_t *rte = rt_lookup_route(net_msg.destination);
if (rte != NULL) {
/* Next hop address is broadcast address of lower layer */
net_enqueue_for_transmission(&net_msg, rte->interface_id,
rte->gateway, true);
}
DEBUG("exit [%u]: rreq_broadcast\n", fk_thread->pid);
}
/**
* @brief Find next RREQ to time out. Post event immediately or
* with utimer.
*/
static void post_next_rreq_timeout(void)
{
DEBUG("call [%u]: post_next_rreq_timeout\n", fk_thread->pid);
int i, j = -1;
uint32_t now, next = 0xffffffff;
for (i = 0; i < MESSAGE_QUEUE_SIZE; i++) {
if ((message_queue[i].timestamp != 0) && (message_queue[i].retry_count !=
RREQ_NONE)) {
int ttl = message_queue[i].retry_count == 1 ? TTL_START : TTL_THRESHOLD;
int to = compute_rreq_timeout(ttl,
message_queue[i].message.destination);
if (message_queue[i].timestamp + to < next) {
next = message_queue[i].timestamp + to;
j = i;
}
}
}
if (j == -1) {
DEBUG("exit [%u]: post_next_rreq_timeout\n", fk_thread->pid);
return;
}
/* Stop any utimer */
rreq_to_active = false;
utimer_remove(&ut);
/* If current time greater than RREQ timeout value */
now = rtc_now();
if (now >= next) {
/* Schedule RREQ-Timeout immediately */
msg m;
m.type = MSG_TIMER;
m.content.ptr = (char *)&message_queue[j];
rreq_to_active = true;
if (msg_send(&m, rreq_timeout_process_pid, false) != 1) {
/* Message could not be send (receiver not waiting), schedule
* timer with minimum delay */
#if (MMR_INFO_LEVEL >= LEVEL_WARN)
puts("MMR [WARN]: Immediate schedule of RREQ-Timeout failed, process not waiting!");
#endif
utimer_set_wpid(&ut, 1, rreq_timeout_process_pid, &message_queue[j]);
}
}
else {
/* Set new utimer with time difference */
rreq_to_active = true;
utimer_set_wpid(&ut, next - now, rreq_timeout_process_pid,
&message_queue[j]);
}
DEBUG("exit [%u]: post_next_rreq_timeout\n", fk_thread->pid);
}
/**
* This event is called periodically after a route request is originated,
* until a route has been found.
*
* Each time it is called, it rebroadcasts the route request message with a
* new rreq id and incremented TTL.
*/
static void rreq_timeout(message_queue_entry_t *mqe)
{
DEBUG("call [%u]: rreq_timeout\n", fk_thread->pid);
/* Test if valid entry passed */
if (mqe->timestamp == 0) {
#if (MMR_INFO_LEVEL >= LEVEL_WARN)
puts("MMR [WARN]: invalid message queue entry for RREQ-Timeout");
#endif
goto post_next_to;
}
/* See if route to destination was found */
route_table_entry_t *rte = rt_lookup_route(mqe->message.destination);
/* If found and no messages in queue for destination: return (queued
* packets are send on reception of RREP); If found but messages in queue:
* trigger send immediately here!*/
if (rte != NULL) {
int msg_count = mq_msgs_for_destination(mqe->message.destination);
if (msg_count > 0) {
mq_dequeue_and_send(mqe->message.destination);
DEBUG("exit [%u]: rreq_timeout\n", fk_thread->pid);
return;
}
else {
/* Added just for security but this case should never occur */
#if (MMR_INFO_LEVEL >= LEVEL_WARN)
puts("MMR [WARN]: RREQ-Timeout occurred, route is available but no messages for destination");
#endif
/* Anyway: jump to update next RREQ-Timeout */
goto post_next_to;
}
}
/* Otherwise send new RREQ if below threshold (means also retry count !=
* RREQ_NONE) */
if (mqe->retry_count < RREQ_THRESHOLD) {
/* Broadcast new RREQ message (with incremented TTL) */
rreq_broadcast(mqe);
}
else {
/* Remove all messages for this destination */
mmr_stats.messages_no_route_found++;
mq_remove_msgs_for_destination(mqe->message.destination);
}
/* Anyway: update or set next RREQ-Timeout */
post_next_to:
post_next_rreq_timeout();
DEBUG("exit [%u]: rreq_timeout\n", fk_thread->pid);
}
static void rreq_timeout_process(void)
{
msg m;
do {
msg_receive(&m);
if (m.type == MSG_TIMER && rreq_to_active) {
rreq_to_active = false;
rreq_timeout((message_queue_entry_t *)m.content.ptr);
}
}
while (m.type != MSG_EXIT);
}
void mmr_peek(net_message_t *message, packet_info_t *packet_info)
{
DEBUG("call [%u]: mmr_peek\n", fk_thread->pid);
/* Only look at micro mesh routing messages */
if (message->protocol == LAYER_2_PROTOCOL_MMR) {
uint8_t type = message->payload[0];
uint16_t my_addr = net_get_address_in_subnet(message->source);
if (type == MMR_TYPE_RREP) {
/* Add routes to route table */
mmr_rrep_message_t *rrep_msg = (mmr_rrep_message_t *)message->payload;
#if (MMR_INFO_LEVEL >= LEVEL_WARN)
if (my_addr == 0) {
puts("MMR [WARN]: received RREP with unknown network part of source address");
puts("MMR [WARN]: => can't find own net address in sub net!");
}
#endif
rt_extract_routes(my_addr, rrep_msg->length, rrep_msg->address);
}
else if (type == MMR_TYPE_RERR) {
#if (MMR_INFO_LEVEL >= LEVEL_WARN)
if (my_addr == 0) {
puts("MMR [WARN]: received RERR with unknown network part of source address");
puts("MMR [WARN]: => can't find own net address in sub net!");
}
#endif
/* If not destination of RERR, then remove route to unavailable
* node in RERR packet */
if (message->destination != my_addr) {
mmr_rerr_message_t *rerr_msg =
(mmr_rerr_message_t *)message->payload;
if (rerr_msg->error_type == RERR_NODE_UNREACHABLE) {
rt_remove_route(rerr_msg->type_specific_info);
}
}
}
}
DEBUG("exit [%u]: mmr_peek\n", fk_thread->pid);
}
bool mmr_send(net_message_t *message)
{
DEBUG("call [%u]: mmr_send\n", fk_thread->pid);
bool enqueue = true;
if (message->destination == net_get_address_in_subnet(message->destination)) {
#if (MMR_INFO_LEVEL >= LEVEL_WARN)
puts("MMR [WARN]: message is already at destination, why is routing called?");
#endif
DEBUG("exit [%u]: mmr_send\n", fk_thread->pid);
return false;
}
if (NETWORK_ADDR_NET(message->destination) == 0) {
#if (MMR_INFO_LEVEL >= LEVEL_WARN)
puts("MMR [WARN]: NET part of address cannot be 0!");
#endif
DEBUG("exit [%u]: mmr_send\n", fk_thread->pid);
return false;
}
if (NETWORK_ADDR_HOST(message->destination) == 0) {
#if (MMR_INFO_LEVEL >= LEVEL_INFO)
puts("MMR [INFO]: broadcast destination, why is routing called? A route entry should exist!");
#endif
enqueue = false;
}
/* Look up next hop address for this destination in routing table */
route_table_entry_t *rte = rt_lookup_route(message->destination);
/* If next hop address found in routing table, forward message */
if (rte != NULL) {
DEBUG("exit [%u]: mmr_send\n", fk_thread->pid);
return net_enqueue_for_transmission(message, rte->interface_id, rte->gateway, true);
}
/* Otherwise, save message in queue; broadcast RREQ message */
else {
if (!enqueue) {
/* Don't enqueue broadcast destinations */
DEBUG("exit [%u]: mmr_send\n", fk_thread->pid);
return false;
}
message_queue_entry_t *mqe = mq_add(message);
if (mqe != NULL) {
rreq_broadcast(mqe);
post_next_rreq_timeout();
mmr_stats.rreq_originated++;
DEBUG("exit [%u]: mmr_send\n", fk_thread->pid);
return true;
}
}
DEBUG("exit [%u]: mmr_send\n", fk_thread->pid);
return false;
}
void mmr_packet_dropped(net_message_t *message, uint16_t next_hop, int error)
{
DEBUG("call [%u]: mmr_packet_dropped\n", fk_thread->pid);
if (error == ROUTE_ERROR_BROKEN_ROUTE) {
/* Local failure detected - remove all routes through broken link */
rt_remove_gateway_routes(next_hop);
mmr_stats.messages_broken_link_on_forward++;
}
else if (error == ROUTE_ERROR_MISSING_ROUTE) {
mmr_stats.messages_no_route_avail_on_forward++;
}
/* If source != net_addr, send RERR to source of message */
if (message->source != net_get_address_in_subnet(message->source)) {
/* Do not generate RERR if it is already a RERR message */
if (is_route_error(message)) {
DEBUG("exit [%u]: mmr_packet_dropped\n", fk_thread->pid);
return;
}
/* Find next hop to source */
route_table_entry_t *rte = rt_lookup_route(message->source);
if (rte != NULL) {
generate_route_error_message(message->source, rte->gateway,
rte->interface_id,
RERR_NODE_UNREACHABLE,
message->destination);
}
#if (MMR_INFO_LEVEL >= LEVEL_WARN)
else {
printf("MMR [WARN]: cannot send RERR to source #%u, no route found!\n",
message->source);
}
#endif
}
DEBUG("exit [%u]: mmr_packet_dropped\n", fk_thread->pid);
}
void mmr_receive(void *msg, int msg_size, packet_info_t *packet_info)
{
DEBUG("call [%u]: mmr_receive\n", fk_thread->pid);
uint8_t *p = (uint8_t *) msg;
uint8_t type = p[0];
if (type == MMR_TYPE_RREQ) {
receive_route_request_message((mmr_rreq_message_t *)msg, packet_info);
mmr_stats.rreq_received++;
}
else if (type == MMR_TYPE_RREP) {
receive_route_reply_message((mmr_rrep_message_t *)msg, packet_info);
mmr_stats.rrep_received++;
}
else if (type == MMR_TYPE_RERR) {
receive_route_error_message((mmr_rerr_message_t *)msg, packet_info);
mmr_stats.rerr_received++;
}
#if (MMR_INFO_LEVEL >= LEVEL_INFO)
else {
printf("MMR [INFO]: can't handle message of type %u\n", type);
}
#endif
DEBUG("exit [%u]: mmr_receive\n", fk_thread->pid);
}
void mmr_print_stats(void)
{
printf("ROUTING LAYER STATS\r\n");
printf("-------------------\r\n");
printf("Route requests originated: %lu\r\n", mmr_stats.rreq_originated);
printf("Route requests duplicated: %lu\r\n", mmr_stats.rreq_duplicated);
printf("Route replies originated: %lu\r\n", mmr_stats.rrep_originated);
printf("Route errors originated: %lu\r\n", mmr_stats.rerr_originated);
printf("Route requests received: %lu\r\n", mmr_stats.rreq_received);
printf("Route replies received: %lu\r\n", mmr_stats.rrep_received);
printf("Route errors received: %lu\r\n", mmr_stats.rerr_received);
printf("\r\n");
printf("#Messages with no route found: %lu\r\n", mmr_stats.messages_no_route_found);
printf("#Messages with broken link on forward: %lu\r\n", mmr_stats.messages_broken_link_on_forward);
printf("#Messages with no route available on forward: %lu\r\n", mmr_stats.messages_no_route_avail_on_forward);
printf("\r\n");
}

View File

@ -1,171 +0,0 @@
/******************************************************************************
Copyright 2008, 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
*******************************************************************************/
#ifndef MMR_H_
#define MMR_H_
/**
* @file
* @internal
* @brief Micro Mesh Routing
*
* @author Freie Universität Berlin, Computer Systems & Telematics
* @author Thomas Hillebrandt <hillebra@inf.fu-berlin.de>
* @version $Revision: 3854 $
*
* @note $Id: mmr.h 3854 2011-12-06 15:27:01Z hwill $
*/
#include "net-types.h"
#define MMR_TYPE_RREQ (1)
#define MMR_TYPE_RREP (2)
#define MMR_TYPE_RERR (3)
#define ADDRESS_LIST_SIZE (21)
#define RERR_NODE_UNREACHABLE (1)
/**
* Represents a Route Request (RREQ) message.
*
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Type | Length | Destination |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Source | Address[1..n] |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
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;
/**
* Represents a Route Reply (RREP) message.
*
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Type | Length | Destination |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Source | Address[1..n] |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
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;
/**
* Represents a Route Error (RERR) message.
*
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Type | Error Type | Type-Specific Information |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
* Valid Error Types are:
*
* 1 = NODE_UNREACHABLE
*
* Node Unreachable Type-Specific Information:
*
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Unreachable Node Address | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
*/
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;
/**
* @brief Initialize MMR layer.
*/
void mmr_init(void);
/**
* Called by the network layer for every incoming packet. A routing
* implementation may wish to look at these packets for informational
* purposes, but should not change their contents.
*
* @param message incoming packet
* @param packet_info Additional packet information
*/
void mmr_peek(net_message_t *message, packet_info_t *packet_info);
/**
* Called by the network layer to request transmission of a packet that
* requires routing. It is the responsibility of the routing layer to provide
* a best-effort transmission of this packet to an appropriate next hop by
* calling the networks layer sending routines once this routing information
* becomes available.
*
* @param message outgoing packet
*
* @return true if packet was successfully stored for transmission; false otherwise
* (e.g. message queue full).
*/
bool mmr_send(net_message_t *message);
/**
* Called by the network layer which forwards notifications of dropped packets
* from the link layer. Not all MAC implementations support this feature!
*
* @param message dropped network packet
* @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);
/**
* @brief Receive a message from network layer.
*
* @param msg message received
* @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);
/**
* @brief Print routing layer statistics.
*/
void mmr_print_stats(void);
#endif /* MMR_H_ */

View File

@ -1,925 +0,0 @@
/******************************************************************************
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
*******************************************************************************/
#include "configure.h"
#include "mmstack.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "utimer.h"
#include "kernel.h"
#include "thread.h"
#include "msg.h"
#include "net.h"
#include "mmr.h"
#include "trans.h"
#include "clock.h"
#include "cmdengine.h"
/**
* @file
* @brief
*
* @author Freie Universität Berlin, Computer Systems & Telematics
* @author Thomas Hillebrandt <hillebra@inf.fu-berlin.de>
* @version $Revision: 3854 $
*
* @note $Id: mmstack.c 3854 2011-12-06 15:27:01Z hwill $
*/
/*---------------------------------------------------------------------------*/
// Data structures for build in ping
/*---------------------------------------------------------------------------*/
#define MMS_PING_PACKETS (4) ///< Default number of packets in a ping
#define MMS_PING_ECHO_REQUEST (8) ///< Ping type: echo request
#define MMS_PING_ECHO_REPLY (0) ///< Ping type: echo reply
/**
* Represents a ping message.
*
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Type | Identifier | SeqNum |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Timestamp |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
typedef struct __attribute__((packed)) {
uint8_t type; ///< Type of ping message (request or reply)
uint8_t identifier; ///< Unique identifier for ping process
uint16_t seq_num; ///< Sequence number (increasing number within that process)
uint32_t timestamp; ///< Timestamp of request message
} mms_ping_message_t;
/**
* @brief Send ping echo request to destination address.
*
* @param destination The destination address.
* @param seq Sequence number of ping message.
* @param prio Priority of ping message.
* @param ttl TTL value for network message.
*/
static void mms_ping(uint16_t destination, uint8_t seq, uint8_t prio, int ttl);
static uint8_t mms_ping_last_proc_id; ///< Random process id of last ping request
static uint8_t mms_ping_packets; ///< Number of ping replies received
static int mms_ping_dups; ///< Duplicates
static bool ping_bc_mode; ///< If option -b is set and address is BC
static bool ping_silent_mode; ///< If option -s is set
static bool *dups; ///< Helper buffer to check for DUPs
static float rtt_min; ///< Min. RTT
static float rtt_max; ///< Max. RTT
static float rtt_avg; ///< Avg. RTT
static struct utimer mms_ping_utimer; ///< utimer for ping
static uint16_t mms_ping_pid; ///< Process ID of process ping is running within
/*---------------------------------------------------------------------------*/
// Data structures for build in SSH
/*---------------------------------------------------------------------------*/
#define MMS_SSH_CON_REQUEST (1) ///< SSH type: connection request
#define MMS_SSH_CON_ACCEPT (2) ///< SSH type: connection accept
#define MMS_SSH_CON_REJECT (3) ///< SSH type: connection reject
#define MMS_SSH_CON_CLOSE (4) ///< SSH type: connection close
#define MMS_SSH_DATA (5) ///< SSH type: data packet
#define MMS_SSH_DATA_MAX (43) ///< Maximum SSH data packet size
/**
* Represents a SSH message.
*
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Type | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
typedef struct __attribute__((packed)) {
uint8_t type; ///< Type of SSH message
} mms_ssh_message_t;
/**
* Represents a SSH data message.
*
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Type | Data |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
typedef struct __attribute__((packed)) {
uint8_t type; ///< Type of SSH message
uint8_t data[MMS_SSH_DATA_MAX]; ///< Message information
} mms_ssh_data_message_t;
/**
* @brief Make SSH connection request with given node.
*
* @param destination The destination address.
*/
static void mms_ssh_connect(uint16_t destination);
/**
* @brief Accept or reject SSH connection request.
*
* @param destination The destination address.
* @param socket The socket to use or -1.
* @param accept Whether to accept or reject the connection request.
*/
static void mms_ssh_reply_connect(uint16_t destination, int socket, bool accept);
/**
* @brief Close SSH connection.
*
* @param destination The destination address.
*/
static void mms_ssh_close(uint16_t destination);
static volatile int ssh_socket = -1;
/*---------------------------------------------------------------------------*/
// Interface definitions
/*---------------------------------------------------------------------------*/
static route_interface_t r_iface = {
rt_add_route,
rt_add_fix_route,
rt_lookup_route,
mmr_peek,
mmr_send,
mmr_packet_dropped,
mmr_receive,
mmr_print_stats
};
/*---------------------------------------------------------------------------*/
// Build in MMS commands
/*---------------------------------------------------------------------------*/
//#if CMD_ISLEVEL(CMD_LEVEL_SYSTEM_DEBUG | CMD_LEVEL_HUMAN_USER | CMD_LEVEL_OPERATION)
ASCCMD(route, CMDFLAG_SERIAL, "[-adfFg] print kernel route table");
CMD_FUNCTION(route, cmdargs)
{
if (cmdargs->arg_size > 0) {
char *msg = (char *)cmdargs->args;
while (*msg == ' ') {
msg++;
}
if (*msg == '-' && *(msg + 1) == 'f') {
mms_flush_routes(false);
printf("Kernel route table flushed (non-static)!\n");
return CMD_SUCCESS;
}
else if (*msg == '-' && *(msg + 1) == 'F') {
mms_flush_routes(true);
printf("Kernel route table flushed (static)!\n");
return CMD_SUCCESS;
}
else if (*msg == '-' && *(msg + 1) == 'd') {
msg++;
msg++;
while (*msg == ' ') {
msg++;
}
uint16_t address = net_strtoaddr(msg, &msg);
if (rt_remove_static_route(address)) {
printf("Static route deleted successfully!\n");
return CMD_SUCCESS;
}
return CMD_ERROR;
}
else if (*msg == '-' && *(msg + 1) == 'g') {
msg++;
msg++;
while (*msg == ' ') {
msg++;
}
uint16_t address = net_strtoaddr(msg, &msg);
int c = rt_remove_static_gateway_routes(address);
printf("%u static route(s) deleted!\n", c);
return CMD_SUCCESS;
}
else if (*msg == '-' && *(msg + 1) == 'a') {
msg++;
msg++;
while (*msg == ' ') {
msg++;
}
uint16_t address = net_strtoaddr(msg, &msg);
uint16_t gateway = net_strtoaddr(msg, &msg);
int metric = (int)strtoul(msg, &msg, 0);
int iface = (int)strtoul(msg, &msg, 0);
if (address != 0 && gateway != 0) {
if (rt_add_static_route(address, gateway, metric, iface)) {
printf("Static route added successfully!\n");
return CMD_SUCCESS;
}
}
return CMD_ERROR;
}
else {
printf("Usage: route [-adfFg] print kernel route table\n\n");
printf(" -a <DST> <GW> <M> <IFACE>, add static route to kernel route table\n");
printf(" -d <DST>, delete static route out of kernel route table\n");
printf(" -f, flush non-static routes out of kernel route table\n");
printf(" -F, flush static routes out of kernel route table\n");
printf(" -g <GW>, delete static routes out of kernel route table with a\n"
" specific gateway\n\n");
printf(" <DST> = destination network address\n");
printf(" <GW> = gateway network address\n");
printf(" <M> = metric, e.g. number of hops\n");
printf(" <IFACE> = network interface number\n\n");
return CMD_ERROR;
}
}
else {
mms_print_routes();
return CMD_SUCCESS;
}
}
ASCCMD(ifconfig, CMDFLAG_SERIAL, "[IFACE]: print interface configuration");
CMD_FUNCTION(ifconfig, cmdargs)
{
if (cmdargs->arg_size > 0) {
char *msg;
int iface = (int)strtoul(cmdargs->args, &msg, 0);
if (cmdargs->arg_size > 1) {
while (*msg == ' ') {
msg++;
}
if (*msg == '-' && (*(msg + 1) == 'P' || *(msg + 1) == 'p')) {
msg++;
msg++;
uint8_t power = (uint8_t)strtoul(msg, &msg, 0);
if (*msg != '\0') {
return CMD_ERROR;
}
if (mms_set_output_power(iface, power)) {
printf("Output power set!\n");
return CMD_SUCCESS;
}
return CMD_ERROR;
}
else if (*msg == '-' && (*(msg + 1) == 'A' || *(msg + 1) == 'a')) {
msg++;
msg++;
while (*msg == ' ') {
msg++;
}
uint16_t address = net_strtoaddr(msg, &msg);
if (mms_set_interface_address(iface, address)) {
printf("Interface address set!\n");
return CMD_SUCCESS;
}
return CMD_ERROR;
}
else {
printf("Usage: ifconfig [IFACE] [-AP] print interface configuration\n\n");
printf(" -A <ADDR>, set interface address, e.g. ifconfig 0 -A 1.1\n");
printf(" -P <POWER>, set output power on interface\n\n");
return CMD_ERROR;
}
}
else {
mms_print_ifconfig(iface);
}
}
else {
mms_print_ifconfig(-1);
}
return CMD_SUCCESS;
}
ASCCMD(ping, CMDFLAG_SERIAL, "ping [-bchpstw] destination");
CMD_FUNCTION(ping, cmdargs)
{
if (cmdargs->arg_size > 0) {
int i;
msg m;
uint8_t count = MMS_PING_PACKETS;
uint8_t prio = PRIORITY_DATA;
bool bc = false;
ping_bc_mode = false;
ping_silent_mode = false;
int ttl = 10;
long timeout = 3;
char adrbuf[10];
const char *msg = cmdargs->args;
read_ping_cmd:
while (*msg == ' ') {
msg++;
}
if (*msg == '-' && (*(msg + 1) == 'B' || *(msg + 1) == 'b')) {
bc = true;
msg++;
msg++;
goto read_ping_cmd;
}
else if (*msg == '-' && (*(msg + 1) == 'C' || *(msg + 1) == 'c')) {
msg++;
msg++;
unsigned long tc = strtoul(msg, (char **)&msg, 0);
if (tc == 0) {
return CMD_ERROR;
}
if (tc > 255) {
puts("Not more than 255 ping messages allowed!");
return CMD_ERROR;
}
count = (uint8_t) tc;
goto read_ping_cmd;
}
else if (*msg == '-' && (*(msg + 1) == 'H' || *(msg + 1) == 'h')) {
printf("Usage: ping [-bchpstw] destination\n\n");
printf(" -b, do a broadcast ping\n");
printf(" -c <COUNT>, set number of ping messages\n");
printf(" -h, print a help synopsis\n");
printf(" -p <PRIO>, set the ping message priority\n");
printf(" PRIO = 1: alarm\n");
printf(" PRIO = 2: warning\n");
printf(" PRIO = 3: data (default)\n");
printf(" -s, silent mode (no messages printed out)\n");
printf(" -t <TTL>, TTL value of ping messages (default: 10)\n");
printf(" -w <WAIT>, time to wait for a response, in seconds (default: 3)\n\n");
return CMD_SUCCESS;
}
else if (*msg == '-' && (*(msg + 1) == 'p' || *(msg + 1) == 'P')) {
msg++;
msg++;
unsigned long tp = strtoul(msg, (char **)&msg, 0);
if (tp == 0) {
return CMD_ERROR;
}
if (tp == 1) {
prio = 0;
}
else if (tp == 2) {
prio = 1;
}
else {
prio = 2;
}
goto read_ping_cmd;
}
else if (*msg == '-' && (*(msg + 1) == 's' || *(msg + 1) == 'S')) {
ping_silent_mode = true;
msg++;
msg++;
goto read_ping_cmd;
}
else if (*msg == '-' && (*(msg + 1) == 't' || *(msg + 1) == 'T')) {
msg++;
msg++;
unsigned long to = strtoul(msg, (char **)&msg, 0);
if (to == 0 || to > 255) {
return CMD_ERROR;
}
ttl = to;
goto read_ping_cmd;
}
else if (*msg == '-' && (*(msg + 1) == 'w' || *(msg + 1) == 'W')) {
msg++;
msg++;
unsigned long to = strtoul(msg, (char **)&msg, 0);
if (to == 0) {
return CMD_ERROR;
}
timeout = to;
goto read_ping_cmd;
}
uint16_t address = net_strtoaddr((char *)msg, (char **)&msg);
if (address == 0) {
return CMD_ERROR;
}
int iface_addr = net_get_address_in_subnet(address);
/* No ping to unsupported network or own address */
if (iface_addr == 0 || iface_addr == address) {
return CMD_ERROR;
}
/* If broadcast destination address, limit TTL to one hop */
if (address == NETWORK_ADDR_BC(address)) {
if (!bc) {
puts("Do you want to ping broadcast? Then -b");
return CMD_ERROR;
}
ttl = 1;
ping_bc_mode = true;
}
/* Try to malloc duplicate detection buffer */
dups = (bool *) malloc(count * sizeof(bool));
if (dups == NULL) {
puts("Not enough system memory to fulfill your request!");
return CMD_ERROR;
}
net_addrtostr(address, adrbuf, sizeof(adrbuf));
printf("PING %s %lu bytes of data.\n", adrbuf, sizeof(mms_ping_message_t));
mms_ping_packets = 0;
mms_ping_dups = 0;
mms_ping_last_proc_id = (rand() % 255) + 1;
rtt_min = 0xffffffff;
rtt_max = 0x00000000;
rtt_avg = 0x00000000;
mms_ping_pid = fk_thread->pid;
long ts_start = (uint32_t)clock_get_systemtime();
for (i = 1; i <= count; i++) {
/* No duplicate for this sequence number possible */
dups[i - 1] = false;
/* Send ping echo request to destination */
mms_ping(address, i, prio, ttl);
/* Set timeout for next ping echo request packet to ::timeout seconds */
utimer_set_wpid(&mms_ping_utimer, timeout, mms_ping_pid, NULL);
/* Wait for ping echo reply or timeout */
msg_receive(&m);
/* Remove user timer because maybe woken up by ping response */
utimer_remove(&mms_ping_utimer);
}
ts_start = (uint32_t)clock_get_systemtime() - ts_start;
printf("--- %s ping statistics ---\n", adrbuf);
if (mms_ping_dups == 0) {
printf("%u packets transmitted, %u received, %u%% packet loss, time %lu ms\n", count,
mms_ping_packets, ((count - mms_ping_packets) * 100) / count, ts_start);
}
else {
printf("%u packets transmitted, %u received, +%i duplicates, %u%% packet loss, time %lu ms\n", count,
mms_ping_packets, mms_ping_dups, ((count - mms_ping_packets) * 100) / count, ts_start);
}
if (mms_ping_packets > 0) {
printf("rtt min/avg/max = %.2f/%.2f/%.2f ms\n", rtt_min, rtt_avg / (mms_ping_packets + mms_ping_dups), rtt_max);
}
if (!ping_bc_mode && mms_ping_packets == count) {
/* Calculate approximate throughput */
printf("--- %s throughput statistics ---\n", adrbuf);
float bw = (count * (8 + 4 + 62 + 2) * 1000) / (float)ts_start; /* for CC1100 */
printf("approximate throughput (air): %.2f byte/sec\n", 2 * bw);
bw = (count * 58 * 1000) / (float)ts_start; /* for CC1100 */
printf("approximate throughput (dll): %.2f byte/sec\n", 2 * bw);
bw = (count * NET_MESSAGE_PAYLOAD_LENGTH * 1000) / (float)ts_start;
printf("approximate throughput (net): %.2f byte/sec\n", 2 * bw);
bw = (count * UDPL_MESSAGE_LENGTH * 1000) / (float)ts_start;
printf("approximate throughput (trans/UDPL): %.2f byte/sec\n", 2 * bw);
bw = (count * TCPL_MESSAGE_LENGTH * 1000) / (float)ts_start;
printf("approximate throughput (trans/TCPL): %.2f byte/sec\n", bw);
}
/* Ping is over, clear random ping process id and buffer */
mms_ping_last_proc_id = 0;
free(dups);
return CMD_SUCCESS;
}
return CMD_ERROR;
}
ASCCMD(ssh, CMDFLAG_SERIAL, "Usage: ssh [-q] destination");
CMD_FUNCTION(ssh, cmdargs)
{
if (cmdargs->arg_size > 0) {
bool quit = false;
const char *msg = cmdargs->args;
while (*msg == ' ') {
msg++;
}
if (*msg == '-' && (*(msg + 1) == 'Q' || *(msg + 1) == 'q')) {
quit = true;
msg++;
msg++;
}
uint16_t address = net_strtoaddr((char *)msg, (char **)&msg);
if (address == 0) {
return CMD_ERROR;
}
int iface_addr = net_get_address_in_subnet(address);
/* No ssh to unsupported network or own address */
if (iface_addr == 0 || iface_addr == address) {
return CMD_ERROR;
}
/* If broadcast destination address, also exit here */
if (address == NETWORK_ADDR_BC(address)) {
return CMD_ERROR;
}
if (!quit) {
mms_ssh_connect(address);
}
else {
mms_ssh_close(address);
}
return CMD_SUCCESS;
}
return CMD_ERROR;
}
//#endif
/*---------------------------------------------------------------------------*/
// Ping message handler and send function
/*---------------------------------------------------------------------------*/
static void mms_ping_handler(void *message, int message_size,
packet_info_t *packet_info)
{
mms_ping_message_t *ping = (mms_ping_message_t *)message;
if (ping->type == MMS_PING_ECHO_REQUEST) {
ping->type = MMS_PING_ECHO_REPLY;
net_send((void *)ping, sizeof(mms_ping_message_t), packet_info->source,
LAYER_2_PROTOCOL_PING, packet_info->tos, 10);
}
else if (ping->type == MMS_PING_ECHO_REPLY) {
if (ping->identifier == mms_ping_last_proc_id) {
msg m;
bool wasDup = false;
char *msgDup;
char buf[10];
if (dups[ping->seq_num - 1]) {
wasDup = true;
mms_ping_dups++;
msgDup = "(DUP!)";
}
else {
mms_ping_packets++;
dups[ping->seq_num - 1] = true;
msgDup = "";
}
if (!ping_bc_mode && !wasDup) {
utimer_remove(&mms_ping_utimer); /* Stop timeout timer */
}
float ms = ((uint32_t)clock_get_systemtime() - ping->timestamp);
if (ms < rtt_min) {
rtt_min = ms;
}
if (ms > rtt_max) {
rtt_max = ms;
}
rtt_avg += ms;
if (!ping_silent_mode) {
net_addrtostr(packet_info->source, buf, sizeof(buf));
printf("%lu bytes from %s: seq=%u ttl=%u time=%.2f ms %s\n",
sizeof(mms_ping_message_t), buf,
ping->seq_num, *packet_info->ttl_ptr, ms, msgDup);
}
if (!ping_bc_mode && !wasDup) {
msg_send(&m, mms_ping_pid, false);
}
}
}
}
static void mms_ping(uint16_t destination, uint8_t seq, uint8_t prio, int ttl)
{
mms_ping_message_t ping_request;
ping_request.type = MMS_PING_ECHO_REQUEST;
ping_request.identifier = 0;
ping_request.identifier = mms_ping_last_proc_id;
ping_request.seq_num = seq;
ping_request.timestamp = (uint32_t)clock_get_systemtime();
net_send((void *)&ping_request, sizeof(mms_ping_message_t),
destination, LAYER_2_PROTOCOL_PING, prio, ttl);
}
/*---------------------------------------------------------------------------*/
// SSH message handler and send functions
/*---------------------------------------------------------------------------*/
static void mms_ssh_connect(uint16_t destination)
{
mms_ssh_message_t ssh;
ssh.type = MMS_SSH_CON_REQUEST;
mms_send((void *)&ssh, sizeof(mms_ssh_message_t), destination,
LAYER_3_PROTOCOL_SSH, PRIORITY_DATA);
}
static void mms_ssh_reply_connect(uint16_t destination, int socket, bool accept)
{
mms_ssh_message_t ssh;
ssh.type = accept ? MMS_SSH_CON_ACCEPT : MMS_SSH_CON_REJECT;
trans_sendto(socket, (void *)&ssh, sizeof(mms_ssh_message_t),
LAYER_3_PROTOCOL_SSH, PRIORITY_DATA, destination);
}
static void mms_ssh_close(uint16_t destination)
{
mms_ssh_message_t ssh;
ssh.type = MMS_SSH_CON_CLOSE;
mms_send((void *)&ssh, sizeof(mms_ssh_message_t), destination,
LAYER_3_PROTOCOL_SSH, PRIORITY_DATA);
}
static void mms_ssh_handler(void *message, int message_size,
packet_info_t *packet_info)
{
char adrbuf[10];
mms_ssh_message_t *ssh = (mms_ssh_message_t *)message;
if (ssh->type == MMS_SSH_CON_REQUEST) {
if (ssh_socket > -1) {
mms_ssh_reply_connect(packet_info->source, -1, false);
return;
}
ssh_socket = trans_socket(SOCK_TCPL);
if (ssh_socket < 0) {
mms_ssh_reply_connect(packet_info->source, -1, false);
return;
}
trans_connect(ssh_socket, packet_info->source);
mms_ssh_reply_connect(packet_info->source, ssh_socket, true);
}
else if (ssh->type == MMS_SSH_CON_ACCEPT) {
net_addrtostr(packet_info->source, adrbuf, sizeof(adrbuf));
printf("SSH connection accepted by %s\n", adrbuf);
}
else if (ssh->type == MMS_SSH_CON_REJECT) {
net_addrtostr(packet_info->source, adrbuf, sizeof(adrbuf));
printf("SSH connection rejected by %s\n", adrbuf);
}
else if (ssh->type == MMS_SSH_CON_CLOSE) {
if (ssh_socket > -1) {
uint16_t peer;
trans_getpeername(ssh_socket, &peer);
if (peer == packet_info->source) {
if (trans_close(ssh_socket, CLOSE_IMMEDIATE) == 1) {
ssh_socket = -1;
}
}
}
}
else if (ssh->type == MMS_SSH_DATA) {
mms_ssh_data_message_t *ssh_data = (mms_ssh_data_message_t *)message;
printf((char *)ssh_data->data);
fflush(stderr);
}
}
void mms_net_printf(const char *format)
{
if (ssh_socket > -1) {
mms_ssh_data_message_t ssh_data;
ssh_data.type = MMS_SSH_DATA;
int i = 0;
int len = strlen(format);
while (i < len) {
int chunk = len - i > (MMS_SSH_DATA_MAX - 1) ? (MMS_SSH_DATA_MAX - 1) : len - i;
memset(ssh_data.data, 0, sizeof(ssh_data.data));
memcpy(ssh_data.data, format + i, chunk);
if (trans_send(ssh_socket, (void *)&ssh_data, sizeof(mms_ssh_data_message_t),
LAYER_3_PROTOCOL_SSH, PRIORITY_DATA) < 0) {
break;
}
i += chunk;
}
}
else {
printf(format);
}
}
/*---------------------------------------------------------------------------*/
// Micro Mesh Stack API
/*---------------------------------------------------------------------------*/
void mms_init(void)
{
mms_initp(LAYER_2_PROTOCOL_MMR, &r_iface);
}
void mms_initp(protocol_t rp, route_interface_t *ri)
{
/* Initialize routing & network layer */
mmr_init();
net_init(ri);
/* Initialize transport layer */
trans_init();
/* Add routing as protocol handler for given route messages */
net_set_protocol_handler(rp, ri->receive);
/* Add transport as protocol handler for UDPL and TCPL messages */
net_set_protocol_handler(LAYER_2_PROTOCOL_UDPL, trans_receive_udpl);
net_set_protocol_handler(LAYER_2_PROTOCOL_TCPL, trans_receive_tcpl);
/* Add MMS ping handler */
net_set_protocol_handler(LAYER_2_PROTOCOL_PING, mms_ping_handler);
/* Add SSH handler */
trans_set_protocol_handler(LAYER_3_PROTOCOL_SSH, mms_ssh_handler);
}
/*---------------------------------------------------------------------------*/
int mms_add_interface(const char *name, uint16_t addr, const radio_t *radio)
{
return net_add_interface(name, addr, radio);
}
/*---------------------------------------------------------------------------*/
uint16_t mms_get_interface_address(int interface_id)
{
return net_get_interface_address(interface_id);
}
/*---------------------------------------------------------------------------*/
bool mms_set_interface_address(int interface_id, uint16_t addr)
{
return net_set_interface_address(interface_id, addr);
}
/*---------------------------------------------------------------------------*/
bool mms_set_output_power(int interface_id, uint8_t pa_idx)
{
return net_set_output_power(interface_id, pa_idx);
}
/*---------------------------------------------------------------------------*/
int mms_set_protocol_handler(protocol_t protocol, packet_handler_t handler)
{
return trans_set_protocol_handler(protocol, handler);
}
/*---------------------------------------------------------------------------*/
void mms_receive(void *msg, int msg_size, packet_info_t *packet_info)
{
net_receive(msg, msg_size, packet_info);
}
/*---------------------------------------------------------------------------*/
int mms_socket(int type)
{
return trans_socket(type);
}
/*---------------------------------------------------------------------------*/
int mms_connect(int socket, uint16_t dest_addr)
{
return trans_connect(socket, dest_addr);
}
/*---------------------------------------------------------------------------*/
int mms_sock_send(int socket, void *buffer, int length, protocol_t protocol,
uint8_t priority)
{
return trans_send(socket, buffer, length, protocol, priority);
}
/*---------------------------------------------------------------------------*/
int mms_sock_sendto(int socket, void *buffer, int length, protocol_t protocol,
uint8_t priority, uint16_t dest_addr)
{
return trans_sendto(socket, buffer, length, protocol, priority, dest_addr);
}
/*---------------------------------------------------------------------------*/
int mms_send(void *msg, int msg_len, uint16_t dst, protocol_t protocol,
uint8_t priority)
{
return trans_sendto(-1, msg, msg_len, protocol, priority, dst);
}
/*---------------------------------------------------------------------------*/
int mms_poll(int socket)
{
return trans_poll(socket);
}
/*---------------------------------------------------------------------------*/
int mms_close(int socket, int how)
{
return trans_close(socket, how);
}
/*---------------------------------------------------------------------------*/
void mms_flush_routes(bool flush_static)
{
rt_flush_routes(flush_static);
}
/*---------------------------------------------------------------------------*/
void mms_print_routes(void)
{
rt_print_routes();
}
/*---------------------------------------------------------------------------*/
void mms_print_ifconfig(int iface)
{
net_print_ifconfig(iface);
}
/*---------------------------------------------------------------------------*/
void mms_print_stats(void)
{
net_print_stats();
printf("\r\n");
r_iface.print_stats();
}

View File

@ -1,214 +0,0 @@
/******************************************************************************
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
*******************************************************************************/
#ifndef MMSTACK_H_
#define MMSTACK_H_
/**
* @defgroup net_mmstack Micro Mesh Stack
* @ingroup net
*
* @{
*/
/**
* @file
* @brief
*
* @author Freie Universität Berlin, Computer Systems & Telematics
* @author Thomas Hillebrandt <hillebra@inf.fu-berlin.de>
* @version $Revision: 3854 $
*
* @note $Id: mmstack.h 3854 2011-12-06 15:27:01Z hwill $
*/
#include "radio.h"
#include "net-types.h"
/**
* @brief Initialize micro mesh stack.
*/
void mms_init(void);
/**
* @brief Initialize micro mesh stack.
*
* @param rp Routing protocol type identifier.
* @param ri Pointer to route interface.
*/
void mms_initp(protocol_t rp, route_interface_t *ri);
/**
* @brief Add network interface.
*
* @param name Network layer name on this interface (maximum 5 characters).
* @param addr Network layer address on this interface.
* @param radio Radio layer API access.
*
* @return Interface identifier or -1 if an error occurs.
*/
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.
*
* @param interface_id The network interface id.
*
* @return The address of the network interface with given id
* or 0 if no interface with given id is found.
*/
uint16_t mms_get_interface_address(int interface_id);
/**
* @brief Set the address of the network interface with the given id.
*
* @param interface_id The network interface id.
* @param addr The new address to set.
*
* @return true if address was successfully set; false otherwise (e.g.
* wrong interface, invalid address etc.)
*/
bool mms_set_interface_address(int interface_id, uint16_t addr);
/**
* @brief Set the output power of the radio device on the network
* interface with the given id.
*
* @param interface_id The network interface id.
* @param pa_idx Output power value from 0 (lowest output power) to
* X (highest output power).
*
* @return true if output power was successfully set; false otherwise
* (e.g. wrong interface, invalid output power value etc.)
*/
bool mms_set_output_power(int interface_id, uint8_t pa_idx);
/**
* @brief Set a protocol handler for a given protocol.
*
* @param protocol The protocol identifier (must be unique).
* @param handler The packet handler called if a packet of given protocol is received.
*
* @return -1 if an error occurs (e.g. handler table full) else >= 0.
*/
int mms_set_protocol_handler(protocol_t protocol, packet_handler_t handler);
/**
* @see ::trans_socket(int)
*/
int mms_socket(int type);
/**
* @see ::trans_connect(int,uint16_t)
*/
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);
/**
* @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);
/**
* @brief Convenience function to send a message via UDPL socket.
*
* @param msg packet payload
* @param msg_len the size of the packet payload in bytes (max. 46 bytes).
* @param dst packet destination address
* @param protocol packet protocol identifier
* @param priority packet priority
*
* @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);
/**
* @see ::trans_poll(int)
*/
int mms_poll(int socket);
/**
* @see ::trans_close(int,int)
*/
int mms_close(int socket, int how);
/**
* @brief Receive function for incoming packets.
*
* This function is the protocol handler function for micro mesh messages received
* on the lower layers.
*
* @param msg Incoming packet.
* @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);
/**
* @brief Flush kernel route table.
*
* @param flush_static Whether to flush static routes also
*/
void mms_flush_routes(bool flush_static);
/**
* @brief Writes to the standard output (stdout) a sequence of data formatted as
* the format argument specifies.
*
* If a SSH connection is active, the output is redirected to the node who
* initialized the SSH connection.
*
* @param format String that contains the text to be written to stdout.
*/
void mms_net_printf(const char *format);
/**
* @brief Print kernel route table.
*/
void mms_print_routes(void);
/**
* @brief Print interface configuration.
*
* @param iface Optional interface parameter.
*/
void mms_print_ifconfig(int iface);
/**
* @brief Print Micro Mesh stack statistics.
*/
void mms_print_stats(void);
/** @} */
#endif /* MMSTACK_H_ */

View File

@ -1,6 +0,0 @@
INCLUDES = -I../include -I../drivers/include -I../lib -I$(RIOTCPU)/$(CPU)/include -I../net -I../../core/include
MODULE =syslog
include $(MAKEBASE)/Makefile.base

View File

@ -1,101 +0,0 @@
/**
* Syslog daemon
*
* Copyright (C) 2009-2013 Freie Universitaet Berlin
*
* 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 syslog
* @{
* @file syslog-api.c
* @author Freie Universitaet Berlin
* @}
*/
*******************************************************************************/
#include <stdarg.h>
#include "syslog.h"
#include "tracelog.h"
#undef VSYSLOG
#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;
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, ...)
{
va_list 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, ...)
{
va_list 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, ...)
{
va_list 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, ...)
{
va_list 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, ...)
{
va_list 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, ...)
{
va_list argp;
va_start(argp, strFmt);
VSYSLOG(SL_DEBUG, mod, strFmt, argp);
va_end(argp);
}
#endif

View File

@ -1,188 +0,0 @@
/******************************************************************************
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
*******************************************************************************/
/**
* @file
* @ingroup syslog
* @brief System Logging Service output implementation
*
* @author Freie Universität Berlin, Computer Systems & Telematics
* @version $Revision: 3854 $
*
* @note $Id: syslog-out.c 3854 2011-12-06 15:27:01Z hwill $
*/
#include <stdio.h>
#include <string.h>
#ifdef MODULE_FAT
#include <unistd.h>
#include <fcntl.h>
#include <sys/errno.h>
#endif
// sys
#include "cfg-feuerware.h"
#include "syslog.h"
#include "clock.h"
#include "device-rs232.h"
#if FEUERWARE_CONF_CORE_SUPPORTS_TIME
#include "timelib.h"
#endif
// net
#include "net-types.h"
#ifdef MODULE_TRACELOG
#include "tracelog.h"
#endif
/*-----------------------------------------------------------------------------------*/
void syslog_format_ascii(struct syslog_args *args, struct syslog_chainlink *chainlink)
{
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
);
}
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);
}
}
/*-----------------------------------------------------------------------------------*/
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;
#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
);
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)
{
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 (chainlink != NULL && chainlink->fpout != NULL) {
chainlink->fpout(args, chainlink->next);
}
}
/*-----------------------------------------------------------------------------------*/
void syslog_out_stdout(struct syslog_args *args, struct syslog_chainlink *chainlink)
{
printf(args->message);
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)
{
char t[20];
int file;
file = open(path, O_WRONLY | O_APPEND | O_CREAT);
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;
}
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) {
#ifdef MODULE_TRACELOG
trace_string(TRACELOG_EV_MEMORY, "fat");
#endif
}
}
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);
}
void syslog_close_file(void)
{
close(syslog_file);
syslog_file = -1;
}
#endif

View File

@ -1,269 +0,0 @@
/******************************************************************************
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
*******************************************************************************/
/**
* @addtogroup syslog
* @{
*/
/**
* @file
* @brief System Logging Service implementation
*
* @author Freie Universität Berlin, Computer Systems & Telematics
* @author Michael Baar <baar@inf.fu-berlin.de>
* @version $Revision: 3854 $
*
* @note $Id: syslog.c 3854 2011-12-06 15:27:01Z hwill $
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cfg-feuerware.h"
#include "cmdengine.h"
#include "device-rs232.h"
#include "syslog.h"
#include "sysmon.h"
#include "tracelog.h"
static const char *syslog_level_stringtable = "emergency\0"
"critical\0"
"warn\0"
"notice\0"
"info\0"
"debug\0"
"\3";
__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);
extern struct syslog_interface syslog_interfaces[];
/*-----------------------------------------------------------------------------------*/
void syslog_init(void)
{
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;
/* 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);
}
}
}
}
/*-----------------------------------------------------------------------------------*/
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);
}
/*-----------------------------------------------------------------------------------*/
#if CMD_ISLEVEL(CMD_LEVEL_HUMAN_USER)
/**
* @brief Syslog-level property: <code>syslog [interface] [newlevel]</code>
* @ingroup commands
* @param[in] interface Name of the syslog interface to change (optional)
* @param[in] newlevel New loglevel value (see uint8_t)
* @return Current level
*
* \p Returns and optionally sets the syslog log-level. For available combinations see
* uint8_t.
*
* \p Usage:
* \li \c syslog Prints syslog configuration
* \li \c syslog \c 0x3f Sets loglevel of syslog node 0 (usually stdout) to 0x3f
* \li \c syslog \c stdout \c 0x3f Sets loglevel of syslog node "stdout" to 0x3f
*/
ASCCMD(syslog, 0, "[interface] [byte val]: syslog-level property");
CMD_FUNCTION(syslog, cmdargs)
{
int i;
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;
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);
}
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)
{
uint8_t l = level;
unsigned short intlevel;
for (intlevel = 0; intlevel < SYSLOG_LEVELS_COUNT; intlevel++) {
if ((l & 1) == 1) {
break;
}
l >>= 1;
}
return intlevel;
}
/*-----------------------------------------------------------------------------------*/
/**
* @brief Find an interface for a given name
*/
static int find_interface_index_for_name(const char *name)
{
int i;
for (i = 0; i < SYSLOG_CONF_NUM_INTERFACES; i++) {
if (strcmp(syslog_interfaces[i].name, name) == 0) {
return i;
}
}
return -1;
}
/** @} */

View File

@ -1,6 +0,0 @@
INCLUDES = -I../include -I../drivers/include -I../lib -I$(RIOTCPU)/$(CPU)/include -I../net -I../../core/include
MODULE =tracelog
include $(MAKEBASE)/Makefile.base

View File

@ -1,295 +0,0 @@
/******************************************************************************
Copyright 2008, 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
*******************************************************************************/
/**
* @ingroup tracelog
* @{
*/
/**
* @file
* @brief Tracelog implementation
*
* @author Freie Universität Berlin, Computer Systems & Telematics
* @author Michael Baar <baar@inf.fu-berlin.de>
*
* @note $Id: tracelog.c 3854 2011-12-06 15:27:01Z hwill $
*/
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "configure.h"
// core
#include "sysmon.h"
#include "cmdengine.h"
#include "tracelog.h"
#include "stringlib.h"
#include "syslog.h"
#if TRACELOG_CONF_NUM_ENTRIES > 0
__attribute__((section(".noinit")))
struct tracelog tracelog;
/// 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";
#endif
/*-----------------------------------------------------------------------------------*/
#if TRACELOG_CONF_NUM_ENTRIES > 0
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
#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';
}
#endif
/*-----------------------------------------------------------------------------------*/
/**
* @brief Writes a new tracelog entry
* @internal
*/
static void
trace(
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;
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;
}
/* fill meta data */
trace->event = event & 0x7F;
trace->type = t;
/* 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
#endif
}
/*-----------------------------------------------------------------------------------*/
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
}
tracelog_initialized = true; // accept traces
trace_reset(); // trace reason for last reset
#endif
}
void
tracelog_dump(void)
{
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);
#endif
printf("}\n");
}
/*-----------------------------------------------------------------------------------*/
void
trace_event(enum tracelog_event event)
{
#if TRACELOG_CONF_NUM_ENTRIES > 0
trace(event, TRACE_NULL, NULL, 0);
#endif
}
/*-----------------------------------------------------------------------------------*/
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));
#endif
}
/*-----------------------------------------------------------------------------------*/
void
trace_pointer(enum tracelog_event event, void *pointer)
{
#if TRACELOG_CONF_NUM_ENTRIES > 0
trace(event, TRACE_POINTER, &pointer, sizeof(void *));
#endif
}
/*-----------------------------------------------------------------------------------*/
void
trace_string(enum tracelog_event event, char *string)
{
#if TRACELOG_CONF_NUM_ENTRIES > 0
trace(event, TRACE_STRING, string, strlen(string));
#endif
}
/*-----------------------------------------------------------------------------------*/
#if CMD_ISLEVEL(CMD_LEVEL_SYSTEM_DEBUG | CMD_LEVEL_HUMAN_USER)
/**
* @brief Trace command: <code>trace [event] [string]</code>
* @ingroup commands
* @param event Event to add to trace (optional)
* @param string String commend to include with event (optional)
*
* If no parameters are given dumps the current system event trace.
*/
ASCCMD(trace, CMDFLAG_SERIAL, "[event] [text]: print tracelog / trace event [num] with [text]");
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;
}
#endif
/*-----------------------------------------------------------------------------------*/
/** @} */