Wednesday, August 10, 2016

Generate an improved interfering node in Contiki OS

Objective

The objective of this post is to make an improved version of the interfering node that i made in a previous tutorial:

http://contiki-iot.blogspot.com.co/2016/08/objective-to-create-interfering-node.html

The previous tutorial just generates an unmodulated carrier as noise, i would like to mention that i got the idea and part of the code from the paper [2]. Now, in this tutorial i improved this version of interfering node adding a model of interference called Bursty Interference described in the section 3.3 of paper [1]. The model just turns the unmodulated carrier on and off with different time periods (t1 and t2). For example, it turns the carrier on for 240ms (t1 = 240ms) and then it turns the carrier off for 510ms (t2 = 510ms); the times t1 and t2 follow a uniform distribution between 0 seconds and 1,5 seconds. I strongly recommend you to read the paper [1].

Code for the sky mote

Below i show you the code that implements the improved interfering node. I order to understand the code you must read section 3.3 of the paper [1], i try to add comments to the code and use the same variables that the paper did.

/*
 * Copyright (c) 2007, Swedish Institute of Computer Science.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the Institute nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * This file is part of the Contiki operating system.
 *
 */

/**
 * \file
 *       Improved example of an interfering node
 * \author
 *        Sergio Diaz
 */


/*INCLUDES*/
#include "contiki.h"
#include "/home/sink/Desktop/contiki-3.0/dev/cc2420/cc2420_const.h" // Include the CC2420 constants 
#include "/home/sink/Desktop/contiki-3.0/core/dev/spi.h" // Include basic SPI macros
#include "dev/leds.h" // Include Leds to debbug
#include "sys/rtimer.h" //Include the real time library

/*DEFINES*/
#define INTERFERENCE  0x01 // I set the less significant bit to indicate there is interference (0x01 = 00000000 00000001)
#define CONSTANT_MICROS 300 // 300 us was defined by the paper [1]
#define TIME_TICK 31 // The time of 1 tick is 30,51 us in rtimer for sky motes in Contiki v3.0. TIME_TICK = 1 / RTIMER_ARCH_SECOND = 1 / 32768 s


/*STRUCT DEFINITIONS*/
struct states{
 unsigned char carrier; // Defines the state of the carrier: Either INTERFERENCE = 0x01 or Not INTERFERENCE = ~0x01
};

struct states state; //Create the state of the carrier
static struct rtimer rtimer; // Create the rtimer variable

/*FUNCTION DEFINITIONS*/

/*---------------------------------------------------------------------------*/
/*
* Generate a random number between 0 and (MaxValue - 1)
*/
unsigned int random_number(unsigned int MaxValue){
       return  rand() % MaxValue;
}
/*---------------------------------------------------------------------------*/
/** 
 * Writes to a register.
 * Note: the SPI_WRITE(0) seems to be needed for getting the
 * write reg working on the Z1 / MSP430X platform
 */
static void
setreg(enum cc2420_register regname, uint16_t value)
{
  CC2420_SPI_ENABLE();
  SPI_WRITE_FAST(regname);
  SPI_WRITE_FAST((uint8_t) (value >> 8));
  SPI_WRITE_FAST((uint8_t) (value & 0xff));
  SPI_WAITFORTx_ENDED();
  SPI_WRITE(0);
  CC2420_SPI_DISABLE();
}

/* Sends a strobe */
static void
strobe(enum cc2420_register regname)
{
  CC2420_SPI_ENABLE();
  SPI_WRITE(regname);
  CC2420_SPI_DISABLE();
}

/*
* Function called by the rtimer to turn the carrier on and off.
*/
static void carrier_OnOff(struct rtimer* timer, void* ptr)
{

    unsigned int R; // Uniformly distributed over [1,100]
    unsigned int Qx;  // Uniformly distributed over [1,x], where x = 50
    unsigned int randNum; // Random number between [1-10]
    uint32_t time_next_period; // Next time period. The duration of the interference or not interference state.
    uint32_t num_ticks; // Number of ticks of the time_next_period

    // Calculate a random number between [1-10]
    randNum = 1 + abs( random_number(10) ) ;
    
    // Decide whether to produce interference or not with equal probability (0.5)
    if( randNum <= 5) // If the random number is less than 5 generate no interference 
    {
        // In this case there will be no interference
        state.carrier &= ~INTERFERENCE; // Set the carrier state to no interference (NOT INTERFERENCE)
    }else{
        // In this case there will be interference
        state.carrier |= INTERFERENCE; // Set the carrier state to interference
    }

    // Turn the unmodulated carrier on or off depending on the carrier state (state.carrier)
    if( state.carrier & INTERFERENCE) // should the node generate interference?
    {
       //The node must generate interference. Turn the carrier on.
       // Creates an unmodulated carrier by setting the appropiate registers in the CC2420
       setreg(CC2420_MANOR, 0x0100); 
       setreg(CC2420_TOPTST, 0x0004);
       setreg(CC2420_MDMCTRL1, 0x0508);
       setreg(CC2420_DACTST, 0x1800);
       strobe(CC2420_STXON);
       // Turn the leds for debug. LEDS_RED on means there is interference
       leds_on(LEDS_RED);
       leds_off(LEDS_GREEN);

    }else{
       //The node must not generate interference. Turn the carrier off.
       //Reset the changes and set back the CC2420 radio chip in normal mode.
       //Not generate unmodulated carrier
       setreg(CC2420_MANOR, 0x0000);
       setreg(CC2420_TOPTST, 0x0010);
       setreg(CC2420_MDMCTRL1, 0x0500);
       setreg(CC2420_DACTST, 0x0000);
       strobe(CC2420_STXON);
       // Turn the leds for debug. LEDS_GREEN on means there is no interference
       leds_on(LEDS_GREEN);
       leds_off(LEDS_RED);
    }
    // Calculate the time of the next period ( time_next_period = R*Q(x)*CONSTANT_MICROS ) 
       R  = 1 +  abs( random_number(100) )  ; // Generate random numbers between [1,100]
       Qx = 1 +  abs(random_number(50))   ; // Generate random numbers between [1,50]
       time_next_period = R * Qx ; // Compute the next time period according to the paper [1]
       time_next_period = time_next_period * CONSTANT_MICROS ;  // Compute the next time period according to the paper [1]


    // Set the rtimer to the time_next_period (num_ticks)
       num_ticks = time_next_period / TIME_TICK; // Compute the number of ticks that corresponds to time_next_period
       printf("Interference = %d ,R = %d, Qx = %d, time = %lu, ticks =  %lu \n", state.carrier & INTERFERENCE, R, Qx, time_next_period, num_ticks); // View the results in console
       rtimer_set(&rtimer, RTIMER_NOW() + num_ticks , 1, carrier_OnOff, NULL);// Set the rtimer again to the time_next_period (num_ticks)
}


/*---------------------------------------------------------------------------*/

PROCESS(turn_carrier_OnOff, "Turn Carrier On Off"); // Declares the process to turn the carrier on and off
AUTOSTART_PROCESSES( &turn_carrier_OnOff); // Load the process on boot

PROCESS_THREAD(turn_carrier_OnOff, ev, data) // Process to turn carrier on and off
{ 
   
  PROCESS_BEGIN(); // Says where the process starts

  rtimer_set(&rtimer, RTIMER_NOW() + RTIMER_ARCH_SECOND, 1, carrier_OnOff, NULL); //Initiates the rtimer 1 second after boot

  PROCESS_END();  //Says where the process ends
}

/*---------------------------------------------------------------------------*/


Video

I created an unmodulated carrier at channel 20 and to visualize the signal i am using the rssi-scanner provided by Contiki. The vertical node is the interfering one. When the interfering node's red led is on, then the carrier at channel 20 appears; and when the interfering node's green led is on, then the carrier at channel 20 disappears. The time of carrier on/off is a uniform distribution between 0 and 1,5 seconds.

References

[1] Boano, Carlo Alberto; Voigt, Thiemo; Tsiftes, Nicolas; Mottola, Luca; Römer, Kay; Zúñiga, Marco Antonio. Making Sensornet MAC Protocols Robust against Interference. Proceedings of the Wireless Sensor Networks: 7th European Conference - EWSN, Coimbra, Portugal, February 17-19, 2010, pp. 272-288.

[2] C. A. Boano, Z. He, Y. Li, T. Voigt, M. Zúñniga and A. Willig, "Controllable radio interference for experimental and testing purposes in Wireless Sensor Networks," 2009 IEEE 34th Conference on Local Computer Networks, Zurich, 2009, pp. 865-872.

1 comment:

  1. Hi
    i'm working in my ioT project, i'm using STM32l152 and its expansion RF board. i want to use Contiki, but i can't get how to combine it with my code (SPIRIT1). can you help me

    ReplyDelete