├── 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 | [](https://travis-ci.org/sdnwiselab/sdn-wise-contiki)
4 | [](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 |
--------------------------------------------------------------------------------