Lots of changes / commits! This allows ravenusbstick example to build at least.

This commit is contained in:
c_oflynn 2008-10-14 19:06:51 +00:00
parent 6e3ee0d917
commit a520fe4646
18 changed files with 1474 additions and 249 deletions

View file

@ -1,5 +1,5 @@
ifndef CONTIKI
${error CONTIKI not defined! You must specify where CONTIKI resides}
${error CONTIKI not defined! You must specify where CONTIKI resides!}
endif
OBJECTDIR = obj_$(TARGET)
@ -8,8 +8,11 @@ CFLAGS += -DCONTIKI_TARGET=$(TARGET)
ifeq ($(TARGET),)
-include Makefile.target
ifeq ($(TARGET),)
${info TARGET not defined, using target 'native'}
TARGET=native
ifeq ($(DEFAULT_TARGET),)
DEFAULT_TARGET=native
endif
${info TARGET not defined, using target '$(DEFAULT_TARGET)'}
TARGET=$(DEFAULT_TARGET)
else
${info using saved target '$(TARGET)'}
endif
@ -44,30 +47,33 @@ endif
include $(CONTIKI)/core/net/rime/Makefile.rime
include $(CONTIKI)/core/net/mac/Makefile.mac
#include $(CONTIKI)/core/net/ipv6/Makefile.ipv6
SYSTEM = process.c procinit.c autostart.c elfloader.c profile.c timetable.c timetable-aggregate.c
THREADS = mt.c
LIBS = memb.c timer.c list.c etimer.c energest.c rtimer.c stimer.c \
print-stats.c ifft.c crc16.c random.c
ifdef UIP_CONF_IPV6
UIP = uip6.c tcpip.c psock.c uip-udp-packet.c uip-split.c \
uip-over-mesh.c resolv.c hc.c tcpdump.c uiplib.c
NET = $(UIP) uip-icmp6.c uip-nd6.c uip-nd6-io.c uip-netif.c sicslowpan.c
else # UIP_CONF_IPV6
UIP = uip.c uiplib.c resolv.c tcpip.c psock.c hc.c uip-split.c uip-fw.c \
uip-fw-drv.c uip_arp.c tcpdump.c uip-neighbor.c uip-udp-packet.c \
uip-over-mesh.c #rawpacket-udp.c
LIBS = timer.c etimer.c random.c memb.c list.c energest.c print-stats.c rtimer.c stimer.c
ifndef UIP_CONF_IPV6
UIP = uip.c tcpip.c uip-split.c psock.c uip-udp-packet.c uip-over-mesh.c resolv.c hc.c tcpdump.c uiplib.c
else
UIP = uip6.c tcpip.c uip-split.c psock.c uip-udp-packet.c uip-over-mesh.c resolv.c hc.c tcpdump.c uiplib.c
endif
#rawpacket-udp.c
ifndef UIP_CONF_IPV6
NET = $(UIP) uaodv.c uaodv-rt.c
endif # UIP_CONF_IPV6
else
NET = $(UIP) uip-icmp6.c uip-nd6.c uip-nd6-io.c uip-netif.c sicslowpan.c
endif
CTK = ctk.c
CTKVNC = $(CTK) ctk-vncserver.c libconio.c vnc-server.c vnc-out.c ctk-vncfont.c
CONTIKIFILES = $(SYSTEM) $(LIBS) $(NET) $(DHCP) $(THREADS)
ifndef CONTIKI_NO_NET
CONTIKIFILES = $(SYSTEM) $(LIBS) $(NET) $(THREADS) $(DHCP)
else
CONTIKIFILES = $(SYSTEM) $(LIBS) $(THREADS) sicslowpan.c fakeuip.c
endif
CONTIKI_SOURCEFILES += $(CONTIKIFILES)
CONTIKIDIRS += ${addprefix $(CONTIKI)/core/,dev lib net net/mac net/rime sys \
cfs ctk lib/ctk loader . }
cfs ctk lib/ctk loader net/sicslow_interop . }
oname = ${patsubst %.c,%.o,${patsubst %.S,%.o,$(1)}}

View file

@ -1,4 +1,4 @@
# $Id: Makefile.avr,v 1.11 2008/10/14 09:44:12 adamdunkels Exp $
# $Id: Makefile.avr,v 1.12 2008/10/14 19:06:51 c_oflynn Exp $
### Check if we are running under Windows
@ -53,8 +53,8 @@ LDFLAGS = -mmcu=$(MCU) -Wl,-Map=contiki-$(TARGET).map \
CONTIKI_TARGET_DIRS_CONCAT = ${addprefix $(CONTIKI)/platform/$(TARGET)/, \
$(CONTIKI_TARGET_DIRS)}
vpath %.c $(PROJECTDIRS) $(CONTIKI)/cpu/avr/dev $(CONTIKI)/cpu/avr/dev/usb \
$(CONTIKI)/cpu/avr/dev/usb/rndis $(CONTIKI)/cpu/avr/dev/usb/serial \
vpath %.c $(PROJECTDIRS) $(CONTIKI)/cpu/avr/dev $(CONTIKI)/cpu/avr/dev/usb \
$(CONTIKI)/cpu/avr/dev/usb/rndis $(CONTIKI)/cpu/avr/dev/usb/serial \
$(CONTIKI)/cpu/avr/dev/usb/storage \
$(CONTIKIDIRS) $(APPDIRS) $(CONTIKI_TARGET_DIRS_CONCAT) \
$(CONTIKI_CPU) $(CONTIKI)/cpu/avr/radio/rf230 $(CONTIKI)/cpu/avr/radio/mac

79
cpu/avr/dev/clock-avr.h Normal file
View file

@ -0,0 +1,79 @@
#ifndef CONTIKI_CLOCK_AVR_H
#define CONTIKI_CLOCK_AVR_H
#if defined (__AVR_ATmega128__)
#define AVR_OUTPUT_COMPARE_INT TIMER0_COMP_vect
#define OCRSetup() \
/* Select internal clock */ \
ASSR = 0x00; \
\
/* Set counter to zero */ \
TCNT0 = 0; \
\
/* \
* Set comparison register: \
* Crystal freq. is 16000000,\
* pre-scale factor is 1024, i.e. we have 125 "ticks" / sec: \
* 16000000 = 1024 * 125 * 125 \
*/ \
OCR0 = 125; \
\
/* \
* Set timer control register: \
* - prescale: 1024 (CS00 - CS02) \
* - counter reset via comparison register (WGM01) \
*/ \
TCCR0 = _BV(CS00) | _BV(CS01) | _BV(CS02) | _BV(WGM01); \
\
/* Clear interrupt flag register */ \
TIFR = 0x00; \
\
/* \
* Raise interrupt when value in OCR0 is reached. Note that the \
* counter value in TCNT0 is cleared automatically. \
*/ \
TIMSK = _BV (OCIE0);
#elif defined (__AVR_ATmega1284P__) || (__AVR_AT90USB1287__)
#define OCRSetup() \
/* Select internal clock */ \
ASSR = 0x00; \
\
/* Set counter to zero */ \
TCNT0 = 0; \
\
/* \
* Set comparison register: \
* Crystal freq. is 8000000,\
* pre-scale factor is 1024, i.e. we have 125 "ticks" / sec: \
* 8000000 = 1024 * 125 * 62.5 \
*/ \
OCR0A = 62; \
\
/* \
* Set timer control register: \
* - prescale: 1024 (CS00 - CS02) \
* - counter reset via comparison register (WGM01) \
*/ \
TCCR0A = _BV(WGM01); \
TCCR0B = _BV(CS00) | _BV(CS02); \
\
/* Clear interrupt flag register */ \
TIFR0 = TIFR0; \
\
/* \
* Raise interrupt when value in OCR0 is reached. Note that the \
* counter value in TCNT0 is cleared automatically. \
*/ \
TIMSK0 = _BV (OCIE0A);
#define AVR_OUTPUT_COMPARE_INT TIMER0_COMPA_vect
#else
#error "Setup CPU in clock-avr.h"
#endif
#endif //CONTIKI_CLOCK_AVR_H

View file

@ -1,5 +1,6 @@
#include "sys/clock.h"
#include "dev/clock-avr.h"
#include "sys/etimer.h"
#include <avr/io.h>
@ -8,7 +9,8 @@
static volatile clock_time_t count;
/*---------------------------------------------------------------------------*/
SIGNAL(SIG_OUTPUT_COMPARE0)
//SIGNAL(SIG_OUTPUT_COMPARE0)
ISR(AVR_OUTPUT_COMPARE_INT)
{
++count;
if(etimer_pending()) {
@ -49,35 +51,8 @@ clock_init(void)
{
cli ();
/* Select internal clock */
ASSR = 0x00;
/* Set counter to zero */
TCNT0 = 0;
/*
* Set comparison register:
* Crystal freq. is 16000000,
* pre-scale factor is 1024, i.e. we have 125 "ticks" / sec:
* 16000000 = 1024 * 125 * 125
*/
OCR0 = 125;
/*
* Set timer control register:
* - prescale: 1024 (CS00 - CS02)
* - counter reset via comparison register (WGM01)
*/
TCCR0 = _BV(CS00) | _BV(CS01) | _BV(CS02) | _BV(WGM01);
/* Clear interrupt flag register */
TIFR = 0x00;
/*
* Raise interrupt when value in OCR0 is reached. Note that the
* counter value in TCNT0 is cleared automatically.
*/
TIMSK = _BV (OCIE0);
OCRSetup();
/*
* Counts the number of ticks. Since clock_time_t is an unsigned

View file

@ -28,7 +28,7 @@
*
* This file is part of the Contiki operating system.
*
* @(#)$Id: rs232.c,v 1.2 2006/12/22 17:00:45 barner Exp $
* @(#)$Id: rs232.c,v 1.3 2008/10/14 19:06:51 c_oflynn Exp $
*/
#include <stdio.h>
@ -49,7 +49,7 @@
#define RS232_PRINTF_BUFFER_LENGTH 64
#endif
#if MCU == atmega128
#if defined (__AVR_ATmega128__) || defined(__AVR_ATmega1284P__)
typedef struct {
volatile uint8_t * UDR;
volatile uint8_t * UBRRH;
@ -86,13 +86,13 @@ static rs232_t rs232_ports[2] = {
#endif
/*---------------------------------------------------------------------------*/
SIGNAL(SIG_UART0_TRANS)
ISR(USART0_TX_vect)
{
rs232_ports[RS232_PORT_0].txwait = 0;
}
/*---------------------------------------------------------------------------*/
SIGNAL(SIG_UART0_RECV)
ISR(USART0_RX_vect)
{
unsigned char c;
@ -104,13 +104,13 @@ SIGNAL(SIG_UART0_RECV)
}
/*---------------------------------------------------------------------------*/
SIGNAL(SIG_UART1_TRANS)
ISR(USART1_TX_vect)
{
rs232_ports[RS232_PORT_1].txwait = 0;
}
/*---------------------------------------------------------------------------*/
SIGNAL(SIG_UART1_RECV)
ISR(USART1_RX_vect)
{
unsigned char c;

View file

@ -31,7 +31,7 @@
* Author: Adam Dunkels <adam@sics.se>
* Simon Barner <barner@in.tum.de>
*
* @(#)$Id: rs232.h,v 1.2 2006/12/22 17:00:45 barner Exp $
* @(#)$Id: rs232.h,v 1.3 2008/10/14 19:06:51 c_oflynn Exp $
*/
#ifndef __RS232_H__
@ -40,8 +40,12 @@
#include <avr/pgmspace.h>
#include "contiki-conf.h"
#if MCU == atmega128
#if defined (__AVR_ATmega128__)
#include "dev/rs232_atmega128.h"
#elif defined (__AVR_ATmega1284P__)
#include "dev/rs232_atmega1284.h"
#elif defined (__AVR_AT90USB1287__)
#include "dev/rs232_at90usb1287.h"
#else
#error "Please implement a rs232 header for your MCU (or set the MCU type \
in contiki-conf.h)."

View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 2006, Technical University of Munich
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* @(#)$$
*/
/**
* \file
* AVR specific definitions for the rs232 port.
*
* \author
* Simon Barner <barner@in.tum.de
*/
#ifndef __RS232_AT90USB1287__
#define __RS232_AT90USB1287__
/******************************************************************************/
/*** Includes */
/******************************************************************************/
#include <avr/io.h>
/******************************************************************************/
/*** RS232 ports */
/******************************************************************************/
#define RS232_PORT_0 0
#define RS232_PORT_1 1
/******************************************************************************/
/*** Baud rates */
/******************************************************************************/
#endif /* #ifndef __RS232_AT90USB1287__ */

View file

@ -0,0 +1,142 @@
/*
* Copyright (c) 2006, Technical University of Munich
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* @(#)$$
*/
/**
* \file
* AVR specific definitions for the rs232 port.
*
* \author
* Simon Barner <barner@in.tum.de
*/
#ifndef __RS232_ATMEGA1284__
#define __RS232_ATMEGA1284__
/******************************************************************************/
/*** Includes */
/******************************************************************************/
#include <avr/io.h>
/******************************************************************************/
/*** RS232 ports */
/******************************************************************************/
#define RS232_PORT_0 0
#define RS232_PORT_1 1
/******************************************************************************/
/*** Baud rates */
/******************************************************************************/
#if MCU_MHZ == 16
/* Single speed operation (U2X = 0)*/
#define USART_BAUD_2400 416
#define USART_BAUD_4800 207
#define USART_BAUD_9600 103
#define USART_BAUD_14400 68
#define USART_BAUD_19200 51
#define USART_BAUD_28800 34
#define USART_BAUD_38400 25
#define USART_BAUD_57600 16
#define USART_BAUD_76800 12
#define USART_BAUD_115200 8
#define USART_BAUD_230400 3
#define USART_BAUD_250000 3
#define USART_BAUD_500000 1
#define USART_BAUD_1000000 0
#elif MCU_MHZ == 8
/* Single speed operation (U2X = 0)*/
#define USART_BAUD_2400 207
#define USART_BAUD_4800 103
#define USART_BAUD_9600 51
#define USART_BAUD_14400 34
#define USART_BAUD_19200 25
#define USART_BAUD_28800 16
#define USART_BAUD_38400 12
#define USART_BAUD_57600 8
#define USART_BAUD_76800 6
#define USART_BAUD_115200 3
#define USART_BAUD_230400 1
#define USART_BAUD_250000 1
#define USART_BAUD_500000 0
#else
#error "Please define the baud rates for your CPU clock: ATmega128 handbook p. \
195-198 or set the rate in contiki-conf.h"
#endif
/******************************************************************************/
/*** Interrupt settings */
/******************************************************************************/
#define USART_INTERRUPT_RX_COMPLETE _BV (RXCIE0)
#define USART_INTERRUPT_TX_COMPLETE _BV (TXCIE0)
#define USART_INTERRUPT_DATA_REG_EMPTY _BV (UDRIE0)
/******************************************************************************/
/*** Receiver / transmitter */
/******************************************************************************/
#define USART_RECEIVER_ENABLE _BV (RXEN0)
#define USART_TRANSMITTER_ENABLE _BV (TXEN0)
/******************************************************************************/
/*** Mode select */
/******************************************************************************/
#define USART_MODE_ASYNC 0x00
#define USART_MODE_SYNC _BV (UMSEL00)
/******************************************************************************/
/*** Parity */
/******************************************************************************/
#define USART_PARITY_NONE 0x00
#define USART_PARITY_EVEN _BV (UPM01)
#define USART_PARITY_ODD _BV (UPM01) | _BV (UPM00)
/******************************************************************************/
/*** Stop bits */
/******************************************************************************/
#define USART_STOP_BITS_1 0x00
#define USART_STOP_BITS_2 _BV (USBS)
/******************************************************************************/
/*** Character size */
/******************************************************************************/
#define USART_DATA_BITS_5 0x00
#define USART_DATA_BITS_6 _BV (UCSZ00)
#define USART_DATA_BITS_7 _BV (UCSZ01)
#define USART_DATA_BITS_8 _BV (UCSZ01) | _BV (UCSZ00)
// #define USART_DATA_BITS_9 (needs also UCSZ2 bit in UCSRnB)
/******************************************************************************/
/*** Clock polarity */
/******************************************************************************/
#define USART_RISING_XCKN_EDGE 0x00
#define USART_FALLING_XCKN_EDGE _BV (UCPOL0)
#endif /* #ifndef __RS232_ATMEGA128__ */

View file

@ -1,9 +1,9 @@
all:
make TARGET=avr-ravenusb -f Makefile.ravenusbstick ravenusbstick.elf
avr-objcopy -O ihex -R .eeprom ravenusbstick.elf ravenusbstick.hex
avr-size -C ravenusbstick.elf
clean:
make -f Makefile.ravenusbstick clean
rm -rf obj_avr-ravenusb
rm symbols.c symbols.h ravenusbstick.elf ravenusbstick.hex
all:
make TARGET=avr-ravenusb -f Makefile.ravenusbstick ravenusbstick.elf
avr-objcopy -O ihex -R .eeprom ravenusbstick.elf ravenusbstick.hex
avr-size -C ravenusbstick.elf
clean:
make -f Makefile.ravenusbstick clean
rm -rf obj_avr-ravenusb
rm symbols.c symbols.h ravenusbstick.elf ravenusbstick.hex

View file

@ -28,12 +28,11 @@
*
* This file is part of the Contiki operating system.
*
* $Id: ravenusbstick.c,v 1.1 2008/10/14 10:01:52 julienabeille Exp $
*/
/*---------------------------------------------------------------------------*/
//#include "mac_event.h"
#include "uip.h"
#include <avr/pgmspace.h>
#include <avr/pgmspace.h>
#include <stdio.h>

View file

@ -1,39 +1,39 @@
CONTIKI_TARGET_DIRS = . rf230 apps net loader
CONTIKI_CORE=contiki-raven-main
CONTIKI_TARGET_MAIN = ${CONTIKI_CORE}.o
#USB Ethernet Interface + USB Serial Port TX Only
USB = uart_usb_lib.c \
cdc_task.c \
rndis_task.c \
rndis.c \
usb_descriptors.c \
usb_drv.c \
usb_specific_request.c \
usb_standard_request.c \
usb_task.c \
scsi_decoder.c \
ctrl_access.c \
storage_task.c \
avr_flash.c
CONTIKI_TARGET_SOURCEFILES += slip.c cfs-eeprom.c eeprom.c random.c \
mmem.c contiki-raven-default-init-lowlevel.c \
contiki-raven-default-init-net.c contiki-raven-main.c \
sicslow_ethernet.c \
$(USB)
USB_INCLUDES = -I$(CONTIKI_CPU)/dev/usb
CONTIKIAVR=$(CONTIKI)/cpu/avr
CONTIKIBOARD=.
CONTIKI_PLAT_DEFS = -DF_CPU=8000000UL -DAVRGCC -DAUTO_CRC_PADDING=2
MCU=at90usb1287
AVRDUDE_PROGRAMMER=jtag2
CONTIKI_CORE=contiki-raven-main
CONTIKI_TARGET_MAIN = ${CONTIKI_CORE}.o
#USB Ethernet Interface + USB Serial Port TX Only
USB = uart_usb_lib.c \
cdc_task.c \
rndis_task.c \
rndis.c \
usb_descriptors.c \
usb_drv.c \
usb_specific_request.c \
usb_standard_request.c \
usb_task.c \
scsi_decoder.c \
ctrl_access.c \
storage_task.c \
avr_flash.c
CONTIKI_TARGET_SOURCEFILES += cfs-eeprom.c eeprom.c random.c \
mmem.c contiki-raven-default-init-lowlevel.c \
contiki-raven-default-init-net.c contiki-raven-main.c \
sicslow_ethernet.c \
$(USB)
USB_INCLUDES = -I$(CONTIKI_CPU)/dev/usb
CONTIKIAVR=$(CONTIKI)/cpu/avr
CONTIKIBOARD=.
CONTIKI_PLAT_DEFS = -DF_CPU=8000000UL -DAVRGCC -DAUTO_CRC_PADDING=2 -DJACKDAW=1
MCU=at90usb1287
AVRDUDE_PROGRAMMER=jtag2
# For usb devices, you may either use PORT=usb, or (e.g. if you have more than one
# programmer connected) you can use the following trick to find out the serial number:
#

View file

@ -1,65 +1,65 @@
:10000000000002AABBCCDDEEFFFFFFFFFFFFFFFFFA
:10001000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
:10002000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
:10003000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
:10004000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
:10005000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
:10006000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
:10007000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
:10008000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
:10009000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
:1000A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
:1000B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
:1000C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
:1000D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
:1000E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
:1000F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
:10010000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
:10011000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
:10012000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
:10013000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
:10014000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
:10015000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
:10016000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
:10017000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
:10018000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
:10019000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
:1001A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
:1001B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
:1001C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
:1001D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
:1001E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
:1001F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
:10020000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
:10021000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
:10022000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
:10023000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
:10024000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
:10025000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
:10026000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
:10027000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
:10028000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
:10029000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
:1002A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
:1002B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
:1002C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
:1002D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
:1002E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
:1002F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
:10030000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
:10031000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
:10032000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
:10033000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
:10034000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
:10035000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
:10036000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
:10037000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
:10038000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
:10039000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
:1003A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
:1003B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
:1003C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
:1003D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
:1003E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
:1003F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
:00000001FF
:10000000000002AABBCCDDEEFFFFFFFFFFFFFFFFFA
:10001000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
:10002000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
:10003000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
:10004000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
:10005000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
:10006000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
:10007000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
:10008000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
:10009000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
:1000A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
:1000B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
:1000C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
:1000D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
:1000E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
:1000F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
:10010000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
:10011000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
:10012000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
:10013000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
:10014000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
:10015000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
:10016000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
:10017000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
:10018000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
:10019000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
:1001A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
:1001B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
:1001C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
:1001D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
:1001E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
:1001F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
:10020000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
:10021000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
:10022000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
:10023000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
:10024000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
:10025000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
:10026000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
:10027000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
:10028000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
:10029000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
:1002A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
:1002B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
:1002C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
:1002D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
:1002E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
:1002F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
:10030000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
:10031000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
:10032000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
:10033000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
:10034000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
:10035000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
:10036000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
:10037000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
:10038000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
:10039000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
:1003A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
:1003B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
:1003C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
:1003D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
:1003E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
:1003F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
:00000001FF

View file

@ -32,74 +32,83 @@
*
* @(#)$$
*/
#include "contiki-raven.h"
#include "contiki.h"
#include "usb_drv.h"
#include "usb_descriptors.h"
#include "usb_specific_request.h"
#include <util/delay.h>
uint8_t checkForFinger(void);
#include "contiki-raven.h"
#include "contiki.h"
#include "usb_drv.h"
#include "usb_descriptors.h"
#include "usb_specific_request.h"
#include <util/delay.h>
uint8_t checkForFinger(void);
uint8_t fingerPresent = 0;
/* Defining this allows you to mount the USB Stick as a mass storage device by shorting the two pins. See docs. */
//#define WINXPSP2
void
init_lowlevel(void)
{
{
Leds_init();
Leds_off();
if (checkForFinger()) {
usb_mode = mass_storage;
}
Leds_off();
if (checkForFinger()) {
#ifdef WINXPSP2
usb_mode = mass_storage;
#else
fingerPresent = 1;
#endif
}
return;
}
uint8_t checkForFinger(void)
{
uint8_t tests;
uint8_t matches;
/*
Three pads on RZUSBSTICK go: GND PD3 PD2
We pulse PD3, and check for that pattern on PD2.
A (moist) finger across those three pads should be enough
to bridge these
*/
//Output
DDRD |= 1<<PD3;
//Input
DDRD &= ~(1<<PD2);
tests = 100;
matches = 0;
while(tests) {
//Set bit PD3 to value of LSB of 'tests'
PORTD = (PORTD & ~(1<<PD3)) | ( (tests & 0x01) << PD3);
//Allow changes to propogate
_delay_us(1);
//Check if PD2 matches what we set PD3 to
if ((PIND & (1<<PD2)) == ((tests & 0x01) << PD2)) {
matches++;
}
tests--;
}
if (matches > 70) {
return 1;
}
return 0;
}
uint8_t checkForFinger(void)
{
uint8_t tests;
uint8_t matches;
/*
Three pads on RZUSBSTICK go: GND PD3 PD2
We pulse PD3, and check for that pattern on PD2.
A (moist) finger across those three pads should be enough
to bridge these
*/
//Output
DDRD |= 1<<PD3;
//Input
DDRD &= ~(1<<PD2);
tests = 100;
matches = 0;
while(tests) {
//Set bit PD3 to value of LSB of 'tests'
PORTD = (PORTD & ~(1<<PD3)) | ( (tests & 0x01) << PD3);
//Allow changes to propogate
_delay_us(1);
//Check if PD2 matches what we set PD3 to
if ((PIND & (1<<PD2)) == ((tests & 0x01) << PD2)) {
matches++;
}
tests--;
}
if (matches > 70) {
return 1;
}
return 0;
}

View file

@ -35,7 +35,7 @@
#include "contiki-raven.h"
#include "mac.h"
#include "zmac.h"
#include "sicslowpan.h"
extern uint64_t rndis_ethernet_addr;
@ -43,12 +43,25 @@ void
init_net(void)
{
/* Set the Ethernet address to the 15.4 MAC address low 5 bytes...*/
rndis_ethernet_addr = macLongAddr & 0x0000ffffffffffffUL;
/* Set as locally administed address */
rndis_ethernet_addr |= 0x020000000000UL;
ieee15_4ManagerAddress.set_long_addr(rndis_ethernet_addr);
/* Set local bit, Clear translate bit, Clear Multicast bit */
macLongAddr &= ~(0x0700000000000000ULL);
macLongAddr |= 0x0200000000000000ULL;
/* Set the Ethernet address to the 15.4 MAC address */
rndis_ethernet_addr = macLongAddr;
/* Remove the middle two bytes... */
rndis_ethernet_addr = (rndis_ethernet_addr & 0xffffffUL) | ((rndis_ethernet_addr & 0xffffff0000000000ULL) >> 16);
/* Change ieee802.15.4 address to correspond with what the ethernet's
IPv6 address will be. This will have ff:fe in the middle. */
macLongAddr = (macLongAddr & 0xffffff0000ffffffULL) | (0x000000fffe000000ULL);
ieee15_4ManagerAddress.set_long_addr(macLongAddr);
}

View file

@ -40,6 +40,8 @@
*/
#include <avr/pgmspace.h>
#include <avr/fuse.h>
#include <avr/eeprom.h>
#include <util/delay.h>
#include <stdio.h>
@ -63,6 +65,17 @@
#include "rndis/rndis_task.h"
#include "storage/storage_task.h"
FUSES =
{
.low = 0xde,
.high = 0x99,
.extended = 0xff,
};
/* Put default MAC address in EEPROM */
uint8_t mac_address[8] EEMEM = {0x02, 0x12, 0x13, 0xff, 0xfe, 0x14, 0x15, 0x16};
PROCINIT(&etimer_process, &mac_process);
int
@ -88,13 +101,13 @@ main(void)
procinit_init();
/* Setup USB */
process_start(&usb_process, NULL);
process_start(&cdc_process, NULL);
process_start(&rndis_process, NULL);
process_start(&storage_process, NULL);
printf_P(PSTR("System online.\n"));
process_start(&usb_process, NULL);
process_start(&cdc_process, NULL);
process_start(&rndis_process, NULL);
process_start(&storage_process, NULL);
printf_P(PSTR("System online.\n"));
//Fix MAC address
init_net();

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2006, Technical University of Munich
* Copyright (c) 2008, Technical University of Munich
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -32,11 +32,8 @@
*/
/**
* \file
* Sample Contiki kernel for STK 501 development board
* \addtogroup usbstick
*
* \author
* Simon Barner <barner@in.tum.de
*/
#ifndef __CONTIKI_RAVEN_H__

View file

@ -0,0 +1,846 @@
/**
* \file sicslow_ethernet.c
* Routines to interface between Ethernet and 6LowPan
*
* \author
* Colin O'Flynn <coflynn@newae.com>
*
* \addtogroup usbstick
*/
/* Copyright (c) 2008 by:
* Colin O'Flynn coflynn@newae.com
* Eric Gnoske egnoske@gmail.com
* Blake Leverett bleverett@gmail.com
* Mike Vidales mavida404@gmail.com
* Kevin Brown kbrown3@uccs.edu
* Nate Bohlmann nate@elfwerks.com
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of the copyright holders nor the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
\ingroup usbstick
\defgroup sicslowinterop 6LowPan Ethernet Interop
@{
*/
/**
\par Ethernet to 6LowPan Address Translation
It should be obvious that since 802.15.4 addresses are 8
bytes, and 802.3 addresses are 6 bytes, some form of
address translation is needed. These routines provide this
\par 802.3 Address Formats
802.3 MAC addresses used here have this form:
\verbatim
+----+----+----+----+----+----+----+----+
+ + + + + + TR + GL + MU +
+----+----+----+----+----+----+----+----+
\endverbatim
It can be seen this is like a normal ethernet MAC address,
with GL being the Global/Local bit, and MU being the
Multicast/Unicast bit.
The addition is the 'TR' bit, which if set indicates that
the address must be translated when going between 802.15.4
and 802.3.
\par Address Translation
If the TRANSLATE (TR) bit is CLEAR, this means the 5th and
4th LSBytes of the 802.15.4 address are fffe, aka the address
has the hexidecial form:
xxxxxxfffexxxxxx
\note
You should always aim to set the 802.15.4 addresses
of the devices on your network to ones that will
satisfy this requirement. Some examples are:
\note
0x02 23 42 ff fe 73 92 28
\note
0x82 00 82 ff fe cd ee 22
\note
So the most significant octets MUST
have bit 0 CLEAR, bit 1 SET, and bit 2 CLEAR. The remaining
bits in this octet can be anything.
If the TRANSLATE bit is SET, this means the address on the
802.3 side does not directly convert to an 802.15.4 address.
To translate it, the remainder of the octet is used as an
index in a look-up table. This look-up table simply stores
the 4th, 5th, and 8th octet of the 802.15.4 address, and attaches
them to the remaining 5 bytes of the 802.3 address.
In this way there can be 32 different 802.15.4 'prefixes',
requiring only 96 bytes of RAM in a storage table on the
802.3 to 802.15.4 bridge.
Mulitcast addresses on 802.3 are mapped to broadcast addresses on
802.15.4 and vis-versa. Since IPv6 does not use 802.3 broadcast,
this code will drop all 802.3 broadcast packets. They are most
likely something unwanted, such as IPv4 packets that snuck in.
\par Notes on how addresses are stored
An 802.15.4 address will be reported for example as:
0x8877665544332211
Stored in the array as passed to these functions, it will be:
\verbatim
array[0] = 0x88;
array[1] = 0x77;
array[2] = 0x66;
etc.
\endverbatim
An 802.3 address will be reported for example as:
02:43:53:35:45:45
Stored in the array as passed to these functions, it will be:
\verbatim
array[0] = 0x02;
array[1] = 0x43;
array[2] = 0x53;
array[3] = 0x35
etc.
\endverbatim
*/
#include "uip.h"
#include "uip_arp.h" //For ethernet header structure
#include "zmac.h"
#include "frame.h"
#include "net/rime.h"
#include "sicslowpan.h"
#include "sicslow_ethernet.h"
#include "rndis/rndis_protocol.h"
#include "rndis/rndis_task.h"
#include "radio.h"
#include <stdint.h>
#include <stdio.h>
#include <string.h>
//#define PRINTF printf
#define PRINTF(...)
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
#define ETHBUF(x) ((struct uip_eth_hdr *)x)
//For little endian, such as our friend mr. AVR
#ifndef LSB
#define LSB(u16) (((uint8_t *)&(u16))[0]) //!< Least significant byte of \a u16.
#define MSB(u16) (((uint8_t *)&(u16))[1]) //!< Most significant byte of \a u16.
#endif
extern uint64_t rndis_ethernet_addr;
extern void (*pinput)(const struct mac_driver *r);
void (*sicslowinput)(const struct mac_driver *r);
parsed_frame_t * parsed_frame;
usbstick_mode_t usbstick_mode;
uint8_t mac_createSicslowpanLongAddr(uint8_t * ethernet, uip_lladdr_t * lowpan);
uint8_t mac_createEthernetAddr(uint8_t * ethernet, uip_lladdr_t * lowpan);
uint8_t memcmp_reverse(uint8_t * a, uint8_t * b, uint8_t num);
void mac_ethhijack(const struct mac_driver *r);
//! Location of TRANSLATE (TR) bit in Ethernet address
#define TRANSLATE_BIT_MASK (1<<2)
//! Location of LOCAL (GL) bit in Ethernet address
#define LOCAL_BIT_MASK (1<<1)
//! Location of MULTICAST (MU) bit in Ethernet address
#define MULTICAST_BIT_MASK (1<<0)
#define PREFIX_BUFFER_SIZE 32
uint8_t prefixCounter;
uint8_t prefixBuffer[PREFIX_BUFFER_SIZE][3];
/* 6lowpan max size + ethernet header size + 1 */
uint8_t raw_buf[127+ UIP_LLH_LEN +1];
void tcpip_input( void )
{
mac_LowpanToEthernet();
}
/**
* \brief Perform any setup needed
*/
struct mac_driver * pmac;
void mac_ethernetSetup(void)
{
usbstick_mode.sicslowpan = 1;
usbstick_mode.sendToRf = 1;
usbstick_mode.translate = 1;
usbstick_mode.raw = 1;
sicslowinput = pinput;
pmac = sicslowmac_get_driver();
pmac->set_receive_function(mac_ethhijack);
}
/**
* \brief Take a packet received over the ethernet link, and send it
* out over 802.15.4
*/
void mac_ethernetToLowpan(uint8_t * ethHeader)
{
//Dest address
uip_lladdr_t destAddr;
uip_lladdr_t *destAddrPtr = NULL;
//If not IPv6 we don't do anything
if (((struct uip_eth_hdr *) ethHeader)->type != HTONS(UIP_ETHTYPE_IPV6)) {
PRINTF("eth2low: Packet is not IPv6, dropping\n");
rndis_stat.txbad++;
uip_len = 0;
return;
}
// In sniffer mode we don't ever send anything
if (usbstick_mode.sendToRf == 0) {
uip_len = 0;
return;
}
/* IPv6 uses 33-33-xx-xx-xx-xx prefix for multicast ND stuff */
if ( (((struct uip_eth_hdr *) ethHeader)->dest.addr[0] == 0x33) &&
(((struct uip_eth_hdr *) ethHeader)->dest.addr[1] == 0x33) )
{
PRINTF("eth2low: Ethernet multicast packet received\n");
;//Do Nothing
} else if ( (((struct uip_eth_hdr *) ethHeader)->dest.addr[0] == 0xFF) &&
(((struct uip_eth_hdr *) ethHeader)->dest.addr[1] == 0xFF) &&
(((struct uip_eth_hdr *) ethHeader)->dest.addr[2] == 0xFF) &&
(((struct uip_eth_hdr *) ethHeader)->dest.addr[3] == 0xFF) &&
(((struct uip_eth_hdr *) ethHeader)->dest.addr[4] == 0xFF) &&
(((struct uip_eth_hdr *) ethHeader)->dest.addr[5] == 0xFF) ) {
/* IPv6 does not use broadcast addresses, hence this should not happen */
PRINTF("eth2low: Ethernet broadcast address received, should not happen?\n");
rndis_stat.txbad++;
uip_len = 0;
return;
} else {
PRINTF("eth2low: Addressed packet received... ");
//Check this returns OK
if (mac_createSicslowpanLongAddr( &(((struct uip_eth_hdr *) ethHeader)->dest.addr[0]), &destAddr) == 0) {
PRINTF(" translation failed\n");
rndis_stat.txbad++;
uip_len = 0;
return;
}
PRINTF(" translated OK\n");
destAddrPtr = &destAddr;
}
//Remove header from length before passing onward
uip_len -= UIP_LLH_LEN;
//Some IP packets have link layer in them, need to change them around!
if (usbstick_mode.translate) {
uint8_t transReturn = mac_translateIPLinkLayer(ll_802154_type);
PRINTF("IPTranslation: returns %d\n", transReturn);
}
if (usbstick_mode.sendToRf){
tcpip_output(destAddrPtr);
rndis_stat.txok++;
}
uip_len = 0;
}
/**
* \brief Take a packet received over the 802.15.4 link, and send it
* out over ethernet, performing any translations needed.
*/
void mac_LowpanToEthernet(void)
{
parsed_frame = sicslowmac_get_frame();
//Setup generic ethernet stuff
ETHBUF(uip_buf)->type = htons(UIP_ETHTYPE_IPV6);
//Check for broadcast message
//if(rimeaddr_cmp((const rimeaddr_t *)destAddr, &rimeaddr_null)) {
if( ( parsed_frame->fcf->destAddrMode == SHORTADDRMODE) &&
( parsed_frame->dest_addr->addr16 == 0xffff) ) {
ETHBUF(uip_buf)->dest.addr[0] = 0x33;
ETHBUF(uip_buf)->dest.addr[1] = 0x33;
ETHBUF(uip_buf)->dest.addr[2] = UIP_IP_BUF->destipaddr.u8[12];
ETHBUF(uip_buf)->dest.addr[3] = UIP_IP_BUF->destipaddr.u8[13];
ETHBUF(uip_buf)->dest.addr[4] = UIP_IP_BUF->destipaddr.u8[14];
ETHBUF(uip_buf)->dest.addr[5] = UIP_IP_BUF->destipaddr.u8[15];
} else {
//Otherwise we have a real address
mac_createEthernetAddr((uint8_t *) &(ETHBUF(uip_buf)->dest.addr[0]),
(uip_lladdr_t *)rimebuf_addr(RIMEBUF_ADDR_RECEIVER));
}
mac_createEthernetAddr((uint8_t *) &(ETHBUF(uip_buf)->src.addr[0]),
(uip_lladdr_t *)rimebuf_addr(RIMEBUF_ADDR_SENDER));
//We only do address translation in network mode!
if (usbstick_mode.translate) {
//Some IP packets have link layer in them, need to change them around!
mac_translateIPLinkLayer(ll_8023_type);
}
PRINTF("Low2Eth: Sending packet to ethernet\n");
uip_len += UIP_LLH_LEN;
rndis_send(uip_buf, uip_len);
rndis_stat.rxok++;
uip_len = 0;
}
/**
* \brief Translate IP packet's possible link-layer addresses, passing
* the message to the appropriate higher level function for this
* packet (aka: ICMP)
* \param target The target we want to end up with - either ll_8023_type
* for ethernet, or ll_802154_type for 802.15.4
* \return Returns how successful the translation was
* \retval 0 Addresses, if present, were translated.
* \retval <0 Negative return values indicate various errors, as defined
* by the higher level function.
*/
int8_t mac_translateIPLinkLayer(lltype_t target)
{
if (UIP_IP_BUF->proto == UIP_PROTO_ICMP6) {
PRINTF("eth2low: ICMP Message detected\n");
return mac_translateIcmpLinkLayer(target);
}
return 0;
}
#include "net/uip-icmp6.h"
#include "net/uip-nd6.h"
typedef struct {
uint8_t type;
uint8_t length;
uint8_t data[16];
} icmp_opts_t;
#define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN])
#define UIP_ICMP_OPTS(x) ((icmp_opts_t *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN + x])
void slide(uint8_t * data, uint8_t length, int16_t slide);
/**
* \brief Translate the link-layer (L2) addresses in an ICMP packet.
* This will just be NA/NS/RA/RS packets currently.
* \param target The target we want to end up with - either ll_8023_type
* for ethernet, or ll_802154_type for 802.15.4
* \return Returns how successful the translation was
* \retval 0 Addresses, if present, were translated.
* \retval -1 ICMP message was unknown type, nothing done.
* \retval -2 ICMP Length does not make sense?
* \retval -3 Unknown 'target' type
*/
int8_t mac_translateIcmpLinkLayer(lltype_t target)
{
uint16_t icmp_opt_offset = 0;
int16_t len = UIP_IP_BUF->len[1] | (UIP_IP_BUF->len[0] << 8);
uint16_t iplen;
uint8_t i;
int16_t sizechange;
uint8_t llbuf[16];
//Figure out offset to start of options
switch(UIP_ICMP_BUF->type) {
case ICMP6_NS:
case ICMP6_NA:
icmp_opt_offset = 24;
break;
case ICMP6_RS:
icmp_opt_offset = 8;
break;
case ICMP6_RA:
icmp_opt_offset = 16;
break;
case ICMP6_REDIRECT:
icmp_opt_offset = 40;
break;
/** Things without link-layer */
case ICMP6_DST_UNREACH:
case ICMP6_PACKET_TOO_BIG:
case ICMP6_TIME_EXCEEDED:
case ICMP6_PARAM_PROB:
case ICMP6_ECHO_REQUEST:
case ICMP6_ECHO_REPLY:
return 0;
break;
default:
return -1;
}
//Figure out length of options
len -= icmp_opt_offset;
//Sanity check
if (len < 8) return -2;
//While we have options to do...
while (len >= 8){
//If we have one of these, we have something useful!
if (((UIP_ICMP_OPTS(icmp_opt_offset)->type) == UIP_ND6_OPT_SLLAO) ||
((UIP_ICMP_OPTS(icmp_opt_offset)->type) == UIP_ND6_OPT_TLLAO) ) {
/* Shrinking the buffer may thrash things, so we store the old
link-layer address */
for(i = 0; i < (UIP_ICMP_OPTS(icmp_opt_offset)->length*8 - 2); i++) {
llbuf[i] = UIP_ICMP_OPTS(icmp_opt_offset)->data[i];
}
//Shrink/grow buffer as needed
if (target == ll_802154_type) {
//Current is 802.3, Hence current link-layer option is 6 extra bytes
sizechange = 8;
slide(UIP_ICMP_OPTS(icmp_opt_offset)->data + 6, len - 6, sizechange);
} else if (target == ll_8023_type) {
/* Current is 802.15.4, Hence current link-layer option is 14 extra
* bytes.
* (Actual LL is 8 bytes, but total option length is in multiples of
* 8 Bytes, hence 8 + 2 = 10. Closest is 16 bytes, then 16 bytes for
* total optional length - 2 bytes for type + length leaves 14 )
*/
sizechange = -8;
slide(UIP_ICMP_OPTS(icmp_opt_offset)->data + 14, len - 14, sizechange);
} else {
return -3; //Uh-oh!
}
//Translate addresses
if (target == ll_802154_type) {
mac_createSicslowpanLongAddr(llbuf, (uip_lladdr_t *)UIP_ICMP_OPTS(icmp_opt_offset)->data);
} else {
mac_createEthernetAddr(UIP_ICMP_OPTS(icmp_opt_offset)->data, (uip_lladdr_t *)llbuf);
}
//Adjust the length
if (target == ll_802154_type) {
UIP_ICMP_OPTS(icmp_opt_offset)->length = 2;
} else {
UIP_ICMP_OPTS(icmp_opt_offset)->length = 1;
}
//Adjust the IP header length, as well as uIP length
iplen = UIP_IP_BUF->len[1] | (UIP_IP_BUF->len[0]<<8);
iplen += sizechange;
len += sizechange;
UIP_IP_BUF->len[1] = (uint8_t)iplen;
UIP_IP_BUF->len[0] = (uint8_t)(iplen >> 8);
uip_len += sizechange;
//We broke ICMP checksum, be sure to fix that
UIP_ICMP_BUF->icmpchksum = 0;
UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum();
//Finally set up next run in while loop
len -= 8 * UIP_ICMP_OPTS(icmp_opt_offset)->length;
icmp_opt_offset += 8 * UIP_ICMP_OPTS(icmp_opt_offset)->length;
} else {
//Not an option we care about, ignore it
len -= 8 * UIP_ICMP_OPTS(icmp_opt_offset)->length;
//This shouldn't happen!
if (UIP_ICMP_OPTS(icmp_opt_offset)->length == 0) {
PRINTF("Option in ND packet has length zero, error?\n");
len = 0;
}
icmp_opt_offset += 8 * UIP_ICMP_OPTS(icmp_opt_offset)->length;
} //If ICMP_OPT is one we care about
} //while(len >= 8)
return 0;
}
/**
* \brief Create a 802.15.4 long address from a 802.3 address
* \param ethernet Pointer to ethernet address
* \param lowpan Pointer to 802.15.4 address
*/
uint8_t mac_createSicslowpanLongAddr(uint8_t * ethernet, uip_lladdr_t * lowpan)
{
uint8_t index;
uint8_t i;
//Special case - if the address is our address, we just copy over what we know to be
//our 802.15.4 address
if (memcmp_reverse((uint8_t *)&rndis_ethernet_addr, ethernet, 6) == 0) {
memcpy((uint8_t *)lowpan, &macLongAddr, 8);
byte_reverse((uint8_t *)lowpan, 8);
return 1;
}
//Check if translate bit is set, hence we have to look up the prefix
if (ethernet[0] & TRANSLATE_BIT_MASK) {
//Get top bits
index = ethernet[0] >> 3;
//Check this is plausible...
if (index >= prefixCounter) {
return 0;
}
//Copy over prefix
lowpan->addr[0] = prefixBuffer[index][0];
lowpan->addr[3] = prefixBuffer[index][1];
lowpan->addr[4] = prefixBuffer[index][2];
//Bit is clear
//so we copy all six
} else {
lowpan->addr[0] = ethernet[0];
lowpan->addr[3] = 0xff;
lowpan->addr[4] = 0xfe;
}
//Copy over reamining five bytes
lowpan->addr[1] = ethernet[1];
lowpan->addr[2] = ethernet[2];
lowpan->addr[5] = ethernet[3];
lowpan->addr[6] = ethernet[4];
lowpan->addr[7] = ethernet[5];
return 1;
}
/**
* \brief Create a 802.3 address from a 802.15.4 long address
* \param ethernet Pointer to ethernet address
* \param lowpan Pointer to 802.15.4 address
*/
uint8_t mac_createEthernetAddr(uint8_t * ethernet, uip_lladdr_t * lowpan)
{
uint8_t index = 0;
uint8_t i,j, match;
//Special case - if the address is our address, we just copy over what we know to be
//our 802.3 address
if (memcmp_reverse((uint8_t *)&macLongAddr, (uint8_t *)lowpan, 8) == 0) {
memcpy(ethernet, &rndis_ethernet_addr, 6);
byte_reverse(ethernet, 6);
return 1;
}
//Check if we need to do anything:
if ((lowpan->addr[3] == 0xff) && (lowpan->addr[4] == 0xfe) &&
((lowpan->addr[0] & TRANSLATE_BIT_MASK) == 0) &&
((lowpan->addr[0] & MULTICAST_BIT_MASK) == 0) &&
(lowpan->addr[0] & LOCAL_BIT_MASK)) {
/** Nope: just copy over 6 bytes **/
ethernet[0] = lowpan->addr[0];
ethernet[1] = lowpan->addr[1];
ethernet[2] = lowpan->addr[2];
ethernet[3] = lowpan->addr[5];
ethernet[4] = lowpan->addr[6];
ethernet[5] = lowpan->addr[7];
} else {
/** Yes: need to store prefix **/
for (i = 0; i < prefixCounter; i++) {
//Check the current prefix - if it fails, check next one
if ((lowpan->addr[0] == prefixBuffer[i][0]) &&
(lowpan->addr[3] == prefixBuffer[i][1]) &&
(lowpan->addr[4] == prefixBuffer[i][2])) {
break;
}
}
index = i;
//Deal with overflow, iron-fist style
if (index >= PREFIX_BUFFER_SIZE) {
index = 0;
prefixCounter = PREFIX_BUFFER_SIZE;
} else {
//Are we making a new one?
if (index == prefixCounter) {
prefixCounter++;
}
}
//Copy the prefix over, no matter if we have a new or old one
prefixBuffer[index][0] = lowpan->addr[0];
prefixBuffer[index][1] = lowpan->addr[3];
prefixBuffer[index][2] = lowpan->addr[4];
//Create ethernet MAC address now
ethernet[1] = lowpan->addr[1];
ethernet[2] = lowpan->addr[2];
ethernet[3] = lowpan->addr[5];
ethernet[4] = lowpan->addr[6];
ethernet[5] = lowpan->addr[7];
ethernet[0] = TRANSLATE_BIT_MASK | LOCAL_BIT_MASK | (index << 3);
}
return 1;
}
/**
* \brief Slide the pointed to memory up a certain amount,
* growing/shrinking a buffer
* \param data Pointer to start of data buffer
* \param length Length of the data buffer
* \param slide How many bytes to slide the buffer up in memory (if +) or
* down in memory (if -)
*/
void slide(uint8_t * data, uint8_t length, int16_t slide)
{
//Sanity checks
if (!length) return;
if (!slide) return;
uint8_t i = 0;
while(length) {
length--;
//If we are sliding up, we do from the top of the buffer down
if (slide > 0) {
*(data + length + slide) = *(data + length);
//If we are sliding down, we do from the bottom of the buffer up
} else {
*(data + slide + i) = *(data + i);
}
i++;
}
}
/*--------------------------------------------------------------------*/
/** \brief Process a received 6lowpan packet. Hijack function.
* \param r The MAC layer
*
* The 6lowpan packet is put in rimebuf by the MAC. This routine calls
* any other needed layers (either 6lowpan, or just raw ethernet dump)
*/
void mac_ethhijack(const struct mac_driver *r)
{
if (usbstick_mode.raw)
mac_802154raw(r);
if (usbstick_mode.sicslowpan)
sicslowinput(r);
}
/*--------------------------------------------------------------------*/
/*--------------------------------------------------------------------*/
/** \brief Logs a sent 6lowpan frame
*
* This routine passes a frame
* directly to the ethernet layer without decompressing.
*/
void mac_logTXtoEthernet(frame_create_params_t *p,frame_result_t *frame_result)
{
uint8_t sendlen;
/* Make sure we are supposed to do this */
if (usbstick_mode.raw == 0) return;
/* Get the raw frame */
memcpy(&raw_buf[UIP_LLH_LEN], frame_result->frame, frame_result->length);
sendlen = frame_result->length;
//Setup generic ethernet stuff
ETHBUF(raw_buf)->type = htons(UIP_ETHTYPE_802154);
uint64_t tempaddr;
//Check for broadcast message
//if(rimeaddr_cmp((const rimeaddr_t *)destAddr, &rimeaddr_null)) {
if( ( p->fcf.destAddrMode == SHORTADDRMODE) &&
( p->dest_addr.addr16 == 0xffff) ) {
ETHBUF(raw_buf)->dest.addr[0] = 0x33;
ETHBUF(raw_buf)->dest.addr[1] = 0x33;
ETHBUF(raw_buf)->dest.addr[2] = UIP_IP_BUF->destipaddr.u8[12];
ETHBUF(raw_buf)->dest.addr[3] = UIP_IP_BUF->destipaddr.u8[13];
ETHBUF(raw_buf)->dest.addr[4] = UIP_IP_BUF->destipaddr.u8[14];
ETHBUF(raw_buf)->dest.addr[5] = UIP_IP_BUF->destipaddr.u8[15];
} else {
tempaddr = p->dest_addr.addr64;
byte_reverse((uint8_t *)&tempaddr, 8);
//Otherwise we have a real address
mac_createEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->dest.addr[0]),
(uip_lladdr_t *)&tempaddr);
}
tempaddr = p->src_addr.addr64;
byte_reverse((uint8_t *)&tempaddr, 8);
mac_createEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->src.addr[0]),
(uip_lladdr_t *)&tempaddr);
PRINTF("Low2Eth: Sending 802.15.4 packet to ethernet\n");
sendlen += UIP_LLH_LEN;
rndis_send(raw_buf, sendlen);
rndis_stat.rxok++;
return;
}
/*--------------------------------------------------------------------*/
/** \brief Process a received 6lowpan packet.
* \param r The MAC layer
*
* The 6lowpan packet is put in rimebuf by the MAC. This routine passes
* it directly to the ethernet layer without decompressing.
*/
void mac_802154raw(const struct mac_driver *r)
{
uint8_t sendlen;
parsed_frame = sicslowmac_get_frame();
/* Get the raw frame */
memcpy(&raw_buf[UIP_LLH_LEN], radio_frame_data(), radio_frame_length());
sendlen = radio_frame_length();
//Setup generic ethernet stuff
ETHBUF(raw_buf)->type = htons(UIP_ETHTYPE_802154);
//Check for broadcast message
//if(rimeaddr_cmp((const rimeaddr_t *)destAddr, &rimeaddr_null)) {
if( ( parsed_frame->fcf->destAddrMode == SHORTADDRMODE) &&
( parsed_frame->dest_addr->addr16 == 0xffff) ) {
ETHBUF(raw_buf)->dest.addr[0] = 0x33;
ETHBUF(raw_buf)->dest.addr[1] = 0x33;
ETHBUF(raw_buf)->dest.addr[2] = UIP_IP_BUF->destipaddr.u8[12];
ETHBUF(raw_buf)->dest.addr[3] = UIP_IP_BUF->destipaddr.u8[13];
ETHBUF(raw_buf)->dest.addr[4] = UIP_IP_BUF->destipaddr.u8[14];
ETHBUF(raw_buf)->dest.addr[5] = UIP_IP_BUF->destipaddr.u8[15];
} else {
//Otherwise we have a real address
mac_createEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->dest.addr[0]),
(uip_lladdr_t *)rimebuf_addr(RIMEBUF_ADDR_RECEIVER));
}
mac_createEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->src.addr[0]),
(uip_lladdr_t *)rimebuf_addr(RIMEBUF_ADDR_SENDER));
PRINTF("Low2Eth: Sending 802.15.4 packet to ethernet\n");
sendlen += UIP_LLH_LEN;
rndis_send(raw_buf, sendlen);
rndis_stat.rxok++;
return;
}
uint8_t memcmp_reverse(uint8_t * a, uint8_t * b, uint8_t num)
{
uint8_t i = 0;
while(num) {
num--;
if (a[i] != b[num]) return 1;
i++;
}
return 0;
}
/** @} */
/** @} */

View file

@ -0,0 +1,82 @@
/**
* \file sicslow_ethernet.c
* Routines to interface between Ethernet and 6LowPan
*
* \author
* Colin O'Flynn <coflynn@newae.com>
*
* \addtogroup usbstick
*/
/* Copyright (c) 2008 by:
Colin O'Flynn coflynn@newae.com
Eric Gnoske egnoske@gmail.com
Blake Leverett bleverett@gmail.com
Mike Vidales mavida404@gmail.com
Kevin Brown kbrown3@uccs.edu
Nate Bohlmann nate@elfwerks.com
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of the copyright holders nor the names of
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SICSLOW_ETHERNET_H
#define SICSLOW_ETHERNET_H
#include "sicslowmac.h"
#include "frame.h"
typedef enum {
ll_802154_type,
ll_8023_type
} lltype_t;
typedef struct {
uint8_t sicslowpan :1;
uint8_t sendToRf :1;
uint8_t translate :1;
uint8_t raw :1;
} usbstick_mode_t;
#define UIP_ETHTYPE_802154 0x809A
extern usbstick_mode_t usbstick_mode;
int8_t mac_translateIcmpLinkLayer(lltype_t target);
int8_t mac_translateIPLinkLayer(lltype_t target);
void mac_LowpanToEthernet(void);
void mac_ethernetToLowpan(uint8_t * ethHeader);
void mac_ethernetSetup(void);
void mac_802154raw(const struct mac_driver *r);
void mac_logTXtoEthernet(frame_create_params_t *p,frame_result_t *frame_result);
#endif