Mudanças entre as edições de "Desenvolvimento de experimentos para a disciplina de Avaliação de Desempenho de Sistemas da Engenharia de Telecomunicações"

De MediaWiki do Campus São José
Ir para navegação Ir para pesquisar
Linha 2 519: Linha 2 519:
  
 
https://www.researchgate.net/publication/232708159_Contiki-based_IEEE_802154_Node%27s_Throughput_and_Wireless_Channel_Utilization_Analysis
 
https://www.researchgate.net/publication/232708159_Contiki-based_IEEE_802154_Node%27s_Throughput_and_Wireless_Channel_Utilization_Analysis
 +
 +
==Artigos Geradores de Tráfego==
 +
 +
http://ieeexplore.ieee.org.ez130.periodicos.capes.gov.br/document/7986326/
 +
 +
pages.cs.wisc.edu/~pb/selfconfig_final.pdf
 +
 +
http://ieeexplore.ieee.org.ez130.periodicos.capes.gov.br/document/4908333/
 +
 +
http://ieeexplore.ieee.org.ez130.periodicos.capes.gov.br/document/7823282/
 +
 +
http://ieeexplore.ieee.org.ez130.periodicos.capes.gov.br/stamp/stamp.jsp?arnumber=5487204

Edição das 08h36min de 17 de novembro de 2017

Sobre o projeto

Resumo do projeto

Nome do Orientador do Projeto: Eraldo Silveira e Silva

Nome do Bolsista do Projeto: André Felippe Weber

A disciplina de Avaliação de Desempenho de Sistemas da Engenharia de Telecomunicações tem como foco a avaliação de redes de telecomunicações usando as três abordagens clássicas: simulação, análise e experimentação. Este projeto visa o desenvolvimento de um conjunto de experimentos para a disciplina de Avaliação de Desempenho de Sistemas da Engenharia de Telecomunicações com fins de melhor adequar a disciplina ao perfil do profissional previsto no PPC, que prevê um foco no desenvolvimento de sistemas. Pretende-se usar a tecnologia de rede IEEE802.15.4, resgatando dispositivos (nodos MICAZ) já adquiridos anteriormente, para desenvolver experimentos que combinem a tríade: análise, simulação e experimentação, permitindo transitar entre ferramentas do tipo Cadeias de Markov para realizar predição de desempenho da rede, projeto de experimento real de avaliação de desempenho usando nodos MICAZ a e simulação da estrutura contemplando a questão de escalabilidade e extensibilidade de cenários.

Plano de trabalho

As seguintes atividades serão desenvolvidas no decorrer da bolsa, não necessáriamente na ordem em que são citadas.

1) Participação na definição preliminar dos experimentos. (2 semanas)

2) Preparação dos nodos MICAZ para uso na disciplina (4 semanas)

2.1- Estudo do Hardware e Software pré-instalado no nodo

2.2-Familiarização com a placa de captura de pacotes

2.3-Familiarização com a placa e software de programação

2.4-Estudo de sistemas operacionais e pilhas de protocolos alternativos

2.5-Seleção e instalação final do sistema nos nodos.

3) Seleção e implementação de modelos de referência MAC para CSMA-CA e IEEE802.15.4(6 semanas)

3.1-Estudo de cadeias de Markov

3.2-Seleção e verificação de modelos de Markov para CSMA-CA e IEEE802.15.4

4) Implementação dos cenários selecionados em (3) em um simulador de rede

5) Implementação de experimentos no MICAZ para reproduzir resultados em de (3)

6) Organização dos roteiros de experimentos e documentação adicional

7) Relatório Final

Horários do bolsista

Horários Segunda-Feira Terça-Feira Quarta-Feira Quinta-Feira Sexta-Feira
7:30 às 9:30 Bolsa Bolsa Bolsa COM2 PJI3
9:40 às 12:00 Bolsa Bolsa COM2 Bolsa Bolsa
13:30 - 15:30 ADS/SMU STC STC CRF SMU
15:40 - 17:40 ECO CRF SUS ADS Bolsa
18:00 - 19:30 Livre Livre Livre Bolsa Bolsa

Semana 1 - Hardware do MICAZ (versão 1) e TinyOS

Semana 1 - 19/06/2017 - 23/06/2017
  • Estudo do Hardware e Software pré-instalado no nodo
    • Hardware do MICAZ (versão 1)

Antes de iniciar o estudo do MICAz é interessante situar o ambiente para o qual ele foi criado. As redes de sensores sem fio (WSN - do inglês wireless sensor network) é uma rede composta por dispositivos autônomos (também conhecidos como Motes) espacialmente distribuídos com o intuito de monitorar fenômenos físicos e ambientais como temperatura, umidade, luz, etc. “Comparado com soluções cabeadas, as WSNs oferecem maiores facilidades de implementação e mais flexibilidade de dispositivos. Com a rapidez do desenvolvimento tecnológico dos sensores as WSNs virarão a tecnologia chave para IoT (internet das coisas)”.[1]

Um dos padrões mais respeitados no mundo do IoT e seguido pelos fabricantes do MICAz é o zigbee. A Zigbee Alliance, que foi formado por um grupo de empresas de tecnologia, decidiu criar um padrão que garantisse a interoperabilidade entre seus produtos. Para isso, utilizaram como base para o zigbee o padrão IEEE 802.15.4 que define as camadas física e de acesso ao meio objetivando o baixo custo de implementação e baixo consumo de energia. A camada MAC oferece acesso ao meio através do CSMA-CA e a camada física proporciona taxas de transmissão de no máximo 250 Kbps quando operando na faixa dos 2.4 GHz resultando em um raio de alcance que, em média, fica entre 10m e 75m em ambientes fechados. Sobre as camadas física e de acesso ao meio foram definidas as camadas de rede e de aplicação seguindo outras especificações da Zigbee Alliance, como por exemplo o uso da arquitetura de rede Mesh e a capacidade de autogerenciamento da rede.

O MICAz utilizado nesta bolsa é um transceiver RF produzido pela Crossbow technology que opera na faixa dos 2.4 GHz e é utilizado para criar redes WSN com baixo consumo de energia. Equipado com o microcontrolador de baixa potência ATmega128L, o MICAz é compatível com o MoteWorks (plataforma de desenvolvimento de redes WSN) diretamente de sua memória flash interna e vem com o TinyOS (Ver sessão Software) por padrão de fábrica. Outras características do MICAz podem ser encontradas no datasheet dele e na imagem abaixo que é um print do datasheet.

AFW bolsa MICAZDATASHEET.jpg


O sistema operacional TinyOS desenvolvido para sensores que compoẽm uma WSN e já vem por padrão no MICAz. Este sistema operacional é basicamente um escalonador de tarefas e possui em sua biblioteca alguns protocolo de rede, drivers para sensoriamento e ferramentas para aquisição de dados. Para criar e programar o TinyOS utilizou-se uma nova linguagem chamada nesC que é baseada no C, e por isso apresenta algumas semelhanças com essa linguagem (O manual de referência do nesC pode ser encontrado em [5]). O código abaixo, retirado da wiki do TinyOS, é um exemplo em nesC de como um driver para LEDs pode ser implementado:

 configuration Led {
   provides {
     interface LedControl;
   }
    uses {
     interface Gpio;
   }
 }
 implementation {
 
   command void LedControl.turnOn() {
     call Gpio.set();
   }
 
   command void LedControl.turnOff() {
     call Gpio.clear();
   }
 }

</syntaxhighlight>

Referências

[1] http://www.iec.ch/whitepaper/pdf/iecWP-internetofthings-LR-en.pdf

[2] http://www.openautomation.net/page/productos/id/22/title/MICAz-2.4-GHz

[3]http://disalw3.epfl.ch/teaching/signals_instruments_systems/ay_2011-12/exercises/lab06/SIS_11-12_lab06_assignment.pdf

[4]https://repositorio-aberto.up.pt/bitstream/10216/71311/1/000143823.pdf

[5]http://nescc.sourceforge.net/papers/nesc-ref.pdf


Semana 2 - IEEE 802.15.4e e Hello World

Semana 2 - 26/06/2017 - 30/06/2017

IEEE 802.15.4e

O Task group 4e foi criado para rever e adicionar melhorias e novas funcionalidades para a camada MAC do padrão IEEE 802.15.4 e atender requisições da indústria. Essas novidades visaram a melhoria na capacidade (escalabilidade) do sistema e diminuir a susceptibilidade do padrão à interferências de outros dispositivos que operam na mesma faixa de frequência que o IEEE 802.15.4 (868 MHz/915MHz/2.4).

Para isso o 4e introduziu alguma variações nos métodos de acesso ao meio da camada de enlace do 802.15.4. O DSME (Deterministic and Synchronous Multi-channel Extension) extende o superframe a aumenta a quantidade de canais de frequência disponíveis para transmissão. O LLDN (Low Latency Deterministic Network) foi criado para redes com topologia estrela. O TSCH (Timeslotted Channel Hopping), que utiliza técnicas de sincronização temporal para melhorar o consumo energético e saltos de frequência para diminuir a vulnerabilidade à interferências do meio é o método mais aclamado por usuários do 802.15.4e. Resultados da comparação entre o 802.15.4 e o 802.15.4e podem ser encontrados em [1] e mais informações sobre o TSCH em [2].

Referências: [1] On MAC Layer protocols towards internet of things: From IEEE802.15.4 to IEEE802.15.4e

[2] http://www.simonduquennoy.net/papers/duquennoy17tsch.pdf


Hello World com o MICAz

  • Criação do ambiente para compilação
    • Instalação do toolchain do tinyOS (Adaptado de tinyos-wiki):

1 - Baixe o código do TinyOS do repositório Git e o extraia:

$	wget http://github.com/tinyos/tinyos-release/archive/tinyos-2_1_2.tar.gz
$	tar xf tinyos-2_1_2.tar.gz

1a - Renomeie o diretório tinyos-release-tinyos-2_1_2 para tinyos-main

$	mv tinyos-release-tinyos-2_1_2 tinyos-main

2 - Crie um arquivo tinyos.env com o seguinte código, porém substituindo o campo <local-tinyos-path> com o caminho escolhido até o diretório tinyos-main (Incluindo o diretorio tinyos no caminho)criado no passo 1:

# Here we setup the environment
# variables needed by the tinyos 
# make system
 
export TOSROOT="<local-tinyos-path>"

export TOSDIR="$TOSROOT/tos"

export CLASSPATH=$CLASSPATH:$TOSROOT/support/sdk/java

export MAKERULES="$TOSROOT/support/make/Makerules"

export PYTHONPATH=$PYTHONPATH:$TOSROOT/support/sdk/python
 
echo "setting up TinyOS on source path $TOSROOT"

3 - Como super-usuário copie o arquivo tinyos.env para o diretório /etc/profile.d/:

$	sudo cp tinyos.env /etc/profile.d/


    • Instalação do uISP ( Micro In-System Programmer) - O uISP é o software padrão para programação da MoteWorks. (Adaptado de akhila12ca)

1 - Baixe o uISP aqui ou aqui

2 - Descompacte o arquivo e faça a instalação


$	tar -xvzf uisp.tar.gz

$	cd uisp

$	./bootstrap

OBS: Neste ponto pode ser necessário realizar a instalação do Automake. Se nenhum erro ocorreu no passo anterior (./bootstrap), então o seguinte comando (apt-get install) pode ser desconsiderado.

$	sudo apt-get install automake
$	./configure

$	make

$	sudo make install


    • Instalação do compilador para o TinyOS, o ncc:
$	sudo apt-get install tinyos-tools


    • Há um erro relacionado com o avr-gcc que solicita que dados sejam colocados no segmento read-only da memória sem que esse dado seja const. O seguinte patch corrige o erro:

tinyos-main - issue #136 ou Download alternativo

Para instála-lo, basta ir para o diretório tinyos-main e aplicar o seguinte comando:

$	patch -p1 < tinyos-atm128-const-fix.patch

Se após a aplicação deste patch o seguinte erro persistir:

/usr/src/tinyos/tos/chips/atm128/McuSleepC.nc:66:15: error: variable ‘McuSleepC__atm128PowerBits’ must be const in order to be put into read-only section by means of ‘__attribute__((progmem))’
   const_uint8_t atm128PowerBits[ATM128_POWER_DOWN + 1] = {

Então, como super usuário, edite o seguinte arquivo:

/usr/src/tinyos/tos/chips/atm128/McuSleepC.nc

E modifique a linha 66 adicionando a palavra const:

  const const_uint8_t atm128PowerBits[ATM128_POWER_DOWN + 1] = {
    • Compilando e instalando o programa na placa

Existem alguns programas exemplo no diretório "tinyos-main/apps/". O programa Blink será utilizado como exemplo:


cd Blink

Para compilar o programa para o MICAz basta digitar o seguinte comando:

 make micaz

Para passar o programa para a placa os seguintes comandos devem ser feitos:

 sudo chmod 666 /dev/ttyUSB0
 make micaz install mib510,/dev/ttyUSB0

 ou para recompilar e instalar com um só comando:

 make micaz reinstall mib510,/dev/ttyUSB0

Semana 3 à 7 - Configuração do modo beacon-enabled e nonbeacon-enabled

Semana 3 à 7 - 03/07/2017 - 04/08/2017

Para configurar a camada MAC de acordo com o IEE802.15.4 é necessário utilizar a implementação deste padrão feita por Jan-Hinrich Hauer da Technical University Berlin. TKN15.4: An IEEE 802.15.4 MAC Implementation for TinyOS 2.

Utilizando as interfaces fornecidas pela TKN15.4 é possível configurar o MICAz para realizar transmissões sem o uso de beacons, com o uso destes e neste caso é possível utilizar a funcionalidade de GTS nos superframes.

Há uma complexidade considerável no entendimento destas interfaces. Por esta razão escolheu-se começar a desenvolver exemplos simples onde apenas um node envia beacons e não espera resposta alguma e, aos poucos, aumentar a complexidade destas aplicações. As aplicações mais recentes têm o potencial de comunicação entre coordenador e device, inclusive de troca de mensagens, e debug via serial.

Todos os arquivos necessários para compilar as aplicações (Ver semana 2) abaixo podem ser encontrado no GitHub (Experimentos_TKN154)

  • Modo nobeacon-enabled (CSMA/CA normal (beaconless))

Como neste modo não há envios periódicos de beacons pelo coordenador o processo de formação de uma rede PAN exige que alguns endereços sejam previamente conhecidos pelos participantes da rede. Se somente o device conhecer, previamente, o endereço do coordenador então este terá que fazer uma requisição de associação à rede. Se o coordenador também conhecer o endereço do device, previamente, então não há necessidade de uma requisição para associação.

As diferenças entre utilizar o modo nonbeacon-enabled e o enabled a nível de código pode ser notado quando for estudado o modo beacon-enabled pois é lá que as mudanças devem ser feitas. Aqui o único indicativo, que um usuário iniciante terá, que uma comunicação sem beacons está sendo feita é notando o valor da variável BEACON_ORDER e SUPERFRAME_ORDER. De acordo com o IEE 802.15.4 quando o valor de macBeaconOrder = 15 o coordenador não deve transmitir beacons, exceto quanto uma requisição for feita. O valor da varável macSuperframeOrder será ignorado quando macBeaconOrder = 15.

Código para o coordenador: Note que quando a MLME é iniciada o valor de macBeaconOrder é 15

/*
 Autor: André Felippe Weber
 Baseado nos trabalhos de Jan Hauer <hauer@tkn.tu-berlin.de>

 Para debugar via serial basta aplicar o seguinte comando no terminal:

 java net.tinyos.tools.PrintfClient -comm serial@/dev/ttyUSB1:57600

*/

#include "TKN154.h"
#include "app_profile.h"
#include "printf.h"

module ConectaEtrocaMsgP
{
  uses {
    interface Boot;
    interface MCPS_DATA;
    interface MLME_RESET;
    interface MLME_START;
    interface MLME_SET;
    interface MLME_GET;
    interface MLME_ASSOCIATE;
    interface MLME_DISASSOCIATE;
    interface MLME_COMM_STATUS;
    interface IEEE154Frame as Frame;
    interface Leds;
  }
} implementation {

  bool m_ledCount;

  event void Boot.booted() {
    call MLME_RESET.request(TRUE);
  }

  event void MLME_RESET.confirm(ieee154_status_t status)
  {
    if (status != IEEE154_SUCCESS)
      return;
    call MLME_SET.macShortAddress(COORDINATOR_ADDRESS);
    call MLME_SET.macAssociationPermit(TRUE);
    call MLME_SET.macRxOnWhenIdle(TRUE);

    call MLME_START.request(
                          PAN_ID,               // PANId
                          RADIO_CHANNEL,        // LogicalChannel
                          0,                    // ChannelPage,
                          0,                    // StartTime,
                          15,         // BeaconOrder
                          15,     // SuperframeOrder
                          TRUE,                 // PANCoordinator
                          FALSE,                // BatteryLifeExtension
                          FALSE,                // CoordRealignment
                          0,                    // CoordRealignSecurity,
                          0                     // BeaconSecurity
                        );
  }

  event void MLME_START.confirm(ieee154_status_t status) {    call Leds.led0On();}

/**********Associação*************/
  uint16_t m_shortAddress;
  ieee154_address_t m_lastDevice;

  event void MLME_ASSOCIATE.indication (
                          uint64_t DeviceAddress,
                          ieee154_CapabilityInformation_t CapabilityInformation,
                          ieee154_security_t *security
                        )
  {
    //call Leds.led1On();
    call MLME_ASSOCIATE.response(DeviceAddress, m_shortAddress++, IEEE154_ASSOCIATION_SUCCESSFUL, 0);
  }

  event void MLME_DISASSOCIATE.indication (
                          uint64_t DeviceAddress,
                          ieee154_disassociation_reason_t DisassociateReason,
                          ieee154_security_t *security
                        )
  {
    call Leds.led1Off();
  }


  event void MLME_COMM_STATUS.indication (
                          uint16_t PANId,
                          uint8_t SrcAddrMode,
                          ieee154_address_t SrcAddr,
                          uint8_t DstAddrMode,
                          ieee154_address_t DstAddr,
                          ieee154_status_t status,
                          ieee154_security_t *security
                        )
  {
    if (status == IEEE154_SUCCESS){
      // association was successful
      call Leds.led1On();
      m_lastDevice.extendedAddress = DstAddr.extendedAddress;
    } else {
      call Leds.led1Off();
    }
  }

  event void MLME_DISASSOCIATE.confirm    (
                          ieee154_status_t status,
                          uint8_t DeviceAddrMode,
                          uint16_t DevicePANID,
                          ieee154_address_t DeviceAddress
                        ){}

  event void MLME_ASSOCIATE.confirm    (
                          uint16_t AssocShortAddress,
                          uint8_t status,
                          ieee154_security_t *security
                        ){}

/*********Recepção de dados***********/


  bool m_ledCount=0;
  event message_t* MCPS_DATA.indication ( message_t* frame )
  {	
    if (m_ledCount++ >= 20) {
      m_ledCount = 0;
      printf("Mensagem recebida do device: %s \n", call Frame.getPayload(frame)/*frame->data*/);
      call Leds.led2Toggle();
    }
    return frame;
  }

  event void MCPS_DATA.confirm(message_t *msg, uint8_t msduHandle, ieee154_status_t status, uint32_t Timestamp){  }

}

Coodigo para o device:


/*
 Autor: André Felippe Weber
 Baseado nos trabalhos de Jan Hauer <hauer@tkn.tu-berlin.de>

 Para debugar via serial basta aplicar o seguinte comando no terminal:

 java net.tinyos.tools.PrintfClient -comm serial@/dev/ttyUSB1:57600

*/

#include "TKN154.h"
#include "app_profile.h"
#include "printf.h"

module RespondeBeaconsP
{
  uses {
    interface Boot;
    interface MCPS_DATA;
    interface MLME_RESET;
    interface MLME_SET;
    interface MLME_GET;
    interface MLME_ASSOCIATE;
    interface MLME_DISASSOCIATE;
    interface MLME_COMM_STATUS;
    interface IEEE154Frame as Frame;
    interface Leds;
    interface Packet;
  }
} implementation {

  message_t m_frame;
  uint8_t m_payloadLen;
  ieee154_PANDescriptor_t m_PANDescriptor;
  bool m_ledCount;
  ieee154_CapabilityInformation_t m_capabilityInformation;

  void startApp();
  task void packetSendTask();


  event void Boot.booted() {
    char payload[] = "Hello Coordinator!";
    uint8_t *payloadRegion;

    m_capabilityInformation.AlternatePANCoordinator = 0;
    m_capabilityInformation.DeviceType = 0;
    m_capabilityInformation.PowerSource = 0;
    m_capabilityInformation.ReceiverOnWhenIdle = 0;
    m_capabilityInformation.Reserved = 0;
    m_capabilityInformation.SecurityCapability = 0;
    m_capabilityInformation.AllocateAddress = 1;    

    m_payloadLen = strlen(payload);
    payloadRegion = call Packet.getPayload(&m_frame, m_payloadLen);
    if (m_payloadLen <= call Packet.maxPayloadLength()){
      memcpy(payloadRegion, payload, m_payloadLen);
      call MLME_RESET.request(TRUE);
    }
  }

  event void MLME_RESET.confirm(ieee154_status_t status)
  {
    if (status == IEEE154_SUCCESS)
      startApp();
  }

  void startApp()
  {
    ieee154_address_t coordAdr;

    coordAdr.shortAddress = COORDINATOR_ADDRESS;
    call MLME_SET.phyCurrentChannel(RADIO_CHANNEL);
    call MLME_SET.macAutoRequest(FALSE);
    call MLME_SET.macPANId(PAN_ID);
    call MLME_SET.macCoordShortAddress(COORDINATOR_ADDRESS);
    call MLME_ASSOCIATE.request(
          RADIO_CHANNEL,
          call MLME_GET.phyCurrentPage(),
          ADDR_MODE_SHORT_ADDRESS,
          PAN_ID,
          coordAdr,
          m_capabilityInformation,
          NULL  // security
          );    
  }

  event void MLME_ASSOCIATE.confirm    (
                          uint16_t AssocShortAddress,
                          uint8_t status,
                          ieee154_security_t *security
                        )
  {
    if ( status == IEEE154_SUCCESS ){
      call Leds.led1On();

      call Frame.setAddressingFields(
          &m_frame,                
          ADDR_MODE_SHORT_ADDRESS,        // SrcAddrMode,
          ADDR_MODE_SHORT_ADDRESS,        // DstAddrMode,
          m_PANDescriptor.CoordPANId,     // DstPANId,
          &m_PANDescriptor.CoordAddress,  // DstAddr,
          NULL                            // security
          );
      post packetSendTask(); 

    } else {
      call Leds.led0On();
      startApp(); // retry
    }
  }

  event void MLME_DISASSOCIATE.confirm    (
                          ieee154_status_t status,
                          uint8_t DeviceAddrMode,
                          uint16_t DevicePANID,
                          ieee154_address_t DeviceAddress
                        )
  {
    if (status == IEEE154_SUCCESS){
      call Leds.led1Off();
    } 
  }

  event void MLME_ASSOCIATE.indication (
                          uint64_t DeviceAddress,
                          ieee154_CapabilityInformation_t CapabilityInformation,
                          ieee154_security_t *security
                        ){}  

  event void MLME_DISASSOCIATE.indication (
                          uint64_t DeviceAddress,
                          ieee154_disassociation_reason_t DisassociateReason,
                          ieee154_security_t *security
                        ){}


  event void MLME_COMM_STATUS.indication (
                          uint16_t PANId,
                          uint8_t SrcAddrMode,
                          ieee154_address_t SrcAddr,
                          uint8_t DstAddrMode,
                          ieee154_address_t DstAddr,
                          ieee154_status_t status,
                          ieee154_security_t *security
                        ) {}


//*************************DADOS*********************************
  task void packetSendTask()
  {

    ieee154_address_t coordAdr;

    coordAdr.shortAddress = COORDINATOR_ADDRESS;
    call Frame.setAddressingFields(
                          &m_frame,                
                          ADDR_MODE_SHORT_ADDRESS,     // SrcAddrMode,
                          ADDR_MODE_SHORT_ADDRESS,     // DstAddrMode,
                          PAN_ID,                      // DstPANId,
                          &coordAdr,              	// DstAddr,
                          NULL                         // security
                        );

       if (call MCPS_DATA.request  (
          &m_frame,                         // frame,
          m_payloadLen,                     // payloadLength,
          0,                                // msduHandle,
          TX_OPTIONS_ACK // TxOptions,
          ) != IEEE154_SUCCESS)
      		call Leds.led0On();
	else{
		//printf("Frame enviado com sucesso! Conteúdo da mensagem: %s ! \n", call Frame.getPayload(&m_frame));
		//call Leds.led2Toggle();
	} 
 }

  event void MCPS_DATA.confirm    (
                          message_t *msg,
                          uint8_t msduHandle,
                          ieee154_status_t status,
                          uint32_t timestamp
                        )
  {
    if (status == IEEE154_SUCCESS && m_ledCount++ >= 20) {
      m_ledCount = 0;
      call Leds.led2Toggle();
    }
    call Leds.led0Toggle();
    post packetSendTask(); 
  }


  event message_t* MCPS_DATA.indication (message_t* frame)
  {
    // we don't expect data
    return frame;
  }

}

  • Modo beacon-enabled (Slotted CSMA)

Quando uma aplicação é programada para atuar com modo beacon-enabled deve-se além de modificar o Makefile, incluir a interface IEEE154TxBeaconPayload que proverá os beacons que serão enviados periodicamente pelo coordenador. Outra diferença à ser notada é o valor da variável BEACON_ORDER que é 15 para as aplicações que atuam no modo nonbeacon-enabled e aqui pode ser variada entre 0 e 14 para aumentar o intervalo entre os beacons enviados.

Na aplicação EnvioDeBeacons um node será programado como um coordenador de uma rede PAN 802.15.4 com envio de beacons. Este beacon será enviado periodicamente de acordo com a variável BEACON_ORDER definida no arquivo app_profile.h de acordo com o padrão 802.15.4.

Código para o coordenador:


/*
 Autor: André Felippe Weber
 Baseado nos trabalhos de Jan Hauer <hauer@tkn.tu-berlin.de>

 Para debugar via serial basta aplicar o seguinte comando no terminal:

 java net.tinyos.tools.PrintfClient -comm serial@/dev/ttyUSB1:57600

*/

#include "TKN154.h"
#include "app_profile.h"
#include "printf.h"

module EnviaBeaconsP
{
  uses {
    interface Boot;
    interface MLME_RESET;
    interface MLME_START;
    interface MLME_SET;
    interface MLME_GET;
    interface IEEE154TxBeaconPayload;
    interface Leds;
  }
} implementation {

 event void Boot.booted() {
    call MLME_RESET.request(TRUE);
  }

  event void MLME_RESET.confirm(ieee154_status_t status)
  {
    if (status != IEEE154_SUCCESS)
      return;
    call MLME_SET.phyTransmitPower(TX_POWER);
    call MLME_SET.macShortAddress(COORDINATOR_ADDRESS);
    call MLME_SET.macAssociationPermit(FALSE);
    call MLME_START.request(
                          PAN_ID,               // PANId
                          RADIO_CHANNEL,        // LogicalChannel
                          0,                    // ChannelPage,
                          0,                    // StartTime,
                          BEACON_ORDER,         // BeaconOrder
                          SUPERFRAME_ORDER,     // SuperframeOrder
                          TRUE,                 // PANCoordinator
                          FALSE,                // BatteryLifeExtension
                          FALSE,                // CoordRealignment
                          0,                    // CoordRealignSecurity,
                          0                     // BeaconSecurity
                        );
  }

  event void MLME_START.confirm(ieee154_status_t status) {}

  event void IEEE154TxBeaconPayload.aboutToTransmit() { 
      call Leds.led1Off();
      call Leds.led0On();
  }
  event void IEEE154TxBeaconPayload.setBeaconPayloadDone(void *beaconPayload, uint8_t length) { }

  event void IEEE154TxBeaconPayload.modifyBeaconPayloadDone(uint8_t offset, void *buffer, uint8_t bufferLength) { }

  event void IEEE154TxBeaconPayload.beaconTransmitted() 
  {
    ieee154_macBSN_t beaconSequenceNumber = call MLME_GET.macBSN();
    printf("Sequencia do beacon enviado: %hu ! \n", beaconSequenceNumber);
    call Leds.led0Off();
    call Leds.led1On();
  }  
}


Na aplicação RespondeBeacons um node será programado como um coordenador de uma rede PAN 802.15.4 com envio de beacons. Outro node deverá ser programado como um device que escaneará o canal pré-definido até receber beacons do coordenador afim de sincronizar-se e receber todos os beacons futuros. Ao receber os beacons o device enviará uma saudação ("Hello Coordinator!") ao coordenador.

Diferente

Código para o coordenador


/* 
 * Copyright (c) 2008, Technische Universitaet Berlin
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * - Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 * - 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.
 * - Neither the name of the Technische Universitaet Berlin nor the names
 *   of its contributors may be used to endorse or promote products derived
 *   from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER 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.
 *
 * - Revision -------------------------------------------------------------
 * $Revision: 1.2 $
 * $Date: 2010-01-05 17:12:56 $
 * @author: Jan Hauer <hauer@tkn.tu-berlin.de>
 * ========================================================================
 *
 *
 * Modificado em 25/07/2017 por André Felippe Weber
 *
 * Para debugar via serial basta aplicar o seguinte comando no terminal:
 *
 * java net.tinyos.tools.PrintfClient -comm serial@/dev/ttyUSB1:57600
 *
 */

#include "TKN154.h"
#include "app_profile.h"
#include "printf.h"

module RespondeBeaconsP
{
  uses {
    interface Boot;
    interface MCPS_DATA;
    interface MLME_RESET;
    interface MLME_START;
    interface MLME_SET;
    interface MLME_GET;
    interface IEEE154Frame as Frame;
    interface IEEE154TxBeaconPayload;
    interface Leds;
  }
} implementation {

  bool m_ledCount;

  event void Boot.booted() {
    call MLME_RESET.request(TRUE);
  }

  event void MLME_RESET.confirm(ieee154_status_t status)
  {
    if (status != IEEE154_SUCCESS)
      return;
    call MLME_SET.phyTransmitPower(TX_POWER);
    call MLME_SET.macShortAddress(COORDINATOR_ADDRESS);
    call MLME_SET.macAssociationPermit(FALSE);
    call MLME_START.request(
                          PAN_ID,               // PANId
                          RADIO_CHANNEL,        // LogicalChannel
                          0,                    // ChannelPage,
                          0,                    // StartTime,
                          BEACON_ORDER,         // BeaconOrder
                          SUPERFRAME_ORDER,     // SuperframeOrder
                          TRUE,                 // PANCoordinator
                          FALSE,                // BatteryLifeExtension
                          FALSE,                // CoordRealignment
                          0,                    // CoordRealignSecurity,
                          0                     // BeaconSecurity
                        );
  }
  bool m_ledCount;
  event message_t* MCPS_DATA.indication ( message_t* frame )
  {	
    if (m_ledCount++ >= 20) {
      m_ledCount = 0;
      printf("Mensagem recebida do device: %s \n", call Frame.getPayload(frame)/*frame->data*/);
      call Leds.led2Toggle();
    }
    return frame;
  }

  event void MLME_START.confirm(ieee154_status_t status) {}

  bool count_teste;
  event void MCPS_DATA.confirm(message_t *msg, uint8_t msduHandle, ieee154_status_t status, uint32_t Timestamp){

  }

  event void IEEE154TxBeaconPayload.aboutToTransmit() {
      call Leds.led1Off();
      call Leds.led0On();
  }

  event void IEEE154TxBeaconPayload.setBeaconPayloadDone(void *beaconPayload, uint8_t length) { }

  event void IEEE154TxBeaconPayload.modifyBeaconPayloadDone(uint8_t offset, void *buffer, uint8_t bufferLength) { }

  event void IEEE154TxBeaconPayload.beaconTransmitted() 
  {
    ieee154_macBSN_t beaconSequenceNumber = call MLME_GET.macBSN();
  //  printf("Sequencia do beacon enviado: %hu ! \n", beaconSequenceNumber);
    call Leds.led0Off();
    call Leds.led1On();
  }  
}

Código para o device


/* 
 * Copyright (c) 2008, Technische Universitaet Berlin
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * - Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 * - 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.
 * - Neither the name of the Technische Universitaet Berlin nor the names
 *   of its contributors may be used to endorse or promote products derived
 *   from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER 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.
 *
 * - Revision -------------------------------------------------------------
 * $Revision: 1.2 $
 * $Date: 2010-01-05 17:12:56 $
 * @author: Jan Hauer <hauer@tkn.tu-berlin.de>
 * ========================================================================
 *
 *
 * Modificado em 25/07/2017 por André Felippe Weber
 *
 * Para debugar via serial basta aplicar o seguinte comando no terminal:
 *
 * java net.tinyos.tools.PrintfClient -comm serial@/dev/ttyUSB1:57600
 *
 */

#include "TKN154.h"
#include "app_profile.h"
#include "printf.h"
module RespondeBeaconsP
{
  uses {
    interface Boot;
    interface MCPS_DATA;
    interface MLME_RESET;
    interface MLME_SET;
    interface MLME_GET;
    interface MLME_SCAN;
    interface MLME_SYNC;
    interface MLME_BEACON_NOTIFY;
    interface MLME_SYNC_LOSS;
    interface IEEE154Frame as Frame;
    interface IEEE154BeaconFrame as BeaconFrame;
    interface Leds;
    interface Packet;
  }
} implementation {

  message_t m_frame;
  uint8_t m_payloadLen;
  ieee154_PANDescriptor_t m_PANDescriptor;
  bool m_ledCount;
  bool m_wasScanSuccessful;

  void startApp();
  task void packetSendTask();


  event void Boot.booted() {
    char payload[] = "Hello Coordinator!";
    uint8_t *payloadRegion;

    m_payloadLen = strlen(payload);
    payloadRegion = call Packet.getPayload(&m_frame, m_payloadLen);
    if (m_payloadLen <= call Packet.maxPayloadLength()){
      memcpy(payloadRegion, payload, m_payloadLen);
      call MLME_RESET.request(TRUE);
    }
  }

  event void MLME_RESET.confirm(ieee154_status_t status)
  {
    if (status == IEEE154_SUCCESS)
      startApp();
  }

  void startApp()
  {
    ieee154_phyChannelsSupported_t channelMask;
    uint8_t scanDuration = BEACON_ORDER;

    call MLME_SET.phyTransmitPower(TX_POWER);
    call MLME_SET.macShortAddress(TOS_NODE_ID);

    // scan only the channel where we expect the coordinator
    channelMask = ((uint32_t) 1) << RADIO_CHANNEL;

    // we want all received beacons to be signalled 
    // through the MLME_BEACON_NOTIFY interface, i.e.
    // we set the macAutoRequest attribute to FALSE
    call MLME_SET.macAutoRequest(FALSE);
    m_wasScanSuccessful = FALSE;
    call MLME_SCAN.request  (
                           PASSIVE_SCAN,           // ScanType
                           channelMask,            // ScanChannels
                           scanDuration,           // ScanDuration
                           0x00,                   // ChannelPage
                           0,                      // EnergyDetectListNumEntries
                           NULL,                   // EnergyDetectList
                           0,                      // PANDescriptorListNumEntries
                           NULL,                   // PANDescriptorList
                           0                       // security
                        );
  }

  event message_t* MLME_BEACON_NOTIFY.indication (message_t* frame)
  { 
    // received a beacon frame
    ieee154_phyCurrentPage_t page = call MLME_GET.phyCurrentPage();
    ieee154_macBSN_t beaconSequenceNumber = call BeaconFrame.getBSN(frame);

    printf("Sequencia do beacon recebido: %hu ! \n", beaconSequenceNumber);

    if (!m_wasScanSuccessful) {
      // received a beacon during channel scanning
      if (call BeaconFrame.parsePANDescriptor(
            frame, RADIO_CHANNEL, page, &m_PANDescriptor) == SUCCESS) {
        // let's see if the beacon is from our coordinator...
        if (m_PANDescriptor.CoordAddrMode == ADDR_MODE_SHORT_ADDRESS &&
            m_PANDescriptor.CoordPANId == PAN_ID &&
            m_PANDescriptor.CoordAddress.shortAddress == COORDINATOR_ADDRESS){
          // yes! wait until SCAN is finished, then syncronize to the beacons
          m_wasScanSuccessful = TRUE;
        }
      }
    } else { 
      // received a beacon during synchronization, toggle LED1
      call Leds.led1Toggle();

    }

    return frame;
  }

  event void MLME_SCAN.confirm    (
                          ieee154_status_t status,
                          uint8_t ScanType,
                          uint8_t ChannelPage,
                          uint32_t UnscannedChannels,
                          uint8_t EnergyDetectListNumEntries,
                          int8_t* EnergyDetectList,
                          uint8_t PANDescriptorListNumEntries,
                          ieee154_PANDescriptor_t* PANDescriptorList
                        )
  {
    if (m_wasScanSuccessful) {
      // we received a beacon from the coordinator before
      call MLME_SET.macCoordShortAddress(m_PANDescriptor.CoordAddress.shortAddress);
      call MLME_SET.macPANId(m_PANDescriptor.CoordPANId);
      call MLME_SYNC.request(m_PANDescriptor.LogicalChannel, m_PANDescriptor.ChannelPage, TRUE);
      call Frame.setAddressingFields(
          &m_frame,                
          ADDR_MODE_SHORT_ADDRESS,        // SrcAddrMode,
          ADDR_MODE_SHORT_ADDRESS,        // DstAddrMode,
          m_PANDescriptor.CoordPANId,     // DstPANId,
          &m_PANDescriptor.CoordAddress,  // DstAddr,
          NULL                            // security
          );
      post packetSendTask(); 
    } else
      startApp();
  }

  task void packetSendTask()
  {
    if (!m_wasScanSuccessful)
      return;
    else if (call MCPS_DATA.request  (
          &m_frame,                         // frame,
          m_payloadLen,                     // payloadLength,
          0,                                // msduHandle,
          TX_OPTIONS_ACK // TxOptions,
          ) != IEEE154_SUCCESS)
      		call Leds.led0On();
	//else
	//	printf("Frame enviado com sucesso! Conteúdo da mensagem: %s ! \n", call Frame.getPayload(&m_frame));
  }

  event void MCPS_DATA.confirm    (
                          message_t *msg,
                          uint8_t msduHandle,
                          ieee154_status_t status,
                          uint32_t timestamp
                        )
  {
    if (status == IEEE154_SUCCESS && m_ledCount++ >= 20) {
      m_ledCount = 0;
      call Leds.led2Toggle();
    }
    post packetSendTask(); 
  }

  event void MLME_SYNC_LOSS.indication(
                          ieee154_status_t lossReason,
                          uint16_t PANId,
                          uint8_t LogicalChannel,
                          uint8_t ChannelPage,
                          ieee154_security_t *security)
  {
    m_wasScanSuccessful = FALSE;
    call Leds.led1Off();
    call Leds.led2Off();
  }

  event message_t* MCPS_DATA.indication (message_t* frame)
  {
    // we don't expect data
    return frame;
  }

}


    • Modo beacon-enabled com o uso de GTS


Semana 8 - Contiki

Semana 8 - 04/08/2017 - 11/08/2017

Contiki é um sistema operacional open source para internet das coisas. Assim como o TinyOS, esse S.O. é utilizado para compilar aplicações para nodes que têm como pré requisito o baixo consumo de bateria e baixo custo. Porém, diferentemente do TinyOS que utiliza a liguagem NesC as aplicações para o Contiki podem ser escritas em C. Como o objetivo desta bolsa é o desenvolvimento de experimentos para a disciplina de Avaliação de Desempenho de Sistemas da Engenharia de Telecomunicações faz sentido que prefira-se trabalhar com uma linguagem já conhecida pelos alunos (C) em detrimento de uma (nesC) que faria com que os alunos perdessem um certo tempo para assimilarem. Por isso esta semana foi dedicada ao estudo desta alternativa ao TinyOS, o Contiki.

Para compilar aplicações para o MICAz utilizando o Contiki é necessário rodar uma máquina virtual com a imagem do Instant Contiki que pode ser encontrado em http://www.contiki-os.org/start.html. Apesar da recomendação de utilizar o VMWare Player para rodar a imagem, foi utilizado o VirtualBOX em uma das máquinas do LaBIC com bons resultados. Apenas uma ressalva deve ser feita, para que o virtual box enxergue as portas USB da máquina física foi necessário seguir os seguintes passos, na máquina física (Real):

  • baixe e instale o Oracle VM VirtualBox Extension Pack para a sua versão do Virtual box
  • Abra o VirtualBox e clique em “Arquivo” >> “Preferências”, e na janela que abrir clique na opção Extensões e então clique no ícone “azulzinho” no lado direito da janela acrescente o novo pacote que você acabou de baixar.
  • Finalmente, no terminal digite o seguinte comando:

$    usermod NOME -a -G vboxusers

Pode ser necessário reiniciar a máquina física também para que as mudanças sejam aplicadas ao VirtualBox

Lembre-se que será necessário adicionar a porta relacionada ao MICAz à máquina virtual. Isso deve ser feito a partir no submenu USB do menu configurações da VM.

Para compilar o primeiro programa utilizando a máquina virtual

  • cd contiki/examples/cc2530dk/
  • make TARGET=micaz
  • make TARGET=micaz blink-hello.upload PORT=/dev/ttyUSB0


OBS: O seguinte erro pode acontecer quando a compilação acima for feita:

/usr/lib/avr/include/avr/boot.h:112:16: error: attempt to use poisoned "SPMCR"
 #elif defined (SPMCR)

Para corrigir basta editar, como root, o arquivo /usr/lib/avr/include/avr/boot.h

Este bloco de "define" que tem uma linha localizada na linha 112 deve ser subsistituído


//Check for SPM Control Register in processor.
#if defined (SPMCSR)
#  define __SPM_REG    SPMCSR
#elif defined (SPMCR)
#  define __SPM_REG    SPMCR
#else
#  error AVR processor does not provide bootloader support!
#endif

Deve ser subsitituído por isso:

#if defined (SPMCSR)
#  define __SPM_REG    SPMCSR
#else
#if defined (SPMCR)
#  define __SPM_REG    SPMCR
#else
#  error AVR processor does not provide bootloader support!
#endif
#endif

O erro parece estar no uso do elif.

Fontes:

http://www.contiki-os.org/

http://sejalivre.org/habilitando-o-suporte-a-usb-no-virtualbox/

Semana 9 - Alternativas ao TinyOS (Contiki e outros) (802.15.4)

Semana 8 - 14/08/2017 - 18/08/2017
Sistema Descrição
TinyOS Uma implementação do 802.15.4 foi estudada dentre as semanas 3 e 7. Esta implementação oferece suporte para os modos beacon e beconless além do uso do GTS. Há outra implementação do 802.15.4 para o tinyOS chamada open-ZB que pode ser utilizada como uma alternativa à primeira implementação.
Contiki Para o Contiki OS existe uma implementação ainda em desenvolvimento do 802.15.4 incluindo algumas adaptações sugeridas na revisão de 2015 da IEE. Incluindo alguns estudos sobre o TSCH vide http://www.simonduquennoy.net/papers/duquennoy17tsch.pdf, https://github.com/contiki-os/contiki/blob/master/apps/orchestra/README.md e https://github.com/contiki-os/contiki/pull/1807/files.
OpenWSN e FreeRTOS O OpenWSN é um projeto que visa a implementação, open-source, de pilhas de protocolos voltados à internet das coisas que possui suporte ao 802.15.4e. O FreeRTOS é o único sistema operacional para sistemas embarcados documentado, oficialmente, pelo OpenWSN (https://openwsn.atlassian.net/wiki/spaces/OW/pages/50102295/FreeRTOS). Porém há duas outras opções em desenvolvimento: Riot e OpenOS (https://openwsn.atlassian.net/wiki/questions/110198890/openwsn-is-operating-system-)
OpenWRT O OpenWRT é um sistema operacional para sistemas embarcados, porém o foco desse SO é roteadores. Há suporte para roteamento de pacotes que utilizam o padrão 802.15.4. Porém, roteamento não é o foco desta bolsa.
-- --
    • contiki

[1]http://anrg.usc.edu/contiki/index.php/MAC_protocols_in_ContikiOS

[2]http://wireless.ictp.it/school_2015/book/book.pdf

[3]https://github.com/contiki-os/contiki/pull/1904 ---> https://github.com/contiki-os/contiki/pull/1904/files#diff-a5c6067d8fa8e56903d7e037399ce294R658

    • OpenWSN

[4]https://openwsn.atlassian.net/wiki/spaces/OW/pages/50102295/FreeRTOS [5]https://pdfs.semanticscholar.org/6d3c/2e987c50edb8ca998d9118112fd0cf5ca0a5.pdf

Semana 9 - Testes com o contiki

Semana 9 - 21/08/2017 - 25/08/2017

Alguns testes utilizando o contiki foram realizado com o objetivo de acessar, diretamente, o rádio do MICAz (CC2420). Este rádio opera utilizando o IEE 802.15.4. Porém as funções que deveriam ser implementadas pela camada MAC não existem no contiki. Logo, algumas funções básicas do 15.4 como designação de coordenadores e nodes ou o envio de beacons não poderão ser utilizadas. Sendo assim, o seguinte código de teste que realiza uma simples comunicação entre dois motes MICAz foi compilado.

Crie um diretório helloTeste em /contiki/examples e crie, em helloTeste, um arquivo radio-test.c com o seguinte código.

/*
 * 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.
 *
 *
 * -----------------------------------------------------------------
 *
 * Author  : Adam Dunkels, Joakim Eriksson, Niclas Finne
 * Created : 2006-03-07
 * Updated : $Date: 2010/01/15 10:32:36 $
 *           $Revision: 1.6 $
 *
 * Simple application to indicate connectivity between two nodes:
 *
 * - Red led indicates a packet sent via radio (one packet sent each second)
 * - Green led indicates that this node can hear the other node but not
 *   necessary vice versa (unidirectional communication).
 * - Blue led indicates that both nodes can communicate with each
 *   other (bidirectional communication)
 */

//Adaptação e comentários por Andre Felippe Weber

#include "contiki.h"
#include "net/rime/rime.h"
#include "dev/leds.h"
#include "dev/button-sensor.h"
#include "cc2420.h"
#include <stdio.h>
#include <string.h>

PROCESS(radio_test_process, "Radio test");
AUTOSTART_PROCESSES(&radio_test_process);

#define ON  1
#define OFF 0

#define HEADER "RTST"
#define PACKET_SIZE 20
#define PORT 9345

struct indicator {
  int onoff;
  int led;
  clock_time_t interval;
  struct etimer timer;
};
static struct etimer send_timer;
static struct indicator recv, other, flash;

/*---------------------------------------------------------------------*/
static void
set(struct indicator *indicator, int onoff) {
  if(indicator->onoff ^ onoff) {
    indicator->onoff = onoff;
    if(onoff) {
      leds_on(indicator->led);
    } else {
      leds_off(indicator->led);
    }
  }
  if(onoff) {
    etimer_set(&indicator->timer, indicator->interval);
  }
}
/*---------------------------------------------------------------------------*/

//Documentacao sobre o abc: http://contiki.sourceforge.net/docs/2.6/a01717.html#_details
//The abc module sends packets to all local area neighbors.

static void
abc_recv(struct abc_conn *c)
{
  /* packet received */
  if(packetbuf_datalen() < PACKET_SIZE
     || strncmp((char *)packetbuf_dataptr(), HEADER, sizeof(HEADER))) {
    /* invalid message */

  } else {
    PROCESS_CONTEXT_BEGIN(&radio_test_process);
    set(&recv, ON);
    set(&other, ((char *)packetbuf_dataptr())[sizeof(HEADER)] ? ON : OFF);

    /* synchronize the sending to keep the nodes from sending
       simultaneously */

    etimer_set(&send_timer, CLOCK_SECOND);
    etimer_adjust(&send_timer, - (int) (CLOCK_SECOND >> 1));
    PROCESS_CONTEXT_END(&radio_test_process);
  }
}
static const struct abc_callbacks abc_call = {abc_recv};
static struct abc_conn abc;
/*---------------------------------------------------------------------*/
PROCESS_THREAD(radio_test_process, ev, data)
{
  static uint8_t txpower;
  PROCESS_BEGIN();

  /*A macro CC2420_TXPOWER_MAX está definida como 31 em cc2420.h. Este valor corresponde ao PA_LEVEL definido 
na Table 9 do datasheet do cc2420 (Link na semana 10). 31 corresponde a 0 dBm.*/

  txpower = CC2420_TXPOWER_MAX;

  /* Initialize the indicators */
  recv.onoff = other.onoff = flash.onoff = OFF;
  recv.interval = other.interval = CLOCK_SECOND;
  flash.interval = 1;
  flash.led = LEDS_RED;
  recv.led = LEDS_GREEN;
  other.led = LEDS_YELLOW;

  abc_open(&abc, PORT, &abc_call);
  etimer_set(&send_timer, CLOCK_SECOND);
  //SENSORS_ACTIVATE(button_sensor);

  while(1) {
    PROCESS_WAIT_EVENT();
    if (ev == PROCESS_EVENT_TIMER) {
      if(data == &send_timer) {
	etimer_reset(&send_timer);

	/* send packet */
	packetbuf_copyfrom(HEADER, sizeof(HEADER));
	((char *)packetbuf_dataptr())[sizeof(HEADER)] = recv.onoff;
	/* send arbitrary data to fill the packet size */
	packetbuf_set_datalen(PACKET_SIZE);
	set(&flash, ON);
	abc_send(&abc);

      } else if(data == &other.timer) {
	set(&other, OFF);

      } else if(data == &recv.timer) {
	set(&recv, OFF);

      } else if(data == &flash.timer) {
	set(&flash, OFF);
      }
    } 
    
   txpower = CC2420_TXPOWER_MAX;

   //utilizar o set_value ao inves do cc2420_set_txpower(txpower) é mais seguro, pois a 
  // primeira opcao testa os valores e retorna confirmacao de sucesso.  
   set_value(RADIO_PARAM_TXPOWER, txpower)
   




  }
  PROCESS_END();
}
/*---------------------------------------------------------------------*/

em um arquivo Makefile cole o seguinte código:

CONTIKI = ../../
ifndef TARGET
TARGET=micaz
endif

all: blink sky-collect #rt-leds test-button test-cfs tcprudolph0

%.tgz: %.ihex
	mkdir $(basename $<) ; \
	mv $< $(basename $<) ; \
	echo $(basename $<)/$(basename $<).ihex 600 > $(basename $<)/runfile ; \
	tar czf $@ $(basename $<)

CONTIKI_WITH_IPV4 = 1
CONTIKI_WITH_RIME = 1
include $(CONTIKI)/Makefile.include

É possível ainda rodar este código diretamente no Cooja que é o simulador de rede do contiki. Para isso o seguinte tutorial deve ser seguido: http://www.contiki-os.org/start.html


Enviando utilizando as funçoes do driver diretamente. https://sourceforge.net/p/contiki/mailman/message/27852273/

Semana 10 e 11- API do contiki para configuração do 802.15.4

Semana 10 e 11- 28/08/2017 - 6/09/2017


Semana 12- Estudo da netstack do contiki, parâmetros configuráveis da camada MAC e funções do driver do cc2420

Semana 12- 11/09/2017 - 15/09/2017

Estudo da netstack

A Netstack do Contiki organiza seus modulos em pilhas de protocolos que cobrem todas as camadas tradicionais do modelo OSI. A Netstack é formada por 4 camadas (Figura 1) conhecidas como:

1. Network layer - NETSTACK_NETWORK - A camada de network cria, automaticamente, uma rede IPV6 com auxilio do protocolo RPL (Routing Protocol for Low-power and Lossy Networks (LLNs)).[4]


2. MAC (Medium Access Control) layer - NETSTACK_MAC - A camada MAC oferece duas implementações possíveis:

  • CSMA/CA: Carrier Sense Multiple Access with Collision Avoidance

+ Verifica se o canal está livre antes de transmitir.

+ Realiza um back-off se outro nodo está transmitindo.

+ Temporização depende da RDC layer.

+ A camada de Network define o número de transmissões.

  • nullmac: Encaminha pacotes da camada superior para o driver de rádio e vice versa.


3. RDC (Radio Duty Cycling) layer - NETSTACK_RDC

O Contiki possui três mecanismos de duty cycling: ContikiMAC, X-MAC and LPP. ContikiMAC é um protocolo baseado nos princípios por trás da verificação de canal com baixo consumo energético porém mais eficiente. Contiki's X-MAC é baseado no protocolo X-MAC original, mas melhorado para reduzir o consumo de energia e manter boas condições de rede. o LPPse baseia no protocolo Low-Power Probing (LPP) mas como mecanismo que melhoram o consumo de energia e também com mecanismos para envio de broadcast.

Para uma descrição detalha da camada RDC, acesse [6].


4. Radio layer - NETSTACK_RADIO

A camada de rádio é onde os pacotes são enviados e também recebidos. A informação pode ser recebida em bytes ou em pacotes inteiros através dos handlers de interrupção.

ContikiNetstack.png

Fonte [4]


Por padrão o Contiki oferece duas pilhas de protocolos de rede (Netstack). Umas delas é o O uIP (micro IP)que subdivide-se nas pilhas IPV4 e IPV6. A outra pilha é do protocolo Rime que oferece algumas primitivas de comunicação do tipo single-hop e multi-hop. No primeiro caso a transmissão é feita de um nodo diretamente para outro enquanto no segundo caso a informação é roteada através de outros nodos. Porém, é importante frisar que o nodos pelos quais a informação é roteada devem invocar as camadas superiores de protocolos ou a aplicação para que um deles defina o próximo salto. Dentre as primitivas de comunicação a mais básica é anonymous best-effort single-hop broadcast (abc). Utilizando o abc um nodo pode realizar o broadcast de uma informação para seus vizinhos de forma anônima. Existem nove outras primitivas que se baseiam no abc para realizar a transmissão de pacotes e estão definidas em [1] .


[1] Descrição detalhada do Rime: https://it.uu.se/edu/course/homepage/wcnes/vt11/schedule/dunkels07adaptive.pdf

[2] Descrição do Contiki: https://www.slideshare.net/ADunkels/building-day-2-upload-1

[3] Configurar a netstack: https://sourceforge.net/p/contiki/mailman/message/25402552/

[4] Network Stack: http://anrg.usc.edu/contiki/index.php/Network_Stack OBS: As referências de 4 contêm alguns slides bastante esclarecedores quanto ao funcionamento da Netstack.

[5] Configurar a netstack: https://github.com/contiki-os/contiki/wiki/Change-mac-or-radio-duty-cycling-protocols#About_MAC_Drivers

[6] Descrição da RDC Layer: https://github.com/contiki-os/contiki/wiki/Radio-duty-cycling

parâmetros configuráveis da camada MAC

Não existem funções para modificar os valores dos parâmetros do CSMA (Como pode ser visto em [1]). Elas são definidas como Macros e portanto algumas modificações deverão ser feitas e funções criadas para que seja possível (re)configurá-los. Dos parâmetros definidos na tabela do topico "parameters" de [2] apenas aqueles que não são relacionados ao uso de superframe, beacon e slots foram definidos na implementação do CSMA do Contiki pois ele implementa o CSMA unslotted. algum dos parâmetros existentes são CSMA_MIN_BE, CSMA_MAX_BE, CSMA_MAX_BACKOFF e CSMA_MAX_MAX_FRAME_RETRIES.

[1] https://github.com/contiki-os/contiki/blob/master/core/net/mac/csma.c [2] http://www.prismmodelchecker.org/casestudies/zigbee.php#protocol

funções do driver do cc2420

O objetivo deste tópico, e que deverá ficar ativo ao longo das próximas semanas é documentar o uso das funções existentes no driver do cc2420 para o Contiki ([1]). Isto é, os parâmetros que devem ser passados e o retorno esperado da chamada de cada função.

Antes de começar a documentar, de fato, decidiu-se realizar alguns testes (com simulações no Cooja) para conhecer as funções:

#include "contiki.h"
#include "cc2420.h"
#include <stdio.h> /* For printf() */
/*---------------------------------------------------------------------------*/
PROCESS(hello_world_process, "Hello world process");
AUTOSTART_PROCESSES(&hello_world_process);
/*---------------------------------------------------------------------------*/

static struct etimer et;

PROCESS_THREAD(hello_world_process, ev, data)
{
  PROCESS_BEGIN();
  static struct etimer et;
  static int cnt;
  static int i;
  for(i=0;i<2222225;i++)
  {
    etimer_set(&et, CLOCK_SECOND);

	   PROCESS_WAIT_EVENT();
	   if(ev == PROCESS_EVENT_TIMER){
		   etimer_reset(&et);
		   if(0==i%6)
		   {
		      cc2420_init();
		      cc2420_on();
		      cc2420_cca();
		      cc2420_off();
		      cc2420_set_channel(26);
		       if(i%8==0)
		       {
			  cc2420_prepare("hill",4);
			  cnt = cc2420_transmit(4);
			  printf("channel is %d,cnt is %d\n",cc2420_get_channel(),cnt);
		       }
		       else
		       {
			  cc2420_prepare("abcde",5);
			  cnt = cc2420_transmit(5);
		       }
		    }
	   }
  }

  PROCESS_END();
}

[1] https://github.com/contiki-os/contiki/blob/master/dev/cc2420/cc2420.c

Semana 13- Arquitetura para desenvolvimento de experimentos

Semana 13 - 18/09/2017 - 22/09/2017

Uma plataforma foi idealizada (Figura 1) com a finalidade de realizar os experimentos para a disciplina de Avaliação de Desempenho de Sistemas. Esta plataforma é constituída de um computador e pelo menos um nodo, e tem como objetivo reconfigurar os parâmetros dos experimentos em tempo real, sem necessidade de um reboot no sistema. Em uma das pontas do sistema um arquivo XML será utilizado para configurar os parâmetros do experimento. Isto é, o usuário escolherá valores de configurações para o CSMA na camada MAC. Por exemplo os valores de CSMA_MIN_BE, CSMA_MAX_BE, CSMA_MAX_BACKOFF e CSMA_MAX_MAX_FRAME_RETRIES poderão ser ajustados.

PlatDesExpADS.jpg


Possíveis casos de uso para a plataforma:

  • O usuário captura o estado de todos os nodos. O estado inclui: nodeid, paraâmetros atualmente configurados:
    • estado da bateria,
    • nível de TX Power;
    • memória disponível;
  • O usuário edita parâmetros a serem repassados para o nodo em arquivo XML.
  • O usuário configura os nodos;
  • O usuário inicia o experimento (incluir até a finalizaçã);
  • O usuário coleta e analisa os dados do experimento.
  • O usuário subsituir o código da aplicação (a verificar);
  • O usuário comanda avaliação de Qualidade de Link e RSSI entre nodos (futuramente estimativa de localização??).

Semana 14- Reconfigurar parâmetros da camada MAC

Semana 14 - 25/09/2017 - 29/09/2017

O objetivo dos trabalhos dessa semana são modificar o código do arquivo csma.c para transformar as macros que guardam os valores de CSMA_MIN_BE, CSMA_MAX_BE, CSMA_MAX_BACKOFF e CSMA_MAX_MAX_FRAME_RETRIES em váriaveis. E então criar um patch que poderá ser aplicado no csma.c existente na VM do contiki.

csma.c


/*
 * Copyright (c) 2010, 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
 *         A Carrier Sense Multiple Access (CSMA) MAC layer
 * \author
 *         Adam Dunkels <adam@sics.se>
 */

#include "net/mac/csma.h"
#include "net/packetbuf.h"
#include "net/queuebuf.h"

#include "sys/ctimer.h"
#include "sys/clock.h"

#include "lib/random.h"

#include "net/netstack.h"

#include "lib/list.h"
#include "lib/memb.h"

#include <string.h>

#include <stdio.h>

#define DEBUG 0
#if DEBUG
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#else /* DEBUG */
#define PRINTF(...)
#endif /* DEBUG */

/* Constants of the IEEE 802.15.4 standard */

/* macMinBE: Initial backoff exponent. Range 0--CSMA_MAX_BE */
/*#ifdef CSMA_CONF_MIN_BE
#define CSMA_MIN_BE CSMA_CONF_MIN_BE
#else
#define CSMA_MIN_BE 0
#endif*/

/* macMaxBE: Maximum backoff exponent. Range 3--8 */
/*#ifdef CSMA_CONF_MAX_BE
#define CSMA_MAX_BE CSMA_CONF_MAX_BE
#else
#define CSMA_MAX_BE 4
#endif
*/
/* macMaxCSMABackoffs: Maximum number of backoffs in case of channel busy/collision. Range 0--5 */
/*#ifdef CSMA_CONF_MAX_BACKOFF
#define CSMA_MAX_BACKOFF CSMA_CONF_MAX_BACKOFF
#else
#define CSMA_MAX_BACKOFF 5
#endif*/

/* macMaxFrameRetries: Maximum number of re-transmissions attampts. Range 0--7 */
/*#ifdef CSMA_CONF_MAX_FRAME_RETRIES
#define CSMA_MAX_MAX_FRAME_RETRIES CSMA_CONF_MAX_FRAME_RETRIES
#else
#define CSMA_MAX_MAX_FRAME_RETRIES 7
#endif*/


/* Packet metadata */
struct qbuf_metadata {
  mac_callback_t sent;
  void *cptr;
  uint8_t max_transmissions;
};

/* Every neighbor has its own packet queue */
struct neighbor_queue {
  struct neighbor_queue *next;
  linkaddr_t addr;
  struct ctimer transmit_timer;
  uint8_t transmissions;
  uint8_t collisions;
  LIST_STRUCT(queued_packet_list);
};

/* The maximum number of co-existing neighbor queues */
#ifdef CSMA_CONF_MAX_NEIGHBOR_QUEUES
#define CSMA_MAX_NEIGHBOR_QUEUES CSMA_CONF_MAX_NEIGHBOR_QUEUES
#else
#define CSMA_MAX_NEIGHBOR_QUEUES 2
#endif /* CSMA_CONF_MAX_NEIGHBOR_QUEUES */

/* The maximum number of pending packet per neighbor */
#ifdef CSMA_CONF_MAX_PACKET_PER_NEIGHBOR
#define CSMA_MAX_PACKET_PER_NEIGHBOR CSMA_CONF_MAX_PACKET_PER_NEIGHBOR
#else
#define CSMA_MAX_PACKET_PER_NEIGHBOR MAX_QUEUED_PACKETS
#endif /* CSMA_CONF_MAX_PACKET_PER_NEIGHBOR */

#define MAX_QUEUED_PACKETS QUEUEBUF_NUM //16
MEMB(neighbor_memb, struct neighbor_queue, CSMA_MAX_NEIGHBOR_QUEUES);
MEMB(packet_memb, struct rdc_buf_list, MAX_QUEUED_PACKETS);
MEMB(metadata_memb, struct qbuf_metadata, MAX_QUEUED_PACKETS);
LIST(neighbor_list);

int get_neighbor_list_length(){
	return list_length(neighbor_list);
}

static void packet_sent(void *ptr, int status, int num_transmissions);
static void transmit_packet_list(void *ptr);
/*---------------------------------------------------------------------------*/
static struct neighbor_queue *
neighbor_queue_from_addr(const linkaddr_t *addr)
{
  struct neighbor_queue *n = list_head(neighbor_list);
  while(n != NULL) {
    if(linkaddr_cmp(&n->addr, addr)) {
      return n;
    }
    n = list_item_next(n);
  }
  return NULL;
}
/*---------------------------------------------------------------------------*/
static clock_time_t
backoff_period(void)
{
  clock_time_t time;
  /* The retransmission time must be proportional to the channel
     check interval of the underlying radio duty cycling layer. */
  time = NETSTACK_RDC.channel_check_interval();

  /* If the radio duty cycle has no channel check interval, we use
   * the default in IEEE 802.15.4: aUnitBackoffPeriod which is
   * 20 symbols i.e. 320 usec. That is, 1/3125 second. */
  if(time == 0) {
    time = MAX(CLOCK_SECOND / 3125, 1);
  }
  return time;
}
/*---------------------------------------------------------------------------*/
static void
transmit_packet_list(void *ptr)
{
  struct neighbor_queue *n = ptr;
  if(n) {
    struct rdc_buf_list *q = list_head(n->queued_packet_list);
    if(q != NULL) {
      PRINTF("csma: preparing number %d %p, queuffe len %d\n", n->transmissions, q,
          list_length(n->queued_packet_list));
      /* Send packets in the neighbor's list */
      NETSTACK_RDC.send_list(packet_sent, n, q);
    }
  }
}
/*---------------------------------------------------------------------------*/
static void
schedule_transmission(struct neighbor_queue *n)
{
  clock_time_t delay;
 // int backoff_exponent; /* BE in IEEE 802.15.4 */

  backoff_exponent = MIN(n->collisions, CSMA_MAX_BE);

  /* Compute max delay as per IEEE 802.15.4: 2^BE-1 backoff periods  */
  delay = ((1 << backoff_exponent) - 1) * backoff_period();
  if(delay > 0) {
    /* Pick a time for next transmission */
    delay = random_rand() % delay;
  }

  PRINTF("csma: scheduling transmission in %u ticks, NB=%u, BE=%u\n",
      (unsigned)delay, n->collisions, backoff_exponent);
  ctimer_set(&n->transmit_timer, delay, transmit_packet_list, n);
}
/*---------------------------------------------------------------------------*/
static void
free_packet(struct neighbor_queue *n, struct rdc_buf_list *p, int status)
{
  if(p != NULL) {
    /* Remove packet from list and deallocate */
    list_remove(n->queued_packet_list, p);

    queuebuf_free(p->buf);
    memb_free(&metadata_memb, p->ptr);
    memb_free(&packet_memb, p);
    PRINTF("csma: free_queued_packet, queue length %d, free packets %d\n",
           list_length(n->queued_packet_list), memb_numfree(&packet_memb));
    if(list_head(n->queued_packet_list) != NULL) {
      /* There is a next packet. We reset current tx information */
      n->transmissions = 0;
      n->collisions = CSMA_MIN_BE;
      /* Schedule next transmissions */
      schedule_transmission(n);
    } else {
      /* This was the last packet in the queue, we free the neighbor */
      ctimer_stop(&n->transmit_timer);
      list_remove(neighbor_list, n);
      memb_free(&neighbor_memb, n);
    }
  }
}
/*---------------------------------------------------------------------------*/
static void
tx_done(int status, struct rdc_buf_list *q, struct neighbor_queue *n)
{
  mac_callback_t sent;
  struct qbuf_metadata *metadata;
  void *cptr;
  uint8_t ntx;

  metadata = (struct qbuf_metadata *)q->ptr;
  sent = metadata->sent;
  cptr = metadata->cptr;
  ntx = n->transmissions;

  switch(status) {
  case MAC_TX_OK:
    PRINTF("csma: rexmit ok %d\n", n->transmissions);
    break;
  case MAC_TX_COLLISION:
  case MAC_TX_NOACK:
    PRINTF("csma: drop with status %d after %d transmissions, %d collisions\n",
                 status, n->transmissions, n->collisions);
    break;
  default:
    PRINTF("csma: rexmit failed %d: %d\n", n->transmissions, status);
    break;
  }

  free_packet(n, q, status);
  mac_call_sent_callback(sent, cptr, status, ntx);
}
/*---------------------------------------------------------------------------*/
static void
rexmit(struct rdc_buf_list *q, struct neighbor_queue *n)
{
  schedule_transmission(n);
  /* This is needed to correctly attribute energy that we spent
     transmitting this packet. */
  queuebuf_update_attr_from_packetbuf(q->buf);
}
/*---------------------------------------------------------------------------*/
static void
collision(struct rdc_buf_list *q, struct neighbor_queue *n,
          int num_transmissions)
{
  struct qbuf_metadata *metadata;

  //Incrementa o contador de colisoes detectadas por este nodo
  colisoes++;

  metadata = (struct qbuf_metadata *)q->ptr;

  n->collisions += num_transmissions;

  if(n->collisions > CSMA_MAX_BACKOFF) {
    n->collisions = CSMA_MIN_BE;
    /* Increment to indicate a next retry */
    n->transmissions++;
  }

  if(n->transmissions >= metadata->max_transmissions) {
    tx_done(MAC_TX_COLLISION, q, n);
  } else {
    PRINTF("csma: rexmit collision %d\n", n->transmissions);
    rexmit(q, n);
  }
}
/*---------------------------------------------------------------------------*/
static void
noack(struct rdc_buf_list *q, struct neighbor_queue *n, int num_transmissions)
{
  struct qbuf_metadata *metadata;

  metadata = (struct qbuf_metadata *)q->ptr;

  n->collisions = CSMA_MIN_BE;
  n->transmissions += num_transmissions;

  if(n->transmissions >= metadata->max_transmissions) {
    tx_done(MAC_TX_NOACK, q, n);
  } else {
    PRINTF("csma: rexmit noack %d\n", n->transmissions);
    rexmit(q, n);
  }
}
/*---------------------------------------------------------------------------*/
static void
tx_ok(struct rdc_buf_list *q, struct neighbor_queue *n, int num_transmissions)
{
  //Incrementa o contador de transmissoes bem sucedidas detectadas por este nodo
  transmissoes_ok++;
  n->collisions = CSMA_MIN_BE;
  n->transmissions += num_transmissions;
  tx_done(MAC_TX_OK, q, n);
}
/*---------------------------------------------------------------------------*/
static void
packet_sent(void *ptr, int status, int num_transmissions)
{
  struct neighbor_queue *n;
  struct rdc_buf_list *q;

  n = ptr;
  if(n == NULL) {
    return;
  }

  /* Find out what packet this callback refers to */
  for(q = list_head(n->queued_packet_list);
      q != NULL; q = list_item_next(q)) {
    if(queuebuf_attr(q->buf, PACKETBUF_ATTR_MAC_SEQNO) ==
       packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO)) {
      break;
    }
  }

  if(q == NULL) {
    PRINTF("csma: seqno %d not found\n",
           packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO));
    return;
  } else if(q->ptr == NULL) {
    PRINTF("csma: no metadata\n");
    return;
  }

  switch(status) {
  case MAC_TX_OK:
    tx_ok(q, n, num_transmissions);
    break;
  case MAC_TX_NOACK:
    noack(q, n, num_transmissions);
    break;
  case MAC_TX_COLLISION:
    collision(q, n, num_transmissions);
    break;
  case MAC_TX_DEFERRED:
    break;
  default:
    tx_done(status, q, n);
    break;
  }
}
/*---------------------------------------------------------------------------*/
static void
send_packet(mac_callback_t sent, void *ptr)
{
  struct rdc_buf_list *q;
  struct neighbor_queue *n;
  static uint8_t initialized = 0;
  static uint16_t seqno;
  const linkaddr_t *addr = packetbuf_addr(PACKETBUF_ADDR_RECEIVER);

  if(!initialized) {
    initialized = 1;
    /* Initialize the sequence number to a random value as per 802.15.4. */
    seqno = random_rand();
  }

  if(seqno == 0) {
    /* PACKETBUF_ATTR_MAC_SEQNO cannot be zero, due to a pecuilarity
       in framer-802154.c. */
    seqno++;
  }
  packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, seqno++);

  /* Look for the neighbor entry */
  n = neighbor_queue_from_addr(addr);
  if(n == NULL) {
    /* Allocate a new neighbor entry */
    n = memb_alloc(&neighbor_memb);
    if(n != NULL) {
      /* Init neighbor entry */
      linkaddr_copy(&n->addr, addr);
      n->transmissions = 0;
      n->collisions = CSMA_MIN_BE;
      /* Init packet list for this neighbor */
      LIST_STRUCT_INIT(n, queued_packet_list);
      /* Add neighbor to the list */
      list_add(neighbor_list, n);
    }
  }

  if(n != NULL) {
    /* Add packet to the neighbor's queue */
    if(list_length(n->queued_packet_list) < CSMA_MAX_PACKET_PER_NEIGHBOR) {
      q = memb_alloc(&packet_memb);
      if(q != NULL) {
        q->ptr = memb_alloc(&metadata_memb);
        if(q->ptr != NULL) {
          q->buf = queuebuf_new_from_packetbuf();
          if(q->buf != NULL) {
            struct qbuf_metadata *metadata = (struct qbuf_metadata *)q->ptr;
            /* Neighbor and packet successfully allocated */
            if(packetbuf_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS) == 0) {
              /* Use default configuration for max transmissions */
              metadata->max_transmissions = CSMA_MAX_MAX_FRAME_RETRIES + 1;
            } else {
              metadata->max_transmissions =
                packetbuf_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS);
            }
            metadata->sent = sent;
            metadata->cptr = ptr;
#if PACKETBUF_WITH_PACKET_TYPE
            if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) ==
               PACKETBUF_ATTR_PACKET_TYPE_ACK) {
              list_push(n->queued_packet_list, q);
            } else
#endif
            {
              list_add(n->queued_packet_list, q);
            }

            PRINTF("csma: send_packet, queue length %d, free packets %d\n",
                   list_length(n->queued_packet_list), memb_numfree(&packet_memb));
            /* If q is the first packet in the neighbor's queue, send asap */
            if(list_head(n->queued_packet_list) == q) {
              schedule_transmission(n);
            }
	    //Incrementa o contador de transmissoes realizadas.
	    transmissoes_total++;
            return;
          }
          memb_free(&metadata_memb, q->ptr);
          PRINTF("csma: could not allocate queuebuf, dropping packet\n");
        }
        memb_free(&packet_memb, q);
        PRINTF("csma: could not allocate queuebuf, dropping packet\n");
      }
      /* The packet allocation failed. Remove and free neighbor entry if empty. */
      if(list_length(n->queued_packet_list) == 0) {
        list_remove(neighbor_list, n);
        memb_free(&neighbor_memb, n);
      }
    } else {
      PRINTF("csma: Neighbor queue full\n");
    }
    PRINTF("csma: could not allocate packet, dropping packet\n");
  } else {
    PRINTF("csma: could not allocate neighbor, dropping packet\n");
  }
  mac_call_sent_callback(sent, ptr, MAC_TX_ERR, 1);
}
/*---------------------------------------------------------------------------*/
static void
input_packet(void)
{
  NETSTACK_LLSEC.input();
}
/*---------------------------------------------------------------------------*/
static int
on(void)
{
  return NETSTACK_RDC.on();
}
/*---------------------------------------------------------------------------*/
static int
off(int keep_radio_on)
{
  return NETSTACK_RDC.off(keep_radio_on);
}
/*---------------------------------------------------------------------------*/
static unsigned short
channel_check_interval(void)
{
  if(NETSTACK_RDC.channel_check_interval) {
    return NETSTACK_RDC.channel_check_interval();
  }
  return 0;
}
/*---------------------------------------------------------------------------*/
static void
init(void)
{
  memb_init(&packet_memb);
  memb_init(&metadata_memb);
  memb_init(&neighbor_memb);
}
/*---------------------------------------------------------------------------*/
const struct mac_driver csma_driver = {
  "CSMA",
  init,
  send_packet,
  input_packet,
  on,
  off,
  channel_check_interval,
};
/*---------------------------------------------------------------------------*/

csma.h


/*
 * 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
 *         A MAC stack protocol that performs retransmissions when the
 *         underlying MAC layer has problems with collisions
 * \author
 *         Adam Dunkels <adam@sics.se>
 */

#ifndef CSMA_H_
#define CSMA_H_

#include "net/mac/mac.h"
#include "dev/radio.h"
#include "net/mac/csma_variable.h"

extern const struct mac_driver csma_driver;

const struct mac_driver *csma_init(const struct mac_driver *r);

unsigned int CSMA_MAX_BE = 3;
unsigned int CSMA_MAX_BACKOFF = 5;
unsigned int CSMA_MIN_BE = 0;
unsigned int CSMA_MAX_MAX_FRAME_RETRIES = 7;
int backoff_exponent;

void set_mac_csma(mac_csma_param_t param, mac_csma_value_t value){
	if(value<0) return;

	switch(param){
		/* macMaxBE: Maximum backoff exponent. Range 3--8 */
		case CSMA_MAX_BE_:
			if(value >=3 && value <= 8)
				CSMA_MAX_BE = value;
			break;
		/* macMinBE: Initial backoff exponent. Range 0--CSMA_MAX_BE */
		case CSMA_MIN_BE_:
			if(value >=0 && value <= CSMA_MAX_BE)
				CSMA_MIN_BE = value;
			break;
		/* macMaxCSMABackoffs: Maximum number of backoffs in case of channel busy/collision. Range 0--5 */
		case CSMA_MAX_BACKOFF_:
			if(value >=0 && value <= 5)
				CSMA_MAX_BACKOFF = value;
			break;
		/* macMaxFrameRetries: Maximum number of re-transmissions attampts. Range 0--7 */
		case CSMA_MAX_MAX_FRAME_RETRIES_:
			if(value >=0 && value <= 7)
				CSMA_MAX_MAX_FRAME_RETRIES = value;
			break;

	}
}

unsigned long int transmissoes_ok=0;
unsigned long int transmissoes_total=0;
unsigned long int colisoes=0;

int get_mac_csma(mac_csma_param_t param){
	switch(param){
		/* macMaxBE: Maximum backoff exponent. Range 3--8 */
		case CSMA_MAX_BE_:
			return CSMA_MAX_BE;
		/* macMinBE: Initial backoff exponent. Range 0--CSMA_MAX_BE */
		case CSMA_MIN_BE_:
			return CSMA_MIN_BE;						
		/* macMaxCSMABackoffs: Maximum number of backoffs in case of channel busy/collision. Range 0--5 */
		case CSMA_MAX_BACKOFF_:
			return CSMA_MAX_BACKOFF;
		/* macMaxFrameRetries: Maximum number of re-transmissions attampts. Range 0--7 */
		case CSMA_MAX_MAX_FRAME_RETRIES_:
			return CSMA_MAX_MAX_FRAME_RETRIES;
		case CSMA_CURRENT_BE_:
			return backoff_exponent;
		case CSMA_COLLISIONS_:
			return colisoes;
		case CSMA_TRANSMISSION_OK_:
			return transmissoes_ok;
		case CSMA_TRANSMISSION_TOTAL_:
			return transmissoes_total;
	}
}

#endif /* CSMA_H_ */

csma_variable.h


#ifndef CSMA_VARIABLE_H_
#define CSMA_VARIABLE_H_

typedef unsigned int mac_csma_value_t;
typedef unsigned mac_csma_param_t;
enum {
	CSMA_MAX_BE_,
	CSMA_MIN_BE_,
	CSMA_MAX_BACKOFF_,
	CSMA_MAX_MAX_FRAME_RETRIES_,
	CSMA_CURRENT_BE_,
	CSMA_COLLISIONS_,
	CSMA_TRANSMISSION_OK_,
	CSMA_TRANSMISSION_TOTAL_
};

#endif

Arquivo para testes


/*
 * 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.
 *
 *
 * -----------------------------------------------------------------
 *
 * Author  : Adam Dunkels, Joakim Eriksson, Niclas Finne
 * Created : 2006-03-07
 * Updated : $Date: 2010/01/15 10:32:36 $
 *           $Revision: 1.6 $
 *
 * Simple application to indicate connectivity between two nodes:
 *
 * - Red led indicates a packet sent via radio (one packet sent each second)
 * - Green led indicates that this node can hear the other node but not
 *   necessary vice versa (unidirectional communication).
 * - Blue led indicates that both nodes can communicate with each
 *   other (bidirectional communication)
 */

#include "contiki.h"
#include "net/rime/rime.h"
#include "net/mac/csma_variable.h"
#include "dev/leds.h"
#include "dev/button-sensor.h"
#include "cc2420.h"
#include <stdio.h>
#include <string.h>

PROCESS(radio_test_process, "Radio test");
AUTOSTART_PROCESSES(&radio_test_process);

#define ON  1
#define OFF 0

#define HEADER "RTST"
#define PACKET_SIZE 20
#define PORT 9345

struct indicator {
  int onoff;
  int led;
  clock_time_t interval;
  struct etimer timer;
};
static struct etimer send_timer;
static struct indicator recv, other, flash;

/*---------------------------------------------------------------------*/
static void
set(struct indicator *indicator, int onoff) {
  if(indicator->onoff ^ onoff) {
    indicator->onoff = onoff;
    if(onoff) {
      leds_on(indicator->led);
    } else {
      leds_off(indicator->led);
    }
  }
  if(onoff) {
    etimer_set(&indicator->timer, indicator->interval);
  }
}
/*---------------------------------------------------------------------------*/
static void
abc_recv(struct abc_conn *c)
{
  /* packet received */
  if(packetbuf_datalen() < PACKET_SIZE
     || strncmp((char *)packetbuf_dataptr(), HEADER, sizeof(HEADER))) {
    /* invalid message */

  } else {
    PROCESS_CONTEXT_BEGIN(&radio_test_process);
    set(&recv, ON);
    set(&other, ((char *)packetbuf_dataptr())[sizeof(HEADER)] ? ON : OFF);

    /* synchronize the sending to keep the nodes from sending
       simultaneously */

    etimer_set(&send_timer, CLOCK_SECOND);
    etimer_adjust(&send_timer, - (int) (CLOCK_SECOND >> 1));
    PROCESS_CONTEXT_END(&radio_test_process);
  }
}
static const struct abc_callbacks abc_call = {abc_recv};
static struct abc_conn abc;
/*---------------------------------------------------------------------*/
int count=0;
PROCESS_THREAD(radio_test_process, ev, data)
{
  //static uint8_t txpower;
  PROCESS_BEGIN();

  //txpower = CC2420_TXPOWER_MAX;

  /* Initialize the indicators */
  recv.onoff = other.onoff = flash.onoff = OFF;
  recv.interval = other.interval = CLOCK_SECOND;
  flash.interval = 1;
  flash.led = LEDS_RED;
  recv.led = LEDS_GREEN;
  other.led = LEDS_BLUE;

  abc_open(&abc, PORT, &abc_call);
  etimer_set(&send_timer, CLOCK_SECOND);
 // SENSORS_ACTIVATE(button_sensor);
  while(1) {
    PROCESS_WAIT_EVENT();
    if (ev == PROCESS_EVENT_TIMER) {
      if(data == &send_timer) {
	etimer_reset(&send_timer);

	/* send packet */
	packetbuf_copyfrom(HEADER, sizeof(HEADER));
	((char *)packetbuf_dataptr())[sizeof(HEADER)] = recv.onoff;
	/* send arbitrary data to fill the packet size */
	packetbuf_set_datalen(PACKET_SIZE);
	set(&flash, ON);
	abc_send(&abc);
        
      } else if(data == &other.timer) {
	set(&other, OFF);

      } else if(data == &recv.timer) {
	set(&recv, OFF);

      } else if(data == &flash.timer) {
	set(&flash, OFF);
      }
    } 
    if(count++ == 50)
	set_mac_csma(CSMA_MAX_BE_, 8);

    if(get_mac_csma(CSMA_MAX_BE_)==8)
	printf("current BE: %d\n", get_mac_csma(CSMA_CURRENT_BE_));  

   printf("tamanho da lista: %d\n", get_mac_csma(CSMA_TRANSMISSION_TOTAL_));

  }
  PROCESS_END();
}
/*---------------------------------------------------------------------*/

Semana 15- CoAP

Semana 15 - 02/10/2017 - 06/09/2017


Fontes:

http://www.vs.inf.ethz.ch/publ/papers/mkovatsc-2011-iotech-coap.pdf

https://www.youtube.com/watch?v=4bSr5x5gKvA

https://training.ti.com/ti-designs-and-products-contiki-6lowpan-overview

https://training.ti.com/ti-designs-and-products-contiki-6lowpan-implementing-smart-grid-application-coap

Semana 16 - Comunicaçao xbee e micaz (contiki)

Semana 16 - 02/10/2017 - 06/09/2017

OBS: O link abaixo pode ser lido adicionando esse código em uma arquivo de texto com extensão .html e abrindo ele com um navegador. http://redmine.labo4g.enstb.fr/projects/public-wiki/wiki/802154_interoperability_tests_between_Xbee_and_Tmote_sky

https://sourceforge.net/p/contiki/mailman/message/32308021/

https://github.com/lbpassos/Robot-Pigeon

Semanas 17-19 - CoAP

Semanas 17-19 - 09/10/2017 - 27/10/2017

As últimas semanas foram dedicadas à tentativas de criar primeiros experimentos e a plataforma de desenvolvimento utilizando o contiki.

Semanas 20-22 - Desenvolvimento da plataforma

Semanas 20-22 - 30/10/2017 - 17/11/2017

Referências Úteis

A critical analysis of Contiki’s network stack for integrating new MAC protocols: https://hal.inria.fr/hal-01202542/document

802154 e cc2420
Datasheet cc2420

] https://github.com/contiki-os/contiki/tree/master/core/net/mac/tsch

http://www.prismmodelchecker.org/casestudies/zigbee.php#protocol

https://it.uu.se/edu/course/homepage/wcnes/vt11/schedule/dunkels07adaptive.pdf

https://george.autonomic-networks.ele.tue.nl/

https://www.researchgate.net/publication/232708159_Contiki-based_IEEE_802154_Node%27s_Throughput_and_Wireless_Channel_Utilization_Analysis

Artigos Geradores de Tráfego

http://ieeexplore.ieee.org.ez130.periodicos.capes.gov.br/document/7986326/

pages.cs.wisc.edu/~pb/selfconfig_final.pdf

http://ieeexplore.ieee.org.ez130.periodicos.capes.gov.br/document/4908333/

http://ieeexplore.ieee.org.ez130.periodicos.capes.gov.br/document/7823282/

http://ieeexplore.ieee.org.ez130.periodicos.capes.gov.br/stamp/stamp.jsp?arnumber=5487204