diff --git a/examples/sensniff/netstack.c b/examples/sensniff/netstack.c new file mode 100644 index 000000000..14068ce77 --- /dev/null +++ b/examples/sensniff/netstack.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2010, Loughborough University - Computer Science + * 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. + */ +/*---------------------------------------------------------------------------*/ +#include "netstack.h" +/*---------------------------------------------------------------------------*/ +void +netstack_init(void) +{ + NETSTACK_RADIO.init(); + NETSTACK_RDC.init(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/sensniff/project-conf.h b/examples/sensniff/project-conf.h new file mode 100644 index 000000000..4d703fc43 --- /dev/null +++ b/examples/sensniff/project-conf.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016, George Oikonomou - http://www.spd.gr + * 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 copyright holder 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 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 HOLDER 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 PROJECT_CONF_H_ +#define PROJECT_CONF_H_ +/*---------------------------------------------------------------------------*/ +#undef NETSTACK_CONF_RDC +#define NETSTACK_CONF_RDC sensniff_rdc_driver +/*---------------------------------------------------------------------------*/ +/* Include platform-specific header */ +#include "target-conf.h" +/*---------------------------------------------------------------------------*/ +#endif /* PROJECT_CONF_H_ */ diff --git a/examples/sensniff/sensniff-rdc.c b/examples/sensniff/sensniff-rdc.c new file mode 100644 index 000000000..3a5eef428 --- /dev/null +++ b/examples/sensniff/sensniff-rdc.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2016, George Oikonomou - http://www.spd.gr + * Copyright (c) 2012-2013, Centre National de la Recherche Scientifique. + * 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 copyright holder 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 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 HOLDER 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. + */ +/*---------------------------------------------------------------------------*/ +/* + * Author: George Oikonomou + * Loosely based on the example contributed by Etienne Duble (CNRS / LIG), as + * part of the work done for the ANR ARESA2 project. + */ +/*---------------------------------------------------------------------------*/ +#include "net/mac/mac.h" +#include "net/mac/rdc.h" +#include "net/netstack.h" +#include "sensniff.h" +/*---------------------------------------------------------------------------*/ +static void +send(mac_callback_t sent, void *ptr) +{ +} +/*---------------------------------------------------------------------------*/ +static void +send_list(mac_callback_t sent, void *ptr, struct rdc_buf_list *list) +{ +} +/*---------------------------------------------------------------------------*/ +static void +input(void) +{ + sensniff_output_frame(); +} +/*---------------------------------------------------------------------------*/ +static int +on(void) +{ + NETSTACK_RADIO.on(); + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +off(int keep_radio_on) +{ + return keep_radio_on; +} +/*---------------------------------------------------------------------------*/ +static unsigned short +cca(void) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ + on(); +} +/*---------------------------------------------------------------------------*/ +const struct rdc_driver sensniff_rdc_driver = { + "sensniff-rdc", + init, + send, + send_list, + input, + on, + off, + cca, +}; +/*---------------------------------------------------------------------------*/ diff --git a/examples/sensniff/sensniff.c b/examples/sensniff/sensniff.c new file mode 100644 index 000000000..93f39ac04 --- /dev/null +++ b/examples/sensniff/sensniff.c @@ -0,0 +1,344 @@ +/* + * Copyright (c) 2016, George Oikonomou - http://www.spd.gr + * 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 copyright holder 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 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 HOLDER 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. + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "sensniff.h" +#include "dev/radio.h" +#include "net/netstack.h" +#include "net/packetbuf.h" +#include "sys/process.h" +#include "sys/ctimer.h" +#include "lib/ringbuf.h" + +#include SENSNIFF_IO_DRIVER_H + +#include +#include +#include +/*---------------------------------------------------------------------------*/ +#define DEBUG 1 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +PROCESS(sensniff_process, "sensniff process"); +AUTOSTART_PROCESSES(&sensniff_process); +/*---------------------------------------------------------------------------*/ +/* Timeout handling for incoming characters. */ +#define TIMEOUT (CLOCK_SECOND >> 1) +static struct ctimer ct; +/*---------------------------------------------------------------------------*/ +#define STATE_WAITING_FOR_MAGIC 0x00 +#define STATE_WAITING_FOR_VERSION 0x01 +#define STATE_WAITING_FOR_CMD 0x02 +#define STATE_WAITING_FOR_LEN_1 0x03 +#define STATE_WAITING_FOR_LEN_2 0x04 +#define STATE_WAITING_FOR_DATA 0x05 + +static uint8_t state; +static uint8_t in_ct; +/*---------------------------------------------------------------------------*/ +#define CMD_FRAME 0x00 +#define CMD_CHANNEL 0x01 +#define CMD_CHANNEL_MIN 0x02 +#define CMD_CHANNEL_MAX 0x03 +#define CMD_ERR_NOT_SUPPORTED 0x7F +#define CMD_GET_CHANNEL 0x81 +#define CMD_GET_CHANNEL_MIN 0x82 +#define CMD_GET_CHANNEL_MAX 0x83 +#define CMD_SET_CHANNEL 0x84 +/*---------------------------------------------------------------------------*/ +#define PROTOCOL_VERSION 2 +/*---------------------------------------------------------------------------*/ +#define BUFSIZE 32 + +static struct ringbuf rxbuf; + +typedef struct cmd_in_s { + uint8_t cmd; + uint16_t len; + uint8_t data; +} cmd_in_t; + +static cmd_in_t command; + +uint8_t cmd_buf[BUFSIZE]; +/*---------------------------------------------------------------------------*/ +static const uint8_t magic[] = { 0xC1, 0x1F, 0xFE, 0x72 }; +/*---------------------------------------------------------------------------*/ +static void +reset_state(void *byte) +{ + state = STATE_WAITING_FOR_MAGIC; + in_ct = 0; + memset(&command, 0, sizeof(command)); +} +/*---------------------------------------------------------------------------*/ +static void +send_header(uint8_t cmd, uint16_t len) +{ + uint16_t i; + + /* Send the magic */ + for(i = 0; i < 4; i++) { + sensniff_io_byte_out(magic[i]); + } + + /* Send the protocol version */ + sensniff_io_byte_out(PROTOCOL_VERSION); + + /* Send the command byte */ + sensniff_io_byte_out(cmd); + + /* Send the length, network endianness */ + sensniff_io_byte_out(len >> 8); + sensniff_io_byte_out(len & 0xFF); +} +/*---------------------------------------------------------------------------*/ +static void +send_error(void) +{ + send_header(CMD_ERR_NOT_SUPPORTED, 0); + + sensniff_io_flush(); +} +/*---------------------------------------------------------------------------*/ +static void +send_channel(void) +{ + radio_value_t chan; + + if(NETSTACK_RADIO.get_value(RADIO_PARAM_CHANNEL, &chan) == + RADIO_RESULT_OK) { + send_header(CMD_CHANNEL, 1); + sensniff_io_byte_out(chan & 0xFF); + sensniff_io_flush(); + return; + } + + send_error(); +} +/*---------------------------------------------------------------------------*/ +static void +set_channel(uint8_t channel) +{ + if(NETSTACK_RADIO.set_value(RADIO_PARAM_CHANNEL, channel) == + RADIO_RESULT_OK) { + send_channel(); + return; + } + + send_error(); +} +/*---------------------------------------------------------------------------*/ +static void +send_channel_min(void) +{ + radio_value_t chan; + + if(NETSTACK_RADIO.get_value(RADIO_CONST_CHANNEL_MIN, &chan) == + RADIO_RESULT_OK) { + send_header(CMD_CHANNEL_MIN, 1); + sensniff_io_byte_out(chan & 0xFF); + sensniff_io_flush(); + return; + } + + send_error(); +} +/*---------------------------------------------------------------------------*/ +static void +send_channel_max(void) +{ + radio_value_t chan; + + if(NETSTACK_RADIO.get_value(RADIO_CONST_CHANNEL_MAX, &chan) == + RADIO_RESULT_OK) { + send_header(CMD_CHANNEL_MAX, 1); + sensniff_io_byte_out(chan & 0xFF); + sensniff_io_flush(); + return; + } + + send_error(); +} +/*---------------------------------------------------------------------------*/ +static int +char_in(unsigned char c) +{ + /* Bump the timeout counter */ + ctimer_set(&ct, TIMEOUT, reset_state, NULL); + + /* Add the character to our ringbuf and poll the consumer process. */ + ringbuf_put(&rxbuf, c); + + process_poll(&sensniff_process); + return 1; +} +/*---------------------------------------------------------------------------*/ +void +sensniff_output_frame() +{ + int i; + uint8_t len = packetbuf_datalen() & 0xFF; + + send_header(CMD_FRAME, len + 2); + + for(i = 0; i < len; i++) { + sensniff_io_byte_out(((uint8_t *)packetbuf_dataptr())[i]); + } + + sensniff_io_byte_out(packetbuf_attr(PACKETBUF_ATTR_RSSI) & 0xFF); + sensniff_io_byte_out(0x80 | + (packetbuf_attr(PACKETBUF_ATTR_LINK_QUALITY) & 0xFF)); + + sensniff_io_flush(); +} +/*---------------------------------------------------------------------------*/ +static void +execute_command(void) +{ + switch(command.cmd) { + case CMD_GET_CHANNEL: + send_channel(); + break; + case CMD_GET_CHANNEL_MIN: + send_channel_min(); + break; + case CMD_GET_CHANNEL_MAX: + send_channel_max(); + break; + case CMD_SET_CHANNEL: + set_channel(command.data); + break; + default: + send_error(); + break; + } +} +/*---------------------------------------------------------------------------*/ +static void +process_incoming_data(void) +{ + int c = 0; + uint8_t byte_in; + + c = ringbuf_get(&rxbuf); + + while(c != -1) { + byte_in = (uint8_t)c; + switch(state) { + case STATE_WAITING_FOR_MAGIC: + if(byte_in == magic[in_ct]) { + in_ct++; + if(in_ct == sizeof(magic)) { + state = STATE_WAITING_FOR_VERSION; + in_ct = 0; + } + } else { + reset_state(&byte_in); + } + break; + case STATE_WAITING_FOR_VERSION: + if(byte_in == PROTOCOL_VERSION) { + state = STATE_WAITING_FOR_CMD; + } else { + reset_state(&byte_in); + } + break; + case STATE_WAITING_FOR_CMD: + command.cmd = byte_in; + + if(command.cmd == CMD_GET_CHANNEL || + command.cmd == CMD_GET_CHANNEL_MIN || + command.cmd == CMD_GET_CHANNEL_MAX) { + execute_command(); + reset_state(&byte_in); + } else { + state = STATE_WAITING_FOR_LEN_1; + } + break; + case STATE_WAITING_FOR_LEN_1: + command.len = byte_in << 8; + state = STATE_WAITING_FOR_LEN_2; + break; + case STATE_WAITING_FOR_LEN_2: + command.len |= byte_in; + if(command.len == 1) { + state = STATE_WAITING_FOR_DATA; + } else { + reset_state(&byte_in); + } + break; + case STATE_WAITING_FOR_DATA: + command.data = byte_in; + execute_command(); + reset_state(&byte_in); + break; + default: + break; + } + c = ringbuf_get(&rxbuf); + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(sensniff_process, ev, data) +{ + PROCESS_BEGIN(); + + /* Turn off RF frame filtering and H/W ACKs */ + if(NETSTACK_RADIO.set_value(RADIO_PARAM_RX_MODE, 0) != RADIO_RESULT_OK) { + PRINTF("sensniff: Error setting RF in promiscuous mode\n"); + PROCESS_EXIT(); + } + + /* Initialise the ring buffer */ + ringbuf_init(&rxbuf, cmd_buf, sizeof(cmd_buf)); + + /* Initialise the state machine */ + reset_state(NULL); + + /* Register for char inputs with the character I/O peripheral */ + sensniff_io_set_input(&char_in); + + while(1) { + PROCESS_YIELD(); + + if(ev == PROCESS_EVENT_POLL) { + process_incoming_data(); + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/sensniff/sensniff.h b/examples/sensniff/sensniff.h new file mode 100644 index 000000000..cbddcb8ca --- /dev/null +++ b/examples/sensniff/sensniff.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2016, George Oikonomou - http://www.spd.gr + * 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 copyright holder 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 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 HOLDER 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 SENSNIFF_H_ +#define SENSNIFF_H_ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" + +#include +/*---------------------------------------------------------------------------*/ +#define SENSNIFF_ERROR 0xFF +#define SENSNIFF_OK 0x00 +/*---------------------------------------------------------------------------*/ +void sensniff_output_frame(void); +/*---------------------------------------------------------------------------*/ +#endif /* SENSNIFF_H_ */ +/*---------------------------------------------------------------------------*/