├── sdn-wise ├── symbols.h ├── symbols.c ├── cooja_firmwares │ ├── mobile.sky │ ├── node.sky │ ├── sink.sky │ ├── node.stm32f401re-nucleo-spirit1 │ └── sink.stm32f401re-nucleo-spirit1 ├── Makefile ├── project-conf.h ├── RUNME.sh ├── packet-handler.h ├── sdn-wise.h ├── RUNME_st.sh ├── packet-creator.h ├── neighbor-table.h ├── node-conf.h ├── address.h ├── packet-buffer.h ├── node-conf.c ├── flowtable.h ├── neighbor-table.c ├── packet-buffer.c ├── address.c ├── packet-creator.c ├── packet-handler.c ├── sdn-wise.c └── flowtable.c ├── .gitmodules ├── sdn-wise-emulated ├── lib │ ├── sdn-wise-cooja.jar │ └── sdn-wise-data.jar ├── build │ └── org │ │ └── contikios │ │ └── cooja │ │ └── sdnwise │ │ ├── CoojaMote.class │ │ ├── CoojaSink.class │ │ ├── CoojaSink$1.class │ │ ├── AbstractCoojaMote.class │ │ ├── SdnWiseMoteType.class │ │ ├── SdnWiseSinkType.class │ │ ├── AbstractCoojaMote$1.class │ │ ├── AbstractCoojaMote$2.class │ │ ├── CoojaSink$TcpSender.class │ │ ├── CoojaSink$TcpListener.class │ │ ├── AbstractCoojaMote$LoggerRunnable.class │ │ └── AbstractCoojaMote$SenderRunnable.class ├── cooja.config ├── build.xml └── src │ └── org │ └── contikios │ └── cooja │ └── sdnwise │ ├── CoojaMote.java │ ├── SdnWiseMoteType.java │ ├── SdnWiseSinkType.java │ ├── CoojaSink.java │ └── AbstractCoojaMote.java ├── .gitignore ├── .travis.yml ├── LICENSE ├── Dockerfile └── README.md /sdn-wise/symbols.h: -------------------------------------------------------------------------------- 1 | #include "loader/symbols.h" 2 | 3 | extern const struct symbols symbols[1]; 4 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "contiki"] 2 | path = contiki 3 | url = https://github.com/contiki-os/contiki.git 4 | -------------------------------------------------------------------------------- /sdn-wise/symbols.c: -------------------------------------------------------------------------------- 1 | #include "symbols.h" 2 | 3 | const int symbols_nelts = 0; 4 | const struct symbols symbols[] = {{0,0}}; 5 | -------------------------------------------------------------------------------- /sdn-wise/cooja_firmwares/mobile.sky: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdnwiselab/sdn-wise-contiki/HEAD/sdn-wise/cooja_firmwares/mobile.sky -------------------------------------------------------------------------------- /sdn-wise/cooja_firmwares/node.sky: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdnwiselab/sdn-wise-contiki/HEAD/sdn-wise/cooja_firmwares/node.sky -------------------------------------------------------------------------------- /sdn-wise/cooja_firmwares/sink.sky: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdnwiselab/sdn-wise-contiki/HEAD/sdn-wise/cooja_firmwares/sink.sky -------------------------------------------------------------------------------- /sdn-wise-emulated/lib/sdn-wise-cooja.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdnwiselab/sdn-wise-contiki/HEAD/sdn-wise-emulated/lib/sdn-wise-cooja.jar -------------------------------------------------------------------------------- /sdn-wise-emulated/lib/sdn-wise-data.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdnwiselab/sdn-wise-contiki/HEAD/sdn-wise-emulated/lib/sdn-wise-data.jar -------------------------------------------------------------------------------- /sdn-wise/cooja_firmwares/node.stm32f401re-nucleo-spirit1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdnwiselab/sdn-wise-contiki/HEAD/sdn-wise/cooja_firmwares/node.stm32f401re-nucleo-spirit1 -------------------------------------------------------------------------------- /sdn-wise/cooja_firmwares/sink.stm32f401re-nucleo-spirit1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdnwiselab/sdn-wise-contiki/HEAD/sdn-wise/cooja_firmwares/sink.stm32f401re-nucleo-spirit1 -------------------------------------------------------------------------------- /sdn-wise-emulated/build/org/contikios/cooja/sdnwise/CoojaMote.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdnwiselab/sdn-wise-contiki/HEAD/sdn-wise-emulated/build/org/contikios/cooja/sdnwise/CoojaMote.class -------------------------------------------------------------------------------- /sdn-wise-emulated/build/org/contikios/cooja/sdnwise/CoojaSink.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdnwiselab/sdn-wise-contiki/HEAD/sdn-wise-emulated/build/org/contikios/cooja/sdnwise/CoojaSink.class -------------------------------------------------------------------------------- /sdn-wise-emulated/build/org/contikios/cooja/sdnwise/CoojaSink$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdnwiselab/sdn-wise-contiki/HEAD/sdn-wise-emulated/build/org/contikios/cooja/sdnwise/CoojaSink$1.class -------------------------------------------------------------------------------- /sdn-wise-emulated/build/org/contikios/cooja/sdnwise/AbstractCoojaMote.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdnwiselab/sdn-wise-contiki/HEAD/sdn-wise-emulated/build/org/contikios/cooja/sdnwise/AbstractCoojaMote.class -------------------------------------------------------------------------------- /sdn-wise-emulated/build/org/contikios/cooja/sdnwise/SdnWiseMoteType.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdnwiselab/sdn-wise-contiki/HEAD/sdn-wise-emulated/build/org/contikios/cooja/sdnwise/SdnWiseMoteType.class -------------------------------------------------------------------------------- /sdn-wise-emulated/build/org/contikios/cooja/sdnwise/SdnWiseSinkType.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdnwiselab/sdn-wise-contiki/HEAD/sdn-wise-emulated/build/org/contikios/cooja/sdnwise/SdnWiseSinkType.class -------------------------------------------------------------------------------- /sdn-wise-emulated/build/org/contikios/cooja/sdnwise/AbstractCoojaMote$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdnwiselab/sdn-wise-contiki/HEAD/sdn-wise-emulated/build/org/contikios/cooja/sdnwise/AbstractCoojaMote$1.class -------------------------------------------------------------------------------- /sdn-wise-emulated/build/org/contikios/cooja/sdnwise/AbstractCoojaMote$2.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdnwiselab/sdn-wise-contiki/HEAD/sdn-wise-emulated/build/org/contikios/cooja/sdnwise/AbstractCoojaMote$2.class -------------------------------------------------------------------------------- /sdn-wise-emulated/build/org/contikios/cooja/sdnwise/CoojaSink$TcpSender.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdnwiselab/sdn-wise-contiki/HEAD/sdn-wise-emulated/build/org/contikios/cooja/sdnwise/CoojaSink$TcpSender.class -------------------------------------------------------------------------------- /sdn-wise-emulated/build/org/contikios/cooja/sdnwise/CoojaSink$TcpListener.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdnwiselab/sdn-wise-contiki/HEAD/sdn-wise-emulated/build/org/contikios/cooja/sdnwise/CoojaSink$TcpListener.class -------------------------------------------------------------------------------- /sdn-wise-emulated/build/org/contikios/cooja/sdnwise/AbstractCoojaMote$LoggerRunnable.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdnwiselab/sdn-wise-contiki/HEAD/sdn-wise-emulated/build/org/contikios/cooja/sdnwise/AbstractCoojaMote$LoggerRunnable.class -------------------------------------------------------------------------------- /sdn-wise-emulated/build/org/contikios/cooja/sdnwise/AbstractCoojaMote$SenderRunnable.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdnwiselab/sdn-wise-contiki/HEAD/sdn-wise-emulated/build/org/contikios/cooja/sdnwise/AbstractCoojaMote$SenderRunnable.class -------------------------------------------------------------------------------- /sdn-wise-emulated/cooja.config: -------------------------------------------------------------------------------- 1 | org.contikios.cooja.Cooja.JARFILES = + sdn-wise-data.jar sdn-wise-cooja.jar 2 | org.contikios.cooja.Cooja.MOTETYPES = + org.contikios.cooja.sdnwise.SdnWiseSinkType org.contikios.cooja.sdnwise.SdnWiseMoteType 3 | -------------------------------------------------------------------------------- /sdn-wise/Makefile: -------------------------------------------------------------------------------- 1 | CONTIKI_PROJECT = sdn-wise 2 | all: $(CONTIKI_PROJECT) 3 | 4 | CONTIKI = ../contiki 5 | CONTIKI_WITH_RIME = 1 6 | 7 | PROJECT_SOURCEFILES = flowtable.c packet-buffer.c address.c neighbor-table.c packet-handler.c node-conf.c packet-creator.c 8 | TARGETDIRS += ../targets 9 | CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" 10 | 11 | include $(CONTIKI)/Makefile.include 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Temp files 2 | *~ 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Libraries 15 | *.lib 16 | *.a 17 | *.la 18 | *.lo 19 | 20 | # Shared objects (inc. Windows DLLs) 21 | *.dll 22 | *.so 23 | *.so.* 24 | *.dylib 25 | 26 | # Executables 27 | *.exe 28 | *.out 29 | *.app 30 | *.i*86 31 | *.x86_64 32 | *.hex 33 | 34 | # Debug files 35 | *.dSYM/ 36 | -------------------------------------------------------------------------------- /sdn-wise/project-conf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * project-conf.h 3 | * 4 | * Created on: 27 jan 2016 5 | * Author: Sebastiano Milardo 6 | */ 7 | 8 | #ifndef PROJECT_CONF_H_ 9 | #define PROJECT_CONF_H_ 10 | 11 | /*************************************************************************/ 12 | #define CFS_ENABLED 0 13 | #define ELF_ENABLED 0 14 | #define BATTERY_ENABLED 0 15 | /*************************************************************************/ 16 | #endif // PROJECT_CONF_H_ 17 | 18 | 19 | -------------------------------------------------------------------------------- /sdn-wise/RUNME.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | TARGET="sky" 3 | COOJA_BUILD=1 4 | SDN_WISE_DEBUG=1 5 | 6 | mkdir cooja_firmwares 7 | 8 | make TARGET=$TARGET DEFINES=COOJA=$COOJA_BUILD,SINK=1,SDN_WISE_DEBUG=$SDN_WISE_DEBUG 9 | mv sdn-wise.$TARGET cooja_firmwares/sink.$TARGET 10 | make TARGET=$TARGET clean 11 | 12 | make TARGET=$TARGET DEFINES=COOJA=$COOJA_BUILD,SINK=0,SDN_WISE_DEBUG=$SDN_WISE_DEBUG 13 | mv sdn-wise.$TARGET cooja_firmwares/node.$TARGET 14 | make TARGET=$TARGET clean 15 | 16 | make TARGET=$TARGET DEFINES=COOJA=$COOJA_BUILD,SINK=0,SDN_WISE_DEBUG=$SDN_WISE_DEBUG,MOBILE=1 17 | mv sdn-wise.$TARGET cooja_firmwares/mobile.$TARGET 18 | make TARGET=$TARGET clean 19 | 20 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | notifications: 2 | email: false 3 | language: c 4 | 5 | before_script: 6 | - WGET="travis_retry wget --continue --tries=20 --waitretry=10 --retry-connrefused --no-dns-cache --timeout 300" 7 | - sudo apt-get -qq update 8 | - cd sdn-wise 9 | 10 | ## Install msp430 toolchain 11 | - sudo apt-get -qq install lib32z1 12 | - $WGET http://simonduq.github.io/resources/mspgcc-4.7.2-compiled.tar.bz2 && 13 | tar xjf mspgcc*.tar.bz2 -C /tmp/ && 14 | sudo cp -f -r /tmp/msp430/* /usr/local/ && 15 | rm -rf /tmp/msp430 mspgcc*.tar.bz2 && 16 | msp430-gcc --version 17 | 18 | ## Install avr toolchain 19 | - sudo apt-get -qq install gcc-avr avr-libc 20 | 21 | ## Install 32-bit compatibility libraries 22 | - sudo apt-get -qq install libc6:i386 libgcc1:i386 gcc-4.6-base:i386 23 | libstdc++5:i386 libstdc++6:i386 24 | 25 | script: 26 | - make TARGET=sky DEFINES=COOJA=1,SINK=1 27 | - make TARGET=sky DEFINES=COOJA=1,SINK=0 28 | -------------------------------------------------------------------------------- /sdn-wise/packet-handler.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 SDN-WISE 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | /** 19 | * \file 20 | * Header file for SDN-WISE Packet Handler. 21 | * \author 22 | * Sebastiano Milardo 23 | */ 24 | 25 | /** 26 | * \addtogroup sdn-wise 27 | * @{ 28 | */ 29 | 30 | #ifndef PACKET_HANDLER_H_ 31 | #define PACKET_HANDLER_H_ 32 | 33 | #include "packet-buffer.h" 34 | 35 | /* Address API. */ 36 | void handle_packet(packet_t*); 37 | void test_handle_open_path(void); 38 | #endif /* PACKET_HANDLER_H_ */ 39 | /** @} */ 40 | -------------------------------------------------------------------------------- /sdn-wise-emulated/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /sdn-wise/sdn-wise.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 SDN-WISE 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | /** 19 | * \file 20 | * Header file for the SDN-WISE Contiki porting. 21 | * \author 22 | * Sebastiano Milardo 23 | */ 24 | 25 | /** 26 | * \defgroup sdn-wise SDN-WISE porting 27 | * @{ 28 | * 29 | * The SDN-WISE module implements SDN-WISE in Contiki. 30 | */ 31 | 32 | #ifndef SDN_WISE_H_ 33 | #define SDN_WISE_H_ 34 | 35 | #include "lib/list.h" 36 | #include "lib/memb.h" 37 | #include "packet-buffer.h" 38 | 39 | void rf_unicast_send(packet_t*); 40 | void rf_broadcast_send(packet_t*); 41 | 42 | #endif /* SDN_WISE_H_ */ 43 | /** @} */ 44 | -------------------------------------------------------------------------------- /sdn-wise/RUNME_st.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | TARGET="stm32f401re-nucleo-spirit1" 3 | BOARD="ids01a4" 4 | SENSORBOARD="iks01a1" 5 | 6 | mkdir cooja_firmwares 7 | 8 | make TARGET=$TARGET BOARD=$BOARD DEFINES=COOJA=0,SINK=1,_MY_ADDRESS=1,SDN_WISE_DEBUG=0 9 | arm-none-eabi-objcopy -O binary sdn-wise.$TARGET sdn-wise.$TARGET 10 | mv sdn-wise.$TARGET cooja_firmwares/sink.$TARGET 11 | make TARGET=$TARGET BOARD=$BOARD clean 12 | 13 | 14 | make TARGET=$TARGET BOARD=$BOARD DEFINES=COOJA=0,SINK=0,_MY_ADDRESS=2,SDN_WISE_DEBUG=1 15 | arm-none-eabi-objcopy -O binary sdn-wise.$TARGET sdn-wise_2.$TARGET 16 | mv sdn-wise_2.$TARGET cooja_firmwares/node_2.$TARGET 17 | make TARGET=$TARGET BOARD=$BOARD clean 18 | 19 | 20 | make TARGET=$TARGET BOARD=$BOARD SENSORBOARD=$SENSORBOARD DEFINES=COOJA=0,SINK=0,_MY_ADDRESS=3,SDN_WISE_DEBUG=1 21 | arm-none-eabi-objcopy -O binary sdn-wise.$TARGET sdn-wise_3.$TARGET 22 | mv sdn-wise_3.$TARGET cooja_firmwares/node_3.$TARGET 23 | make TARGET=$TARGET BOARD=$BOARD SENSORBOARD=$SENSORBOARD clean 24 | 25 | 26 | make TARGET=$TARGET BOARD=$BOARD SENSORBOARD=$SENSORBOARD DEFINES=COOJA=0,SINK=0,_MY_ADDRESS=4,SDN_WISE_DEBUG=1 27 | arm-none-eabi-objcopy -O binary sdn-wise.$TARGET sdn-wise_4.$TARGET 28 | mv sdn-wise_4.$TARGET cooja_firmwares/node_4.$TARGET 29 | make TARGET=$TARGET BOARD=$BOARD SENSORBOARD=$SENSORBOARD clean 30 | 31 | 32 | make TARGET=$TARGET BOARD=$BOARD clean 33 | -------------------------------------------------------------------------------- /sdn-wise/packet-creator.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 SDN-WISE 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | /** 19 | * \file 20 | * Header file for SDN-WISE Packet Creator. 21 | * \author 22 | * Sebastiano Milardo 23 | */ 24 | 25 | /** 26 | * \addtogroup sdn-wise 27 | * @{ 28 | */ 29 | 30 | #ifndef PACKET_CREATOR_H_ 31 | #define PACKET_CREATOR_H_ 32 | 33 | #define BEACON_HOPS_INDEX 0 34 | #define BEACON_BATT_INDEX 1 35 | #define REPORT_INIT_INDEX 2 36 | #define OPEN_PATH_WINDOWS_INDEX 0 37 | 38 | #include "packet-buffer.h" 39 | 40 | /* packets API. */ 41 | packet_t* create_beacon(void); 42 | packet_t* create_data(uint8_t); 43 | packet_t* create_report(void); 44 | packet_t* create_reg_proxy(void); 45 | void create_and_send_request(packet_t*); 46 | packet_t* create_config(void); 47 | #endif /* PACKET_CREATOR_H_ */ 48 | /** @} */ 49 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016, SDN-WISE Lab 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of sdn-wise-contiki nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /sdn-wise-emulated/src/org/contikios/cooja/sdnwise/CoojaMote.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 SDN-WISE 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package org.contikios.cooja.sdnwise;; 18 | 19 | import com.github.sdnwiselab.sdnwise.mote.battery.Battery; 20 | import com.github.sdnwiselab.sdnwise.mote.core.*; 21 | import com.github.sdnwiselab.sdnwise.util.NodeAddress; 22 | import org.contikios.cooja.*; 23 | 24 | /** 25 | * @author Sebastiano Milardo 26 | */ 27 | public class CoojaMote extends AbstractCoojaMote { 28 | 29 | public CoojaMote() { 30 | super(); 31 | } 32 | 33 | public CoojaMote(MoteType moteType, Simulation simulation) { 34 | super(moteType, simulation); 35 | } 36 | 37 | @Override 38 | public final void init() { 39 | battery = new Battery(); 40 | core = new MoteCore((byte) 1, new NodeAddress(this.getID()), battery); 41 | core.start(); 42 | startThreads(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM multiarch/ubuntu-core:i386-xenial 2 | MAINTAINER Sebastiano Milardo 3 | 4 | ENV JAVA_TOOL_OPTIONS -Dfile.encoding=UTF8 5 | ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-i386 6 | 7 | # On MAC OSX: 8 | # open -a XQuartz 9 | # ip=$(ifconfig en0 | grep inet | awk '$1=="inet" {print $2}') 10 | # xhost + $ip 11 | # docker run -it -v $(pwd):/src/sdn-wise-contiki -e DISPLAY=$ip:0 -v /tmp/.X11-unix:/tmp/.X11-unix sdn-wise-contiki 12 | 13 | # Update and install minimal 14 | RUN apt-get update \ 15 | && apt-get install \ 16 | --yes \ 17 | --no-install-recommends \ 18 | --no-install-suggests \ 19 | build-essential \ 20 | binutils-msp430 \ 21 | gcc-msp430 \ 22 | msp430-libc \ 23 | binutils-avr \ 24 | gcc-avr \ 25 | gdb-avr \ 26 | avr-libc \ 27 | avrdude \ 28 | binutils-arm-none-eabi \ 29 | gcc-arm-none-eabi \ 30 | gdb-arm-none-eabi \ 31 | openjdk-8-jdk \ 32 | openjdk-8-jre \ 33 | ant \ 34 | libncurses5-dev \ 35 | doxygen \ 36 | srecord \ 37 | git \ 38 | autoconf \ 39 | automake \ 40 | ca-certificates \ 41 | git \ 42 | libtool \ 43 | net-tools \ 44 | openssh-client \ 45 | patch \ 46 | curl \ 47 | iputils-ping \ 48 | 49 | # Clean up packages 50 | && apt-get clean \ 51 | && rm -rf /var/lib/apt/lists/* 52 | 53 | LABEL org.label-schema.name="SDN-WISE" \ 54 | org.label-schema.description="The stateful Software Defined Networking solution for the Internet of Things" \ 55 | org.label-schema.url="http://sdn-wise.dieei.unict.it/" \ 56 | org.label-schema.schema-version="1.0" 57 | 58 | WORKDIR /src/sdn-wise-contiki/contiki/tools/cooja 59 | CMD ["ant", "run"] 60 | -------------------------------------------------------------------------------- /sdn-wise/neighbor-table.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 SDN-WISE 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | /** 19 | * \file 20 | * Header file for the SDN-WISE Neighbor's table. 21 | * \author 22 | * Sebastiano Milardo 23 | */ 24 | 25 | /** 26 | * \addtogroup sdn-wise 27 | * @{ 28 | */ 29 | 30 | #ifndef NEIGHBOR_TABLE_H_ 31 | #define NEIGHBOR_TABLE_H_ 32 | 33 | #include "address.h" 34 | #include "packet-buffer.h" 35 | 36 | #define NEIGHBOR_LENGTH (ADDRESS_LENGTH + 1) 37 | 38 | typedef struct neighbor_struct { 39 | struct neighbor_struct *next; 40 | address_t address; 41 | uint8_t rssi; 42 | } neighbor_t; 43 | 44 | /* Header API. */ 45 | void add_neighbor(address_t*, uint8_t rssi); 46 | void purge_neighbor_table(void); 47 | void fill_payload_with_neighbors(packet_t*); 48 | void neighbor_table_init(void); 49 | void print_neighbor_table(void); 50 | void test_neighbor_table(void); 51 | neighbor_t* neighbor_table_contains(address_t*); 52 | uint8_t neighbor_cmp(neighbor_t*, neighbor_t*); 53 | #endif /* NEIGHBOR_TABLE_H_ */ 54 | /** @} */ -------------------------------------------------------------------------------- /sdn-wise/node-conf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 SDN-WISE 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | /** 19 | * \file 20 | * Header file for the SDN-WISE Node Configurations. 21 | * \author 22 | * Sebastiano Milardo 23 | */ 24 | 25 | /** 26 | * \addtogroup sdn-wise 27 | * @{ 28 | */ 29 | 30 | #ifndef NODE_CONF_H_ 31 | #define NODE_CONF_H_ 32 | 33 | #include 34 | #include "address.h" 35 | 36 | #define _NET 1 37 | #define _BEACON_PERIOD 5 38 | #define _REPORT_PERIOD 10 39 | #define _RESET_PERIOD 100 40 | #define _RULE_TTL 100 41 | #define _RSSI_MIN 0 42 | #define _RSSI_MAX 255 43 | #define _PACKET_TTL 100 44 | #define _MAX_DISTANCE _RSSI_MAX 45 | #define _MIN_DISTANCE 0 46 | 47 | typedef struct node_conf_struct { 48 | uint8_t my_net; 49 | address_t my_address; 50 | uint8_t packet_ttl; 51 | uint8_t rssi_min; 52 | uint16_t beacon_period; 53 | uint16_t report_period; 54 | uint16_t reset_period; 55 | uint16_t rule_ttl; 56 | address_t nxh_vs_sink; 57 | uint16_t distance_from_sink; 58 | uint8_t hops_from_sink; 59 | address_t sink_address; 60 | uint8_t is_active; 61 | uint8_t requests_count; 62 | } node_conf_t; 63 | 64 | extern node_conf_t conf; 65 | 66 | /* Node Configuration API. */ 67 | void node_conf_init(void); 68 | void print_node_conf(void); 69 | #endif /* NODE_CONF */ 70 | /** @} */ 71 | -------------------------------------------------------------------------------- /sdn-wise/address.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 SDN-WISE 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | /** 19 | * \file 20 | * Header file for the SDN-WISE Address. 21 | * \author 22 | * Sebastiano Milardo 23 | */ 24 | 25 | /** 26 | * \addtogroup sdn-wise 27 | * @{ 28 | */ 29 | 30 | #ifndef ADDRESS_H_ 31 | #define ADDRESS_H_ 32 | 33 | #include 34 | 35 | #define ADDRESS_LENGTH 2 36 | 37 | typedef struct __attribute__((__packed__)) address_struct { 38 | uint8_t u8[ADDRESS_LENGTH]; 39 | } address_t; 40 | 41 | typedef struct accepted_address_struct { 42 | struct accepted_address_struct* next; 43 | address_t address; 44 | } accepted_address_t; 45 | 46 | /* Address API. */ 47 | uint8_t is_broadcast(address_t*); 48 | uint8_t is_my_address(address_t*); 49 | void set_broadcast_address(address_t*); 50 | address_t get_address_from_array(uint8_t*); 51 | address_t get_address_from_int(uint16_t); 52 | void fill_array_with_address(uint8_t*, address_t*); 53 | uint8_t address_cmp(address_t*, address_t*); 54 | void print_address(address_t*); 55 | void swap_addresses(address_t*,address_t*); 56 | 57 | /* Accepted Address API. */ 58 | void address_list_init(void); 59 | void add_accepted_address(address_t*); 60 | accepted_address_t* address_list_contains(address_t*); 61 | void purge_address_list(void); 62 | void print_address_list(void); 63 | 64 | /* Test API. */ 65 | void test_address_list(void); 66 | 67 | 68 | #endif /* ADDRESS_H_ */ 69 | /** @} */ -------------------------------------------------------------------------------- /sdn-wise-emulated/src/org/contikios/cooja/sdnwise/SdnWiseMoteType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009, Swedish Institute of Computer Science. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of the Institute nor the names of its contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | * 29 | * 30 | */ 31 | 32 | package org.contikios.cooja.sdnwise; 33 | 34 | import java.io.File; 35 | 36 | import org.contikios.cooja.AbstractionLevelDescription; 37 | import org.contikios.cooja.ClassDescription; 38 | import org.contikios.cooja.motes.*; 39 | 40 | /** 41 | * @author Sebastiano Milardo 42 | */ 43 | @ClassDescription("SDN-WISE Emulated Mote") 44 | @AbstractionLevelDescription("Application level") 45 | public class SdnWiseMoteType extends ImportAppMoteType { 46 | 47 | public SdnWiseMoteType() { 48 | super(); 49 | setDescription("SDN-WISE Emulated Mote"); 50 | setMoteClassPath(new File("../../../../sdn-wise-emulated/build")); 51 | setMoteClassName("org.contikios.cooja.sdnwise.CoojaMote"); 52 | } 53 | 54 | public SdnWiseMoteType(String identifier) { 55 | super(identifier); 56 | setDescription("SDN-WISE Emulated Mote #" + identifier); 57 | setMoteClassPath(new File("../../../../sdn-wise-emulated/build")); 58 | setMoteClassName("org.contikios.cooja.sdnwise.CoojaMote"); 59 | } 60 | } 61 | 62 | -------------------------------------------------------------------------------- /sdn-wise-emulated/src/org/contikios/cooja/sdnwise/SdnWiseSinkType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009, Swedish Institute of Computer Science. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of the Institute nor the names of its contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | * 29 | * 30 | */ 31 | 32 | package org.contikios.cooja.sdnwise; 33 | 34 | import java.io.File; 35 | 36 | import org.contikios.cooja.AbstractionLevelDescription; 37 | import org.contikios.cooja.ClassDescription; 38 | import org.contikios.cooja.motes.*; 39 | 40 | /** 41 | * @author Sebastiano Milardo 42 | */ 43 | @ClassDescription("SDN-WISE Emulated Sink") 44 | @AbstractionLevelDescription("Application level") 45 | public class SdnWiseSinkType extends ImportAppMoteType { 46 | 47 | public SdnWiseSinkType() { 48 | super(); 49 | setDescription("SDN-WISE Emulated Sink"); 50 | setMoteClassPath(new File("../../../../sdn-wise-emulated/build")); 51 | setMoteClassName("org.contikios.cooja.sdnwise.CoojaSink"); 52 | } 53 | 54 | public SdnWiseSinkType(String identifier) { 55 | super(identifier); 56 | setDescription("SDN-WISE Emulated Sink #" + identifier); 57 | setMoteClassPath(new File("../../../../sdn-wise-emulated/build")); 58 | setMoteClassName("org.contikios.cooja.sdnwise.CoojaSink"); 59 | } 60 | } 61 | 62 | -------------------------------------------------------------------------------- /sdn-wise/packet-buffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 SDN-WISE 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | /** 19 | * \file 20 | * Header file for the SDN-WISE Packet buffer. 21 | * \author 22 | * Sebastiano Milardo 23 | */ 24 | 25 | /** 26 | * \addtogroup sdn-wise 27 | * @{ 28 | */ 29 | 30 | #ifndef PACKET_BUFFER_H_ 31 | #define PACKET_BUFFER_H_ 32 | 33 | #include "address.h" 34 | 35 | #define ADDRESS_LENGTH 2 36 | 37 | #define NET_INDEX (0) 38 | #define LEN_INDEX (NET_INDEX + 1) 39 | #define DST_INDEX (LEN_INDEX + 1) 40 | #define SRC_INDEX (DST_INDEX + ADDRESS_LENGTH) 41 | #define TYP_INDEX (SRC_INDEX + ADDRESS_LENGTH) 42 | #define TTL_INDEX (TYP_INDEX + 1) 43 | #define NXH_INDEX (TTL_INDEX + 1) 44 | #define PLD_INDEX (NXH_INDEX + ADDRESS_LENGTH) 45 | 46 | #define MAX_PAYLOAD_LENGTH 106 47 | #define MAX_PACKET_LENGTH (MAX_PAYLOAD_LENGTH + PLD_INDEX) 48 | 49 | typedef enum __attribute__((__packed__)) packet_type{ 50 | DATA, 51 | BEACON, 52 | REPORT, 53 | REQUEST, 54 | RESPONSE, 55 | OPEN_PATH, 56 | CONFIG, 57 | REG_PROXY 58 | } packet_type_t; 59 | 60 | typedef struct __attribute__((__packed__)) packet_info { 61 | uint8_t rssi; 62 | } packet_info_t; 63 | 64 | typedef struct __attribute__((__packed__)) packet_header { 65 | uint8_t net; 66 | uint8_t len; 67 | address_t dst; 68 | address_t src; 69 | packet_type_t typ; 70 | uint8_t ttl; 71 | address_t nxh; 72 | } header_t; 73 | 74 | typedef struct __attribute__((__packed__)) packet_struct { 75 | header_t header; 76 | uint8_t payload[MAX_PAYLOAD_LENGTH]; 77 | packet_info_t info; 78 | struct packet_struct *next; 79 | } packet_t; 80 | 81 | /* Header API. */ 82 | packet_t* get_packet_from_array(uint8_t*); 83 | uint8_t get_payload_at(packet_t*, uint8_t); 84 | void set_payload_at(packet_t*, uint8_t, uint8_t); 85 | void restore_ttl(packet_t*); 86 | 87 | packet_t* create_packet(uint8_t, address_t*, address_t*, packet_type_t, 88 | address_t*); 89 | packet_t* create_packet_empty(void); 90 | packet_t* create_packet_payload(uint8_t, address_t*, address_t*, packet_type_t, 91 | address_t*, uint8_t*, uint8_t); 92 | void packet_deallocate(packet_t*); 93 | 94 | void packet_buffer_init(void); 95 | void print_packet(packet_t*); 96 | void print_packet_uart(packet_t*); 97 | 98 | void test_packet_buffer(void); 99 | 100 | #endif /* PACKET_BUFFER_H_ */ 101 | /** @} */ 102 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | SDN-WISE-CONTIKI 2 | ==================================== 3 | [![Build Status](https://travis-ci.org/sdnwiselab/sdn-wise-contiki.svg?branch=master)](https://travis-ci.org/sdnwiselab/sdn-wise-contiki) 4 | [![Analytics](https://ga-beacon.appspot.com/UA-112624043-2/sdn-wise-contiki/readme)](https://github.com/sdnwiselab/sdn-wise-contiki) 5 | 6 | The Open Source OS for the Internet of Things meets the Software Defined Networking. 7 | 8 | ### Build 9 | 10 | To build SDN-WISE run the `sdn-wise/RUNME.sh` script. 11 | 12 | To select the target for your build change the `TARGET` variable inside this script with one of the supported contiki [platforms](http://www.contiki-os.org/hardware.html). 13 | 14 | To build SDN-WISE for Cooja emulated devices please set `COOJA_BUILD=1` otherwise set `COOJA_BUILD=0`. 15 | 16 | The script will deploy two compiled firmwares inside `sdn-wise/cooja_firmware`. One for the sink of the network, called `sink.target`, and one for the other nodes, called `node.target`. 17 | 18 | 19 | ### Versioning 20 | 21 | This project uses [semantic versioning](http://semver.org). 22 | 23 | ## Papers 24 | 25 | Our approach is detailed in four scientific contributions: 26 | ``` 27 | @article{Anadiotis:2019, 28 | author = {{Angelos-Christos} Anadiotis and Laura Galluccio and Sebastiano Milardo and Giacomo Morabito and Sergio Palazzo}, 29 | title = {{SD-WISE: A Software-Defined WIreless SEnsor network}}, 30 | journal = {Computer Networks}, 31 | volume = {159}, 32 | pages = {84 - 95}, 33 | year = {2019}, 34 | doi = {10.1016/j.comnet.2019.04.029}, 35 | url = {http://www.sciencedirect.com/science/article/pii/S1389128618312192}, 36 | } 37 | ``` 38 | 39 | ``` 40 | @inproceedings{DiDio:2016, 41 | author = {Paolo {Di Dio} and Salvatore Faraci and Laura Galluccio and Sebastiano Milardo and Giacomo Morabito and Sergio Palazzo and Patrizia Livreri}, 42 | booktitle = {2016 Mediterranean Ad Hoc Networking Workshop (Med-Hoc-Net)}, 43 | doi = {10.1109/MedHocNet.2016.7528421}, 44 | title = {{Exploiting state information to support QoS in Software-Defined WSNs}}, 45 | year = {2016}, 46 | url = {http://ieeexplore.ieee.org/document/7528421/}, 47 | } 48 | ``` 49 | 50 | ``` 51 | @inproceedings{Galluccio:2015b, 52 | author = {Laura Galluccio and Sebastiano Milardo and Giacomo Morabito and Sergio Palazzo}, 53 | booktitle = {2015 IEEE Conference on Computer Communications Workshops (INFOCOM WKSHPS)}, 54 | doi = {10.1109/INFCOMW.2015.7179322}, 55 | title = {{Reprogramming Wireless Sensor Networks by using SDN-WISE: A hands-on demo}}, 56 | year = {2015}, 57 | url = {http://ieeexplore.ieee.org/document/7179322/}, 58 | } 59 | ``` 60 | 61 | ``` 62 | @inproceedings{Galluccio:2015a, 63 | author = {Laura Galluccio and Sebastiano Milardo and Giacomo Morabito and Sergio Palazzo}, 64 | booktitle = {2015 IEEE Conference on Computer Communications (INFOCOM)}, 65 | doi = {10.1109/INFOCOM.2015.7218418}, 66 | title = {{SDN-WISE: Design, prototyping and experimentation of a stateful SDN solution for WIreless SEnsor networks}}, 67 | year = {2015}, 68 | url = {http://ieeexplore.ieee.org/document/7218418/}, 69 | } 70 | ``` 71 | 72 | -------------------------------------------------------------------------------- /sdn-wise/node-conf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 SDN-WISE 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | /** 19 | * \file 20 | * SDN-WISE Node Configurations. 21 | * \author 22 | * Sebastiano Milardo 23 | */ 24 | 25 | /** 26 | * \addtogroup sdn-wise 27 | * @{ 28 | */ 29 | 30 | #include 31 | 32 | #include "address.h" 33 | #include "node-conf.h" 34 | #include "net/rime/rime.h" 35 | 36 | #ifndef SDN_WISE_DEBUG 37 | #define SDN_WISE_DEBUG 0 38 | #endif 39 | #if SDN_WISE_DEBUG 40 | #include 41 | #define PRINTF(...) printf(__VA_ARGS__) 42 | #else 43 | #define PRINTF(...) 44 | #endif 45 | /*----------------------------------------------------------------------------*/ 46 | node_conf_t conf; 47 | /*----------------------------------------------------------------------------*/ 48 | void 49 | node_conf_init(void) 50 | { 51 | 52 | #if COOJA 53 | conf.my_address.u8[1] = linkaddr_node_addr.u8[0]; 54 | conf.my_address.u8[0] = linkaddr_node_addr.u8[1]; 55 | #else 56 | conf.my_address = get_address_from_int(_MY_ADDRESS); 57 | linkaddr_node_addr.u8[1] = conf.my_address.u8[0]; 58 | linkaddr_node_addr.u8[0] = conf.my_address.u8[1]; 59 | #endif 60 | conf.requests_count = 0; 61 | conf.my_net = _NET; 62 | conf.beacon_period = _BEACON_PERIOD; 63 | conf.report_period = _REPORT_PERIOD; 64 | conf.rule_ttl = _RULE_TTL; 65 | conf.rssi_min = _RSSI_MIN; 66 | conf.packet_ttl = _PACKET_TTL; 67 | #if SINK 68 | conf.is_active = 1; 69 | conf.nxh_vs_sink = conf.my_address; 70 | conf.sink_address = conf.my_address; 71 | conf.distance_from_sink = _MIN_DISTANCE; 72 | conf.hops_from_sink = 0; 73 | #else 74 | conf.is_active = 0; 75 | set_broadcast_address(&(conf.nxh_vs_sink)); 76 | set_broadcast_address(&(conf.sink_address)); 77 | conf.distance_from_sink = _MAX_DISTANCE; 78 | conf.hops_from_sink = _PACKET_TTL; 79 | conf.reset_period = _RESET_PERIOD; 80 | #endif 81 | } 82 | /*----------------------------------------------------------------------------*/ 83 | void 84 | print_node_conf(void){ 85 | PRINTF("[CFG]: NODE: "); 86 | print_address(&(conf.my_address)); 87 | PRINTF("\n"); 88 | PRINTF("[CFG]: - Network ID: %d\n[CFG]: - Beacon Period: %d\n[CFG]: - " 89 | "Report Period: %d\n[CFG]: - Rules TTL: %d\n[CFG]: - Min RSSI: " 90 | "%d\n[CFG]: - Packet TTL: %d\n[CFG]: - Next Hop -> Sink: ", 91 | conf.my_net, conf.beacon_period, conf.report_period, 92 | conf.rule_ttl, conf.rssi_min, conf.packet_ttl); 93 | print_address(&(conf.nxh_vs_sink)); 94 | PRINTF(" (hops: %d, distance: %d)\n", conf.hops_from_sink, conf.distance_from_sink); 95 | PRINTF("[CFG]: - Sink: "); 96 | print_address(&(conf.sink_address)); 97 | PRINTF("\n"); 98 | } 99 | /*----------------------------------------------------------------------------*/ 100 | /** @} */ 101 | -------------------------------------------------------------------------------- /sdn-wise/flowtable.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 SDN-WISE 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | /** 19 | * \file 20 | * Header file implementing a FlowTable in Contiki. 21 | * \author 22 | * Sebastiano Milardo 23 | */ 24 | 25 | /** 26 | * \addtogroup sdn-wise 27 | * @{ 28 | */ 29 | 30 | #ifndef FLOWTABLE_H_ 31 | #define FLOWTABLE_H_ 32 | 33 | #include "packet-buffer.h" 34 | #include "lib/list.h" 35 | 36 | #define MERGE_BYTES(a,b) ((a << 8) | b) 37 | #define WINDOW_SIZE 5 38 | 39 | typedef enum action_type { 40 | NULL_TYPE, 41 | FORWARD_U, 42 | FORWARD_B, 43 | DROP, 44 | ASK, 45 | FUNCTION, 46 | SET_, 47 | MATCH 48 | } action_type_t; 49 | 50 | typedef enum operator_location { 51 | NULL_LOC, 52 | CONST, 53 | PACKET, 54 | STATUS 55 | } operator_location_t; 56 | 57 | typedef enum operator_size { 58 | SIZE_1, 59 | SIZE_2 60 | } operator_size_t; 61 | 62 | typedef enum operator_name { 63 | EQUAL, 64 | NOT_EQUAL, 65 | GREATER, 66 | LESS, 67 | GREATER_OR_EQUAL, 68 | LESS_OR_EQUAL 69 | } operator_t; 70 | 71 | typedef enum set_name { 72 | ADD, 73 | SUB, 74 | DIV, 75 | MUL, 76 | MOD, 77 | AND, 78 | OR, 79 | XOR 80 | } set_operator_t; 81 | 82 | typedef struct window{ 83 | struct window *next; 84 | operator_t operation; 85 | operator_size_t size; 86 | operator_location_t lhs_location; 87 | operator_location_t rhs_location; 88 | uint16_t lhs; 89 | uint16_t rhs; 90 | } window_t; 91 | 92 | typedef struct byte{ 93 | struct byte *next; 94 | uint8_t value; 95 | } byte_t; 96 | 97 | typedef struct action{ 98 | struct action *next; 99 | action_type_t type; 100 | LIST_STRUCT(bytes); 101 | } action_t; 102 | 103 | typedef struct stats{ 104 | uint16_t ttl; 105 | uint16_t count; 106 | } stats_t; 107 | 108 | typedef struct entry{ 109 | struct entry *next; 110 | LIST_STRUCT(windows); 111 | LIST_STRUCT(actions); 112 | stats_t stats; 113 | } entry_t; 114 | 115 | /* FlowTable API. */ 116 | void flowtable_init(void); 117 | void test_flowtable(void); 118 | entry_t* get_entry_from_array(uint8_t*, uint16_t); 119 | void print_flowtable(void); 120 | void print_entry(entry_t*); 121 | uint8_t action_cmp(action_t*, action_t*); 122 | uint8_t window_cmp(window_t*, window_t*); 123 | uint8_t entry_cmp(entry_t*, entry_t*); 124 | void add_entry(entry_t*); 125 | window_t* get_window_from_array(uint8_t*); 126 | 127 | uint8_t get_array_from_window(uint8_t*, window_t*); 128 | uint8_t get_array_from_action(uint8_t*, action_t*); 129 | uint8_t get_array_from_entry(uint8_t*, entry_t*); 130 | uint8_t get_array_from_entry_id(uint8_t*, int); 131 | 132 | entry_t* create_entry(void); 133 | window_t* create_window(void); 134 | action_t* create_action(action_type_t, uint8_t*, uint8_t); 135 | void add_window(entry_t*, window_t*); 136 | void add_action(entry_t*, action_t*); 137 | 138 | void match_packet(packet_t*); 139 | int match_entry(packet_t*, entry_t*); 140 | int match_window(packet_t*,uint8_t* s, window_t*); 141 | int run_action(packet_t*, uint8_t* s, action_t*); 142 | #endif /* FLOWTABLE_H_ */ 143 | /** @} */ 144 | -------------------------------------------------------------------------------- /sdn-wise-emulated/src/org/contikios/cooja/sdnwise/CoojaSink.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 SDN-WISE 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package org.contikios.cooja.sdnwise;; 18 | 19 | import com.github.sdnwiselab.sdnwise.mote.battery.SinkBattery; 20 | import com.github.sdnwiselab.sdnwise.mote.core.*; 21 | import com.github.sdnwiselab.sdnwise.packet.NetworkPacket; 22 | import com.github.sdnwiselab.sdnwise.util.NodeAddress; 23 | import java.io.*; 24 | import java.net.*; 25 | import java.util.logging.*; 26 | import javax.swing.JOptionPane; 27 | import org.contikios.cooja.*; 28 | 29 | /** 30 | * @author Sebastiano Milardo 31 | */ 32 | public class CoojaSink extends AbstractCoojaMote { 33 | 34 | private Socket tcpSocket; 35 | private DataInputStream riceviOBJ; 36 | private DataOutputStream inviaOBJ; 37 | private InetAddress addrController; 38 | private int portController; 39 | 40 | public CoojaSink() { 41 | super(); 42 | } 43 | 44 | public CoojaSink(MoteType moteType, Simulation simulation) { 45 | super(moteType, simulation); 46 | } 47 | 48 | @Override 49 | public final void init() { 50 | try { 51 | battery = new SinkBattery(); 52 | String[] tmp = getControllerIpPort(); 53 | 54 | addrController = InetAddress.getByName(tmp[0]); 55 | portController = Integer.parseInt(tmp[1]); 56 | 57 | core = new SinkCore((byte) 1, 58 | new NodeAddress(this.getID()), 59 | battery, 60 | "00000001", 61 | "00:01:02:03:04:05", 62 | 1, 63 | addrController, 64 | portController); 65 | core.start(); 66 | startThreads(); 67 | } catch (UnknownHostException ex) { 68 | log(ex.getLocalizedMessage()); 69 | } 70 | } 71 | 72 | private class TcpListener implements Runnable { 73 | 74 | @Override 75 | public void run() { 76 | try { 77 | riceviOBJ = new DataInputStream(tcpSocket.getInputStream()); 78 | while (true) { 79 | NetworkPacket np = new NetworkPacket(riceviOBJ); 80 | core.rxRadioPacket(np, 255); 81 | } 82 | } catch (IOException ex) { 83 | Logger.getLogger(CoojaSink.class.getName()).log(Level.SEVERE, null, ex); 84 | } 85 | } 86 | } 87 | 88 | private class TcpSender implements Runnable { 89 | 90 | @Override 91 | public void run() { 92 | try { 93 | inviaOBJ = new DataOutputStream(tcpSocket.getOutputStream()); 94 | while (true) { 95 | NetworkPacket np = ((SinkCore) core).getControllerPacketTobeSend(); 96 | inviaOBJ.write(np.toByteArray()); 97 | } 98 | } catch (IOException | InterruptedException ex) { 99 | Logger.getLogger(CoojaSink.class.getName()).log(Level.SEVERE, null, ex); 100 | } 101 | } 102 | } 103 | 104 | @Override 105 | void startThreads() { 106 | super.startThreads(); 107 | try { 108 | tcpSocket = new Socket(addrController, portController); 109 | new Thread(new TcpListener()).start(); 110 | new Thread(new TcpSender()).start(); 111 | } catch (IOException ex) { 112 | log(ex.getLocalizedMessage() + " " + addrController + ":" + portController); 113 | } 114 | 115 | } 116 | 117 | private String[] getControllerIpPort() { 118 | String s = (String) JOptionPane.showInputDialog(null, 119 | "Please insert the IP address and TCP port of the controller:", 120 | "SDN-WISE Sink", 121 | JOptionPane.QUESTION_MESSAGE, null, null, "192.168.1.101:9999"); 122 | 123 | String[] tmp = s.split(":"); 124 | 125 | if (tmp.length != 2) { 126 | return getControllerIpPort(); 127 | } else { 128 | return tmp; 129 | } 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /sdn-wise/neighbor-table.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 SDN-WISE 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | /** 19 | * \file 20 | * SDN-WISE Neighbor's table. 21 | * \author 22 | * Sebastiano Milardo 23 | */ 24 | 25 | /** 26 | * \addtogroup sdn-wise 27 | * @{ 28 | */ 29 | 30 | #include 31 | 32 | #include "lib/memb.h" 33 | #include "lib/list.h" 34 | 35 | #include "packet-buffer.h" 36 | #include "neighbor-table.h" 37 | #include "packet-creator.h" 38 | 39 | #ifndef SDN_WISE_DEBUG 40 | #define SDN_WISE_DEBUG 0 41 | #endif 42 | #if SDN_WISE_DEBUG 43 | #include 44 | #define PRINTF(...) printf(__VA_ARGS__) 45 | #else 46 | #define PRINTF(...) 47 | #endif 48 | /*----------------------------------------------------------------------------*/ 49 | LIST(neighbor_table); 50 | MEMB(neighbors_memb, neighbor_t, (MAX_PAYLOAD_LENGTH) / (NEIGHBOR_LENGTH)); 51 | /*----------------------------------------------------------------------------*/ 52 | static neighbor_t * neighbor_allocate(void); 53 | static void neighbor_free(neighbor_t *); 54 | static void print_neighbor(neighbor_t*); 55 | /*----------------------------------------------------------------------------*/ 56 | static void 57 | print_neighbor(neighbor_t* n) 58 | { 59 | print_address(&(n->address)); 60 | PRINTF("%d",n->rssi); 61 | } 62 | /*----------------------------------------------------------------------------*/ 63 | void 64 | print_neighbor_table(void) 65 | { 66 | neighbor_t *n; 67 | for(n = list_head(neighbor_table); n != NULL; n = n->next) { 68 | PRINTF("[NGT]: "); 69 | print_neighbor(n); 70 | PRINTF("\n"); 71 | } 72 | } 73 | /*----------------------------------------------------------------------------*/ 74 | void 75 | purge_neighbor_table(void) 76 | { 77 | neighbor_t *n; 78 | neighbor_t *next; 79 | 80 | for(n = list_head(neighbor_table); n != NULL;) { 81 | next = n->next; 82 | neighbor_free(n); 83 | n = next; 84 | } 85 | } 86 | /*----------------------------------------------------------------------------*/ 87 | static neighbor_t * 88 | neighbor_allocate(void) 89 | { 90 | neighbor_t *p; 91 | p = memb_alloc(&neighbors_memb); 92 | if(p == NULL) { 93 | PRINTF("[NGT]: Failed to allocate a neighbor\n"); 94 | } 95 | return p; 96 | } 97 | /*----------------------------------------------------------------------------*/ 98 | static void 99 | neighbor_free(neighbor_t* n) 100 | { 101 | list_remove(neighbor_table, n); 102 | int res = memb_free(&neighbors_memb, n); 103 | if (res !=0){ 104 | PRINTF("[NGT]: Failed to free a neighbor. Reference count: %d\n",res); 105 | } 106 | } 107 | /*----------------------------------------------------------------------------*/ 108 | uint8_t 109 | neighbor_cmp(neighbor_t* a, neighbor_t* b) 110 | { 111 | return address_cmp(&(a->address),&(b->address)); 112 | } 113 | /*----------------------------------------------------------------------------*/ 114 | neighbor_t* 115 | neighbor_table_contains(address_t* a) 116 | { 117 | neighbor_t* tmp; 118 | for(tmp = list_head(neighbor_table); tmp != NULL; tmp = tmp->next) { 119 | if(address_cmp(&(tmp->address),a)){ 120 | return tmp; 121 | } 122 | } 123 | return NULL; 124 | } 125 | /*----------------------------------------------------------------------------*/ 126 | void 127 | add_neighbor(address_t* address, uint8_t rssi) 128 | { 129 | neighbor_t* res = neighbor_table_contains(address); 130 | if (res == NULL){ 131 | neighbor_t* n = neighbor_allocate(); 132 | if (n != NULL){ 133 | memset(n, 0, sizeof(*n)); 134 | n->address = *address; 135 | n->rssi = rssi; 136 | list_add(neighbor_table,n); 137 | } 138 | } else { 139 | res->rssi = rssi; 140 | } 141 | } 142 | /*----------------------------------------------------------------------------*/ 143 | void 144 | fill_payload_with_neighbors(packet_t* p) 145 | { 146 | uint8_t i = REPORT_INIT_INDEX; 147 | set_payload_at(p,i,(uint8_t)(list_length(neighbor_table) & 0xFF)); 148 | i++; 149 | neighbor_t *n; 150 | for(n = list_head(neighbor_table); n != NULL; n = n->next) { 151 | uint8_t j = 0; 152 | for (j = 0; j < ADDRESS_LENGTH; ++j){ 153 | set_payload_at(p,i,n->address.u8[j]); 154 | ++i; 155 | } 156 | set_payload_at(p,i,n->rssi); 157 | ++i; 158 | } 159 | purge_neighbor_table(); 160 | } 161 | /*----------------------------------------------------------------------------*/ 162 | void 163 | neighbor_table_init(void) 164 | { 165 | list_init(neighbor_table); 166 | memb_init(&neighbors_memb); 167 | } 168 | /*----------------------------------------------------------------------------*/ 169 | void 170 | test_neighbor_table(void) 171 | { 172 | address_t addr1; 173 | addr1.u8[0] = 1; 174 | addr1.u8[1] = 1; 175 | uint8_t rssi1 = 100; 176 | 177 | address_t addr3; 178 | addr3.u8[0] = 1; 179 | addr3.u8[1] = 1; 180 | uint8_t rssi3 = 50; 181 | 182 | address_t addr2; 183 | addr2.u8[0] = 2; 184 | addr2.u8[1] = 2; 185 | uint8_t rssi2 = 200; 186 | 187 | if (!list_length(neighbor_table)){ 188 | add_neighbor(&addr1,rssi1); 189 | add_neighbor(&addr2,rssi2); 190 | add_neighbor(&addr3,rssi3); 191 | print_neighbor_table(); 192 | }else{ 193 | purge_neighbor_table(); 194 | print_neighbor_table(); 195 | } 196 | } 197 | /*----------------------------------------------------------------------------*/ 198 | /** @} */ 199 | -------------------------------------------------------------------------------- /sdn-wise/packet-buffer.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 SDN-WISE 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | /** 19 | * \file 20 | * SDN-WISE Packet buffer. 21 | * \author 22 | * Sebastiano Milardo 23 | */ 24 | 25 | /** 26 | * \addtogroup sdn-wise 27 | * @{ 28 | */ 29 | 30 | #include 31 | #include 32 | #include "lib/memb.h" 33 | #include "lib/list.h" 34 | 35 | #include "packet-buffer.h" 36 | #include "address.h" 37 | 38 | #define MAX_TTL 100 39 | 40 | #ifndef SDN_WISE_DEBUG 41 | #define SDN_WISE_DEBUG 0 42 | #endif 43 | #if SDN_WISE_DEBUG 44 | #define PRINTF(...) printf(__VA_ARGS__) 45 | #else 46 | #define PRINTF(...) 47 | #endif 48 | /*----------------------------------------------------------------------------*/ 49 | MEMB(packets_memb, packet_t, 4); 50 | /*----------------------------------------------------------------------------*/ 51 | static packet_t * packet_allocate(void); 52 | /*----------------------------------------------------------------------------*/ 53 | void 54 | print_packet_uart(packet_t* p) 55 | { 56 | uint16_t i = 0; 57 | putchar(122); 58 | uint8_t* tmp = (uint8_t*)p; 59 | for (i = 0; i< p->header.len; ++i){ 60 | putchar(tmp[i]); 61 | } 62 | putchar(126); 63 | putchar('\n'); 64 | packet_deallocate(p); 65 | } 66 | /*----------------------------------------------------------------------------*/ 67 | void 68 | print_packet(packet_t* p) 69 | { 70 | uint16_t i = 0; 71 | PRINTF("%d %d ", p->header.net, p->header.len); 72 | print_address(&(p->header.dst)); 73 | print_address(&(p->header.src)); 74 | PRINTF("%d %d ", p->header.typ, p->header.ttl); 75 | print_address(&(p->header.nxh)); 76 | for (i=0; i < (p->header.len - PLD_INDEX); ++i){ 77 | PRINTF("%d ",get_payload_at(p,i)); 78 | } 79 | } 80 | /*----------------------------------------------------------------------------*/ 81 | static packet_t * 82 | packet_allocate(void) 83 | { 84 | packet_t *p = NULL; 85 | p = memb_alloc(&packets_memb); 86 | if(p == NULL) { 87 | PRINTF("[PBF]: Failed to allocate a packet\n"); 88 | } 89 | return p; 90 | } 91 | /*----------------------------------------------------------------------------*/ 92 | void 93 | packet_deallocate(packet_t* p) 94 | { 95 | int res = memb_free(&packets_memb, p); 96 | if (res !=0){ 97 | PRINTF("[FLT]: Failed to deallocate a packet. Reference count: %d\n",res); 98 | } 99 | } 100 | /*----------------------------------------------------------------------------*/ 101 | packet_t* 102 | create_packet_payload(uint8_t net, address_t* dst, address_t* src, 103 | packet_type_t typ, address_t* nxh, uint8_t* payload, uint8_t len) 104 | { 105 | packet_t* p = create_packet(net, dst, src, typ, nxh); 106 | if (p != NULL){ 107 | uint8_t i; 108 | 109 | for (i = 0; i < len; ++i){ 110 | set_payload_at(p, i, payload[i]); 111 | } 112 | } 113 | return p; 114 | } 115 | /*----------------------------------------------------------------------------*/ 116 | packet_t* 117 | get_packet_from_array(uint8_t* array) 118 | { 119 | // TODO fragmentation 120 | // This works if the compiler complies with __attribute__((__packed__)) 121 | packet_t* p = packet_allocate(); 122 | if (p != NULL){ 123 | memcpy((uint8_t*)p, array, array[LEN_INDEX]); 124 | } 125 | return p; 126 | } 127 | /*----------------------------------------------------------------------------*/ 128 | uint8_t 129 | get_payload_at(packet_t* p, uint8_t index) 130 | { 131 | if (index < MAX_PACKET_LENGTH){ 132 | return p->payload[index]; 133 | } else { 134 | return 0; 135 | } 136 | } 137 | /*----------------------------------------------------------------------------*/ 138 | void 139 | set_payload_at(packet_t* p, uint8_t index, uint8_t value) 140 | { 141 | if (index < MAX_PACKET_LENGTH){ 142 | p->payload[index] = value; 143 | if (index + PLD_INDEX + 1 > p->header.len){ 144 | p->header.len = index + PLD_INDEX + 1; 145 | } 146 | } 147 | } 148 | /*----------------------------------------------------------------------------*/ 149 | void 150 | restore_ttl(packet_t* p) 151 | { 152 | p->header.ttl = MAX_TTL; 153 | } 154 | /*----------------------------------------------------------------------------*/ 155 | packet_t* 156 | create_packet_empty(void) 157 | { 158 | packet_t* p = packet_allocate(); 159 | if (p != NULL){ 160 | memset(&(p->header), 0, sizeof(p->header)); 161 | memset(&(p->info), 0, sizeof(p->info)); 162 | restore_ttl(p); 163 | } 164 | return p; 165 | } 166 | /*----------------------------------------------------------------------------*/ 167 | packet_t* 168 | create_packet(uint8_t net, address_t* dst, address_t* src, packet_type_t typ, 169 | address_t* nxh) 170 | { 171 | packet_t* p = packet_allocate(); 172 | if (p != NULL){ 173 | memset(&(p->header), 0, sizeof(p->header)); 174 | memset(&(p->info), 0, sizeof(p->info)); 175 | p->header.net=net; 176 | p->header.dst=*dst; 177 | p->header.src=*src; 178 | p->header.typ=typ; 179 | p->header.nxh=*nxh; 180 | restore_ttl(p); 181 | } 182 | return p; 183 | } 184 | /*----------------------------------------------------------------------------*/ 185 | void 186 | packet_buffer_init(void) 187 | { 188 | memb_init(&packets_memb); 189 | } 190 | 191 | /*----------------------------------------------------------------------------*/ 192 | void 193 | test_packet_buffer(void) 194 | { 195 | uint8_t array[73] = {1, 73, 0, 0, 0, 2, 4, 100, 0, 0, 20, 18, 0, 6, 0, 10, 196 | 18, 0, 50, 0, 1, 90, 0, 10, 0, 1, 122, 0, 12, 0, 5, 1, 4, 8, 6, 2, 0, 10, 197 | 0, 40, 0, 0, 8, 5, 1, 0, 0, 0, 0, 0, 0, 1, 3, 3, 2, 255, 255, 3, 1, 0, 3, 198 | 1, 7, 8, 6, 132, 0, 11, 0, 12, 0, 13, 254}; 199 | 200 | packet_t* second = get_packet_from_array(array); 201 | print_packet(second); 202 | } 203 | /*----------------------------------------------------------------------------*/ 204 | /** @} */ 205 | -------------------------------------------------------------------------------- /sdn-wise/address.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 SDN-WISE 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | /** 19 | * \file 20 | * SDN-WISE Address. 21 | * \author 22 | * Sebastiano Milardo 23 | */ 24 | 25 | /** 26 | * \addtogroup sdn-wise 27 | * @{ 28 | */ 29 | 30 | #include 31 | #include 32 | 33 | #include "lib/memb.h" 34 | #include "lib/list.h" 35 | 36 | #include "address.h" 37 | #include "node-conf.h" 38 | 39 | #ifndef SDN_WISE_DEBUG 40 | #define SDN_WISE_DEBUG 0 41 | #endif 42 | #if SDN_WISE_DEBUG 43 | #define PRINTF(...) printf(__VA_ARGS__) 44 | #else 45 | #define PRINTF(...) 46 | #endif 47 | /*----------------------------------------------------------------------------*/ 48 | LIST(address_list); 49 | MEMB(addresses_memb, accepted_address_t, 4); 50 | /*----------------------------------------------------------------------------*/ 51 | static void accepted_address_free(accepted_address_t*); 52 | static accepted_address_t * accepted_address_allocate(void); 53 | /*----------------------------------------------------------------------------*/ 54 | void swap_addresses(address_t* a, address_t* b) 55 | { 56 | address_t tmp = *a; 57 | *a = *b; 58 | *b = tmp; 59 | } 60 | /*----------------------------------------------------------------------------*/ 61 | uint8_t 62 | is_my_address(address_t* a) 63 | { 64 | return (address_cmp(&(conf.my_address), a) || address_list_contains(a)); 65 | } 66 | /*----------------------------------------------------------------------------*/ 67 | void 68 | print_address(address_t* a) 69 | { 70 | uint16_t i = 0; 71 | for (i=0;iu8[i]); 73 | } 74 | PRINTF("%d ",a->u8[i]); 75 | } 76 | /*----------------------------------------------------------------------------*/ 77 | void 78 | print_address_list(void) 79 | { 80 | accepted_address_t *a; 81 | for(a = list_head(address_list); a != NULL; a = a->next) { 82 | PRINTF("[ADR]: "); 83 | print_address(&(a->address)); 84 | PRINTF("\n"); 85 | } 86 | } 87 | /*----------------------------------------------------------------------------*/ 88 | static accepted_address_t * 89 | accepted_address_allocate(void) 90 | { 91 | accepted_address_t* p; 92 | p = memb_alloc(&addresses_memb); 93 | if(p == NULL) { 94 | PRINTF("[AAL]: Failed to allocate an address\n"); 95 | } 96 | return p; 97 | } 98 | /*----------------------------------------------------------------------------*/ 99 | static void 100 | accepted_address_free(accepted_address_t* n) 101 | { 102 | list_remove(address_list, n); 103 | int res = memb_free(&addresses_memb, n); 104 | if (res !=0){ 105 | PRINTF("[AAL]: Failed to free an address. Reference count: %d\n",res); 106 | } 107 | } 108 | /*----------------------------------------------------------------------------*/ 109 | accepted_address_t* 110 | address_list_contains(address_t* a) 111 | { 112 | accepted_address_t* tmp; 113 | for(tmp = list_head(address_list); tmp != NULL; tmp = tmp->next) { 114 | if(address_cmp(&(tmp->address),a)){ 115 | return tmp; 116 | } 117 | } 118 | return NULL; 119 | } 120 | 121 | /*----------------------------------------------------------------------------*/ 122 | void 123 | add_accepted_address(address_t* address) 124 | { 125 | accepted_address_t* res = address_list_contains(address); 126 | if (res == NULL){ 127 | accepted_address_t* a = accepted_address_allocate(); 128 | if (a != NULL){ 129 | memset(a, 0, sizeof(*a)); 130 | a->address = *address; 131 | list_add(address_list,a); 132 | } 133 | } 134 | } 135 | /*----------------------------------------------------------------------------*/ 136 | void 137 | purge_address_list(void) 138 | { 139 | accepted_address_t* n; 140 | accepted_address_t* next; 141 | 142 | for(n = list_head(address_list); n != NULL;) { 143 | next = n->next; 144 | accepted_address_free(n); 145 | n = next; 146 | } 147 | } 148 | /*----------------------------------------------------------------------------*/ 149 | void 150 | fill_array_with_address(uint8_t* array, address_t* address) 151 | { 152 | uint16_t i; 153 | for (i = 0; i < ADDRESS_LENGTH; ++i){ 154 | array[i] = address->u8[i]; 155 | } 156 | } 157 | /*----------------------------------------------------------------------------*/ 158 | address_t 159 | get_address_from_int(uint16_t value) 160 | { 161 | address_t address; 162 | address.u8[ADDRESS_LENGTH-2] = value >> 8; 163 | address.u8[ADDRESS_LENGTH-1] = value & 0xFF; 164 | return address; 165 | } 166 | /*----------------------------------------------------------------------------*/ 167 | address_t 168 | get_address_from_array(uint8_t* array) 169 | { 170 | uint16_t i; 171 | address_t address; 172 | for (i = 0; i < ADDRESS_LENGTH; ++i){ 173 | address.u8[i] = array[i]; 174 | } 175 | return address; 176 | } 177 | /*----------------------------------------------------------------------------*/ 178 | void 179 | set_broadcast_address(address_t* address) 180 | { 181 | uint16_t i; 182 | for (i = 0; i < ADDRESS_LENGTH; ++i){ 183 | address->u8[i] = 255; 184 | } 185 | } 186 | /*----------------------------------------------------------------------------*/ 187 | uint8_t 188 | is_broadcast(address_t* a) 189 | { 190 | uint16_t i; 191 | for (i = 0; i < ADDRESS_LENGTH; ++i){ 192 | if (a->u8[i] != 255){ 193 | return 0; 194 | } 195 | } 196 | return 1; 197 | } 198 | /*----------------------------------------------------------------------------*/ 199 | uint8_t 200 | address_cmp(address_t* a, address_t* b) 201 | { 202 | uint16_t i; 203 | for (i = 0; i < ADDRESS_LENGTH; ++i){ 204 | if (a->u8[i] != b->u8[i]){ 205 | return 0; 206 | } 207 | } 208 | return 1; 209 | } 210 | /*----------------------------------------------------------------------------*/ 211 | void 212 | address_list_init(void) 213 | { 214 | list_init(address_list); 215 | memb_init(&addresses_memb); 216 | } 217 | /*----------------------------------------------------------------------------*/ 218 | void 219 | test_address_list(void) 220 | { 221 | address_t addr1; 222 | addr1.u8[0] = 10; 223 | addr1.u8[1] = 10; 224 | 225 | address_t addr3; 226 | addr3.u8[0] = 255; 227 | addr3.u8[1] = 255; 228 | 229 | address_t addr2; 230 | addr2.u8[0] = 10; 231 | addr2.u8[1] = 10; 232 | 233 | if (!list_length(address_list)){ 234 | add_accepted_address(&addr1); 235 | add_accepted_address(&addr2); 236 | add_accepted_address(&addr3); 237 | print_address_list(); 238 | }else{ 239 | purge_address_list(); 240 | print_address_list(); 241 | } 242 | } 243 | /*----------------------------------------------------------------------------*/ 244 | /** @} */ 245 | -------------------------------------------------------------------------------- /sdn-wise/packet-creator.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 SDN-WISE 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | /** 19 | * \file 20 | * SDN-WISE Packet Creator. 21 | * \author 22 | * Sebastiano Milardo 23 | */ 24 | 25 | /** 26 | * \addtogroup sdn-wise 27 | * @{ 28 | */ 29 | #include 30 | #include "packet-buffer.h" 31 | #include "packet-creator.h" 32 | #include "node-conf.h" 33 | #include "address.h" 34 | #include "neighbor-table.h" 35 | #include "sdn-wise.h" 36 | 37 | #if BATTERY_ENABLED 38 | #include "dev/battery-sensor.h" 39 | #endif 40 | 41 | #ifdef X_NUCLEO_IKS01A1 42 | #include "dev/temperature-sensor.h" 43 | #include "dev/humidity-sensor.h" 44 | #include "dev/pressure-sensor.h" 45 | #include "dev/sensor-common.h" 46 | #define NO_OF_SENSORS 3 47 | #endif /*X_NUCLEO_IKS01A1*/ 48 | 49 | #ifndef SDN_WISE_DEBUG 50 | #define SDN_WISE_DEBUG 0 51 | #endif 52 | #if SDN_WISE_DEBUG 53 | #define PRINTF(...) printf(__VA_ARGS__) 54 | #else 55 | #define PRINTF(...) 56 | #endif 57 | /*----------------------------------------------------------------------------*/ 58 | packet_t* 59 | create_beacon(void) 60 | { 61 | packet_t* p = create_packet_empty(); 62 | if (p != NULL){ 63 | p->header.net = conf.my_net; 64 | set_broadcast_address(&(p->header.dst)); 65 | p->header.src = conf.my_address; 66 | p->header.typ = BEACON; 67 | p->header.nxh = conf.sink_address; 68 | 69 | set_payload_at(p, BEACON_HOPS_INDEX, conf.hops_from_sink); 70 | 71 | #if BATTERY_ENABLED 72 | SENSORS_ACTIVATE(battery_sensor); 73 | set_payload_at(p, BEACON_BATT_INDEX, battery_sensor.value(0)); 74 | SENSORS_DEACTIVATE(battery_sensor); 75 | #else 76 | set_payload_at(p, BEACON_BATT_INDEX, 0xff); 77 | #endif 78 | } 79 | return p; 80 | } 81 | /*----------------------------------------------------------------------------*/ 82 | packet_t* 83 | create_data(uint8_t count) 84 | { 85 | #ifdef X_NUCLEO_IKS01A1 86 | int i = 0; 87 | uint8_t sensor_values[sizeof(int)*NO_OF_SENSORS]; 88 | int* sensor_values_ptr = &sensor_values; 89 | SENSORS_ACTIVATE(temperature_sensor); 90 | SENSORS_ACTIVATE(humidity_sensor); 91 | SENSORS_ACTIVATE(pressure_sensor); 92 | 93 | sensor_values_ptr[1] = temperature_sensor.value(0); 94 | sensor_values_ptr[2] = humidity_sensor.value(0); 95 | sensor_values_ptr[3] = pressure_sensor.value(0); 96 | 97 | SENSORS_DEACTIVATE(temperature_sensor); 98 | SENSORS_DEACTIVATE(humidity_sensor); 99 | SENSORS_DEACTIVATE(pressure_sensor); 100 | #endif 101 | 102 | packet_t* p = NULL; 103 | #if !SINK 104 | p = create_packet_empty(); 105 | if (p != NULL){ 106 | p->header.net = conf.my_net; 107 | p->header.dst = get_address_from_int(5); // Replace 5 with your dst 108 | p->header.src = conf.my_address; 109 | p->header.typ = DATA; 110 | p->header.nxh = conf.nxh_vs_sink; 111 | #ifdef X_NUCLEO_IKS01A1 112 | for (i = 0; i < sizeof(int)*NO_OF_SENSORS; i++){ 113 | set_payload_at(p, i, sensor_values[i]); 114 | } 115 | #else 116 | set_payload_at(p, 0, count); 117 | #endif 118 | } 119 | #endif 120 | return p; 121 | } 122 | /*----------------------------------------------------------------------------*/ 123 | packet_t* 124 | create_report(void) 125 | { 126 | packet_t* p = create_packet_empty(); 127 | if (p != NULL){ 128 | p->header.net = conf.my_net; 129 | p->header.dst = conf.sink_address; 130 | p->header.src = conf.my_address; 131 | p->header.typ = REPORT; 132 | p->header.nxh = conf.nxh_vs_sink; 133 | 134 | set_payload_at(p, BEACON_HOPS_INDEX, conf.hops_from_sink); 135 | 136 | #if BATTERY_ENABLED 137 | SENSORS_ACTIVATE(battery_sensor); 138 | set_payload_at(p, BEACON_BATT_INDEX, battery_sensor.value(0)); 139 | SENSORS_DEACTIVATE(battery_sensor); 140 | #else 141 | set_payload_at(p, BEACON_BATT_INDEX, 0xff); 142 | #endif 143 | 144 | fill_payload_with_neighbors(p); 145 | } 146 | return p; 147 | } 148 | /*----------------------------------------------------------------------------*/ 149 | packet_t* 150 | create_reg_proxy(void) 151 | { 152 | uint8_t payload[] = { 153 | 48, 48, 48, 48, 48, 48, 48, 49, 154 | 0, 1, 2, 3, 4, 5, 0, 0, 155 | 0, 0, 0, 0, 0, 1,-64,-88, 156 | 1, 108, 39, 6 157 | }; 158 | 159 | packet_t* p = create_packet_payload( 160 | conf.my_net, 161 | &conf.sink_address, 162 | &conf.my_address, 163 | REG_PROXY, 164 | &conf.nxh_vs_sink, 165 | payload, 166 | 28); 167 | return p; 168 | } 169 | /*----------------------------------------------------------------------------*/ 170 | void 171 | create_and_send_request(packet_t* p) 172 | { 173 | 174 | uint8_t i = 0; 175 | 176 | if (p->header.len < MAX_PAYLOAD_LENGTH){ 177 | packet_t* r = create_packet_empty(); 178 | if (r != NULL){ 179 | r->header.net = conf.my_net; 180 | r->header.dst = conf.sink_address; 181 | r->header.src = conf.my_address; 182 | r->header.typ = REQUEST; 183 | r->header.nxh = conf.nxh_vs_sink; 184 | 185 | uint8_t* a = (uint8_t*)p; 186 | set_payload_at(r, 0, conf.requests_count); 187 | set_payload_at(r, 1, 0); 188 | set_payload_at(r, 2, 1); 189 | for (i = 0; i < (p->header.len); ++i){ 190 | set_payload_at(r, i+3, a[i]); 191 | } 192 | rf_unicast_send(r); 193 | conf.requests_count++; 194 | 195 | } 196 | } else { 197 | packet_t* r1 = create_packet_empty(); 198 | packet_t* r2 = create_packet_empty(); 199 | 200 | if (r1 != NULL && r2 != NULL){ 201 | r1->header.net = conf.my_net; 202 | r1->header.dst = conf.sink_address; 203 | r1->header.src = conf.my_address; 204 | r1->header.typ = REQUEST; 205 | r1->header.nxh = conf.nxh_vs_sink; 206 | 207 | r2->header.net = conf.my_net; 208 | r2->header.dst = conf.sink_address; 209 | r2->header.src = conf.my_address; 210 | r2->header.typ = REQUEST; 211 | r2->header.nxh = conf.nxh_vs_sink; 212 | 213 | set_payload_at(r1, 0, conf.requests_count); 214 | set_payload_at(r1, 1, 0); 215 | set_payload_at(r1, 2, 2); 216 | 217 | set_payload_at(r2, 0, conf.requests_count); 218 | set_payload_at(r2, 1, 1); 219 | set_payload_at(r2, 2, 2); 220 | 221 | uint8_t* a = (uint8_t*)p; 222 | for (i = 0; i < MAX_PAYLOAD_LENGTH; ++i){ 223 | set_payload_at(r1, i+3, a[i]); 224 | } 225 | 226 | for (i = 0; i < (p->header.len - MAX_PAYLOAD_LENGTH); ++i){ 227 | set_payload_at(r2, i+3, a[i + MAX_PAYLOAD_LENGTH]); 228 | } 229 | 230 | rf_unicast_send(r1); 231 | rf_unicast_send(r2); 232 | 233 | conf.requests_count++; 234 | } else { 235 | if (r1 == NULL){ 236 | packet_deallocate(r1); 237 | } else { 238 | packet_deallocate(r2); 239 | } 240 | } 241 | } 242 | packet_deallocate(p); 243 | } 244 | /*----------------------------------------------------------------------------*/ 245 | packet_t* 246 | create_config(void) 247 | { 248 | // TODO 249 | return NULL; 250 | } 251 | /*----------------------------------------------------------------------------*/ 252 | /** @} */ 253 | -------------------------------------------------------------------------------- /sdn-wise-emulated/src/org/contikios/cooja/sdnwise/AbstractCoojaMote.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010, Swedish Institute of Computer Science. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of the Institute nor the names of its contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | * 29 | * 30 | */ 31 | 32 | package org.contikios.cooja.sdnwise; 33 | 34 | import com.github.sdnwiselab.sdnwise.mote.core.*; 35 | import com.github.sdnwiselab.sdnwise.mote.logger.MoteFormatter; 36 | import com.github.sdnwiselab.sdnwise.packet.NetworkPacket; 37 | import static com.github.sdnwiselab.sdnwise.packet.NetworkPacket.*; 38 | import java.io.*; 39 | import java.util.*; 40 | import java.util.logging.*; 41 | import org.contikios.cooja.*; 42 | import org.contikios.cooja.interfaces.*; 43 | import org.contikios.cooja.motes.AbstractApplicationMote; 44 | 45 | /** 46 | * Example SdnWise mote. 47 | * 48 | * This mote is simulated in COOJA via the Imported App Mote Type. 49 | * 50 | * @author Sebastiano Milardo 51 | */ 52 | public abstract class AbstractCoojaMote extends AbstractApplicationMote { 53 | 54 | // Statistics 55 | private int sentBytes; 56 | private int receivedBytes; 57 | private int sentDataBytes; 58 | private int receivedDataBytes; 59 | private long lastTx; 60 | private long doneTx; 61 | 62 | // Cooja 63 | private Simulation simulation; 64 | private Random random; 65 | private ApplicationRadio radio; 66 | private ApplicationLED leds; 67 | private final Level defaultLogLevel = Level.FINEST; 68 | private Logger measureLogger; 69 | protected com.github.sdnwiselab.sdnwise.mote.battery.Battery battery; 70 | 71 | AbstractCore core; 72 | 73 | public AbstractCoojaMote() { 74 | super(); 75 | } 76 | 77 | public AbstractCoojaMote(MoteType moteType, Simulation simulation) { 78 | super(moteType, simulation); 79 | } 80 | 81 | public abstract void init(); 82 | 83 | public void logger() { 84 | measureLogger.log(Level.FINEST, // NODE;BATTERY LVL(mC);BATTERY LVL(%);NO. RULES INSTALLED; B SENT; B RECEIVED; 85 | "{0};{1};{2};{3};{4};{5};{6};{7};", 86 | new Object[]{core.getMyAddress(), 87 | String.valueOf(battery.getLevel()), 88 | String.valueOf(battery.getByteLevel() / 2.55), 89 | core.getFlowTableSize(), 90 | sentBytes, receivedBytes, 91 | sentDataBytes, receivedDataBytes}); 92 | } 93 | 94 | @Override 95 | public void execute(long time) { 96 | 97 | if (radio == null) { 98 | simulation = getSimulation(); 99 | random = simulation.getRandomGenerator(); 100 | radio = (ApplicationRadio) getInterfaces().getRadio(); 101 | leds = (ApplicationLED) getInterfaces().getLED(); 102 | init(); 103 | measureLogger = initLogger(Level.FINEST, core.getMyAddress() 104 | + ".log", new MoteFormatter()); 105 | } 106 | 107 | // The nodes do not start all at the same time 108 | int delay = random.nextInt(10); 109 | 110 | // This event simulates a clock running every 1s 111 | simulation.scheduleEvent( 112 | new MoteTimeEvent(this, 0) { 113 | @Override 114 | public void execute(long t) { 115 | if (battery.getByteLevel() > 0) { 116 | core.timer(); 117 | battery.keepAlive(1); 118 | } 119 | logger(); 120 | requestImmediateWakeup(); 121 | } 122 | }, 123 | simulation.getSimulationTime() 124 | + (1000 + delay) * Simulation.MILLISECOND 125 | ); 126 | } 127 | 128 | @Override 129 | public void receivedPacket(RadioPacket p) { 130 | if (battery.getByteLevel() > 0) { 131 | 132 | byte[] networkPacket; 133 | 134 | if (NetworkPacket.isSdnWise(p.getPacketData())) { 135 | networkPacket = Arrays.copyOfRange(p.getPacketData(), 0, p.getPacketData().length); 136 | } else { 137 | networkPacket = Arrays.copyOfRange(p.getPacketData(), 15, p.getPacketData().length - 2); 138 | } 139 | 140 | NetworkPacket np = new NetworkPacket(networkPacket); 141 | if (np.isSdnWise()) { 142 | receivedBytes += np.getLen(); 143 | if (DATA == np.getTyp()) { 144 | receivedDataBytes += np.getPayloadSize(); 145 | } 146 | } 147 | battery.receiveRadio(p.getPacketData().length); 148 | core.rxRadioPacket(np, (int) (255 + radio.getCurrentSignalStrength())); 149 | } 150 | } 151 | 152 | @Override 153 | public void sentPacket(RadioPacket p) { 154 | } 155 | 156 | @Override 157 | public String toString() { 158 | return "SDN-WISE Mote " + getID(); 159 | } 160 | 161 | private Logger initLogger(Level level, String file, java.util.logging.Formatter formatter) { 162 | Logger LOGGER = java.util.logging.Logger.getLogger(file); 163 | LOGGER.setLevel(level); 164 | try { 165 | FileHandler fh; 166 | File dir = new File("logs"); 167 | dir.mkdir(); 168 | fh = new FileHandler("logs/" + file); 169 | fh.setFormatter(formatter); 170 | LOGGER.addHandler(fh); 171 | LOGGER.setUseParentHandlers(false); 172 | } catch (IOException | SecurityException ex) { 173 | LOGGER.log(Level.SEVERE, null, ex); 174 | } 175 | return LOGGER; 176 | } 177 | 178 | private void radioTX(final NetworkPacket np) { 179 | if (battery.getByteLevel() > 0) { 180 | long actualTime = simulation.getSimulationTime(); 181 | 182 | if (radio.isTransmitting() || radio.isReceiving() || radio.isInterfered() || doneTx == actualTime) { 183 | 184 | lastTx = Math.max(lastTx, actualTime) + 1 * Simulation.MILLISECOND; 185 | simulation.scheduleEvent(new MoteTimeEvent(this, 0) { 186 | @Override 187 | public void execute(long t) { 188 | radioTX(np); 189 | } 190 | }, 191 | lastTx 192 | ); 193 | 194 | } else { 195 | // send the NetworkPacket over the radio 196 | if (np.isSdnWise()) { 197 | sentBytes += np.getLen(); 198 | if (DATA == np.getTyp()) { 199 | sentDataBytes += np.getPayloadSize(); 200 | } 201 | } 202 | // simulates the battery consumption 203 | RadioPacket pk = new COOJARadioPacket(np.toByteArray()); 204 | battery.transmitRadio(pk.getPacketData().length); 205 | doneTx = actualTime; 206 | radio.startTransmittingPacket(pk, 1 * Simulation.MILLISECOND); 207 | } 208 | } 209 | } 210 | 211 | void startThreads() { 212 | new Thread(new SenderRunnable()).start(); 213 | new Thread(new LoggerRunnable()).start(); 214 | } 215 | 216 | private class SenderRunnable implements Runnable { 217 | 218 | @Override 219 | public void run() { 220 | try { 221 | while (true) { 222 | radioTX(core.getNetworkPacketToBeSend()); 223 | } 224 | } catch (InterruptedException ex) { 225 | log(ex.getLocalizedMessage()); 226 | } 227 | } 228 | } 229 | 230 | private class LoggerRunnable implements Runnable { 231 | 232 | @Override 233 | public void run() { 234 | try { 235 | while (true) { 236 | Pair tmp = core.getLogToBePrinted(); 237 | if (tmp.getKey().intValue() >= Level.INFO.intValue()) { 238 | log(tmp.getValue()); 239 | } 240 | } 241 | } catch (Exception ex) { 242 | log(ex.getLocalizedMessage()); 243 | } 244 | } 245 | } 246 | 247 | } 248 | -------------------------------------------------------------------------------- /sdn-wise/packet-handler.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 SDN-WISE 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | /** 19 | * \file 20 | * SDN-WISE Packet Handler. 21 | * \author 22 | * Sebastiano Milardo 23 | */ 24 | 25 | /** 26 | * \addtogroup sdn-wise 27 | * @{ 28 | */ 29 | 30 | #include 31 | #include 32 | #include "contiki.h" 33 | #include "dev/watchdog.h" 34 | #include "packet-handler.h" 35 | #include "address.h" 36 | #include "packet-buffer.h" 37 | #include "packet-creator.h" 38 | #include "neighbor-table.h" 39 | #include "flowtable.h" 40 | #include "node-conf.h" 41 | #include "sdn-wise.h" 42 | 43 | typedef enum conf_id{ 44 | RESET, 45 | MY_NET, 46 | MY_ADDRESS, 47 | PACKET_TTL, 48 | RSSI_MIN, 49 | BEACON_PERIOD, 50 | REPORT_PERIOD, 51 | RESET_PERIOD, 52 | RULE_TTL, 53 | ADD_ALIAS, 54 | REM_ALIAS, 55 | GET_ALIAS, 56 | ADD_RULE, 57 | REM_RULE, 58 | GET_RULE, 59 | ADD_FUNCTION, 60 | REM_FUNCTION, 61 | GET_FUNCTION 62 | } conf_id_t; 63 | 64 | const uint8_t conf_size[RULE_TTL+1] = 65 | { 66 | 0, 67 | sizeof(conf.my_net), 68 | sizeof(conf.my_address), 69 | sizeof(conf.packet_ttl), 70 | sizeof(conf.rssi_min), 71 | sizeof(conf.beacon_period), 72 | sizeof(conf.report_period), 73 | sizeof(conf.reset_period), 74 | sizeof(conf.rule_ttl) 75 | }; 76 | 77 | const void* conf_ptr[RULE_TTL+1] = 78 | { 79 | NULL, 80 | &conf.my_net, 81 | &conf.my_address, 82 | &conf.packet_ttl, 83 | &conf.rssi_min, 84 | &conf.beacon_period, 85 | &conf.report_period, 86 | &conf.reset_period, 87 | &conf.rule_ttl, 88 | }; 89 | 90 | #define CNF_READ 0 91 | #define CNF_WRITE 1 92 | 93 | #ifndef SDN_WISE_DEBUG 94 | #define SDN_WISE_DEBUG 0 95 | #endif 96 | #if SDN_WISE_DEBUG 97 | #define PRINTF(...) printf(__VA_ARGS__) 98 | #else 99 | #define PRINTF(...) 100 | #endif 101 | /*----------------------------------------------------------------------------*/ 102 | static void handle_beacon(packet_t*); 103 | static void handle_data(packet_t*); 104 | static void handle_report(packet_t*); 105 | static void handle_response(packet_t*); 106 | static void handle_open_path(packet_t*); 107 | static void handle_config(packet_t*); 108 | /*----------------------------------------------------------------------------*/ 109 | void 110 | handle_packet(packet_t* p) 111 | { 112 | if (p->info.rssi >= conf.rssi_min && p->header.net == conf.my_net){ 113 | if (p->header.typ == BEACON){ 114 | PRINTF("[PHD]: Beacon\n"); 115 | handle_beacon(p); 116 | } else { 117 | if (is_my_address(&(p->header.nxh))){ 118 | switch (p->header.typ){ 119 | case DATA: 120 | PRINTF("[PHD]: Data\n"); 121 | handle_data(p); 122 | break; 123 | 124 | case RESPONSE: 125 | PRINTF("[PHD]: Response\n"); 126 | handle_response(p); 127 | break; 128 | 129 | case OPEN_PATH: 130 | PRINTF("[PHD]: Open Path\n"); 131 | handle_open_path(p); 132 | break; 133 | 134 | case CONFIG: 135 | PRINTF("[PHD]: Config\n"); 136 | handle_config(p); 137 | break; 138 | 139 | default: 140 | PRINTF("[PHD]: Request/Report\n"); 141 | handle_report(p); 142 | break; 143 | } 144 | } 145 | } 146 | } else { 147 | packet_deallocate(p); 148 | } 149 | } 150 | /*----------------------------------------------------------------------------*/ 151 | void 152 | handle_beacon(packet_t* p) 153 | { 154 | add_neighbor(&(p->header.src),p->info.rssi); 155 | #if !SINK 156 | uint8_t new_hops = get_payload_at(p, BEACON_HOPS_INDEX); 157 | uint8_t new_distance = p->info.rssi; 158 | 159 | if (address_cmp(&(conf.nxh_vs_sink), &(p->header.src)) || 160 | #if MOBILE 161 | (new_distance < conf.distance_from_sink) 162 | #else 163 | (new_hops <= conf.hops_from_sink-1 && new_distance < conf.distance_from_sink) 164 | #endif 165 | ) 166 | { 167 | conf.nxh_vs_sink = p->header.src; 168 | conf.distance_from_sink = new_distance; 169 | conf.sink_address = p->header.nxh; 170 | conf.hops_from_sink = new_hops+1; 171 | } 172 | #endif 173 | packet_deallocate(p); 174 | } 175 | /*----------------------------------------------------------------------------*/ 176 | void 177 | handle_data(packet_t* p) 178 | { 179 | if (is_my_address(&(p->header.dst))) 180 | { 181 | PRINTF("[PHD]: Consuming Packet...\n"); 182 | packet_deallocate(p); 183 | } else { 184 | match_packet(p); 185 | } 186 | } 187 | /*----------------------------------------------------------------------------*/ 188 | void 189 | handle_report(packet_t* p) 190 | { 191 | #if SINK 192 | print_packet_uart(p); 193 | #else 194 | 195 | p->header.nxh = conf.nxh_vs_sink; 196 | rf_unicast_send(p); 197 | #endif 198 | } 199 | /*----------------------------------------------------------------------------*/ 200 | void 201 | handle_response(packet_t* p) 202 | { 203 | if (is_my_address(&(p->header.dst))) 204 | { 205 | entry_t* e = get_entry_from_array(p->payload, p->header.len - PLD_INDEX); 206 | if (e != NULL) 207 | { 208 | add_entry(e); 209 | } 210 | packet_deallocate(p); 211 | } else { 212 | match_packet(p); 213 | } 214 | } 215 | /*----------------------------------------------------------------------------*/ 216 | void 217 | handle_open_path(packet_t* p) 218 | { 219 | int i; 220 | uint8_t n_windows = get_payload_at(p,OPEN_PATH_WINDOWS_INDEX); 221 | uint8_t start = n_windows*WINDOW_SIZE + 1; 222 | uint8_t path_len = (p->header.len - (start + PLD_INDEX))/ADDRESS_LENGTH; 223 | int my_index = -1; 224 | uint8_t my_position = 0; 225 | uint8_t end = p->header.len - PLD_INDEX; 226 | 227 | for (i = start; i < end; i += ADDRESS_LENGTH) 228 | { 229 | address_t tmp = get_address_from_array(&(p->payload[i])); 230 | if (is_my_address(&tmp)) 231 | { 232 | my_index = i; 233 | break; 234 | } 235 | my_position++; 236 | } 237 | 238 | if (my_index == -1){ 239 | printf("[PHD]: Nothing to learn, matching...\n"); 240 | match_packet(p); 241 | } else { 242 | if (my_position > 0) 243 | { 244 | uint8_t prev = my_index - ADDRESS_LENGTH; 245 | uint8_t first = start; 246 | entry_t* e = create_entry(); 247 | 248 | window_t* w = create_window(); 249 | w->operation = EQUAL; 250 | w->size = SIZE_2; 251 | w->lhs = DST_INDEX; 252 | w->lhs_location = PACKET; 253 | w->rhs = MERGE_BYTES(p->payload[first], p->payload[first+1]); 254 | w->rhs_location = CONST; 255 | 256 | add_window(e,w); 257 | 258 | for (i = 0; ipayload[i*WINDOW_SIZE + 1]))); 261 | } 262 | 263 | action_t* a = create_action(FORWARD_U, &(p->payload[prev]), ADDRESS_LENGTH); 264 | add_action(e,a); 265 | add_entry(e); 266 | } 267 | 268 | if (my_position < path_len-1) 269 | { 270 | uint8_t next = my_index + ADDRESS_LENGTH; 271 | uint8_t last = end - ADDRESS_LENGTH; 272 | entry_t* e = create_entry(); 273 | 274 | window_t* w = create_window(); 275 | w->operation = EQUAL; 276 | w->size = SIZE_2; 277 | w->lhs = DST_INDEX; 278 | w->lhs_location = PACKET; 279 | w->rhs = MERGE_BYTES(p->payload[last], p->payload[last+1]); 280 | w->rhs_location = CONST; 281 | 282 | add_window(e,w); 283 | 284 | for (i = 0; ipayload[i*WINDOW_SIZE + 1]))); 287 | } 288 | 289 | action_t* a = create_action(FORWARD_U, &(p->payload[next]), ADDRESS_LENGTH); 290 | add_action(e,a); 291 | add_entry(e); 292 | 293 | address_t next_address = get_address_from_array(&(p->payload[next])); 294 | p->header.nxh = next_address; 295 | p->header.dst = next_address; 296 | rf_unicast_send(p); 297 | } 298 | 299 | if (my_position == path_len-1){ 300 | packet_deallocate(p); 301 | } 302 | } 303 | } 304 | /*----------------------------------------------------------------------------*/ 305 | void 306 | handle_config(packet_t* p) 307 | { 308 | if (is_my_address(&(p->header.dst))) 309 | { 310 | #if SINK 311 | if (!is_my_address(&(p->header.src))){ 312 | print_packet_uart(p); 313 | } else { 314 | #endif 315 | uint8_t i = 0; 316 | uint8_t id = p->payload[i] & 127; 317 | if ((p->payload[i] & 128) == CNF_READ) 318 | { 319 | //READ 320 | switch (id) 321 | { 322 | // TODO 323 | case RESET: 324 | case GET_ALIAS: 325 | case GET_FUNCTION: 326 | break; 327 | 328 | case GET_RULE: 329 | p->header.len += get_array_from_entry_id(&p->payload[i+2],p->payload[i+1]); 330 | break; 331 | 332 | case MY_NET: 333 | case MY_ADDRESS: 334 | case PACKET_TTL: 335 | case RSSI_MIN: 336 | case BEACON_PERIOD: 337 | case REPORT_PERIOD: 338 | case RULE_TTL: 339 | // TODO check payload size 340 | if (conf_size[id] == 1){ 341 | memcpy(&(p->payload[i+1]), conf_ptr[id], conf_size[id]); 342 | } else if (conf_size[id] == 2) { 343 | uint16_t value = *((uint16_t*)conf_ptr[id]); 344 | p->payload[i+1] = value >> 8; 345 | p->payload[i+2] = value & 0xFF; 346 | } 347 | p->header.len += conf_size[id]; 348 | break; 349 | 350 | 351 | default: 352 | break; 353 | } 354 | swap_addresses(&(p->header.src),&(p->header.dst)); 355 | #if !SINK 356 | match_packet(p); 357 | #else 358 | print_packet_uart(p); 359 | #endif 360 | } else { 361 | //WRITE 362 | switch (id) 363 | { 364 | // TODO 365 | case ADD_ALIAS: 366 | case REM_ALIAS: 367 | case ADD_RULE: 368 | case REM_RULE: 369 | case ADD_FUNCTION: 370 | case REM_FUNCTION: 371 | break; 372 | 373 | case RESET: 374 | watchdog_reboot(); 375 | break; 376 | 377 | case MY_NET: 378 | case MY_ADDRESS: 379 | case PACKET_TTL: 380 | case RSSI_MIN: 381 | case BEACON_PERIOD: 382 | case REPORT_PERIOD: 383 | case RESET_PERIOD: 384 | case RULE_TTL: 385 | if (conf_size[id] == 1){ 386 | memcpy((uint8_t*)conf_ptr[id], &(p->payload[i+1]), conf_size[id]); 387 | } else if (conf_size[id] == 2) { 388 | uint16_t h = p->payload[i+1] << 8; 389 | uint16_t l = p->payload[i+2]; 390 | *((uint16_t*)conf_ptr[id]) = h + l; 391 | } 392 | break; 393 | 394 | default: 395 | break; 396 | } 397 | packet_deallocate(p); 398 | } 399 | #if SINK 400 | } 401 | #endif 402 | } 403 | else { 404 | match_packet(p); 405 | } 406 | } 407 | /*----------------------------------------------------------------------------*/ 408 | void 409 | test_handle_open_path(void) 410 | { 411 | uint8_t array[19] = { 412 | 1, 19, 0, 1, 0, 2, 5, 100, 0, 1, 0, 0, 1, 0, 2, 0, 3, 0, 4, 413 | }; 414 | 415 | packet_t* p = get_packet_from_array(array); 416 | handle_open_path(p); 417 | } 418 | /*----------------------------------------------------------------------------*/ 419 | /** @} */ 420 | -------------------------------------------------------------------------------- /sdn-wise/sdn-wise.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 SDN-WISE 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | /** 19 | * \file 20 | * SDN-WISE for Contiki. 21 | * \author 22 | * Sebastiano Milardo 23 | */ 24 | 25 | /** 26 | * \addtogroup sdn-wise 27 | * @{ 28 | */ 29 | 30 | #include "contiki.h" 31 | #include "net/rime/rime.h" 32 | #include "net/linkaddr.h" 33 | #include "dev/watchdog.h" 34 | #include "dev/uart1.h" 35 | #include "dev/leds.h" 36 | #include "lib/list.h" 37 | #if CFS_ENABLED 38 | #include "cfs/cfs.h" 39 | #endif 40 | #if ELF_ENABLED 41 | #include "loader/elfloader.h" 42 | #endif 43 | #include "sdn-wise.h" 44 | #include "flowtable.h" 45 | #include "packet-buffer.h" 46 | #include "packet-handler.h" 47 | #include "packet-creator.h" 48 | #include "neighbor-table.h" 49 | #include "node-conf.h" 50 | 51 | #define UART_BUFFER_SIZE MAX_PACKET_LENGTH 52 | 53 | #define UNICAST_CONNECTION_NUMBER 29 54 | #define BROADCAST_CONNECTION_NUMBER 30 55 | 56 | #define TIMER_EVENT 50 57 | #define RF_U_SEND_EVENT 51 58 | #define RF_B_SEND_EVENT 52 59 | #define RF_U_RECEIVE_EVENT 53 60 | #define RF_B_RECEIVE_EVENT 54 61 | #define UART_RECEIVE_EVENT 55 62 | #define RF_SEND_BEACON_EVENT 56 63 | #define RF_SEND_REPORT_EVENT 57 64 | #define RF_SEND_DATA_EVENT 58 65 | #define NEW_PACKET_EVENT 59 66 | #define ACTIVATE_EVENT 60 67 | 68 | #ifndef SDN_WISE_DEBUG 69 | #define SDN_WISE_DEBUG 0 70 | #endif 71 | #if SDN_WISE_DEBUG 72 | #include 73 | #define PRINTF(...) printf(__VA_ARGS__) 74 | #else 75 | #define PRINTF(...) 76 | #endif 77 | 78 | /*----------------------------------------------------------------------------*/ 79 | PROCESS(main_proc, "Main Process"); 80 | PROCESS(rf_u_send_proc, "RF Unicast Send Process"); 81 | PROCESS(rf_b_send_proc, "RF Broadcast Send Process"); 82 | PROCESS(packet_handler_proc, "Packet Handler Process"); 83 | PROCESS(timer_proc, "Timer Process"); 84 | PROCESS(beacon_timer_proc, "Beacon Timer Process"); 85 | PROCESS(report_timer_proc, "Report Timer Process"); 86 | PROCESS(data_timer_proc, "Data Timer Process"); 87 | AUTOSTART_PROCESSES( 88 | &main_proc, 89 | &rf_u_send_proc, 90 | &rf_b_send_proc, 91 | &timer_proc, 92 | &beacon_timer_proc, 93 | &report_timer_proc, 94 | &packet_handler_proc, 95 | &data_timer_proc 96 | ); 97 | /*----------------------------------------------------------------------------*/ 98 | static uint8_t uart_buffer[UART_BUFFER_SIZE]; 99 | static uint8_t uart_buffer_index = 0; 100 | static uint8_t uart_buffer_expected = 0; 101 | #if MOBILE 102 | static uint8_t count=0; 103 | static packet_t* p; 104 | #endif 105 | /*----------------------------------------------------------------------------*/ 106 | void 107 | rf_unicast_send(packet_t* p) 108 | { 109 | process_post(&rf_u_send_proc, RF_U_SEND_EVENT, (process_data_t)p); 110 | } 111 | /*----------------------------------------------------------------------------*/ 112 | void 113 | rf_broadcast_send(packet_t* p) 114 | { 115 | process_post(&rf_b_send_proc, RF_B_SEND_EVENT, (process_data_t)p); 116 | } 117 | 118 | /*----------------------------------------------------------------------------*/ 119 | static uint8_t 120 | get_packet_rssi(uint16_t raw_value) 121 | { 122 | // TODO the exact rssi value depends on the radio 123 | // http://sourceforge.net/p/contiki/mailman/message/31805752/ 124 | #if COOJA 125 | return (uint8_t) -raw_value; 126 | #else 127 | return (uint8_t) raw_value; 128 | #endif 129 | } 130 | 131 | /*----------------------------------------------------------------------------*/ 132 | static void 133 | unicast_rx_callback(struct unicast_conn *c, const linkaddr_t *from) 134 | { 135 | packet_t* p = get_packet_from_array((uint8_t *)packetbuf_dataptr()); 136 | if (p != NULL){ 137 | p->info.rssi = get_packet_rssi(packetbuf_attr(PACKETBUF_ATTR_RSSI)); 138 | process_post(&main_proc, RF_U_RECEIVE_EVENT, (process_data_t)p); 139 | } 140 | } 141 | /*----------------------------------------------------------------------------*/ 142 | static void 143 | broadcast_rx_callback(struct broadcast_conn *c, const linkaddr_t *from) 144 | { 145 | packet_t* p = get_packet_from_array((uint8_t *)packetbuf_dataptr()); 146 | if (p != NULL){ 147 | p->info.rssi = get_packet_rssi(packetbuf_attr(PACKETBUF_ATTR_RSSI)); 148 | process_post(&main_proc, RF_B_RECEIVE_EVENT, (process_data_t)p); 149 | } 150 | } 151 | /*----------------------------------------------------------------------------*/ 152 | int 153 | uart_rx_callback(unsigned char c) 154 | { 155 | uart_buffer[uart_buffer_index] = c; 156 | if (uart_buffer_index == LEN_INDEX){ 157 | uart_buffer_expected = c; 158 | } 159 | uart_buffer_index++; 160 | if (uart_buffer_index == uart_buffer_expected){ 161 | uart_buffer_index = 0; 162 | uart_buffer_expected = 0; 163 | packet_t* p = get_packet_from_array(uart_buffer); 164 | if (p != NULL){ 165 | p->info.rssi = 0; 166 | process_post(&main_proc, UART_RECEIVE_EVENT, (process_data_t)p); 167 | } 168 | } 169 | return 0; 170 | } 171 | /*----------------------------------------------------------------------------*/ 172 | static const struct unicast_callbacks unicast_callbacks = { 173 | unicast_rx_callback 174 | }; 175 | static struct unicast_conn uc; 176 | static const struct broadcast_callbacks broadcast_callbacks = { 177 | broadcast_rx_callback 178 | }; 179 | static struct broadcast_conn bc; 180 | /*----------------------------------------------------------------------------*/ 181 | PROCESS_THREAD(main_proc, ev, data) { 182 | PROCESS_BEGIN(); 183 | 184 | uart1_init(BAUD2UBR(115200)); /* set the baud rate as necessary */ 185 | uart1_set_input(uart_rx_callback); /* set the callback function */ 186 | 187 | node_conf_init(); 188 | flowtable_init(); 189 | packet_buffer_init(); 190 | neighbor_table_init(); 191 | address_list_init(); 192 | leds_init(); 193 | 194 | #if SINK 195 | print_packet_uart(create_reg_proxy()); 196 | #endif 197 | 198 | while(1) { 199 | PROCESS_WAIT_EVENT(); 200 | switch(ev) { 201 | case TIMER_EVENT: 202 | // test_handle_open_path(); 203 | // test_flowtable(); 204 | // test_neighbor_table(); 205 | // test_packet_buffer(); 206 | // test_address_list(); 207 | print_flowtable(); 208 | print_node_conf(); 209 | break; 210 | 211 | case UART_RECEIVE_EVENT: 212 | leds_toggle(LEDS_GREEN); 213 | process_post(&packet_handler_proc, NEW_PACKET_EVENT, (process_data_t)data); 214 | break; 215 | 216 | case RF_B_RECEIVE_EVENT: 217 | leds_toggle(LEDS_YELLOW); 218 | if (!conf.is_active){ 219 | conf.is_active = 1; 220 | process_post(&beacon_timer_proc, ACTIVATE_EVENT, (process_data_t)NULL); 221 | process_post(&report_timer_proc, ACTIVATE_EVENT, (process_data_t)NULL); 222 | } 223 | case RF_U_RECEIVE_EVENT: 224 | process_post(&packet_handler_proc, NEW_PACKET_EVENT, (process_data_t)data); 225 | break; 226 | 227 | case RF_SEND_BEACON_EVENT: 228 | rf_broadcast_send(create_beacon()); 229 | break; 230 | 231 | case RF_SEND_REPORT_EVENT: 232 | rf_unicast_send(create_report()); 233 | #if !SINK 234 | if (conf.reset_period == 0){ 235 | conf.distance_from_sink = _MAX_DISTANCE; 236 | conf.reset_period = _RESET_PERIOD; 237 | } else { 238 | conf.reset_period--; 239 | } 240 | #endif 241 | break; 242 | 243 | case RF_SEND_DATA_EVENT: 244 | #if MOBILE 245 | if (conf.is_active){ 246 | p = create_data(count); 247 | if (p != NULL){ 248 | match_packet(p); 249 | } 250 | count++; 251 | } 252 | #endif 253 | break; 254 | } 255 | } 256 | PROCESS_END(); 257 | } 258 | /*----------------------------------------------------------------------------*/ 259 | PROCESS_THREAD(rf_u_send_proc, ev, data) { 260 | static linkaddr_t addr; 261 | PROCESS_EXITHANDLER(unicast_close(&uc);) 262 | PROCESS_BEGIN(); 263 | 264 | unicast_open(&uc, UNICAST_CONNECTION_NUMBER, &unicast_callbacks); 265 | while(1) { 266 | PROCESS_WAIT_EVENT_UNTIL(ev == RF_U_SEND_EVENT); 267 | packet_t* p = (packet_t*)data; 268 | 269 | if (p != NULL){ 270 | p->header.ttl--; 271 | 272 | PRINTF("[TXU]: "); 273 | print_packet(p); 274 | PRINTF("\n"); 275 | 276 | if (!is_my_address(&(p->header.dst))){ 277 | int i = 0; 278 | 279 | int sent_size = 0; 280 | 281 | if (LINKADDR_SIZE < ADDRESS_LENGTH){ 282 | sent_size = LINKADDR_SIZE; 283 | } else { 284 | sent_size = ADDRESS_LENGTH; 285 | 286 | } 287 | 288 | for ( i=0; iheader.nxh.u8[(sent_size-1)-i]; 290 | } 291 | 292 | addr.u8[0] = p->header.nxh.u8[1]; 293 | addr.u8[1] = p->header.nxh.u8[0]; 294 | uint8_t* a = (uint8_t*)p; 295 | packetbuf_copyfrom(a,p->header.len); 296 | unicast_send(&uc, &addr); 297 | } 298 | #if SINK 299 | else { 300 | print_packet_uart(p); 301 | } 302 | #endif 303 | packet_deallocate(p); 304 | } 305 | } 306 | PROCESS_END(); 307 | } 308 | /*----------------------------------------------------------------------------*/ 309 | PROCESS_THREAD(rf_b_send_proc, ev, data) { 310 | PROCESS_EXITHANDLER(broadcast_close(&bc);) 311 | PROCESS_BEGIN(); 312 | broadcast_open(&bc, BROADCAST_CONNECTION_NUMBER, &broadcast_callbacks); 313 | while(1) { 314 | 315 | PROCESS_WAIT_EVENT_UNTIL(ev == RF_B_SEND_EVENT); 316 | packet_t* p = (packet_t*)data; 317 | 318 | if (p != NULL){ 319 | p->header.ttl--; 320 | PRINTF("[TXB]: "); 321 | print_packet(p); 322 | PRINTF("\n"); 323 | 324 | uint8_t* a = (uint8_t*)p; 325 | packetbuf_copyfrom(a,p->header.len); 326 | broadcast_send(&bc); 327 | packet_deallocate(p); 328 | } 329 | } 330 | PROCESS_END(); 331 | } 332 | /*----------------------------------------------------------------------------*/ 333 | PROCESS_THREAD(timer_proc, ev, data) { 334 | static struct etimer et; 335 | PROCESS_BEGIN(); 336 | 337 | while(1) { 338 | etimer_set(&et, 3 * CLOCK_SECOND); 339 | PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); 340 | process_post(&main_proc, TIMER_EVENT, (process_data_t)NULL); 341 | } 342 | PROCESS_END(); 343 | } 344 | /*----------------------------------------------------------------------------*/ 345 | PROCESS_THREAD(beacon_timer_proc, ev, data) { 346 | static struct etimer et; 347 | 348 | PROCESS_BEGIN(); 349 | while(1){ 350 | #if !SINK 351 | if (!conf.is_active){ 352 | PROCESS_WAIT_EVENT_UNTIL(ev == ACTIVATE_EVENT); 353 | } 354 | #endif 355 | etimer_set(&et, conf.beacon_period * CLOCK_SECOND); 356 | PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); 357 | process_post(&main_proc, RF_SEND_BEACON_EVENT, (process_data_t)NULL); 358 | } 359 | PROCESS_END(); 360 | } 361 | /*----------------------------------------------------------------------------*/ 362 | PROCESS_THREAD(report_timer_proc, ev, data) { 363 | static struct etimer et; 364 | 365 | PROCESS_BEGIN(); 366 | while(1){ 367 | #if !SINK 368 | if (!conf.is_active){ 369 | PROCESS_WAIT_EVENT_UNTIL(ev == ACTIVATE_EVENT); 370 | } 371 | #endif 372 | etimer_set(&et, conf.report_period * CLOCK_SECOND); 373 | PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); 374 | process_post(&main_proc, RF_SEND_REPORT_EVENT, (process_data_t)NULL); 375 | } 376 | PROCESS_END(); 377 | } 378 | /*----------------------------------------------------------------------------*/ 379 | PROCESS_THREAD(data_timer_proc, ev, data) { 380 | static struct etimer et; 381 | 382 | PROCESS_BEGIN(); 383 | while(1){ 384 | etimer_set(&et, 5 * CLOCK_SECOND); 385 | PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); 386 | process_post(&main_proc, RF_SEND_DATA_EVENT, (process_data_t)NULL); 387 | } 388 | PROCESS_END(); 389 | } 390 | 391 | /*----------------------------------------------------------------------------*/ 392 | PROCESS_THREAD(packet_handler_proc, ev, data) { 393 | PROCESS_BEGIN(); 394 | while(1) { 395 | PROCESS_WAIT_EVENT_UNTIL(ev == NEW_PACKET_EVENT); 396 | packet_t* p = (packet_t*)data; 397 | PRINTF("[RX ]: "); 398 | print_packet(p); 399 | PRINTF("\n"); 400 | handle_packet(p); 401 | } 402 | PROCESS_END(); 403 | } 404 | /*----------------------------------------------------------------------------*/ 405 | -------------------------------------------------------------------------------- /sdn-wise/flowtable.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 SDN-WISE 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | /** 19 | * \file 20 | * FlowTable for Contiki. 21 | * \author 22 | * Sebastiano Milardo 23 | */ 24 | 25 | /** 26 | * \addtogroup sdn-wise 27 | * @{ 28 | */ 29 | 30 | #include 31 | 32 | #include "lib/memb.h" 33 | #include "lib/list.h" 34 | 35 | #include "flowtable.h" 36 | #include "packet-buffer.h" 37 | #include "sdn-wise.h" 38 | #include "packet-creator.h" 39 | 40 | #define W_OP_BIT 5 41 | #define W_OP_LEN 3 42 | #define W_OP_INDEX 0 43 | 44 | #define W_LEFT_BIT 3 45 | #define W_LEFT_LEN 2 46 | #define W_LEFT_INDEX 1 47 | 48 | #define W_RIGHT_BIT 1 49 | #define W_RIGHT_LEN W_LEFT_LEN 50 | #define W_RIGHT_INDEX 3 51 | 52 | #define W_SIZE_BIT 0 53 | #define W_SIZE_LEN 1 54 | 55 | #define S_OP_INDEX 0 56 | #define S_OP_BIT 3 57 | #define S_OP_LEN 3 58 | 59 | #define S_LEFT_BIT 1 60 | #define S_LEFT_LEN 2 61 | #define S_LEFT_INDEX 3 62 | 63 | #define S_RIGHT_BIT 6 64 | #define S_RIGHT_LEN S_LEFT_LEN 65 | #define S_RIGHT_INDEX 5 66 | 67 | #define S_RES_BIT 0 68 | #define S_RES_LEN 1 69 | #define S_RES_INDEX 1 70 | 71 | #define STATS_SIZE 2 72 | #define STATUS_REGISTER_SIZE 20 73 | 74 | #define GET_BITS(b,s,n) (((b) >> (s)) & ((1 << (n)) - 1)) 75 | #define SET_BITS(b,s) ((b) << (s)) 76 | 77 | #ifndef SDN_WISE_DEBUG 78 | #define SDN_WISE_DEBUG 0 79 | #endif 80 | #if SDN_WISE_DEBUG 81 | #include 82 | #define PRINTF(...) printf(__VA_ARGS__) 83 | #else 84 | #define PRINTF(...) 85 | #endif 86 | /*----------------------------------------------------------------------------*/ 87 | LIST(flowtable); 88 | MEMB(entries_memb, entry_t, 10); 89 | MEMB(windows_memb, window_t, 30); 90 | MEMB(actions_memb, action_t, 20); 91 | MEMB(bytes_memb, byte_t, 50); 92 | uint8_t status_register[STATUS_REGISTER_SIZE]; 93 | /*----------------------------------------------------------------------------*/ 94 | static void print_window(window_t*); 95 | static void print_action(action_t*); 96 | static window_t* window_allocate(void); 97 | static void window_free(window_t*); 98 | static action_t* action_allocate(void); 99 | static void action_free(action_t*); 100 | static entry_t* entry_allocate(void); 101 | static void entry_free(entry_t*); 102 | static void purge_flowtable(void); 103 | static void entry_init(entry_t*); 104 | static int compare(operator_t, uint16_t, uint16_t); 105 | static uint16_t get_operand(packet_t*, uint8_t*, operator_size_t, 106 | operator_location_t, uint16_t); 107 | static uint16_t do_operation(set_operator_t, uint16_t, uint16_t); 108 | static byte_t* byte_allocate(void); 109 | static void set_action(packet_t*, uint8_t*, uint8_t*); 110 | /*----------------------------------------------------------------------------*/ 111 | // TODO check what happens when memory is full 112 | /*----------------------------------------------------------------------------*/ 113 | entry_t* 114 | create_entry(void) 115 | { 116 | return entry_allocate(); 117 | } 118 | /*----------------------------------------------------------------------------*/ 119 | window_t* 120 | create_window(void) 121 | { 122 | return window_allocate(); 123 | } 124 | /*----------------------------------------------------------------------------*/ 125 | action_t* 126 | create_action(action_type_t type, uint8_t* array, uint8_t len) 127 | { 128 | action_t* a = action_allocate(); 129 | if (a != NULL) 130 | { 131 | if(len > 0){ 132 | uint8_t i; 133 | for(i = 0; i < len; ++i) 134 | { 135 | byte_t* b = byte_allocate(); 136 | if (b != NULL){ 137 | b->value = array[i]; 138 | list_add(a->bytes,b); 139 | } 140 | } 141 | } 142 | a->type = type; 143 | } 144 | return a; 145 | } 146 | /*----------------------------------------------------------------------------*/ 147 | void 148 | add_window(entry_t* entry, window_t* w) 149 | { 150 | list_add(entry->windows,w); 151 | } 152 | /*----------------------------------------------------------------------------*/ 153 | void 154 | add_action(entry_t* entry, action_t* a) 155 | { 156 | list_add(entry->actions,a); 157 | } 158 | /*----------------------------------------------------------------------------*/ 159 | static void 160 | print_window(window_t* w) 161 | { 162 | switch(w->lhs_location) 163 | { 164 | case NULL_LOC: break; 165 | case CONST: break; 166 | case PACKET: PRINTF("P."); break; 167 | case STATUS: PRINTF("R."); break; 168 | } 169 | 170 | PRINTF("%d",w->lhs); 171 | 172 | switch(w->operation) 173 | { 174 | case EQUAL: PRINTF(" = "); break; 175 | case NOT_EQUAL: PRINTF(" != "); break; 176 | case GREATER: PRINTF(" > "); break; 177 | case LESS: PRINTF(" < "); break; 178 | case GREATER_OR_EQUAL: PRINTF(" >= "); break; 179 | case LESS_OR_EQUAL: PRINTF(" <= "); break; 180 | } 181 | 182 | switch(w->rhs_location) 183 | { 184 | case NULL_LOC: break; 185 | case CONST: break; 186 | case PACKET: PRINTF("P."); break; 187 | case STATUS: PRINTF("R."); break; 188 | } 189 | 190 | PRINTF("%d",w->rhs); 191 | } 192 | /*----------------------------------------------------------------------------*/ 193 | static void 194 | print_action(action_t* a) 195 | { 196 | byte_t *b; 197 | 198 | switch(a->type){ 199 | case NULL_TYPE: break; 200 | case FORWARD_U: PRINTF("FORWARD_U "); break; 201 | case FORWARD_B: PRINTF("FORWARD_B "); break; 202 | case DROP: PRINTF("DROP"); break; 203 | case ASK: PRINTF("ASK"); break; 204 | case FUNCTION: PRINTF("FUNCTION "); break; 205 | case SET_: PRINTF("SET "); break; 206 | case MATCH: PRINTF("MATCH"); break; 207 | } 208 | 209 | for(b = list_head(a->bytes); b != NULL; b = b->next) { 210 | PRINTF(" %d", b->value); 211 | } 212 | } 213 | /*----------------------------------------------------------------------------*/ 214 | void 215 | print_entry(entry_t* e) 216 | { 217 | window_t *w; 218 | action_t *a; 219 | PRINTF("IF ("); 220 | for(w = list_head(e->windows); w != NULL; w = w->next) { 221 | print_window(w); 222 | PRINTF(";"); 223 | } 224 | PRINTF("){"); 225 | for(a = list_head(e->actions); a != NULL; a = a->next) { 226 | print_action(a); 227 | PRINTF(";"); 228 | } 229 | PRINTF("}[%d %d]", e->stats.ttl, e->stats.count); 230 | } 231 | /*----------------------------------------------------------------------------*/ 232 | void 233 | print_flowtable(void) 234 | { 235 | entry_t *e; 236 | for(e = list_head(flowtable); e != NULL; e = e->next) { 237 | PRINTF("[FLT]: "); 238 | print_entry(e); 239 | PRINTF("\n"); 240 | } 241 | } 242 | /*----------------------------------------------------------------------------*/ 243 | static window_t * 244 | window_allocate(void) 245 | { 246 | window_t *w; 247 | w = memb_alloc(&windows_memb); 248 | if(w == NULL) { 249 | PRINTF("[FLT]: Failed to allocate a window\n"); 250 | } 251 | return w; 252 | } 253 | /*----------------------------------------------------------------------------*/ 254 | static void 255 | window_free(window_t *w) 256 | { 257 | if(memb_free(&windows_memb, w)==-1){ 258 | PRINTF("[FLT]: Failed to free a window\n"); 259 | } 260 | } 261 | /*----------------------------------------------------------------------------*/ 262 | static byte_t * 263 | byte_allocate(void) 264 | { 265 | byte_t *b; 266 | b = memb_alloc(&bytes_memb); 267 | if(b == NULL) { 268 | PRINTF("[FLT]: Failed to allocate an action\n"); 269 | return NULL; 270 | } 271 | b->value = 0; 272 | return b; 273 | } 274 | /*----------------------------------------------------------------------------*/ 275 | static void 276 | byte_free(byte_t *b) 277 | { 278 | int res = memb_free(&bytes_memb, b); 279 | if (res !=0){ 280 | PRINTF("[FLT]: Failed to free a byte. Reference count: %d\n",res); 281 | } 282 | } 283 | /*----------------------------------------------------------------------------*/ 284 | static action_t * 285 | action_allocate(void) 286 | { 287 | action_t *a; 288 | a = memb_alloc(&actions_memb); 289 | if(a == NULL) { 290 | PRINTF("[FLT]: Failed to allocate an action\n"); 291 | return NULL; 292 | } 293 | memset(a, 0, sizeof(*a)); 294 | LIST_STRUCT_INIT(a, bytes); 295 | return a; 296 | } 297 | /*----------------------------------------------------------------------------*/ 298 | static void 299 | purge_bytes(list_t bytes) 300 | { 301 | byte_t *e; 302 | byte_t *next; 303 | 304 | for(e = list_head(bytes); e != NULL;) { 305 | next = e->next; 306 | byte_free(e); 307 | e = next; 308 | } 309 | } 310 | /*----------------------------------------------------------------------------*/ 311 | static void 312 | action_free(action_t *a) 313 | { 314 | purge_bytes(a->bytes); 315 | int res = memb_free(&actions_memb, a); 316 | if (res !=0){ 317 | PRINTF("[FLT]: Failed to free an action. Reference count: %d\n",res); 318 | } 319 | } 320 | /*----------------------------------------------------------------------------*/ 321 | static void 322 | purge_windows(list_t windows) 323 | { 324 | window_t *e; 325 | window_t *next; 326 | 327 | for(e = list_head(windows); e != NULL;) { 328 | next = e->next; 329 | window_free(e); 330 | e = next; 331 | } 332 | } 333 | /*----------------------------------------------------------------------------*/ 334 | static void 335 | purge_actions(list_t actions) 336 | { 337 | action_t *e; 338 | action_t *next; 339 | 340 | for(e = list_head(actions); e != NULL;) { 341 | next = e->next; 342 | action_free(e); 343 | e = next; 344 | } 345 | } 346 | /*----------------------------------------------------------------------------*/ 347 | static void 348 | purge_flowtable(void) 349 | { 350 | entry_t *e; 351 | entry_t *next; 352 | 353 | for(e = list_head(flowtable); e != NULL;) { 354 | next = e->next; 355 | entry_free(e); 356 | e = next; 357 | } 358 | } 359 | /*----------------------------------------------------------------------------*/ 360 | static void 361 | entry_init(entry_t *e) 362 | { 363 | memset(e, 0, sizeof(*e)); 364 | e->stats.ttl = 0; 365 | e->stats.count = 0; 366 | LIST_STRUCT_INIT(e, windows); 367 | LIST_STRUCT_INIT(e, actions); 368 | } 369 | /*----------------------------------------------------------------------------*/ 370 | static entry_t * 371 | entry_allocate(void) 372 | { 373 | entry_t *e; 374 | 375 | e = memb_alloc(&entries_memb); 376 | if(e == NULL) { 377 | purge_flowtable(); 378 | e = memb_alloc(&entries_memb); 379 | if(e == NULL) { 380 | PRINTF("[FLT]: Failed to allocate an entry\n"); 381 | return NULL; 382 | } 383 | } 384 | entry_init(e); 385 | return e; 386 | } 387 | /*----------------------------------------------------------------------------*/ 388 | static void 389 | entry_free(entry_t *e) 390 | { 391 | purge_windows(e->windows); 392 | purge_actions(e->actions); 393 | list_remove(flowtable, e); 394 | int res = memb_free(&entries_memb, e); 395 | if (res !=0){ 396 | PRINTF("[FLT]: Failed to free an entry. Reference count: %d\n",res); 397 | } 398 | } 399 | /*----------------------------------------------------------------------------*/ 400 | void 401 | flowtable_init(void) 402 | { 403 | list_init(flowtable); 404 | memb_init(&entries_memb); 405 | memb_init(&windows_memb); 406 | memb_init(&actions_memb); 407 | memb_init(&bytes_memb); 408 | } 409 | /*----------------------------------------------------------------------------*/ 410 | window_t* 411 | get_window_from_array(uint8_t* array){ 412 | window_t* w = window_allocate(); 413 | w->operation = GET_BITS(array[W_OP_INDEX], W_OP_BIT, W_OP_LEN); 414 | 415 | w->size = GET_BITS(array[W_OP_INDEX], W_SIZE_BIT, W_SIZE_LEN); 416 | 417 | w->lhs = MERGE_BYTES(array[W_LEFT_INDEX], array[W_LEFT_INDEX+1]); 418 | w->lhs_location = GET_BITS(array[W_OP_INDEX], W_LEFT_BIT, W_LEFT_LEN); 419 | 420 | w->rhs = MERGE_BYTES(array[W_RIGHT_INDEX], array[W_RIGHT_INDEX+1]); 421 | w->rhs_location = GET_BITS(array[W_OP_INDEX], W_RIGHT_BIT, W_RIGHT_LEN); 422 | return w; 423 | } 424 | /*----------------------------------------------------------------------------*/ 425 | uint8_t 426 | get_array_from_window(uint8_t* array, window_t* w){ 427 | array[W_OP_INDEX] = SET_BITS(w->operation, W_OP_BIT) + 428 | SET_BITS(w->size, W_SIZE_BIT) + 429 | SET_BITS(w->lhs_location, W_LEFT_BIT) + 430 | SET_BITS(w->rhs_location, W_RIGHT_BIT); 431 | array[W_LEFT_INDEX+1] = w->lhs & 0xFF; 432 | array[W_LEFT_INDEX] = w->lhs >> 8; 433 | array[W_RIGHT_INDEX+1] = w->rhs & 0xFF; 434 | array[W_RIGHT_INDEX] = w->rhs >> 8; 435 | return WINDOW_SIZE; 436 | } 437 | /*----------------------------------------------------------------------------*/ 438 | action_t* 439 | get_action_from_array(uint8_t* array, uint8_t action_size){ 440 | return create_action(array[0], &(array[1]), action_size-1); 441 | } 442 | /*----------------------------------------------------------------------------*/ 443 | uint8_t 444 | get_array_from_action(uint8_t* array, action_t* a){ 445 | int i = 2; 446 | array[1] = a->type; 447 | byte_t *b; 448 | for(b = list_head(a->bytes); b != NULL; b = b->next) { 449 | array[i] = b->value; 450 | i++; 451 | } 452 | array[0] = i-1; 453 | return i; 454 | } 455 | /*----------------------------------------------------------------------------*/ 456 | entry_t* 457 | get_entry_from_array(uint8_t* array, uint16_t length) 458 | { 459 | entry_t* entry = entry_allocate(); 460 | if (entry != NULL){ 461 | uint16_t i = 0; 462 | uint8_t n_windows = array[i]; 463 | 464 | for(i = 1; i <= n_windows; i += WINDOW_SIZE){ 465 | window_t* w = get_window_from_array(&array[i]); 466 | list_add(entry->windows,w); 467 | } 468 | 469 | while (i < (length - STATS_SIZE)) { 470 | uint8_t action_size = array[i]; 471 | i++; 472 | action_t* a = get_action_from_array(&array[i], action_size); 473 | list_add(entry->actions,a); 474 | i += action_size; 475 | } 476 | 477 | entry->stats.ttl = array[i]; 478 | i++; 479 | entry->stats.count = array[i]; 480 | } 481 | return entry; 482 | } 483 | /*----------------------------------------------------------------------------*/ 484 | uint8_t 485 | get_array_from_entry(uint8_t* array, entry_t* e) 486 | { 487 | uint8_t index = 1; 488 | array[0] = 0; 489 | window_t *w; 490 | action_t *a; 491 | for(w = list_head(e->windows); w != NULL; w = w->next) { 492 | index += get_array_from_window(&array[index], w); 493 | array[0] += WINDOW_SIZE; 494 | } 495 | for(a = list_head(e->actions); a != NULL; a = a->next) { 496 | index += get_array_from_action(&array[index], a); 497 | } 498 | array[index] = e->stats.ttl; 499 | index++; 500 | array[index] = e->stats.count; 501 | index++; 502 | return index; 503 | } 504 | /*----------------------------------------------------------------------------*/ 505 | uint8_t 506 | get_array_from_entry_id(uint8_t* array, int entry_id) 507 | { 508 | int i = 0; 509 | uint8_t size = 0; 510 | entry_t *e; 511 | for(e = list_head(flowtable); e != NULL; e = e->next) { 512 | if (i == entry_id){ 513 | size += get_array_from_entry(array, e); 514 | break; 515 | } 516 | i++; 517 | } 518 | return size; 519 | } 520 | /*----------------------------------------------------------------------------*/ 521 | uint8_t 522 | window_cmp(window_t* a, window_t* b) 523 | { 524 | print_window(a); 525 | PRINTF("\n"); 526 | print_window(b); 527 | PRINTF("\n"); 528 | return a->operation == b->operation && 529 | a->size == b->size && 530 | a->lhs_location == b->lhs_location && 531 | a->rhs_location == b->rhs_location && 532 | a->lhs == b->lhs && 533 | a->rhs == b->rhs; 534 | } 535 | /*----------------------------------------------------------------------------*/ 536 | uint8_t 537 | entry_cmp(entry_t* a, entry_t* b) 538 | { 539 | if (list_length(a->windows) == list_length(b->windows)) 540 | { 541 | window_t* aw; 542 | window_t* bw; 543 | bw = list_head(b->windows); 544 | for (aw = list_head(a->windows); aw != NULL; aw = aw->next){ 545 | if (window_cmp(aw,bw)){ 546 | bw = bw->next; 547 | } else { 548 | return 0; 549 | } 550 | } 551 | return 1; 552 | } return 0; 553 | } 554 | /*----------------------------------------------------------------------------*/ 555 | void 556 | add_entry(entry_t* e){ 557 | entry_t* tmp; 558 | entry_t* found = NULL; 559 | for(tmp = list_head(flowtable); tmp != NULL; tmp = tmp->next) { 560 | if (entry_cmp(e,tmp)){ 561 | found = tmp; 562 | } 563 | } 564 | 565 | if (found != NULL){ 566 | entry_free(found); 567 | } 568 | list_add(flowtable,e); 569 | } 570 | /*----------------------------------------------------------------------------*/ 571 | void 572 | match_packet(packet_t* p){ 573 | entry_t *e; 574 | int found = 0; 575 | PRINTF("[FLT]: Matching Packet...\n"); 576 | 577 | for(e = list_head(flowtable); e != NULL; e = e->next) { 578 | found = match_entry(p,e); 579 | if (found){ 580 | break; 581 | } 582 | } 583 | if (!found){ 584 | PRINTF("[FLT]: Match Not Found!\n"); 585 | create_and_send_request(p); 586 | } 587 | } 588 | /*----------------------------------------------------------------------------*/ 589 | int 590 | match_entry(packet_t* p, entry_t* e){ 591 | window_t *w; 592 | action_t *a; 593 | int target = list_length(e->windows); 594 | int actual = 0; 595 | 596 | if (target == 0) {return 0;} 597 | 598 | for(w = list_head(e->windows); w != NULL; w = w->next) { 599 | actual = actual + match_window(p, status_register, w); 600 | } 601 | 602 | if (actual == target){ 603 | PRINTF("[FLT]: Match Found!\n"); 604 | for(a = list_head(e->actions); a != NULL; a = a->next) { 605 | run_action(p, status_register, a); 606 | } 607 | e->stats.count++; 608 | return 1; 609 | } else { 610 | return 0; 611 | } 612 | } 613 | /*----------------------------------------------------------------------------*/ 614 | static int 615 | compare(operator_t op, uint16_t lhs, uint16_t rhs) 616 | { 617 | switch (op) { 618 | case EQUAL: return lhs == rhs; 619 | case NOT_EQUAL: return lhs != rhs; 620 | case GREATER: return lhs > rhs; 621 | case LESS: return lhs < rhs; 622 | case GREATER_OR_EQUAL: return lhs >= rhs; 623 | case LESS_OR_EQUAL: return lhs <= rhs; 624 | default: return 0; 625 | } 626 | } 627 | /*----------------------------------------------------------------------------*/ 628 | static uint16_t 629 | get_operand(packet_t* p, uint8_t* r, operator_size_t s, operator_location_t l, 630 | uint16_t v) 631 | { 632 | uint8_t* ptr; 633 | int limit; 634 | uint8_t* a = (uint8_t*)p; 635 | 636 | switch(l) 637 | { 638 | case CONST: return v; 639 | case PACKET: ptr = a; limit = p->header.len-1; break; 640 | case STATUS: ptr = r; limit = STATUS_REGISTER_SIZE-1; break; 641 | default: return 0; 642 | } 643 | 644 | switch(s) 645 | { 646 | case SIZE_1: if (v > limit) { return -1;} else {return ptr[v];} 647 | case SIZE_2: if (v + 1 > limit) { return -1;} else { return MERGE_BYTES(ptr[v],ptr[v + 1]);} 648 | default: return 0; 649 | } 650 | } 651 | /*----------------------------------------------------------------------------*/ 652 | int 653 | match_window(packet_t* p, uint8_t* s, window_t* w) 654 | { 655 | operator_t op = w->operation; 656 | uint16_t lhs = get_operand(p, s, w->size, w->lhs_location, w->lhs); 657 | uint16_t rhs = get_operand(p, s, w->size, w->rhs_location, w->rhs); 658 | return compare(op, lhs, rhs); 659 | } 660 | /*----------------------------------------------------------------------------*/ 661 | static uint16_t 662 | do_operation(set_operator_t op, uint16_t lhs, uint16_t rhs) 663 | { 664 | switch (op) 665 | { 666 | case ADD: return lhs + rhs; 667 | case SUB: return lhs - rhs; 668 | case DIV: return lhs / rhs; 669 | case MUL: return lhs * rhs; 670 | case MOD: return lhs % rhs; 671 | case AND: return lhs & rhs; 672 | case OR: return lhs | rhs; 673 | case XOR: return lhs ^ rhs; 674 | default: return 0; 675 | } 676 | } 677 | /*----------------------------------------------------------------------------*/ 678 | static void 679 | set_action(packet_t* p, uint8_t* s, uint8_t* action_array) 680 | { 681 | set_operator_t op = GET_BITS(action_array[S_OP_INDEX],S_OP_BIT,S_OP_LEN); 682 | 683 | operator_location_t lhs_location = GET_BITS(action_array[S_OP_INDEX],S_LEFT_BIT,S_LEFT_LEN); 684 | uint16_t lhs = MERGE_BYTES(action_array[S_LEFT_INDEX],action_array[S_LEFT_INDEX+1]); 685 | 686 | operator_location_t rhs_location = GET_BITS(action_array[S_OP_INDEX],S_RIGHT_BIT,S_RIGHT_LEN); 687 | uint16_t rhs = MERGE_BYTES(action_array[S_RIGHT_INDEX],action_array[S_RIGHT_INDEX+1]); 688 | 689 | operator_location_t res_location = GET_BITS(action_array[S_OP_INDEX],S_RES_BIT,S_RES_LEN)+2; 690 | uint16_t res = MERGE_BYTES(action_array[S_RES_INDEX],action_array[S_RES_INDEX+1]); 691 | 692 | uint16_t l = get_operand(p, s, SIZE_1, lhs_location, lhs); 693 | uint16_t r = get_operand(p, s, SIZE_1, rhs_location, rhs); 694 | 695 | if (res_location == PACKET){ 696 | ((uint8_t*)p)[res] = do_operation(op, l, r); 697 | } else { 698 | s[res] = do_operation(op, l, r); 699 | } 700 | } 701 | /*----------------------------------------------------------------------------*/ 702 | int 703 | run_action(packet_t* p, uint8_t* s, action_t* a){ 704 | int len = list_length(a->bytes); 705 | int i = 0; 706 | uint8_t action_array[len]; 707 | byte_t* b; 708 | 709 | if (len>0){ 710 | for(b = list_head(a->bytes); b != NULL; b = b->next) { 711 | action_array[i] = b->value; 712 | ++i; 713 | } 714 | } 715 | 716 | switch(a->type){ 717 | case FORWARD_U: 718 | p->header.nxh = get_address_from_array(action_array); 719 | rf_unicast_send(p); 720 | break; 721 | 722 | case FORWARD_B: 723 | p->header.nxh = get_address_from_array(action_array); 724 | rf_broadcast_send(p); 725 | break; 726 | 727 | case ASK: 728 | create_and_send_request(p); 729 | break; 730 | 731 | case MATCH: 732 | // TODO there may be problems if match is in the middle of a list of actions 733 | match_packet(p); 734 | break; 735 | 736 | case FUNCTION: 737 | // TODO function 738 | break; 739 | 740 | case SET_: 741 | set_action(p, s, action_array); 742 | break; 743 | 744 | default: 745 | packet_deallocate(p); 746 | break; 747 | } 748 | return -1; 749 | } 750 | /*----------------------------------------------------------------------------*/ 751 | void 752 | test_flowtable(void) 753 | { 754 | uint8_t array[25] = { 755 | 20, 18, 0, 6, 0, 2, 82, 0, 15, 0, 1, 114, 756 | 0, 16, 0, 2, 50, 0, 17, 0, 5, 1, 4, 254, 757 | 0}; 758 | 759 | if (!list_length(flowtable)){ 760 | entry_t* e = get_entry_from_array(array,25); 761 | if (e != NULL){ 762 | add_entry(e); 763 | } 764 | }else{ 765 | entry_free(list_pop(flowtable)); 766 | } 767 | 768 | uint8_t array1[116] = { 769 | 1, 116, 0, 0, 0, 2, 2, 100, 0, 0, 770 | 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 771 | 21, 90, 10, 10, 10, 11, 22, 10, 12, 10, 772 | 35, 11, 14, 18, 16, 12, 10, 10, 10, 40, 773 | 40, 10, 18, 15, 11, 10, 10, 10, 10, 10, 774 | 50, 11, 13, 13, 12, 25, 25, 31, 11, 01, 775 | 61, 11, 17, 18, 16, 13, 10, 11, 10, 12, 776 | 71, 11, 17, 18, 16, 13, 10, 11, 10, 12, 777 | 81, 11, 17, 18, 16, 13, 10, 11, 10, 12, 778 | 91, 11, 17, 18, 16, 13, 10, 11, 10, 12, 779 | 11, 11, 17, 18, 16, 13, 10, 11, 10, 12, 780 | 10, 13, 254,11, 12, 13 781 | }; 782 | 783 | 784 | packet_t* p = get_packet_from_array(array1); 785 | match_packet(p); 786 | packet_deallocate(p); 787 | } 788 | /*----------------------------------------------------------------------------*/ 789 | /** @} */ 790 | --------------------------------------------------------------------------------