0

I am trying to analyze a network by measuring Throughput, Packet Delivery Ratio and Network Lifetime using TelosB. I am using TinyOS-2.1.1 for simulating and programming. As a base code, I am using the TestNetworkC.nc that comes with the OS.

I have done a few modifications to obtain the data, but the output I get is buggy. The output shows that only 1 node, the root is transmitting and receiving, while the rest remains idle.

#include <Timer.h>
#include "TestNetwork.h"
#include "CtpDebugMsg.h"

module TestNetworkC {
  uses interface Boot;
  uses interface SplitControl as RadioControl;
  uses interface SplitControl as SerialControl;
  uses interface StdControl as RoutingControl;
  uses interface StdControl as DisseminationControl;
  uses interface DisseminationValue<uint32_t> as DisseminationPeriod;
  uses interface Send;
  uses interface Leds;
  uses interface Read<uint16_t> as ReadSensor;
  uses interface Timer<TMilli>;
  uses interface Timer<TMilli> as Timer1;
  uses interface RootControl;
  uses interface Receive;
  uses interface AMSend as UARTSend;
  uses interface CollectionPacket;
  uses interface CtpInfo;
  uses interface CtpCongestion;
  uses interface Random;
  uses interface Queue<message_t*>;
  uses interface Pool<message_t>;
  uses interface CollectionDebug;
  uses interface AMPacket;
  uses interface Packet as RadioPacket;
}
implementation {
  task void uartEchoTask();
  message_t packet;
  message_t uartpacket;
  message_t* recvPtr = &uartpacket;
  uint8_t msglen;
  uint8_t msgsuccess;
  uint8_t msgfail;
  uint8_t totmsg;
  uint8_t sendpkt;
  uint8_t pkts;
  uint8_t recpkt;
  uint8_t battery = 100;
  bool sendBusy = FALSE;
  bool uartbusy = FALSE;
  bool firstTimer = TRUE;
  bool measurebat = TRUE;
  uint16_t seqno;
  enum {
    SEND_INTERVAL = 8192
  };

  event void ReadSensor.readDone(error_t err, uint16_t val) { }  

  event void Boot.booted() {
    dbg("App", "Booted at %s.\n", sim_time_string());
    call SerialControl.start();
    if(measurebat)
    call Timer1.startPeriodic( 5000 );
  }
  event void Timer1.fired()
  {
    //dbg("App", "Battery at @ %s is %d.\n", sim_time_string(), battery);
    dbg("App", "Sent: %d\nRec: %d\nSuc: %d\nFail:%d\nFailed: %d", sendpkt, recpkt, msgsuccess, msgfail, pkts);

  }
  event void SerialControl.startDone(error_t err) {
    call RadioControl.start();
    dbg("App", "Radio on %s.\n", sim_time_string());

  }
  event void RadioControl.startDone(error_t err) {
    if (err != SUCCESS) {
      call RadioControl.start();
    }
    else {
      call DisseminationControl.start();
      call RoutingControl.start();
      if (TOS_NODE_ID % 500 == 0) {
        dbg("App", "Root Node %d.\n", TOS_NODE_ID);
    call RootControl.setRoot();
      }
      seqno = 0;
        call Timer.startOneShot(call Random.rand16() & 0x1ff);
    }
  }

  event void RadioControl.stopDone(error_t err) {
    dbg("App", "Radio Stopped at %s.\n", sim_time_string());
  }

  event void SerialControl.stopDone(error_t err) {} 

  void failedSend() {
    dbg("App", "%s: Send failed.\n", __FUNCTION__);

    call CollectionDebug.logEvent(NET_C_DBG_1);
  }


  void sendMessage() {
    TestNetworkMsg* msg = (TestNetworkMsg*)call Send.getPayload(&packet, sizeof(TestNetworkMsg));
    uint16_t metric;
    am_addr_t parent = 0;
    sendpkt++;
    call CtpInfo.getParent(&parent);
    call CtpInfo.getEtx(&metric);

    msg->source = TOS_NODE_ID;
    msg->seqno = seqno;
    msg->data = 0xCAFE;
    msg->parent = parent;
    msg->hopcount = 0;
    msg->metric = metric;
    msg->powerCount = battery;
    battery = battery - 2;

    if (call Send.send(&packet, sizeof(TestNetworkMsg)) != SUCCESS) {
      failedSend();
      call Leds.led0On();
      pkts++;
      dbg("TestNetworkC", "%s: Transmission failed.\n", __FUNCTION__);
    }
    else {
      sendBusy = TRUE;
      seqno++; 

      dbg("TestNetworkC", "%s: Transmission succeeded.\n", __FUNCTION__);
    }
    if(msg->powerCount <= 0){
      //call RadioControl.stop();
    }
  }


  event void Timer.fired() {
    uint32_t nextInt;
    dbg("TestNetworkC", "TestNetworkC: Timer fired.\n");
    nextInt = call Random.rand32() % SEND_INTERVAL;
    nextInt += SEND_INTERVAL >> 1;
    call Timer.startOneShot(nextInt);
    if (!sendBusy)
    sendMessage();
  }

  event void Send.sendDone(message_t* m, error_t err) {
    if (err != SUCCESS) {
      msgfail++;
      call Leds.led0On();
    }
    sendBusy = FALSE;
    msgsuccess++;
    dbg("TestNetworkC", "Send completed.\n");
  }

  event void DisseminationPeriod.changed() {
    const uint32_t* newVal = call DisseminationPeriod.get();
    call Timer.stop();
    call Timer.startPeriodic(*newVal);
  }


  uint8_t prevSeq = 0;
  uint8_t firstMsg = 0;

  event message_t* 
  Receive.receive(message_t* msg, void* payload, uint8_t len) {
    dbg("TestNetworkCrec", "Received packet at %s from node %hhu with seq no %hhu.\n", sim_time_string(), call CollectionPacket.getOrigin(msg), call CollectionPacket.getSequenceNumber(msg));
    call Leds.led1Toggle();
    recpkt++;

    if (call CollectionPacket.getOrigin(msg) == 1) {
      if (firstMsg == 1) {
    if (call CollectionPacket.getSequenceNumber(msg) - prevSeq > 1) {
      call Leds.led2On();
    }
      } else {
    firstMsg = 1;
      }
      prevSeq = call CollectionPacket.getSequenceNumber(msg);
    }

    if (!call Pool.empty() && call Queue.size() < call Queue.maxSize()) {
      message_t* tmp = call Pool.get();
      call Queue.enqueue(msg);
      if (!uartbusy) {
        post uartEchoTask();
      }
      return tmp;
    }
    return msg;
 }

 task void uartEchoTask() {
    dbg("Traffic", "Sending packet to UART.\n");
   if (call Queue.empty()) {
     return;
   }
   else if (!uartbusy) {
     message_t* msg = call Queue.dequeue();
     dbg("Traffic", "Sending packet to UART.\n");
     if (call UARTSend.send(0xffff, msg, call RadioPacket.payloadLength(msg)) == SUCCESS) {
       uartbusy = TRUE;
     }
     else {
      call CollectionDebug.logEventMsg(NET_C_DBG_2,
                       call CollectionPacket.getSequenceNumber(msg),
                       call CollectionPacket.getOrigin(msg),
                       call AMPacket.destination(msg));
     }
   }
 }

  event void UARTSend.sendDone(message_t *msg, error_t error) {
    dbg("Traffic", "UART send done.\n");
    uartbusy = FALSE;
    call Pool.put(msg);
    if (!call Queue.empty()) {
      post uartEchoTask();
    } 
    else {
      //        call CtpCongestion.setClientCongested(FALSE);
    }
  }

  /* Default implementations for CollectionDebug calls.
   * These allow CollectionDebug not to be wired to anything if debugging
   * is not desired. */

    default command error_t CollectionDebug.logEvent(uint8_t type) {
        return SUCCESS;
    }
    default command error_t CollectionDebug.logEventSimple(uint8_t type, uint16_t arg) {
        return SUCCESS;
    }
    default command error_t CollectionDebug.logEventDbg(uint8_t type, uint16_t arg1, uint16_t arg2, uint16_t arg3) {
        return SUCCESS;
    }
    default command error_t CollectionDebug.logEventMsg(uint8_t type, uint16_t msg, am_addr_t origin, am_addr_t node) {
        return SUCCESS;
    }
    default command error_t CollectionDebug.logEventRoute(uint8_t type, am_addr_t parent, uint8_t hopcount, uint16_t metric) {
        return SUCCESS;
    }

}

The Python code I am using to simulate is

:
from TOSSIM import *
from tinyos.tossim.TossimApp import *
from random import *
import sys

#n = NescApp("TestNetwork", "app.xml")
#t = Tossim(n.variables.variables())
t = Tossim([])
r = t.radio()

f = open("sparse-grid.txt", "r")
lines = f.readlines()
for line in lines:
  s = line.split()
  if (len(s) > 0):
    if s[0] == "gain":
      r.add(int(s[1]), int(s[2]), float(s[3]))

noise = open("meyer-short.txt", "r")
lines = noise.readlines()
for line in lines:
  str = line.strip()
  if (str != ""):
    val = int(str)
    for i in range(0, 10):
      m = t.getNode(i);
      m.addNoiseTraceReading(val)



for i in range(0, 10):
  m = t.getNode(i);
  m.createNoiseModel();
  time = randint(t.ticksPerSecond(),  15* t.ticksPerSecond())
  m.bootAtTime(time)
  print "Booting ", i, " at time ", time

print "Starting simulation."

#t.addChannel("AM", sys.stdout)
#t.addChannel("TreeRouting", sys.stdout)
#t.addChannel("TestNetworkC", sys.stdout)
#t.addChannel("Route", sys.stdout)
#t.addChannel("PointerBug", sys.stdout)
#t.addChannel("QueueC", sys.stdout)
#t.addChannel("Gain", sys.stdout)
#t.addChannel("Forwarder", sys.stdout)
#t.addChannel("TestNetworkC", sys.stdout)
#t.addChannel("TestNetworkCrec", sys.stdout)
t.addChannel("App", sys.stdout)
#t.addChannel("Traffic", sys.stdout)
#t.addChannel("Acks", sys.stdout)
#t.addChannel("TreeRoutingCtl", sys.stdout)
#t.addChannel("LI", sys.stdout)
#t.addChannel("rept", sys.stdout)

while (t.time() < 1000 * t.ticksPerSecond()):
  t.runNextEvent()

print "Completed simulation."

The output I am getting is

DEBUG (1): Sent: 1 Rec: 0 Suc: 0 Fail:0 Failed: 0

for all the nodes except for the root i.e node 0:

DEBUG (0): Sent: 115 Rec: 115 Suc: 115 Fail:0 Failed: 0

Ideally, there should be failed messages, which doesn't happen here.

The question is why is it only the root node that is both sending and receiving. How can I measure throughput, PDR and Network Lifetime in this setup?

Irfanuddin
  • 2,295
  • 1
  • 15
  • 29
  • What's in sparse-grid.txt? I wondered if your 10 nodes are too far apart, so cannot communicate. Maybe try a different topology. Also, what changes have you made to testnetworkc? – James Allen Sep 30 '18 at 19:42
  • The sparse-grid.txt comes by default in the TinyOS package, it's available in their [GitHub repo](https://github.com/tinyos/tinyos-main/blob/master/apps/tests/TestNetwork/sparse-grid.txt). I have just added 4 counters `uint8_t msgsuccess; uint8_t msgfail; uint8_t totmsg; uint8_t sendpkt; uint8_t pkts; uint8_t recpkt; ` to count messages sent and received, and also a timer to display them periodically. – Irfanuddin Sep 30 '18 at 19:58
  • @IrfanuddinShafi One issue I can spot at the moment has to do with how you handle the msgfail and msgsuccess variables, notably the msgsuccess variable is always incremented regardless of if the message succeeded or failed. I haven't had time to look at your code thoroughly so I don't know if that's causing problems but you can fix that error and check. – KillaKem Oct 01 '18 at 14:27
  • 1
    @IrfanuddinShafi Can you try running the simulation with constant channel gains, like a constant channel gain of 0db for every link or something and see how the statistics change. – KillaKem Oct 01 '18 at 14:29
  • @KillaKem I will try changing according to your suggestions and revert back to you with my results. – Irfanuddin Oct 01 '18 at 14:38
  • @KillaKem, changing the gain values does the work. Now I can see all my nodes are sending the data, and the root node is the only node that receives. Where can I put my `msgsuccess` and `msgfail` to measure successful message transmission and failed message transmissions? – Irfanuddin Oct 01 '18 at 15:02
  • 1
    @IrfanuddinShafi You can increment msgsucess in the else branch of the IF statement where you check success. `if (err != SUCCESS) { msgfail++; call Leds.led0On(); } else { msgsuccess++;}` – KillaKem Oct 02 '18 at 12:33
  • @KillaKem I tried incrementing `msgsuccess` in else part as you suggested. Nothing has changed, still failed messages are counted as success, and fail remains 0. – Irfanuddin Oct 02 '18 at 16:16
  • @IrfanuddinShafi If the msgsuccess variable is incremented then the message has been successfully sent as the SendDone method will have returned SUCCESS. If the message is not received then that means the message got lost during transmission. Just because a message is sent successfully doesn't mean that the message will be received successfully. Why do you say failed messages are counted as success? What are the new stats that are output after changing the gains? – KillaKem Oct 05 '18 at 13:53
  • 1
    @IrfanuddinShafi Also try testing for success directly by having `if (err == SUCCESS) { msgsuccess++;} else { msgfail++; call Leds.led0On(); }` because `err` can return take many values. – KillaKem Oct 05 '18 at 13:56
  • @KillaKem I have gone for a totally different approach since none of these has worked. I tried getting acknowledgement from the receiver using packet acknowledgement. It seems to be working. Thank you for all the suggestions, will revert if I need more help! – Irfanuddin Oct 07 '18 at 09:59

0 Answers0