1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-12-25 06:23:53 +01:00

Merge pull request #140 from LudwigOrtmann/nativenet_transceiver

Nativenet transceiver
This commit is contained in:
Oleg Hahm 2013-08-15 06:06:37 -07:00
commit b798663151
24 changed files with 912 additions and 183 deletions

View File

@ -1,13 +1,12 @@
MODULE = cpu
INCLUDES = -I../include -I$(RIOTBASE)/core/include
INCLUDES += -I../include -I$(RIOTBASE)/core/include
DIRS =
ifneq (,$(findstring rtc,$(USEMODULE)))
DIRS += rtc
endif
ifneq (,$(findstring cc110x_ng,$(USEMODULE)))
DIRS += cc110x_ng
INCLUDES += -I$(RIOTBASE)/drivers/cc110x_ng/include
ifneq (,$(findstring nativenet,$(USEMODULE)))
DIRS += net
endif
all: $(BINDIR)$(MODULE).a

26
cpu/native/README Normal file
View File

@ -0,0 +1,26 @@
If you compile RIOT for the native cpu and include the native_net
module, you need to specify a network interface like this:
./bin/default-native.elf tap0
SETTING UP A TAP NETWORK
========================
There is a shellscript in RIOT/cpu/native called tapsetup.sh which you
can use to create a network of tap interfaces.
Usage:
To create a bridge and two (or count at your option) tap interfaces:
./tapsetup.sh create [count]
To delete the bridge and all tap interfaces:
./tapsetup.sh delete
OSX
===
For tun/tap networking in OSX you will need:
http://tuntaposx.sourceforge.net/
For OSX there is a seperate script called tapsetup-osx.sh. Usage is
just like the other one.

View File

@ -1,7 +0,0 @@
INCLUDES = -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/core/include
INCLUDES += -I$(RIOTBASE)/drivers/cc110x_ng/include/ -I$(RIOTBASE)/sys/include
MODULE =cc110x_ng
include $(MAKEBASE)/Makefile.base

View File

@ -1,153 +0,0 @@
#include <stdio.h>
#include <err.h>
#include <debug.h>
#include <cc110x-arch.h>
#include <cc110x_ng.h>
#include <cc110x_spi.h>
#include <cc110x-internal.h> /* CC1100_READ_BURST etc. */
static int native_cc110x_enabled;
static int native_cc110x_gd0;
static int native_cc110x_gd1;
static int native_cc110x_gd2;
static int native_cc110x_gd0_enabled;
static int native_cc110x_gd2_enabled;
static uint8_t native_cc110x_ssp0dr;
/* arch */
/**
* writes to SSP0 data register and reads from it once it is ready
*/
uint8_t cc110x_txrx(uint8_t c)
{
native_cc110x_ssp0dr = c;
switch(c) {
case CC1100_READ_BURST:
case CC1100_WRITE_BURST:
case CC1100_READ_SINGLE:
case CC1100_NOBYTE:
default:
warnx("cc110x_txrx (%i): not implemented", c);
}
DEBUG("cc110x_txrx\n");
return native_cc110x_ssp0dr;
}
/**
* disables GDO0 interrupt
*/
void cc110x_gdo0_enable(void)
{
/* this would be for rising/high edge if this was proper hardware */
native_cc110x_gd0_enabled = 1;
DEBUG("cc110x_gdo0_enable\n");
return;
}
/**
* enables GDO0 interrupt
*/
void cc110x_gdo0_disable(void)
{
native_cc110x_gd0_enabled = 0;
DEBUG("cc110x_gdo0_disable\n");
return;
}
/**
* enables GDO2 interrupt
*/
void cc110x_gdo2_enable(void)
{
/* this would be for falling/low edge if this was proper hardware */
native_cc110x_gd2_enabled = 1;
DEBUG("cc110x_gdo2_enable\n");
return;
}
/**
* disables GDO2 interrupt
*/
void cc110x_gdo2_disable(void)
{
native_cc110x_gd2_enabled = 0;
DEBUG("cc110x_gdo2_disable\n");
return;
}
/**
* enable interrupts for GDO0 and GDO2
*/
void cc110x_init_interrupts(void)
{
/* this would be for low edge in both cases if this was proper hardware */
cc110x_gdo2_enable();
cc110x_gdo0_enable();
DEBUG("cc110x_init_interrupts\n");
return;
}
void cc110x_before_send(void)
{
cc110x_gdo2_disable();
DEBUG("cc110x_before_send\n");
return;
}
void cc110x_after_send(void)
{
cc110x_gdo2_enable();
DEBUG("cc110x_after_send\n");
return;
}
/* spi */
int cc110x_get_gdo0(void)
{
DEBUG("cc110x_get_gdo0\n");
return native_cc110x_gd0;
}
int cc110x_get_gdo1(void)
{
DEBUG("cc110x_get_gdo1\n");
return native_cc110x_gd1;
}
int cc110x_get_gdo2(void)
{
DEBUG("cc110x_get_gdo2\n");
return native_cc110x_gd2;
}
void cc110x_spi_init(void)
{
native_cc110x_enabled = 1; /* power on */
DEBUG("cc110x_spi_init\n");
return;
}
void cc110x_spi_cs(void)
{
DEBUG("cc110x_spi_cs\n");
return;
}
void cc110x_spi_select(void)
{
DEBUG("cc110x_spi_select\n");
return;
}
void cc110x_spi_unselect(void)
{
DEBUG("cc110x_spi_unselect\n");
return;
}
/* ng */

View File

@ -40,7 +40,7 @@
#include "debug.h"
#define HWTIMERMINOFFSET 1000
#define HWTIMERMINOFFSET 100000
static unsigned long native_hwtimer_now;
@ -217,6 +217,7 @@ unsigned long hwtimer_arch_now(void)
DEBUG("hwtimer_arch_now()\n");
_native_in_syscall = 1;
#ifdef __MACH__
clock_serv_t cclock;
mach_timespec_t mts;
@ -232,6 +233,7 @@ unsigned long hwtimer_arch_now(void)
}
#endif
_native_in_syscall = 0;
native_hwtimer_now = ts2ticks(&t);

View File

@ -18,16 +18,16 @@
#include <signal.h>
/* TODO: choose more sensibly? */
#define KERNEL_CONF_STACKSIZE_PRINTF (8192)
#define KERNEL_CONF_STACKSIZE_PRINTF (81920)
#ifdef __MACH__
#ifdef __MACH__ /* OSX */
#define KERNEL_CONF_STACKSIZE_DEFAULT (163840)
#define KERNEL_CONF_STACKSIZE_IDLE (163840)
#define NATIVE_ISR_STACKSIZE (163840)
#define TRANSCEIVER_STACK_SIZE (163840)
#define MINIMUM_STACK_SIZE (163840)
#else
#define KERNEL_CONF_STACKSIZE_DEFAULT (8192)
#else /* Linux etc. */
#define KERNEL_CONF_STACKSIZE_DEFAULT (KERNEL_CONF_STACKSIZE_PRINTF + 8192)
#define KERNEL_CONF_STACKSIZE_IDLE (16384)
#define NATIVE_ISR_STACKSIZE (16384)
/* undefine the TRANSCEIVER_STACK_SIZE (2048 or 512) defined in transceiver.h */
@ -35,12 +35,9 @@
#undef TRANSCEIVER_STACK_SIZE
#endif
#define TRANSCEIVER_STACK_SIZE (16384)
#define MINIMUM_STACK_SIZE (16384)
#endif
#endif /* OS */
/* for cc110x_ng */
#define RX_BUF_SIZE (10)
#define TRANSCEIVER_BUFFER_SIZE (3)
#define NATIVE_ETH_PROTO 0x1234
#endif /* CPUCONF_H_ */

View File

@ -68,5 +68,9 @@ extern unsigned int _native_saved_eip;
extern int _native_in_isr;
extern int _native_in_syscall;
extern int _native_sigpend;
#ifdef MODULE_UART0
#include <sys/select.h>
extern fd_set _native_rfds;
#endif
/** @} */
#endif //_CPU_H

View File

@ -0,0 +1,29 @@
#include <net/ethernet.h>
#define RX_BUF_SIZE (10)
#define TRANSCEIVER_BUFFER_SIZE (3)
#ifndef NATIVE_MAX_DATA_LENGTH
/* TODO: set this properly: */
#define NATIVE_MAX_DATA_LENGTH (ETHER_MAX_LEN - (ETHER_HDR_LEN+2))
#else
#warning be careful not to exceed (ETHER_MAX_LEN) with NATIVE_MAX_DATA_LENGTH
#endif /* NATIVE_MAX_DATA_LENGTH */
void nativenet_init(int transceiver_pid);
void nativenet_powerdown();
void nativenet_set_monitor(uint8_t mode);
uint8_t nativenet_send(radio_packet_t *packet);
int16_t nativenet_set_address(radio_address_t address);
int16_t nativenet_get_address();
int16_t nativenet_set_channel(uint8_t channel);
int16_t nativenet_get_channel();
uint16_t nativenet_set_pan(uint16_t pan);
uint16_t nativenet_get_pan();
void nativenet_switch_to_rx();

View File

@ -0,0 +1,24 @@
#include "tap.h"
#define NNEV_PWRDWN 0x01
#define NNEV_PWRUP 0x02
#define NNEV_MONITOR 0x03
#define NNEV_GETCHAN 0x04
#define NNEV_SETCHAN 0x05
#define NNEV_GETADDR 0x06
#define NNEV_SETADDR 0x07
#define NNEV_GETPAN 0x08
#define NNEV_SETPAN 0x09
#define NNEV_SEND 0x0a
#define NNEV_SWTRX 0x0b
#define NNEV_MAXEV 0x0b
struct rx_buffer_s {
radio_packet_t packet;
char data[NATIVE_MAX_DATA_LENGTH];
};
extern struct rx_buffer_s _nativenet_rx_buffer[];
extern volatile uint8_t rx_buffer_next;
void _nativenet_handle_packet(radio_packet_t *packet);

29
cpu/native/include/tap.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef _TAP_H
#define _TAP_H
#include <net/ethernet.h>
#include "radio/types.h"
/**
* create and/or open tap device "name"
*
* if "name" is an empty string, the kernel chooses a name
* if "name" is an existing device, that device is used
* otherwise a device named "name" is created
*/
int tap_init(char *name);
int send_buf(radio_packet_t *packet);
extern int _native_tap_fd;
extern unsigned char _native_tap_mac[ETHER_ADDR_LEN];
union eth_frame {
struct {
struct ether_header header;
unsigned char data[ETHERMTU];
} field;
unsigned char buffer[ETHER_MAX_LEN];
};
#endif /* _TAP_H */

View File

@ -49,6 +49,10 @@ struct int_handler_t {
static struct int_handler_t native_irq_handlers[255];
char sigalt_stk[SIGSTKSZ];
void native_irq_handler();
void print_thread_sigmask(ucontext_t *cp)
{
sigset_t *p = &cp->uc_sigmask;
@ -133,6 +137,10 @@ unsigned disableIRQ(void)
_native_in_syscall = 1;
DEBUG("disableIRQ()\n");
if (_native_in_isr == 1) {
DEBUG("disableIRQ + _native_in_isr\n");
}
if (sigfillset(&mask) == -1) {
err(1, "disableIRQ(): sigfillset");
}
@ -155,10 +163,13 @@ unsigned disableIRQ(void)
prev_state = native_interrupts_enabled;
native_interrupts_enabled = 0;
if (_native_sigpend > 0) {
// XXX: does this make sense?
if ((_native_sigpend > 0) && (_native_in_isr == 0)) {
DEBUG("\n\n\t\treturn from syscall, calling native_irq_handler\n\n");
_native_in_syscall = 0;
printf("calling swapcontext()\n");
DEBUG("disableIRQ: calling swapcontext()\n");
DEBUG("disableIRQ: _native_cur_ctx == %p, _native_isr_ctx == %p\n", _native_cur_ctx, _native_isr_ctx);
makecontext(&native_isr_context, native_irq_handler, 0);
swapcontext(_native_cur_ctx, _native_isr_ctx);
}
else {
@ -180,6 +191,10 @@ unsigned enableIRQ(void)
_native_in_syscall = 1;
DEBUG("enableIRQ()\n");
if (_native_in_isr == 1) {
DEBUG("enableIRQ + _native_in_isr\n");
}
if (sigprocmask(SIG_SETMASK, &native_sig_set, NULL) == -1) {
err(1, "enableIRQ(): sigprocmask()");
}
@ -189,10 +204,12 @@ unsigned enableIRQ(void)
//print_sigmasks();
//native_print_signals();
if (_native_sigpend > 0) {
if ((_native_sigpend > 0) && (_native_in_isr == 0)) {
DEBUG("\n\n\t\treturn from syscall, calling native_irq_handler\n\n");
_native_in_syscall = 0;
printf("calling swapcontext()\n");
DEBUG("enableIRQ: calling swapcontext()\n");
DEBUG("enableIRQ: _native_cur_ctx == %p, _native_isr_ctx == %p\n", _native_cur_ctx, _native_isr_ctx);
makecontext(&native_isr_context, native_irq_handler, 0);
swapcontext(_native_cur_ctx, _native_isr_ctx);
}
else {
@ -243,6 +260,7 @@ int _native_popsig(void)
nleft = sizeof(int);
i = 0;
_native_in_syscall = 1;
while ((nleft > 0) && ((nread = read(pipefd[0], &sig + i, nleft)) != -1)) {
i += nread;
nleft -= nread;
@ -251,6 +269,7 @@ int _native_popsig(void)
if (nread == -1) {
err(1, "_native_popsig(): read()");
}
_native_in_syscall = 0;
return sig;
}
@ -278,7 +297,7 @@ void native_irq_handler()
DEBUG("ignoring SIGUSR1\n");
}
else {
printf("XXX: no handler for signal %i\n", sig);
DEBUG("XXX: no handler for signal %i\n", sig);
errx(1, "XXX: this should not have happened!\n");
}
}

View File

@ -44,8 +44,15 @@ void lpm_init(void)
void _native_lpm_sleep()
{
#ifdef MODULE_UART0
int retval;
retval = select(1, &_native_uart_rfds, NULL, NULL, NULL);
int retval, nfds;
/* set fds */
nfds = 0;
FD_ZERO(&_native_rfds);
nfds = _native_set_uart_fds();
nfds++;
retval = select(nfds, &_native_rfds, NULL, NULL, NULL);
DEBUG("_native_lpm_sleep: retval: %i\n", retval);
if (retval != -1) {

View File

@ -36,6 +36,10 @@ extern volatile tcb_t *active_thread;
static ucontext_t end_context;
static char __isr_stack[SIGSTKSZ];
#ifdef MODULE_UART0
fd_set _native_rfds;
#endif
/**
* TODO: implement
*/

6
cpu/native/net/Makefile Normal file
View File

@ -0,0 +1,6 @@
INCLUDES += -I$(RIOTBASE)/core/include -I$(RIOTBASE)/sys/include
MODULE = nativenet
include $(MAKEBASE)/Makefile.base

186
cpu/native/net/interface.c Normal file
View File

@ -0,0 +1,186 @@
#include <stdio.h>
#include <err.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#define ENABLE_DEBUG (0)
#include "debug.h"
#include "transceiver.h"
#include "tap.h"
#include "nativenet.h"
#include "nativenet_internal.h"
#include "cpu.h"
struct nativenet_callback_s {
void (*func)(void);
};
static struct nativenet_callback_s _nativenet_callbacks[255];
struct rx_buffer_s _nativenet_rx_buffer[RX_BUF_SIZE];
volatile uint8_t rx_buffer_next;
uint8_t _native_net_chan;
uint16_t _native_net_pan;
uint8_t _native_net_monitor;
static int _native_net_tpid;
radio_address_t _native_net_addr;
/************************************************************************/
/* nativenet.h **********************************************************/
/************************************************************************/
void nativenet_init(int transceiver_pid)
{
DEBUG("nativenet_init(transceiver_pid=%d)", transceiver_pid);
_native_net_pan = 0;
_native_net_chan = 0;
_native_net_monitor = 0;
_native_net_tpid = transceiver_pid;
}
void nativenet_powerdown()
{
return;
}
void nativenet_set_monitor(uint8_t mode)
{
DEBUG("nativenet_set_monitor(mode=%d)\n", mode);
_native_net_monitor = mode;
}
int16_t nativenet_set_channel(uint8_t channel)
{
_native_net_chan = channel;
return _native_net_chan;
}
int16_t nativenet_get_channel()
{
return _native_net_chan;
}
uint16_t nativenet_set_pan(uint16_t pan)
{
_native_net_pan = pan;
return _native_net_pan;
}
uint16_t nativenet_get_pan()
{
return _native_net_pan;
}
int16_t nativenet_set_address(radio_address_t address)
{
_native_net_addr = address;
return _native_net_addr;
}
int16_t nativenet_get_address()
{
return _native_net_addr;
}
uint8_t nativenet_send(radio_packet_t *packet)
{
DEBUG("nativenet_send: Sending packet of length %u to %u: %s\n", packet->length, packet->dst, (char*) packet->data);
if (send_buf(packet) == -1) {
warnx("nativenet_send: error sending packet");
}
return 0;
}
void nativenet_switch_to_rx()
{
return;
}
/************************************************************************/
/* nativenet_internal.h *************************************************/
/************************************************************************/
int _nativenet_register_cb(int event, void *func)
{
if (event > NNEV_MAXEV) {
DEBUG("_nativenet_register_cb: event > NNEV_MAXEV");
return -1;
}
_nativenet_callbacks[event].func = func;
return 0;
}
int _nativenet_unregister_cb(int event)
{
if (event > NNEV_MAXEV) {
DEBUG("_nativenet_unregister_cb: event > NNEV_MAXEV");
return -1;
}
_nativenet_callbacks[event].func = NULL;
return 0;
}
void do_cb(int event)
{
if (event > NNEV_MAXEV) {
DEBUG("do_cb: event > NNEV_MAXEV");
return;
}
if (_nativenet_callbacks[event].func != NULL) {
_nativenet_callbacks[event].func();
}
}
void _nativenet_handle_packet(radio_packet_t *packet)
{
uint8_t dst_addr = packet->dst;
/* address filter / monitor mode */
if (_native_net_monitor == 1) {
DEBUG("_nativenet_handle_packet: monitoring, not filtering address \n");
}
else {
/* own addr check */
if (dst_addr == _native_net_addr) {
DEBUG("_nativenet_handle_packet: accept packet, addressed to us\n");
}
else if (dst_addr == 0) {
DEBUG("_nativenet_handle_packet: accept packet, broadcast\n");
}
else {
DEBUG("_nativenet_handle_packet: discard packet addressed to someone else\n");
return;
}
}
/* copy packet to rx buffer */
memcpy(&_nativenet_rx_buffer[rx_buffer_next].data, packet->data, packet->length);
memcpy(&_nativenet_rx_buffer[rx_buffer_next].packet, packet, sizeof(radio_packet_t));
/* notify transceiver thread if any */
if (_native_net_tpid) {
DEBUG("_nativenet_handle_packet: notifying transceiver thread!\n");
msg_t m;
m.type = (uint16_t) RCV_PKT_NATIVE;
m.content.value = rx_buffer_next;
msg_send_int(&m, _native_net_tpid);
}
else {
DEBUG("_nativenet_handle_packet: no one to notify =(\n");
}
/* shift to next buffer element */
if (++rx_buffer_next == RX_BUF_SIZE) {
rx_buffer_next = 0;
}
}

203
cpu/native/net/tap.c Normal file
View File

@ -0,0 +1,203 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>
#include <err.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <arpa/inet.h>
#ifdef __MACH__
#define _POSIX_C_SOURCE
#include <net/if.h>
#undef _POSIX_C_SOURCE
#include <ifaddrs.h>
#include <net/if_dl.h>
#else
#include <net/if.h>
#include <linux/if_tun.h>
#include <linux/if_ether.h>
#endif
#define ENABLE_DEBUG (0)
#include "debug.h"
#include "cpu.h"
#include "cpu-conf.h"
#include "tap.h"
#include "nativenet.h"
#include "nativenet_internal.h"
#define TAP_BUFFER_LENGTH (ETHER_MAX_LEN)
int _native_marshall_ethernet(uint8_t *framebuf, radio_packet_t *packet);
int _native_tap_fd;
unsigned char _native_tap_mac[ETHER_ADDR_LEN];
void _native_handle_tap_input(void)
{
int nread;
unsigned char buf[TAP_BUFFER_LENGTH];
union eth_frame *f;
radio_packet_t p;
DEBUG("_native_handle_tap_input\n");
/* TODO: check whether this is an input or an output event
TODO: refactor this into general io-signal multiplexer */
_native_in_syscall = 1;
nread = read(_native_tap_fd, buf, TAP_BUFFER_LENGTH);
_native_in_syscall = 0;
DEBUG("_native_handle_tap_input - read %d bytes\n", nread);
if (nread > 0) {
f = (union eth_frame*)&buf;
if (ntohs(f->field.header.ether_type) == NATIVE_ETH_PROTO) {
nread = nread - ETHER_HDR_LEN;
if ((nread - 1) <= 0) {
DEBUG("_native_handle_tap_input: no payload");
}
else {
/* XXX: check overflow */
p.length = (uint8_t)buf[ETHER_HDR_LEN];
p.dst = (uint8_t)buf[ETHER_HDR_LEN+1];
p.data = buf+ETHER_HDR_LEN+2;
DEBUG("_native_handle_tap_input: received packet of length %u for %u: %s\n", p.length, p.dst, (char*) p.data);
_nativenet_handle_packet(&p);
}
}
else {
DEBUG("ignoring non-native frame\n");
}
}
else if (nread == -1) {
err(EXIT_FAILURE, "read");
}
else {
errx(EXIT_FAILURE, "internal error _native_handle_tap_input");
}
}
int _native_marshall_ethernet(uint8_t *framebuf, radio_packet_t *packet)
{
int data_len;
union eth_frame *f;
unsigned char addr[ETHER_ADDR_LEN];
f = (union eth_frame*)framebuf;
addr[0] = addr[1] = addr[2] = addr[3] = addr[4] = addr[5] = (char)0xFF;
memcpy(f->field.header.ether_dhost, addr, ETHER_ADDR_LEN);
memcpy(f->field.header.ether_shost, _native_tap_mac, ETHER_ADDR_LEN);
f->field.header.ether_type = htons(NATIVE_ETH_PROTO);
/* XXX: check overflow */
memcpy(f->field.data+2, packet->data, packet->length);
f->field.data[0] = packet->length;
f->field.data[1] = packet->dst;
data_len = packet->length + 2;
return data_len;
}
int send_buf(radio_packet_t *packet)
{
uint8_t buf[TAP_BUFFER_LENGTH];
int nsent, to_send;
DEBUG("send_buf: Sending packet of length %u to %u: %s\n", packet->length, packet->dst, (char*) packet->data);
to_send = _native_marshall_ethernet(buf, packet);
if ((ETHER_HDR_LEN + to_send) < ETHERMIN) {
DEBUG("padding data! (%d ->", to_send);
to_send = ETHERMIN - ETHER_HDR_LEN;
DEBUG("%d)\n", to_send);
}
DEBUG("send_buf: trying to send %d bytes\n", to_send);
if ((nsent = write(_native_tap_fd, buf, to_send + ETHER_HDR_LEN)) == -1) {;
warn("write");
return -1;
}
return 0;
}
int tap_init(char *name)
{
#ifdef __MACH__ /* OSX */
char clonedev[255] = "/dev/"; /* XXX bad size */
strncpy(clonedev+5, name, 250);
#else /* Linux */
struct ifreq ifr;
char *clonedev = "/dev/net/tun";
#endif
/* implicitly create the tap interface */
if ((_native_tap_fd = open(clonedev , O_RDWR)) == -1) {
err(EXIT_FAILURE, "open(%s)", clonedev);
}
#ifdef __MACH__ /* OSX */
struct ifaddrs* iflist;
if (getifaddrs(&iflist) == 0) {
for (struct ifaddrs *cur = iflist; cur; cur = cur->ifa_next) {
if ((cur->ifa_addr->sa_family == AF_LINK) && (strcmp(cur->ifa_name, name) == 0) && cur->ifa_addr) {
struct sockaddr_dl* sdl = (struct sockaddr_dl*)cur->ifa_addr;
memcpy(_native_tap_mac, LLADDR(sdl), sdl->sdl_alen);
break;
}
}
freeifaddrs(iflist);
}
#else /* Linux */
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
strncpy(ifr.ifr_name, name, IFNAMSIZ);
if (ioctl(_native_tap_fd, TUNSETIFF, (void *)&ifr) == -1) {
warn("ioctl");
if (close(_native_tap_fd) == -1) {
warn("close");
}
exit(EXIT_FAILURE);
}
/* TODO: use strncpy */
strcpy(name, ifr.ifr_name);
/* get MAC address */
memset (&ifr, 0, sizeof (ifr));
snprintf (ifr.ifr_name, sizeof (ifr.ifr_name), "%s", name);
if (ioctl(_native_tap_fd, SIOCGIFHWADDR, &ifr) == -1) {
warn("ioctl");
if (close(_native_tap_fd) == -1) {
warn("close");
}
exit(EXIT_FAILURE);
}
memcpy(_native_tap_mac, ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN);
#endif
/*TODO: check OSX vvv */
/* configure signal handler for fds */
register_interrupt(SIGIO, _native_handle_tap_input);
/* configure fds to send signals on io */
if (fcntl(_native_tap_fd, F_SETOWN, getpid()) == -1) {
err(1, "_native_init_uart0(): fcntl()");
}
/* set file access mode to nonblocking */
if (fcntl(_native_tap_fd, F_SETFL, O_NONBLOCK|O_ASYNC) == -1) {
err(1, "_native_init_uart0(): fcntl()");
}
/*TODO: check OSX ^^^ */
puts("RIOT native tap initialized.");
return _native_tap_fd;
}

View File

@ -15,17 +15,33 @@
*/
#include <stdio.h>
#include <stdlib.h>
#include <err.h>
#include <kernel_internal.h>
#include <cpu.h>
#include "tap.h"
extern void board_init(void);
extern void native_cpu_init(void);
extern void native_interrupt_init(void);
__attribute__((constructor)) static void startup(void)
__attribute__((constructor)) static void startup(int argc, char **argv)
{
#ifdef MODULE_NATIVENET
if (argc < 2) {
printf("usage: %s <tap interface>\n", argv[0]);
exit(EXIT_FAILURE);
}
#endif
native_cpu_init();
native_interrupt_init();
#ifdef MODULE_NATIVENET
tap_init(argv[1]);
#endif
board_init();

47
cpu/native/tapsetup-osx.sh Executable file
View File

@ -0,0 +1,47 @@
#!/bin/sh
COMMAND=${1}
COUNT=${2}
DEFCOUNT="2"
DEFBRNAME="bridge1234"
if [ -z "${USER}" ]; then
echo 'need to export $USER'
exit 1
fi
if [ -z "${COMMAND}" ]; then
echo "usage: $(basename $0) <create [count]|delete>"
exit 1
fi
if [ -z "${BRNAME}" ]; then
BRNAME="${DEFBRNAME}"
fi
if [ "${COMMAND}" = 'create' ]; then
if [ -z "${COUNT}" ]; then
COUNT="${DEFCOUNT}"
fi
sudo ifconfig ${BRNAME} create || exit 1
echo "upping ${BRNAME}"
sudo ifconfig ${BRNAME} up || exit 1
for N in $(seq 0 "$((COUNT - 1))"); do
sudo chown ${USER} /dev/tap${N} || exit 1
echo "start RIOT instance for tap${N} now and hit enter"
read
sudo ifconfig ${BRNAME} addm tap${N} || exit 1
sudo ifconfig tap${N} up
done
elif [ "${COMMAND}" = 'delete' ]; then
sudo ifconfig ${BRNAME} destroy
else
echo 'unknown command'
exit 1
fi
exit 0

50
cpu/native/tapsetup.sh Executable file
View File

@ -0,0 +1,50 @@
#!/bin/sh
COMMAND=${1}
COUNT=${2}
DEFCOUNT="2"
DEFBRNAME="tapbr0"
if [ -z "${USER}" ]; then
echo 'need to export $USER'
exit 1
fi
if [ -z "${COMMAND}" ]; then
echo "usage: $(basename $0) <create [count]|delete>"
exit 1
fi
if [ -z "${BRNAME}" ]; then
BRNAME="${DEFBRNAME}"
fi
if [ "${COMMAND}" = 'create' ]; then
if [ -z "${COUNT}" ]; then
COUNT="${DEFCOUNT}"
fi
sudo brctl addbr ${BRNAME} || exit 1
sudo -s sh -c "echo 1 > /proc/sys/net/ipv6/conf/${BRNAME}/disable_ipv6" || exit 1
sudo ip link set ${BRNAME} up || exit 1
for N in $(seq 0 "$((COUNT - 1))"); do
sudo ip tuntap add dev tap${N} mode tap user ${USER} || exit 1
sudo -s sh -c "echo 1 > /proc/sys/net/ipv6/conf/tap${N}/disable_ipv6" || exit 1
sudo brctl addif ${BRNAME} tap${N} || exit 1
sudo ip link set tap${N} up || exit 1
done
elif [ "${COMMAND}" = 'delete' ]; then
for IF in $(ls /sys/class/net/${BRNAME}/brif); do
sudo ip link delete "${IF}"
done
sudo ip link set ${BRNAME} down
sudo brctl delbr ${BRNAME}
else
echo 'unknown command'
exit 1
fi
exit 0

View File

@ -56,6 +56,11 @@
#define PAYLOAD_SIZE (MC1322X_MAX_DATA_LENGTH)
#endif
#endif
#ifdef MODULE_NATIVENET
#if (NATIVE_MAX_DATA_LENGTH > PAYLOAD_SIZE)
#define PAYLOAD_SIZE (NATIVE_MAX_DATA_LENGTH)
#endif
#endif
/* The maximum of threads to register */
#define TRANSCEIVER_MAX_REGISTERED (4)
@ -71,6 +76,7 @@
#define TRANSCEIVER_CC1020 (0x02) ///< CC1020 transceivers
#define TRANSCEIVER_CC2420 (0x04) ///< CC2420 transceivers
#define TRANSCEIVER_MC1322X (0x08) ///< MC1322X transceivers
#define TRANSCEIVER_NATIVE (0x10) ///< NATIVE transceivers
/**
* @brief Data type for transceiver specification
@ -86,6 +92,7 @@ enum transceiver_msg_type_t {
RCV_PKT_CC1100, ///< packet was received by CC1100 transceiver
RCV_PKT_CC2420, ///< packet was received by CC2420 transceiver
RCV_PKT_MC1322X, ///< packet was received by mc1322x transceiver
RCV_PKT_NATIVE, ///< packet was received by native transceiver
/* Message types for transceiver <-> upper layer communication */
PKT_PENDING, ///< packet pending in transceiver buffer

View File

@ -13,6 +13,10 @@ ifneq (,$(findstring cc110x,$(USEMODULE)))
INCLUDES += -I$(RIOTBASE)/drivers/cc110x/
SRC += sc_cc1100.c
endif
ifneq (,$(findstring nativenet,$(USEMODULE)))
INCLUDES += -I$(RIOTBASE)/cpu/native/include
SRC += sc_nativenet.c
endif
ifneq (,$(findstring mci,$(USEMODULE)))
SRC += sc_disk.c
endif

View File

@ -0,0 +1,127 @@
/**
* Shell commands for native transceiver
*
* Copyright (C) 2013 Ludwig Ortmann.
*
* This file subject to the terms and conditions of the GNU Lesser General
* Public License. See the file LICENSE in the top level directory for more
* details.
*
* @ingroup shell_commands
* @{
* @file sc_nativenet.c
* @brief provides shell commands to configure nativenet transceiver
* @author Ludwig Ortmann <ludwig.ortmann@fu-berlin.de>
* @}
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include "transceiver.h"
#include "nativenet.h"
#include "msg.h"
#define TEXT_SIZE (255) /* XXX: this aint enough for everybody */
char text_msg[TEXT_SIZE];
msg_t mesg;
transceiver_command_t tcmd;
void _nativenet_get_set_address_handler(char *addr)
{
int16_t a;
tcmd.transceivers = TRANSCEIVER_NATIVE;
tcmd.data = &a;
mesg.content.ptr = (char *) &tcmd;
a = (int16_t)atoi(addr + 5);
if (strlen(addr) > 5) {
printf("[nativenet] trying to set address %" PRIi16 "\n", a);
mesg.type = SET_ADDRESS;
}
else {
mesg.type = GET_ADDRESS;
}
msg_send_receive(&mesg, &mesg, transceiver_pid);
printf("[nativenet] got address: %i\n", a);
}
void _nativenet_get_set_channel_handler(char *chan)
{
int16_t c;
tcmd.transceivers = TRANSCEIVER_NATIVE;
tcmd.data = &c;
mesg.content.ptr = (char *) &tcmd;
c = atoi(chan + 5);
if (strlen(chan) > 5) {
printf("[nativenet] Trying to set channel %i\n", c);
mesg.type = SET_CHANNEL;
}
else {
mesg.type = GET_CHANNEL;
}
msg_send_receive(&mesg, &mesg, transceiver_pid);
printf("[nativenet] Got channel: %i\n", c);
}
void _nativenet_send_handler(char *pkt)
{
radio_packet_t p;
uint32_t response;
uint16_t addr;
char *tok;
tcmd.transceivers = TRANSCEIVER_NATIVE;
tcmd.data = &p;
tok = strtok(pkt + 7, " ");
if (tok) {
addr = atoi(tok);
tok = strtok(NULL, " ");
if (tok) {
memset(text_msg, 0, TEXT_SIZE);
memcpy(text_msg, tok, strlen(tok));
p.data = (uint8_t *) text_msg;
p.length = strlen(text_msg) + 1;
p.dst = addr;
mesg.type = SND_PKT;
mesg.content.ptr = (char *)&tcmd;
printf("[nativenet] Sending packet of length %u to %u: %s\n", p.length, p.dst, (char*) p.data);
msg_send_receive(&mesg, &mesg, transceiver_pid);
response = mesg.content.value;
printf("[nativenet] Packet sent: %" PRIu32 "\n", response);
return;
}
}
puts("Usage:\ttxtsnd <ADDR> <MSG>");
}
void _nativenet_monitor_handler(char *mode)
{
unsigned int m;
tcmd.transceivers = TRANSCEIVER_NATIVE;
tcmd.data = &m;
mesg.content.ptr = (char *) &tcmd;
m = atoi(mode + 8);
if (strlen(mode) > 8) {
printf("Setting monitor mode: %u\n", m);
mesg.type = SET_MONITOR;
msg_send(&mesg, transceiver_pid, 1);
}
else {
puts("Usage:\nmonitor <MODE>");
}
}

View File

@ -70,6 +70,15 @@ extern void _cc2420_monitor_handler(char *mode);
#endif
#endif
#ifdef MODULE_TRANSCEIVER
#ifdef MODULE_NATIVENET
extern void _nativenet_get_set_address_handler(char *addr);
extern void _nativenet_get_set_channel_handler(char *chan);
extern void _nativenet_send_handler(char *pkt);
extern void _nativenet_monitor_handler(char *mode);
#endif
#endif
#ifdef MODULE_MCI
extern void _get_sectorsize(char *unused);
extern void _get_blocksize(char *unused);
@ -123,6 +132,14 @@ const shell_command_t _shell_command_list[] = {
{"monitor", "Enables or disables address checking for the CC2420 transceiver", _cc2420_monitor_handler},
#endif
#endif
#ifdef MODULE_TRANSCEIVER
#ifdef MODULE_NATIVENET
{"addr", "Gets or sets the address for the native transceiver", _nativenet_get_set_address_handler},
{"chan", "Gets or sets the channel for the native transceiver", _nativenet_get_set_channel_handler},
{"txtsnd", "Sends a text message to a given node via the native transceiver", _nativenet_send_handler},
{"monitor", "Enables or disables address checking for the native transceiver", _nativenet_monitor_handler},
#endif
#endif
#ifdef MODULE_MCI
{DISK_READ_SECTOR_CMD, "Reads the specified sector of inserted memory card", _read_sector},
{DISK_READ_BYTES_CMD, "Reads the specified bytes from inserted memory card", _read_bytes},

View File

@ -23,6 +23,7 @@
#include "thread.h"
#include "msg.h"
#include "irq.h"
#include "radio/types.h"
@ -47,6 +48,11 @@
#include "maca_packet.h"
#endif
#ifdef MODULE_NATIVENET
#include "nativenet.h"
#include "nativenet_internal.h"
#endif
#define ENABLE_DEBUG (0)
#if ENABLE_DEBUG
#undef TRANSCEIVER_STACK_SIZE
@ -97,6 +103,8 @@ void cc1100_packet_monitor(void *payload, int payload_size, protocol_t protocol,
void receive_cc1100_packet(radio_packet_t *trans_p);
#elif MODULE_CC2420
static void receive_cc2420_packet(radio_packet_t *trans_p);
#elif MODULE_NATIVENET
static void receive_nativenet_packet(radio_packet_t *trans_p);
#endif
static uint8_t send_packet(transceiver_type_t t, void *pkt);
static int16_t get_channel(transceiver_type_t t);
@ -134,7 +142,7 @@ void transceiver_init(transceiver_type_t t)
reg[i].pid = 0;
}
/* check if a non defined bit is set */
if (t & ~(TRANSCEIVER_CC1100 | TRANSCEIVER_CC2420 | TRANSCEIVER_MC1322X)) {
if (t & ~(TRANSCEIVER_CC1100 | TRANSCEIVER_CC2420 | TRANSCEIVER_MC1322X | TRANSCEIVER_NATIVE)) {
puts("Invalid transceiver type");
}
else {
@ -171,6 +179,11 @@ int transceiver_start(void)
else if (transceivers & TRANSCEIVER_MC1322X) {
maca_init();
}
#endif
#ifdef MODULE_NATIVENET
else if (transceivers & TRANSCEIVER_NATIVE) {
nativenet_init(transceiver_pid);
}
#endif
return transceiver_pid;
}
@ -222,6 +235,7 @@ void run(void)
case RCV_PKT_CC1100:
case RCV_PKT_CC2420:
case RCV_PKT_MC1322X:
case RCV_PKT_NATIVE:
receive_packet(m.type, m.content.value);
break;
case SND_PKT:
@ -348,6 +362,12 @@ static void receive_packet(uint16_t type, uint8_t pos)
#else
trans_p = NULL;
type = TRANSCEIVER_NONE;
#endif
}
else if (type == RCV_PKT_NATIVE) {
#ifdef MODULE_NATIVENET
receive_nativenet_packet(trans_p);
type = TRANSCEIVER_NATIVE;
#endif
}
else {
@ -452,6 +472,26 @@ void receive_mc1322x_packet(radio_packet_t *trans_p) {
#endif
#ifdef MODULE_NATIVENET
void receive_nativenet_packet(radio_packet_t *trans_p) {
unsigned state;
radio_packet_t *p = &_nativenet_rx_buffer[rx_buffer_pos].packet;
/* disable interrupts while copying packet */
state = disableIRQ();
DEBUG("Handling nativenet packet\n");
memcpy(trans_p, p, sizeof(radio_packet_t));
memcpy((void*) &(data_buffer[transceiver_buffer_pos * PAYLOAD_SIZE]), p->data, p->length);
trans_p->data = (uint8_t*) &(data_buffer[transceiver_buffer_pos * PAYLOAD_SIZE]);
DEBUG("Packet %p was from %hu to %hu, size: %u\n", trans_p, trans_p->src, trans_p->dst, trans_p->length);
/* reset interrupts */
restoreIRQ(state);
}
#endif
/*------------------------------------------------------------------------------------*/
/*
* @brief Sends a radio packet to the receiver
@ -526,6 +566,11 @@ static uint8_t send_packet(transceiver_type_t t, void *pkt)
maca_set_tx_packet( maca_pkt );
res = 1;
break;
#endif
#ifdef MODULE_NATIVENET
case TRANSCEIVER_NATIVE:
res = nativenet_send(&p);
break;
#endif
default:
puts("Unknown transceiver");
@ -565,6 +610,10 @@ static int16_t set_channel(transceiver_type_t t, void *channel)
case TRANSCEIVER_MC1322X:
maca_set_channel(c);
return c; ///< TODO: should be changed! implement get channel
#endif
#ifdef MODULE_NATIVENET
case TRANSCEIVER_NATIVE:
return nativenet_set_channel(c);
#endif
default:
return -1;
@ -593,8 +642,14 @@ static int16_t get_channel(transceiver_type_t t)
case TRANSCEIVER_CC2420:
return cc2420_get_channel();
#endif
#ifdef MODULE_MC1322X
case TRANSCEIVER_MC1322X:
///< TODO:implement return maca_get_channel();
#endif
#ifdef MODULE_NATIVENET
case TRANSCEIVER_NATIVE:
return nativenet_get_channel();
#endif
default:
return -1;
}
@ -615,6 +670,10 @@ static uint16_t set_pan(transceiver_type_t t, void *pan) {
#ifdef MODULE_CC2420
case TRANSCEIVER_CC2420:
return cc2420_set_pan(c);
#endif
#ifdef MODULE_NATIVENET
case TRANSCEIVER_NATIVE:
return nativenet_set_pan(c);
#endif
default:
/* get rid of compiler warning about unused variable */
@ -635,6 +694,10 @@ static uint16_t get_pan(transceiver_type_t t) {
#ifdef MODULE_CC2420
case TRANSCEIVER_CC2420:
return cc2420_get_pan();
#endif
#ifdef MODULE_NATIVENET
case TRANSCEIVER_NATIVE:
return nativenet_get_pan();
#endif
default:
return -1;
@ -666,6 +729,10 @@ static int16_t get_address(transceiver_type_t t)
#ifdef MODULE_MC1322X
case TRANSCEIVER_MC1322X:
return maca_get_address();
#endif
#ifdef MODULE_NATIVENET
case TRANSCEIVER_NATIVE:
return nativenet_get_address();
#endif
default:
return -1;
@ -700,6 +767,10 @@ static int16_t set_address(transceiver_type_t t, void *address)
#ifdef MODULE_MC1322X
case TRANSCEIVER_MC1322X:
return maca_set_address(addr);
#endif
#ifdef MODULE_NATIVENET
case TRANSCEIVER_NATIVE:
return nativenet_set_address(addr);
#endif
default:
return -1;
@ -724,6 +795,11 @@ static void set_monitor(transceiver_type_t t, void *mode)
case TRANSCEIVER_CC2420:
cc2420_set_monitor(*((uint8_t*) mode));
break;
#endif
#ifdef MODULE_NATIVENET
case TRANSCEIVER_NATIVE:
nativenet_set_monitor(*((uint8_t*) mode));
break;
#endif
default:
break;
@ -753,6 +829,11 @@ static void powerdown(transceiver_type_t t)
case TRANSCEIVER_MC1322X:
maca_off();
break;
#endif
#ifdef MODULE_NATIVENET
case TRANSCEIVER_NATIVE:
nativenet_powerdown();
break;
#endif
default:
break;
@ -772,6 +853,11 @@ static void switch_to_rx(transceiver_type_t t)
case TRANSCEIVER_CC2420:
cc2420_switch_to_rx();
break;
#endif
#ifdef MODULE_NATIVENET
case TRANSCEIVER_NATIVE:
nativenet_switch_to_rx();
break;
#endif
default:
break;