diff --git a/cpu/native/Makefile b/cpu/native/Makefile index 4b642a35e1..34ae69f430 100644 --- a/cpu/native/Makefile +++ b/cpu/native/Makefile @@ -1,6 +1,6 @@ MODULE = cpu -INCLUDES = -I../include -I$(RIOTBASE)/core/include +INCLUDES = -I../include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/cc110x_ng/include DIRS = ifneq (,$(findstring rtc,$(USEMODULE))) DIRS += rtc diff --git a/cpu/native/README b/cpu/native/README new file mode 100644 index 0000000000..ccd8cd1136 --- /dev/null +++ b/cpu/native/README @@ -0,0 +1,26 @@ +If you compile RIOT for the native cpu and include the cc110x_ng +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. diff --git a/cpu/native/cc110x_ng/cc1100-sim.c b/cpu/native/cc110x_ng/cc1100-sim.c new file mode 100644 index 0000000000..3644e0ab09 --- /dev/null +++ b/cpu/native/cc110x_ng/cc1100-sim.c @@ -0,0 +1,756 @@ +#include +#include +#include +#include +#include + +#include "debug.h" + +#include "cc110x_ng.h" +#include "cc110x-internal.h" /* CC1100_READ_BURST etc. */ +#include "tap.h" +#include "cc1100sim.h" + +#define CC1100_EVENT_SET_POWER 0x01 +#define CC1100_EVENT_SET_CHANNEL 0x02 + +/** + * simplified states according to cc1100.pdf figure 5, page 23 + */ +#define STATE_IDLE 0x00 +/* SPWD || WOR -> STATE_SLEEP + * SXOFF -> STATE_XTALOFF + * SCAL -> STATE_FREQ_SCAL + * SRX || STX || WOR -> STATE_FREQ_SST */ +#define STATE_SLEEP 0x01 /* CSn=0 -> STATE_IDLE */ +#define STATE_XTALOFF 0x02 /* CSn=0 -> STATE_IDLE */ +#define STATE_FREQ_SCAL 0x03 /* -> STATE_IDLE */ + +#define STATE_FREQ_SST 0x04 +/* SFSTXON -> STATE_FREQ_SON + * STX -> STATE_TX + * SRX||WOR -> STATE_RX */ +#define STATE_FREQ_SON 0x05 /* STX -> STATE_TX */ +#define STATE_TX 0x06 +/* TXOFF_MODE = 11 || SRX -> STATE_RX + * TXOFF_MODE = 01 -> STATE_FREQ_SON + * STATE_TX_FFUF */ +#define STATE_TX_FFUF 0x07 /* SFTX -> STATE_IDLE */ +#define STATE_RX 0x08 +/* RXOFF_MODE = 10 || STX -> STATE_TX + * RXOFF_MODE = 00 -> STATE_FREQ_SON + * -> STATE_TX_FFUF */ +#define STATE_RX_FFOF 0x09 /* SFRX -> STATE_IDLE */ + + +/** + * status byte state bits according to cc1100.pdf, page 26, table 17 + */ +#define M_IDLE 0x00 +#define M_RX 0x10 +#define M_TX 0x20 +#define M_FSTXON 0x30 +#define M_CALIBRATE 0x40 +#define M_SETTLING 0x50 +#define M_RXFIFO_OVERFLOW 0x60 +#define M_TXFIFO_UNDERFLOW 0x70 + +#define MASK_STATE 0x70 +#define MASK_CHIP_RDYn 0x80 +#define MASK_FIFO_BYTES_AVAILABLE 0x0F + +#if 0 +static uint8_t internal_state; /* according to table 17 */ +static uint8_t _native_cc1100_spi; /* the pins */ +/* one byte goes in, one byte goes out */ +static uint8_t _native_cc1100_serial_io; +#endif + +uint8_t addr; /* as sent in header */ +uint8_t _native_cc110x_state; + + +uint8_t configuration_registers[((0x2E)+1)]; /* address 0x00 - 0x2E */ +uint8_t configuration_registers_idx; /* for burst access */ +uint8_t status_registers[((0x3D-0x30)+1)]; /* address 0x30 - 0x3D */ +/* command strobes reside at the addresses 0x30 to 0x3D when writing */ +uint8_t patable[8]; /* address 0x3E */ +uint8_t patable_idx; /* for burst access */ + +uint8_t tx_fifo[64]; +uint8_t tx_fifo_idx; +uint8_t rx_fifo[64]; +uint8_t rx_fifo_idx; + +int native_cc110x_gd0; +int native_cc110x_gd1; +int native_cc110x_gd2; +int native_cc110x_gd0_enabled; +int native_cc110x_gd2_enabled; + +/* static uint8_t address_space[0xFF]; */ +/* static uint8_t address_space_pointer; */ + +/* network layer handlers for cc1100 events: */ +struct cc1100_callback_t { + void (*func)(void); +}; +static struct cc1100_callback_t _native_cc1100_callbacks[255]; + +/* cc1100 default configuration */ +unsigned char cc1100_reset_configuration_regs[] = { + 0x29, /* IOCFG2 */ + 0x2E, /* IOCFG1 */ + 0x3F, /* IOCFG0 */ + 0x07, /* FIFOTHR */ + 0xD3, /* SYNC1 */ + 0x91, /* SYNC0 */ + 0xFF, /* PKTLEN */ + 0x04, /* PKTCTRL1 */ + 0x45, /* PKTCTRL0 */ + 0x00, /* ADDR */ + 0x00, /* CHANNR */ + 0x0F, /* FSCTRL1 */ + 0x00, /* FSCTRL0 */ + 0x1E, /* FREQ2 */ + 0xC4, /* FREQ1 */ + 0xEC, /* FREQ0 */ + 0x2C, /* MDMCFG4 */ + 0x22, /* MDMCFG3 */ + 0x02, /* MDMCFG2 */ + 0x22, /* MDMCFG1 */ + 0xF8, /* MDMCFG0 */ + 0x47, /* DEVIATN */ + 0x07, /* MCSM2 */ + 0x30, /* MCSM1 */ + 0x04, /* MCSM0 */ + 0x66, /* FOCCFG */ + 0x66, /* BSCFG */ + 0x03, /* AGCCTRL2 */ + 0x40, /* AGCCTRL1 */ + 0x91, /* AGCCTRL0 */ + 0x87, /* WOREVT1 */ + 0x6B, /* WOREVT0 */ + 0xF8, /* WORCTRL */ + 0x56, /* FREND1 */ + 0x10, /* FREND0 */ + 0xA9, /* FSCAL3 */ + 0x0A, /* FSCAL2 */ + 0x20, /* FSCAL1 */ + 0x0D, /* FSCAL0 */ + 0x41, /* RCCTRL1 */ + 0x00, /* RCCTRL0 */ + 0x59, /* FSTEST */ + 0x7F, /* PTEST */ + 0x3F, /* AGCTEST */ + 0x88, /* TEST2 */ + 0x31, /* TEST1 */ + 0x0B /* TEST0 */ +}; + +/* cc1100 default status */ +unsigned char cc1100_reset_status_regs[] = { + 0x00, /* PARTNUM */ + 0x03, /* VERSION */ + 0x00, /* FREQEST */ + 0x00, /* LQI */ + 0x00, /* RSSI */ + 0x00, /* MARCSTATE */ + 0x00, /* WORTIME1 */ + 0x00, /* WORTIME0 */ + 0x00, /* PKTSTATUS */ + 0x00, /* VCO_VC_DAC */ + 0x00, /* TXBYTES */ + 0x00, /* RXBYTES */ + 0x00, /* RCCTRL1_STATUS */ + 0x00 /* RCCTRL0_STATUS */ +}; + +void do_sres(void) +{ + int i; + + for (i = 0; i < 0x2E; i++) { + configuration_registers[i] = cc1100_reset_configuration_regs[i]; + } + for (i = 0; i < (0x3D - 0x30); i++) { + status_registers[i] = cc1100_reset_status_regs[i]; + } + for (i = 1; i < 8; i++) { + patable[i] = 0; + } +} + +uint8_t do_strobe(void) +{ + DEBUG("issue strobe command\n"); + switch (addr) { + case CC1100_SRES: + do_sres(); + break; + case CC1100_SFSTXON: + //warnx("do_strobe: not implemented: CC1100_SFSTXON"); + break; + case CC1100_SXOFF: + //warnx("do_strobe: not implemented: CC1100_SXOFF"); + break; + case CC1100_SCAL: + //warnx("do_strobe: not implemented: CC1100_SCAL"); + break; + case CC1100_SRX: + //warnx("do_strobe: not implemented: CC1100_SRX"); + break; + case CC1100_STX: + //warnx("do_strobe: not properly implemented: CC1100_STX"); + if (((status_registers[CC1100_TXBYTES - 0x30] & 0x7F) > 0) && (send_buf() == -1)) { + native_cc110x_gd2 = 1; + } + else { + native_cc110x_gd2 = 1; + } + break; + case CC1100_SIDLE: + //warnx("do_strobe: not implemented: CC1100_SIDLE "); + break; + case CC1100_SAFC: + //warnx("do_strobe: not implemented: CC1100_SAFC"); + break; + case CC1100_SWOR: + //warnx("do_strobe: not implemented: CC1100_SWOR"); + break; + case CC1100_SPWD: + //warnx("do_strobe: not implemented: CC1100_SPWD"); + break; + case CC1100_SFRX: + status_registers[CC1100_RXBYTES - 0x30] = 0x00; + rx_fifo_idx = 0x00; + break; + case CC1100_SFTX: + status_registers[CC1100_TXBYTES - 0x30] = 0x00; + tx_fifo_idx = 0x00; + break; + case CC1100_SWORRST: + //warnx("do_strobe: not implemented: CC1100_SWORRST"); + break; + case CC1100_SNOP: + //warnx("do_strobe: not implemented: CC1100_SNOP"); + break; + default: + errx(EXIT_FAILURE, "do_strobe: internal error"); + } + return addr; +} + +uint8_t parse_header(uint8_t c) +{ + DEBUG("parse_header(0x%02X): ", c); + + addr = c & 0x3F; /* bits [5..0] */ + uint8_t mode = c & 0xC0; /* bits [76]*/ + + /* set access mode, set status bute (c) */ + switch (mode) { + case CC1100_READ_BURST: + /* status registers can only be read single */ + if ((addr >= 0x30) && (addr <= 0x3D)) { + DEBUG(" CC1100_READ_SINGLE"); + _native_cc110x_state = STATE_READ_S; + } + else { + DEBUG(" CC1100_READ_BURST"); + _native_cc110x_state = STATE_READ_B; + } + c = status_registers[CC1100_RXBYTES - 0x30] - rx_fifo_idx; + break; + case CC1100_WRITE_BURST: + DEBUG(" CC1100_WRITE_BURST"); + _native_cc110x_state = STATE_WRITE_B; + c = 0x0F - status_registers[CC1100_TXBYTES - 0x30]; + break; + case CC1100_READ_SINGLE: + DEBUG(" CC1100_READ_SINGLE"); + _native_cc110x_state = STATE_READ_S; + c = status_registers[CC1100_RXBYTES - 0x30] - rx_fifo_idx; + break; + default: + DEBUG(" CC1100_WRITE_SINGLE"); + _native_cc110x_state = STATE_WRITE_S; + c = 0x0F - status_registers[CC1100_TXBYTES - 0x30]; + } + if (addr <= 0x2E) { + DEBUG(" configuration register"); + } + else if ((addr >= 0x30) && (addr <= 0x3D)) { + if ((_native_cc110x_state == STATE_WRITE_B) || (_native_cc110x_state == STATE_WRITE_S)) { + DEBUG(" strobe command"); + /* strobe commands get executed directly */ + do_strobe(); + } + else { + DEBUG(" status register"); + } + } + else if (addr == 0x3E) { + DEBUG(" patable"); + } + else if (addr == 0x3F) { + if ((_native_cc110x_state == STATE_WRITE_B) || (_native_cc110x_state == STATE_WRITE_S)) { + DEBUG(" TX"); + } + else { + DEBUG(" RX"); + } + } + else { + errx(EXIT_FAILURE, "parse_header: unhandled addr: 0x%02X", addr); + } + DEBUG("==\n"); + + return c; +} + +uint8_t read_single(uint8_t c) +{ + DEBUG("read_single\n"); + if (addr <= 0x2E) { + DEBUG("read configuration_registers\n"); + return configuration_registers[addr++]; + } + else if ((addr >= 0x30) && (addr <= 0x3D)) { + DEBUG("read status_registers\n"); + if (addr == 0x3B) { + DEBUG("\n\n\t\treturning RXBYTES: %d\n\n", status_registers[(addr) - 0x30]); + } + else { + DEBUG("\n\n\t\treturning: %d\n\n", status_registers[(addr) - 0x30]); + } + return status_registers[(addr++) - 0x30]; + } + else if (addr == 0x3E) { + DEBUG("read patable\n"); + if (patable_idx > 7) { + patable_idx = 0; + } + return patable[patable_idx++]; + } + else if (addr == 0x3F) { + DEBUG("read rx fifo\n"); + int off = (status_registers[CC1100_RXBYTES - 0x30] - rx_fifo_idx); + switch (off) { + case 0: + /* CRC OK */ + return CRC_OK; + case -1: + /* CRC OK */ + return 0xFF; + } + if (rx_fifo_idx >= status_registers[CC1100_RXBYTES - 0x30]) { + //warnx("read_single: buffer empty"); + } + return rx_fifo[rx_fifo_idx++]; + } + else { + errx(EXIT_FAILURE, "read_single: unhandled addr: 0x%02X", addr); + } + return c; +} + +uint8_t read_burst(uint8_t c) +{ + DEBUG(" read_burst: "); + if (c != 0xFF) { + warnx("read_burst: unexpected value"); + } + + if (addr <= 0x2E) { + DEBUG("read configuration_registers\n"); + return configuration_registers[addr++]; + } + else if ((addr >= 0x30) && (addr <= 0x3D)) { + DEBUG("read status_registers\n"); + return status_registers[(addr++) - 0x30]; + } + else if (addr == 0x3E) { + DEBUG("read patable\n"); + if (patable_idx > 7) { + patable_idx = 0; + } + return patable[patable_idx++]; + } + else if (addr == 0x3F) { + DEBUG("read rx fifo\n"); + int off = (status_registers[CC1100_RXBYTES - 0x30] - rx_fifo_idx); + switch (off) { + case 0: + /* CRC OK */ + return CRC_OK; + case -1: + /* CRC OK */ + return 0xFF; + } + if (rx_fifo_idx >= status_registers[CC1100_RXBYTES - 0x30]) { + //warnx("read_burst: buffer empty"); + } + return rx_fifo[rx_fifo_idx++]; + } + else { + errx(EXIT_FAILURE, "write_single: unhandled addr: 0x%02X", addr); + } +} + +void do_write_conf(uint8_t c) +{ + DEBUG("write configuration register\n"); + configuration_registers[addr] = c; + if (_native_cc1100_callbacks[addr].func != NULL) { + DEBUG("calling cc1100 callback for %i\n", addr); + _native_cc1100_callbacks[addr].func(); + } +} + +void do_write_patable(uint8_t c) +{ + DEBUG("write patable\n"); + patable[patable_idx] = c; +} +void do_write_tx(uint8_t c) +{ + DEBUG("write TX\n"); + if (status_registers[CC1100_TXBYTES - 0x30] == CC1100_FIFO_LENGTH) { + errx(EXIT_FAILURE, "do_write_tx: buffer too small"); + } + tx_fifo[tx_fifo_idx++] = c; + status_registers[CC1100_TXBYTES - 0x30]++; +} + +uint8_t write_single(uint8_t c) +{ + DEBUG("write_single\n"); + + if (addr <= 0x2E) { + do_write_conf(c); + } + else if ((addr >= 0x30) && (addr <= 0x3D)) { + do_strobe(); + } + else if (addr == 0x3E) { + do_write_patable(c); + } + else if (addr == 0x3F) { + do_write_tx(c); + } + else { + errx(EXIT_FAILURE, "write_single: unhandled addr: 0x%02X", addr); + } + + return 0; +} + +uint8_t write_burst(uint8_t c) +{ + DEBUG("write_burst\n"); + + if (addr <= 0x2E) { + do_write_conf(c); + addr++; + } + else if ((addr >= 0x30) && (addr <= 0x3D)) { + do_strobe(); + addr++; + } + else if (addr == 0x3E) { + DEBUG("write patable\n"); + } + else if (addr == 0x3F) { + do_write_tx(c); + } + else { + errx(EXIT_FAILURE, "write_single: unhandled addr: 0x%02X", addr); + } + + return 0; +} + +uint8_t do_txrx(uint8_t c) +{ + switch (_native_cc110x_state) { + case STATE_SEL: + c = parse_header(c); + break; + case STATE_WRITE_B: + c = write_burst(c); + break; + case STATE_READ_B: + c = read_burst(c); + break; + case STATE_READ_S: + c = read_single(c); + _native_cc110x_state = STATE_SEL; + break; + case STATE_WRITE_S: + c = write_single(c); + _native_cc110x_state = STATE_SEL; + break; + case STATE_NULL: + //warnx("received command(?) in NULL state"); + c = 0x00; + default: + errx(EXIT_FAILURE, "funny cc110x_ng state"); + } + return c; +} + +void _native_cc1100_register_callback(int event, void *cb) +{ + _native_cc1100_callbacks[event].func = cb; +} + +void _native_cc1100_handle_packet(unsigned char *buf, int size) +{ + unsigned char dst_addr; + + dst_addr = buf[1]; + + /* packet automation */ + + /* monitor mode */ + if ((configuration_registers[CC1100_PKTCTRL1] & 0x03) == 0x00) { + DEBUG("_native_cc1100_handle_packet: not filtering address\n"); + } + /* address filter */ + else { + /* own addr check */ + if (dst_addr == configuration_registers[CC1100_ADDR]) { + DEBUG("_native_cc1100_handle_packet: accept packet, addressed to us\n"); + } + /* 0x00 only broadcast */ + else if ( + ((configuration_registers[CC1100_PKTCTRL1] & 0x03) == 0x02) && + (dst_addr == 0x00) + ) { + DEBUG("_native_cc1100_handle_packet: accept packet, broadcast\n"); + } + /* 0x00 only broadcast */ + else if ( + ((configuration_registers[CC1100_PKTCTRL1] & 0x03) == 0x03) && + ((dst_addr == 0x00) || (dst_addr == 0xFF)) + ) { + DEBUG("_native_cc1100_handle_packet: accept packet, broadcast\n"); + } + else { + DEBUG("_native_cc1100_handle_packet: discard packet addressed to someone else\n"); + return; + } + } + /* length filter */ + /* variable packet length */ + if ((configuration_registers[CC1100_PKTCTRL0] & 0x03) == 0x01) { + if (size > configuration_registers[CC1100_PKTLEN]) { + DEBUG("_native_cc1100_handle_packet: discard packet longer than CC1100_PKTLEN\n"); + return; + } + else { + DEBUG("_native_cc1100_handle_packet: accept packet <= CC1100_PKTLEN\n"); + } + } + /* fixed packet length */ + else if ((configuration_registers[CC1100_PKTCTRL0] & 0x03) == 0x00) { + if (size != configuration_registers[CC1100_PKTLEN]) { + DEBUG("_native_cc1100_handle_packet: discard packet, size differs from CC1100_PKTLEN\n"); + return; + } + else { + DEBUG("_native_cc1100_handle_packet: accept packet == CC1100_PKTLEN\n"); + } + } + else { + errx(EXIT_FAILURE, "_native_cc1100_handle_packet: packet length mode not supported"); + } + + /* copy packet to rx_fifo */ + /* XXX: handle overflow */ + rx_fifo_idx = 0; + memcpy(rx_fifo, buf, size); + status_registers[CC1100_RXBYTES - 0x30] = size; + DEBUG("_native_cc1100_handle_packet: got %d bytes payload\n", size); + + /* toggle interrupt */ + cc110x_gdo2_irq(); +} + +#if 0 /* future ahead */ + +void step_state_idle(void) +{ + switch (addr) { + /* configuration registers: */ + case CC1100_IOCFG2: + case CC1100_IOCFG1: + case CC1100_IOCFG0: + case CC1100_FIFOTHR: + case CC1100_SYNC1: + case CC1100_SYNC0: + case CC1100_PKTLEN: + case CC1100_PKTCTRL1: + case CC1100_PKTCTRL0: + case CC1100_ADDR: + case CC1100_CHANNR: + case CC1100_FSCTRL1: + case CC1100_FSCTRL0: + case CC1100_FREQ2: + case CC1100_FREQ1: + case CC1100_FREQ0: + case CC1100_MDMCFG4: + case CC1100_MDMCFG3: + case CC1100_MDMCFG2: + case CC1100_MDMCFG1: + case CC1100_MDMCFG0: + case CC1100_DEVIATN: + case CC1100_MCSM2: + case CC1100_MCSM1: + case CC1100_MCSM0: + case CC1100_FOCCFG: + case CC1100_BSCFG: + case CC1100_AGCCTRL2: + case CC1100_AGCCTRL1: + case CC1100_AGCCTRL0: + case CC1100_WOREVT1: + case CC1100_WOREVT0: + case CC1100_WORCTRL: + case CC1100_FREND1: + case CC1100_FREND0: + case CC1100_FSCAL3: + case CC1100_FSCAL2: + case CC1100_FSCAL1: + case CC1100_FSCAL0: + case CC1100_RCCTRL1: + case CC1100_RCCTRL0: + case CC1100_FSTEST: + case CC1100_PTEST: + case CC1100_AGCTEST: + case CC1100_TEST2: + case CC1100_TEST1: + case CC1100_TEST0: + /* command strobes */ + case CC1100_SRES: + case CC1100_SFSTXON: + case CC1100_SXOFF: + case CC1100_SCAL: + case CC1100_SRX: + case CC1100_STX: + case CC1100_SIDLE: + case CC1100_SAFC: + case CC1100_SWOR: + case CC1100_SPWD: + case CC1100_SFRX: + case CC1100_SFTX: + case CC1100_SWORRST: + case CC1100_SNOP: + /* patable */ + case CC1100_PATABLE: + /* tx/rx */ + case CC1100_RXFIFO: /* == CC1100_TXFIFO */ + default: + errx(EXIT_FAILURE, "step_state_idle: unhandled addr: %d", addr); + } +} + +void step_state_sleep(void) +{ + ; +} + +void step_state_xtaloff(void) +{ + ; +} + +void step_state_freq_scal(void) +{ + ; +} + +void step_state_freq_sst(void) +{ + ; +} + +void step_state_freq_son(void) +{ + ; +} + +void step_state_tx(void) +{ + ; +} + +void step_state_rx(void) +{ + ; +} + +void step_state_tx_ffuf(void) +{ + ; +} + +void step_state_rx_ffof(void) +{ + ; +} + +void step(void) +{ + switch (internal_state) { + case (STATE_IDLE): + step_state_idle(); + break; + + case (STATE_SLEEP): + step_state_sleep(); + break; + + case (STATE_XTALOFF): + step_state_xtaloff(); + break; + + case (STATE_FREQ_SCAL): + step_state_freq_scal(); + break; + + case (STATE_FREQ_SST): + step_state_freq_sst(); + break; + + case (STATE_FREQ_SON): + step_state_freq_son(); + break; + + case (STATE_TX): + step_state_tx(); + break; + + case (STATE_RX): + step_state_rx(); + break; + + case (STATE_TX_FFUF): + step_state_tx_ffuf(); + break; + + case (STATE_RX_FFOF): + step_state_rx_ffof(); + break; + + default: + errx(EXIT_FAILURE, "internal error in CC1100 state machine"); + } +} + +void _native_cc1100_receive(uint8_t *buf, int len) +{ + ; +} + +#endif diff --git a/cpu/native/cc110x_ng/cc110x_ng_cpu.c b/cpu/native/cc110x_ng/cc110x_ng_cpu.c index 2b64159384..551010fd77 100644 --- a/cpu/native/cc110x_ng/cc110x_ng_cpu.c +++ b/cpu/native/cc110x_ng/cc110x_ng_cpu.c @@ -1,44 +1,36 @@ #include #include +#include +#include +#include +#include -#include +#include -#include -#include -#include -#include /* CC1100_READ_BURST etc. */ +#include "debug.h" -static int native_cc110x_enabled; +#include "tap.h" +#include "cc1100sim.h" +#include "cpu.h" -static int native_cc110x_gd0; -static int native_cc110x_gd1; -static int native_cc110x_gd2; +#include "cc110x-arch.h" +#include "cc110x_ng.h" +#include "cc110x_spi.h" +#include "cc110x-internal.h" /* CC1100 constants */ -static int native_cc110x_gd0_enabled; -static int native_cc110x_gd2_enabled; -static uint8_t native_cc110x_ssp0dr; +static int _native_cc110x_enabled; /* arch */ /** * writes to SSP0 data register and reads from it once it is ready + * TODO: move content to simulator */ 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; + return do_txrx(c); } /** @@ -47,19 +39,18 @@ uint8_t cc110x_txrx(uint8_t c) 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"); + native_cc110x_gd0_enabled = 1; return; } - /** * enables GDO0 interrupt */ void cc110x_gdo0_disable(void) { - native_cc110x_gd0_enabled = 0; DEBUG("cc110x_gdo0_disable\n"); + native_cc110x_gd0_enabled = 0; return; } @@ -69,8 +60,8 @@ void cc110x_gdo0_disable(void) 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"); + native_cc110x_gd2_enabled = 1; return; } @@ -79,8 +70,8 @@ void cc110x_gdo2_enable(void) */ void cc110x_gdo2_disable(void) { - native_cc110x_gd2_enabled = 0; DEBUG("cc110x_gdo2_disable\n"); + native_cc110x_gd2_enabled = 0; return; } @@ -90,22 +81,23 @@ void cc110x_gdo2_disable(void) void cc110x_init_interrupts(void) { /* this would be for low edge in both cases if this was proper hardware */ + DEBUG("cc110x_init_interrupts\n"); cc110x_gdo2_enable(); cc110x_gdo0_enable(); - DEBUG("cc110x_init_interrupts\n"); return; } +/* Disables RX interrupt etc. */ void cc110x_before_send(void) { - cc110x_gdo2_disable(); DEBUG("cc110x_before_send\n"); + cc110x_gdo2_disable(); return; } void cc110x_after_send(void) { - cc110x_gdo2_enable(); DEBUG("cc110x_after_send\n"); + cc110x_gdo2_enable(); return; } @@ -124,13 +116,13 @@ int cc110x_get_gdo1(void) int cc110x_get_gdo2(void) { DEBUG("cc110x_get_gdo2\n"); - return native_cc110x_gd2; + return native_cc110x_gd2--; } void cc110x_spi_init(void) { - native_cc110x_enabled = 1; /* power on */ DEBUG("cc110x_spi_init\n"); + _native_cc110x_enabled = 1; /* power on */ return; } @@ -141,12 +133,14 @@ void cc110x_spi_cs(void) } void cc110x_spi_select(void) { - DEBUG("cc110x_spi_select\n"); + DEBUG("___cc110x_spi_select\n"); + _native_cc110x_state = STATE_SEL; return; } void cc110x_spi_unselect(void) { DEBUG("cc110x_spi_unselect\n"); + _native_cc110x_state = STATE_NULL; return; } diff --git a/cpu/native/hwtimer_cpu.c b/cpu/native/hwtimer_cpu.c index 993d7a4677..f8c30d56f2 100644 --- a/cpu/native/hwtimer_cpu.c +++ b/cpu/native/hwtimer_cpu.c @@ -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); diff --git a/cpu/native/include/cc1100sim.h b/cpu/native/include/cc1100sim.h new file mode 100644 index 0000000000..797501119f --- /dev/null +++ b/cpu/native/include/cc1100sim.h @@ -0,0 +1,39 @@ +extern uint8_t configuration_registers[((0x2E)+1)]; /* address 0x00 - 0x2E */ +extern uint8_t configuration_registers_idx; /* for burst access */ +extern uint8_t status_registers[((0x3D-0x30)+1)]; /* address 0x30 - 0x3D */ +extern uint8_t rx_fifo[]; /* address 0x3F + RW high (BF: 1011 1111) */ +extern uint8_t rx_fifo_idx; /* for burst access */ +extern uint8_t tx_fifo[]; /* address 0x3F + RW low (3F: 0011 1111) */ +extern uint8_t tx_fifo_idx; /* for burst access */ +extern uint8_t patable[8]; /* address 0x3E */ +extern uint8_t patable_idx; /* for burst access */ + + +extern int native_cc110x_gd0; +extern int native_cc110x_gd1; +extern int native_cc110x_gd2; +extern int native_cc110x_gd0_enabled; +extern int native_cc110x_gd2_enabled; + +extern uint8_t addr; +extern uint8_t _native_cc110x_state; + +uint8_t do_txrx(uint8_t c); +void do_sres(void); +uint8_t do_strobe(void); +uint8_t parse_header(uint8_t c); +uint8_t write_burst(uint8_t c); +uint8_t read_burst(uint8_t c); +uint8_t write_single(uint8_t c); +uint8_t read_single(uint8_t c); + +#define STATE_NULL 0x00 +#define STATE_SEL 0x01 +#define STATE_WRITE_B 0x02 +#define STATE_READ_B 0x03 +#define STATE_READ_S 0x04 +#define STATE_WRITE_S 0x05 + +void _native_cc1100_handle_packet(unsigned char *buf, int size); + +#define CC1100_FIFO_LENGTH 64 diff --git a/cpu/native/include/cpu-conf.h b/cpu/native/include/cpu-conf.h index 337b38c0ca..e631e6249a 100644 --- a/cpu/native/include/cpu-conf.h +++ b/cpu/native/include/cpu-conf.h @@ -18,15 +18,15 @@ #include /* 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 +#else /* Linux etc. */ #define KERNEL_CONF_STACKSIZE_DEFAULT (8192) #define KERNEL_CONF_STACKSIZE_IDLE (16384) #define NATIVE_ISR_STACKSIZE (16384) @@ -35,12 +35,12 @@ #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_ */ diff --git a/cpu/native/include/cpu.h b/cpu/native/include/cpu.h index 1187129df9..955bb85522 100644 --- a/cpu/native/include/cpu.h +++ b/cpu/native/include/cpu.h @@ -68,5 +68,12 @@ extern unsigned int _native_saved_eip; extern int _native_in_isr; extern int _native_in_syscall; extern int _native_sigpend; +#if (defined(MODULE_UART0) || defined(MODULE_CC110X_NG)) +#include +extern fd_set _native_rfds; +#endif +#ifdef MODULE_CC110X_NG +int _native_set_cc110xng_fds(void); +#endif /** @} */ #endif //_CPU_H diff --git a/cpu/native/include/tap.h b/cpu/native/include/tap.h new file mode 100644 index 0000000000..65d1351703 --- /dev/null +++ b/cpu/native/include/tap.h @@ -0,0 +1,29 @@ +#ifndef _TAP_H +#define _TAP_H + +#include + +/** + * 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(void); +void _native_marshall_ethernet(uint8_t *framebuf, uint8_t *data, int data_len); +void _native_cc1100_handle_input(unsigned char *buf, int size); + +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 */ diff --git a/cpu/native/irq_cpu.c b/cpu/native/irq_cpu.c index 7dfd33884b..365308aed0 100644 --- a/cpu/native/irq_cpu.c +++ b/cpu/native/irq_cpu.c @@ -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"); + printf("disableIRQ: calling swapcontext()\n"); + printf("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"); + printf("enableIRQ: calling swapcontext()\n"); + printf("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; } diff --git a/cpu/native/lpm_cpu.c b/cpu/native/lpm_cpu.c index 3931df7ba5..576a3e2475 100644 --- a/cpu/native/lpm_cpu.c +++ b/cpu/native/lpm_cpu.c @@ -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) { diff --git a/cpu/native/native_cpu.c b/cpu/native/native_cpu.c index f9a4ce35c8..8323654c9e 100644 --- a/cpu/native/native_cpu.c +++ b/cpu/native/native_cpu.c @@ -36,6 +36,10 @@ extern volatile tcb_t *active_thread; static ucontext_t end_context; static char __isr_stack[SIGSTKSZ]; +#if (defined(MODULE_UART0) || defined(MODULE_CC110X_NG)) +fd_set _native_rfds; +#endif + /** * TODO: implement */ diff --git a/cpu/native/startup.c b/cpu/native/startup.c index 39a3534dbd..fe371cd3ba 100644 --- a/cpu/native/startup.c +++ b/cpu/native/startup.c @@ -15,17 +15,33 @@ */ #include +#include +#include + #include #include +#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_CC110X_NG + if (argc < 2) { + printf("usage: %s \n", argv[0]); + exit(EXIT_FAILURE); + } +#endif + native_cpu_init(); native_interrupt_init(); +#ifdef MODULE_CC110X_NG + tap_init(argv[1]); +#endif board_init(); diff --git a/cpu/native/tap.c b/cpu/native/tap.c new file mode 100644 index 0000000000..8f75f0a1d1 --- /dev/null +++ b/cpu/native/tap.c @@ -0,0 +1,235 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __MACH__ +#define _POSIX_C_SOURCE +#include +#undef _POSIX_C_SOURCE +#include +#include +#else +#include +#include +#include +#endif + +#include "debug.h" + +#include "cpu.h" +#include "cpu-conf.h" +#include "tap.h" +#include "cc1100sim.h" +#include "cc110x-internal.h" /* CC1100 constants */ + +#define TAP_BUFFER_LENGTH (CC1100_FIFO_LENGTH + ETHER_HDR_LEN + 1) + +int _native_tap_fd; +unsigned char _native_tap_mac[ETHER_ADDR_LEN]; + +void _native_handle_cc110xng_input(void) +{ + int nread; + unsigned char buf[TAP_BUFFER_LENGTH]; + union eth_frame *f; + + DEBUG("_native_handle_cc110xng_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_cc110xng_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_cc110xng_input: no payload"); + } + else { + nread = buf[ETHER_HDR_LEN]; + _native_cc1100_handle_packet(buf+ETHER_HDR_LEN+1, nread); + } + } + else { + DEBUG("ignoring non-native frame\n"); + } + } + else if (nread == -1) { + err(EXIT_FAILURE, "read"); + } + else { + errx(EXIT_FAILURE, "internal error in _native_handle_cc110xng_input"); + } +} + +int send_buf(void) +{ + uint8_t buf[TAP_BUFFER_LENGTH]; + int nsent; + uint8_t to_send; + + to_send = status_registers[CC1100_TXBYTES - 0x30]; + _native_marshall_ethernet(buf, tx_fifo, to_send); + to_send += 1; + + if ((ETHER_HDR_LEN + to_send) < ETHERMIN) { + DEBUG("padding data! (%d ->", to_send); + to_send = ETHERMIN - ETHER_HDR_LEN; + DEBUG("%d)\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_cc110xng_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; +} + +void _native_marshall_ethernet(uint8_t *framebuf, uint8_t *data, 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, dst, ETHER_ADDR_LEN); + memcpy(f->field.header.ether_dhost, addr, ETHER_ADDR_LEN); + //memcpy(f->field.header.ether_shost, src, ETHER_ADDR_LEN); + memcpy(f->field.header.ether_shost, _native_tap_mac, ETHER_ADDR_LEN); + f->field.header.ether_type = htons(NATIVE_ETH_PROTO); + memcpy(f->field.data+1, data, data_len); + f->field.data[0] = (uint8_t)data_len; +} + +#ifdef TAPTESTBINARY +/** + * test tap device + */ +int main(int argc, char *argv[]) +{ + int fd; + unsigned char buffer[2048]; + + if (argc < 2) { + errx(EXIT_FAILURE, "you need to specify a tap name"); + } + fd = tap_init(argv[1]); + + printf("trying to write to fd: %i\n", _native_tap_fd); + char *payld = "abcdefg"; + int data_len = strlen(payld); + _native_marshall_ethernet(buffer, payld, data_len); + if (write(_native_tap_fd, buffer, ETHER_HDR_LEN + data_len) == -1) { + err(EXIT_FAILURE, "write"); + } + + printf("reading\n"); + int nread; + while (1) { + /* Note that "buffer" should be at least the MTU size of the + * interface, eg 1500 bytes */ + nread = read(fd,buffer,sizeof(buffer)); + if(nread < 0) { + warn("Reading from interface"); + if (close(fd) == -1) { + warn("close"); + } + exit(EXIT_FAILURE); + } + + /* Do whatever with the data */ + printf("Read %d bytes\n", nread); + } + + return EXIT_SUCCESS; +} +#endif diff --git a/cpu/native/tapsetup-osx.sh b/cpu/native/tapsetup-osx.sh new file mode 100755 index 0000000000..36317f2ef9 --- /dev/null +++ b/cpu/native/tapsetup-osx.sh @@ -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) " + 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 diff --git a/cpu/native/tapsetup.sh b/cpu/native/tapsetup.sh new file mode 100755 index 0000000000..e64485a413 --- /dev/null +++ b/cpu/native/tapsetup.sh @@ -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) " + 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 diff --git a/drivers/cc110x_ng/include/cc110x-internal.h b/drivers/cc110x_ng/include/cc110x-internal.h index 392b30626d..d3409e9979 100644 --- a/drivers/cc110x_ng/include/cc110x-internal.h +++ b/drivers/cc110x_ng/include/cc110x-internal.h @@ -88,7 +88,7 @@ #define CC1100_WRITE_BURST (0x40) ///< Offset for burst write. #define CC1100_READ_SINGLE (0x80) ///< Offset for read single byte. #define CC1100_READ_BURST (0xC0) ///< Offset for read burst. -#define CC1100_NOBYTE (0x00) ///< No command (for reading). +#define CC1100_NOBYTE (0xFF) ///< No command (for reading). /** @} */ /**