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:
commit
88b8ccf3e8
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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 */
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 = .);
|
||||
|
||||
@ -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
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
207
sys/logd/logd.c
207
sys/logd/logd.c
@ -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);
|
||||
}
|
||||
@ -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
|
||||
|
||||
967
sys/net/mm/mmr.c
967
sys/net/mm/mmr.c
@ -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");
|
||||
}
|
||||
171
sys/net/mm/mmr.h
171
sys/net/mm/mmr.h
@ -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_ */
|
||||
@ -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();
|
||||
}
|
||||
@ -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_ */
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
@ -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;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/** @} */
|
||||
Loading…
x
Reference in New Issue
Block a user