Preliminary Collision tests

This commit is contained in:
Tommaso Pecorella
2014-04-06 23:01:10 +02:00
parent 6c6dcbaf31
commit d486f26151
5 changed files with 263 additions and 40 deletions

View File

@@ -91,84 +91,84 @@ LrWpanCsmaCa::GetMac (void) const
}
void
LrWpanCsmaCa::setSlottedCsmaCa (void)
LrWpanCsmaCa::SetSlottedCsmaCa (void)
{
NS_LOG_FUNCTION (this);
m_isSlotted = true;
}
void
LrWpanCsmaCa::setUnSlottedCsmaCa (void)
LrWpanCsmaCa::SetUnSlottedCsmaCa (void)
{
NS_LOG_FUNCTION (this);
m_isSlotted = false;
}
bool
LrWpanCsmaCa::isSlottedCsmaCa (void) const
LrWpanCsmaCa::IsSlottedCsmaCa (void) const
{
NS_LOG_FUNCTION (this);
return (m_isSlotted);
}
bool
LrWpanCsmaCa::isUnSlottedCsmaCa (void) const
LrWpanCsmaCa::IsUnSlottedCsmaCa (void) const
{
NS_LOG_FUNCTION (this);
return (!m_isSlotted);
}
void
LrWpanCsmaCa::setMacMinBE (uint8_t macMinBE)
LrWpanCsmaCa::SetMacMinBE (uint8_t macMinBE)
{
NS_LOG_FUNCTION (this << macMinBE);
m_macMinBE = macMinBE;
}
uint8_t
LrWpanCsmaCa::getMacMinBE (void) const
LrWpanCsmaCa::GetMacMinBE (void) const
{
NS_LOG_FUNCTION (this);
return m_macMinBE;
}
void
LrWpanCsmaCa::setMacMaxBE (uint8_t macMaxBE)
LrWpanCsmaCa::SetMacMaxBE (uint8_t macMaxBE)
{
NS_LOG_FUNCTION (this << macMaxBE);
m_macMinBE = macMaxBE;
}
uint8_t
LrWpanCsmaCa::getMacMaxBE (void) const
LrWpanCsmaCa::GetMacMaxBE (void) const
{
NS_LOG_FUNCTION (this);
return m_macMaxBE;
}
void
LrWpanCsmaCa::setmacMaxCSMABackoffs (uint8_t macMaxCSMABackoffs)
LrWpanCsmaCa::SetMacMaxCSMABackoffs (uint8_t macMaxCSMABackoffs)
{
NS_LOG_FUNCTION (this << macMaxCSMABackoffs);
m_macMaxCSMABackoffs = macMaxCSMABackoffs;
}
uint8_t
LrWpanCsmaCa::getmacMaxCSMABackoffs (void) const
LrWpanCsmaCa::GetMacMaxCSMABackoffs (void) const
{
NS_LOG_FUNCTION (this);
return m_macMaxCSMABackoffs;
}
void
LrWpanCsmaCa::setUnitBackoffPeriod (uint64_t unitBackoffPeriod)
LrWpanCsmaCa::SetUnitBackoffPeriod (uint64_t unitBackoffPeriod)
{
NS_LOG_FUNCTION (this << unitBackoffPeriod);
m_aUnitBackoffPeriod = unitBackoffPeriod;
}
uint64_t
LrWpanCsmaCa::getUnitBackoffPeriod (void) const
LrWpanCsmaCa::GetUnitBackoffPeriod (void) const
{
NS_LOG_FUNCTION (this);
return m_aUnitBackoffPeriod;
@@ -176,7 +176,7 @@ LrWpanCsmaCa::getUnitBackoffPeriod (void) const
//TODO:
uint64_t
LrWpanCsmaCa::getTimeToNextSlot (void) const
LrWpanCsmaCa::GetTimeToNextSlot (void) const
{
NS_LOG_FUNCTION (this);
uint64_t diffT = 0;
@@ -192,7 +192,7 @@ LrWpanCsmaCa::Start ()
NS_LOG_FUNCTION (this);
uint64_t backoffBoundary = 0;
m_NB = 0;
if (isSlottedCsmaCa ())
if (IsSlottedCsmaCa ())
{
m_CW = 2;
if (m_BLE)
@@ -204,7 +204,7 @@ LrWpanCsmaCa::Start ()
m_BE = m_macMinBE;
}
//TODO: for slotted, locate backoff period boundary. i.e. delay to the next slot boundary
backoffBoundary = getTimeToNextSlot ();
backoffBoundary = GetTimeToNextSlot ();
m_randomBackoffEvent = Simulator::Schedule (Seconds (backoffBoundary), &LrWpanCsmaCa::RandomBackoffDelay, this);
}
else
@@ -248,9 +248,9 @@ LrWpanCsmaCa::RandomBackoffDelay ()
symbolRate = (uint64_t) m_mac->GetPhy ()->GetDataOrSymbolRate (isData); //symbols per second
backoffPeriod = (uint64_t)m_random.GetValue (0, upperBound); //num backoff periods
randomBackoff = MicroSeconds (backoffPeriod * getUnitBackoffPeriod () * 1000 * 1000 / symbolRate);
randomBackoff = MicroSeconds (backoffPeriod * GetUnitBackoffPeriod () * 1000 * 1000 / symbolRate);
if (isUnSlottedCsmaCa ())
if (IsUnSlottedCsmaCa ())
{
NS_LOG_LOGIC ("Unslotted: requesting CCA after backoff of " << randomBackoff.GetMicroSeconds () << " us");
m_requestCcaEvent = Simulator::Schedule (randomBackoff, &LrWpanCsmaCa::RequestCCA, this);
@@ -282,7 +282,7 @@ LrWpanCsmaCa::CanProceed ()
if (canProceed)
{
// TODO: For slotted, Perform CCA on backoff period boundary i.e. delay to next slot boundary
backoffBoundary = getTimeToNextSlot ();
backoffBoundary = GetTimeToNextSlot ();
m_requestCcaEvent = Simulator::Schedule (Seconds (backoffBoundary), &LrWpanCsmaCa::RequestCCA, this);
}
else
@@ -315,7 +315,7 @@ LrWpanCsmaCa::PlmeCcaConfirm (LrWpanPhyEnumeration status)
m_ccaRequestRunning = false;
if (status == IEEE_802_15_4_PHY_IDLE)
{
if (isSlottedCsmaCa ())
if (IsSlottedCsmaCa ())
{
m_CW--;
if (m_CW == 0)
@@ -345,7 +345,7 @@ LrWpanCsmaCa::PlmeCcaConfirm (LrWpanPhyEnumeration status)
}
else
{
if (isSlottedCsmaCa ())
if (IsSlottedCsmaCa ())
{
m_CW = 2;
}

View File

@@ -50,25 +50,25 @@ public:
void SetMac (Ptr<LrWpanMac> mac);
Ptr<LrWpanMac> GetMac (void) const;
void setSlottedCsmaCa (void);
void setUnSlottedCsmaCa (void);
bool isSlottedCsmaCa (void) const;
bool isUnSlottedCsmaCa (void) const;
void SetSlottedCsmaCa (void);
void SetUnSlottedCsmaCa (void);
bool IsSlottedCsmaCa (void) const;
bool IsUnSlottedCsmaCa (void) const;
void setMacMinBE (uint8_t macMinBE);
uint8_t getMacMinBE (void) const;
void setMacMaxBE (uint8_t macMaxBE);
uint8_t getMacMaxBE (void) const;
void setmacMaxCSMABackoffs (uint8_t macMaxCSMABackoffs);
uint8_t getmacMaxCSMABackoffs (void) const;
void SetMacMinBE (uint8_t macMinBE);
uint8_t GetMacMinBE (void) const;
void SetMacMaxBE (uint8_t macMaxBE);
uint8_t GetMacMaxBE (void) const;
void SetMacMaxCSMABackoffs (uint8_t macMaxCSMABackoffs);
uint8_t GetMacMaxCSMABackoffs (void) const;
void setUnitBackoffPeriod (uint64_t unitBackoffPeriod);
uint64_t getUnitBackoffPeriod (void) const;
void SetUnitBackoffPeriod (uint64_t unitBackoffPeriod);
uint64_t GetUnitBackoffPeriod (void) const;
/*
* Amount of time from now to the beginning of the next slot
*/
uint64_t getTimeToNextSlot (void) const;
uint64_t GetTimeToNextSlot (void) const;
/*
* Start CSMA-CA algorithm (step 1), initialize NB, BE for both slotted and unslotted

View File

@@ -302,7 +302,7 @@ LrWpanMac::McpsDataRequest (McpsDataRequestParams params, Ptr<Packet> p)
}
//if is Slotted CSMA means its beacon enabled
if (m_csmaCa->isSlottedCsmaCa ())
if (m_csmaCa->IsSlottedCsmaCa ())
{
if (b1 == TX_OPTION_GTS)
{
@@ -546,14 +546,14 @@ LrWpanMac::PdDataIndication (uint32_t psduLength, Ptr<Packet> p, uint8_t lqi)
|| (receivedMacHdr.GetType () == LrWpanMacHeader::LRWPAN_MAC_COMMAND))
&& (receivedMacHdr.GetSrcAddrMode () > 1))
{
acceptFrame = receivedMacHdr.GetSrcPanId () == m_macPanId; //TODO need to check if PAN coord
acceptFrame = receivedMacHdr.GetSrcPanId () == m_macPanId; // \todo need to check if PAN coord
}
if (acceptFrame)
{
m_macRxTrace (originalPkt);
// TODO: What should we do if we receive a frame while waiting for an ACK?
// Especially if this frame has the ACK request bit set, should we reply with an ACK, possibly missing the pending ACK?
// \todo: What should we do if we receive a frame while waiting for an ACK?
// Especially if this frame has the ACK request bit set, should we reply with an ACK, possibly missing the pending ACK?
// If the received frame is a frame with the ACK request bit set, we immediately send back an ACK.
// If we are currently waiting for a pending ACK, we assume the ACK was lost and trigger a retransmission after sending the ACK.
@@ -572,8 +572,8 @@ LrWpanMac::PdDataIndication (uint32_t psduLength, Ptr<Packet> p, uint8_t lqi)
}
else if (m_lrWpanMacState == MAC_CSMA)
{
// TODO: If we receive a packet while doing CSMA/CA, should we drop the packet because of channel busy,
// or should we restart CSMA/CA for the packet after sending the ACK?
// \todo: If we receive a packet while doing CSMA/CA, should we drop the packet because of channel busy,
// or should we restart CSMA/CA for the packet after sending the ACK?
// Currently we simply restart CSMA/CA after sending the ACK.
m_csmaCa->Cancel ();
}
@@ -968,7 +968,7 @@ LrWpanMac::ChangeMacState (LrWpanMacState newState)
uint64_t
LrWpanMac::GetMacAckWaitDuration (void) const
{
return m_csmaCa->getUnitBackoffPeriod () + m_phy->aTurnaroundTime + m_phy->GetPhySHRDuration ()
return m_csmaCa->GetUnitBackoffPeriod () + m_phy->aTurnaroundTime + m_phy->GetPhySHRDuration ()
+ ceil (6 * m_phy->GetPhySymbolsPerOctet ());
}

View File

@@ -0,0 +1,222 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014 Universita' di Firenze, Italy
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Tommaso Pecorella <tommaso.pecorella@unifi.it>
*/
#include <ns3/test.h>
#include <ns3/packet.h>
#include <ns3/lr-wpan-module.h>
#include <ns3/mobility-module.h>
#include <ns3/propagation-module.h>
#include <ns3/spectrum-module.h>
#include <ns3/mac16-address.h>
#include <ns3/mac64-address.h>
#include <ns3/log.h>
NS_LOG_COMPONENT_DEFINE ("lr-wpan-collision-test");
using namespace ns3;
// This is an example TestCase.
class LrWpanCollisionTestCase : public TestCase
{
public:
LrWpanCollisionTestCase ();
virtual ~LrWpanCollisionTestCase ();
void DataIndication (McpsDataIndicationParams params, Ptr<Packet> p);
private:
virtual void DoRun (void);
uint8_t m_rxPackets;
};
LrWpanCollisionTestCase::LrWpanCollisionTestCase ()
: TestCase ("Test the 802.15.4 collision handling")
{
m_rxPackets = 0;
}
LrWpanCollisionTestCase::~LrWpanCollisionTestCase ()
{
}
void LrWpanCollisionTestCase::DataIndication (McpsDataIndicationParams params, Ptr<Packet> p)
{
m_rxPackets ++;
}
void
LrWpanCollisionTestCase::DoRun (void)
{
// Create 3 nodes, and a NetDevice for each one
Ptr<Node> n0 = CreateObject <Node> ();
Ptr<Node> n1 = CreateObject <Node> ();
Ptr<Node> n2 = CreateObject <Node> ();
Ptr<LrWpanNetDevice> dev0 = CreateObject<LrWpanNetDevice> ();
Ptr<LrWpanNetDevice> dev1 = CreateObject<LrWpanNetDevice> ();
Ptr<LrWpanNetDevice> dev2 = CreateObject<LrWpanNetDevice> ();
dev0->SetAddress (Mac16Address ("00:01"));
dev1->SetAddress (Mac16Address ("00:02"));
dev2->SetAddress (Mac16Address ("00:03"));
// Each device must be attached to the same channel
Ptr<SingleModelSpectrumChannel> channel = CreateObject<SingleModelSpectrumChannel> ();
Ptr<LogDistancePropagationLossModel> propModel = CreateObject<LogDistancePropagationLossModel> ();
Ptr<ConstantSpeedPropagationDelayModel> delayModel = CreateObject<ConstantSpeedPropagationDelayModel> ();
channel->AddPropagationLossModel (propModel);
channel->SetPropagationDelayModel (delayModel);
dev0->SetChannel (channel);
dev1->SetChannel (channel);
dev2->SetChannel (channel);
// To complete configuration, a LrWpanNetDevice must be added to a node
n0->AddDevice (dev0);
n1->AddDevice (dev1);
n2->AddDevice (dev2);
Ptr<ConstantPositionMobilityModel> sender0Mobility = CreateObject<ConstantPositionMobilityModel> ();
sender0Mobility->SetPosition (Vector (0,0,0));
dev0->GetPhy ()->SetMobility (sender0Mobility);
n0->AggregateObject (sender0Mobility);
Ptr<ConstantPositionMobilityModel> sender1Mobility = CreateObject<ConstantPositionMobilityModel> ();
// Configure position 10 m distance
sender1Mobility->SetPosition (Vector (0,10,0));
dev1->GetPhy ()->SetMobility (sender1Mobility);
n1->AggregateObject (sender1Mobility);
Ptr<ConstantPositionMobilityModel> sender2Mobility = CreateObject<ConstantPositionMobilityModel> ();
// Configure position 10 m distance
sender2Mobility->SetPosition (Vector (30,0,0));
dev2->GetPhy ()->SetMobility (sender2Mobility);
n2->AggregateObject (sender2Mobility);
dev0->GetMac ()->SetMcpsDataIndicationCallback (MakeCallback (&LrWpanCollisionTestCase::DataIndication, this));
// Disable first backoff
dev0->GetCsmaCa ()->SetMacMinBE (0);
dev1->GetCsmaCa ()->SetMacMinBE (0);
dev2->GetCsmaCa ()->SetMacMinBE (0);
Ptr<Packet> p0 = Create<Packet> (50);
Ptr<Packet> p1 = Create<Packet> (60);
Ptr<Packet> p2 = Create<Packet> (120);
McpsDataRequestParams params;
params.m_srcAddrMode = SHORT_ADDR;
params.m_dstAddrMode = SHORT_ADDR;
params.m_dstPanId = 0;
params.m_msduHandle = 0;
// params.m_txOptions = TX_OPTION_ACK;
// First case: concurrent tx and no ACKs
m_rxPackets = 0;
params.m_dstAddr = Mac16Address ("00:02");
Simulator::Schedule (Seconds (0.0),
&LrWpanMac::McpsDataRequest,
dev0->GetMac (), params, p0);
params.m_dstAddr = Mac16Address ("00:01");
Simulator::Schedule (Seconds (0.0),
&LrWpanMac::McpsDataRequest,
dev1->GetMac (), params, p1);
Simulator::Run ();
NS_TEST_EXPECT_MSG_EQ (m_rxPackets, 0, "Not received a packet (as expected)");
// Second case: concurrent tx and ACKs
m_rxPackets = 0;
params.m_txOptions = TX_OPTION_ACK;
params.m_dstAddr = Mac16Address ("00:02");
Simulator::Schedule (Seconds (0.0),
&LrWpanMac::McpsDataRequest,
dev0->GetMac (), params, p0);
params.m_dstAddr = Mac16Address ("00:01");
Simulator::Schedule (Seconds (0.0),
&LrWpanMac::McpsDataRequest,
dev1->GetMac (), params, p1);
Simulator::Run ();
NS_TEST_EXPECT_MSG_EQ (m_rxPackets, 1, "Received a packet (as expected)");
// Third case: two concurrent tx and no ACKs
m_rxPackets = 0;
params.m_txOptions = 0;
params.m_dstAddr = Mac16Address ("00:01");
Simulator::Schedule (Seconds (0.0),
&LrWpanMac::McpsDataRequest,
dev1->GetMac (), params, p2);
params.m_dstAddr = Mac16Address ("00:01");
Simulator::Schedule (Seconds (0.0),
&LrWpanMac::McpsDataRequest,
dev2->GetMac (), params, p2);
Simulator::Run ();
std::cout << "m_rxPackets = " << int(m_rxPackets) << std::endl;
NS_TEST_EXPECT_MSG_EQ (m_rxPackets, 0, "Received a packet (as expected)");
// Fourth case: two concurrent tx and ACKs
m_rxPackets = 0;
params.m_txOptions = TX_OPTION_ACK;
params.m_dstAddr = Mac16Address ("00:01");
Simulator::Schedule (Seconds (0.0),
&LrWpanMac::McpsDataRequest,
dev1->GetMac (), params, p0);
params.m_dstAddr = Mac16Address ("00:01");
Simulator::Schedule (Seconds (0.0),
&LrWpanMac::McpsDataRequest,
dev2->GetMac (), params, p1);
Simulator::Run ();
std::cout << "m_rxPackets = " << int(m_rxPackets) << std::endl;
NS_TEST_EXPECT_MSG_EQ (m_rxPackets, 2, "Received two packets (as expected)");
Simulator::Destroy ();
}
// ==============================================================================
class LrWpanCollisionTestSuite : public TestSuite
{
public:
LrWpanCollisionTestSuite ();
};
LrWpanCollisionTestSuite::LrWpanCollisionTestSuite ()
: TestSuite ("lr-wpan-collision", UNIT)
{
AddTestCase (new LrWpanCollisionTestCase, TestCase::QUICK);
}
static LrWpanCollisionTestSuite g_lrWpanCollisionTestSuite;

View File

@@ -23,6 +23,7 @@ def build(bld):
'test/lr-wpan-packet-test.cc',
'test/lr-wpan-error-model-test.cc',
'test/lr-wpan-spectrum-value-helper-test.cc',
'test/lr-wpan-collision-test.cc',
]
headers = bld(features='ns3header')