ACK (Sascha Jopen), NetDevice (Tommaso Pecorella and Margherita Filippetti), FCS changes (Erwan Livolant), and clang compliance
This commit is contained in:
@@ -25,13 +25,15 @@
|
||||
* Trace Phy state changes, and Mac DataIndication and DataConfirm events
|
||||
* to stdout
|
||||
*/
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/core-module.h"
|
||||
#include "ns3/lr-wpan-module.h"
|
||||
#include "ns3/propagation-loss-model.h"
|
||||
#include "ns3/simulator.h"
|
||||
#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>
|
||||
|
||||
@@ -83,7 +85,9 @@ int main (int argc, char *argv[])
|
||||
// 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);
|
||||
@@ -128,21 +132,24 @@ int main (int argc, char *argv[])
|
||||
|
||||
// The below should trigger two callbacks when end-to-end data is working
|
||||
// 1) DataConfirm callback is called
|
||||
// 2) DataIndication callback is called with value of 20
|
||||
Ptr<Packet> p0 = Create<Packet> (50); // 20 bytes of dummy data
|
||||
// 2) DataIndication callback is called with value of 50
|
||||
Ptr<Packet> p0 = Create<Packet> (50); // 50 bytes of dummy data
|
||||
McpsDataRequestParams params;
|
||||
params.m_srcAddrMode = 2;
|
||||
params.m_dstAddrMode = 2;
|
||||
params.m_srcAddrMode = SHORT_ADDR;
|
||||
params.m_dstAddrMode = SHORT_ADDR;
|
||||
params.m_dstPanId = 0;
|
||||
params.m_dstAddr = Mac16Address ("00:02");
|
||||
params.m_msduHandle = 0;
|
||||
params.m_txOptions = 0;
|
||||
dev0->GetMac ()->McpsDataRequest (params, p0);
|
||||
params.m_txOptions = TX_OPTION_ACK;
|
||||
// dev0->GetMac ()->McpsDataRequest (params, p0);
|
||||
Simulator::ScheduleWithContext (1, Seconds (0.0),
|
||||
&LrWpanMac::McpsDataRequest,
|
||||
dev0->GetMac (), params, p0);
|
||||
|
||||
// Send a packet back at time 2 seconds
|
||||
Ptr<Packet> p2 = Create<Packet> (60); // 20 bytes of dummy data
|
||||
Ptr<Packet> p2 = Create<Packet> (60); // 60 bytes of dummy data
|
||||
params.m_dstAddr = Mac16Address ("00:01");
|
||||
Simulator::Schedule (MilliSeconds (2.0),
|
||||
Simulator::ScheduleWithContext (2, Seconds (2.0),
|
||||
&LrWpanMac::McpsDataRequest,
|
||||
dev1->GetMac (), params, p2);
|
||||
|
||||
|
||||
@@ -23,28 +23,26 @@
|
||||
// LogDistance propagation loss model, the 2.4 GHz OQPSK error model, a
|
||||
// default transmit power of 0 dBm, and a default packet size of 20 bytes of
|
||||
// 802.15.4 payload.
|
||||
|
||||
|
||||
#include "ns3/test.h"
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/callback.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/lr-wpan-error-model.h"
|
||||
#include "ns3/propagation-loss-model.h"
|
||||
#include "ns3/lr-wpan-net-device.h"
|
||||
#include "ns3/lr-wpan-spectrum-value-helper.h"
|
||||
#include "ns3/lr-wpan-mac.h"
|
||||
#include "ns3/node.h"
|
||||
#include "ns3/net-device.h"
|
||||
#include "ns3/single-model-spectrum-channel.h"
|
||||
#include "ns3/mac16-address.h"
|
||||
#include "ns3/constant-position-mobility-model.h"
|
||||
#include "ns3/uinteger.h"
|
||||
#include "ns3/nstime.h"
|
||||
#include "ns3/abort.h"
|
||||
#include "ns3/command-line.h"
|
||||
#include "ns3/gnuplot.h"
|
||||
#include <ns3/test.h>
|
||||
#include <ns3/log.h>
|
||||
#include <ns3/callback.h>
|
||||
#include <ns3/packet.h>
|
||||
#include <ns3/simulator.h>
|
||||
#include <ns3/lr-wpan-error-model.h>
|
||||
#include <ns3/propagation-loss-model.h>
|
||||
#include <ns3/lr-wpan-net-device.h>
|
||||
#include <ns3/lr-wpan-spectrum-value-helper.h>
|
||||
#include <ns3/lr-wpan-mac.h>
|
||||
#include <ns3/node.h>
|
||||
#include <ns3/net-device.h>
|
||||
#include <ns3/single-model-spectrum-channel.h>
|
||||
#include <ns3/mac16-address.h>
|
||||
#include <ns3/constant-position-mobility-model.h>
|
||||
#include <ns3/uinteger.h>
|
||||
#include <ns3/nstime.h>
|
||||
#include <ns3/abort.h>
|
||||
#include <ns3/command-line.h>
|
||||
#include <ns3/gnuplot.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
@@ -17,15 +17,15 @@
|
||||
*
|
||||
* Author: Gary Pei <guangyu.pei@boeing.com>
|
||||
*/
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/uinteger.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/nstime.h"
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/abort.h"
|
||||
#include "ns3/command-line.h"
|
||||
#include "ns3/gnuplot.h"
|
||||
#include "ns3/lr-wpan-error-model.h"
|
||||
#include <ns3/packet.h>
|
||||
#include <ns3/uinteger.h>
|
||||
#include <ns3/simulator.h>
|
||||
#include <ns3/nstime.h>
|
||||
#include <ns3/log.h>
|
||||
#include <ns3/abort.h>
|
||||
#include <ns3/command-line.h>
|
||||
#include <ns3/gnuplot.h>
|
||||
#include <ns3/lr-wpan-error-model.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
@@ -17,9 +17,8 @@
|
||||
*
|
||||
* Author: Tom Henderson <thomas.r.henderson@boeing.com>
|
||||
*/
|
||||
|
||||
#include "ns3/core-module.h"
|
||||
#include "ns3/lr-wpan-module.h"
|
||||
#include <ns3/core-module.h>
|
||||
#include <ns3/lr-wpan-module.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
*
|
||||
* Author: Gary Pei <guangyu.pei@boeing.com>
|
||||
*/
|
||||
|
||||
#include <ns3/log.h>
|
||||
#include <ns3/test.h>
|
||||
#include <ns3/packet.h>
|
||||
#include <ns3/lr-wpan-phy.h>
|
||||
#include <ns3/lr-wpan-mac.h>
|
||||
#include <ns3/simulator.h>
|
||||
@@ -37,7 +37,7 @@ void GetSetTRXStateConfirm (LrWpanPhyEnumeration status)
|
||||
void
|
||||
ReceivePdDataIndication (uint32_t psduLength,
|
||||
Ptr<Packet> p,
|
||||
uint32_t lqi)
|
||||
uint8_t lqi)
|
||||
{
|
||||
NS_LOG_UNCOND ("At: " << Simulator::Now ()
|
||||
<< " Received frame size: " << psduLength << " LQI: " <<
|
||||
|
||||
@@ -19,13 +19,14 @@
|
||||
* Gary Pei <guangyu.pei@boeing.com>
|
||||
* Tom Henderson <thomas.r.henderson@boeing.com>
|
||||
*/
|
||||
|
||||
#include "lr-wpan-helper.h"
|
||||
#include "ns3/lr-wpan-phy.h"
|
||||
#include "ns3/lr-wpan-net-device.h"
|
||||
#include "ns3/propagation-loss-model.h"
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/config.h"
|
||||
#include <ns3/lr-wpan-csmaca.h>
|
||||
#include <ns3/lr-wpan-error-model.h>
|
||||
#include <ns3/lr-wpan-net-device.h>
|
||||
#include <ns3/mobility-model.h>
|
||||
#include <ns3/single-model-spectrum-channel.h>
|
||||
#include <ns3/propagation-loss-model.h>
|
||||
#include <ns3/log.h>
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("LrWpanHelper");
|
||||
|
||||
|
||||
@@ -22,17 +22,16 @@
|
||||
#ifndef LR_WPAN_HELPER_H
|
||||
#define LR_WPAN_HELPER_H
|
||||
|
||||
#include "ns3/node-container.h"
|
||||
#include "ns3/net-device-container.h"
|
||||
#include "ns3/lr-wpan-phy.h"
|
||||
#include "ns3/lr-wpan-mac.h"
|
||||
#include "ns3/lr-wpan-csmaca.h"
|
||||
#include "ns3/trace-helper.h"
|
||||
#include "ns3/lr-wpan-error-model.h"
|
||||
#include "ns3/single-model-spectrum-channel.h"
|
||||
#include <ns3/node-container.h>
|
||||
#include <ns3/lr-wpan-phy.h>
|
||||
#include <ns3/lr-wpan-mac.h>
|
||||
#include <ns3/trace-helper.h>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class SingleModelSpectrumChannel;
|
||||
class MobilityModel;
|
||||
|
||||
/**
|
||||
* \ingroup lr-wpan
|
||||
*
|
||||
@@ -51,7 +50,7 @@ public:
|
||||
* \brief Create a LrWpan helper in an empty state.
|
||||
*/
|
||||
LrWpanHelper (void);
|
||||
~LrWpanHelper (void);
|
||||
virtual ~LrWpanHelper (void);
|
||||
|
||||
/**
|
||||
* \brief Add mobility model to a physical device
|
||||
|
||||
@@ -15,13 +15,14 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: kwong yin <kwong-sang.yin@boeing.com>
|
||||
* Author:
|
||||
* kwong yin <kwong-sang.yin@boeing.com>
|
||||
* Sascha Alexander Jopen <jopen@cs.uni-bonn.de>
|
||||
*/
|
||||
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/lr-wpan-csmaca.h"
|
||||
#include "ns3/lr-wpan-mac.h"
|
||||
#include "ns3/log.h"
|
||||
#include "lr-wpan-csmaca.h"
|
||||
#include <ns3/simulator.h>
|
||||
#include <ns3/log.h>
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("LrWpanCsmaCa");
|
||||
|
||||
@@ -52,10 +53,16 @@ LrWpanCsmaCa::LrWpanCsmaCa ()
|
||||
// TODO-- make these into ns-3 attributes
|
||||
|
||||
m_isSlotted = false;
|
||||
m_NB = 0;
|
||||
m_CW = 2;
|
||||
m_BLE = false;
|
||||
m_macMinBE = 3;
|
||||
m_macMaxBE = 5;
|
||||
m_macMaxCSMABackoffs = 4;
|
||||
m_aUnitBackoffPeriod = 20; //20 symbols
|
||||
m_random = UniformVariable ();
|
||||
m_BE = m_macMinBE;
|
||||
m_ccaRequestRunning = false;
|
||||
}
|
||||
|
||||
LrWpanCsmaCa::~LrWpanCsmaCa ()
|
||||
@@ -67,6 +74,7 @@ void
|
||||
LrWpanCsmaCa::DoDispose ()
|
||||
{
|
||||
m_lrWpanMacStateCallback = MakeNullCallback< void, LrWpanMacState> ();
|
||||
Cancel ();
|
||||
m_mac = 0;
|
||||
}
|
||||
|
||||
@@ -197,12 +205,12 @@ LrWpanCsmaCa::Start ()
|
||||
}
|
||||
//TODO: for slotted, locate backoff period boundary. i.e. delay to the next slot boundary
|
||||
backoffBoundary = getTimeToNextSlot ();
|
||||
Simulator::Schedule (Seconds (backoffBoundary),&LrWpanCsmaCa::RandomBackoffDelay,this);
|
||||
m_randomBackoffEvent = Simulator::Schedule (Seconds (backoffBoundary), &LrWpanCsmaCa::RandomBackoffDelay, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_BE = m_macMinBE;
|
||||
Simulator::ScheduleNow (&LrWpanCsmaCa::RandomBackoffDelay,this);
|
||||
m_randomBackoffEvent = Simulator::ScheduleNow (&LrWpanCsmaCa::RandomBackoffDelay, this);
|
||||
}
|
||||
/*
|
||||
* TODO: If using Backoff.cc (will need to modify Backoff::GetBackoffTime)
|
||||
@@ -217,9 +225,11 @@ LrWpanCsmaCa::Start ()
|
||||
void
|
||||
LrWpanCsmaCa::Cancel ()
|
||||
{
|
||||
m_randomBackoffEvent.Cancel ();
|
||||
m_requestCcaEvent.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
|
||||
@@ -229,8 +239,6 @@ LrWpanCsmaCa::RandomBackoffDelay ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
SeedManager::SetSeed (100);
|
||||
UniformVariable uniformVar;
|
||||
uint64_t upperBound = (uint64_t) pow (2, m_BE) - 1;
|
||||
uint64_t backoffPeriod;
|
||||
Time randomBackoff;
|
||||
@@ -239,19 +247,18 @@ LrWpanCsmaCa::RandomBackoffDelay ()
|
||||
|
||||
|
||||
symbolRate = (uint64_t) m_mac->GetPhy ()->GetDataOrSymbolRate (isData); //symbols per second
|
||||
uniformVar = UniformVariable (0, upperBound);
|
||||
backoffPeriod = (uint64_t)uniformVar.GetValue (); //num backoff periods
|
||||
backoffPeriod = (uint64_t)m_random.GetValue (0, upperBound); //num backoff periods
|
||||
randomBackoff = MicroSeconds (backoffPeriod * getUnitBackoffPeriod () * 1000 * 1000 / symbolRate);
|
||||
|
||||
if (isUnSlottedCsmaCa ())
|
||||
{
|
||||
NS_LOG_LOGIC ("Unslotted: requesting CCA after backoff of " << randomBackoff.GetMicroSeconds () << " us");
|
||||
Simulator::Schedule (randomBackoff,&LrWpanCsmaCa::RequestCCA,this);
|
||||
m_requestCcaEvent = Simulator::Schedule (randomBackoff, &LrWpanCsmaCa::RequestCCA, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_LOGIC ("Slotted: proceeding after backoff of " << randomBackoff.GetMicroSeconds () << " us");
|
||||
Simulator::Schedule (randomBackoff,&LrWpanCsmaCa::CanProceed,this);
|
||||
m_canProceedEvent = Simulator::Schedule (randomBackoff, &LrWpanCsmaCa::CanProceed, this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -276,11 +283,11 @@ LrWpanCsmaCa::CanProceed ()
|
||||
{
|
||||
// TODO: For slotted, Perform CCA on backoff period boundary i.e. delay to next slot boundary
|
||||
backoffBoundary = getTimeToNextSlot ();
|
||||
Simulator::Schedule (Seconds (backoffBoundary),&LrWpanCsmaCa::RequestCCA,this);
|
||||
m_requestCcaEvent = Simulator::Schedule (Seconds (backoffBoundary), &LrWpanCsmaCa::RequestCCA, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
Simulator::Schedule (Seconds (nextCap),&LrWpanCsmaCa::RandomBackoffDelay,this);
|
||||
m_randomBackoffEvent = Simulator::Schedule (Seconds (nextCap), &LrWpanCsmaCa::RandomBackoffDelay, this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,6 +295,7 @@ void
|
||||
LrWpanCsmaCa::RequestCCA ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_ccaRequestRunning = true;
|
||||
m_mac->GetPhy ()->PlmeCcaRequest ();
|
||||
}
|
||||
|
||||
@@ -299,60 +307,67 @@ LrWpanCsmaCa::PlmeCcaConfirm (LrWpanPhyEnumeration status)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << status);
|
||||
|
||||
if (status == IEEE_802_15_4_PHY_IDLE)
|
||||
// Only react on this event, if we are actually waiting for a CCA.
|
||||
// If the CSMA algorithm was canceled, we could still receive this event from
|
||||
// the PHY. In this case we ignore the event.
|
||||
if (m_ccaRequestRunning)
|
||||
{
|
||||
if (isSlottedCsmaCa ())
|
||||
m_ccaRequestRunning = false;
|
||||
if (status == IEEE_802_15_4_PHY_IDLE)
|
||||
{
|
||||
m_CW--;
|
||||
if (m_CW == 0)
|
||||
if (isSlottedCsmaCa ())
|
||||
{
|
||||
// inform MAC channel is idle
|
||||
m_CW--;
|
||||
if (m_CW == 0)
|
||||
{
|
||||
// inform MAC channel is idle
|
||||
if (!m_lrWpanMacStateCallback.IsNull ())
|
||||
{
|
||||
NS_LOG_LOGIC ("Notifying MAC of idle channel");
|
||||
m_lrWpanMacStateCallback (CHANNEL_IDLE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_LOGIC ("Perform CCA again, m_CW = " << m_CW);
|
||||
m_requestCcaEvent = Simulator::ScheduleNow (&LrWpanCsmaCa::RequestCCA, this); // Perform CCA again
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// inform MAC, channel is idle
|
||||
if (!m_lrWpanMacStateCallback.IsNull ())
|
||||
{
|
||||
NS_LOG_LOGIC ("Notifying MAC of idle channel");
|
||||
m_lrWpanMacStateCallback (CHANNEL_IDLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isSlottedCsmaCa ())
|
||||
{
|
||||
m_CW = 2;
|
||||
}
|
||||
m_BE = MIN (m_BE + 1, m_macMaxBE);
|
||||
m_NB++;
|
||||
if (m_NB > m_macMaxCSMABackoffs)
|
||||
{
|
||||
// no channel found so cannot send pkt
|
||||
NS_LOG_DEBUG ("Channel access failure");
|
||||
if (!m_lrWpanMacStateCallback.IsNull ())
|
||||
{
|
||||
NS_LOG_LOGIC ("Notifying MAC of Channel access failure");
|
||||
m_lrWpanMacStateCallback (CHANNEL_ACCESS_FAILURE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_LOGIC ("Perform CCA again, m_CW = " << m_CW);
|
||||
Simulator::ScheduleNow (&LrWpanCsmaCa::RequestCCA,this); // Perform CCA again
|
||||
NS_LOG_DEBUG ("Perform another backoff; m_NB = " << static_cast<uint16_t> (m_NB));
|
||||
m_randomBackoffEvent = Simulator::ScheduleNow (&LrWpanCsmaCa::RandomBackoffDelay, this); //Perform another backoff (step 2)
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// inform MAC, channel is idle
|
||||
if (!m_lrWpanMacStateCallback.IsNull ())
|
||||
{
|
||||
NS_LOG_LOGIC ("Notifying MAC of idle channel");
|
||||
m_lrWpanMacStateCallback (CHANNEL_IDLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isSlottedCsmaCa ())
|
||||
{
|
||||
m_CW = 2;
|
||||
}
|
||||
m_BE = MIN (m_BE + 1, m_macMaxBE);
|
||||
m_NB++;
|
||||
if (m_NB > m_macMaxCSMABackoffs)
|
||||
{
|
||||
// no channel found so cannot send pkt
|
||||
NS_LOG_DEBUG ("Channel access failure");
|
||||
if (!m_lrWpanMacStateCallback.IsNull ())
|
||||
{
|
||||
NS_LOG_LOGIC ("Notifying MAC of Channel access failure");
|
||||
m_lrWpanMacStateCallback (CHANNEL_ACCESS_FAILURE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_DEBUG ("Perform another backoff; m_NB = " << static_cast<uint16_t> (m_NB));
|
||||
Simulator::ScheduleNow (&LrWpanCsmaCa::RandomBackoffDelay,this); //Perform another backoff (step 2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,24 +15,23 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: kwong yin <kwong-sang.yin@boeing.com>
|
||||
* Author:
|
||||
* kwong yin <kwong-sang.yin@boeing.com>
|
||||
* Sascha Alexander Jopen <jopen@cs.uni-bonn.de>
|
||||
*/
|
||||
|
||||
#ifndef LRWPANCSMACA_H
|
||||
#define LRWPANCSMACA_H
|
||||
#ifndef LR_WPAN_CSMACA_H
|
||||
#define LR_WPAN_CSMACA_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "ns3/object.h"
|
||||
#include "ns3/nstime.h"
|
||||
#include "ns3/random-variable.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/lr-wpan-phy.h"
|
||||
#include "ns3/lr-wpan-mac.h"
|
||||
#include <ns3/object.h>
|
||||
#include <ns3/random-variable.h>
|
||||
#include <ns3/event-id.h>
|
||||
#include <ns3/lr-wpan-mac.h>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/* This method informs MAC that channel is idle or busy */
|
||||
typedef Callback< void, LrWpanMacState> LrWpanMacStateCallback;
|
||||
typedef Callback<void, LrWpanMacState> LrWpanMacStateCallback;
|
||||
|
||||
/**
|
||||
* \ingroup lr-wpan
|
||||
@@ -44,10 +43,10 @@ class LrWpanCsmaCa : public Object
|
||||
{
|
||||
|
||||
public:
|
||||
static TypeId GetTypeId ();
|
||||
static TypeId GetTypeId (void);
|
||||
|
||||
LrWpanCsmaCa ();
|
||||
~LrWpanCsmaCa ();
|
||||
LrWpanCsmaCa (void);
|
||||
virtual ~LrWpanCsmaCa (void);
|
||||
|
||||
void SetMac (Ptr<LrWpanMac> mac);
|
||||
Ptr<LrWpanMac> GetMac (void) const;
|
||||
@@ -80,12 +79,12 @@ public:
|
||||
/*
|
||||
* cancel CSMA-CA algorithm
|
||||
*/
|
||||
void Cancel ();
|
||||
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 RandomBackoffDelay (void);
|
||||
|
||||
/*
|
||||
* In the slotted CSMA-CA, after random backoff, Determine if the remaining
|
||||
@@ -94,13 +93,13 @@ public:
|
||||
* This step is NOT performed for the unslotted CSMA-CA. If it can proceed
|
||||
* function CCAconfirmed() is called.
|
||||
*/
|
||||
void CanProceed ();
|
||||
void CanProceed (void);
|
||||
|
||||
/*
|
||||
* Request the Phy to perform CCA (Step 3)
|
||||
*
|
||||
*/
|
||||
void RequestCCA ();
|
||||
void RequestCCA (void);
|
||||
|
||||
/**
|
||||
* IEEE 802.15.4-2006 section 6.2.2.2
|
||||
@@ -123,7 +122,7 @@ public:
|
||||
void SetLrWpanMacStateCallback (LrWpanMacStateCallback macState);
|
||||
|
||||
private:
|
||||
virtual void DoDispose ();
|
||||
virtual void DoDispose (void);
|
||||
LrWpanMacStateCallback m_lrWpanMacStateCallback;
|
||||
bool m_isSlotted; // beacon-enabled slotted or nonbeacon-enabled unslotted CSMA-CA
|
||||
// beacon order == 15 means nonbeacon-enabled
|
||||
@@ -138,11 +137,16 @@ private:
|
||||
uint8_t m_macMaxBE; //3-8 default 5
|
||||
uint8_t m_macMaxCSMABackoffs; //0-5 default 4
|
||||
uint64_t m_aUnitBackoffPeriod; // 20 symbols in each backoff periods
|
||||
UniformVariable m_random;
|
||||
|
||||
EventId m_randomBackoffEvent;
|
||||
EventId m_requestCcaEvent;
|
||||
EventId m_canProceedEvent;
|
||||
bool m_ccaRequestRunning;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// namespace ns-3
|
||||
|
||||
#endif /* LRWPANCSMACA_H */
|
||||
#endif /* LR_WPAN_CSMACA_H */
|
||||
|
||||
@@ -17,8 +17,10 @@
|
||||
*
|
||||
* Author: Gary Pei <guangyu.pei@boeing.com>
|
||||
*/
|
||||
#include "ns3/lr-wpan-error-model.h"
|
||||
#include "ns3/log.h"
|
||||
#include "lr-wpan-error-model.h"
|
||||
#include <ns3/log.h>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("LrWpanErrorModel");
|
||||
|
||||
@@ -36,8 +38,25 @@ LrWpanErrorModel::GetTypeId (void)
|
||||
return tid;
|
||||
}
|
||||
|
||||
LrWpanErrorModel::LrWpanErrorModel ()
|
||||
LrWpanErrorModel::LrWpanErrorModel (void)
|
||||
{
|
||||
m_binomialCoefficients[0] = 1;
|
||||
m_binomialCoefficients[1] = -16;
|
||||
m_binomialCoefficients[2] = 120;
|
||||
m_binomialCoefficients[3] = -560;
|
||||
m_binomialCoefficients[4] = 1820;
|
||||
m_binomialCoefficients[5] = -4368;
|
||||
m_binomialCoefficients[6] = 8008;
|
||||
m_binomialCoefficients[7] = -11440;
|
||||
m_binomialCoefficients[8] = 12870;
|
||||
m_binomialCoefficients[9] = -11440;
|
||||
m_binomialCoefficients[10] = 8008;
|
||||
m_binomialCoefficients[11] = -4368;
|
||||
m_binomialCoefficients[12] = 1820;
|
||||
m_binomialCoefficients[13] = -560;
|
||||
m_binomialCoefficients[14] = 120;
|
||||
m_binomialCoefficients[15] = -16;
|
||||
m_binomialCoefficients[16] = 1;
|
||||
}
|
||||
|
||||
double
|
||||
@@ -47,7 +66,7 @@ LrWpanErrorModel::GetChunkSuccessRate (double snr, uint32_t nbits) const
|
||||
|
||||
for (uint32_t k = 2; k <= 16; k++)
|
||||
{
|
||||
ber += pow (-1.0, (double) k) * BinomialCoefficient (k,16) * exp (20.0 * snr * (1.0 / k - 1.0));
|
||||
ber += m_binomialCoefficients[k] * exp (20.0 * snr * (1.0 / k - 1.0));
|
||||
}
|
||||
|
||||
ber = ber * 8.0 / 15.0 / 16.0;
|
||||
@@ -57,23 +76,4 @@ LrWpanErrorModel::GetChunkSuccessRate (double snr, uint32_t nbits) const
|
||||
return retval;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
LrWpanErrorModel::Factorial (uint32_t k) const
|
||||
{
|
||||
uint64_t fact = 1;
|
||||
while (k > 0)
|
||||
{
|
||||
fact *= k;
|
||||
k--;
|
||||
}
|
||||
return fact;
|
||||
}
|
||||
|
||||
uint32_t LrWpanErrorModel::BinomialCoefficient (uint32_t k, uint32_t n) const
|
||||
{
|
||||
uint32_t retval = Factorial (n) / Factorial (k) / Factorial (n - k);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -20,9 +20,7 @@
|
||||
#ifndef LR_WPAN_ERROR_MODEL_H
|
||||
#define LR_WPAN_ERROR_MODEL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
#include "ns3/object.h"
|
||||
#include <ns3/object.h>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -38,7 +36,7 @@ class LrWpanErrorModel : public Object
|
||||
public:
|
||||
static TypeId GetTypeId (void);
|
||||
|
||||
LrWpanErrorModel ();
|
||||
LrWpanErrorModel (void);
|
||||
|
||||
/**
|
||||
* return chunk success rate for given SNR
|
||||
@@ -49,8 +47,8 @@ public:
|
||||
double GetChunkSuccessRate (double snr, uint32_t nbits) const;
|
||||
|
||||
private:
|
||||
uint64_t Factorial (uint32_t k) const;
|
||||
uint32_t BinomialCoefficient (uint32_t k, uint32_t n) const;
|
||||
double m_binomialCoefficients[17];
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2011 The Boeing Company
|
||||
*
|
||||
* 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: Gary Pei <guangyu.pei@boeing.com>
|
||||
*/
|
||||
#include "ns3/lr-wpan-error-rate-model.h"
|
||||
#include "ns3/log.h"
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("LrWpanErrorRateModel");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (LrWpanErrorRateModel);
|
||||
|
||||
TypeId
|
||||
LrWpanErrorRateModel::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::LrWpanErrorRateModel")
|
||||
.SetParent<Object> ()
|
||||
.AddConstructor<LrWpanErrorRateModel> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
LrWpanErrorRateModel::LrWpanErrorRateModel ()
|
||||
{
|
||||
}
|
||||
|
||||
double
|
||||
LrWpanErrorRateModel::GetChunkSuccessRate (double snr, uint32_t nbits) const
|
||||
{
|
||||
double ber = 0.0;
|
||||
|
||||
for (uint32_t k = 2; k <= 16; k++)
|
||||
{
|
||||
ber += pow (-1.0, (double) k) * BinomialCoefficient (k,16) * exp (20.0 * snr * (1.0 / k - 1.0));
|
||||
}
|
||||
|
||||
ber = ber * 8.0 / 15.0 / 16.0;
|
||||
|
||||
ber = std::min (ber, 1.0);
|
||||
double retval = pow (1.0 - ber, nbits);
|
||||
return retval;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
LrWpanErrorRateModel::Factorial (uint32_t k) const
|
||||
{
|
||||
uint64_t fact = 1;
|
||||
while (k > 0)
|
||||
{
|
||||
fact *= k;
|
||||
k--;
|
||||
}
|
||||
return fact;
|
||||
}
|
||||
|
||||
uint32_t LrWpanErrorRateModel::BinomialCoefficient (uint32_t k, uint32_t n) const
|
||||
{
|
||||
uint32_t retval = Factorial (n) / Factorial (k) / Factorial (n - k);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
} // namespace ns3
|
||||
@@ -1,51 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2011 The Boeing Company
|
||||
*
|
||||
* 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: Gary Pei <guangyu.pei@boeing.com>
|
||||
*/
|
||||
#ifndef LR_WPAN_ERROR_RATE_MODEL_H
|
||||
#define LR_WPAN_ERROR_RATE_MODEL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
#include "ns3/object.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/**
|
||||
* Model the error rate for IEEE 802.15.4 2.4 GHz AWGN channel for OQPSK
|
||||
* the model description can be found in IEEE Std 802.15.4-2006, section
|
||||
* E.4.1.7
|
||||
*/
|
||||
class LrWpanErrorRateModel : public Object
|
||||
{
|
||||
public:
|
||||
static TypeId GetTypeId (void);
|
||||
|
||||
LrWpanErrorRateModel ();
|
||||
|
||||
double GetChunkSuccessRate (double snr, uint32_t nbits) const;
|
||||
|
||||
private:
|
||||
uint64_t Factorial (uint32_t k) const;
|
||||
uint32_t BinomialCoefficient (uint32_t k, uint32_t n) const;
|
||||
};
|
||||
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif /* LR_WPAN_ERROR_RATE_MODEL_H */
|
||||
94
src/lr-wpan/model/lr-wpan-lqi-tag.cc
Normal file
94
src/lr-wpan/model/lr-wpan-lqi-tag.cc
Normal file
@@ -0,0 +1,94 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013 Fraunhofer FKIE
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Sascha Alexander Jopen <jopen@cs.uni-bonn.de>
|
||||
*/
|
||||
#include "lr-wpan-lqi-tag.h"
|
||||
#include <ns3/integer.h>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (LrWpanLqiTag);
|
||||
|
||||
TypeId
|
||||
LrWpanLqiTag::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::LrWpanLqiTag")
|
||||
.SetParent<Tag> ()
|
||||
.AddConstructor<LrWpanLqiTag> ()
|
||||
.AddAttribute ("Lqi", "The lqi of the last packet received",
|
||||
IntegerValue (0),
|
||||
MakeIntegerAccessor (&LrWpanLqiTag::Get),
|
||||
MakeIntegerChecker<uint8_t> ())
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
TypeId
|
||||
LrWpanLqiTag::GetInstanceTypeId (void) const
|
||||
{
|
||||
return GetTypeId ();
|
||||
}
|
||||
|
||||
LrWpanLqiTag::LrWpanLqiTag (void)
|
||||
: m_lqi (0)
|
||||
{
|
||||
}
|
||||
|
||||
LrWpanLqiTag::LrWpanLqiTag (uint8_t lqi)
|
||||
: m_lqi (lqi)
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t
|
||||
LrWpanLqiTag::GetSerializedSize (void) const
|
||||
{
|
||||
return sizeof (uint8_t);
|
||||
}
|
||||
|
||||
void
|
||||
LrWpanLqiTag::Serialize (TagBuffer i) const
|
||||
{
|
||||
i.WriteU8 (m_lqi);
|
||||
}
|
||||
|
||||
void
|
||||
LrWpanLqiTag::Deserialize (TagBuffer i)
|
||||
{
|
||||
m_lqi = i.ReadU8 ();
|
||||
}
|
||||
|
||||
void
|
||||
LrWpanLqiTag::Print (std::ostream &os) const
|
||||
{
|
||||
os << "Lqi = " << m_lqi;
|
||||
}
|
||||
|
||||
void
|
||||
LrWpanLqiTag::Set (uint8_t lqi)
|
||||
{
|
||||
m_lqi = lqi;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
LrWpanLqiTag::Get (void) const
|
||||
{
|
||||
return m_lqi;
|
||||
}
|
||||
|
||||
}
|
||||
69
src/lr-wpan/model/lr-wpan-lqi-tag.h
Normal file
69
src/lr-wpan/model/lr-wpan-lqi-tag.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013 Fraunhofer FKIE
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Sascha Alexander Jopen <jopen@cs.uni-bonn.de>
|
||||
*/
|
||||
#ifndef LR_WPAN_LQI_TAG_H
|
||||
#define LR_WPAN_LQI_TAG_H
|
||||
|
||||
#include <ns3/tag.h>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class Tag;
|
||||
|
||||
class LrWpanLqiTag : public Tag
|
||||
{
|
||||
public:
|
||||
static TypeId GetTypeId (void);
|
||||
virtual TypeId GetInstanceTypeId (void) const;
|
||||
|
||||
/**
|
||||
* Create a LrWpanLqiTag with the default LQI 0 .
|
||||
*/
|
||||
LrWpanLqiTag (void);
|
||||
|
||||
/**
|
||||
* Create a LrWpanLqiTag with the given LQI value.
|
||||
*/
|
||||
LrWpanLqiTag (uint8_t lqi);
|
||||
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
virtual void Serialize (TagBuffer i) const;
|
||||
virtual void Deserialize (TagBuffer i);
|
||||
virtual void Print (std::ostream &os) const;
|
||||
|
||||
/**
|
||||
* Set the LQI to the given value.
|
||||
*
|
||||
* @param lqi the value of the LQI to set
|
||||
*/
|
||||
void Set (uint8_t lqi);
|
||||
/**
|
||||
* Get the LQI value.
|
||||
*
|
||||
* @return the LQI value
|
||||
*/
|
||||
uint8_t Get (void) const;
|
||||
private:
|
||||
uint8_t m_lqi;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
#endif /* LR_WPAN_LQI_TAG_H */
|
||||
@@ -17,11 +17,8 @@
|
||||
*
|
||||
* Author: kwong yin <kwong-sang.yin@boeing.com>
|
||||
*/
|
||||
|
||||
#include "ns3/lr-wpan-mac-header.h"
|
||||
#include "ns3/mac16-address.h"
|
||||
#include "ns3/mac64-address.h"
|
||||
#include "ns3/address-utils.h"
|
||||
#include "lr-wpan-mac-header.h"
|
||||
#include <ns3/address-utils.h>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
|
||||
@@ -35,14 +35,12 @@
|
||||
* ++ - These fields are optional and of variable size
|
||||
*/
|
||||
|
||||
#ifndef LRWPAN_MAC_HEADER_H
|
||||
#define LRWPAN_MAC_HEADER_H
|
||||
#ifndef LR_WPAN_MAC_HEADER_H
|
||||
#define LR_WPAN_MAC_HEADER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "ns3/header.h"
|
||||
#include "ns3/nstime.h"
|
||||
#include "ns3/mac16-address.h"
|
||||
#include "ns3/mac64-address.h"
|
||||
#include <ns3/header.h>
|
||||
#include <ns3/mac16-address.h>
|
||||
#include <ns3/mac64-address.h>
|
||||
|
||||
|
||||
namespace ns3 {
|
||||
@@ -211,7 +209,7 @@ private:
|
||||
Mac64Address m_addrExtSrcAddr; // 0 or 8 Octet
|
||||
|
||||
/* Auxiliary Security Header // 0, 5, 6, 10 or 14 Octets */
|
||||
uint8_t m_auxSecCtrl; // 1 Octet see below
|
||||
// uint8_t m_auxSecCtrl; // 1 Octet see below
|
||||
uint32_t m_auxFrmCntr; // 4 Octet
|
||||
|
||||
/* Security Control fields */
|
||||
@@ -235,7 +233,7 @@ private:
|
||||
|
||||
}; //LrWpanMacHeader
|
||||
}; // namespace ns-3
|
||||
#endif /* LRWPAN_MAC_HEADER_H */
|
||||
#endif /* LR_WPAN_MAC_HEADER_H */
|
||||
|
||||
// ----------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -15,27 +15,25 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: kwong yin <kwong-sang.yin@boeing.com>
|
||||
* Author:
|
||||
* kwong yin <kwong-sang.yin@boeing.com>
|
||||
* Sascha Alexander Jopen <jopen@cs.uni-bonn.de>
|
||||
* Erwan Livolant <erwan.livolant@inria.fr>
|
||||
*/
|
||||
|
||||
#include "lr-wpan-mac-trailer.h"
|
||||
#include "ns3/object.h"
|
||||
#include <ns3/packet.h>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (LrWpanMacTrailer);
|
||||
|
||||
LrWpanMacTrailer::LrWpanMacTrailer ()
|
||||
LrWpanMacTrailer::LrWpanMacTrailer () :
|
||||
m_fcs (0), m_calcFcs (false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
LrWpanMacTrailer::~LrWpanMacTrailer ()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
TypeId LrWpanMacTrailer::GetTypeId (void)
|
||||
TypeId
|
||||
LrWpanMacTrailer::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::LrWpanMacTrailer")
|
||||
.SetParent<Trailer> ()
|
||||
@@ -44,30 +42,108 @@ TypeId LrWpanMacTrailer::GetTypeId (void)
|
||||
return tid;
|
||||
}
|
||||
|
||||
TypeId LrWpanMacTrailer::GetInstanceTypeId (void) const
|
||||
TypeId
|
||||
LrWpanMacTrailer::GetInstanceTypeId (void) const
|
||||
{
|
||||
return GetTypeId ();
|
||||
}
|
||||
|
||||
void LrWpanMacTrailer::Print (std::ostream &os) const
|
||||
void
|
||||
LrWpanMacTrailer::Print (std::ostream &os) const
|
||||
{
|
||||
|
||||
os << " FCS = " << m_fcs;
|
||||
}
|
||||
|
||||
uint32_t LrWpanMacTrailer::GetSerializedSize (void) const
|
||||
uint32_t
|
||||
LrWpanMacTrailer::GetSerializedSize (void) const
|
||||
{
|
||||
return LRWPAN_MAC_FCS_LENGTH;
|
||||
}
|
||||
|
||||
void LrWpanMacTrailer::Serialize (Buffer::Iterator start) const
|
||||
void
|
||||
LrWpanMacTrailer::Serialize (Buffer::Iterator start) const
|
||||
{
|
||||
start.Prev (LRWPAN_MAC_FCS_LENGTH);
|
||||
start.WriteU16 (0);
|
||||
start.WriteU16 (m_fcs);
|
||||
}
|
||||
|
||||
uint32_t LrWpanMacTrailer::Deserialize (Buffer::Iterator start)
|
||||
uint32_t
|
||||
LrWpanMacTrailer::Deserialize (Buffer::Iterator start)
|
||||
{
|
||||
start.Prev (LRWPAN_MAC_FCS_LENGTH);
|
||||
m_fcs = start.ReadU16 ();
|
||||
|
||||
return LRWPAN_MAC_FCS_LENGTH;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
LrWpanMacTrailer::GetFcs (void) const
|
||||
{
|
||||
return m_fcs;
|
||||
}
|
||||
|
||||
void
|
||||
LrWpanMacTrailer::SetFcs (Ptr<const Packet> p)
|
||||
{
|
||||
if (m_calcFcs)
|
||||
{
|
||||
uint16_t size = p->GetSize ();
|
||||
uint8_t *serial_packet = new uint8_t[size];
|
||||
|
||||
p->CopyData(serial_packet, size);
|
||||
|
||||
m_fcs = GenerateCrc16(serial_packet, size);
|
||||
delete[] serial_packet;
|
||||
}
|
||||
}
|
||||
|
||||
/* Be sure to have removed the trailer and only the trailer
|
||||
* from the packet before to use CheckFcs */
|
||||
bool
|
||||
LrWpanMacTrailer::CheckFcs (Ptr<const Packet> p)
|
||||
{
|
||||
if (!m_calcFcs)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16_t checkFcs;
|
||||
uint16_t size = p->GetSize ();
|
||||
uint8_t *serial_packet = new uint8_t[size];
|
||||
|
||||
p->CopyData(serial_packet, size);
|
||||
|
||||
checkFcs = GenerateCrc16(serial_packet, size);
|
||||
delete[] serial_packet;
|
||||
return (checkFcs == GetFcs ());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LrWpanMacTrailer::EnableFcs (bool enable)
|
||||
{
|
||||
m_calcFcs = enable;
|
||||
}
|
||||
|
||||
/* CRC16-CCITT with a generator polynomial = ^16 + ^12 + ^5 + 1,
|
||||
* LSB first and initial value = 0x0000 */
|
||||
uint16_t
|
||||
LrWpanMacTrailer::GenerateCrc16 (uint8_t *data, int length)
|
||||
{
|
||||
int i;
|
||||
uint16_t accumulator = 0;
|
||||
|
||||
for(i = 0; i < length; ++i)
|
||||
{
|
||||
accumulator ^= *data;
|
||||
accumulator = (accumulator >> 8) | (accumulator << 8);
|
||||
accumulator ^= (accumulator & 0xff00) << 4;
|
||||
accumulator ^= (accumulator >> 8) >> 4;
|
||||
accumulator ^= (accumulator & 0xff00) >> 5;
|
||||
++data;
|
||||
}
|
||||
return accumulator;
|
||||
}
|
||||
|
||||
} //namespace ns3
|
||||
|
||||
@@ -15,17 +15,21 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: kwong yin <kwong-sang.yin@boeing.com>
|
||||
* Author:
|
||||
* kwong yin <kwong-sang.yin@boeing.com>
|
||||
* Sascha Alexander Jopen <jopen@cs.uni-bonn.de>
|
||||
* Erwan Livolant <erwan.livolant@inria.fr>
|
||||
*/
|
||||
|
||||
#ifndef LRWPANMACTRAILER_H_
|
||||
#define LRWPANMACTRAILER_H_
|
||||
#ifndef LR_WPAN_MAC_TRAILER_H
|
||||
#define LR_WPAN_MAC_TRAILER_H
|
||||
|
||||
#include "ns3/trailer.h"
|
||||
#include <stdint.h>
|
||||
#include <ns3/trailer.h>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class Packet;
|
||||
|
||||
/**
|
||||
* The length in octets of the IEEE 802.15.4 MAC FCS field
|
||||
*/
|
||||
@@ -36,7 +40,6 @@ class LrWpanMacTrailer : public Trailer
|
||||
{
|
||||
public:
|
||||
LrWpanMacTrailer ();
|
||||
~LrWpanMacTrailer ();
|
||||
|
||||
static TypeId GetTypeId (void);
|
||||
virtual TypeId GetInstanceTypeId (void) const;
|
||||
@@ -44,6 +47,16 @@ public:
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
virtual void Serialize (Buffer::Iterator start) const;
|
||||
virtual uint32_t Deserialize (Buffer::Iterator start);
|
||||
|
||||
uint16_t GetFcs (void) const;
|
||||
void SetFcs (Ptr<const Packet> p);
|
||||
bool CheckFcs (Ptr<const Packet> p);
|
||||
void EnableFcs (bool enable);
|
||||
|
||||
private:
|
||||
uint16_t m_fcs;
|
||||
bool m_calcFcs;
|
||||
uint16_t GenerateCrc16 (uint8_t *data, int length);
|
||||
};
|
||||
} // namespace ns3
|
||||
#endif /* LRWPANMACTRAILER_H_ */
|
||||
#endif /* LR_WPAN_MAC_TRAILER_H */
|
||||
|
||||
@@ -19,16 +19,18 @@
|
||||
* Gary Pei <guangyu.pei@boeing.com>
|
||||
* kwong yin <kwong-sang.yin@boeing.com>
|
||||
* Tom Henderson <thomas.r.henderson@boeing.com>
|
||||
* Sascha Alexander Jopen <jopen@cs.uni-bonn.de>
|
||||
* Erwan Livolant <erwan.livolant@inria.fr>
|
||||
*/
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/lr-wpan-mac.h"
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/uinteger.h"
|
||||
#include "ns3/trace-source-accessor.h"
|
||||
#include "ns3/lr-wpan-csmaca.h"
|
||||
#include "ns3/lr-wpan-phy.h"
|
||||
#include "ns3/mac16-address.h"
|
||||
#include "ns3/mac64-address.h"
|
||||
#include "lr-wpan-mac.h"
|
||||
#include "lr-wpan-csmaca.h"
|
||||
#include "lr-wpan-mac-header.h"
|
||||
#include "lr-wpan-mac-trailer.h"
|
||||
#include <ns3/simulator.h>
|
||||
#include <ns3/log.h>
|
||||
#include <ns3/uinteger.h>
|
||||
#include <ns3/node.h>
|
||||
#include <ns3/packet.h>
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("LrWpanMac");
|
||||
|
||||
@@ -52,11 +54,14 @@ LrWpanMac::GetTypeId (void)
|
||||
UintegerValue (),
|
||||
MakeUintegerAccessor (&LrWpanMac::m_macPanId),
|
||||
MakeUintegerChecker<uint16_t> ())
|
||||
.AddTraceSource ("MacTxQueue",
|
||||
"Trace source indicating a packet has was enqueued or dequeued to/from the transaction queue",
|
||||
MakeTraceSourceAccessor (&LrWpanMac::m_macTxQueueTrace))
|
||||
.AddTraceSource ("MacTx",
|
||||
"Trace source indicating a packet has arrived for transmission by this device",
|
||||
MakeTraceSourceAccessor (&LrWpanMac::m_macTxTrace))
|
||||
.AddTraceSource ("MacTxDrop",
|
||||
"Trace source indicating a packet has been dropped by the device before transmission",
|
||||
"Trace source indicating a packet has been dropped during transmission",
|
||||
MakeTraceSourceAccessor (&LrWpanMac::m_macTxDropTrace))
|
||||
.AddTraceSource ("MacPromiscRx",
|
||||
"A packet has been received by this device, has been passed up from the physical layer "
|
||||
@@ -85,13 +90,19 @@ LrWpanMac::GetTypeId (void)
|
||||
LrWpanMac::LrWpanMac ()
|
||||
{
|
||||
|
||||
// First set the state to a known value, call ChangeMacState to fire trace source.
|
||||
m_lrWpanMacState = MAC_IDLE;
|
||||
ChangeMacState (MAC_IDLE);
|
||||
|
||||
m_macRxOnWhenIdle = true;
|
||||
m_macPanId = 0;
|
||||
m_associationStatus = ASSOCIATED;
|
||||
m_selfExt = Mac64Address::Allocate ();
|
||||
m_macPromiscuousMode = false;
|
||||
m_macMaxFrameRetries = 3;
|
||||
m_retransmission = 0;
|
||||
m_txPkt = 0;
|
||||
|
||||
SeedManager::SetSeed (100);
|
||||
UniformVariable uniformVar;
|
||||
uniformVar = UniformVariable (0, 255);
|
||||
m_macDsn = SequenceNumber16 (uniformVar.GetValue ());
|
||||
@@ -102,6 +113,21 @@ LrWpanMac::~LrWpanMac ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
LrWpanMac::DoInitialize ()
|
||||
{
|
||||
if (m_macRxOnWhenIdle)
|
||||
{
|
||||
m_phy->PlmeSetTRXStateRequest (IEEE_802_15_4_PHY_RX_ON);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_phy->PlmeSetTRXStateRequest (IEEE_802_15_4_PHY_TRX_OFF);
|
||||
}
|
||||
|
||||
Object::DoInitialize ();
|
||||
}
|
||||
|
||||
void
|
||||
LrWpanMac::DoDispose ()
|
||||
{
|
||||
@@ -120,8 +146,34 @@ LrWpanMac::DoDispose ()
|
||||
m_phy = 0;
|
||||
m_mcpsDataIndicationCallback = MakeNullCallback< void, McpsDataIndicationParams, Ptr<Packet> > ();
|
||||
m_mcpsDataConfirmCallback = MakeNullCallback< void, McpsDataConfirmParams > ();
|
||||
|
||||
Object::DoDispose ();
|
||||
}
|
||||
|
||||
bool
|
||||
LrWpanMac::GetRxOnWhenIdle ()
|
||||
{
|
||||
return m_macRxOnWhenIdle;
|
||||
}
|
||||
|
||||
void
|
||||
LrWpanMac::SetRxOnWhenIdle (bool rxOnWhenIdle)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << rxOnWhenIdle);
|
||||
m_macRxOnWhenIdle = rxOnWhenIdle;
|
||||
|
||||
if (m_lrWpanMacState == MAC_IDLE)
|
||||
{
|
||||
if (m_macRxOnWhenIdle)
|
||||
{
|
||||
m_phy->PlmeSetTRXStateRequest (IEEE_802_15_4_PHY_RX_ON);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_phy->PlmeSetTRXStateRequest (IEEE_802_15_4_PHY_TRX_OFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LrWpanMac::SetShortAddress (Mac16Address address)
|
||||
@@ -158,6 +210,10 @@ LrWpanMac::McpsDataRequest (McpsDataRequestParams params, Ptr<Packet> p)
|
||||
McpsDataConfirmParams confirmParams;
|
||||
confirmParams.m_msduHandle = params.m_msduHandle;
|
||||
|
||||
// TODO: We need a drop trace for the case that the packet is too large or the request parameters are maleformed.
|
||||
// The current tx drop trace is not suitable, because packets dropped using this trace carry the mac header
|
||||
// and footer, while packets being dropped here do not have them.
|
||||
|
||||
LrWpanMacHeader macHdr (LrWpanMacHeader::LRWPAN_MAC_DATA, (uint8_t)m_macDsn.GetValue ());
|
||||
m_macDsn++;
|
||||
if (m_macDsn > SequenceNumber16 (255))
|
||||
@@ -218,15 +274,20 @@ LrWpanMac::McpsDataRequest (McpsDataRequestParams params, Ptr<Packet> p)
|
||||
}
|
||||
|
||||
macHdr.SetDstAddrMode (params.m_dstAddrMode);
|
||||
// TODO: Add field for EXT_ADDR destination address (and use it here).
|
||||
macHdr.SetDstAddrFields (params.m_dstPanId, params.m_dstAddr);
|
||||
macHdr.SetSecDisable ();
|
||||
//extract the last 3 bits in TxOptions and map to macHdr
|
||||
int b0 = params.m_txOptions & 1;
|
||||
int b1 = params.m_txOptions & 2;
|
||||
int b2 = params.m_txOptions & 4;
|
||||
if (b0 == 1)
|
||||
int b0 = params.m_txOptions & TX_OPTION_ACK;
|
||||
int b1 = params.m_txOptions & TX_OPTION_GTS;
|
||||
int b2 = params.m_txOptions & TX_OPTION_INDIRECT;
|
||||
if (b0 == TX_OPTION_ACK)
|
||||
{
|
||||
macHdr.SetAckReq ();
|
||||
// Set AckReq bit only if the destination is not the broadcast address.
|
||||
if (!(macHdr.GetDstAddrMode () == SHORT_ADDR && macHdr.GetShortDstAddr() == "ff:ff"))
|
||||
{
|
||||
macHdr.SetAckReq ();
|
||||
}
|
||||
}
|
||||
else if (b0 == 0)
|
||||
{
|
||||
@@ -246,7 +307,7 @@ LrWpanMac::McpsDataRequest (McpsDataRequestParams params, Ptr<Packet> p)
|
||||
//if is Slotted CSMA means its beacon enabled
|
||||
if (m_csmaCa->isSlottedCsmaCa ())
|
||||
{
|
||||
if (b1 == 2)
|
||||
if (b1 == TX_OPTION_GTS)
|
||||
{
|
||||
//TODO:GTS Transmission
|
||||
}
|
||||
@@ -279,7 +340,7 @@ LrWpanMac::McpsDataRequest (McpsDataRequestParams params, Ptr<Packet> p)
|
||||
}
|
||||
}
|
||||
|
||||
if (b2 == 4)
|
||||
if (b2 == TX_OPTION_INDIRECT)
|
||||
{
|
||||
//TODO :indirect tx
|
||||
}
|
||||
@@ -301,43 +362,50 @@ LrWpanMac::McpsDataRequest (McpsDataRequestParams params, Ptr<Packet> p)
|
||||
p->AddHeader (macHdr);
|
||||
|
||||
LrWpanMacTrailer macTrailer;
|
||||
// Calculate FCS if the global attribute ChecksumEnable is set.
|
||||
if (Node::ChecksumEnabled ())
|
||||
{
|
||||
macTrailer.EnableFcs (true);
|
||||
macTrailer.SetFcs (p);
|
||||
}
|
||||
p->AddTrailer (macTrailer);
|
||||
|
||||
m_macTxTrace (p);
|
||||
confirmParams.m_status = IEEE_802_15_4_SUCCESS;
|
||||
if (!m_mcpsDataConfirmCallback.IsNull ())
|
||||
{
|
||||
m_mcpsDataConfirmCallback (confirmParams);
|
||||
}
|
||||
m_macTxQueueTrace (p, true);
|
||||
|
||||
TxQueueElement *txQElement = new TxQueueElement;
|
||||
txQElement->txQMsduHandle = params.m_msduHandle;
|
||||
txQElement->txQPkt = p;
|
||||
if (m_txQueue.empty ())
|
||||
m_txQueue.push_back (txQElement);
|
||||
|
||||
CheckQueue ();
|
||||
}
|
||||
|
||||
void
|
||||
LrWpanMac::CheckQueue ()
|
||||
{
|
||||
// Pull a packet from the queue and start sending, if we are not already sending.
|
||||
if (m_lrWpanMacState == MAC_IDLE && !m_txQueue.empty () && m_txPkt == 0)
|
||||
{
|
||||
m_txPkt = txQElement->txQPkt->Copy ();
|
||||
m_txQueue.push_front (txQElement); // the first packet in the queue is currently worked on
|
||||
// Start CCA process for this packet
|
||||
Simulator::ScheduleNow (&LrWpanCsmaCa::Start, m_csmaCa);
|
||||
}
|
||||
else
|
||||
{
|
||||
// if queue is not empty put this packet at the end of Tx queue
|
||||
m_txQueue.push_back (txQElement);
|
||||
TxQueueElement *txQElement = m_txQueue.front ();
|
||||
m_txPkt = txQElement->txQPkt;
|
||||
Simulator::ScheduleNow (&LrWpanMac::SetLrWpanMacState, this, MAC_CSMA);
|
||||
}
|
||||
}
|
||||
|
||||
void LrWpanMac::SetCsmaCa (Ptr<LrWpanCsmaCa> csmaCa)
|
||||
void
|
||||
LrWpanMac::SetCsmaCa (Ptr<LrWpanCsmaCa> csmaCa)
|
||||
{
|
||||
m_csmaCa = csmaCa;
|
||||
}
|
||||
|
||||
void LrWpanMac::SetPhy (Ptr<LrWpanPhy> phy)
|
||||
void
|
||||
LrWpanMac::SetPhy (Ptr<LrWpanPhy> phy)
|
||||
{
|
||||
m_phy = phy;
|
||||
}
|
||||
|
||||
Ptr<LrWpanPhy> LrWpanMac::GetPhy (void)
|
||||
Ptr<LrWpanPhy>
|
||||
LrWpanMac::GetPhy (void)
|
||||
{
|
||||
return m_phy;
|
||||
}
|
||||
@@ -355,38 +423,14 @@ LrWpanMac::SetMcpsDataConfirmCallback (McpsDataConfirmCallback c)
|
||||
}
|
||||
|
||||
void
|
||||
LrWpanMac::PdDataIndication (uint32_t psduLength, Ptr<Packet> p, uint32_t lqi)
|
||||
LrWpanMac::PdDataIndication (uint32_t psduLength, Ptr<Packet> p, uint8_t lqi)
|
||||
{
|
||||
NS_ASSERT (m_lrWpanMacState == MAC_IDLE || m_lrWpanMacState == MAC_ACK_PENDING || m_lrWpanMacState == MAC_CSMA);
|
||||
|
||||
NS_LOG_FUNCTION (this << psduLength << p << lqi);
|
||||
|
||||
bool acceptFrame;
|
||||
|
||||
Ptr<Packet> originalPkt = p->Copy (); // because we will strip headers
|
||||
LrWpanMacHeader receivedMacHdr;
|
||||
p->RemoveHeader (receivedMacHdr);
|
||||
LrWpanMacTrailer receivedMacTrailer;
|
||||
p->RemoveTrailer (receivedMacTrailer);
|
||||
|
||||
m_promiscSnifferTrace (originalPkt);
|
||||
|
||||
McpsDataIndicationParams params;
|
||||
params.m_dsn = receivedMacHdr.GetSeqNum ();
|
||||
params.m_mpduLinkQuality = lqi;
|
||||
params.m_srcPanId = receivedMacHdr.GetSrcPanId ();
|
||||
params.m_srcAddrMode = receivedMacHdr.GetSrcAddrMode ();
|
||||
if (params.m_srcAddrMode == SHORT_ADDR)
|
||||
{
|
||||
params.m_srcAddr = receivedMacHdr.GetShortSrcAddr ();
|
||||
}
|
||||
params.m_dstPanId = receivedMacHdr.GetDstPanId ();
|
||||
params.m_dstAddrMode = receivedMacHdr.GetDstAddrMode ();
|
||||
if (params.m_dstAddrMode == SHORT_ADDR)
|
||||
{
|
||||
params.m_dstAddr = receivedMacHdr.GetShortDstAddr ();
|
||||
}
|
||||
|
||||
NS_LOG_DEBUG ("Packet from " << params.m_srcAddr << " to " << params.m_dstAddr);
|
||||
|
||||
// from sec 7.5.6.2 Reception and rejection, Std802.15.4-2006
|
||||
// level 1 filtering, test FCS field and reject if frame fails
|
||||
// level 2 filtering if promiscuous mode pass frame to higher layer otherwise perform level 3 filtering
|
||||
@@ -397,79 +441,56 @@ LrWpanMac::PdDataIndication (uint32_t psduLength, Ptr<Packet> p, uint32_t lqi)
|
||||
// if beacon frame then srcPanId = m_macPanId
|
||||
// if only srcAddr field in Data or Command frame,accept frame if srcPanId=m_macPanId
|
||||
|
||||
Ptr<Packet> originalPkt = p->Copy (); // because we will strip headers
|
||||
|
||||
m_promiscSnifferTrace (originalPkt);
|
||||
|
||||
m_macPromiscRxTrace (originalPkt);
|
||||
// XXX no rejection tracing (to macRxDropTrace) being performed below
|
||||
|
||||
if (m_macPromiscuousMode)
|
||||
LrWpanMacTrailer receivedMacTrailer;
|
||||
p->RemoveTrailer (receivedMacTrailer);
|
||||
if (Node::ChecksumEnabled ())
|
||||
{
|
||||
//level 2 filtering
|
||||
if (!m_mcpsDataIndicationCallback.IsNull ())
|
||||
{
|
||||
NS_LOG_DEBUG ("promiscuous mode, forwarding up");
|
||||
m_mcpsDataIndicationCallback (params, p);
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_ERROR (this << " Data Indication Callback not initialised");
|
||||
}
|
||||
receivedMacTrailer.EnableFcs (true);
|
||||
}
|
||||
|
||||
// level 1 filtering
|
||||
if(!receivedMacTrailer.CheckFcs (p))
|
||||
{
|
||||
m_macRxDropTrace (originalPkt);
|
||||
}
|
||||
else
|
||||
{
|
||||
//level 3 frame filtering
|
||||
acceptFrame = (receivedMacHdr.GetType () != LrWpanMacHeader::LRWPAN_MAC_RESERVED);
|
||||
LrWpanMacHeader receivedMacHdr;
|
||||
p->RemoveHeader (receivedMacHdr);
|
||||
|
||||
if (acceptFrame)
|
||||
McpsDataIndicationParams params;
|
||||
params.m_dsn = receivedMacHdr.GetSeqNum ();
|
||||
params.m_mpduLinkQuality = lqi;
|
||||
params.m_srcPanId = receivedMacHdr.GetSrcPanId ();
|
||||
params.m_srcAddrMode = receivedMacHdr.GetSrcAddrMode ();
|
||||
// TODO: Add field for EXT_ADDR source address.
|
||||
if (params.m_srcAddrMode == SHORT_ADDR)
|
||||
{
|
||||
acceptFrame = (receivedMacHdr.GetFrameVer () <= 1);
|
||||
params.m_srcAddr = receivedMacHdr.GetShortSrcAddr ();
|
||||
}
|
||||
params.m_dstPanId = receivedMacHdr.GetDstPanId ();
|
||||
params.m_dstAddrMode = receivedMacHdr.GetDstAddrMode ();
|
||||
// TODO: Add field for EXT_ADDR destination address.
|
||||
if (params.m_dstAddrMode == SHORT_ADDR)
|
||||
{
|
||||
params.m_dstAddr = receivedMacHdr.GetShortDstAddr ();
|
||||
}
|
||||
|
||||
if (acceptFrame
|
||||
&& (receivedMacHdr.GetDstAddrMode () > 1))
|
||||
{
|
||||
acceptFrame = receivedMacHdr.GetDstPanId () == m_macPanId
|
||||
|| receivedMacHdr.GetDstPanId () == 0xffff;
|
||||
}
|
||||
NS_LOG_DEBUG ("Packet from " << params.m_srcAddr << " to " << params.m_dstAddr);
|
||||
|
||||
if (acceptFrame
|
||||
&& (receivedMacHdr.GetDstAddrMode () == 2))
|
||||
if (m_macPromiscuousMode)
|
||||
{
|
||||
acceptFrame = receivedMacHdr.GetShortDstAddr () == m_shortAddress
|
||||
|| receivedMacHdr.GetShortDstAddr () == Mac16Address ("ff:ff"); // check for broadcast addrs
|
||||
}
|
||||
|
||||
if (acceptFrame
|
||||
&& (receivedMacHdr.GetDstAddrMode () == 3))
|
||||
{
|
||||
acceptFrame = (receivedMacHdr.GetExtDstAddr () == m_selfExt);
|
||||
}
|
||||
|
||||
if (acceptFrame
|
||||
&& (receivedMacHdr.GetType () == LrWpanMacHeader::LRWPAN_MAC_BEACON))
|
||||
{
|
||||
if (m_macPanId == 0xffff)
|
||||
{
|
||||
acceptFrame = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
acceptFrame = receivedMacHdr.GetSrcPanId () == m_macPanId;
|
||||
}
|
||||
}
|
||||
|
||||
if (acceptFrame
|
||||
&& ((receivedMacHdr.GetType () == LrWpanMacHeader::LRWPAN_MAC_DATA)
|
||||
|| (receivedMacHdr.GetType () == LrWpanMacHeader::LRWPAN_MAC_COMMAND))
|
||||
&& (receivedMacHdr.GetSrcAddrMode () > 1))
|
||||
{
|
||||
acceptFrame = receivedMacHdr.GetSrcPanId () == m_macPanId; //TODO need to check if PAN coord
|
||||
}
|
||||
|
||||
if (acceptFrame)
|
||||
{
|
||||
m_macRxTrace (originalPkt);
|
||||
//level 2 filtering
|
||||
if (!m_mcpsDataIndicationCallback.IsNull ())
|
||||
{
|
||||
NS_LOG_DEBUG ("PdDataIndication(): Packet is for me; forwarding up");
|
||||
NS_LOG_DEBUG ("promiscuous mode, forwarding up");
|
||||
m_mcpsDataIndicationCallback (params, p);
|
||||
}
|
||||
else
|
||||
@@ -479,36 +500,288 @@ LrWpanMac::PdDataIndication (uint32_t psduLength, Ptr<Packet> p, uint32_t lqi)
|
||||
}
|
||||
else
|
||||
{
|
||||
m_macRxDropTrace (originalPkt);
|
||||
p = 0;
|
||||
//level 3 frame filtering
|
||||
acceptFrame = (receivedMacHdr.GetType () != LrWpanMacHeader::LRWPAN_MAC_RESERVED);
|
||||
|
||||
if (acceptFrame)
|
||||
{
|
||||
acceptFrame = (receivedMacHdr.GetFrameVer () <= 1);
|
||||
}
|
||||
|
||||
if (acceptFrame
|
||||
&& (receivedMacHdr.GetDstAddrMode () > 1))
|
||||
{
|
||||
acceptFrame = receivedMacHdr.GetDstPanId () == m_macPanId
|
||||
|| receivedMacHdr.GetDstPanId () == 0xffff;
|
||||
}
|
||||
|
||||
if (acceptFrame
|
||||
&& (receivedMacHdr.GetDstAddrMode () == 2))
|
||||
{
|
||||
acceptFrame = receivedMacHdr.GetShortDstAddr () == m_shortAddress
|
||||
|| receivedMacHdr.GetShortDstAddr () == Mac16Address ("ff:ff"); // check for broadcast addrs
|
||||
}
|
||||
|
||||
if (acceptFrame
|
||||
&& (receivedMacHdr.GetDstAddrMode () == 3))
|
||||
{
|
||||
acceptFrame = (receivedMacHdr.GetExtDstAddr () == m_selfExt);
|
||||
}
|
||||
|
||||
if (acceptFrame
|
||||
&& (receivedMacHdr.GetType () == LrWpanMacHeader::LRWPAN_MAC_BEACON))
|
||||
{
|
||||
if (m_macPanId == 0xffff)
|
||||
{
|
||||
// TODO: Accept only if the frame version field is valid
|
||||
acceptFrame = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
acceptFrame = receivedMacHdr.GetSrcPanId () == m_macPanId;
|
||||
}
|
||||
}
|
||||
|
||||
if (acceptFrame
|
||||
&& ((receivedMacHdr.GetType () == LrWpanMacHeader::LRWPAN_MAC_DATA)
|
||||
|| (receivedMacHdr.GetType () == LrWpanMacHeader::LRWPAN_MAC_COMMAND))
|
||||
&& (receivedMacHdr.GetSrcAddrMode () > 1))
|
||||
{
|
||||
acceptFrame = receivedMacHdr.GetSrcPanId () == m_macPanId; //TODO need to check if PAN coord
|
||||
}
|
||||
|
||||
if (acceptFrame)
|
||||
{
|
||||
m_macRxTrace (originalPkt);
|
||||
// TODO: What should we do if we receive a frame while waiting for an ACK?
|
||||
// Especially if this frame has the ACK request bit set, should we reply with an ACK, possibly missing the pending ACK?
|
||||
|
||||
// If the received frame is a frame with the ACK request bit set, we immediately send back an ACK.
|
||||
// If we are currently waiting for a pending ACK, we assume the ACK was lost and trigger a retransmission after sending the ACK.
|
||||
if ((receivedMacHdr.IsData () || receivedMacHdr.IsCommand ()) && receivedMacHdr.IsAckReq ()
|
||||
&& !(receivedMacHdr.GetDstAddrMode () == SHORT_ADDR && receivedMacHdr.GetShortDstAddr () == "ff:ff"))
|
||||
{
|
||||
// If this is a data or mac command frame, which is not a broadcast,
|
||||
// with ack req set, generate and send an ack frame.
|
||||
// If there is a CSMA medium access in progress we cancel the medium access
|
||||
// for sending the ACK frame. A new transmission attempt will be started
|
||||
// after the ACK was send.
|
||||
if (m_lrWpanMacState == MAC_ACK_PENDING)
|
||||
{
|
||||
m_ackWaitTimeout.Cancel ();
|
||||
PrepareRetransmission ();
|
||||
}
|
||||
else if (m_lrWpanMacState == MAC_CSMA)
|
||||
{
|
||||
// TODO: If we receive a packet while doing CSMA/CA, should we drop the packet because of channel busy,
|
||||
// or should we restart CSMA/CA for the packet after sending the ACK?
|
||||
// Currently we simply restart CSMA/CA after sending the ACK.
|
||||
m_csmaCa->Cancel ();
|
||||
}
|
||||
ChangeMacState (MAC_IDLE);
|
||||
Simulator::ScheduleNow (&LrWpanMac::SendAck, this, receivedMacHdr.GetSeqNum ());
|
||||
}
|
||||
|
||||
if (receivedMacHdr.IsData () && !m_mcpsDataIndicationCallback.IsNull ())
|
||||
{
|
||||
// If it is a data frame, push it up the stack.
|
||||
NS_LOG_DEBUG ("PdDataIndication(): Packet is for me; forwarding up");
|
||||
m_mcpsDataIndicationCallback (params, p);
|
||||
}
|
||||
else if (receivedMacHdr.IsAcknowledgment () && m_txPkt && m_lrWpanMacState == MAC_ACK_PENDING)
|
||||
{
|
||||
LrWpanMacHeader macHdr;;
|
||||
m_txPkt->PeekHeader (macHdr);
|
||||
if (receivedMacHdr.GetSeqNum () == macHdr.GetSeqNum ())
|
||||
{
|
||||
// If it is an ACK with the expected sequence number, finish the transmission
|
||||
// and notify the upper layer.
|
||||
m_ackWaitTimeout.Cancel ();
|
||||
if (!m_mcpsDataConfirmCallback.IsNull ())
|
||||
{
|
||||
TxQueueElement *txQElement = m_txQueue.front ();
|
||||
McpsDataConfirmParams confirmParams;
|
||||
confirmParams.m_msduHandle = txQElement->txQMsduHandle;
|
||||
confirmParams.m_status = IEEE_802_15_4_SUCCESS;
|
||||
m_mcpsDataConfirmCallback (confirmParams);
|
||||
}
|
||||
RemoveFirstTxQElement ();
|
||||
Simulator::ScheduleNow (&LrWpanMac::SetLrWpanMacState, this, MAC_IDLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If it is an ACK with an unexpected sequence number, mark the current transmission as failed and start a retransmit. (cf 7.5.6.4.3)
|
||||
m_ackWaitTimeout.Cancel ();
|
||||
if (!PrepareRetransmission ())
|
||||
{
|
||||
Simulator::ScheduleNow (&LrWpanMac::SetLrWpanMacState, this, MAC_IDLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
Simulator::ScheduleNow (&LrWpanMac::SetLrWpanMacState, this, MAC_CSMA);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_macRxDropTrace (originalPkt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
LrWpanMac::SendAck (uint8_t seqno)
|
||||
{
|
||||
NS_ASSERT (m_lrWpanMacState == MAC_IDLE);
|
||||
|
||||
// Generate a corresponding ACK Frame.
|
||||
LrWpanMacHeader macHdr (LrWpanMacHeader::LRWPAN_MAC_ACKNOWLEDGMENT, seqno);
|
||||
LrWpanMacTrailer macTrailer;
|
||||
Ptr<Packet> ackPacket = Create<Packet> (0);
|
||||
ackPacket->AddHeader (macHdr);
|
||||
ackPacket->AddTrailer (macTrailer);
|
||||
|
||||
// Enqueue the ACK packet for further processing
|
||||
// when the transmitter is activated.
|
||||
m_txPkt = ackPacket;
|
||||
|
||||
// Switch transceiver to TX mode. Proceed sending the Ack on confirm.
|
||||
ChangeMacState (MAC_SENDING);
|
||||
m_phy->PlmeSetTRXStateRequest (IEEE_802_15_4_PHY_TX_ON);
|
||||
}
|
||||
|
||||
void
|
||||
LrWpanMac::RemoveFirstTxQElement (void)
|
||||
{
|
||||
TxQueueElement *txQElement = m_txQueue.front ();
|
||||
Ptr<const Packet> p = txQElement->txQPkt;
|
||||
txQElement->txQPkt = 0;
|
||||
delete txQElement;
|
||||
m_txQueue.pop_front ();
|
||||
m_txPkt = 0;
|
||||
m_retransmission = 0;
|
||||
m_macTxQueueTrace (p, false);
|
||||
}
|
||||
|
||||
void
|
||||
LrWpanMac::AckWaitTimeout (void)
|
||||
{
|
||||
// TODO: If we are a PAN coordinator and this was an indirect transmission,
|
||||
// we will not initiate a retransmission. Instead we wait for the data
|
||||
// being extracted after a new data request command.
|
||||
if (!PrepareRetransmission ())
|
||||
{
|
||||
SetLrWpanMacState (MAC_IDLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLrWpanMacState (MAC_CSMA);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
LrWpanMac::PrepareRetransmission (void)
|
||||
{
|
||||
if (m_retransmission >= m_macMaxFrameRetries)
|
||||
{
|
||||
// Maximum number of retransmissions has been reached.
|
||||
// remove the copy of the packet that was just sent
|
||||
TxQueueElement *txQElement = m_txQueue.front ();
|
||||
m_macTxDropTrace (txQElement->txQPkt);
|
||||
if (!m_mcpsDataConfirmCallback.IsNull ())
|
||||
{
|
||||
McpsDataConfirmParams confirmParams;
|
||||
confirmParams.m_msduHandle = txQElement->txQMsduHandle;
|
||||
confirmParams.m_status = IEEE_802_15_4_NO_ACK;
|
||||
m_mcpsDataConfirmCallback (confirmParams);
|
||||
}
|
||||
RemoveFirstTxQElement ();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_retransmission++;
|
||||
// Start next CCA process for this packet.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LrWpanMac::PdDataConfirm (LrWpanPhyEnumeration status)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << status << m_txQueue.empty () ? 0 : m_txQueue.size ());
|
||||
m_phy->PlmeSetTRXStateRequest (IEEE_802_15_4_PHY_RX_ON);
|
||||
NS_ASSERT (m_lrWpanMacState == MAC_SENDING);
|
||||
|
||||
if (status == IEEE_802_15_4_PHY_SUCCESS || status == IEEE_802_15_4_PHY_UNSPECIFIED)
|
||||
NS_LOG_FUNCTION (this << status << (m_txQueue.empty () ? 0 : m_txQueue.size ()));
|
||||
|
||||
TxQueueElement *txQElement = m_txQueue.front ();
|
||||
|
||||
LrWpanMacHeader macHdr;
|
||||
m_txPkt->PeekHeader (macHdr);
|
||||
if (status == IEEE_802_15_4_PHY_SUCCESS)
|
||||
{
|
||||
// remove the copy of the packet that was just sent
|
||||
TxQueueElement *txQElement = m_txQueue.front ();
|
||||
txQElement->txQPkt = 0;
|
||||
delete txQElement;
|
||||
m_txQueue.pop_front ();
|
||||
ChangeMacState (CHANNEL_IDLE);
|
||||
if (!m_txQueue.empty ())
|
||||
if (!macHdr.IsAcknowledgment ())
|
||||
{
|
||||
NS_LOG_FUNCTION ("PdDataConfirm: start CCA process for next packet");
|
||||
// Start CCA process for next packet in the tx queue
|
||||
m_txPkt = m_txQueue.front ()->txQPkt->Copy ();
|
||||
Simulator::ScheduleNow (&LrWpanCsmaCa::Start, m_csmaCa);
|
||||
// We have just send a regular data packet, check if we have to wait
|
||||
// for an ACK.
|
||||
if (macHdr.IsAckReq ())
|
||||
{
|
||||
// wait for the ack or the next retransmission timeout
|
||||
// start retransmission timer
|
||||
Time waitTime = MicroSeconds (GetMacAckWaitDuration () * 1000 * 1000 / m_phy->GetDataOrSymbolRate (false));
|
||||
NS_ASSERT (m_ackWaitTimeout.IsExpired());
|
||||
m_ackWaitTimeout = Simulator::Schedule (waitTime, &LrWpanMac::AckWaitTimeout, this);
|
||||
Simulator::ScheduleNow (&LrWpanMac::SetLrWpanMacState, this, MAC_ACK_PENDING);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// remove the copy of the packet that was just sent
|
||||
if (!m_mcpsDataConfirmCallback.IsNull ())
|
||||
{
|
||||
McpsDataConfirmParams confirmParams;
|
||||
confirmParams.m_msduHandle = txQElement->txQMsduHandle;
|
||||
confirmParams.m_status = IEEE_802_15_4_SUCCESS;
|
||||
m_mcpsDataConfirmCallback (confirmParams);
|
||||
}
|
||||
RemoveFirstTxQElement ();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// We have send an ACK. Clear the packet buffer.
|
||||
m_txPkt = 0;
|
||||
}
|
||||
}
|
||||
else if (status == IEEE_802_15_4_PHY_UNSPECIFIED)
|
||||
{
|
||||
|
||||
if (!macHdr.IsAcknowledgment ())
|
||||
{
|
||||
m_macTxDropTrace (txQElement->txQPkt);
|
||||
if (!m_mcpsDataConfirmCallback.IsNull ())
|
||||
{
|
||||
McpsDataConfirmParams confirmParams;
|
||||
confirmParams.m_msduHandle = txQElement->txQMsduHandle;
|
||||
confirmParams.m_status = IEEE_802_15_4_FRAME_TOO_LONG;
|
||||
m_mcpsDataConfirmCallback (confirmParams);
|
||||
}
|
||||
RemoveFirstTxQElement ();
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_ERROR ("Unable to send ACK");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Something went really wrong. The PHY is not in the correct state for
|
||||
// data transmission.
|
||||
NS_FATAL_ERROR ("Transmission attempt failed with PHY status " << status);
|
||||
}
|
||||
|
||||
Simulator::ScheduleNow (&LrWpanMac::SetLrWpanMacState, this, MAC_IDLE);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -529,7 +802,7 @@ LrWpanMac::PlmeEdConfirm (LrWpanPhyEnumeration status, uint8_t energyLevel)
|
||||
void
|
||||
LrWpanMac::PlmeGetAttributeConfirm (LrWpanPhyEnumeration status,
|
||||
LrWpanPibAttributeIdentifier id,
|
||||
LrWpanPhyPIBAttributes* attribute)
|
||||
LrWpanPhyPibAttributes* attribute)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << status << id << attribute);
|
||||
}
|
||||
@@ -538,14 +811,36 @@ void
|
||||
LrWpanMac::PlmeSetTRXStateConfirm (LrWpanPhyEnumeration status)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << status);
|
||||
if (status == IEEE_802_15_4_PHY_TX_ON || status == IEEE_802_15_4_PHY_SUCCESS)
|
||||
|
||||
if (m_lrWpanMacState == MAC_SENDING && (status == IEEE_802_15_4_PHY_TX_ON || status == IEEE_802_15_4_PHY_SUCCESS))
|
||||
{
|
||||
if ((m_txPkt) && (m_lrWpanMacState == SET_PHY_TX_ON))
|
||||
{
|
||||
m_promiscSnifferTrace (m_txPkt);
|
||||
m_snifferTrace (m_txPkt);
|
||||
m_phy->PdDataRequest (m_txPkt->GetSize (), m_txPkt);
|
||||
}
|
||||
NS_ASSERT (m_txPkt);
|
||||
|
||||
// Start sending if we are in state SENDING and the PHY transmitter was enabled.
|
||||
m_promiscSnifferTrace (m_txPkt);
|
||||
m_snifferTrace (m_txPkt);
|
||||
m_phy->PdDataRequest (m_txPkt->GetSize (), m_txPkt);
|
||||
}
|
||||
else if (m_lrWpanMacState == MAC_CSMA && (status == IEEE_802_15_4_PHY_RX_ON || status == IEEE_802_15_4_PHY_SUCCESS))
|
||||
{
|
||||
// Start the CSMA algorithm as soon as the receiver is enabled.
|
||||
m_csmaCa->Start ();
|
||||
}
|
||||
else if (m_lrWpanMacState == MAC_IDLE)
|
||||
{
|
||||
NS_ASSERT (status == IEEE_802_15_4_PHY_RX_ON || status == IEEE_802_15_4_PHY_SUCCESS || status == IEEE_802_15_4_PHY_TRX_OFF);
|
||||
// Do nothing special when going idle.
|
||||
}
|
||||
else if (m_lrWpanMacState == MAC_ACK_PENDING)
|
||||
{
|
||||
NS_ASSERT (status == IEEE_802_15_4_PHY_RX_ON || status == IEEE_802_15_4_PHY_SUCCESS);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: What to do when we receive an error?
|
||||
// If we want to transmit a packet, but switching the transceiver on results
|
||||
// in an error, we have to recover somehow (and start sending again).
|
||||
NS_FATAL_ERROR ("Error changing transceiver state");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -563,39 +858,57 @@ LrWpanMac::SetLrWpanMacState (LrWpanMacState macState)
|
||||
|
||||
McpsDataConfirmParams confirmParams;
|
||||
|
||||
ChangeMacState (macState);
|
||||
if ((m_lrWpanMacState == CHANNEL_IDLE) && (m_txPkt))
|
||||
if (macState == MAC_IDLE)
|
||||
{
|
||||
ChangeMacState (MAC_IDLE);
|
||||
|
||||
if (m_macRxOnWhenIdle)
|
||||
{
|
||||
m_phy->PlmeSetTRXStateRequest (IEEE_802_15_4_PHY_RX_ON);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_phy->PlmeSetTRXStateRequest (IEEE_802_15_4_PHY_TRX_OFF);
|
||||
}
|
||||
|
||||
CheckQueue ();
|
||||
}
|
||||
else if (macState == MAC_ACK_PENDING)
|
||||
{
|
||||
ChangeMacState (MAC_ACK_PENDING);
|
||||
m_phy->PlmeSetTRXStateRequest (IEEE_802_15_4_PHY_RX_ON);
|
||||
}
|
||||
else if (macState == MAC_CSMA)
|
||||
{
|
||||
NS_ASSERT (m_lrWpanMacState == MAC_IDLE);
|
||||
|
||||
ChangeMacState (MAC_CSMA);
|
||||
m_phy->PlmeSetTRXStateRequest (IEEE_802_15_4_PHY_RX_ON);
|
||||
}
|
||||
else if (m_lrWpanMacState == MAC_CSMA && macState == CHANNEL_IDLE)
|
||||
{
|
||||
// Channel is idle, set transmitter to TX_ON
|
||||
NS_LOG_DEBUG ( this << " channel idle");
|
||||
ChangeMacState (SET_PHY_TX_ON);
|
||||
ChangeMacState (MAC_SENDING);
|
||||
m_phy->PlmeSetTRXStateRequest (IEEE_802_15_4_PHY_TX_ON);
|
||||
}
|
||||
else if ((m_lrWpanMacState == CHANNEL_ACCESS_FAILURE) && (m_txPkt))
|
||||
else if (m_lrWpanMacState == MAC_CSMA && macState == CHANNEL_ACCESS_FAILURE)
|
||||
{
|
||||
NS_ASSERT (m_txPkt);
|
||||
|
||||
// cannot find a clear channel, drop the current packet.
|
||||
NS_LOG_DEBUG ( this << " cannot find clear channel");
|
||||
confirmParams.m_msduHandle = m_txQueue.front ()->txQMsduHandle;
|
||||
confirmParams.m_status = IEEE_802_15_4_CHANNEL_ACCESS_FAILURE;
|
||||
m_macTxDropTrace (m_txPkt);
|
||||
// remove the copy of the packet that was just sent
|
||||
TxQueueElement *txQElement = m_txQueue.front ();
|
||||
txQElement->txQPkt = 0;
|
||||
delete txQElement;
|
||||
m_txQueue.pop_front ();
|
||||
if (!m_mcpsDataConfirmCallback.IsNull ())
|
||||
{
|
||||
m_mcpsDataConfirmCallback (confirmParams);
|
||||
}
|
||||
// if there are more packets waiting to be sent
|
||||
if (!m_txQueue.empty ())
|
||||
{
|
||||
// Start CCA process for next packet in the tx queue
|
||||
m_txPkt = m_txQueue.front ()->txQPkt->Copy ();
|
||||
Simulator::ScheduleNow (&LrWpanCsmaCa::Start, m_csmaCa);
|
||||
}
|
||||
}
|
||||
// remove the copy of the packet that was just sent
|
||||
RemoveFirstTxQElement ();
|
||||
|
||||
Simulator::ScheduleNow (&LrWpanMac::SetLrWpanMacState, this, MAC_IDLE);
|
||||
}
|
||||
}
|
||||
|
||||
LrWpanAssociationStatus
|
||||
@@ -631,4 +944,24 @@ LrWpanMac::ChangeMacState (LrWpanMacState newState)
|
||||
m_macStateLogger (Simulator::Now (), m_lrWpanMacState, newState);
|
||||
m_lrWpanMacState = newState;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
LrWpanMac::GetMacAckWaitDuration (void) const
|
||||
{
|
||||
return m_csmaCa->getUnitBackoffPeriod () + m_phy->aTurnaroundTime + m_phy->GetPhySHRDuration ()
|
||||
+ ceil (6 * m_phy->GetPhySymbolsPerOctet ());
|
||||
}
|
||||
|
||||
uint8_t
|
||||
LrWpanMac::GetMacMaxFrameRetries (void) const
|
||||
{
|
||||
return m_macMaxFrameRetries;
|
||||
}
|
||||
|
||||
void
|
||||
LrWpanMac::SetMacMaxFrameRetries (uint8_t retries)
|
||||
{
|
||||
m_macMaxFrameRetries = retries;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -19,35 +19,44 @@
|
||||
* Gary Pei <guangyu.pei@boeing.com>
|
||||
* kwong yin <kwong-sang.yin@boeing.com>
|
||||
* Tom Henderson <thomas.r.henderson@boeing.com>
|
||||
* Sascha Alexander Jopen <jopen@cs.uni-bonn.de>
|
||||
*/
|
||||
#ifndef LR_WPAN_MAC_H
|
||||
#define LR_WPAN_MAC_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
#include "ns3/object.h"
|
||||
#include "ns3/callback.h"
|
||||
#include "ns3/mac16-address.h"
|
||||
#include "lr-wpan-phy.h"
|
||||
#include "lr-wpan-mac-header.h"
|
||||
#include "lr-wpan-mac-trailer.h"
|
||||
#include "ns3/mac16-address.h"
|
||||
#include "ns3/mac64-address.h"
|
||||
#include <ns3/object.h>
|
||||
#include <ns3/traced-callback.h>
|
||||
#include <ns3/mac16-address.h>
|
||||
#include <ns3/mac64-address.h>
|
||||
#include <ns3/sequence-number.h>
|
||||
#include <ns3/lr-wpan-phy.h>
|
||||
#include <ns3/event-id.h>
|
||||
#include <deque>
|
||||
#include "ns3/sequence-number.h"
|
||||
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class Packet;
|
||||
class LrWpanCsmaCa;
|
||||
|
||||
/**
|
||||
* \defgroup lr-wpan LR-WPAN models
|
||||
*
|
||||
* This section documents the API of the IEEE 802.15.4-related models. For a generic functional description, please refer to the ns-3 manual.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
TX_OPTION_ACK = 1,
|
||||
TX_OPTION_GTS = 2,
|
||||
TX_OPTION_INDIRECT = 4
|
||||
} LrWpanTxOption;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MAC_IDLE,
|
||||
MAC_CSMA,
|
||||
MAC_SENDING,
|
||||
MAC_ACK_PENDING,
|
||||
CHANNEL_ACCESS_FAILURE,
|
||||
CHANNEL_IDLE,
|
||||
SET_PHY_TX_ON
|
||||
@@ -97,8 +106,12 @@ typedef enum
|
||||
|
||||
struct McpsDataRequestParams
|
||||
{
|
||||
uint8_t m_srcAddrMode;
|
||||
uint8_t m_dstAddrMode;
|
||||
McpsDataRequestParams () :
|
||||
m_srcAddrMode (SHORT_ADDR), m_dstAddrMode (SHORT_ADDR), m_dstPanId (0),
|
||||
m_dstAddr (), m_msduHandle (0), m_txOptions (0)
|
||||
{ };
|
||||
LrWpanAddressMode m_srcAddrMode;
|
||||
LrWpanAddressMode m_dstAddrMode;
|
||||
uint16_t m_dstPanId;
|
||||
Mac16Address m_dstAddr;
|
||||
uint8_t m_msduHandle;
|
||||
@@ -126,16 +139,15 @@ struct McpsDataIndicationParams
|
||||
// This callback is called after a McpsDataRequest has been called from
|
||||
// the higher layer. It returns a status of the outcome of the
|
||||
// transmission request
|
||||
typedef Callback< void, McpsDataConfirmParams > McpsDataConfirmCallback;
|
||||
typedef Callback<void, McpsDataConfirmParams> McpsDataConfirmCallback;
|
||||
|
||||
// This callback is called after a Mcps has successfully received a
|
||||
// frame and wants to deliver it to the higher layer.
|
||||
//
|
||||
// XXX for now, we do not deliver all of the parameters in section
|
||||
// 7.1.1.3.1 but just send up the packet.
|
||||
typedef Callback< void, McpsDataIndicationParams, Ptr<Packet> > McpsDataIndicationCallback;
|
||||
typedef Callback<void, McpsDataIndicationParams, Ptr<Packet> > McpsDataIndicationCallback;
|
||||
|
||||
class LrWpanCsmaCa;
|
||||
|
||||
/**
|
||||
* \ingroup lr-wpan
|
||||
@@ -153,6 +165,9 @@ public:
|
||||
LrWpanMac ();
|
||||
virtual ~LrWpanMac ();
|
||||
|
||||
bool GetRxOnWhenIdle ();
|
||||
void SetRxOnWhenIdle (bool rxOnWhenIdle);
|
||||
|
||||
// XXX these setters will become obsolete if we use the attribute system
|
||||
void SetShortAddress (Mac16Address address);
|
||||
Mac16Address GetShortAddress (void) const;
|
||||
@@ -188,7 +203,7 @@ public:
|
||||
* @param p the packet to be transmitted
|
||||
* @param lqi Link quality (LQI) value measured during reception of the PPDU
|
||||
*/
|
||||
void PdDataIndication (uint32_t psduLength, Ptr<Packet> p, uint32_t lqi);
|
||||
void PdDataIndication (uint32_t psduLength, Ptr<Packet> p, uint8_t lqi);
|
||||
|
||||
/**
|
||||
* IEEE 802.15.4-2006 section 6.2.1.2
|
||||
@@ -223,7 +238,7 @@ public:
|
||||
*/
|
||||
void PlmeGetAttributeConfirm (LrWpanPhyEnumeration status,
|
||||
LrWpanPibAttributeIdentifier id,
|
||||
LrWpanPhyPIBAttributes* attribute);
|
||||
LrWpanPhyPibAttributes* attribute);
|
||||
|
||||
/**
|
||||
* IEEE 802.15.4-2006 section 6.2.2.8
|
||||
@@ -263,7 +278,7 @@ public:
|
||||
uint64_t m_aBaseSlotDuration; // 60 symbols in each superframe slot
|
||||
uint64_t m_aNumSuperframeSlots; // 16 slots in each superframe
|
||||
uint64_t m_aBaseSuperframeDuration; // aBaseSlotDuration * aNumSuperframeSlots in symbols
|
||||
|
||||
|
||||
//MAC PIB attributes
|
||||
uint64_t m_macBeaconTxTime; // time the device tx last beacon frame in symbols, only 24 bits used
|
||||
uint64_t m_macSyncSymbolOffset; // symbol boundary is same as m_macBeaconTxTime
|
||||
@@ -271,11 +286,33 @@ public:
|
||||
uint64_t m_macSuperframeOrder; // 0..14 and 15 means superframe shall not remain active after beacon
|
||||
bool m_macPromiscuousMode; // Indicates if MAC sublayer is in receive all mode. True mean accept all frames from PHY.
|
||||
uint16_t m_macPanId; // 16bits id of PAN on which this device is operating. 0xffff means not asscoiated
|
||||
SequenceNumber16 m_macDsn; //Seq num added to transmitted data or MAC command frame 00-ff
|
||||
SequenceNumber16 m_macDsn; // Seq num added to transmitted data or MAC command frame 00-ff
|
||||
uint8_t m_macMaxFrameRetries; // The maximum number of retries allowed after a transmission failure
|
||||
|
||||
uint64_t GetMacAckWaitDuration (void) const;
|
||||
uint8_t GetMacMaxFrameRetries (void) const;
|
||||
void SetMacMaxFrameRetries (uint8_t retries);
|
||||
|
||||
protected:
|
||||
virtual void DoInitialize (void);
|
||||
virtual void DoDispose (void);
|
||||
|
||||
private:
|
||||
virtual void DoDispose (void);
|
||||
struct TxQueueElement
|
||||
{
|
||||
uint8_t txQMsduHandle;
|
||||
Ptr<Packet> txQPkt;
|
||||
};
|
||||
|
||||
void SendAck (uint8_t seqno);
|
||||
void RemoveFirstTxQElement (void);
|
||||
void ChangeMacState (LrWpanMacState newState);
|
||||
void AckWaitTimeout (void);
|
||||
bool PrepareRetransmission (void);
|
||||
void CheckQueue (void);
|
||||
|
||||
|
||||
TracedCallback<Ptr<const Packet>, bool> m_macTxQueueTrace;
|
||||
/**
|
||||
* The trace source fired when packets come into the "top" of the device
|
||||
* at the L3/L2 transition, before being queued for transmission.
|
||||
@@ -373,13 +410,10 @@ private:
|
||||
Ptr<Packet> m_txPkt; // XXX need packet buffer instead of single packet
|
||||
Mac16Address m_shortAddress;
|
||||
Mac64Address m_selfExt;
|
||||
|
||||
struct TxQueueElement
|
||||
{
|
||||
uint8_t txQMsduHandle;
|
||||
Ptr<Packet> txQPkt;
|
||||
};
|
||||
std::deque<TxQueueElement*> m_txQueue;
|
||||
uint8_t m_retransmission;
|
||||
EventId m_ackWaitTimeout;
|
||||
bool m_macRxOnWhenIdle;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -15,18 +15,24 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Tom Henderson <thomas.r.henderson@boeing.com>
|
||||
* Author:
|
||||
* Tom Henderson <thomas.r.henderson@boeing.com>
|
||||
* Tommaso Pecorella <tommaso.pecorella@unifi.it>
|
||||
* Margherita Filippetti <morag87@gmail.com>
|
||||
*/
|
||||
|
||||
#include "ns3/abort.h"
|
||||
#include "ns3/node.h"
|
||||
#include "lr-wpan-net-device.h"
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/lr-wpan-mac.h"
|
||||
#include "ns3/lr-wpan-phy.h"
|
||||
#include "ns3/lr-wpan-csmaca.h"
|
||||
#include "ns3/spectrum-channel.h"
|
||||
#include "ns3/pointer.h"
|
||||
#include "lr-wpan-phy.h"
|
||||
#include "lr-wpan-csmaca.h"
|
||||
#include "lr-wpan-error-model.h"
|
||||
#include <ns3/abort.h>
|
||||
#include <ns3/node.h>
|
||||
#include <ns3/log.h>
|
||||
#include <ns3/spectrum-channel.h>
|
||||
#include <ns3/pointer.h>
|
||||
#include <ns3/boolean.h>
|
||||
#include <ns3/mobility-model.h>
|
||||
#include <ns3/packet.h>
|
||||
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("LrWpanNetDevice");
|
||||
|
||||
@@ -54,6 +60,10 @@ LrWpanNetDevice::GetTypeId (void)
|
||||
MakePointerAccessor (&LrWpanNetDevice::GetMac,
|
||||
&LrWpanNetDevice::SetMac),
|
||||
MakePointerChecker<LrWpanMac> ())
|
||||
.AddAttribute ("UseAcks", "Request acknowledgments for data frames.",
|
||||
BooleanValue (true),
|
||||
MakeBooleanAccessor (&LrWpanNetDevice::m_useAcks),
|
||||
MakeBooleanChecker ())
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
@@ -114,11 +124,13 @@ LrWpanNetDevice::CompleteConfig (void)
|
||||
}
|
||||
m_mac->SetPhy (m_phy);
|
||||
m_mac->SetCsmaCa (m_csmaca);
|
||||
m_mac->SetMcpsDataIndicationCallback (MakeCallback (&LrWpanNetDevice::McpsDataIndication, this));
|
||||
m_csmaca->SetMac (m_mac);
|
||||
|
||||
m_phy->SetMobility (m_node->GetObject<MobilityModel> ());
|
||||
Ptr<LrWpanErrorModel> model = CreateObject<LrWpanErrorModel> ();
|
||||
m_phy->SetErrorModel (model);
|
||||
m_phy->SetDevice (this);
|
||||
|
||||
m_phy->SetPdDataIndicationCallback (MakeCallback (&LrWpanMac::PdDataIndication, m_mac));
|
||||
m_phy->SetPdDataConfirmCallback (MakeCallback (&LrWpanMac::PdDataConfirm, m_mac));
|
||||
@@ -252,8 +264,12 @@ LrWpanNetDevice::SetMtu (const uint16_t mtu)
|
||||
uint16_t
|
||||
LrWpanNetDevice::GetMtu (void) const
|
||||
{
|
||||
NS_ABORT_MSG ("Unsupported");
|
||||
return 0;
|
||||
NS_LOG_FUNCTION (this);
|
||||
// Maximum payload size is: max psdu - frame control - seqno - addressing - security - fcs
|
||||
// = 127 - 2 - 1 - (2+2+2+2) - 0 - 2
|
||||
// = 114
|
||||
// assuming no security and addressing with only 16 bit addresses without pan id compression.
|
||||
return 114;
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -280,15 +296,15 @@ LrWpanNetDevice::IsBroadcast (void) const
|
||||
Address
|
||||
LrWpanNetDevice::GetBroadcast (void) const
|
||||
{
|
||||
NS_ABORT_MSG ("Unsupported; add me");
|
||||
return Address ();
|
||||
NS_LOG_FUNCTION (this);
|
||||
return Mac16Address ("ff:ff");
|
||||
}
|
||||
|
||||
bool
|
||||
LrWpanNetDevice::IsMulticast (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
Address
|
||||
@@ -301,8 +317,34 @@ LrWpanNetDevice::GetMulticast (Ipv4Address multicastGroup) const
|
||||
Address
|
||||
LrWpanNetDevice::GetMulticast (Ipv6Address addr) const
|
||||
{
|
||||
NS_ABORT_MSG ("Unsupported");
|
||||
return Address ();
|
||||
NS_LOG_FUNCTION (this);
|
||||
/* Implementation based on RFC 4944 Section 9.
|
||||
* An IPv6 packet with a multicast destination address (DST),
|
||||
* consisting of the sixteen octets DST[1] through DST[16], is
|
||||
* transmitted to the following 802.15.4 16-bit multicast address:
|
||||
* 0 1
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* |1 0 0|DST[15]* | DST[16] |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* Here, DST[15]* refers to the last 5 bits in octet DST[15], that is,
|
||||
* bits 3-7 within DST[15]. The initial 3-bit pattern of "100" follows
|
||||
* the 16-bit address format for multicast addresses (Section 12). */
|
||||
|
||||
// \todo re-add this once Lr-Wpan will be able to accept these multicast addresses
|
||||
// uint8_t buf[16];
|
||||
// uint8_t buf2[2];
|
||||
//
|
||||
// addr.GetBytes(buf);
|
||||
//
|
||||
// buf2[0] = 0x80 | (buf[14] & 0x1F);
|
||||
// buf2[1] = buf[15];
|
||||
//
|
||||
// Mac16Address newaddr = Mac16Address();
|
||||
// newaddr.CopyFrom(buf2);
|
||||
// return newaddr;
|
||||
|
||||
return Mac16Address ("ff:ff");
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -327,14 +369,35 @@ LrWpanNetDevice::Send (Ptr<Packet> packet, const Address& dest, uint16_t protoco
|
||||
// McpsDataRequest parameters.
|
||||
// For further study: how to support these methods somehow, such as
|
||||
// inventing a fake ethertype and packet tag for McpsDataRequest
|
||||
NS_ABORT_MSG ("Unsupported; use McpsDataRequest instead");
|
||||
return false;
|
||||
NS_LOG_FUNCTION (this << packet << dest << protocolNumber);
|
||||
|
||||
if (packet->GetSize () > GetMtu ())
|
||||
{
|
||||
NS_LOG_ERROR ("Fragmentation is needed for this packet, drop the packet ");
|
||||
return false;
|
||||
}
|
||||
|
||||
McpsDataRequestParams m_mcpsDataRequestParams;
|
||||
m_mcpsDataRequestParams.m_dstAddr = Mac16Address::ConvertFrom (dest);
|
||||
m_mcpsDataRequestParams.m_dstAddrMode = SHORT_ADDR;
|
||||
m_mcpsDataRequestParams.m_dstPanId = m_mac->GetPanId ();
|
||||
m_mcpsDataRequestParams.m_srcAddrMode = SHORT_ADDR;
|
||||
// Using ACK requests for broadcast destinations is ok here. They are disabled
|
||||
// by the MAC.
|
||||
if (m_useAcks)
|
||||
{
|
||||
m_mcpsDataRequestParams.m_txOptions = TX_OPTION_ACK;
|
||||
}
|
||||
m_mcpsDataRequestParams.m_msduHandle = 0;
|
||||
m_mac->McpsDataRequest (m_mcpsDataRequestParams, packet);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
LrWpanNetDevice::SendFrom (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber)
|
||||
{
|
||||
NS_ABORT_MSG ("Unsupported; use McpsDataRequest instead");
|
||||
NS_ABORT_MSG ("Unsupported");
|
||||
// TODO: To support SendFrom, the MACs McpsDataRequest has to use the provided source address, instead of to local one.
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -356,19 +419,15 @@ LrWpanNetDevice::SetNode (Ptr<Node> node)
|
||||
bool
|
||||
LrWpanNetDevice::NeedsArp (void) const
|
||||
{
|
||||
NS_ABORT_MSG ("Unsupported");
|
||||
return false;
|
||||
NS_LOG_FUNCTION (this);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
LrWpanNetDevice::SetReceiveCallback (ReceiveCallback cb)
|
||||
{
|
||||
// This method basically assumes an 802.3-compliant device, but a raw
|
||||
// 802.15.4 device does not have an ethertype, and requires specific
|
||||
// McpsDataIndication parameters.
|
||||
// For further study: how to support these methods somehow, such as
|
||||
// inventing a fake ethertype and packet tag for McpsDataRequest
|
||||
NS_LOG_WARN ("Unsupported; use LrWpan MAC APIs instead");
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_receiveCallback = cb;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -382,6 +441,14 @@ LrWpanNetDevice::SetPromiscReceiveCallback (PromiscReceiveCallback cb)
|
||||
NS_LOG_WARN ("Unsupported; use LrWpan MAC APIs instead");
|
||||
}
|
||||
|
||||
void
|
||||
LrWpanNetDevice::McpsDataIndication (McpsDataIndicationParams params, Ptr<Packet> pkt)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
// TODO: Use the PromiscReceiveCallback if the MAC is in promiscuous mode.
|
||||
m_receiveCallback (this, pkt, 0, params.m_srcAddr);
|
||||
}
|
||||
|
||||
bool
|
||||
LrWpanNetDevice::SupportsSendFrom (void) const
|
||||
{
|
||||
|
||||
@@ -15,20 +15,20 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Tom Henderson <thomas.r.henderson@boeing.com>
|
||||
* Author:
|
||||
* Tom Henderson <thomas.r.henderson@boeing.com>
|
||||
* Tommaso Pecorella <tommaso.pecorella@unifi.it>
|
||||
* Margherita Filippetti <morag87@gmail.com>
|
||||
*/
|
||||
#ifndef LR_WPAN_NET_DEVICE_H
|
||||
#define LR_WPAN_NET_DEVICE_H
|
||||
|
||||
#include <string>
|
||||
#include <stdint.h>
|
||||
#include "ns3/net-device.h"
|
||||
#include "ns3/traced-callback.h"
|
||||
|
||||
#include <ns3/net-device.h>
|
||||
#include <ns3/traced-callback.h>
|
||||
#include <ns3/lr-wpan-mac.h>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class LrWpanMac;
|
||||
class LrWpanPhy;
|
||||
class LrWpanCsmaCa;
|
||||
class SingleModelSpectrumChannel;
|
||||
@@ -52,8 +52,8 @@ class LrWpanNetDevice : public NetDevice
|
||||
public:
|
||||
static TypeId GetTypeId (void);
|
||||
|
||||
LrWpanNetDevice ();
|
||||
virtual ~LrWpanNetDevice ();
|
||||
LrWpanNetDevice (void);
|
||||
virtual ~LrWpanNetDevice (void);
|
||||
|
||||
void SetMac (Ptr<LrWpanMac> mac);
|
||||
void SetPhy (Ptr<LrWpanPhy> phy);
|
||||
@@ -103,6 +103,8 @@ public:
|
||||
virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb);
|
||||
virtual bool SupportsSendFrom (void) const;
|
||||
|
||||
void McpsDataIndication (McpsDataIndicationParams params, Ptr<Packet> pkt);
|
||||
|
||||
private:
|
||||
virtual void DoDispose (void);
|
||||
virtual void DoStart (void);
|
||||
@@ -116,13 +118,15 @@ private:
|
||||
Ptr<LrWpanCsmaCa> m_csmaca;
|
||||
Ptr<Node> m_node;
|
||||
bool m_configComplete;
|
||||
bool m_useAcks;
|
||||
|
||||
bool m_linkUp;
|
||||
uint32_t m_ifIndex;
|
||||
|
||||
TracedCallback<> m_linkChanges;
|
||||
ReceiveCallback m_receiveCallback;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif /* NET_DEVICE_H */
|
||||
#endif /* LR_WPAN_NET_DEVICE_H */
|
||||
|
||||
@@ -15,14 +15,25 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Gary Pei <guangyu.pei@boeing.com>
|
||||
* Author:
|
||||
* Gary Pei <guangyu.pei@boeing.com>
|
||||
* Sascha Alexander Jopen <jopen@cs.uni-bonn.de>
|
||||
*/
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/abort.h"
|
||||
#include <math.h>
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/lr-wpan-phy.h"
|
||||
#include "ns3/trace-source-accessor.h"
|
||||
#include "lr-wpan-phy.h"
|
||||
#include "lr-wpan-lqi-tag.h"
|
||||
#include "lr-wpan-spectrum-signal-parameters.h"
|
||||
#include "lr-wpan-spectrum-value-helper.h"
|
||||
#include "lr-wpan-error-model.h"
|
||||
#include <ns3/log.h>
|
||||
#include <ns3/abort.h>
|
||||
#include <ns3/simulator.h>
|
||||
#include <ns3/spectrum-value.h>
|
||||
#include <ns3/antenna-model.h>
|
||||
#include <ns3/mobility-model.h>
|
||||
#include <ns3/spectrum-channel.h>
|
||||
#include <ns3/packet.h>
|
||||
#include <ns3/packet-burst.h>
|
||||
#include <ns3/net-device.h>
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("LrWpanPhy");
|
||||
|
||||
@@ -91,8 +102,7 @@ LrWpanPhy::LrWpanPhy ()
|
||||
: m_edRequest (),
|
||||
m_setTRXState ()
|
||||
{
|
||||
m_trxState = IEEE_802_15_4_PHY_IDLE;
|
||||
ChangeTrxState (IEEE_802_15_4_PHY_RX_ON);
|
||||
m_trxState = IEEE_802_15_4_PHY_TRX_OFF;
|
||||
m_trxStatePending = IEEE_802_15_4_PHY_IDLE;
|
||||
|
||||
// default PHY PIB attributes
|
||||
@@ -121,6 +131,8 @@ LrWpanPhy::LrWpanPhy ()
|
||||
m_currentRxPacket = std::make_pair (none, true);
|
||||
m_currentTxPacket = std::make_pair (none, true);
|
||||
m_errorModel = 0;
|
||||
|
||||
ChangeTrxState (IEEE_802_15_4_PHY_TRX_OFF);
|
||||
}
|
||||
|
||||
LrWpanPhy::~LrWpanPhy ()
|
||||
@@ -131,6 +143,12 @@ void
|
||||
LrWpanPhy::DoDispose ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
// Cancel pending transceiver state change, if one is in progress.
|
||||
m_setTRXState.Cancel ();
|
||||
m_trxState = IEEE_802_15_4_PHY_TRX_OFF;
|
||||
m_trxStatePending = IEEE_802_15_4_PHY_IDLE;
|
||||
|
||||
m_mobility = 0;
|
||||
m_device = 0;
|
||||
m_channel = 0;
|
||||
@@ -138,11 +156,11 @@ LrWpanPhy::DoDispose ()
|
||||
m_rxPsd = 0;
|
||||
m_noise = 0;
|
||||
m_errorModel = 0;
|
||||
m_pdDataIndicationCallback = MakeNullCallback< void, uint32_t, Ptr<Packet>, uint32_t > ();
|
||||
m_pdDataIndicationCallback = MakeNullCallback< void, uint32_t, Ptr<Packet>, uint8_t > ();
|
||||
m_pdDataConfirmCallback = MakeNullCallback< void, LrWpanPhyEnumeration > ();
|
||||
m_plmeCcaConfirmCallback = MakeNullCallback< void, LrWpanPhyEnumeration > ();
|
||||
m_plmeEdConfirmCallback = MakeNullCallback< void, LrWpanPhyEnumeration,uint8_t > ();
|
||||
m_plmeGetAttributeConfirmCallback = MakeNullCallback< void, LrWpanPhyEnumeration, LrWpanPibAttributeIdentifier, LrWpanPhyPIBAttributes* > ();
|
||||
m_plmeGetAttributeConfirmCallback = MakeNullCallback< void, LrWpanPhyEnumeration, LrWpanPibAttributeIdentifier, LrWpanPhyPibAttributes* > ();
|
||||
m_plmeSetTRXStateConfirmCallback = MakeNullCallback< void, LrWpanPhyEnumeration > ();
|
||||
m_plmeSetAttributeConfirmCallback = MakeNullCallback< void, LrWpanPhyEnumeration, LrWpanPibAttributeIdentifier > ();
|
||||
|
||||
@@ -192,6 +210,7 @@ LrWpanPhy::SetChannel (Ptr<SpectrumChannel> c)
|
||||
Ptr<SpectrumChannel>
|
||||
LrWpanPhy::GetChannel (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
return m_channel;
|
||||
}
|
||||
|
||||
@@ -199,6 +218,7 @@ LrWpanPhy::GetChannel (void)
|
||||
Ptr<const SpectrumModel>
|
||||
LrWpanPhy::GetRxSpectrumModel () const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
if (m_txPsd)
|
||||
{
|
||||
return m_txPsd->GetSpectrumModel ();
|
||||
@@ -212,6 +232,7 @@ LrWpanPhy::GetRxSpectrumModel () const
|
||||
Ptr<AntennaModel>
|
||||
LrWpanPhy::GetRxAntenna ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
return m_antenna;
|
||||
}
|
||||
|
||||
@@ -233,25 +254,53 @@ LrWpanPhy::StartRx (Ptr<SpectrumSignalParameters> spectrumRxParams)
|
||||
|
||||
Ptr<LrWpanSpectrumSignalParameters> lrWpanRxParams = DynamicCast<LrWpanSpectrumSignalParameters> (spectrumRxParams);
|
||||
|
||||
if (lrWpanRxParams != 0)
|
||||
if (m_trxState == IEEE_802_15_4_PHY_RX_ON)
|
||||
{
|
||||
// The specification doesn't seem to refer to BUSY_RX, but vendor
|
||||
// data sheets suggest that this is a substate of the RX_ON state
|
||||
// that is entered after preamble detection when the digital receiver
|
||||
// is enabled. Here, for now, we use BUSY_RX to mark the period between
|
||||
// StartRx() and EndRx() states.
|
||||
ChangeTrxState (IEEE_802_15_4_PHY_BUSY_RX);
|
||||
if (lrWpanRxParams != 0)
|
||||
{
|
||||
// The specification doesn't seem to refer to BUSY_RX, but vendor
|
||||
// data sheets suggest that this is a substate of the RX_ON state
|
||||
// that is entered after preamble detection when the digital receiver
|
||||
// is enabled. Here, for now, we use BUSY_RX to mark the period between
|
||||
// StartRx() and EndRx() states.
|
||||
Ptr<Packet> p = (lrWpanRxParams->packetBurst->GetPackets ()).front ();
|
||||
NS_ASSERT(p != 0);
|
||||
m_rxPsd = lrWpanRxParams->psd;
|
||||
m_rxTotalPower = psdHelper.TotalAvgPower (m_rxPsd);
|
||||
|
||||
Time duration = lrWpanRxParams->duration;
|
||||
if (m_rxTotalPower >= m_rxSensitivity)
|
||||
{
|
||||
ChangeTrxState (IEEE_802_15_4_PHY_BUSY_RX);
|
||||
Time duration = lrWpanRxParams->duration;
|
||||
m_currentRxPacket = std::make_pair (p, false);
|
||||
|
||||
Ptr<Packet> p = (lrWpanRxParams->packetBurst->GetPackets ()).front ();
|
||||
m_currentRxPacket = std::make_pair (p, false);
|
||||
m_rxPsd = lrWpanRxParams->psd;
|
||||
m_rxTotalPower = psdHelper.TotalAvgPower (*m_rxPsd);
|
||||
Simulator::Schedule (duration, &LrWpanPhy::EndRx, this);
|
||||
m_phyRxBeginTrace (p);
|
||||
Simulator::Schedule (duration, &LrWpanPhy::EndRx, this);
|
||||
m_phyRxBeginTrace (p);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We are below our receiver sensitivity, the packet cannot be received.
|
||||
// TODO: Add the power somehow to the interference.
|
||||
m_phyRxDropTrace (p);
|
||||
}
|
||||
}
|
||||
NS_LOG_LOGIC (this << " state: " << m_trxState << " m_rxTotalPower: " << m_rxTotalPower);
|
||||
}
|
||||
else if (m_trxState == IEEE_802_15_4_PHY_BUSY_RX)
|
||||
{
|
||||
// TODO: Drop the second packet and add the signal power to the interference of
|
||||
// the currently received packet. Consider the received signal power
|
||||
// during CCA/ED, too.
|
||||
NS_LOG_DEBUG (this << " packet collision");
|
||||
Ptr<Packet> p = (lrWpanRxParams->packetBurst->GetPackets ()).front ();
|
||||
m_phyRxDropTrace (p);
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_DEBUG (this << " transceiver not in RX state");
|
||||
Ptr<Packet> p = (lrWpanRxParams->packetBurst->GetPackets ()).front ();
|
||||
m_phyRxDropTrace (p);
|
||||
}
|
||||
NS_LOG_LOGIC (this << " state: " << m_trxState << " m_rxTotalPower: " << m_rxTotalPower);
|
||||
}
|
||||
|
||||
void LrWpanPhy::EndRx ()
|
||||
@@ -261,62 +310,84 @@ void LrWpanPhy::EndRx ()
|
||||
// Calculate whether packet was lost
|
||||
if (m_currentRxPacket.second == true)
|
||||
{
|
||||
NS_LOG_DEBUG ("Reception was previously terminated; dropping packet");
|
||||
m_phyRxDropTrace (m_currentRxPacket.first);
|
||||
}
|
||||
else if (m_errorModel != 0)
|
||||
{
|
||||
double sinr = psdHelper.TotalAvgPower (*m_rxPsd) / psdHelper.TotalAvgPower (*m_noise);
|
||||
Ptr<Packet> p = m_currentRxPacket.first;
|
||||
// Simplified calculation; the chunk is the whole packet
|
||||
double per = 1.0 - m_errorModel->GetChunkSuccessRate (sinr, p->GetSize () * 8);
|
||||
if (m_random.GetValue () > per)
|
||||
if (m_currentRxPacket.first != 0)
|
||||
{
|
||||
NS_LOG_DEBUG ("Reception success for packet: per " << per << " sinr " << sinr);
|
||||
m_phyRxEndTrace (p, sinr);
|
||||
if (!m_pdDataIndicationCallback.IsNull ())
|
||||
NS_LOG_DEBUG ("Reception was previously terminated; dropping packet");
|
||||
m_phyRxDropTrace (m_currentRxPacket.first);
|
||||
m_currentRxPacket.first = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: This should never happen, but it does!
|
||||
NS_LOG_UNCOND (this << " Finishing receive of NULL packet!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_errorModel != 0)
|
||||
{
|
||||
double sinr = psdHelper.TotalAvgPower (m_rxPsd) / psdHelper.TotalAvgPower (m_noise);
|
||||
Ptr<Packet> p = m_currentRxPacket.first;
|
||||
NS_ASSERT (p != 0);
|
||||
p->AddPacketTag (LrWpanLqiTag (sinr));
|
||||
|
||||
// Simplified calculation; the chunk is the whole packet
|
||||
double per = 1.0 - m_errorModel->GetChunkSuccessRate (sinr, p->GetSize () * 8);
|
||||
if (m_random.GetValue () > per)
|
||||
{
|
||||
m_pdDataIndicationCallback (p->GetSize (), p, (uint32_t)sinr);
|
||||
NS_LOG_DEBUG ("Reception success for packet: per " << per << " sinr " << sinr);
|
||||
m_phyRxEndTrace (p, sinr);
|
||||
if (!m_pdDataIndicationCallback.IsNull ())
|
||||
{
|
||||
m_pdDataIndicationCallback (p->GetSize (), p, (uint8_t)sinr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Failure */
|
||||
NS_LOG_DEBUG ("Reception failure for packet per" << per << " sinr " << sinr);
|
||||
m_phyRxEndTrace (p, sinr);
|
||||
m_phyRxDropTrace (p);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Failure */
|
||||
NS_LOG_DEBUG ("Reception failure for packet per" << per << " sinr " << sinr);
|
||||
m_phyRxEndTrace (p, sinr);
|
||||
m_phyRxDropTrace (p);
|
||||
NS_LOG_WARN ("Missing ErrorModel");
|
||||
Ptr<Packet> p = m_currentRxPacket.first;
|
||||
p->AddPacketTag (LrWpanLqiTag ());
|
||||
m_phyRxEndTrace (p, 0);
|
||||
if (!m_pdDataIndicationCallback.IsNull ())
|
||||
{
|
||||
m_pdDataIndicationCallback (p->GetSize (), p, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_WARN ("Missing ErrorModel");
|
||||
Ptr<Packet> p = m_currentRxPacket.first;
|
||||
m_phyRxEndTrace (p, 0);
|
||||
if (!m_pdDataIndicationCallback.IsNull ())
|
||||
{
|
||||
m_pdDataIndicationCallback (p->GetSize (), p, 0);
|
||||
}
|
||||
}
|
||||
|
||||
m_rxTotalPower = 0;
|
||||
m_currentRxPacket.first = 0;
|
||||
m_currentRxPacket.second = false;
|
||||
// We may be waiting to apply a pending state change
|
||||
if (m_trxStatePending != IEEE_802_15_4_PHY_IDLE)
|
||||
{
|
||||
NS_LOG_LOGIC ("Apply pending state change to " << m_trxStatePending);
|
||||
ChangeTrxState (m_trxStatePending);
|
||||
m_trxStatePending = IEEE_802_15_4_PHY_IDLE;
|
||||
if (!m_plmeSetTRXStateConfirmCallback.IsNull ())
|
||||
m_rxTotalPower = 0;
|
||||
Ptr<Packet> none = 0;
|
||||
m_currentRxPacket = std::make_pair (none, true);
|
||||
|
||||
// We may be waiting to apply a pending state change.
|
||||
if (m_trxStatePending != IEEE_802_15_4_PHY_IDLE)
|
||||
{
|
||||
m_plmeSetTRXStateConfirmCallback (IEEE_802_15_4_PHY_SUCCESS);
|
||||
// Only change the state immediately, if the transceiver is not already
|
||||
// switching the state.
|
||||
if (!m_setTRXState.IsRunning ())
|
||||
{
|
||||
NS_LOG_LOGIC ("Apply pending state change to " << m_trxStatePending);
|
||||
ChangeTrxState (m_trxStatePending);
|
||||
m_trxStatePending = IEEE_802_15_4_PHY_IDLE;
|
||||
if (!m_plmeSetTRXStateConfirmCallback.IsNull ())
|
||||
{
|
||||
m_plmeSetTRXStateConfirmCallback (IEEE_802_15_4_PHY_SUCCESS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_trxState != IEEE_802_15_4_PHY_TRX_OFF)
|
||||
else
|
||||
{
|
||||
ChangeTrxState (IEEE_802_15_4_PHY_RX_ON);
|
||||
if (m_trxState != IEEE_802_15_4_PHY_TRX_OFF)
|
||||
{
|
||||
ChangeTrxState (IEEE_802_15_4_PHY_RX_ON);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -341,6 +412,10 @@ LrWpanPhy::PdDataRequest (const uint32_t psduLength, Ptr<Packet> p)
|
||||
//send down
|
||||
NS_ASSERT (m_channel);
|
||||
|
||||
// Remove a possible LQI tag from a previous transmission of the packet.
|
||||
LrWpanLqiTag lqiTag;
|
||||
p->RemovePacketTag (lqiTag);
|
||||
|
||||
Ptr<LrWpanSpectrumSignalParameters> txParams = Create<LrWpanSpectrumSignalParameters> ();
|
||||
txParams->duration = CalculateTxTime (p);
|
||||
txParams->txPhy = GetObject<SpectrumPhy> ();
|
||||
@@ -379,17 +454,24 @@ void
|
||||
LrWpanPhy::PlmeCcaRequest (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
if (m_trxState == IEEE_802_15_4_PHY_RX_ON)
|
||||
if (m_trxState == IEEE_802_15_4_PHY_RX_ON || m_trxState == IEEE_802_15_4_PHY_BUSY_RX)
|
||||
{
|
||||
//call StartRx or ED and then get updated m_rxTotalPower in EndCCA?
|
||||
Time ccaTime = Seconds (8.0 / GetDataOrSymbolRate (false));
|
||||
Simulator::Schedule (ccaTime, &LrWpanPhy::EndCca, this);
|
||||
m_ccaRequest = Simulator::Schedule (ccaTime, &LrWpanPhy::EndCca, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!m_plmeCcaConfirmCallback.IsNull ())
|
||||
{
|
||||
m_plmeCcaConfirmCallback (m_trxState);
|
||||
if (m_trxState == IEEE_802_15_4_PHY_TRX_OFF)
|
||||
{
|
||||
m_plmeCcaConfirmCallback (IEEE_802_15_4_PHY_TRX_OFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_plmeCcaConfirmCallback (IEEE_802_15_4_PHY_BUSY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -441,8 +523,8 @@ LrWpanPhy::PlmeGetAttributeRequest (LrWpanPibAttributeIdentifier id)
|
||||
}
|
||||
if (!m_plmeGetAttributeConfirmCallback.IsNull ())
|
||||
{
|
||||
LrWpanPhyPIBAttributes retValue;
|
||||
memcpy (&retValue, &m_phyPIBAttributes, sizeof(LrWpanPhyPIBAttributes));
|
||||
LrWpanPhyPibAttributes retValue;
|
||||
memcpy (&retValue, &m_phyPIBAttributes, sizeof(LrWpanPhyPibAttributes));
|
||||
m_plmeGetAttributeConfirmCallback (status,id,&retValue);
|
||||
}
|
||||
}
|
||||
@@ -460,17 +542,24 @@ LrWpanPhy::PlmeSetTRXStateRequest (LrWpanPhyEnumeration state)
|
||||
&& (state != IEEE_802_15_4_PHY_TX_ON) );
|
||||
|
||||
NS_LOG_LOGIC ("Trying to set m_trxState from " << m_trxState << " to " << state);
|
||||
|
||||
// this method always overrides previous state setting attempts
|
||||
if (!m_setTRXState.IsExpired ())
|
||||
{
|
||||
if (m_trxStatePending == state)
|
||||
{
|
||||
// Simply wait for the ongoing state switch.
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_DEBUG ("Cancel m_setTRXState");
|
||||
m_setTRXState.Cancel();
|
||||
}
|
||||
}
|
||||
if (m_trxStatePending != IEEE_802_15_4_PHY_IDLE)
|
||||
{
|
||||
m_trxStatePending = IEEE_802_15_4_PHY_IDLE;
|
||||
}
|
||||
if (m_setTRXState.IsRunning ())
|
||||
{
|
||||
NS_LOG_DEBUG ("Cancel m_setTRXState");
|
||||
m_setTRXState.Cancel ();
|
||||
}
|
||||
|
||||
if (state == m_trxState)
|
||||
{
|
||||
@@ -494,19 +583,29 @@ LrWpanPhy::PlmeSetTRXStateRequest (LrWpanPhyEnumeration state)
|
||||
// a valid SFD. Here, we are not modelling at that level of
|
||||
// granularity, so we just test for BUSY_RX state (any part of
|
||||
// a packet being actively received)
|
||||
if ((state == IEEE_802_15_4_PHY_TRX_OFF)
|
||||
&& (m_trxState == IEEE_802_15_4_PHY_BUSY_RX)
|
||||
&& (m_currentRxPacket.first) && (!m_currentRxPacket.second))
|
||||
if (state == IEEE_802_15_4_PHY_TRX_OFF)
|
||||
{
|
||||
NS_LOG_DEBUG ("Receiver has valid SFD; defer state change");
|
||||
m_trxStatePending = state;
|
||||
return; // Send PlmeSetTRXStateConfirm later
|
||||
if ((m_trxState == IEEE_802_15_4_PHY_BUSY_RX)
|
||||
&& (m_currentRxPacket.first) && (!m_currentRxPacket.second))
|
||||
{
|
||||
NS_LOG_DEBUG ("Receiver has valid SFD; defer state change");
|
||||
m_trxStatePending = state;
|
||||
return; // Send PlmeSetTRXStateConfirm later
|
||||
}
|
||||
else if (m_trxState == IEEE_802_15_4_PHY_RX_ON || m_trxState == IEEE_802_15_4_PHY_TX_ON)
|
||||
{
|
||||
ChangeTrxState (IEEE_802_15_4_PHY_TRX_OFF);
|
||||
if (!m_plmeSetTRXStateConfirmCallback.IsNull ())
|
||||
{
|
||||
m_plmeSetTRXStateConfirmCallback (state);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (state == IEEE_802_15_4_PHY_TX_ON)
|
||||
{
|
||||
NS_LOG_DEBUG ("turn on PHY_TX_ON");
|
||||
ChangeTrxState (IEEE_802_15_4_PHY_TX_ON);
|
||||
if ((m_trxState == IEEE_802_15_4_PHY_BUSY_RX) || (m_trxState == IEEE_802_15_4_PHY_RX_ON))
|
||||
{
|
||||
if (m_currentRxPacket.first)
|
||||
@@ -516,16 +615,44 @@ LrWpanPhy::PlmeSetTRXStateRequest (LrWpanPhyEnumeration state)
|
||||
NS_LOG_DEBUG ("force TX_ON, terminate reception");
|
||||
m_currentRxPacket.second = true;
|
||||
}
|
||||
|
||||
// If CCA is in progress, cancel CCA and return BUSY.
|
||||
if (!m_ccaRequest.IsExpired ())
|
||||
{
|
||||
m_ccaRequest.Cancel ();
|
||||
if (!m_plmeCcaConfirmCallback.IsNull ())
|
||||
{
|
||||
m_plmeCcaConfirmCallback (IEEE_802_15_4_PHY_BUSY);
|
||||
}
|
||||
}
|
||||
|
||||
m_trxStatePending = IEEE_802_15_4_PHY_TX_ON;
|
||||
// Prevent PHY from receiving another packet while switching.
|
||||
ChangeTrxState (IEEE_802_15_4_PHY_IDLE);
|
||||
|
||||
// Delay for turnaround time
|
||||
// TODO: Does it also take aTurnaroundTime to switch the transceiver state,
|
||||
// even when the receiver is not busy? (6.9.2)
|
||||
Time setTime = Seconds ( (double) aTurnaroundTime / GetDataOrSymbolRate (false));
|
||||
m_setTRXState = Simulator::Schedule (setTime, &LrWpanPhy::EndSetTRXState, this);
|
||||
return;
|
||||
}
|
||||
else
|
||||
else if (m_trxState == IEEE_802_15_4_PHY_BUSY_TX || m_trxState == IEEE_802_15_4_PHY_TX_ON)
|
||||
{
|
||||
// We do NOT change the transceiver state here. We only report that
|
||||
// the transceiver is already in TX_ON state.
|
||||
if (!m_plmeSetTRXStateConfirmCallback.IsNull ())
|
||||
{
|
||||
m_plmeSetTRXStateConfirmCallback (IEEE_802_15_4_PHY_SUCCESS);
|
||||
m_plmeSetTRXStateConfirmCallback (IEEE_802_15_4_PHY_TX_ON);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (m_trxState == IEEE_802_15_4_PHY_TRX_OFF)
|
||||
{
|
||||
ChangeTrxState (IEEE_802_15_4_PHY_TX_ON);
|
||||
if (!m_plmeSetTRXStateConfirmCallback.IsNull ())
|
||||
{
|
||||
m_plmeSetTRXStateConfirmCallback (IEEE_802_15_4_PHY_TX_ON);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -550,7 +677,6 @@ LrWpanPhy::PlmeSetTRXStateRequest (LrWpanPhyEnumeration state)
|
||||
{
|
||||
NS_LOG_DEBUG ("force TRX_OFF, terminate transmission");
|
||||
m_currentTxPacket.second = true;
|
||||
m_currentTxPacket.first = 0;
|
||||
}
|
||||
ChangeTrxState (IEEE_802_15_4_PHY_TRX_OFF);
|
||||
// Clear any other state
|
||||
@@ -563,15 +689,33 @@ LrWpanPhy::PlmeSetTRXStateRequest (LrWpanPhyEnumeration state)
|
||||
return;
|
||||
}
|
||||
|
||||
if ((state == IEEE_802_15_4_PHY_RX_ON) && (m_trxState == IEEE_802_15_4_PHY_TX_ON))
|
||||
if (state == IEEE_802_15_4_PHY_RX_ON)
|
||||
{
|
||||
// Turnaround delay
|
||||
m_trxStatePending = IEEE_802_15_4_PHY_RX_ON;
|
||||
Time setTime = Seconds ( (double) aTurnaroundTime / GetDataOrSymbolRate (false));
|
||||
m_setTRXState = Simulator::Schedule (setTime, &LrWpanPhy::EndSetTRXState, this);
|
||||
return;
|
||||
if (m_trxState == IEEE_802_15_4_PHY_TX_ON || m_trxState == IEEE_802_15_4_PHY_TRX_OFF)
|
||||
{
|
||||
// Turnaround delay
|
||||
// TODO: Does it really take aTurnaroundTime to switch the transceiver state,
|
||||
// even when the transmitter is not busy? (6.9.1)
|
||||
m_trxStatePending = IEEE_802_15_4_PHY_RX_ON;
|
||||
|
||||
// Prevent PHY from sending another packet while switching.
|
||||
ChangeTrxState (IEEE_802_15_4_PHY_IDLE);
|
||||
|
||||
Time setTime = Seconds ( (double) aTurnaroundTime / GetDataOrSymbolRate (false));
|
||||
m_setTRXState = Simulator::Schedule (setTime, &LrWpanPhy::EndSetTRXState, this);
|
||||
return;
|
||||
}
|
||||
else if (m_trxState == IEEE_802_15_4_PHY_BUSY_RX)
|
||||
{
|
||||
if (!m_plmeSetTRXStateConfirmCallback.IsNull ())
|
||||
{
|
||||
m_plmeSetTRXStateConfirmCallback (IEEE_802_15_4_PHY_RX_ON);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
NS_FATAL_ERROR ("Catch other transitions");
|
||||
|
||||
NS_FATAL_ERROR ("Unexpected transition from state " << m_trxState << " to state " << state);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -594,10 +738,10 @@ LrWpanPhy::ChannelSupported (uint8_t channel)
|
||||
|
||||
void
|
||||
LrWpanPhy::PlmeSetAttributeRequest (LrWpanPibAttributeIdentifier id,
|
||||
LrWpanPhyPIBAttributes* attribute)
|
||||
LrWpanPhyPibAttributes* attribute)
|
||||
{
|
||||
NS_ASSERT (attribute);
|
||||
NS_LOG_FUNCTION (this << id << attribute);
|
||||
NS_ASSERT (attribute);
|
||||
LrWpanPhyEnumeration status = IEEE_802_15_4_PHY_SUCCESS;
|
||||
|
||||
switch (id)
|
||||
@@ -609,7 +753,22 @@ LrWpanPhy::PlmeSetAttributeRequest (LrWpanPibAttributeIdentifier id,
|
||||
status = IEEE_802_15_4_PHY_INVALID_PARAMETER;
|
||||
}
|
||||
if (m_phyPIBAttributes.phyCurrentChannel != attribute->phyCurrentChannel)
|
||||
{ //any packet in transmission or reception will be corrupted
|
||||
{
|
||||
// Cancel a pending tranceiver state change.
|
||||
// Switch off the transceiver.
|
||||
// TODO: Is switching off the transceiver the right choice?
|
||||
m_trxState = IEEE_802_15_4_PHY_TRX_OFF;
|
||||
if (m_trxStatePending != IEEE_802_15_4_PHY_IDLE)
|
||||
{
|
||||
m_trxStatePending = IEEE_802_15_4_PHY_IDLE;
|
||||
m_setTRXState.Cancel ();
|
||||
if (!m_plmeSetTRXStateConfirmCallback.IsNull ())
|
||||
{
|
||||
m_plmeSetTRXStateConfirmCallback (IEEE_802_15_4_PHY_TRX_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
// Any packet in transmission or reception will be corrupted.
|
||||
if (m_currentRxPacket.first)
|
||||
{
|
||||
m_currentRxPacket.second = true;
|
||||
@@ -623,11 +782,6 @@ LrWpanPhy::PlmeSetAttributeRequest (LrWpanPibAttributeIdentifier id,
|
||||
{
|
||||
m_pdDataConfirmCallback (IEEE_802_15_4_PHY_TRX_OFF);
|
||||
}
|
||||
|
||||
if (m_trxStatePending != IEEE_802_15_4_PHY_IDLE)
|
||||
{
|
||||
m_trxStatePending = IEEE_802_15_4_PHY_IDLE;
|
||||
}
|
||||
}
|
||||
m_phyPIBAttributes.phyCurrentChannel = attribute->phyCurrentChannel;
|
||||
}
|
||||
@@ -744,6 +898,7 @@ LrWpanPhy::ChangeTrxState (LrWpanPhyEnumeration newState)
|
||||
bool
|
||||
LrWpanPhy::PhyIsBusy (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << m_trxState);
|
||||
return ((m_trxState == IEEE_802_15_4_PHY_BUSY_TX)
|
||||
|| (m_trxState == IEEE_802_15_4_PHY_BUSY_RX)
|
||||
|| (m_trxState == IEEE_802_15_4_PHY_BUSY));
|
||||
@@ -782,7 +937,7 @@ void
|
||||
LrWpanPhy::EndCca ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
LrWpanPhyEnumeration sensedChannelState;
|
||||
LrWpanPhyEnumeration sensedChannelState = IEEE_802_15_4_PHY_UNSPECIFIED;
|
||||
|
||||
if ((PhyIsBusy ()) || (m_rxTotalNum > 0))
|
||||
{
|
||||
@@ -842,7 +997,7 @@ LrWpanPhy::EndSetTRXState ()
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
NS_ABORT_IF ( (m_trxStatePending != IEEE_802_15_4_PHY_RX_ON) && (m_trxStatePending != IEEE_802_15_4_PHY_TX_ON) );
|
||||
m_trxState = m_trxStatePending;
|
||||
ChangeTrxState (m_trxStatePending);
|
||||
m_trxStatePending = IEEE_802_15_4_PHY_IDLE;
|
||||
|
||||
if (!m_plmeSetTRXStateConfirmCallback.IsNull ())
|
||||
@@ -880,25 +1035,38 @@ LrWpanPhy::EndTx ()
|
||||
}
|
||||
m_currentTxPacket.first = 0;
|
||||
m_currentTxPacket.second = false;
|
||||
|
||||
|
||||
// We may be waiting to apply a pending state change.
|
||||
if (m_trxStatePending != IEEE_802_15_4_PHY_IDLE)
|
||||
{
|
||||
NS_LOG_LOGIC ("Apply pending state change to " << m_trxStatePending);
|
||||
ChangeTrxState (m_trxStatePending);
|
||||
m_trxStatePending = IEEE_802_15_4_PHY_IDLE;
|
||||
if (!m_plmeSetTRXStateConfirmCallback.IsNull ())
|
||||
// Only change the state immediately, if the transceiver is not already
|
||||
// switching the state.
|
||||
if (!m_setTRXState.IsRunning ())
|
||||
{
|
||||
m_plmeSetTRXStateConfirmCallback (IEEE_802_15_4_PHY_SUCCESS);
|
||||
NS_LOG_LOGIC ("Apply pending state change to " << m_trxStatePending);
|
||||
ChangeTrxState (m_trxStatePending);
|
||||
m_trxStatePending = IEEE_802_15_4_PHY_IDLE;
|
||||
if (!m_plmeSetTRXStateConfirmCallback.IsNull ())
|
||||
{
|
||||
m_plmeSetTRXStateConfirmCallback (IEEE_802_15_4_PHY_SUCCESS);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ChangeTrxState (IEEE_802_15_4_PHY_RX_ON);
|
||||
if (m_trxState != IEEE_802_15_4_PHY_TRX_OFF)
|
||||
{
|
||||
ChangeTrxState (IEEE_802_15_4_PHY_TX_ON);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Time
|
||||
LrWpanPhy::CalculateTxTime (Ptr<const Packet> packet)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << packet);
|
||||
|
||||
Time txTime = Seconds (0);
|
||||
bool isData = true;
|
||||
|
||||
@@ -911,6 +1079,8 @@ LrWpanPhy::CalculateTxTime (Ptr<const Packet> packet)
|
||||
double
|
||||
LrWpanPhy::GetDataOrSymbolRate (bool isData)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << isData);
|
||||
|
||||
double rate = 0.0;
|
||||
|
||||
NS_ASSERT (m_phyOption < IEEE_802_15_4_INVALID_PHY_OPTION);
|
||||
@@ -930,6 +1100,8 @@ LrWpanPhy::GetDataOrSymbolRate (bool isData)
|
||||
double
|
||||
LrWpanPhy::GetPpduHeaderTxTime (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
bool isData = false;
|
||||
double totalPpduHdrSymbols;
|
||||
|
||||
@@ -946,6 +1118,8 @@ LrWpanPhy::GetPpduHeaderTxTime (void)
|
||||
void
|
||||
LrWpanPhy::SetMyPhyOption (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
m_phyOption = IEEE_802_15_4_INVALID_PHY_OPTION;
|
||||
|
||||
if (m_phyPIBAttributes.phyCurrentPage == 0)
|
||||
@@ -990,6 +1164,7 @@ LrWpanPhy::SetMyPhyOption (void)
|
||||
LrWpanPhyOption
|
||||
LrWpanPhy::GetMyPhyOption (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
return m_phyOption;
|
||||
}
|
||||
|
||||
@@ -1033,4 +1208,23 @@ LrWpanPhy::GetErrorModel (void) const
|
||||
return m_errorModel;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
LrWpanPhy::GetPhySHRDuration (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
NS_ASSERT (m_phyOption < IEEE_802_15_4_INVALID_PHY_OPTION);
|
||||
|
||||
return ppduHeaderSymbolNumbers[m_phyOption].shrPreamble
|
||||
+ ppduHeaderSymbolNumbers[m_phyOption].shrSfd;
|
||||
}
|
||||
|
||||
double
|
||||
LrWpanPhy::GetPhySymbolsPerOctet (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
NS_ASSERT (m_phyOption < IEEE_802_15_4_INVALID_PHY_OPTION);
|
||||
|
||||
return dataSymbolRates [m_phyOption].symbolRate / (dataSymbolRates [m_phyOption].bitRate / 8);
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -15,34 +15,30 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Gary Pei <guangyu.pei@boeing.com>
|
||||
* Author:
|
||||
* Gary Pei <guangyu.pei@boeing.com>
|
||||
* Sascha Alexander Jopen <jopen@cs.uni-bonn.de>
|
||||
*/
|
||||
#ifndef LR_WPAN_PHY_H
|
||||
#define LR_WPAN_PHY_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
#include <ns3/callback.h>
|
||||
#include <ns3/traced-callback.h>
|
||||
#include "ns3/object.h"
|
||||
#include <ns3/packet-burst.h>
|
||||
#include <ns3/spectrum-phy.h>
|
||||
#include <ns3/spectrum-channel.h>
|
||||
#include <ns3/spectrum-interference.h>
|
||||
#include <ns3/spectrum-value.h>
|
||||
#include <ns3/antenna-model.h>
|
||||
#include <ns3/mobility-model.h>
|
||||
#include <ns3/packet.h>
|
||||
#include <ns3/nstime.h>
|
||||
#include <ns3/net-device.h>
|
||||
#include <ns3/traced-callback.h>
|
||||
#include <ns3/event-id.h>
|
||||
#include <ns3/random-variable.h>
|
||||
#include "lr-wpan-spectrum-value-helper.h"
|
||||
#include "lr-wpan-error-model.h"
|
||||
#include "lr-wpan-spectrum-signal-parameters.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class Packet;
|
||||
class SpectrumValue;
|
||||
class LrWpanErrorModel;
|
||||
struct LrWpanSpectrumSignalParameters;
|
||||
class MobilityModel;
|
||||
class SpectrumChannel;
|
||||
class SpectrumModel;
|
||||
class AntennaModel;
|
||||
class NetDevice;
|
||||
|
||||
/**
|
||||
* IEEE802.15.4-2006 Table 1 and 2 in section 6.1.1 and 6.1.2
|
||||
*/
|
||||
@@ -124,7 +120,7 @@ typedef struct
|
||||
uint32_t phyMaxFrameDuration;
|
||||
uint32_t phySHRDuration;
|
||||
double phySymbolsPerOctet;
|
||||
} LrWpanPhyPIBAttributes;
|
||||
} LrWpanPhyPibAttributes;
|
||||
|
||||
/**
|
||||
* This method implements the PD SAP: PdDataIndication
|
||||
@@ -133,7 +129,7 @@ typedef struct
|
||||
* @param p the packet to be transmitted
|
||||
* @param lqi Link quality (LQI) value measured during reception of the PPDU
|
||||
*/
|
||||
typedef Callback< void, uint32_t, Ptr<Packet>, uint32_t > PdDataIndicationCallback;
|
||||
typedef Callback< void, uint32_t, Ptr<Packet>, uint8_t > PdDataIndicationCallback;
|
||||
|
||||
/**
|
||||
* This method implements the PD SAP: PdDataConfirm
|
||||
@@ -166,7 +162,7 @@ typedef Callback< void, LrWpanPhyEnumeration,uint8_t > PlmeEdConfirmCallback;
|
||||
*/
|
||||
typedef Callback< void, LrWpanPhyEnumeration,
|
||||
LrWpanPibAttributeIdentifier,
|
||||
LrWpanPhyPIBAttributes* > PlmeGetAttributeConfirmCallback;
|
||||
LrWpanPhyPibAttributes* > PlmeGetAttributeConfirmCallback;
|
||||
|
||||
/**
|
||||
* This method implements the PD SAP: PlmeSetTRXStateConfirm
|
||||
@@ -289,7 +285,7 @@ public:
|
||||
* @param id the attributed identifier
|
||||
* @param * attribute the attribute value
|
||||
*/
|
||||
void PlmeSetAttributeRequest (LrWpanPibAttributeIdentifier id, LrWpanPhyPIBAttributes* attribute);
|
||||
void PlmeSetAttributeRequest (LrWpanPibAttributeIdentifier id, LrWpanPhyPibAttributes* attribute);
|
||||
|
||||
/**
|
||||
* set the callback for the end of a RX, as part of the
|
||||
@@ -367,7 +363,10 @@ public:
|
||||
* @return pointer to LrWpanErrorModel in use
|
||||
*/
|
||||
Ptr<LrWpanErrorModel> GetErrorModel (void) const;
|
||||
|
||||
|
||||
uint64_t GetPhySHRDuration (void) const;
|
||||
double GetPhySymbolsPerOctet (void) const;
|
||||
|
||||
protected:
|
||||
static const LrWpanPhyDataAndSymbolRates dataSymbolRates[7];
|
||||
static const LrWpanPhyPpduHeaderSymbolNumber ppduHeaderSymbolNumbers[7];
|
||||
@@ -394,7 +393,7 @@ private:
|
||||
Ptr<const SpectrumValue> m_rxPsd;
|
||||
Ptr<const SpectrumValue> m_noise;
|
||||
Ptr<LrWpanErrorModel> m_errorModel;
|
||||
LrWpanPhyPIBAttributes m_phyPIBAttributes;
|
||||
LrWpanPhyPibAttributes m_phyPIBAttributes;
|
||||
|
||||
// State variables
|
||||
LrWpanPhyEnumeration m_trxState; /// transceiver state
|
||||
@@ -465,6 +464,7 @@ private:
|
||||
PacketAndStatus m_currentRxPacket;
|
||||
PacketAndStatus m_currentTxPacket;
|
||||
|
||||
EventId m_ccaRequest;
|
||||
EventId m_edRequest;
|
||||
EventId m_setTRXState;
|
||||
EventId m_pdDataRequest;
|
||||
|
||||
@@ -17,17 +17,16 @@
|
||||
*
|
||||
* Author: Gary Pei <guangyu.pei@boeing.com>
|
||||
*/
|
||||
|
||||
#include "lr-wpan-spectrum-signal-parameters.h"
|
||||
#include <ns3/log.h>
|
||||
#include <ns3/packet-burst.h>
|
||||
#include "lr-wpan-spectrum-signal-parameters.h"
|
||||
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("LrWpanSpectrumSignalParameters");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
LrWpanSpectrumSignalParameters::LrWpanSpectrumSignalParameters ()
|
||||
LrWpanSpectrumSignalParameters::LrWpanSpectrumSignalParameters (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
}
|
||||
@@ -40,7 +39,7 @@ LrWpanSpectrumSignalParameters::LrWpanSpectrumSignalParameters (const LrWpanSpec
|
||||
}
|
||||
|
||||
Ptr<SpectrumSignalParameters>
|
||||
LrWpanSpectrumSignalParameters::Copy ()
|
||||
LrWpanSpectrumSignalParameters::Copy (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
return Create<LrWpanSpectrumSignalParameters> (*this);
|
||||
|
||||
@@ -37,12 +37,12 @@ struct LrWpanSpectrumSignalParameters : public SpectrumSignalParameters
|
||||
{
|
||||
|
||||
// inherited from SpectrumSignalParameters
|
||||
virtual Ptr<SpectrumSignalParameters> Copy ();
|
||||
virtual Ptr<SpectrumSignalParameters> Copy (void);
|
||||
|
||||
/**
|
||||
* default constructor
|
||||
*/
|
||||
LrWpanSpectrumSignalParameters ();
|
||||
LrWpanSpectrumSignalParameters (void);
|
||||
|
||||
/**
|
||||
* copy constructor
|
||||
|
||||
@@ -17,9 +17,12 @@
|
||||
*
|
||||
* Author: Gary Pei <guangyu.pei@boeing.com>
|
||||
*/
|
||||
#include "ns3/log.h"
|
||||
|
||||
#include "lr-wpan-spectrum-value-helper.h"
|
||||
#include <ns3/log.h>
|
||||
#include <ns3/spectrum-value.h>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("LrWpanSpectrumValueHelper");
|
||||
|
||||
namespace ns3 {
|
||||
@@ -29,13 +32,14 @@ Ptr<SpectrumModel> g_LrWpanSpectrumModel;
|
||||
class LrWpanSpectrumModelInitializer
|
||||
{
|
||||
public:
|
||||
LrWpanSpectrumModelInitializer ()
|
||||
LrWpanSpectrumModelInitializer (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
Bands bands;
|
||||
// 1 MHz resolution from 2400 to 2483 MHz (center freq)
|
||||
for (int i = -1; i < 85; i++)
|
||||
// 1 MHz resolution, with center frequency of 2400, 2401, ... 2483
|
||||
// overall frequency span of 2399.5 MHz through 2483.5 MHz (83 bands)
|
||||
for (int i = -1; i < 83; i++)
|
||||
{
|
||||
BandInfo bi;
|
||||
bi.fl = 2400.5e6 + i * 1.0e6;
|
||||
@@ -48,13 +52,13 @@ public:
|
||||
|
||||
} g_LrWpanSpectrumModelInitializerInstance;
|
||||
|
||||
LrWpanSpectrumValueHelper::LrWpanSpectrumValueHelper ()
|
||||
LrWpanSpectrumValueHelper::LrWpanSpectrumValueHelper (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_noiseFactor = 1.0;
|
||||
}
|
||||
|
||||
LrWpanSpectrumValueHelper::~LrWpanSpectrumValueHelper ()
|
||||
LrWpanSpectrumValueHelper::~LrWpanSpectrumValueHelper (void)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -67,23 +71,26 @@ LrWpanSpectrumValueHelper::CreateTxPowerSpectralDensity (double txPower, uint32_
|
||||
// txPower is expressed in dBm. We must convert it into natural unit.
|
||||
txPower = pow (10., (txPower - 30) / 10);
|
||||
|
||||
// The effective occupied bandwidth of the signal is modelled to be 2 MHz.
|
||||
// 99.5% of power is within +/- 1MHz of center frequency, and 0.5% is outside.
|
||||
// There are 5 bands containing signal power. The middle (center) band
|
||||
// contains half of the power. The two inner side bands contain 49.5%.
|
||||
// The two outer side bands contain roughly 0.5%.
|
||||
double txPowerDensity = txPower / 2.0e6;
|
||||
|
||||
NS_ASSERT_MSG ((channel >= 11 && channel <= 26), "Invalid channel numbers");
|
||||
|
||||
// The channel assignment is in section 6.1.2.1
|
||||
// Table 25 specify the Tx PSD
|
||||
(*txPsd)[2405 + 5 * (channel - 11) - 2400 - 5] = txPowerDensity * 0.01; // -20 dB
|
||||
(*txPsd)[2405 + 5 * (channel - 11) - 2400 - 4] = txPowerDensity * 0.01; // -20 dB
|
||||
(*txPsd)[2405 + 5 * (channel - 11) - 2400 - 3] = txPowerDensity * 0.1; // -10 dB
|
||||
(*txPsd)[2405 + 5 * (channel - 11) - 2400 - 2] = txPowerDensity * 0.1; // -10 dB
|
||||
(*txPsd)[2405 + 5 * (channel - 11) - 2400 - 1] = txPowerDensity * 0.5; // -3 dB
|
||||
// Channel 11 centered at 2.405 GHz, 12 at 2.410 GHz, ... 26 at 2.480 GHz
|
||||
(*txPsd)[2405 + 5 * (channel - 11) - 2400 - 2] = txPowerDensity * 0.005;
|
||||
(*txPsd)[2405 + 5 * (channel - 11) - 2400 - 1] = txPowerDensity * 0.495;
|
||||
(*txPsd)[2405 + 5 * (channel - 11) - 2400] = txPowerDensity; // center
|
||||
(*txPsd)[2405 + 5 * (channel - 11) - 2400 + 1 ] = txPowerDensity * 0.5; // -3 dB
|
||||
(*txPsd)[2405 + 5 * (channel - 11) - 2400 + 2 ] = txPowerDensity * 0.1; // -10 dB
|
||||
(*txPsd)[2405 + 5 * (channel - 11) - 2400 + 3 ] = txPowerDensity * 0.1; // -10 dB
|
||||
(*txPsd)[2405 + 5 * (channel - 11) - 2400 + 4 ] = txPowerDensity * 0.01; // -20 dB
|
||||
(*txPsd)[2405 + 5 * (channel - 11) - 2400 + 5 ] = txPowerDensity * 0.01; // -20 dB
|
||||
(*txPsd)[2405 + 5 * (channel - 11) - 2400 + 1 ] = txPowerDensity * 0.495;
|
||||
(*txPsd)[2405 + 5 * (channel - 11) - 2400 + 2 ] = txPowerDensity * 0.005;
|
||||
|
||||
// If more power is allocated to more subbands in future revisions of
|
||||
// this model, make sure to renormalize so that the integral of the
|
||||
// txPsd still equals txPower
|
||||
|
||||
return txPsd;
|
||||
}
|
||||
@@ -102,31 +109,25 @@ LrWpanSpectrumValueHelper::CreateNoisePowerSpectralDensity (uint32_t channel)
|
||||
|
||||
NS_ASSERT_MSG ((channel >= 11 && channel <= 26), "Invalid channel numbers");
|
||||
|
||||
(*noisePsd)[2405 + 5 * (channel - 11) - 2400 - 1] = noisePowerDensity;
|
||||
(*noisePsd)[2405 + 5 * (channel - 11) - 2400 - 2] = noisePowerDensity;
|
||||
(*noisePsd)[2405 + 5 * (channel - 11) - 2400 - 3] = noisePowerDensity;
|
||||
(*noisePsd)[2405 + 5 * (channel - 11) - 2400 - 4] = noisePowerDensity;
|
||||
(*noisePsd)[2405 + 5 * (channel - 11) - 2400 - 5] = noisePowerDensity;
|
||||
(*noisePsd)[2405 + 5 * (channel - 11) - 2400 - 1] = noisePowerDensity;
|
||||
(*noisePsd)[2405 + 5 * (channel - 11) - 2400] = noisePowerDensity;
|
||||
(*noisePsd)[2405 + 5 * (channel - 11) - 2400 + 1] = noisePowerDensity;
|
||||
(*noisePsd)[2405 + 5 * (channel - 11) - 2400 + 2] = noisePowerDensity;
|
||||
(*noisePsd)[2405 + 5 * (channel - 11) - 2400 + 3] = noisePowerDensity;
|
||||
(*noisePsd)[2405 + 5 * (channel - 11) - 2400 + 4] = noisePowerDensity;
|
||||
(*noisePsd)[2405 + 5 * (channel - 11) - 2400 + 5] = noisePowerDensity;
|
||||
|
||||
return noisePsd;
|
||||
}
|
||||
|
||||
double
|
||||
LrWpanSpectrumValueHelper::TotalAvgPower (const SpectrumValue &psd)
|
||||
LrWpanSpectrumValueHelper::TotalAvgPower (Ptr<const SpectrumValue> psd)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
NS_LOG_FUNCTION (this << psd);
|
||||
double totalAvgPower = 0.0;
|
||||
|
||||
// numerically integrate to get area under psd using
|
||||
// 1 MHz resolution from 2400 to 2483 MHz (center freq)
|
||||
|
||||
totalAvgPower = Sum (psd * 1.0e6);
|
||||
totalAvgPower = Sum (*psd * 1.0e6);
|
||||
return totalAvgPower;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,11 +20,12 @@
|
||||
#ifndef LR_WPAN_SPECTRUM_VALUE_HELPER_H
|
||||
#define LR_WPAN_SPECTRUM_VALUE_HELPER_H
|
||||
|
||||
#include <ns3/spectrum-value.h>
|
||||
#include <cmath>
|
||||
#include <ns3/ptr.h>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class SpectrumValue;
|
||||
|
||||
/**
|
||||
* \ingroup lr-wpan
|
||||
*
|
||||
@@ -33,8 +34,8 @@ namespace ns3 {
|
||||
class LrWpanSpectrumValueHelper
|
||||
{
|
||||
public:
|
||||
LrWpanSpectrumValueHelper ();
|
||||
virtual ~LrWpanSpectrumValueHelper ();
|
||||
LrWpanSpectrumValueHelper (void);
|
||||
virtual ~LrWpanSpectrumValueHelper (void);
|
||||
|
||||
/**
|
||||
* \brief create spectrum value
|
||||
@@ -56,7 +57,7 @@ public:
|
||||
* \param power spectral density
|
||||
* \return total power (using composite trap. rule to numerally integrate
|
||||
*/
|
||||
double TotalAvgPower (const SpectrumValue &psd);
|
||||
double TotalAvgPower (Ptr<const SpectrumValue> psd);
|
||||
|
||||
private:
|
||||
double m_noiseFactor;
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2011 The Boeing Company
|
||||
*
|
||||
* 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: kwong yin <kwong-sang.yin@boeing.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "ns3/wpan-address.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
WpanAddress::WpanAddress ()
|
||||
{
|
||||
|
||||
}
|
||||
WpanAddress::WpanAddress (uint16_t addr)
|
||||
{
|
||||
SetAddress (addr);
|
||||
}
|
||||
|
||||
WpanAddress::WpanAddress (uint64_t addr)
|
||||
{
|
||||
SetAddress (addr);
|
||||
}
|
||||
|
||||
WpanAddress::~WpanAddress ()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void WpanAddress::SetAddress (uint64_t addr)
|
||||
{
|
||||
m_addr64 = addr;
|
||||
}
|
||||
|
||||
void WpanAddress::SetAddress (uint16_t addr)
|
||||
{
|
||||
m_addr16 = addr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint16_t WpanAddress::GetShortAddress (void) const
|
||||
{
|
||||
return(m_addr16);
|
||||
}
|
||||
|
||||
uint64_t WpanAddress::GetExtAddress (void) const
|
||||
{
|
||||
return(m_addr64);
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
@@ -1,53 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2011 The Boeing Company
|
||||
*
|
||||
* 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: kwong yin <kwong-sang.yin@boeing.com>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef WPANADDRESS_H_
|
||||
#define WPANADDRESS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class WpanAddress
|
||||
{
|
||||
public:
|
||||
WpanAddress ();
|
||||
WpanAddress (uint16_t addr);
|
||||
WpanAddress (uint64_t addr);
|
||||
~WpanAddress ();
|
||||
|
||||
void SetAddress (uint64_t addr);
|
||||
void SetAddress (uint16_t addr);
|
||||
|
||||
uint16_t GetShortAddress (void) const;
|
||||
uint64_t GetExtAddress (void) const;
|
||||
private:
|
||||
union
|
||||
{
|
||||
uint64_t m_addr64; //8 octet for ext addr
|
||||
uint16_t m_addr16; //2 octet for short addr
|
||||
};
|
||||
};
|
||||
|
||||
} //namespace ns3
|
||||
|
||||
#endif /* WPANADDRESS_H_ */
|
||||
@@ -1,91 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2011 The Boeing Company
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Authors:
|
||||
* Gary Pei <guangyu.pei@boeing.com>
|
||||
*/
|
||||
|
||||
#include <ns3/mobility-model.h>
|
||||
#include <ns3/wpan-spectrum-propagation-loss-model.h>
|
||||
#include <math.h>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (WpanSpectrumPropagationLossModel);
|
||||
|
||||
WpanSpectrumPropagationLossModel::WpanSpectrumPropagationLossModel ()
|
||||
{
|
||||
m_simpleLossModel = 0;
|
||||
}
|
||||
|
||||
WpanSpectrumPropagationLossModel::~WpanSpectrumPropagationLossModel ()
|
||||
{
|
||||
m_simpleLossModel = 0;
|
||||
}
|
||||
|
||||
TypeId
|
||||
WpanSpectrumPropagationLossModel::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::WpanSpectrumPropagationLossModel")
|
||||
.SetParent<SpectrumPropagationLossModel> ()
|
||||
.AddConstructor<WpanSpectrumPropagationLossModel> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
Ptr<SpectrumValue>
|
||||
WpanSpectrumPropagationLossModel::DoCalcRxPowerSpectralDensity (Ptr<const SpectrumValue> txPsd,
|
||||
Ptr<const MobilityModel> a,
|
||||
Ptr<const MobilityModel> b) const
|
||||
{
|
||||
Ptr<SpectrumValue> rxPsd = Copy<SpectrumValue> (txPsd);
|
||||
Values::iterator vit = rxPsd->ValuesBegin ();
|
||||
Bands::const_iterator fit = rxPsd->ConstBandsBegin ();
|
||||
|
||||
NS_ASSERT (a);
|
||||
NS_ASSERT (b);
|
||||
|
||||
//double d = a->GetDistanceFrom (b);
|
||||
|
||||
while (vit != rxPsd->ValuesEnd ())
|
||||
{
|
||||
NS_ASSERT (fit != rxPsd->ConstBandsEnd ());
|
||||
*vit /= CalculateLossFromSimpleLossModel (a, b); // Prx = Ptx / loss
|
||||
++vit;
|
||||
++fit;
|
||||
}
|
||||
return rxPsd;
|
||||
}
|
||||
|
||||
double
|
||||
WpanSpectrumPropagationLossModel::CalculateLossFromSimpleLossModel (Ptr<const MobilityModel> a,
|
||||
Ptr<const MobilityModel> b) const
|
||||
{
|
||||
double loss = 1.0;
|
||||
|
||||
if (m_simpleLossModel)
|
||||
{
|
||||
loss = m_simpleLossModel->CalcRxPower (0.0, ConstCast<MobilityModel> (a), ConstCast<MobilityModel> (b));
|
||||
loss = pow (10.0, loss / 10.0);
|
||||
loss = 1.0 / loss;
|
||||
}
|
||||
|
||||
return loss;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2011 The Boeing Company
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Authors:
|
||||
* Gary Pei <guangyu.pei@boeing.com>
|
||||
*/
|
||||
#ifndef WPAN_SPECTRUM_PROPAGATION_LOSS_MODEL_H
|
||||
#define WPAN_SPECTRUM_PROPAGATION_LOSS_MODEL_H
|
||||
|
||||
#include <ns3/spectrum-propagation-loss-model.h>
|
||||
#include <ns3/propagation-loss-model.h>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class MobilityModel;
|
||||
|
||||
/**
|
||||
* \brief propagation loss model for WPAN that uses simple PropagationLossModel
|
||||
*/
|
||||
class WpanSpectrumPropagationLossModel : public SpectrumPropagationLossModel
|
||||
{
|
||||
|
||||
public:
|
||||
WpanSpectrumPropagationLossModel ();
|
||||
~WpanSpectrumPropagationLossModel ();
|
||||
|
||||
static TypeId GetTypeId ();
|
||||
|
||||
|
||||
virtual Ptr<SpectrumValue> DoCalcRxPowerSpectralDensity (Ptr<const SpectrumValue> txPsd,
|
||||
Ptr<const MobilityModel> a,
|
||||
Ptr<const MobilityModel> b) const;
|
||||
|
||||
|
||||
private:
|
||||
double CalculateLossFromSimpleLossModel (Ptr<const MobilityModel> a,
|
||||
Ptr<const MobilityModel> b) const;
|
||||
Ptr<PropagationLossModel> m_simpleLossModel;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* WPAN_SPECTRUM_PROPAGATION_LOSS_MODEL_H */
|
||||
@@ -17,21 +17,20 @@
|
||||
*
|
||||
* Author: Tom Henderson <thomas.r.henderson@boeing.com>
|
||||
*/
|
||||
|
||||
#include <ns3/test.h>
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/callback.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/lr-wpan-error-model.h"
|
||||
#include "ns3/propagation-loss-model.h"
|
||||
#include "ns3/lr-wpan-net-device.h"
|
||||
#include "ns3/lr-wpan-mac.h"
|
||||
#include "ns3/node.h"
|
||||
#include "ns3/net-device.h"
|
||||
#include "ns3/single-model-spectrum-channel.h"
|
||||
#include "ns3/mac16-address.h"
|
||||
#include "ns3/constant-position-mobility-model.h"
|
||||
#include <ns3/log.h>
|
||||
#include <ns3/callback.h>
|
||||
#include <ns3/packet.h>
|
||||
#include <ns3/simulator.h>
|
||||
#include <ns3/lr-wpan-error-model.h>
|
||||
#include <ns3/propagation-loss-model.h>
|
||||
#include <ns3/lr-wpan-net-device.h>
|
||||
#include <ns3/lr-wpan-mac.h>
|
||||
#include <ns3/node.h>
|
||||
#include <ns3/net-device.h>
|
||||
#include <ns3/single-model-spectrum-channel.h>
|
||||
#include <ns3/mac16-address.h>
|
||||
#include <ns3/constant-position-mobility-model.h>
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("lr-wpan-error-model-test");
|
||||
|
||||
@@ -106,8 +105,8 @@ LrWpanErrorDistanceTestCase::DoRun (void)
|
||||
dev1->GetMac ()->SetMcpsDataIndicationCallback (cb0);
|
||||
|
||||
McpsDataRequestParams params;
|
||||
params.m_srcAddrMode = 2;
|
||||
params.m_dstAddrMode = 2;
|
||||
params.m_srcAddrMode = SHORT_ADDR;
|
||||
params.m_dstAddrMode = SHORT_ADDR;
|
||||
params.m_dstPanId = 0;
|
||||
params.m_dstAddr = Mac16Address ("00:02");
|
||||
params.m_msduHandle = 0;
|
||||
|
||||
@@ -17,14 +17,13 @@
|
||||
*
|
||||
* Author: Tom Henderson <thomas.r.henderson@boeing.com>
|
||||
*/
|
||||
|
||||
#include <ns3/test.h>
|
||||
#include <ns3/packet.h>
|
||||
#include <ns3/lr-wpan-mac-header.h>
|
||||
#include <ns3/lr-wpan-mac-trailer.h>
|
||||
#include <ns3/mac16-address.h>
|
||||
#include <ns3/mac64-address.h>
|
||||
#include "ns3/log.h"
|
||||
#include <ns3/log.h>
|
||||
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("lr-wpan-packet-test");
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
*
|
||||
* Author: Gary Pei <guangyu.pei@boeing.com>
|
||||
*/
|
||||
|
||||
#include <ns3/log.h>
|
||||
#include <ns3/test.h>
|
||||
#include <ns3/packet.h>
|
||||
#include <ns3/lr-wpan-phy.h>
|
||||
#include <ns3/lr-wpan-mac.h>
|
||||
#include <ns3/simulator.h>
|
||||
@@ -36,7 +36,7 @@ public:
|
||||
|
||||
private:
|
||||
virtual void DoRun (void);
|
||||
void ReceivePdDataInndication (uint32_t psduLength, Ptr<Packet> p, uint32_t lqi);
|
||||
void ReceivePdDataInndication (uint32_t psduLength, Ptr<Packet> p, uint8_t lqi);
|
||||
};
|
||||
|
||||
LrWpanPlmeAndPdInterfaceTestCase::LrWpanPlmeAndPdInterfaceTestCase ()
|
||||
@@ -51,7 +51,7 @@ LrWpanPlmeAndPdInterfaceTestCase::~LrWpanPlmeAndPdInterfaceTestCase ()
|
||||
void
|
||||
LrWpanPlmeAndPdInterfaceTestCase::ReceivePdDataInndication (uint32_t psduLength,
|
||||
Ptr<Packet> p,
|
||||
uint32_t lqi)
|
||||
uint8_t lqi)
|
||||
{
|
||||
NS_LOG_UNCOND ("At: " << Simulator::Now ()
|
||||
<< " Received frame size: " << psduLength << " LQI: " <<
|
||||
|
||||
@@ -17,10 +17,12 @@
|
||||
*
|
||||
* Author: Tom Henderson <thomas.r.henderson@boeing.com>
|
||||
*/
|
||||
|
||||
#include <ns3/log.h>
|
||||
#include <ns3/test.h>
|
||||
#include <ns3/lr-wpan-spectrum-value-helper.h>
|
||||
#include <ns3/spectrum-value.h>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
@@ -57,7 +59,7 @@ LrWpanSpectrumValueHelperTestCase::DoRun (void)
|
||||
value = helper.CreateTxPowerSpectralDensity (pwrdBm, chan);
|
||||
pwrWatts = pow (10.0, pwrdBm / 10.0) / 1000;
|
||||
// Test that average power calculation is within +/- 25% of expected
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (helper.TotalAvgPower (*value), pwrWatts, pwrWatts / 4.0, "Not equal for channel " << chan << " pwrdBm " << pwrdBm);
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (helper.TotalAvgPower (value), pwrWatts, pwrWatts / 4.0, "Not equal for channel " << chan << " pwrdBm " << pwrdBm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ def build(bld):
|
||||
'model/lr-wpan-net-device.cc',
|
||||
'model/lr-wpan-spectrum-value-helper.cc',
|
||||
'model/lr-wpan-spectrum-signal-parameters.cc',
|
||||
'model/lr-wpan-lqi-tag.cc',
|
||||
'helper/lr-wpan-helper.cc',
|
||||
]
|
||||
|
||||
@@ -35,6 +36,7 @@ def build(bld):
|
||||
'model/lr-wpan-net-device.h',
|
||||
'model/lr-wpan-spectrum-value-helper.h',
|
||||
'model/lr-wpan-spectrum-signal-parameters.h',
|
||||
'model/lr-wpan-lqi-tag.h',
|
||||
'helper/lr-wpan-helper.h',
|
||||
]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user