lr-wpan: Beacon Enabled Mode Direct transmissions
This commit is contained in:
committed by
Tommaso Pecorella
parent
2fde925da7
commit
c2054cb25b
1
AUTHORS
1
AUTHORS
@@ -83,7 +83,6 @@ Tom Henderson (tomhend@u.washington.edu)
|
||||
Christopher Hepner (hepner@hs-ulm.de)
|
||||
Budiarto Herman (budiarto.herman@magister.fi)
|
||||
Tom Hewer (tomhewer@mac.com)
|
||||
Jack Higgins (shattered.feelings@gmail.com)
|
||||
Kristian A. Hiorth (kristahi@ifi.uio.no)
|
||||
Kim Højgaard-Hansen (kimrhh@gmail.com)
|
||||
Chris Hood (chood8@gatech.edu)
|
||||
|
||||
211
src/lr-wpan/examples/lr-wpan-mlme.cc
Normal file
211
src/lr-wpan/examples/lr-wpan-mlme.cc
Normal file
@@ -0,0 +1,211 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2019 Ritsumeikan University, Shiga, Japan.
|
||||
*
|
||||
* 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: Alberto Gallegos Ramonet <ramonet@fc.ritsumei.ac.jp>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Coordinator End Device
|
||||
* N0 <---------------- N1
|
||||
* (dev0) (dev1)
|
||||
*
|
||||
* This example demonstrate the usage of the MAC primitives involved in
|
||||
* direct transmissions for the beacon enabled mode of IEEE 802.15.4-2011.
|
||||
* A single packet is sent from an end device to the coordinator during the CAP
|
||||
* of the first incoming superframe.
|
||||
*
|
||||
* This example do not demonstrate a full protocol stack usage.
|
||||
* For full protocol stack usage refer to 6lowpan examples.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <ns3/log.h>
|
||||
#include <ns3/core-module.h>
|
||||
#include <ns3/lr-wpan-module.h>
|
||||
#include <ns3/propagation-loss-model.h>
|
||||
#include <ns3/propagation-delay-model.h>
|
||||
#include <ns3/simulator.h>
|
||||
#include <ns3/single-model-spectrum-channel.h>
|
||||
#include <ns3/constant-position-mobility-model.h>
|
||||
#include <ns3/packet.h>
|
||||
#include <iostream>
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
static void BeaconIndication (MlmeBeaconNotifyIndicationParams params, Ptr<Packet> p)
|
||||
{
|
||||
NS_LOG_UNCOND (Simulator::Now ().GetSeconds () << " secs | Received BEACON packet of size " << p->GetSize ());
|
||||
}
|
||||
|
||||
static void DataIndication (McpsDataIndicationParams params, Ptr<Packet> p)
|
||||
{
|
||||
NS_LOG_UNCOND (Simulator::Now ().GetSeconds () << " secs | Received DATA packet of size " << p->GetSize ());
|
||||
}
|
||||
|
||||
static void TransEndIndication (McpsDataConfirmParams params)
|
||||
{
|
||||
// In the case of transmissions with the Ack flag activated, the transaction is only
|
||||
// successful if the Ack was received.
|
||||
if (params.m_status == LrWpanMcpsDataConfirmStatus::IEEE_802_15_4_SUCCESS)
|
||||
{
|
||||
NS_LOG_UNCOND (Simulator::Now ().GetSeconds () << " secs | Transmission successfully sent");
|
||||
}
|
||||
}
|
||||
|
||||
static void DataIndicationCoordinator (McpsDataIndicationParams params, Ptr<Packet> p)
|
||||
{
|
||||
NS_LOG_UNCOND (Simulator::Now ().GetSeconds () << "s Coordinator Received DATA packet (size " << p->GetSize () << " bytes)");
|
||||
}
|
||||
|
||||
static void StartConfirm (MlmeStartConfirmParams params)
|
||||
{
|
||||
if (params.m_status == MLMESTART_SUCCESS)
|
||||
{
|
||||
NS_LOG_UNCOND (Simulator::Now ().GetSeconds () << "Beacon status SUCESSFUL");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
|
||||
|
||||
LogComponentEnableAll (LOG_PREFIX_TIME);
|
||||
LogComponentEnableAll (LOG_PREFIX_FUNC);
|
||||
LogComponentEnable ("LrWpanMac", LOG_LEVEL_INFO);
|
||||
LogComponentEnable ("LrWpanCsmaCa", LOG_LEVEL_INFO);
|
||||
|
||||
|
||||
LrWpanHelper lrWpanHelper;
|
||||
|
||||
// Create 2 nodes, and a NetDevice for each one
|
||||
Ptr<Node> n0 = CreateObject <Node> ();
|
||||
Ptr<Node> n1 = CreateObject <Node> ();
|
||||
|
||||
Ptr<LrWpanNetDevice> dev0 = CreateObject<LrWpanNetDevice> ();
|
||||
Ptr<LrWpanNetDevice> dev1 = CreateObject<LrWpanNetDevice> ();
|
||||
|
||||
dev0->SetAddress (Mac16Address ("00:01"));
|
||||
dev1->SetAddress (Mac16Address ("00:02"));
|
||||
|
||||
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);
|
||||
|
||||
n0->AddDevice (dev0);
|
||||
n1->AddDevice (dev1);
|
||||
|
||||
///////////////// Mobility ///////////////////////
|
||||
Ptr<ConstantPositionMobilityModel> sender0Mobility = CreateObject<ConstantPositionMobilityModel> ();
|
||||
sender0Mobility->SetPosition (Vector (0,0,0));
|
||||
dev0->GetPhy ()->SetMobility (sender0Mobility);
|
||||
Ptr<ConstantPositionMobilityModel> sender1Mobility = CreateObject<ConstantPositionMobilityModel> ();
|
||||
|
||||
sender1Mobility->SetPosition (Vector (0,10,0)); //10 m distance
|
||||
dev1->GetPhy ()->SetMobility (sender1Mobility);
|
||||
|
||||
|
||||
/////// MAC layer Callbacks hooks/////////////
|
||||
|
||||
MlmeStartConfirmCallback cb0;
|
||||
cb0 = MakeCallback (&StartConfirm);
|
||||
dev0->GetMac ()->SetMlmeStartConfirmCallback (cb0);
|
||||
|
||||
McpsDataConfirmCallback cb1;
|
||||
cb1 = MakeCallback (&TransEndIndication);
|
||||
dev1->GetMac ()->SetMcpsDataConfirmCallback (cb1);
|
||||
|
||||
MlmeBeaconNotifyIndicationCallback cb3;
|
||||
cb3 = MakeCallback (&BeaconIndication);
|
||||
dev1->GetMac ()->SetMlmeBeaconNotifyIndicationCallback (cb3);
|
||||
|
||||
McpsDataIndicationCallback cb4;
|
||||
cb4 = MakeCallback (&DataIndication);
|
||||
dev1->GetMac ()->SetMcpsDataIndicationCallback (cb4);
|
||||
|
||||
McpsDataIndicationCallback cb5;
|
||||
cb5 = MakeCallback (&DataIndicationCoordinator);
|
||||
dev0->GetMac ()->SetMcpsDataIndicationCallback (cb5);
|
||||
|
||||
|
||||
|
||||
//////////// Manual device association ////////////////////
|
||||
// Note: We manually associate the devices to a PAN coordinator
|
||||
// because currently there is no automatic association behavior (bootstrap);
|
||||
// The PAN COORDINATOR does not need to associate or set its
|
||||
// PAN Id or its own coordinator id, these are set
|
||||
// by the MLME-start.request primitive when used.
|
||||
|
||||
dev1->GetMac ()->SetPanId (5);
|
||||
dev1->GetMac ()->SetAssociatedCoor (Mac16Address ("00:01"));
|
||||
|
||||
|
||||
|
||||
///////////////////// Start transmitting beacons from coordinator ////////////////////////
|
||||
|
||||
MlmeStartRequestParams params;
|
||||
params.m_panCoor = true;
|
||||
params.m_PanId = 5;
|
||||
params.m_bcnOrd = 14;
|
||||
params.m_sfrmOrd = 6;
|
||||
Simulator::ScheduleWithContext (1, Seconds (2.0),
|
||||
&LrWpanMac::MlmeStartRequest,
|
||||
dev0->GetMac (), params);
|
||||
|
||||
///////////////////// Transmission of data Packets from end device //////////////////////
|
||||
|
||||
Ptr<Packet> p1 = Create<Packet> (5);
|
||||
McpsDataRequestParams params2;
|
||||
params2.m_dstPanId = 5;
|
||||
params2.m_srcAddrMode = SHORT_ADDR;
|
||||
params2.m_dstAddrMode = SHORT_ADDR;
|
||||
params2.m_dstAddr = Mac16Address ("00:01");
|
||||
params2.m_msduHandle = 0;
|
||||
// params2.m_txOptions = TX_OPTION_ACK; // Enable direct transmission with Ack
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// Examples of time parameters for transmissions in the first incoming superframe. //
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// 2.981 sec No time to finish CCA in CAP, the transmission at this time will cause
|
||||
// the packet to be deferred to the next superframe.
|
||||
|
||||
// 2.98272 sec No time to finish random backoff delay in CAP, the transmission at this
|
||||
// time will cause the packet to be deferred to the next superframe.
|
||||
|
||||
// 2.93 sec Enough time, the packet can be transmitted within the CAP of the first superframe
|
||||
|
||||
|
||||
// MCPS-DATA.request Beacon enabled Direct Transmission (dev1)
|
||||
// Frame transmission from End Device to Coordinator (Direct transmission)
|
||||
Simulator::ScheduleWithContext (1, Seconds (2.93),
|
||||
&LrWpanMac::McpsDataRequest,
|
||||
dev1->GetMac (), params2, p1);
|
||||
|
||||
|
||||
Simulator::Stop (Seconds (600));
|
||||
Simulator::Run ();
|
||||
|
||||
Simulator::Destroy ();
|
||||
return 0;
|
||||
}
|
||||
@@ -15,3 +15,6 @@ def build(bld):
|
||||
|
||||
obj = bld.create_ns3_program('lr-wpan-error-distance-plot', ['lr-wpan', 'stats'])
|
||||
obj.source = 'lr-wpan-error-distance-plot.cc'
|
||||
|
||||
obj = bld.create_ns3_program('lr-wpan-mlme', ['lr-wpan'])
|
||||
obj.source = 'lr-wpan-mlme.cc'
|
||||
|
||||
@@ -254,6 +254,63 @@ LrWpanHelper::AssociateToPan (NetDeviceContainer c, uint16_t panId)
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
LrWpanHelper::AssociateToBeaconPan (NetDeviceContainer c, uint16_t panId, Mac16Address coor, uint8_t bcnOrd, uint8_t sfrmOrd)
|
||||
{
|
||||
NetDeviceContainer devices;
|
||||
uint16_t id = 1;
|
||||
uint8_t idBuf[2];
|
||||
Mac16Address address;
|
||||
|
||||
if (bcnOrd > 14)
|
||||
{
|
||||
NS_LOG_DEBUG("The Beacon Order must be an int between 0 and 14");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if ((sfrmOrd > 14) || (sfrmOrd > bcnOrd))
|
||||
{
|
||||
NS_LOG_DEBUG("The Superframe Order must be an int between 0 and 14, and less or equal to Beacon Order");
|
||||
return;
|
||||
}
|
||||
|
||||
for (NetDeviceContainer::Iterator i = c.Begin (); i != c.End (); i++)
|
||||
{
|
||||
Ptr<LrWpanNetDevice> device = DynamicCast<LrWpanNetDevice> (*i);
|
||||
if (device)
|
||||
{
|
||||
idBuf[0] = (id >> 8) & 0xff;
|
||||
idBuf[1] = (id >> 0) & 0xff;
|
||||
address.CopyFrom (idBuf);
|
||||
|
||||
device->GetMac ()->SetShortAddress (address);
|
||||
|
||||
if (address == coor)
|
||||
{
|
||||
MlmeStartRequestParams params;
|
||||
params.m_panCoor = true;
|
||||
params.m_PanId = panId;
|
||||
params.m_bcnOrd = bcnOrd;
|
||||
params.m_sfrmOrd = sfrmOrd;
|
||||
|
||||
Ptr<UniformRandomVariable> uniformRandomVariable = CreateObject<UniformRandomVariable> ();;
|
||||
Time jitter = Time (MilliSeconds (uniformRandomVariable->GetInteger (0, 10)));
|
||||
|
||||
Simulator::Schedule (jitter, &LrWpanMac::MlmeStartRequest,
|
||||
device->GetMac (), params);
|
||||
}
|
||||
else
|
||||
{
|
||||
device->GetMac ()->SetPanId (panId);
|
||||
device->GetMac ()->SetAssociatedCoor(coor);
|
||||
}
|
||||
id++;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write a packet in a PCAP file
|
||||
* @param file the output file
|
||||
|
||||
@@ -112,6 +112,19 @@ public:
|
||||
*/
|
||||
void AssociateToPan (NetDeviceContainer c, uint16_t panId);
|
||||
|
||||
/**
|
||||
* \brief Associate the nodes to the same PAN and initiate beacon enabled mode.
|
||||
*
|
||||
* \param c a set of nodes
|
||||
* \param panID the PAN id
|
||||
* \param coor the address of the PAN coordinator
|
||||
* \param bcnOrd indicates the interval between beacons.
|
||||
* The value must be an int between 0 and 14.
|
||||
* \param sfrmOrd indicates the length of the superframe.
|
||||
* The value must be an int between 0 and 14 and less or equal to the bcnOrd
|
||||
*/
|
||||
void AssociateToBeaconPan (NetDeviceContainer c, uint16_t panId, Mac16Address coor, uint8_t bcnOrd, uint8_t sfrmOrd);
|
||||
|
||||
/**
|
||||
* Helper to enable all LrWpan log components with one statement
|
||||
*/
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
* Author:
|
||||
* kwong yin <kwong-sang.yin@boeing.com>
|
||||
* Sascha Alexander Jopen <jopen@cs.uni-bonn.de>
|
||||
* Alberto Gallegos Ramonet <ramonet@fc.ritsumei.ac.jp>
|
||||
*/
|
||||
|
||||
#include "lr-wpan-csmaca.h"
|
||||
@@ -26,6 +27,10 @@
|
||||
#include <ns3/log.h>
|
||||
#include <algorithm>
|
||||
|
||||
#undef NS_LOG_APPEND_CONTEXT
|
||||
#define NS_LOG_APPEND_CONTEXT \
|
||||
std::clog << "[address " << m_mac->GetShortAddress () << "] ";
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("LrWpanCsmaCa");
|
||||
@@ -50,14 +55,16 @@ LrWpanCsmaCa::LrWpanCsmaCa ()
|
||||
m_isSlotted = false;
|
||||
m_NB = 0;
|
||||
m_CW = 2;
|
||||
m_BLE = false;
|
||||
m_macBattLifeExt = false;
|
||||
m_macMinBE = 3;
|
||||
m_macMaxBE = 5;
|
||||
m_macMaxCSMABackoffs = 4;
|
||||
m_aUnitBackoffPeriod = 20; //20 symbols
|
||||
m_aUnitBackoffPeriod = 20; // symbols
|
||||
m_random = CreateObject<UniformRandomVariable> ();
|
||||
m_BE = m_macMinBE;
|
||||
m_ccaRequestRunning = false;
|
||||
m_randomBackoffPeriodsLeft = 0;
|
||||
m_coorDest = false;
|
||||
}
|
||||
|
||||
LrWpanCsmaCa::~LrWpanCsmaCa ()
|
||||
@@ -68,7 +75,9 @@ LrWpanCsmaCa::~LrWpanCsmaCa ()
|
||||
void
|
||||
LrWpanCsmaCa::DoDispose ()
|
||||
{
|
||||
m_lrWpanMacStateCallback = MakeNullCallback< void, LrWpanMacState> ();
|
||||
m_lrWpanMacStateCallback = MakeNullCallback <void, LrWpanMacState> ();
|
||||
m_lrWpanMacTransCostCallback = MakeNullCallback <void, uint32_t> ();
|
||||
|
||||
Cancel ();
|
||||
m_mac = 0;
|
||||
}
|
||||
@@ -169,26 +178,66 @@ LrWpanCsmaCa::GetUnitBackoffPeriod (void) const
|
||||
return m_aUnitBackoffPeriod;
|
||||
}
|
||||
|
||||
|
||||
Time
|
||||
LrWpanCsmaCa::GetTimeToNextSlot (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
// TODO: Calculate the offset to the next slot.
|
||||
// The reference for the beginning of the CAP changes depending
|
||||
// on the data packet being sent from the Coordinator/outgoing frame (Tx beacon time reference)
|
||||
// or other device/incoming frame (Rx beacon time reference).
|
||||
|
||||
return Seconds (0);
|
||||
uint32_t elapsedSuperframe;
|
||||
uint64_t currentTimeSymbols;
|
||||
uint32_t symbolsToBoundary;
|
||||
Time nextBoundary;
|
||||
|
||||
currentTimeSymbols = Simulator::Now ().GetSeconds () * m_mac->GetPhy ()->GetDataOrSymbolRate (false);
|
||||
|
||||
|
||||
if (m_coorDest)
|
||||
{
|
||||
// Take the Incoming Frame Reference
|
||||
elapsedSuperframe = currentTimeSymbols - m_mac->m_beaconRxTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Take the Outgoing Frame Reference
|
||||
elapsedSuperframe = currentTimeSymbols - m_mac->m_macBeaconTxTime;
|
||||
}
|
||||
|
||||
symbolsToBoundary = m_aUnitBackoffPeriod - std::fmod (elapsedSuperframe,m_aUnitBackoffPeriod);
|
||||
nextBoundary = MicroSeconds (symbolsToBoundary * 1000 * 1000 / m_mac->GetPhy ()->GetDataOrSymbolRate (false));
|
||||
|
||||
NS_LOG_DEBUG ("Elapsed symbols in CAP: " << elapsedSuperframe << "(" << elapsedSuperframe / m_aUnitBackoffPeriod << " backoff periods)");
|
||||
NS_LOG_DEBUG ("Next backoff period boundary in " << symbolsToBoundary << " symbols ("
|
||||
<< nextBoundary.GetSeconds () << " s)");
|
||||
|
||||
|
||||
return nextBoundary;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LrWpanCsmaCa::Start ()
|
||||
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_NB = 0;
|
||||
if (IsSlottedCsmaCa ())
|
||||
{
|
||||
// TODO: Check if the current PHY is using the Japanese band 950 Mhz:
|
||||
// (IEEE_802_15_4_950MHZ_BPSK and IEEE_802_15_4_950MHZ_2GFSK)
|
||||
// if in use, m_CW = 1.
|
||||
// Currently 950 Mhz band PHYs are not supported in ns-3.
|
||||
// To know the current used PHY, making the method for GetPhy()->GetMyPhyOption()
|
||||
// public is necessary. Alternatively, the current PHY used
|
||||
// can be known using phyCurrentPage variable.
|
||||
|
||||
m_CW = 2;
|
||||
if (m_BLE)
|
||||
|
||||
if (m_macBattLifeExt)
|
||||
{
|
||||
m_BE = std::min (static_cast<uint8_t> (2), m_macMinBE);
|
||||
}
|
||||
@@ -196,23 +245,20 @@ LrWpanCsmaCa::Start ()
|
||||
{
|
||||
m_BE = m_macMinBE;
|
||||
}
|
||||
//TODO: for slotted, locate backoff period boundary. i.e. delay to the next slot boundary
|
||||
|
||||
// m_coorDest to decide between incoming and outgoing superframes times
|
||||
m_coorDest = m_mac->isCoordDest ();
|
||||
|
||||
// Locate backoff period boundary. (i.e. a time delay to align with the next backoff period boundary)
|
||||
Time backoffBoundary = GetTimeToNextSlot ();
|
||||
m_randomBackoffEvent = Simulator::Schedule (backoffBoundary, &LrWpanCsmaCa::RandomBackoffDelay, this);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
m_BE = m_macMinBE;
|
||||
m_randomBackoffEvent = Simulator::ScheduleNow (&LrWpanCsmaCa::RandomBackoffDelay, this);
|
||||
}
|
||||
/*
|
||||
* TODO: If using Backoff.cc (will need to modify Backoff::GetBackoffTime)
|
||||
* Backoff.m_minSlots = 0;
|
||||
* Backoff.m_ceiling = m_BE;
|
||||
* Backoff.ResetBackoffTime(); //m_NB is same as m_numBackoffRetries in Backoff.h
|
||||
* Backoff.m_maxRetries = macMaxCSMABackoffs;
|
||||
* Backoff.m_slotTime = m_backoffPeriod;
|
||||
*/
|
||||
}
|
||||
|
||||
void
|
||||
@@ -223,65 +269,166 @@ LrWpanCsmaCa::Cancel ()
|
||||
m_canProceedEvent.Cancel ();
|
||||
}
|
||||
|
||||
/*
|
||||
* Delay for backoff period in the range 0 to 2^BE -1 units
|
||||
* TODO: If using Backoff.cc (Backoff::GetBackoffTime) will need to be slightly modified
|
||||
*/
|
||||
|
||||
|
||||
void
|
||||
LrWpanCsmaCa::RandomBackoffDelay ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
uint64_t upperBound = (uint64_t) pow (2, m_BE) - 1;
|
||||
uint64_t backoffPeriod;
|
||||
Time randomBackoff;
|
||||
uint64_t symbolRate;
|
||||
bool isData = false;
|
||||
uint32_t backoffPeriodsLeftInCap;
|
||||
|
||||
symbolRate = (uint64_t) m_mac->GetPhy ()->GetDataOrSymbolRate (false); //symbols per second
|
||||
|
||||
symbolRate = (uint64_t) m_mac->GetPhy ()->GetDataOrSymbolRate (isData); //symbols per second
|
||||
backoffPeriod = (uint64_t)m_random->GetValue (0, upperBound+1); // num backoff periods
|
||||
randomBackoff = MicroSeconds (backoffPeriod * GetUnitBackoffPeriod () * 1000 * 1000 / symbolRate);
|
||||
// We should not recalculate the random backoffPeriods if we are in a slotted CSMA-CA and the
|
||||
// transmission was previously deferred (m_randomBackoffPeriods != 0)
|
||||
if (m_randomBackoffPeriodsLeft == 0 || IsUnSlottedCsmaCa ())
|
||||
{
|
||||
m_randomBackoffPeriodsLeft = (uint64_t)m_random->GetValue (0, upperBound + 1);
|
||||
}
|
||||
|
||||
randomBackoff = MicroSeconds (m_randomBackoffPeriodsLeft * GetUnitBackoffPeriod () * 1000 * 1000 / symbolRate);
|
||||
|
||||
if (IsUnSlottedCsmaCa ())
|
||||
{
|
||||
NS_LOG_LOGIC ("Unslotted: requesting CCA after backoff of " << randomBackoff.GetMicroSeconds () << " us");
|
||||
NS_LOG_DEBUG ("Unslotted CSMA-CA: requesting CCA after backoff of " << m_randomBackoffPeriodsLeft <<
|
||||
" periods (" << randomBackoff.GetSeconds () << " s)");
|
||||
m_requestCcaEvent = Simulator::Schedule (randomBackoff, &LrWpanCsmaCa::RequestCCA, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_LOGIC ("Slotted: proceeding after backoff of " << randomBackoff.GetMicroSeconds () << " us");
|
||||
m_canProceedEvent = Simulator::Schedule (randomBackoff, &LrWpanCsmaCa::CanProceed, this);
|
||||
// We must make sure there are enough backoff periods left in the CAP, otherwise we continue in
|
||||
// the CAP of the next superframe after the transmission/reception of the beacon (and the IFS)
|
||||
backoffPeriodsLeftInCap = GetBackoffPeriodsLeftInCap ();
|
||||
|
||||
NS_LOG_DEBUG ("Slotted CSMA-CA: proceeding after backoff of " << m_randomBackoffPeriodsLeft <<
|
||||
" periods (" << randomBackoff.GetSeconds () << " s)");
|
||||
|
||||
Time rmnCapTime = MicroSeconds (backoffPeriodsLeftInCap * GetUnitBackoffPeriod () * 1000 * 1000 / symbolRate);
|
||||
NS_LOG_DEBUG ("Backoff periods left in CAP: " << backoffPeriodsLeftInCap << " (" << rmnCapTime.GetSeconds () << " s)");
|
||||
|
||||
if (m_randomBackoffPeriodsLeft > backoffPeriodsLeftInCap)
|
||||
{
|
||||
m_randomBackoffPeriodsLeft = m_randomBackoffPeriodsLeft - backoffPeriodsLeftInCap;
|
||||
NS_LOG_DEBUG ("No time in CAP to complete backoff delay, deferring to the next CAP");
|
||||
|
||||
m_endCapEvent = Simulator::Schedule (rmnCapTime, &LrWpanCsmaCa::DeferCsmaTimeout, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_canProceedEvent = Simulator::Schedule (randomBackoff, &LrWpanCsmaCa::CanProceed, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO : Determine if transmission can be completed before end of CAP for the slotted csmaca
|
||||
// If not delay to the next CAP
|
||||
|
||||
uint32_t
|
||||
LrWpanCsmaCa::GetBackoffPeriodsLeftInCap ()
|
||||
{
|
||||
uint64_t currentTimeSymbols;
|
||||
uint16_t capSymbols;
|
||||
uint64_t endCapSymbols;
|
||||
uint64_t activeSlot;
|
||||
|
||||
|
||||
//At this point, the currentTime should be aligned on a backoff period boundary
|
||||
|
||||
|
||||
currentTimeSymbols = Simulator::Now ().GetMicroSeconds () * 1000 * 1000 *
|
||||
m_mac->GetPhy ()->GetDataOrSymbolRate (false);
|
||||
|
||||
if (m_coorDest)
|
||||
{ // Take Incoming frame reference
|
||||
activeSlot = m_mac->m_incomingSuperframeDuration / 16;
|
||||
capSymbols = activeSlot * (m_mac->m_incomingFnlCapSlot + 1);
|
||||
endCapSymbols = m_mac->m_beaconRxTime + capSymbols;
|
||||
}
|
||||
else
|
||||
{ // Take Outgoing frame reference
|
||||
activeSlot = m_mac->m_superframeDuration / 16;
|
||||
capSymbols = activeSlot * (m_mac->m_fnlCapSlot + 1);
|
||||
endCapSymbols = m_mac->m_macBeaconTxTime + capSymbols;
|
||||
}
|
||||
|
||||
return ((endCapSymbols - currentTimeSymbols) / m_aUnitBackoffPeriod);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LrWpanCsmaCa::CanProceed ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
bool canProceed = true;
|
||||
uint32_t backoffPeriodsLeftInCap;
|
||||
uint16_t ccaSymbols;
|
||||
uint32_t transactionSymbols;
|
||||
uint64_t symbolRate;
|
||||
|
||||
if (m_BLE)
|
||||
ccaSymbols = 0;
|
||||
m_randomBackoffPeriodsLeft = 0;
|
||||
symbolRate = (uint64_t) m_mac->GetPhy ()->GetDataOrSymbolRate (false);
|
||||
backoffPeriodsLeftInCap = GetBackoffPeriodsLeftInCap ();
|
||||
|
||||
|
||||
// TODO: On the 950 Mhz Band (Japanese Band)
|
||||
// only a single CCA check is performed;
|
||||
// the CCA check duration time is:
|
||||
//
|
||||
// CCA symbols = phyCCADuration * m_CW (1)
|
||||
// other PHYs:
|
||||
// CCA symbols = 8 * m_CW(2)
|
||||
//
|
||||
// note: phyCCADuration & 950Mhz band PHYs are
|
||||
// not currently implemented in ns-3.
|
||||
ccaSymbols += 8 * m_CW;
|
||||
|
||||
// The MAC sublayer shall proceed if the remaining CSMA-CA algorithm steps
|
||||
// can be completed before the end of the CAP.
|
||||
// See IEEE 802.15.4-2011 (Sections 5.1.1.1 and 5.1.1.4)
|
||||
// Transaction = 2 CCA + frame transmission (PPDU) + turnaroudtime or Ack time (optional) + IFS
|
||||
|
||||
transactionSymbols = ccaSymbols + m_mac->GetTxPacketSymbols ();
|
||||
|
||||
if (m_mac->isTxAckReq ())
|
||||
{
|
||||
NS_LOG_DEBUG ("ACK duration symbols: " << m_mac->GetMacAckWaitDuration ());
|
||||
transactionSymbols += m_mac->GetMacAckWaitDuration ();
|
||||
}
|
||||
else
|
||||
{
|
||||
//time the PHY takes to switch from TX to Rx or Rx to Tx
|
||||
transactionSymbols += m_mac->GetPhy ()->aTurnaroundTime;
|
||||
}
|
||||
transactionSymbols += m_mac->GetIfsSize ();
|
||||
|
||||
// Report the transaction cost
|
||||
if (!m_lrWpanMacTransCostCallback.IsNull ())
|
||||
{
|
||||
m_lrWpanMacTransCostCallback (transactionSymbols);
|
||||
}
|
||||
|
||||
if (canProceed)
|
||||
NS_LOG_DEBUG ("Total required transaction symbols: " << transactionSymbols);
|
||||
|
||||
if (transactionSymbols > (backoffPeriodsLeftInCap * GetUnitBackoffPeriod ()))
|
||||
{
|
||||
// TODO: For slotted, Perform CCA on backoff period boundary i.e. delay to next slot boundary
|
||||
Time backoffBoundary = GetTimeToNextSlot ();
|
||||
m_requestCcaEvent = Simulator::Schedule (backoffBoundary, &LrWpanCsmaCa::RequestCCA, this);
|
||||
NS_LOG_DEBUG ("Transaction of " << transactionSymbols << " symbols " <<
|
||||
"cannot be completed in CAP, deferring transmission to the next CAP");
|
||||
|
||||
Time waitTime = MicroSeconds (backoffPeriodsLeftInCap * GetUnitBackoffPeriod () * 1000 * 10000 / symbolRate);
|
||||
|
||||
NS_LOG_DEBUG ("Symbols left in CAP: " << backoffPeriodsLeftInCap * GetUnitBackoffPeriod () <<
|
||||
" (" << waitTime.GetSeconds () << "s)");
|
||||
|
||||
m_endCapEvent = Simulator::Schedule (waitTime, &LrWpanCsmaCa::DeferCsmaTimeout, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
Time nextCap = Seconds (0);
|
||||
m_randomBackoffEvent = Simulator::Schedule (nextCap, &LrWpanCsmaCa::RandomBackoffDelay, this);
|
||||
m_requestCcaEvent = Simulator::ScheduleNow (&LrWpanCsmaCa::RequestCCA,this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
@@ -292,9 +439,13 @@ LrWpanCsmaCa::RequestCCA ()
|
||||
m_mac->GetPhy ()->PlmeCcaRequest ();
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is called when the phy calls back after completing a PlmeCcaRequest
|
||||
*/
|
||||
void
|
||||
LrWpanCsmaCa::DeferCsmaTimeout ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_lrWpanMacStateCallback (MAC_CSMA_DEFERRED);
|
||||
}
|
||||
|
||||
void
|
||||
LrWpanCsmaCa::PlmeCcaConfirm (LrWpanPhyEnumeration status)
|
||||
{
|
||||
@@ -364,6 +515,15 @@ LrWpanCsmaCa::PlmeCcaConfirm (LrWpanPhyEnumeration status)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LrWpanCsmaCa::SetLrWpanMacTransCostCallback (LrWpanMacTransCostCallback c)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_lrWpanMacTransCostCallback = c;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LrWpanCsmaCa::SetLrWpanMacStateCallback (LrWpanMacStateCallback c)
|
||||
{
|
||||
@@ -371,6 +531,13 @@ LrWpanCsmaCa::SetLrWpanMacStateCallback (LrWpanMacStateCallback c)
|
||||
m_lrWpanMacStateCallback = c;
|
||||
}
|
||||
|
||||
void
|
||||
LrWpanCsmaCa::SetBatteryLifeExtension (bool batteryLifeExtension)
|
||||
{
|
||||
m_macBattLifeExt = batteryLifeExtension;
|
||||
}
|
||||
|
||||
|
||||
int64_t
|
||||
LrWpanCsmaCa::AssignStreams (int64_t stream)
|
||||
{
|
||||
@@ -385,4 +552,10 @@ LrWpanCsmaCa::GetNB (void)
|
||||
return m_NB;
|
||||
}
|
||||
|
||||
bool
|
||||
LrWpanCsmaCa::GetBatteryLifeExtension (void)
|
||||
{
|
||||
return m_macBattLifeExt;
|
||||
}
|
||||
|
||||
} //namespace ns3
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
* Author:
|
||||
* kwong yin <kwong-sang.yin@boeing.com>
|
||||
* Sascha Alexander Jopen <jopen@cs.uni-bonn.de>
|
||||
* Alberto Gallegos Ramonet <ramonet@fc.ritsumei.ac.jp>
|
||||
*/
|
||||
|
||||
#ifndef LR_WPAN_CSMACA_H
|
||||
@@ -34,10 +35,18 @@ class UniformRandomVariable;
|
||||
/**
|
||||
* \ingroup lr-wpan
|
||||
*
|
||||
* This method informs the MAC whether the channel is idle or busy.
|
||||
* This method informs the MAC whether the channel is idle or busy.
|
||||
*/
|
||||
typedef Callback<void, LrWpanMacState> LrWpanMacStateCallback;
|
||||
|
||||
/**
|
||||
* \ingroup lr-wpan
|
||||
*
|
||||
* This method informs the transaction cost in a slotted CSMA-CA data transmission.
|
||||
* i.e. Reports number of symbols (time) it would take slotted CSMA-CA to process the current transaction.
|
||||
* 1 Transaction = 2 CCA + frame transmission (PPDU) + turnaroudtime or Ack time (optional) + IFS
|
||||
* See IEEE 802.15.4-2011 (Sections 5.1.1.1 and 5.1.1.4)
|
||||
*/
|
||||
typedef Callback<void, uint32_t> LrWpanMacTransCostCallback;
|
||||
/**
|
||||
* \ingroup lr-wpan
|
||||
*
|
||||
@@ -54,20 +63,17 @@ public:
|
||||
* \return the object TypeId
|
||||
*/
|
||||
static TypeId GetTypeId (void);
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
LrWpanCsmaCa (void);
|
||||
virtual ~LrWpanCsmaCa (void);
|
||||
|
||||
/**
|
||||
* Set the MAC to which this CSMA/CA implementation is attached to.
|
||||
*
|
||||
* \param mac the used MAC
|
||||
*/
|
||||
void SetMac (Ptr<LrWpanMac> mac);
|
||||
|
||||
/**
|
||||
* Get the MAC to which this CSMA/CA implementation is attached to.
|
||||
*
|
||||
@@ -79,26 +85,22 @@ public:
|
||||
* Configure for the use of the slotted CSMA/CA version.
|
||||
*/
|
||||
void SetSlottedCsmaCa (void);
|
||||
|
||||
/**
|
||||
* Configure for the use of the unslotted CSMA/CA version.
|
||||
*/
|
||||
void SetUnSlottedCsmaCa (void);
|
||||
|
||||
/**
|
||||
* Check if the slotted CSMA/CA version is being used.
|
||||
*
|
||||
* \return true, if slotted CSMA/CA is used, false otherwise.
|
||||
*/
|
||||
bool IsSlottedCsmaCa (void) const;
|
||||
|
||||
/**
|
||||
* Check if the unslotted CSMA/CA version is being used.
|
||||
*
|
||||
* \return true, if unslotted CSMA/CA is used, false otherwise.
|
||||
*/
|
||||
bool IsUnSlottedCsmaCa (void) const;
|
||||
|
||||
/**
|
||||
* Set the minimum backoff exponent value.
|
||||
* See IEEE 802.15.4-2006, section 7.4.2, Table 86.
|
||||
@@ -106,7 +108,6 @@ public:
|
||||
* \param macMinBE the minimum backoff exponent value
|
||||
*/
|
||||
void SetMacMinBE (uint8_t macMinBE);
|
||||
|
||||
/**
|
||||
* Get the minimum backoff exponent value.
|
||||
* See IEEE 802.15.4-2006, section 7.4.2, Table 86.
|
||||
@@ -114,7 +115,6 @@ public:
|
||||
* \return the minimum backoff exponent value
|
||||
*/
|
||||
uint8_t GetMacMinBE (void) const;
|
||||
|
||||
/**
|
||||
* Set the maximum backoff exponent value.
|
||||
* See IEEE 802.15.4-2006, section 7.4.2, Table 86.
|
||||
@@ -122,7 +122,6 @@ public:
|
||||
* \param macMaxBE the maximum backoff exponent value
|
||||
*/
|
||||
void SetMacMaxBE (uint8_t macMaxBE);
|
||||
|
||||
/**
|
||||
* Get the maximum backoff exponent value.
|
||||
* See IEEE 802.15.4-2006, section 7.4.2, Table 86.
|
||||
@@ -130,7 +129,6 @@ public:
|
||||
* \return the maximum backoff exponent value
|
||||
*/
|
||||
uint8_t GetMacMaxBE (void) const;
|
||||
|
||||
/**
|
||||
* Set the maximum number of backoffs.
|
||||
* See IEEE 802.15.4-2006, section 7.4.2, Table 86.
|
||||
@@ -146,7 +144,6 @@ public:
|
||||
* \return the maximum number of backoffs
|
||||
*/
|
||||
uint8_t GetMacMaxCSMABackoffs (void) const;
|
||||
|
||||
/**
|
||||
* Set the number of symbols forming the basic time period used by the
|
||||
* CSMA-CA algorithm.
|
||||
@@ -155,7 +152,6 @@ public:
|
||||
* \param unitBackoffPeriod the period length in symbols
|
||||
*/
|
||||
void SetUnitBackoffPeriod (uint64_t unitBackoffPeriod);
|
||||
|
||||
/**
|
||||
* Get the number of symbols forming the basic time period used by the
|
||||
* CSMA-CA algorithm.
|
||||
@@ -164,30 +160,26 @@ public:
|
||||
* \return the period length in symbols
|
||||
*/
|
||||
uint64_t GetUnitBackoffPeriod (void) const;
|
||||
|
||||
/**
|
||||
* Get the amount of time from now to the beginning of the next slot.
|
||||
* Locates the time to the next backoff period boundary and returns the
|
||||
* amount of time left (in symbols).
|
||||
*
|
||||
* \return time offset to the next slot
|
||||
*/
|
||||
Time GetTimeToNextSlot (void) const;
|
||||
|
||||
/**
|
||||
* Start CSMA-CA algorithm (step 1), initialize NB, BE for both slotted and unslotted
|
||||
* CSMA-CA. For the slotted initialize CW plus also start on the backoff boundary
|
||||
* CSMA-CA. For slotted CSMA-CA initializes CW and starts the backoff slot count.
|
||||
*/
|
||||
void Start (void);
|
||||
|
||||
/**
|
||||
* Cancel CSMA-CA algorithm.
|
||||
*/
|
||||
void Cancel (void);
|
||||
|
||||
/**
|
||||
* In step 2 of the CSMA-CA, perform a random backoff in the range of 0 to 2^BE -1
|
||||
*/
|
||||
void RandomBackoffDelay (void);
|
||||
|
||||
/**
|
||||
* In the slotted CSMA-CA, after random backoff, determine if the remaining
|
||||
* CSMA-CA operation can proceed, i.e. can the entire transactions can be
|
||||
@@ -196,12 +188,15 @@ public:
|
||||
* proceed function RequestCCA() is called.
|
||||
*/
|
||||
void CanProceed (void);
|
||||
|
||||
/**
|
||||
* Request the Phy to perform CCA (Step 3)
|
||||
*/
|
||||
void RequestCCA (void);
|
||||
|
||||
/**
|
||||
* The CSMA algorithm call this function at the end of the CAP to return the MAC state
|
||||
* back to to IDLE after a transmission was deferred due to the lack of time in the CAP.
|
||||
*/
|
||||
void DeferCsmaTimeout (void);
|
||||
/**
|
||||
* IEEE 802.15.4-2006 section 6.2.2.2
|
||||
* PLME-CCA.confirm status
|
||||
@@ -214,7 +209,14 @@ public:
|
||||
* treat as channel access failure (step 4).
|
||||
*/
|
||||
void PlmeCcaConfirm (LrWpanPhyEnumeration status);
|
||||
|
||||
/**
|
||||
* Set the callback function to report a transaction cost in slotted CSMA-CA. The callback is
|
||||
* triggered in CanProceed() after calculating the transaction cost (2 CCA checks,transmission cost, turnAroundTime, ifs)
|
||||
* in the boundary of an Active Period.
|
||||
*
|
||||
* \param trans the transaction cost callback
|
||||
*/
|
||||
void SetLrWpanMacTransCostCallback (LrWpanMacTransCostCallback trans);
|
||||
/**
|
||||
* Set the callback function to the MAC. Used at the end of a Channel Assessment, as part of the
|
||||
* interconnections between the CSMA-CA and the MAC. The callback
|
||||
@@ -223,7 +225,12 @@ public:
|
||||
* \param macState the mac state callback
|
||||
*/
|
||||
void SetLrWpanMacStateCallback (LrWpanMacStateCallback macState);
|
||||
|
||||
/**
|
||||
* Set the value of the Battery Life Extension
|
||||
*
|
||||
* \param batteryLifeExtension the Battery Life Extension value active or inactive
|
||||
*/
|
||||
void SetBatteryLifeExtension (bool batteryLifeExtension);
|
||||
/**
|
||||
* Assign a fixed random variable stream number to the random variables
|
||||
* used by this model. Return the number of streams that have been assigned.
|
||||
@@ -232,13 +239,18 @@ public:
|
||||
* \return the number of stream indices assigned by this model
|
||||
*/
|
||||
int64_t AssignStreams (int64_t stream);
|
||||
|
||||
/**
|
||||
* Get the number of CSMA retries
|
||||
*
|
||||
* \returns the number of CSMA retries
|
||||
*/
|
||||
uint8_t GetNB (void);
|
||||
/**
|
||||
* Get the value of the Battery Life Extension
|
||||
*
|
||||
* \returns true or false to Battery Life Extension support
|
||||
*/
|
||||
bool GetBatteryLifeExtension (void);
|
||||
|
||||
private:
|
||||
// Disable implicit copy constructors
|
||||
@@ -251,90 +263,98 @@ private:
|
||||
* \returns
|
||||
*/
|
||||
LrWpanCsmaCa& operator= (LrWpanCsmaCa const &);
|
||||
|
||||
virtual void DoDispose (void);
|
||||
|
||||
virtual void DoDispose (void);
|
||||
/**
|
||||
* \brief Get the periods left in the CAP portion of the Outgoing or Incoming frame.
|
||||
* \return num of backoff periods left in the CAP
|
||||
*/
|
||||
uint32_t GetBackoffPeriodsLeftInCap ();
|
||||
/**
|
||||
* The callback to inform the cost of a transaction in slotted CSMA-CA.
|
||||
*/
|
||||
LrWpanMacTransCostCallback m_lrWpanMacTransCostCallback;
|
||||
/**
|
||||
* The callback to inform the configured MAC of the CSMA/CA result.
|
||||
*/
|
||||
LrWpanMacStateCallback m_lrWpanMacStateCallback;
|
||||
|
||||
/**
|
||||
* Beacon-enabled slotted or nonbeacon-enabled unslotted CSMA-CA.
|
||||
*/
|
||||
bool m_isSlotted;
|
||||
|
||||
/**
|
||||
* The MAC instance for which this CSMAÄ/CA implementation is configured.
|
||||
* The MAC instance for which this CSMA/CA implemenation is configured.
|
||||
*/
|
||||
Ptr<LrWpanMac> m_mac;
|
||||
|
||||
/**
|
||||
* Number of backoffs for the current transmission.
|
||||
*/
|
||||
uint8_t m_NB;
|
||||
|
||||
/**
|
||||
* Contention window length (used in slotted ver only).
|
||||
*/
|
||||
uint8_t m_CW;
|
||||
|
||||
/**
|
||||
* Backoff exponent.
|
||||
*/
|
||||
uint8_t m_BE;
|
||||
|
||||
/**
|
||||
* Battery Life Extension.
|
||||
*/
|
||||
bool m_BLE;
|
||||
|
||||
bool m_macBattLifeExt;
|
||||
/**
|
||||
* Minimum backoff exponent. 0 - macMaxBE, default 3
|
||||
*/
|
||||
uint8_t m_macMinBE; //
|
||||
|
||||
/**
|
||||
* Maximum backoff exponent. 3 - 8, default 5
|
||||
*/
|
||||
uint8_t m_macMaxBE;
|
||||
|
||||
/**
|
||||
* Maximum number of backoffs. 0 - 5, default 4
|
||||
*/
|
||||
uint8_t m_macMaxCSMABackoffs;
|
||||
|
||||
/**
|
||||
* Number of symbols per CSMA/CA time unit, default 20 symbols.
|
||||
*/
|
||||
uint64_t m_aUnitBackoffPeriod;
|
||||
|
||||
/**
|
||||
* Count the number of remaining random backoff periods left to delay.
|
||||
*/
|
||||
uint64_t m_randomBackoffPeriodsLeft;
|
||||
/**
|
||||
* Uniform random variable stream.
|
||||
*/
|
||||
Ptr<UniformRandomVariable> m_random;
|
||||
|
||||
/**
|
||||
* Scheduler event for the start of the next random backoff/slot.
|
||||
*/
|
||||
EventId m_randomBackoffEvent;
|
||||
|
||||
/**
|
||||
* Scheduler event for the end of the current CAP
|
||||
*/
|
||||
EventId m_endCapEvent;
|
||||
/**
|
||||
* Scheduler event when to start the CCA after a random backoff.
|
||||
*/
|
||||
EventId m_requestCcaEvent;
|
||||
|
||||
/**
|
||||
* Scheduler event for checking if we can complete the transmission before the
|
||||
* end of the CAP.
|
||||
*/
|
||||
EventId m_canProceedEvent;
|
||||
|
||||
/**
|
||||
* Flag indicating that the PHY is currently running a CCA. Used to prevent
|
||||
* reporting the channel status to the MAC while canceling the CSMA algorithm.
|
||||
*/
|
||||
bool m_ccaRequestRunning;
|
||||
/**
|
||||
* Indicates whether the CSMA procedure is targeted for a message to be sent to the coordinator.
|
||||
* Used to run slotted CSMA/CA on the incoming or outgoing superframe
|
||||
* according to the target.
|
||||
*/
|
||||
bool m_coorDest;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
491
src/lr-wpan/model/lr-wpan-fields.cc
Normal file
491
src/lr-wpan/model/lr-wpan-fields.cc
Normal file
@@ -0,0 +1,491 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2019 Ritsumeikan University, Shiga, Japan.
|
||||
*
|
||||
* 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: Alberto Gallegos Ramonet <ramonet@fc.ritsumei.ac.jp>
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "lr-wpan-fields.h"
|
||||
#include <ns3/log.h>
|
||||
#include <ns3/address-utils.h>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
SuperframeField::SuperframeField ()
|
||||
{
|
||||
SetBeaconOrder (15);
|
||||
SetSuperframeOrder (15);
|
||||
SetFinalCapSlot (0);
|
||||
SetBattLifeExt (false);
|
||||
SetPanCoor (false);
|
||||
SetAssocPermit (false);
|
||||
}
|
||||
|
||||
void
|
||||
SuperframeField::SetSuperframe (uint16_t superFrmSpec)
|
||||
{
|
||||
m_sspecBcnOrder = (superFrmSpec) & (0x0F); //Bits 0-3
|
||||
m_sspecSprFrmOrder = (superFrmSpec >> 4) & (0x0F); //Bits 4-7
|
||||
m_sspecFnlCapSlot = (superFrmSpec >> 8) & (0x0F); //Bits 8-11
|
||||
m_sspecBatLifeExt = (superFrmSpec >> 12) & (0x01); //Bit 12
|
||||
//Bit 13 (Reserved)
|
||||
m_sspecPanCoor = (superFrmSpec >> 14) & (0x01); //Bit 14
|
||||
m_sspecAssocPermit = (superFrmSpec >> 15) & (0x01); //Bit 15
|
||||
}
|
||||
|
||||
void
|
||||
SuperframeField::SetBeaconOrder (uint8_t bcnOrder)
|
||||
{
|
||||
if (bcnOrder > 15)
|
||||
{
|
||||
std::cout << "SuperframeField Beacon Order value must be 15 or less\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
m_sspecBcnOrder = bcnOrder;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SuperframeField::SetSuperframeOrder (uint8_t frmOrder)
|
||||
{
|
||||
if (frmOrder > 15)
|
||||
{
|
||||
std::cout << "SuperframeField Frame Order value must be 15 or less\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
m_sspecSprFrmOrder = frmOrder;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SuperframeField::SetFinalCapSlot (uint8_t capSlot)
|
||||
{
|
||||
if (capSlot > 15)
|
||||
{
|
||||
std::cout << "The final slot cannot greater than the slots in a CAP (15)\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
m_sspecFnlCapSlot = capSlot;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SuperframeField::SetBattLifeExt (bool battLifeExt)
|
||||
{
|
||||
m_sspecBatLifeExt = battLifeExt;
|
||||
}
|
||||
|
||||
void
|
||||
SuperframeField::SetPanCoor (bool panCoor)
|
||||
{
|
||||
m_sspecPanCoor = panCoor;
|
||||
}
|
||||
|
||||
void
|
||||
SuperframeField::SetAssocPermit (bool assocPermit)
|
||||
{
|
||||
m_sspecAssocPermit = assocPermit;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
SuperframeField::GetBeaconOrder (void) const
|
||||
{
|
||||
return m_sspecBcnOrder;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
SuperframeField::GetFrameOrder (void) const
|
||||
{
|
||||
return m_sspecSprFrmOrder;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
SuperframeField::GetFinalCapSlot (void) const
|
||||
{
|
||||
return m_sspecFnlCapSlot;
|
||||
}
|
||||
|
||||
bool
|
||||
SuperframeField::IsBattLifeExt (void) const
|
||||
{
|
||||
return m_sspecBatLifeExt;
|
||||
}
|
||||
|
||||
bool
|
||||
SuperframeField::IsPanCoor (void) const
|
||||
{
|
||||
return m_sspecPanCoor;
|
||||
}
|
||||
|
||||
bool
|
||||
SuperframeField::IsAssocPermit (void) const
|
||||
{
|
||||
return m_sspecAssocPermit;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
SuperframeField::GetSuperframe (void) const
|
||||
{
|
||||
uint16_t superframe;
|
||||
|
||||
superframe = m_sspecBcnOrder & (0x0F); // Bits 0-3
|
||||
superframe |= (m_sspecSprFrmOrder << 4) & (0x0F << 4); // Bits 4-7
|
||||
superframe |= (m_sspecFnlCapSlot << 8) & (0x0F << 8); // Bits 8-11
|
||||
superframe |= (m_sspecBatLifeExt << 12) & (0x01 << 12); // Bit 12
|
||||
// Bit 13 (Reserved)
|
||||
superframe |= (m_sspecPanCoor << 14) & (0x01 << 14); // Bit 14
|
||||
superframe |= (m_sspecAssocPermit << 15) & (0x01 << 15); // Bit 15
|
||||
|
||||
return superframe;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
SuperframeField::GetSerializedSize (void) const
|
||||
{
|
||||
return 2; // 2 Octets (superframeSpec)
|
||||
}
|
||||
|
||||
Buffer::Iterator
|
||||
SuperframeField::Serialize (Buffer::Iterator i) const
|
||||
{
|
||||
i.WriteHtolsbU16 (GetSuperframe ());
|
||||
return i;
|
||||
}
|
||||
|
||||
Buffer::Iterator
|
||||
SuperframeField::Deserialize (Buffer::Iterator i)
|
||||
{
|
||||
uint16_t superframe = i.ReadLsbtohU16 ();
|
||||
SetSuperframe (superframe);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* output stream output operator
|
||||
*
|
||||
* \param os output stream
|
||||
* \param superframeField The Superframe Specification Field
|
||||
*
|
||||
* \returns output stream
|
||||
*/
|
||||
std::ostream &
|
||||
operator << (std::ostream &os, const SuperframeField &superframeField)
|
||||
{
|
||||
os << " Beacon Order = " << uint32_t (superframeField.GetBeaconOrder ())
|
||||
<< ", Frame Order = " << uint32_t (superframeField.GetFrameOrder ())
|
||||
<< ", Final CAP slot = " << uint32_t (superframeField.GetFinalCapSlot ())
|
||||
<< ", Battery Life Ext = " << bool (superframeField.IsBattLifeExt ())
|
||||
<< ", PAN Coordinator = " << bool (superframeField.IsPanCoor ())
|
||||
<< ", Association Permit = " << bool (superframeField.IsAssocPermit ());
|
||||
return os;
|
||||
}
|
||||
|
||||
/***********************************************************
|
||||
* Guaranteed Time Slots (GTS) Fields
|
||||
***********************************************************/
|
||||
|
||||
GtsFields::GtsFields ()
|
||||
{
|
||||
// GTS Specification Field
|
||||
m_gtsSpecDescCount = 0;
|
||||
m_gtsSpecPermit = 0;
|
||||
// GTS Direction Field
|
||||
m_gtsDirMask = 0;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
GtsFields::GetGtsSpecField (void) const
|
||||
{
|
||||
uint8_t gtsSpecField;
|
||||
|
||||
gtsSpecField = m_gtsSpecDescCount & (0x07); // Bits 0-2
|
||||
// Bits 3-6 (Reserved)
|
||||
gtsSpecField |= (m_gtsSpecPermit << 7) & (0x01 << 7); // Bit 7
|
||||
|
||||
return gtsSpecField;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
GtsFields::GetGtsDirectionField (void) const
|
||||
{
|
||||
uint8_t gtsDirectionField;
|
||||
|
||||
gtsDirectionField = m_gtsDirMask & (0x7F); // Bit 0-6
|
||||
// Bit 7 (Reserved)
|
||||
return gtsDirectionField;
|
||||
}
|
||||
|
||||
void
|
||||
GtsFields::SetGtsSpecField (uint8_t gtsSpec)
|
||||
{
|
||||
m_gtsSpecDescCount = (gtsSpec) & (0x07); // Bits 0-2
|
||||
// Bits 3-6 (Reserved)
|
||||
m_gtsSpecPermit = (gtsSpec >> 7) & (0x01); // Bit 7
|
||||
}
|
||||
|
||||
void
|
||||
GtsFields::SetGtsDirectionField (uint8_t gtsDir)
|
||||
{
|
||||
m_gtsDirMask = (gtsDir) & (0x7F); // Bits 0-6
|
||||
// Bit 7 (Reserved)
|
||||
}
|
||||
|
||||
uint32_t
|
||||
GtsFields::GetSerializedSize (void) const
|
||||
{
|
||||
uint32_t size;
|
||||
|
||||
size = 1; // 1 octet GTS Specification Field
|
||||
if (m_gtsSpecDescCount > 0)
|
||||
{
|
||||
size += 1; // 1 octet GTS Direction Field
|
||||
size += (m_gtsSpecDescCount * 3); // 3 octets per GTS descriptor
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
Buffer::Iterator
|
||||
GtsFields::Serialize (Buffer::Iterator i) const
|
||||
{
|
||||
i.WriteU8 (GetGtsSpecField ());
|
||||
|
||||
if (m_gtsSpecDescCount > 0)
|
||||
{
|
||||
uint8_t gtsDescStartAndLenght;
|
||||
i.WriteU8 (GetGtsDirectionField ());
|
||||
|
||||
for (int j = 0; j < m_gtsSpecDescCount; j++)
|
||||
{
|
||||
WriteTo (i,m_gtsList[j].m_gtsDescDevShortAddr);
|
||||
|
||||
gtsDescStartAndLenght = m_gtsList[j].m_gtsDescStartSlot & (0x0F);
|
||||
gtsDescStartAndLenght = (m_gtsList[j].m_gtsDescLength << 4) & (0x0F);
|
||||
|
||||
i.WriteU8 (gtsDescStartAndLenght);
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
Buffer::Iterator
|
||||
GtsFields::Deserialize (Buffer::Iterator i)
|
||||
{
|
||||
|
||||
uint8_t gtsSpecField = i.ReadU8 ();
|
||||
SetGtsSpecField (gtsSpecField);
|
||||
|
||||
if (m_gtsSpecDescCount > 0)
|
||||
{
|
||||
uint8_t gtsDirectionField = i.ReadU8 ();
|
||||
SetGtsDirectionField (gtsDirectionField);
|
||||
|
||||
uint8_t gtsDescStartAndLenght;
|
||||
for (int j = 0; j < m_gtsSpecDescCount; j++)
|
||||
{
|
||||
ReadFrom (i, m_gtsList[j].m_gtsDescDevShortAddr);
|
||||
|
||||
gtsDescStartAndLenght = i.ReadU8 ();
|
||||
m_gtsList[j].m_gtsDescStartSlot = (gtsDescStartAndLenght) & (0x0F);
|
||||
m_gtsList[j].m_gtsDescLength = (gtsDescStartAndLenght >> 4) & (0x0F);
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************
|
||||
* Pending Address Fields
|
||||
***********************************************************/
|
||||
|
||||
PendingAddrFields::PendingAddrFields ()
|
||||
{
|
||||
m_pndAddrSpecNumShortAddr = 0;
|
||||
m_pndAddrSpecNumExtAddr = 0;
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
PendingAddrFields::GetNumShortAddr (void) const
|
||||
{
|
||||
return m_pndAddrSpecNumShortAddr;
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
PendingAddrFields::GetNumExtAddr (void) const
|
||||
{
|
||||
return m_pndAddrSpecNumExtAddr;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
PendingAddrFields::GetPndAddrSpecField (void) const
|
||||
{
|
||||
uint8_t pndAddrSpecField;
|
||||
|
||||
pndAddrSpecField = m_pndAddrSpecNumShortAddr & (0x07); // Bits 0-2
|
||||
// Bit 3 (Reserved)
|
||||
pndAddrSpecField |= (m_pndAddrSpecNumExtAddr << 4) & (0x07 << 4); // Bits 4-6
|
||||
// Bit 7 (Reserved)
|
||||
|
||||
return pndAddrSpecField;
|
||||
}
|
||||
|
||||
void
|
||||
PendingAddrFields::AddAddress (Mac16Address shortAddr)
|
||||
{
|
||||
uint8_t totalPendAddr = m_pndAddrSpecNumShortAddr + m_pndAddrSpecNumExtAddr;
|
||||
|
||||
if (totalPendAddr == 7)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_shortAddrList[m_pndAddrSpecNumShortAddr] = shortAddr;
|
||||
m_pndAddrSpecNumShortAddr++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PendingAddrFields::AddAddress (Mac64Address extAddr)
|
||||
{
|
||||
uint8_t totalPendAddr = m_pndAddrSpecNumShortAddr + m_pndAddrSpecNumExtAddr;
|
||||
|
||||
if (totalPendAddr == 7)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_extAddrList[m_pndAddrSpecNumExtAddr] = extAddr;
|
||||
m_pndAddrSpecNumExtAddr++;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
PendingAddrFields::SearchAddress (Mac16Address shortAddr)
|
||||
{
|
||||
for (int j = 0; j <= m_pndAddrSpecNumShortAddr; j++)
|
||||
{
|
||||
if (shortAddr == m_shortAddrList[j])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PendingAddrFields::SearchAddress (Mac64Address extAddr)
|
||||
{
|
||||
for (int j = 0; j <= m_pndAddrSpecNumExtAddr; j++)
|
||||
{
|
||||
if (extAddr == m_extAddrList[j])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PendingAddrFields::SetPndAddrSpecField (uint8_t pndAddrSpecField)
|
||||
{
|
||||
m_pndAddrSpecNumShortAddr = (pndAddrSpecField) & (0x07); // Bit 0-2
|
||||
// Bit 3
|
||||
m_pndAddrSpecNumExtAddr = (pndAddrSpecField >> 4) & (0x07); // Bit 4-6
|
||||
// Bit 7
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
PendingAddrFields::GetSerializedSize (void) const
|
||||
{
|
||||
uint32_t size;
|
||||
|
||||
size = 1; // 1 octet (Pending Address Specification Field)
|
||||
size = size + (m_pndAddrSpecNumShortAddr * 2); // X octets (Short Pending Address List)
|
||||
size = size + (m_pndAddrSpecNumExtAddr * 8); // X octets (Extended Pending Address List)
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
Buffer::Iterator
|
||||
PendingAddrFields::Serialize (Buffer::Iterator i) const
|
||||
{
|
||||
i.WriteU8 (GetPndAddrSpecField ());
|
||||
|
||||
for (int j = 0; j < m_pndAddrSpecNumShortAddr; j++)
|
||||
{
|
||||
WriteTo (i,m_shortAddrList[j]);
|
||||
}
|
||||
|
||||
for (int k = 0; k < m_pndAddrSpecNumExtAddr; k++ )
|
||||
{
|
||||
WriteTo (i,m_extAddrList[k]);
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
Buffer::Iterator
|
||||
PendingAddrFields::Deserialize (Buffer::Iterator i)
|
||||
{
|
||||
uint8_t pndAddrSpecField = i.ReadU8 ();
|
||||
|
||||
SetPndAddrSpecField (pndAddrSpecField);
|
||||
|
||||
for (int j = 0; j < m_pndAddrSpecNumShortAddr; j++)
|
||||
{
|
||||
ReadFrom (i, m_shortAddrList[j]);
|
||||
}
|
||||
|
||||
for (int k = 0; k < m_pndAddrSpecNumExtAddr; k++)
|
||||
{
|
||||
ReadFrom (i, m_extAddrList[k]);
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* output stream output operator
|
||||
*
|
||||
* \param os output stream
|
||||
* \param PendingAddrField the Pending Address Specification Field
|
||||
*
|
||||
* \returns output stream
|
||||
*/
|
||||
std::ostream &
|
||||
operator << (std::ostream &os, const PendingAddrFields &pendingAddrFields)
|
||||
{
|
||||
os << " Num. Short Addr = " << uint32_t (pendingAddrFields.GetNumShortAddr ())
|
||||
<< ", Num. Ext Addr = " << uint32_t (pendingAddrFields.GetNumExtAddr ());
|
||||
return os;
|
||||
}
|
||||
|
||||
} // ns-3 namespace
|
||||
314
src/lr-wpan/model/lr-wpan-fields.h
Normal file
314
src/lr-wpan/model/lr-wpan-fields.h
Normal file
@@ -0,0 +1,314 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2019 Ritsumeikan University, Shiga, Japan.
|
||||
*
|
||||
* 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: Alberto Gallegos Ramonet <ramonet@fc.ritsumei.ac.jp>
|
||||
*
|
||||
* This file implements Information Fields present in IEEE 802.15.4-2011.
|
||||
* Information Fields are in practice similar to the Information Elements(IE)
|
||||
* introduced in later revisions of the standard, however, they lack
|
||||
* descriptors and common format unlike the IEs. To keep this implementation
|
||||
* consistent with the IEEE 802.15.4-2011 std. the present file implements
|
||||
* Information Fields not Information Elements.
|
||||
*/
|
||||
#ifndef LR_WPAN_FIELDS_H
|
||||
#define LR_WPAN_FIELDS_H
|
||||
|
||||
|
||||
#include <ns3/mac16-address.h>
|
||||
#include <ns3/mac64-address.h>
|
||||
#include "ns3/buffer.h"
|
||||
#include <array>
|
||||
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/**
|
||||
* The device Capabilities.
|
||||
*/
|
||||
enum DeviceType
|
||||
{
|
||||
RFD = 0, //!< Reduced Functional Device (RFD)
|
||||
FFD = 1 //!< Full Functional Device (FFD)
|
||||
};
|
||||
|
||||
/**
|
||||
* \ingroup lr-wpan
|
||||
* Represent the Superframe Specification information field.
|
||||
* See IEEE 802.15.4-2011 Section 5.2.2.1.2 Figure 41
|
||||
*/
|
||||
class SuperframeField
|
||||
{
|
||||
|
||||
public:
|
||||
SuperframeField ();
|
||||
/**
|
||||
* Set the whole Superframe Specification Information field.
|
||||
* \param superFrm The Superframe Specification information field.
|
||||
*/
|
||||
void SetSuperframe (uint16_t superFrm);
|
||||
/**
|
||||
* Set the superframe specification Beacon Order field.
|
||||
* \param bcnOrder The beacon order value to set in the superframe.
|
||||
*/
|
||||
void SetBeaconOrder (uint8_t bcnOrder);
|
||||
/**
|
||||
* Set the superframe specification Superframe Order field.
|
||||
* \param frmOrder The frame Order value to set on the superframe.
|
||||
*/
|
||||
void SetSuperframeOrder (uint8_t frmOrder);
|
||||
/**
|
||||
* Set the superframe specification Final CAP slot field.
|
||||
* \param capSlot Set the final slot of the Contention Access Period (CAP).
|
||||
*/
|
||||
void SetFinalCapSlot (uint8_t capSlot);
|
||||
/**
|
||||
* Set the Superframe Specification Battery Life Extension (BLE).
|
||||
* \param battLifeExt Sets true or false the value of the Battery Life Extension flag of the superframe field.
|
||||
*/
|
||||
void SetBattLifeExt (bool battLifeExt);
|
||||
/**
|
||||
* Set the Superframe Specification PAN coordinator field.
|
||||
* \param panCoor set true or false the value for the PAN Coordinator flag of the superframe field.
|
||||
*/
|
||||
void SetPanCoor (bool panCoor);
|
||||
/**
|
||||
* Set the Superframe Specification Association Permit field.
|
||||
* \param assocPermit set true or false the value of the Association Permit flag of the superframe field.
|
||||
*/
|
||||
void SetAssocPermit (bool assocPermit);
|
||||
/**
|
||||
* Get the Superframe Specification Beacon Order field.
|
||||
*/
|
||||
uint8_t GetBeaconOrder (void) const;
|
||||
/**
|
||||
* Get the Superframe Specification Frame Order field.
|
||||
*/
|
||||
uint8_t GetFrameOrder (void) const;
|
||||
/**
|
||||
* Check if the Final CAP Slot bit is enabled.
|
||||
*/
|
||||
uint8_t GetFinalCapSlot (void) const;
|
||||
/**
|
||||
* Check if the Battery Life Extension bit is enabled.
|
||||
*/
|
||||
bool IsBattLifeExt (void) const;
|
||||
/**
|
||||
* Check if the PAN Coordinator bit is enabled.
|
||||
*/
|
||||
bool IsPanCoor (void) const;
|
||||
/**
|
||||
* Check if the Association Permit bit is enabled.
|
||||
*/
|
||||
bool IsAssocPermit (void) const;
|
||||
/**
|
||||
* Get the Superframe specification information field.
|
||||
* \return the Superframe Specification Information field bits.
|
||||
*/
|
||||
uint16_t GetSuperframe (void) const;
|
||||
/**
|
||||
* Get the size of the serialized Superframe specification information field.
|
||||
* \return the size of the serialized field.
|
||||
*/
|
||||
uint32_t GetSerializedSize (void) const;
|
||||
/**
|
||||
* Serialize the entire superframe specification field.
|
||||
* \param i an iterator which points to where the superframe specification field should be written.
|
||||
* \return an iterator.
|
||||
*/
|
||||
Buffer::Iterator Serialize (Buffer::Iterator i) const;
|
||||
/**
|
||||
* Deserialize the entire superframe specification field.
|
||||
* \param i an iterator which points to where the superframe specification field should be read.
|
||||
* \return an iterator.
|
||||
*/
|
||||
Buffer::Iterator Deserialize (Buffer::Iterator i);
|
||||
|
||||
|
||||
private:
|
||||
// Superframe Specification field
|
||||
// See IEEE 802.14.15-2011 5.2.2.1.2
|
||||
uint8_t m_sspecBcnOrder; //!< Superframe Specification field Beacon Order (Bit 0-3)
|
||||
uint8_t m_sspecSprFrmOrder; //!< Superframe Specification field Superframe Order (Bit 4-7)
|
||||
uint8_t m_sspecFnlCapSlot; //!< Superframe Specification field Final CAP slot (Bit 8-11)
|
||||
bool m_sspecBatLifeExt; //!< Superframe Specification field Battery Life Extension (Bit 12)
|
||||
//!< Superframe Specification field Reserved (not necessary) (Bit 13)
|
||||
bool m_sspecPanCoor; //!< Superframe Specification field PAN Coordinator (Bit 14)
|
||||
bool m_sspecAssocPermit; //!< Superframe Specification field Association Permit (Bit 15)
|
||||
|
||||
};
|
||||
std::ostream &operator << (std::ostream &os, const SuperframeField &superframeField);
|
||||
|
||||
/**
|
||||
* \ingroup lr-wpan
|
||||
* Represent the GTS information fields.
|
||||
* See IEEE 802.15.4-2011 Section 5.2.2 Figure 39
|
||||
*/
|
||||
class GtsFields
|
||||
{
|
||||
|
||||
public:
|
||||
GtsFields ();
|
||||
/**
|
||||
* Get the GTS Specification Field from the GTS Fields
|
||||
* \return The GTS Spcecification Field
|
||||
*/
|
||||
uint8_t GetGtsSpecField (void) const;
|
||||
/**
|
||||
* Get the GTS Direction Field from the GTS Fields
|
||||
* \return The GTS Direction Field
|
||||
*/
|
||||
uint8_t GetGtsDirectionField (void) const;
|
||||
/**
|
||||
* Set the GTS Specification Field to the GTS Fields
|
||||
* gtsSpec The GTS Specification Field to set.
|
||||
*/
|
||||
void SetGtsSpecField (uint8_t gtsSpec);
|
||||
/**
|
||||
* Set the GTS direction field to the GTS Fields
|
||||
* gtsDir The GTS Direction Field to set
|
||||
*/
|
||||
void SetGtsDirectionField (uint8_t gtsDir);
|
||||
/**
|
||||
* Get the size of the serialized GTS fields.
|
||||
* \return the size of the serialized fields.
|
||||
*/
|
||||
uint32_t GetSerializedSize (void) const;
|
||||
/**
|
||||
* Serialize the entire GTS fields.
|
||||
* \param i an iterator which points to where the superframe specification field should be written.
|
||||
* \return an iterator.
|
||||
*/
|
||||
Buffer::Iterator Serialize (Buffer::Iterator i) const;
|
||||
/**
|
||||
* Deserialize the entire GTS fields.
|
||||
* \param i an iterator which points to where the superframe specification field should be read.
|
||||
* \return an iterator.
|
||||
*/
|
||||
Buffer::Iterator Deserialize (Buffer::Iterator i);
|
||||
|
||||
private:
|
||||
//GTS Descriptor
|
||||
struct gtsDescriptor
|
||||
{
|
||||
Mac16Address m_gtsDescDevShortAddr; //!< GTS Descriptor Device Short Address (Bit 0-15)
|
||||
u_int8_t m_gtsDescStartSlot; //!< GTS Descriptor GTS Starting Slot(Bit 16-19)
|
||||
u_int8_t m_gtsDescLength; //!< GTS Descriptor GTS Length (Bit 20-23)
|
||||
};
|
||||
|
||||
//GTS specification field
|
||||
u_int8_t m_gtsSpecDescCount; //!< GTS specification field Descriptor Count (Bit 0-2)
|
||||
//!< GTS specification field Reserved (Not necessary) (Bit 3-6)
|
||||
u_int8_t m_gtsSpecPermit; //!< GTS specification field GTS Permit (Bit 7)
|
||||
//GTS Direction field
|
||||
u_int8_t m_gtsDirMask; //!< GTS Direction field Directions Mask (Bit 0-6)
|
||||
//!< GTS Direction field Reserved (Not Necessary) (Bit 7)
|
||||
//GTS List
|
||||
gtsDescriptor m_gtsList[6]; //!< GTS List field (maximum descriptors stored == 7)
|
||||
};
|
||||
std::ostream &operator << (std::ostream &os, const GtsFields >sFields);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* \ingroup lr-wpan
|
||||
* Represent the Pending Address Specification field.
|
||||
* See IEEE 802.15.4-2011 Section 5.2.2.1.6. Figure 45
|
||||
*/
|
||||
class PendingAddrFields
|
||||
{
|
||||
|
||||
public:
|
||||
PendingAddrFields ();
|
||||
/**
|
||||
* Add a short Pending Address to the Address List.
|
||||
* \param shortAddr The extended Pending Address List.
|
||||
*/
|
||||
void AddAddress (Mac16Address shortAddr);
|
||||
/**
|
||||
* Add a extended Pending Address to the Address List.
|
||||
* \param extAddr The extended Pending Address List.
|
||||
*/
|
||||
void AddAddress (Mac64Address extAddr);
|
||||
/**
|
||||
* Search for the short Pending Address in the Address List.
|
||||
* \param shortAddr The extended Address to look in the Address List.
|
||||
* \return True if the address exist in the extended Address List.
|
||||
*/
|
||||
bool SearchAddress (Mac16Address shortAddr);
|
||||
/**
|
||||
* Search for the extended Pending Address in the Address List.
|
||||
* \param extAddr The extended Address to look in the Address List.
|
||||
* \return True if the address exist in the extended Address List.
|
||||
*/
|
||||
bool SearchAddress (Mac64Address extAddr);
|
||||
/**
|
||||
* Get the whole Pending Address Specification Field from the Pending Address Fields.
|
||||
* \return The Pending Address Specification Field.
|
||||
*/
|
||||
uint8_t GetPndAddrSpecField (void) const;
|
||||
/**
|
||||
* Get the number of Short Pending Address indicated in the Pending Address Specification Field.
|
||||
* \return The number Short Pending Address.
|
||||
*/
|
||||
uint8_t GetNumShortAddr (void) const;
|
||||
/**
|
||||
* Get the number of Extended Pending Address indicated in the Pending Address Specification Field.
|
||||
* \return The number Short Pending Address.
|
||||
*/
|
||||
uint8_t GetNumExtAddr (void) const;
|
||||
|
||||
/**
|
||||
* Set the whole Pending Address Specification field. This field is part of the
|
||||
* Pending Address Fields header.
|
||||
* \param pndAddrSpecField The Pending Address Specification Field
|
||||
*/
|
||||
void SetPndAddrSpecField (uint8_t pndAddrSpecField);
|
||||
/**
|
||||
* Get the size of the serialized Pending Address Fields.
|
||||
* \return the size of the serialized fields.
|
||||
*/
|
||||
uint32_t GetSerializedSize (void) const;
|
||||
/**
|
||||
* Serialize the entire Pending Address Fields.
|
||||
* \param i an iterator which points to where the Pending Address Fields should be written.
|
||||
* \return an iterator.
|
||||
*/
|
||||
Buffer::Iterator Serialize (Buffer::Iterator i) const;
|
||||
/**
|
||||
* Deserialize the all the Pending Address Fields.
|
||||
* \param start an iterator which points to where the Pending Address Fields should be read.
|
||||
* \return an iterator.
|
||||
*/
|
||||
Buffer::Iterator Deserialize (Buffer::Iterator i);
|
||||
|
||||
private:
|
||||
// Pending Address Specification Field
|
||||
uint8_t m_pndAddrSpecNumShortAddr; //!< Pending Address Specification field Number of Short Address (Bits 0-2)
|
||||
//!< Pending Address Specification field Reserved (Not Necessary)(Bit 3)
|
||||
uint8_t m_pndAddrSpecNumExtAddr; //!< Pending Address Specification field Number of Extended Address (Bits 4-6)
|
||||
//!< Pending Address Specification field Reserved (Not Necessary) (Bit 7)
|
||||
// Address List
|
||||
std::array <Mac16Address,7> m_shortAddrList; //!< Pending Short Address List
|
||||
std::array<Mac64Address,7> m_extAddrList; //!< Pending Extended Address List
|
||||
|
||||
};
|
||||
std::ostream &operator << (std::ostream &os, const PendingAddrFields &pendingAddrFields);
|
||||
|
||||
|
||||
} //end namespace ns3
|
||||
|
||||
#endif /* LR_WPAN_FIELDS_H */
|
||||
@@ -252,31 +252,24 @@ LrWpanMacHeader::GetKeyIdIndex (void) const
|
||||
return(m_auxKeyIdKeyIndex);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
LrWpanMacHeader::IsBeacon (void) const
|
||||
{
|
||||
return(m_fctrlFrmType == LRWPAN_MAC_BEACON);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
LrWpanMacHeader::IsData (void) const
|
||||
{
|
||||
return(m_fctrlFrmType == LRWPAN_MAC_DATA);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
LrWpanMacHeader::IsAcknowledgment (void) const
|
||||
{
|
||||
return(m_fctrlFrmType == LRWPAN_MAC_ACKNOWLEDGMENT);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
LrWpanMacHeader::IsCommand (void) const
|
||||
{
|
||||
@@ -787,9 +780,6 @@ LrWpanMacHeader::Deserialize (Buffer::Iterator start)
|
||||
return i.GetDistanceFrom (start);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
} //namespace ns3
|
||||
|
||||
|
||||
|
||||
@@ -54,17 +54,16 @@ class LrWpanMacHeader : public Header
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* The possible MAC types, see IEEE 802.15.4-2006, Table 79.
|
||||
*/
|
||||
enum LrWpanMacType
|
||||
{
|
||||
LRWPAN_MAC_BEACON = 0, //!< LRWPAN_MAC_BEACON
|
||||
LRWPAN_MAC_DATA = 1, //!< LRWPAN_MAC_DATA
|
||||
LRWPAN_MAC_ACKNOWLEDGMENT = 2,//!< LRWPAN_MAC_ACKNOWLEDGMENT
|
||||
LRWPAN_MAC_COMMAND = 3, //!< LRWPAN_MAC_COMMAND
|
||||
LRWPAN_MAC_RESERVED //!< LRWPAN_MAC_RESERVED
|
||||
LRWPAN_MAC_BEACON = 0, //!< LRWPAN_MAC_BEACON
|
||||
LRWPAN_MAC_DATA = 1, //!< LRWPAN_MAC_DATA
|
||||
LRWPAN_MAC_ACKNOWLEDGMENT = 2, //!< LRWPAN_MAC_ACKNOWLEDGMENT
|
||||
LRWPAN_MAC_COMMAND = 3, //!< LRWPAN_MAC_COMMAND
|
||||
LRWPAN_MAC_RESERVED //!< LRWPAN_MAC_RESERVED
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -113,37 +112,31 @@ public:
|
||||
* \return the Frame control field
|
||||
*/
|
||||
uint16_t GetFrameControl (void) const;
|
||||
|
||||
/**
|
||||
* Check if Security Enabled bit of Frame Control is enabled
|
||||
* \return true if Security Enabled bit is enabled
|
||||
*/
|
||||
bool IsSecEnable (void) const;
|
||||
|
||||
/**
|
||||
* Check if Frame Pending bit of Frame Control is enabled
|
||||
* \return true if Frame Pending bit is enabled
|
||||
*/
|
||||
bool IsFrmPend (void) const;
|
||||
|
||||
/**
|
||||
* Check if Ack. Request bit of Frame Control is enabled
|
||||
* \return true if Ack. Request bit is enabled
|
||||
*/
|
||||
bool IsAckReq (void) const;
|
||||
|
||||
/**
|
||||
* Check if PAN ID Compression bit of Frame Control is enabled
|
||||
* \return true if PAN ID Compression bit is enabled
|
||||
*/
|
||||
bool IsPanIdComp (void) const;
|
||||
|
||||
/**
|
||||
* Get the Reserved bits of Frame control field
|
||||
* \return the Reserved bits
|
||||
*/
|
||||
uint8_t GetFrmCtrlRes (void) const;
|
||||
|
||||
/**
|
||||
* Get the Dest. Addressing Mode of Frame control field
|
||||
* \return the Dest. Addressing Mode bits
|
||||
@@ -159,13 +152,11 @@ public:
|
||||
* \return the Source Addressing Mode bits
|
||||
*/
|
||||
uint8_t GetSrcAddrMode (void) const;
|
||||
|
||||
/**
|
||||
* Get the frame Sequence number
|
||||
* \return the sequence number
|
||||
*/
|
||||
uint8_t GetSeqNum (void) const;
|
||||
|
||||
/**
|
||||
* Get the Destination PAN ID
|
||||
* \return the Destination PAN ID
|
||||
@@ -196,7 +187,6 @@ public:
|
||||
* \return the Source Extended address
|
||||
*/
|
||||
Mac64Address GetExtSrcAddr (void) const;
|
||||
|
||||
/**
|
||||
* Get the Auxiliary Security Header - Security Control Octect
|
||||
* \return the Auxiliary Security Header - Security Control Octect
|
||||
@@ -223,7 +213,6 @@ public:
|
||||
* \return the Auxiliary Security Header - Security Control - Reserved bits
|
||||
*/
|
||||
uint8_t GetSecCtrlReserved (void) const;
|
||||
|
||||
/**
|
||||
* Get the Auxiliary Security Header - Key Identifier - Key Source (2 Octects)
|
||||
* \return the Auxiliary Security Header - Key Identifier - Key Source (2 Octects)
|
||||
@@ -239,7 +228,6 @@ public:
|
||||
* \return the Auxiliary Security Header - Key Identifier - Key Index
|
||||
*/
|
||||
uint8_t GetKeyIdIndex (void) const;
|
||||
|
||||
/**
|
||||
* Returns true if the header is a beacon
|
||||
* \return true if the header is a beacon
|
||||
@@ -260,59 +248,48 @@ public:
|
||||
* \return true if the header is a command
|
||||
*/
|
||||
bool IsCommand (void) const;
|
||||
|
||||
/**
|
||||
* Set the Frame Control field "Frame Type" bits
|
||||
* \param wpanMacType the frame type
|
||||
*/
|
||||
void SetType (enum LrWpanMacType wpanMacType);
|
||||
|
||||
/**
|
||||
* Set the whole Frame Control field
|
||||
* \param frameControl the Frame Control field
|
||||
*/
|
||||
void SetFrameControl (uint16_t frameControl);
|
||||
|
||||
/**
|
||||
* Set the Frame Control field "Security Enabled" bit to true
|
||||
*/
|
||||
void SetSecEnable (void);
|
||||
|
||||
/**
|
||||
* Set the Frame Control field "Security Enabled" bit to false
|
||||
*/
|
||||
void SetSecDisable (void);
|
||||
|
||||
/**
|
||||
* Set the Frame Control field "Frame Pending" bit to true
|
||||
*/
|
||||
void SetFrmPend (void);
|
||||
|
||||
/**
|
||||
* Set the Frame Control field "Frame Pending" bit to false
|
||||
*/
|
||||
void SetNoFrmPend (void);
|
||||
|
||||
/**
|
||||
* Set the Frame Control field "Ack. Request" bit to true
|
||||
*/
|
||||
void SetAckReq (void);
|
||||
|
||||
/**
|
||||
* Set the Frame Control field "Ack. Request" bit to false
|
||||
*/
|
||||
void SetNoAckReq (void);
|
||||
|
||||
/**
|
||||
* Set the Frame Control field "PAN ID Compression" bit to true
|
||||
*/
|
||||
void SetPanIdComp (void);
|
||||
|
||||
/**
|
||||
* Set the Frame Control field "PAN ID Compression" bit to false
|
||||
*/
|
||||
void SetNoPanIdComp (void);
|
||||
|
||||
/**
|
||||
* Set the Frame Control field "Reserved" bits
|
||||
* \param res reserved bits
|
||||
@@ -333,13 +310,11 @@ public:
|
||||
* \param addrMode Source address mode
|
||||
*/
|
||||
void SetSrcAddrMode (uint8_t addrMode);
|
||||
|
||||
/**
|
||||
* Set the Sequence number
|
||||
* \param seqNum sequence number
|
||||
*/
|
||||
void SetSeqNum (uint8_t seqNum);
|
||||
|
||||
/* The Source/Destination Addressing fields are only set if SrcAddrMode/DstAddrMode are set */
|
||||
/**
|
||||
* Set Source address fields
|
||||
@@ -377,7 +352,6 @@ public:
|
||||
* \param frmCntr the "Frame Counter" octect
|
||||
*/
|
||||
void SetFrmCounter (uint32_t frmCntr);
|
||||
|
||||
/**
|
||||
* Set the Security Control field "Security Level" bits (3 bits)
|
||||
* \param secLevel the "Security Level" bits
|
||||
@@ -388,13 +362,11 @@ public:
|
||||
* \param keyIdMode the "Key Identifier Mode" bits
|
||||
*/
|
||||
void SetKeyIdMode (uint8_t keyIdMode);
|
||||
|
||||
/**
|
||||
* Set the Security Control field "Reserved" bits (3 bits)
|
||||
* \param res the "Reserved" bits
|
||||
*/
|
||||
void SetSecCtrlReserved (uint8_t res);
|
||||
|
||||
/* Variable length will be dependent on Key Id Mode*/
|
||||
/**
|
||||
* Set the Key Index
|
||||
@@ -413,7 +385,6 @@ public:
|
||||
* \param keyIndex the Key index
|
||||
*/
|
||||
void SetKeyId (uint64_t keySrc, uint8_t keyIndex);
|
||||
|
||||
/**
|
||||
* \brief Get the type ID.
|
||||
* \return the object TypeId
|
||||
|
||||
240
src/lr-wpan/model/lr-wpan-mac-pl-headers.cc
Normal file
240
src/lr-wpan/model/lr-wpan-mac-pl-headers.cc
Normal file
@@ -0,0 +1,240 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2020 Ritsumeikan University, Shiga, Japan.
|
||||
*
|
||||
* 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: Alberto Gallegos Ramonet <ramonet@fc.ritsumei.ac.jp>
|
||||
*/
|
||||
|
||||
#include "lr-wpan-mac-pl-headers.h"
|
||||
#include <ns3/simulator.h>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/***********************************************************
|
||||
* Beacon MAC Payload
|
||||
***********************************************************/
|
||||
|
||||
BeaconPayloadHeader::BeaconPayloadHeader ()
|
||||
{
|
||||
}
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (BeaconPayloadHeader);
|
||||
|
||||
TypeId
|
||||
BeaconPayloadHeader::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::BeaconPayloadHeader")
|
||||
.SetParent<Header> ()
|
||||
.SetGroupName ("LrWpan")
|
||||
.AddConstructor<BeaconPayloadHeader> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
TypeId
|
||||
BeaconPayloadHeader::GetInstanceTypeId (void) const
|
||||
{
|
||||
return GetTypeId ();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
BeaconPayloadHeader::GetSerializedSize (void) const
|
||||
{
|
||||
uint32_t size = 0;
|
||||
size += m_superframeField.GetSerializedSize ();
|
||||
size += m_gtsFields.GetSerializedSize ();
|
||||
size += m_pndAddrFields.GetSerializedSize ();
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void
|
||||
BeaconPayloadHeader::Serialize (Buffer::Iterator start) const
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
i = m_superframeField.Serialize (i);
|
||||
i = m_gtsFields.Serialize (i);
|
||||
i = m_pndAddrFields.Serialize (i);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
BeaconPayloadHeader::Deserialize (Buffer::Iterator start)
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
i = m_superframeField.Deserialize (i);
|
||||
i = m_gtsFields.Deserialize (i);
|
||||
i = m_pndAddrFields.Deserialize (i);
|
||||
|
||||
return i.GetDistanceFrom (start);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BeaconPayloadHeader::Print (std::ostream &os) const
|
||||
{
|
||||
os << "| Superframe Spec Field | = " << m_superframeField
|
||||
<< "| GTS Spec Field | = " << m_gtsFields.GetGtsSpecField ()
|
||||
<< "| Pending Spec Field| =" << m_pndAddrFields.GetPndAddrSpecField ();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BeaconPayloadHeader::SetSuperframeSpecField (SuperframeField sf)
|
||||
{
|
||||
m_superframeField = sf;
|
||||
}
|
||||
|
||||
void
|
||||
BeaconPayloadHeader::SetGtsFields (GtsFields gtsFields)
|
||||
{
|
||||
m_gtsFields = gtsFields;
|
||||
}
|
||||
|
||||
void
|
||||
BeaconPayloadHeader::SetPndAddrFields (PendingAddrFields pndAddrFields)
|
||||
{
|
||||
m_pndAddrFields = pndAddrFields;
|
||||
}
|
||||
|
||||
SuperframeField
|
||||
BeaconPayloadHeader::GetSuperframeSpecField (void) const
|
||||
{
|
||||
return m_superframeField;
|
||||
}
|
||||
|
||||
GtsFields
|
||||
BeaconPayloadHeader::GetGtsFields (void) const
|
||||
{
|
||||
return m_gtsFields;
|
||||
}
|
||||
|
||||
PendingAddrFields
|
||||
BeaconPayloadHeader::GetPndAddrFields (void) const
|
||||
{
|
||||
return m_pndAddrFields;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************
|
||||
* Command MAC Payload
|
||||
***********************************************************/
|
||||
|
||||
CommandPayloadHeader::CommandPayloadHeader ()
|
||||
{
|
||||
SetCommandFrameType (CMD_RESERVED);
|
||||
}
|
||||
|
||||
|
||||
CommandPayloadHeader::CommandPayloadHeader (enum MacCommand macCmd)
|
||||
{
|
||||
SetCommandFrameType (macCmd);
|
||||
}
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (CommandPayloadHeader);
|
||||
|
||||
TypeId
|
||||
CommandPayloadHeader::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::CommandPayloadHeader")
|
||||
.SetParent<Header> ()
|
||||
.SetGroupName ("LrWpan")
|
||||
.AddConstructor<CommandPayloadHeader> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
TypeId
|
||||
CommandPayloadHeader::GetInstanceTypeId (void) const
|
||||
{
|
||||
return GetTypeId ();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
CommandPayloadHeader::GetSerializedSize (void) const
|
||||
{
|
||||
uint32_t size = 1;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void
|
||||
CommandPayloadHeader::Serialize (Buffer::Iterator start) const
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
i.WriteU8 (m_cmdFrameId);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
CommandPayloadHeader::Deserialize (Buffer::Iterator start)
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
m_cmdFrameId = i.ReadU8 ();
|
||||
|
||||
return i.GetDistanceFrom (start);
|
||||
}
|
||||
|
||||
void
|
||||
CommandPayloadHeader::Print (std::ostream &os) const
|
||||
{
|
||||
os << "| MAC Command Frame ID | = " << (uint32_t) m_cmdFrameId;
|
||||
}
|
||||
|
||||
void
|
||||
CommandPayloadHeader::SetCommandFrameType (MacCommand macCommand)
|
||||
{
|
||||
m_cmdFrameId = macCommand;
|
||||
}
|
||||
|
||||
|
||||
CommandPayloadHeader::MacCommand
|
||||
CommandPayloadHeader::GetCommandFrameType (void) const
|
||||
{
|
||||
switch (m_cmdFrameId)
|
||||
{
|
||||
case 0x01:
|
||||
return ASSOCIATION_REQ;
|
||||
break;
|
||||
case 0x02:
|
||||
return ASSOCIATION_RESP;
|
||||
break;
|
||||
case 0x03:
|
||||
return DISASSOCIATION_NOTIF;
|
||||
break;
|
||||
case 0x04:
|
||||
return DATA_REQ;
|
||||
break;
|
||||
case 0x05:
|
||||
return PANID_CONFLICT;
|
||||
break;
|
||||
case 0x06:
|
||||
return ORPHAN_NOTIF;
|
||||
break;
|
||||
case 0x07:
|
||||
return BEACON_REQ;
|
||||
break;
|
||||
case 0x08:
|
||||
return COOR_REALIGN;
|
||||
break;
|
||||
case 0x09:
|
||||
return GTS_REQ;
|
||||
break;
|
||||
default:
|
||||
return CMD_RESERVED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // ns3 namespace
|
||||
165
src/lr-wpan/model/lr-wpan-mac-pl-headers.h
Normal file
165
src/lr-wpan/model/lr-wpan-mac-pl-headers.h
Normal file
@@ -0,0 +1,165 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2019 Ritsumeikan University, Shiga, Japan.
|
||||
*
|
||||
* 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: Alberto Gallegos Ramonet <ramonet@fc.ritsumei.ac.jp>
|
||||
*/
|
||||
|
||||
#ifndef LR_WPAN_MAC_PL_HEADERS_H
|
||||
#define LR_WPAN_MAC_PL_HEADERS_H
|
||||
|
||||
#include <ns3/header.h>
|
||||
#include <ns3/mac16-address.h>
|
||||
#include <ns3/mac64-address.h>
|
||||
#include "lr-wpan-fields.h"
|
||||
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* \ingroup lr-wpan
|
||||
* Implements the header for the MAC payload beacon frame according to
|
||||
* the IEEE 802.15.4-2011 Std.
|
||||
*/
|
||||
class BeaconPayloadHeader : public Header
|
||||
{
|
||||
|
||||
public:
|
||||
BeaconPayloadHeader ();
|
||||
/**
|
||||
* \brief Get the type ID.
|
||||
* \return the object TypeId
|
||||
*/
|
||||
static TypeId GetTypeId (void);
|
||||
TypeId GetInstanceTypeId (void) const;
|
||||
uint32_t GetSerializedSize (void) const;
|
||||
virtual void Serialize (Buffer::Iterator start) const;
|
||||
uint32_t Deserialize (Buffer::Iterator start);
|
||||
void Print (std::ostream &os) const;
|
||||
/**
|
||||
* Set the superframe specification field to the beacon payload header.
|
||||
* \param sfrmField The superframe specification field
|
||||
*/
|
||||
void SetSuperframeSpecField (SuperframeField sfrmField);
|
||||
/**
|
||||
* Set the superframe Guaranteed Time Slot (GTS) fields to the beacon payload header.
|
||||
* \param gtsFields The GTS fields.
|
||||
*/
|
||||
void SetGtsFields (GtsFields gtsFields);
|
||||
/**
|
||||
* Set the superframe Pending Address fields to the beacon payload header.
|
||||
* \param pndAddrFields The Pending Address fields.
|
||||
*/
|
||||
void SetPndAddrFields (PendingAddrFields pndAddrFields);
|
||||
/**
|
||||
* Get the superframe specification field from the beacon payload header.
|
||||
* \return The superframe specification field
|
||||
*/
|
||||
SuperframeField GetSuperframeSpecField (void) const;
|
||||
/**
|
||||
* Get the Guaranteed Time Slots (GTS) fields from the beacon payload header.
|
||||
* \return The GTS fields.
|
||||
*/
|
||||
GtsFields GetGtsFields (void) const;
|
||||
/***
|
||||
* Get the pending address fields from the beacon payload header.
|
||||
* \return The Pending Address fields.
|
||||
*/
|
||||
PendingAddrFields GetPndAddrFields (void) const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Superframe Specification Field
|
||||
*/
|
||||
SuperframeField m_superframeField;
|
||||
/**
|
||||
* GTS Fields
|
||||
*/
|
||||
GtsFields m_gtsFields;
|
||||
/**
|
||||
* Pending Address Fields
|
||||
*/
|
||||
PendingAddrFields m_pndAddrFields;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \ingroup lr-wpan
|
||||
* Implements the header for the MAC payload command frame according to
|
||||
* the IEEE 802.15.4-2011 Std.
|
||||
*/
|
||||
class CommandPayloadHeader : public Header
|
||||
{
|
||||
|
||||
public:
|
||||
/**
|
||||
* The MAC command frames.
|
||||
* See IEEE 802.15.4-2011, Table 5
|
||||
*/
|
||||
enum MacCommand
|
||||
{
|
||||
ASSOCIATION_REQ = 0x01, //!< Association request (RFD true: Tx)
|
||||
ASSOCIATION_RESP = 0x02, //!< Association response (RFD true: Rx)
|
||||
DISASSOCIATION_NOTIF = 0x03, //!< Disassociation notification (RFD true: TX, Rx)
|
||||
DATA_REQ = 0x04, //!< Data Request (RFD true: Tx)
|
||||
PANID_CONFLICT = 0x05, //!< Pan ID conflict notification (RFD true: Tx)
|
||||
ORPHAN_NOTIF = 0x06, //!< Orphan Notification (RFD true: Tx)
|
||||
BEACON_REQ = 0x07, //!< Beacon Request (RFD true: none )
|
||||
COOR_REALIGN = 0x08, //!< Coordinator Realignment (RFD true: Rx)
|
||||
GTS_REQ = 0x09, //!< GTS Request (RFD true: none)
|
||||
CMD_RESERVED = 0xff //!< Reserved
|
||||
};
|
||||
|
||||
|
||||
CommandPayloadHeader (void);
|
||||
/**
|
||||
* Constructor
|
||||
* \param macCmd the command type of this command header
|
||||
*/
|
||||
CommandPayloadHeader (enum MacCommand macCmd);
|
||||
/**
|
||||
* \brief Get the type ID.
|
||||
* \return the object TypeId
|
||||
*/
|
||||
static TypeId GetTypeId (void);
|
||||
TypeId GetInstanceTypeId (void) const;
|
||||
uint32_t GetSerializedSize (void) const;
|
||||
virtual void Serialize (Buffer::Iterator start) const;
|
||||
uint32_t Deserialize (Buffer::Iterator start);
|
||||
void Print (std::ostream &os) const;
|
||||
|
||||
/**
|
||||
* Set the command frame type
|
||||
*/
|
||||
void SetCommandFrameType (MacCommand macCmd);
|
||||
/**
|
||||
* Get the command frame type
|
||||
*/
|
||||
MacCommand GetCommandFrameType (void) const;
|
||||
|
||||
|
||||
private:
|
||||
/** The command Frame Identifier*/
|
||||
uint8_t m_cmdFrameId;
|
||||
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif /* LR_WPAN_MAC_PL_HEADERS_H */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
283
src/lr-wpan/test/lr-wpan-ifs-test.cc
Normal file
283
src/lr-wpan/test/lr-wpan-ifs-test.cc
Normal file
@@ -0,0 +1,283 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2019 Ritsumeikan University, Shiga, Japan
|
||||
*
|
||||
* 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:
|
||||
* Alberto Gallegos Ramonet <ramonet@fc.ritsumei.ac.jp>
|
||||
*/
|
||||
|
||||
#include <ns3/log.h>
|
||||
#include <ns3/core-module.h>
|
||||
#include <ns3/lr-wpan-module.h>
|
||||
#include <ns3/propagation-loss-model.h>
|
||||
#include <ns3/propagation-delay-model.h>
|
||||
#include <ns3/simulator.h>
|
||||
#include <ns3/single-model-spectrum-channel.h>
|
||||
#include <ns3/constant-position-mobility-model.h>
|
||||
#include <ns3/packet.h>
|
||||
#include "ns3/rng-seed-manager.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("lr-wpan-ifs-test");
|
||||
|
||||
/**
|
||||
* \ingroup lr-wpan-test
|
||||
* \ingroup tests
|
||||
*
|
||||
* \brief LrWpan Dataframe transmission with Interframe Space
|
||||
*/
|
||||
class LrWpanDataIfsTestCase : public TestCase
|
||||
{
|
||||
public:
|
||||
LrWpanDataIfsTestCase ();
|
||||
virtual ~LrWpanDataIfsTestCase ();
|
||||
|
||||
|
||||
|
||||
private:
|
||||
static void DataConfirm (LrWpanDataIfsTestCase *testcase,
|
||||
Ptr<LrWpanNetDevice> dev,
|
||||
McpsDataConfirmParams params);
|
||||
|
||||
static void DataReceived (LrWpanDataIfsTestCase *testcase,
|
||||
Ptr<LrWpanNetDevice> dev,
|
||||
Ptr<const Packet>);
|
||||
|
||||
static void MacState (LrWpanDataIfsTestCase *testcase,
|
||||
Ptr<LrWpanNetDevice> dev,
|
||||
LrWpanMacState oldValue,
|
||||
LrWpanMacState newValue);
|
||||
|
||||
|
||||
|
||||
virtual void DoRun (void);
|
||||
Time m_lastTxTime; //!< The time of the last transmitted packet
|
||||
Time m_ackRxTime; //!< The time of the received acknoledgment.
|
||||
Time m_endIfs; //!< The time where the Interframe Space ended.
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
LrWpanDataIfsTestCase::LrWpanDataIfsTestCase ()
|
||||
: TestCase ("Lrwpan: IFS with and without ACK")
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
LrWpanDataIfsTestCase::~LrWpanDataIfsTestCase ()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
LrWpanDataIfsTestCase::DataConfirm (LrWpanDataIfsTestCase *testcase, Ptr<LrWpanNetDevice> dev, McpsDataConfirmParams params)
|
||||
{
|
||||
std::cout << Simulator::Now ().GetSeconds () << " | Dataframe Sent\n";
|
||||
testcase->m_lastTxTime = Simulator::Now ();
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
LrWpanDataIfsTestCase::DataReceived (LrWpanDataIfsTestCase *testcase,Ptr<LrWpanNetDevice> dev, Ptr<const Packet> p)
|
||||
{
|
||||
Ptr<Packet> RxPacket = p->Copy ();
|
||||
LrWpanMacHeader receivedMacHdr;
|
||||
RxPacket->RemoveHeader (receivedMacHdr);
|
||||
|
||||
NS_ASSERT (receivedMacHdr.IsAcknowledgment ());
|
||||
testcase->m_ackRxTime = Simulator::Now ();
|
||||
|
||||
std::cout << Simulator::Now ().GetSeconds () << " | ACK received\n";
|
||||
}
|
||||
|
||||
void
|
||||
LrWpanDataIfsTestCase::MacState (LrWpanDataIfsTestCase *testcase, Ptr<LrWpanNetDevice> dev,LrWpanMacState oldValue, LrWpanMacState newValue)
|
||||
{
|
||||
// Check the time after the MAC layer go back to IDLE state
|
||||
// (i.e. after the packet has been sent and the IFS is finished)
|
||||
|
||||
if (newValue == LrWpanMacState::MAC_IDLE)
|
||||
{
|
||||
testcase->m_endIfs = Simulator::Now ();
|
||||
std::cout << Simulator::Now ().GetSeconds () << " | MAC layer is free\n";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
LrWpanDataIfsTestCase::DoRun ()
|
||||
{
|
||||
// Test of Interframe Spaces (IFS)
|
||||
|
||||
// The MAC layer needs a finite amount of time to process the data received from the PHY.
|
||||
// To allow this, to successive transmitted frames must be separated for at least one IFS.
|
||||
// The IFS size depends on the transmitted frame. This test verifies that the IFS is correctly
|
||||
// implemented and its size correspond to the situations described by the standard.
|
||||
// For more info see IEEE 802.15.4-2011 Section 5.1.1.3
|
||||
|
||||
|
||||
// Create 2 nodes, and a NetDevice for each one
|
||||
Ptr<Node> n0 = CreateObject <Node> ();
|
||||
Ptr<Node> n1 = CreateObject <Node> ();
|
||||
|
||||
Ptr<LrWpanNetDevice> dev0 = CreateObject<LrWpanNetDevice> ();
|
||||
Ptr<LrWpanNetDevice> dev1 = CreateObject<LrWpanNetDevice> ();
|
||||
|
||||
dev0->SetAddress (Mac16Address ("00:01"));
|
||||
dev1->SetAddress (Mac16Address ("00:02"));
|
||||
|
||||
// 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);
|
||||
|
||||
// To complete configuration, a LrWpanNetDevice must be added to a node
|
||||
n0->AddDevice (dev0);
|
||||
n1->AddDevice (dev1);
|
||||
|
||||
// Connect to trace files in the MAC layer
|
||||
dev0->GetMac ()->TraceConnectWithoutContext ("MacStateValue", MakeBoundCallback (&LrWpanDataIfsTestCase::MacState, this, dev0));
|
||||
dev0->GetMac ()->TraceConnectWithoutContext ("MacRx", MakeBoundCallback (&LrWpanDataIfsTestCase::DataReceived, this, dev0));
|
||||
|
||||
Ptr<ConstantPositionMobilityModel> sender0Mobility = CreateObject<ConstantPositionMobilityModel> ();
|
||||
sender0Mobility->SetPosition (Vector (0,0,0));
|
||||
dev0->GetPhy ()->SetMobility (sender0Mobility);
|
||||
Ptr<ConstantPositionMobilityModel> sender1Mobility = CreateObject<ConstantPositionMobilityModel> ();
|
||||
// Configure position 10 m distance
|
||||
sender1Mobility->SetPosition (Vector (0,10,0));
|
||||
dev1->GetPhy ()->SetMobility (sender1Mobility);
|
||||
|
||||
McpsDataConfirmCallback cb0;
|
||||
cb0 = MakeBoundCallback (&LrWpanDataIfsTestCase::DataConfirm, this, dev0);
|
||||
dev0->GetMac ()->SetMcpsDataConfirmCallback (cb0);
|
||||
|
||||
Ptr<Packet> p0 = Create<Packet> (2);
|
||||
McpsDataRequestParams params;
|
||||
params.m_dstPanId = 0;
|
||||
|
||||
params.m_srcAddrMode = SHORT_ADDR;
|
||||
params.m_dstAddrMode = SHORT_ADDR;
|
||||
params.m_dstAddr = Mac16Address ("00:02");
|
||||
params.m_msduHandle = 0;
|
||||
|
||||
Time ifsSize;
|
||||
|
||||
//////////////////////// SIFS ///////////////////////////
|
||||
|
||||
Simulator::ScheduleWithContext (1, Seconds (0.0),
|
||||
&LrWpanMac::McpsDataRequest,
|
||||
dev0->GetMac (), params, p0);
|
||||
|
||||
|
||||
Simulator::Run ();
|
||||
|
||||
// MPDU = MAC header (11 bytes) + MSDU (2 bytes)+ MAC trailer (2 bytes) = 15)
|
||||
// MPDU (15 bytes) < 18 bytes therefore IFS = SIFS
|
||||
// SIFS = 12 symbols (192 Microseconds on a 2.4Ghz O-QPSK PHY)
|
||||
ifsSize = m_endIfs - m_lastTxTime;
|
||||
NS_TEST_EXPECT_MSG_EQ (ifsSize, Time (MicroSeconds (192)), "Wrong Short InterFrame Space (SIFS) Size after dataframe Tx");
|
||||
|
||||
//////////////////////// LIFS ///////////////////////////
|
||||
|
||||
p0 = Create<Packet> (6);
|
||||
|
||||
Simulator::ScheduleWithContext (1, Seconds (0.0),
|
||||
&LrWpanMac::McpsDataRequest,
|
||||
dev0->GetMac (), params, p0);
|
||||
|
||||
|
||||
Simulator::Run ();
|
||||
|
||||
// MPDU = MAC header (11 bytes) + MSDU (6 bytes)+ MAC trailer (2 bytes) = 19)
|
||||
// MPDU (19 bytes) > 18 bytes therefore IFS = LIFS
|
||||
// LIFS = 20 symbols (640 Microseconds on a 2.4Ghz O-QPSK PHY)
|
||||
ifsSize = m_endIfs - m_lastTxTime;
|
||||
NS_TEST_EXPECT_MSG_EQ (ifsSize, Time (MicroSeconds (640)), "Wrong Long InterFrame Space (LIFS) Size after dataframe Tx");
|
||||
|
||||
//////////////////////// SIFS after ACK //////////////////
|
||||
|
||||
params.m_txOptions = TX_OPTION_ACK;
|
||||
p0 = Create<Packet> (2);
|
||||
|
||||
Simulator::ScheduleWithContext (1, Seconds (0.0),
|
||||
&LrWpanMac::McpsDataRequest,
|
||||
dev0->GetMac (), params, p0);
|
||||
|
||||
Simulator::Run ();
|
||||
|
||||
// MPDU = MAC header (11 bytes) + MSDU (2 bytes)+ MAC trailer (2 bytes) = 15)
|
||||
// MPDU (15 bytes) < 18 bytes therefore IFS = SIFS
|
||||
// SIFS = 12 symbols (192 Microseconds on a 2.4Ghz O-QPSK PHY)
|
||||
ifsSize = m_endIfs - m_ackRxTime;
|
||||
NS_TEST_EXPECT_MSG_EQ (ifsSize, Time (MicroSeconds (192)), "Wrong Short InterFrame Space (SIFS) Size after ACK Rx");
|
||||
|
||||
//////////////////////// LIFS after ACK //////////////////
|
||||
|
||||
params.m_txOptions = TX_OPTION_ACK;
|
||||
p0 = Create<Packet> (6);
|
||||
|
||||
Simulator::ScheduleWithContext (1, Seconds (0.0),
|
||||
&LrWpanMac::McpsDataRequest,
|
||||
dev0->GetMac (), params, p0);
|
||||
|
||||
|
||||
Simulator::Run ();
|
||||
|
||||
// MPDU = MAC header (11 bytes) + MSDU (6 bytes)+ MAC trailer (2 bytes) = 19)
|
||||
// MPDU (19 bytes) > 18 bytes therefore IFS = LIFS
|
||||
// LIFS = 20 symbols (640 Microseconds on a 2.4Ghz O-QPSK PHY)
|
||||
ifsSize = m_endIfs - m_ackRxTime;
|
||||
NS_TEST_EXPECT_MSG_EQ (ifsSize, Time (MicroSeconds (640)), "Wrong Long InterFrame Space (LIFS) Size after ACK Rx");
|
||||
|
||||
Simulator::Destroy ();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \ingroup lr-wpan-test
|
||||
* \ingroup tests
|
||||
*
|
||||
* \brief LrWpan IFS TestSuite
|
||||
*/
|
||||
|
||||
class LrWpanIfsTestSuite : public TestSuite
|
||||
{
|
||||
public:
|
||||
LrWpanIfsTestSuite ();
|
||||
};
|
||||
|
||||
LrWpanIfsTestSuite::LrWpanIfsTestSuite ()
|
||||
: TestSuite ("lr-wpan-ifs-test", UNIT)
|
||||
{
|
||||
AddTestCase (new LrWpanDataIfsTestCase, TestCase::QUICK);
|
||||
}
|
||||
|
||||
static LrWpanIfsTestSuite lrWpanIfsTestSuite; //!< Static variable for test initialization
|
||||
|
||||
|
||||
|
||||
|
||||
342
src/lr-wpan/test/lr-wpan-slotted-csmaca-test.cc
Normal file
342
src/lr-wpan/test/lr-wpan-slotted-csmaca-test.cc
Normal file
@@ -0,0 +1,342 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2019 Ritsumeikan University, Shiga, Japan
|
||||
*
|
||||
* 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:
|
||||
* Alberto Gallegos Ramonet <ramonet@fc.ritsumei.ac.jp>
|
||||
*/
|
||||
|
||||
#include <ns3/log.h>
|
||||
#include <ns3/core-module.h>
|
||||
#include <ns3/lr-wpan-module.h>
|
||||
#include <ns3/propagation-loss-model.h>
|
||||
#include <ns3/propagation-delay-model.h>
|
||||
#include <ns3/simulator.h>
|
||||
#include <ns3/single-model-spectrum-channel.h>
|
||||
#include <ns3/constant-position-mobility-model.h>
|
||||
#include <ns3/packet.h>
|
||||
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("lr-wpan-slotted-csma-test");
|
||||
|
||||
/**
|
||||
* \ingroup lr-wpan-test
|
||||
* \ingroup tests
|
||||
*
|
||||
* \brief Test the correct allocation of DIRECT transmissions in the
|
||||
* contention access period (CAP) of the superframe
|
||||
* (Slotted CSMA-CA algorithm).
|
||||
*/
|
||||
class LrWpanSlottedCsmacaTestCase : public TestCase
|
||||
{
|
||||
public:
|
||||
LrWpanSlottedCsmacaTestCase ();
|
||||
virtual ~LrWpanSlottedCsmacaTestCase ();
|
||||
|
||||
|
||||
|
||||
private:
|
||||
/**
|
||||
* \brief Function called when McpsDataConfirm is hit.
|
||||
* \param testcase The TestCase.
|
||||
* \param dev The LrWpanNetDevice.
|
||||
* \param params The McpsDataConfirm parameters.
|
||||
*/
|
||||
static void TransEndIndication (LrWpanSlottedCsmacaTestCase *testcase,
|
||||
Ptr<LrWpanNetDevice> dev,
|
||||
McpsDataConfirmParams params);
|
||||
/**
|
||||
* \brief Function called when McpsDataIndication is hit.
|
||||
* \param testcase The TestCase.
|
||||
* \param dev The LrWpanNetDevice.
|
||||
* \param params The McpsDataIndication parameters.
|
||||
* \param p The received packet.
|
||||
*/
|
||||
static void DataIndicationCoordinator (LrWpanSlottedCsmacaTestCase *testcase,
|
||||
Ptr<LrWpanNetDevice> dev,
|
||||
McpsDataIndicationParams params,
|
||||
Ptr<Packet> p);
|
||||
/**
|
||||
* \brief Function called when MlmeStartConfirm is hit.
|
||||
* \param testcase The TestCase.
|
||||
* \param dev The LrWpanNetDevice.
|
||||
* \param params The MlmeStartConfirm parameters.
|
||||
*/
|
||||
static void StartConfirm (LrWpanSlottedCsmacaTestCase *testcase,
|
||||
Ptr<LrWpanNetDevice> dev,
|
||||
MlmeStartConfirmParams params);
|
||||
|
||||
/**
|
||||
* \brief Function called on each Superframe status change (CAP|CFP|INACTIVE).
|
||||
* \param testcase The TestCase.
|
||||
* \param dev The LrWpanNetDevice.
|
||||
* \param oldValue The previous superframe status.
|
||||
* \param newValue THe new superframe status.
|
||||
*/
|
||||
static void IncomingSuperframeStatus (LrWpanSlottedCsmacaTestCase *testcase,
|
||||
Ptr<LrWpanNetDevice> dev,
|
||||
SuperframeStatus oldValue,
|
||||
SuperframeStatus newValue);
|
||||
|
||||
/**
|
||||
* \brief Function called to indicated the calculated transaction cost in slotted CSMA-CA
|
||||
* \param testcase The TestCase.
|
||||
* \param dev The LrWpanNetDevice.
|
||||
* \param trans The transaction cost in symbols.
|
||||
*/
|
||||
static void TransactionCost (LrWpanSlottedCsmacaTestCase *testcase,
|
||||
Ptr<LrWpanNetDevice> dev,
|
||||
uint32_t trans);
|
||||
|
||||
virtual void DoRun (void);
|
||||
|
||||
Time m_startCap; //!< The time of the start of the Contention Access Period (CAP).
|
||||
Time m_apBoundary; //!< Indicates the time after the calculation of the transaction cost (A boundary of an Active Period in the CAP)
|
||||
Time m_sentTime; //!< Indicates the time after a successful transmission.
|
||||
uint32_t m_transCost; //!< The current transaction cost in symbols.
|
||||
};
|
||||
|
||||
|
||||
LrWpanSlottedCsmacaTestCase::LrWpanSlottedCsmacaTestCase ()
|
||||
: TestCase ("Lrwpan: Slotted CSMA-CA test")
|
||||
{
|
||||
m_transCost = 0;
|
||||
}
|
||||
|
||||
LrWpanSlottedCsmacaTestCase::~LrWpanSlottedCsmacaTestCase ()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
LrWpanSlottedCsmacaTestCase::TransEndIndication (LrWpanSlottedCsmacaTestCase *testcase, Ptr<LrWpanNetDevice> dev, McpsDataConfirmParams params)
|
||||
{
|
||||
// In the case of transmissions with the acknowledgment flag activated, the transmission is only
|
||||
// successful if the acknowledgment was received.
|
||||
if (params.m_status == LrWpanMcpsDataConfirmStatus::IEEE_802_15_4_SUCCESS)
|
||||
{
|
||||
NS_LOG_UNCOND (Simulator::Now ().GetSeconds () << "s Transmission successfully sent");
|
||||
testcase->m_sentTime = Simulator::Now ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LrWpanSlottedCsmacaTestCase::DataIndicationCoordinator (LrWpanSlottedCsmacaTestCase *testcase, Ptr<LrWpanNetDevice> dev, McpsDataIndicationParams params, Ptr<Packet> p)
|
||||
{
|
||||
NS_LOG_UNCOND (Simulator::Now ().GetSeconds () << "s Coordinator Received DATA packet (size " << p->GetSize () << " bytes)");
|
||||
}
|
||||
|
||||
void
|
||||
LrWpanSlottedCsmacaTestCase::StartConfirm (LrWpanSlottedCsmacaTestCase *testcase, Ptr<LrWpanNetDevice> dev, MlmeStartConfirmParams params)
|
||||
{
|
||||
NS_LOG_UNCOND (Simulator::Now ().GetSeconds () << "s Beacon Sent");
|
||||
}
|
||||
|
||||
void
|
||||
LrWpanSlottedCsmacaTestCase::IncomingSuperframeStatus (LrWpanSlottedCsmacaTestCase *testcase, Ptr<LrWpanNetDevice> dev,SuperframeStatus oldValue, SuperframeStatus newValue)
|
||||
{
|
||||
if (newValue == SuperframeStatus::CAP)
|
||||
{
|
||||
testcase->m_startCap = Simulator::Now ();
|
||||
NS_LOG_UNCOND (Simulator::Now ().GetSeconds () << "s Incoming superframe CAP starts");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LrWpanSlottedCsmacaTestCase::TransactionCost (LrWpanSlottedCsmacaTestCase *testcase, Ptr<LrWpanNetDevice> dev, uint32_t trans)
|
||||
{
|
||||
testcase->m_apBoundary = Simulator::Now ();
|
||||
testcase->m_transCost = trans;
|
||||
NS_LOG_UNCOND (Simulator::Now ().GetSeconds () << "s Transaction Cost is:" << trans);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void
|
||||
LrWpanSlottedCsmacaTestCase::DoRun ()
|
||||
{
|
||||
// Create 2 nodes, and a NetDevice for each one
|
||||
Ptr<Node> n0 = CreateObject <Node> ();
|
||||
Ptr<Node> n1 = CreateObject <Node> ();
|
||||
|
||||
Ptr<LrWpanNetDevice> dev0 = CreateObject<LrWpanNetDevice> ();
|
||||
Ptr<LrWpanNetDevice> dev1 = CreateObject<LrWpanNetDevice> ();
|
||||
|
||||
dev0->SetAddress (Mac16Address ("00:01"));
|
||||
dev1->SetAddress (Mac16Address ("00:02"));
|
||||
|
||||
// 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);
|
||||
|
||||
// To complete configuration, a LrWpanNetDevice must be added to a node
|
||||
n0->AddDevice (dev0);
|
||||
n1->AddDevice (dev1);
|
||||
|
||||
|
||||
// Set mobility
|
||||
Ptr<ConstantPositionMobilityModel> sender0Mobility = CreateObject<ConstantPositionMobilityModel> ();
|
||||
sender0Mobility->SetPosition (Vector (0,0,0));
|
||||
dev0->GetPhy ()->SetMobility (sender0Mobility);
|
||||
Ptr<ConstantPositionMobilityModel> sender1Mobility = CreateObject<ConstantPositionMobilityModel> ();
|
||||
|
||||
sender1Mobility->SetPosition (Vector (0,10,0));
|
||||
dev1->GetPhy ()->SetMobility (sender1Mobility);
|
||||
|
||||
|
||||
// MAC layer and CSMA-CA callback hooks
|
||||
|
||||
MlmeStartConfirmCallback cb0;
|
||||
cb0 = MakeBoundCallback (&LrWpanSlottedCsmacaTestCase::StartConfirm, this, dev0);
|
||||
dev0->GetMac ()->SetMlmeStartConfirmCallback (cb0);
|
||||
|
||||
McpsDataConfirmCallback cb1;
|
||||
cb1 = MakeBoundCallback (&LrWpanSlottedCsmacaTestCase::TransEndIndication, this, dev1);
|
||||
dev1->GetMac ()->SetMcpsDataConfirmCallback (cb1);
|
||||
|
||||
LrWpanMacTransCostCallback cb2;
|
||||
cb2 = MakeBoundCallback (&LrWpanSlottedCsmacaTestCase::TransactionCost, this, dev1);
|
||||
dev1->GetCsmaCa ()->SetLrWpanMacTransCostCallback (cb2);
|
||||
|
||||
McpsDataIndicationCallback cb5;
|
||||
cb5 = MakeBoundCallback (&LrWpanSlottedCsmacaTestCase::DataIndicationCoordinator, this, dev0);
|
||||
dev0->GetMac ()->SetMcpsDataIndicationCallback (cb5);
|
||||
|
||||
|
||||
// Connect to trace in the MAC layer
|
||||
dev1->GetMac ()->TraceConnectWithoutContext ("MacIncSuperframeStatus",
|
||||
MakeBoundCallback (&LrWpanSlottedCsmacaTestCase::IncomingSuperframeStatus, this, dev1));
|
||||
|
||||
|
||||
// Manual Device Association
|
||||
// Note: We manually associate dev1 device to a PAN coordinator
|
||||
// because currently there is no automatic association behavior;
|
||||
// The PAN COORDINATOR does not need to associate, set
|
||||
// PAN Id or its own coordinator id, these are set
|
||||
// by the MLME-start.request primitive when used.
|
||||
|
||||
dev1->GetMac ()->SetPanId (5);
|
||||
dev1->GetMac ()->SetAssociatedCoor (Mac16Address ("00:01"));
|
||||
|
||||
|
||||
// Dev0 sets the start time for beacons
|
||||
MlmeStartRequestParams params;
|
||||
params.m_panCoor = true;
|
||||
params.m_PanId = 5;
|
||||
params.m_bcnOrd = 14;
|
||||
params.m_sfrmOrd = 6;
|
||||
Simulator::ScheduleWithContext (1, Seconds (2.0),
|
||||
&LrWpanMac::MlmeStartRequest,
|
||||
dev0->GetMac (), params);
|
||||
|
||||
// Dev1 sets the transmission of data packet
|
||||
|
||||
Ptr<Packet> p1 = Create<Packet> (5); // 5 bytes of dummy data
|
||||
McpsDataRequestParams params2;
|
||||
params2.m_dstPanId = 5;
|
||||
params2.m_srcAddrMode = SHORT_ADDR;
|
||||
params2.m_dstAddrMode = SHORT_ADDR;
|
||||
params2.m_dstAddr = Mac16Address ("00:01");
|
||||
params2.m_msduHandle = 0;
|
||||
|
||||
|
||||
// Beacon-enabled | Device to Coordinator | Direct transmission
|
||||
Simulator::ScheduleWithContext (1, Seconds (2.93),
|
||||
&LrWpanMac::McpsDataRequest,
|
||||
dev1->GetMac (), params2, p1);
|
||||
|
||||
|
||||
Simulator::Stop (Seconds (4));
|
||||
Simulator::Run ();
|
||||
|
||||
Time activePeriodsSum;
|
||||
Time transactionTime;
|
||||
uint64_t symbolRate;
|
||||
u_int32_t activePeriodSize = 20;
|
||||
double boundary;
|
||||
|
||||
|
||||
// Verifies that the CCA checks and the rest of the transaction runs
|
||||
// on a boundary of an Active Period in the slotted CSMA-CA.
|
||||
|
||||
symbolRate = (uint64_t) dev1->GetMac ()->GetPhy ()->GetDataOrSymbolRate (false);
|
||||
activePeriodsSum = m_apBoundary - m_startCap;
|
||||
boundary = (activePeriodsSum.GetMicroSeconds () * 1000 * 1000 * symbolRate) % activePeriodSize;
|
||||
|
||||
NS_TEST_EXPECT_MSG_EQ (boundary, 0, "Error, the transaction is not calculated on a boundary of an Active Period in the CAP");
|
||||
|
||||
|
||||
// Slotted CSMA-CA needs to precalculate the cost of the transaction to ensure there
|
||||
// is enough time in the CAP to complete the transmission. The following checks that such
|
||||
// pre-calculation matches the time it took to complete the transmission.
|
||||
|
||||
// The calculated transaction includes the IFS time, so we need to subtract its value to compare it.
|
||||
// MPDU = MAC Header + MSDU (payload)
|
||||
// Mac Header = 13 bytes
|
||||
// If the MPDU is > aMaxSIFSFrameSize (18 bytes) then IFS = LIFS (40 symbols), else IFS = SIFS (12 symbols)
|
||||
|
||||
uint32_t ifsSize;
|
||||
if (p1->GetSize () > 18)
|
||||
{
|
||||
ifsSize = 40;
|
||||
}
|
||||
else
|
||||
{
|
||||
ifsSize = 12;
|
||||
}
|
||||
|
||||
transactionTime = MicroSeconds ((m_transCost - ifsSize) * 1000 * 1000 / symbolRate);
|
||||
|
||||
NS_TEST_EXPECT_MSG_EQ (m_sentTime,(m_apBoundary + transactionTime),"Error, the transaction time is not the expected value");
|
||||
|
||||
Simulator::Destroy ();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \ingroup lr-wpan-test
|
||||
* \ingroup tests
|
||||
*
|
||||
* \brief LrWpan Slotted CSMA-CA TestSuite
|
||||
*/
|
||||
|
||||
class LrWpanSlottedCsmacaTestSuite : public TestSuite
|
||||
{
|
||||
public:
|
||||
LrWpanSlottedCsmacaTestSuite ();
|
||||
};
|
||||
|
||||
LrWpanSlottedCsmacaTestSuite::LrWpanSlottedCsmacaTestSuite ()
|
||||
: TestSuite ("lr-wpan-slotted-csmaca", UNIT)
|
||||
{
|
||||
AddTestCase (new LrWpanSlottedCsmacaTestCase, TestCase::QUICK);
|
||||
}
|
||||
|
||||
static LrWpanSlottedCsmacaTestSuite lrWpanSlottedCsmacaTestSuite; //!< Static variable for test initialization
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@ def build(bld):
|
||||
'model/lr-wpan-phy.cc',
|
||||
'model/lr-wpan-mac.cc',
|
||||
'model/lr-wpan-mac-header.cc',
|
||||
'model/lr-wpan-mac-pl-headers.cc',
|
||||
'model/lr-wpan-fields.cc',
|
||||
'model/lr-wpan-mac-trailer.cc',
|
||||
'model/lr-wpan-csmaca.cc',
|
||||
'model/lr-wpan-net-device.cc',
|
||||
@@ -27,6 +29,8 @@ def build(bld):
|
||||
'test/lr-wpan-packet-test.cc',
|
||||
'test/lr-wpan-pd-plme-sap-test.cc',
|
||||
'test/lr-wpan-spectrum-value-helper-test.cc',
|
||||
'test/lr-wpan-ifs-test.cc',
|
||||
'test/lr-wpan-slotted-csmaca-test.cc',
|
||||
]
|
||||
|
||||
headers = bld(features='ns3header')
|
||||
@@ -37,6 +41,8 @@ def build(bld):
|
||||
'model/lr-wpan-phy.h',
|
||||
'model/lr-wpan-mac.h',
|
||||
'model/lr-wpan-mac-header.h',
|
||||
'model/lr-wpan-mac-pl-headers.h',
|
||||
'model/lr-wpan-fields.h',
|
||||
'model/lr-wpan-mac-trailer.h',
|
||||
'model/lr-wpan-csmaca.h',
|
||||
'model/lr-wpan-net-device.h',
|
||||
|
||||
181
src/sixlowpan/examples/example-ping-lr-wpan-beacon.cc
Normal file
181
src/sixlowpan/examples/example-ping-lr-wpan-beacon.cc
Normal file
@@ -0,0 +1,181 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2020 Ritsumeikan University, Shiga, Japan
|
||||
*
|
||||
* 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: Alberto Gallegos Ramonet <ramonet@fc.ritsumei.ac.jp>
|
||||
*/
|
||||
|
||||
|
||||
#include <fstream>
|
||||
#include "ns3/core-module.h"
|
||||
#include "ns3/internet-module.h"
|
||||
#include "ns3/internet-apps-module.h"
|
||||
#include "ns3/mobility-module.h"
|
||||
#include "ns3/spectrum-module.h"
|
||||
#include "ns3/propagation-module.h"
|
||||
#include "ns3/sixlowpan-module.h"
|
||||
#include "ns3/lr-wpan-module.h"
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
|
||||
static void dataSentMacConfirm (McpsDataConfirmParams params)
|
||||
{
|
||||
// In the case of transmissions with the Ack flag activated, the transaction is only
|
||||
// successful if the Ack was received.
|
||||
if (params.m_status == LrWpanMcpsDataConfirmStatus::IEEE_802_15_4_SUCCESS)
|
||||
{
|
||||
NS_LOG_UNCOND ("**********" << Simulator::Now ().GetSeconds () << " secs | Transmission successfully sent");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
|
||||
bool verbose = false;
|
||||
|
||||
CommandLine cmd;
|
||||
cmd.AddValue ("verbose", "turn on log components", verbose);
|
||||
cmd.Parse (argc, argv);
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
LogComponentEnableAll (LOG_PREFIX_TIME);
|
||||
LogComponentEnableAll (LOG_PREFIX_FUNC);
|
||||
LogComponentEnable ("LrWpanMac", LOG_LEVEL_INFO);
|
||||
LogComponentEnable ("LrWpanCsmaCa", LOG_LEVEL_INFO);
|
||||
LogComponentEnable ("LrWpanHelper", LOG_LEVEL_ALL);
|
||||
LogComponentEnable ("Ping6Application", LOG_LEVEL_INFO);
|
||||
}
|
||||
|
||||
|
||||
NodeContainer nodes;
|
||||
nodes.Create (2);
|
||||
|
||||
MobilityHelper mobility;
|
||||
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
|
||||
mobility.SetPositionAllocator ("ns3::GridPositionAllocator",
|
||||
"MinX", DoubleValue (0.0),
|
||||
"MinY", DoubleValue (0.0),
|
||||
"DeltaX", DoubleValue (20),
|
||||
"DeltaY", DoubleValue (20),
|
||||
"GridWidth", UintegerValue (3),
|
||||
"LayoutType", StringValue ("RowFirst"));
|
||||
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
|
||||
mobility.Install (nodes);
|
||||
|
||||
LrWpanHelper lrWpanHelper;
|
||||
// Add and install the LrWpanNetDevice for each node
|
||||
NetDeviceContainer lrwpanDevices = lrWpanHelper.Install (nodes);
|
||||
|
||||
Ptr<LrWpanNetDevice> dev1 = lrwpanDevices.Get (0)->GetObject<LrWpanNetDevice> ();
|
||||
Ptr<LrWpanNetDevice> dev2 = lrwpanDevices.Get (1)->GetObject<LrWpanNetDevice> ();
|
||||
|
||||
McpsDataConfirmCallback cb1;
|
||||
cb1 = MakeCallback (&dataSentMacConfirm);
|
||||
dev1->GetMac ()->SetMcpsDataConfirmCallback (cb1);
|
||||
dev2->GetMac ()->SetMcpsDataConfirmCallback (cb1);
|
||||
|
||||
|
||||
// Fake PAN association, coordinator assignment, short address assignment and initialization
|
||||
// of beacon-enabled mode in 802.15.4-2011.
|
||||
// This is needed because the lr-wpan module does not provide (yet)
|
||||
// a full PAN association procedure.
|
||||
|
||||
// AssociateToBeaconPan (devices, PAN ID, Coordinator Address, Beacon Order, Superframe Order)
|
||||
|
||||
// Must be careful not setting the beacon order (BO) and the superframe order (SO) too far apart
|
||||
// or the ping reply (ICMPV6 echo reply) can time out during the inactive period of the superframe.
|
||||
// A full time table of the BO/SO time equivalence can be found at the end of this document.
|
||||
// The current configuration is BO = 14, SO = 13 :
|
||||
|
||||
// Contention Access Period (CAP) Inactive
|
||||
// (125.82912 secs) (125.82088)
|
||||
// |---------------------------------------------|-------------------------------------------|
|
||||
// Beacon Beacon
|
||||
// Beacon Interval = 251.65 secs
|
||||
// |-----------------------------------------------------------------------------------------|
|
||||
|
||||
lrWpanHelper.AssociateToBeaconPan (lrwpanDevices, 0, Mac16Address ("00:01"), 14,13);
|
||||
|
||||
|
||||
InternetStackHelper internetv6;
|
||||
internetv6.Install (nodes);
|
||||
|
||||
SixLowPanHelper sixlowpan;
|
||||
NetDeviceContainer devices = sixlowpan.Install (lrwpanDevices);
|
||||
|
||||
Ipv6AddressHelper ipv6;
|
||||
ipv6.SetBase (Ipv6Address ("2001:2::"), Ipv6Prefix (64));
|
||||
Ipv6InterfaceContainer deviceInterfaces;
|
||||
deviceInterfaces = ipv6.Assign (devices);
|
||||
|
||||
|
||||
// Send ping packets after the 2nd second of the simulation during the
|
||||
// first 8 seconds of the CAP in the incoming superframe
|
||||
|
||||
uint32_t packetSize = 10;
|
||||
uint32_t maxPacketCount = 5;
|
||||
Time interPacketInterval = Seconds (1);
|
||||
Ping6Helper ping6;
|
||||
|
||||
ping6.SetLocal (deviceInterfaces.GetAddress (0, 1));
|
||||
ping6.SetRemote (deviceInterfaces.GetAddress (1, 1));
|
||||
|
||||
ping6.SetAttribute ("MaxPackets", UintegerValue (maxPacketCount));
|
||||
ping6.SetAttribute ("Interval", TimeValue (interPacketInterval));
|
||||
ping6.SetAttribute ("PacketSize", UintegerValue (packetSize));
|
||||
ApplicationContainer apps = ping6.Install (nodes.Get (0));
|
||||
|
||||
apps.Start (Seconds (2.0));
|
||||
apps.Stop (Seconds (10.0));
|
||||
|
||||
AsciiTraceHelper ascii;
|
||||
lrWpanHelper.EnableAsciiAll (ascii.CreateFileStream ("Ping-6LoW-lr-wpan-beacon.tr"));
|
||||
lrWpanHelper.EnablePcapAll (std::string ("Ping-6LoW-lr-wpan-beacon"), true);
|
||||
|
||||
|
||||
Simulator::Stop (Seconds (600));
|
||||
|
||||
Simulator::Run ();
|
||||
Simulator::Destroy ();
|
||||
|
||||
}
|
||||
|
||||
// BO/SO values to time equivalence
|
||||
// These times are only valid for a 250kbps O-QPSK modulation,
|
||||
// times differ with other modulation configurations.
|
||||
|
||||
// +------------------------+
|
||||
// | BO/SO | Time (secs) |
|
||||
// +------------------------+
|
||||
// | 0 | 0.01536 secs |
|
||||
// | 1 | 0.03072 secs |
|
||||
// | 2 | 0.06144 secs |
|
||||
// | 3 | 0.12288 secs |
|
||||
// | 4 | 0.24576 secs |
|
||||
// | 5 | 0.49152 secs |
|
||||
// | 6 | 0.98304 secs |
|
||||
// | 7 | 1.96608 secs |
|
||||
// | 8 | 3.93216 secs |
|
||||
// | 9 | 7.86432 secs |
|
||||
// | 10 | 15.72864 secs |
|
||||
// | 11 | 31.45728 secs |
|
||||
// | 12 | 62.91456 secs |
|
||||
// | 13 | 125.82912 secs |
|
||||
// | 14 | 251.65 secs |
|
||||
// +------------------------+
|
||||
@@ -11,6 +11,10 @@ def build(bld):
|
||||
obj = bld.create_ns3_program('example-ping-lr-wpan',
|
||||
['network', 'sixlowpan', 'internet', 'lr-wpan', 'internet-apps'])
|
||||
obj.source = 'example-ping-lr-wpan.cc'
|
||||
|
||||
obj = bld.create_ns3_program('example-ping-lr-wpan-beacon',
|
||||
['network', 'sixlowpan', 'internet', 'lr-wpan', 'internet-apps'])
|
||||
obj.source = 'example-ping-lr-wpan-beacon.cc'
|
||||
|
||||
obj = bld.create_ns3_program('example-ping-lr-wpan-mesh-under',
|
||||
['network', 'sixlowpan', 'internet', 'lr-wpan', 'internet-apps', 'csma'])
|
||||
|
||||
Reference in New Issue
Block a user