From 131f31f56a1ed2e80e7dbc0ce8be539c8e42e09d Mon Sep 17 00:00:00 2001 From: Tommaso Pecorella Date: Sun, 23 Feb 2014 16:24:11 +0100 Subject: [PATCH] ACK (Sascha Jopen), NetDevice (Tommaso Pecorella and Margherita Filippetti), FCS changes (Erwan Livolant), and clang compliance --- src/lr-wpan/examples/lr-wpan-data.cc | 33 +- .../examples/lr-wpan-error-distance-plot.cc | 42 +- .../examples/lr-wpan-error-model-plot.cc | 18 +- src/lr-wpan/examples/lr-wpan-packet-print.cc | 5 +- src/lr-wpan/examples/lr-wpan-phy-test.cc | 4 +- src/lr-wpan/helper/lr-wpan-helper.cc | 13 +- src/lr-wpan/helper/lr-wpan-helper.h | 17 +- src/lr-wpan/model/lr-wpan-csmaca.cc | 129 ++-- src/lr-wpan/model/lr-wpan-csmaca.h | 44 +- src/lr-wpan/model/lr-wpan-error-model.cc | 46 +- src/lr-wpan/model/lr-wpan-error-model.h | 10 +- src/lr-wpan/model/lr-wpan-error-rate-model.cc | 79 --- src/lr-wpan/model/lr-wpan-error-rate-model.h | 51 -- src/lr-wpan/model/lr-wpan-lqi-tag.cc | 94 +++ src/lr-wpan/model/lr-wpan-lqi-tag.h | 69 ++ src/lr-wpan/model/lr-wpan-mac-header.cc | 7 +- src/lr-wpan/model/lr-wpan-mac-header.h | 16 +- src/lr-wpan/model/lr-wpan-mac-trailer.cc | 112 ++- src/lr-wpan/model/lr-wpan-mac-trailer.h | 27 +- src/lr-wpan/model/lr-wpan-mac.cc | 663 +++++++++++++----- src/lr-wpan/model/lr-wpan-mac.h | 88 ++- src/lr-wpan/model/lr-wpan-net-device.cc | 123 +++- src/lr-wpan/model/lr-wpan-net-device.h | 24 +- src/lr-wpan/model/lr-wpan-phy.cc | 424 ++++++++--- src/lr-wpan/model/lr-wpan-phy.h | 48 +- .../lr-wpan-spectrum-signal-parameters.cc | 7 +- .../lr-wpan-spectrum-signal-parameters.h | 4 +- .../model/lr-wpan-spectrum-value-helper.cc | 57 +- .../model/lr-wpan-spectrum-value-helper.h | 11 +- src/lr-wpan/model/wpan-address.cc | 68 -- src/lr-wpan/model/wpan-address.h | 53 -- .../wpan-spectrum-propagation-loss-model.cc | 91 --- .../wpan-spectrum-propagation-loss-model.h | 58 -- src/lr-wpan/test/lr-wpan-error-model-test.cc | 31 +- src/lr-wpan/test/lr-wpan-packet-test.cc | 3 +- src/lr-wpan/test/lr-wpan-pd-plme-sap-test.cc | 6 +- .../lr-wpan-spectrum-value-helper-test.cc | 6 +- src/lr-wpan/wscript | 2 + 38 files changed, 1543 insertions(+), 1040 deletions(-) delete mode 100644 src/lr-wpan/model/lr-wpan-error-rate-model.cc delete mode 100644 src/lr-wpan/model/lr-wpan-error-rate-model.h create mode 100644 src/lr-wpan/model/lr-wpan-lqi-tag.cc create mode 100644 src/lr-wpan/model/lr-wpan-lqi-tag.h delete mode 100644 src/lr-wpan/model/wpan-address.cc delete mode 100644 src/lr-wpan/model/wpan-address.h delete mode 100644 src/lr-wpan/model/wpan-spectrum-propagation-loss-model.cc delete mode 100644 src/lr-wpan/model/wpan-spectrum-propagation-loss-model.h diff --git a/src/lr-wpan/examples/lr-wpan-data.cc b/src/lr-wpan/examples/lr-wpan-data.cc index 962e37e72..ff6962a68 100644 --- a/src/lr-wpan/examples/lr-wpan-data.cc +++ b/src/lr-wpan/examples/lr-wpan-data.cc @@ -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 +#include +#include +#include +#include +#include #include #include +#include #include @@ -83,7 +85,9 @@ int main (int argc, char *argv[]) // Each device must be attached to the same channel Ptr channel = CreateObject (); Ptr propModel = CreateObject (); + Ptr delayModel = CreateObject (); 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 p0 = Create (50); // 20 bytes of dummy data + // 2) DataIndication callback is called with value of 50 + Ptr p0 = Create (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 p2 = Create (60); // 20 bytes of dummy data + Ptr p2 = Create (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); diff --git a/src/lr-wpan/examples/lr-wpan-error-distance-plot.cc b/src/lr-wpan/examples/lr-wpan-error-distance-plot.cc index 43261ae1b..42ca79193 100644 --- a/src/lr-wpan/examples/lr-wpan-error-distance-plot.cc +++ b/src/lr-wpan/examples/lr-wpan-error-distance-plot.cc @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/src/lr-wpan/examples/lr-wpan-error-model-plot.cc b/src/lr-wpan/examples/lr-wpan-error-model-plot.cc index e8eacfe29..6f2adb30c 100644 --- a/src/lr-wpan/examples/lr-wpan-error-model-plot.cc +++ b/src/lr-wpan/examples/lr-wpan-error-model-plot.cc @@ -17,15 +17,15 @@ * * Author: Gary Pei */ -#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 +#include +#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/src/lr-wpan/examples/lr-wpan-packet-print.cc b/src/lr-wpan/examples/lr-wpan-packet-print.cc index 4f45e7eec..8eb589a11 100644 --- a/src/lr-wpan/examples/lr-wpan-packet-print.cc +++ b/src/lr-wpan/examples/lr-wpan-packet-print.cc @@ -17,9 +17,8 @@ * * Author: Tom Henderson */ - -#include "ns3/core-module.h" -#include "ns3/lr-wpan-module.h" +#include +#include #include diff --git a/src/lr-wpan/examples/lr-wpan-phy-test.cc b/src/lr-wpan/examples/lr-wpan-phy-test.cc index 76e0a7ddf..f20536bcd 100644 --- a/src/lr-wpan/examples/lr-wpan-phy-test.cc +++ b/src/lr-wpan/examples/lr-wpan-phy-test.cc @@ -17,9 +17,9 @@ * * Author: Gary Pei */ - #include #include +#include #include #include #include @@ -37,7 +37,7 @@ void GetSetTRXStateConfirm (LrWpanPhyEnumeration status) void ReceivePdDataIndication (uint32_t psduLength, Ptr p, - uint32_t lqi) + uint8_t lqi) { NS_LOG_UNCOND ("At: " << Simulator::Now () << " Received frame size: " << psduLength << " LQI: " << diff --git a/src/lr-wpan/helper/lr-wpan-helper.cc b/src/lr-wpan/helper/lr-wpan-helper.cc index 336c75fc3..072f71e13 100644 --- a/src/lr-wpan/helper/lr-wpan-helper.cc +++ b/src/lr-wpan/helper/lr-wpan-helper.cc @@ -19,13 +19,14 @@ * Gary Pei * Tom Henderson */ - #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 +#include +#include +#include +#include +#include +#include NS_LOG_COMPONENT_DEFINE ("LrWpanHelper"); diff --git a/src/lr-wpan/helper/lr-wpan-helper.h b/src/lr-wpan/helper/lr-wpan-helper.h index 3b8b916ab..6410a428e 100644 --- a/src/lr-wpan/helper/lr-wpan-helper.h +++ b/src/lr-wpan/helper/lr-wpan-helper.h @@ -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 +#include +#include +#include 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 diff --git a/src/lr-wpan/model/lr-wpan-csmaca.cc b/src/lr-wpan/model/lr-wpan-csmaca.cc index 8e36d095d..626ebc2cd 100644 --- a/src/lr-wpan/model/lr-wpan-csmaca.cc +++ b/src/lr-wpan/model/lr-wpan-csmaca.cc @@ -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 + * Author: + * kwong yin + * Sascha Alexander Jopen */ -#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 +#include 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 (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 (m_NB)); - Simulator::ScheduleNow (&LrWpanCsmaCa::RandomBackoffDelay,this); //Perform another backoff (step 2) - } } } diff --git a/src/lr-wpan/model/lr-wpan-csmaca.h b/src/lr-wpan/model/lr-wpan-csmaca.h index 841b80cb8..2e6e6a382 100644 --- a/src/lr-wpan/model/lr-wpan-csmaca.h +++ b/src/lr-wpan/model/lr-wpan-csmaca.h @@ -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 + * Author: + * kwong yin + * Sascha Alexander Jopen */ -#ifndef LRWPANCSMACA_H -#define LRWPANCSMACA_H +#ifndef LR_WPAN_CSMACA_H +#define LR_WPAN_CSMACA_H -#include -#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 +#include +#include +#include namespace ns3 { /* This method informs MAC that channel is idle or busy */ -typedef Callback< void, LrWpanMacState> LrWpanMacStateCallback; +typedef Callback 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 mac); Ptr 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 */ diff --git a/src/lr-wpan/model/lr-wpan-error-model.cc b/src/lr-wpan/model/lr-wpan-error-model.cc index f49a40e4c..796168d0e 100644 --- a/src/lr-wpan/model/lr-wpan-error-model.cc +++ b/src/lr-wpan/model/lr-wpan-error-model.cc @@ -17,8 +17,10 @@ * * Author: Gary Pei */ -#include "ns3/lr-wpan-error-model.h" -#include "ns3/log.h" +#include "lr-wpan-error-model.h" +#include + +#include 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 diff --git a/src/lr-wpan/model/lr-wpan-error-model.h b/src/lr-wpan/model/lr-wpan-error-model.h index 06e9ce34b..38bc18f8d 100644 --- a/src/lr-wpan/model/lr-wpan-error-model.h +++ b/src/lr-wpan/model/lr-wpan-error-model.h @@ -20,9 +20,7 @@ #ifndef LR_WPAN_ERROR_MODEL_H #define LR_WPAN_ERROR_MODEL_H -#include -#include -#include "ns3/object.h" +#include 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]; + }; diff --git a/src/lr-wpan/model/lr-wpan-error-rate-model.cc b/src/lr-wpan/model/lr-wpan-error-rate-model.cc deleted file mode 100644 index b5dae66e6..000000000 --- a/src/lr-wpan/model/lr-wpan-error-rate-model.cc +++ /dev/null @@ -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 - */ -#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 () - .AddConstructor () - ; - 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 diff --git a/src/lr-wpan/model/lr-wpan-error-rate-model.h b/src/lr-wpan/model/lr-wpan-error-rate-model.h deleted file mode 100644 index 84463e5df..000000000 --- a/src/lr-wpan/model/lr-wpan-error-rate-model.h +++ /dev/null @@ -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 - */ -#ifndef LR_WPAN_ERROR_RATE_MODEL_H -#define LR_WPAN_ERROR_RATE_MODEL_H - -#include -#include -#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 */ diff --git a/src/lr-wpan/model/lr-wpan-lqi-tag.cc b/src/lr-wpan/model/lr-wpan-lqi-tag.cc new file mode 100644 index 000000000..a7b87f6cd --- /dev/null +++ b/src/lr-wpan/model/lr-wpan-lqi-tag.cc @@ -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 . + * + * Author: + * Sascha Alexander Jopen + */ +#include "lr-wpan-lqi-tag.h" +#include + +namespace ns3 { + +NS_OBJECT_ENSURE_REGISTERED (LrWpanLqiTag); + +TypeId +LrWpanLqiTag::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::LrWpanLqiTag") + .SetParent () + .AddConstructor () + .AddAttribute ("Lqi", "The lqi of the last packet received", + IntegerValue (0), + MakeIntegerAccessor (&LrWpanLqiTag::Get), + MakeIntegerChecker ()) + ; + 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; +} + +} diff --git a/src/lr-wpan/model/lr-wpan-lqi-tag.h b/src/lr-wpan/model/lr-wpan-lqi-tag.h new file mode 100644 index 000000000..af1b1b952 --- /dev/null +++ b/src/lr-wpan/model/lr-wpan-lqi-tag.h @@ -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 . + * + * Author: + * Sascha Alexander Jopen + */ +#ifndef LR_WPAN_LQI_TAG_H +#define LR_WPAN_LQI_TAG_H + +#include + +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 */ diff --git a/src/lr-wpan/model/lr-wpan-mac-header.cc b/src/lr-wpan/model/lr-wpan-mac-header.cc index fbe6b6323..feba50c85 100644 --- a/src/lr-wpan/model/lr-wpan-mac-header.cc +++ b/src/lr-wpan/model/lr-wpan-mac-header.cc @@ -17,11 +17,8 @@ * * Author: kwong yin */ - -#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 namespace ns3 { diff --git a/src/lr-wpan/model/lr-wpan-mac-header.h b/src/lr-wpan/model/lr-wpan-mac-header.h index 4315ec361..45fc4a378 100644 --- a/src/lr-wpan/model/lr-wpan-mac-header.h +++ b/src/lr-wpan/model/lr-wpan-mac-header.h @@ -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 -#include "ns3/header.h" -#include "ns3/nstime.h" -#include "ns3/mac16-address.h" -#include "ns3/mac64-address.h" +#include +#include +#include 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 */ // ---------------------------------------------------------------------------------------------------------- diff --git a/src/lr-wpan/model/lr-wpan-mac-trailer.cc b/src/lr-wpan/model/lr-wpan-mac-trailer.cc index 74373e2ad..4048bdf98 100644 --- a/src/lr-wpan/model/lr-wpan-mac-trailer.cc +++ b/src/lr-wpan/model/lr-wpan-mac-trailer.cc @@ -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 + * Author: + * kwong yin + * Sascha Alexander Jopen + * Erwan Livolant */ - #include "lr-wpan-mac-trailer.h" -#include "ns3/object.h" +#include 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 () @@ -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 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 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 diff --git a/src/lr-wpan/model/lr-wpan-mac-trailer.h b/src/lr-wpan/model/lr-wpan-mac-trailer.h index c4fefc05b..7ddbfccfc 100644 --- a/src/lr-wpan/model/lr-wpan-mac-trailer.h +++ b/src/lr-wpan/model/lr-wpan-mac-trailer.h @@ -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 + * Author: + * kwong yin + * Sascha Alexander Jopen + * Erwan Livolant */ -#ifndef LRWPANMACTRAILER_H_ -#define LRWPANMACTRAILER_H_ +#ifndef LR_WPAN_MAC_TRAILER_H +#define LR_WPAN_MAC_TRAILER_H -#include "ns3/trailer.h" -#include +#include 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 p); + bool CheckFcs (Ptr 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 */ diff --git a/src/lr-wpan/model/lr-wpan-mac.cc b/src/lr-wpan/model/lr-wpan-mac.cc index 182d1b905..6f3ccee3e 100644 --- a/src/lr-wpan/model/lr-wpan-mac.cc +++ b/src/lr-wpan/model/lr-wpan-mac.cc @@ -19,16 +19,18 @@ * Gary Pei * kwong yin * Tom Henderson + * Sascha Alexander Jopen + * Erwan Livolant */ -#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 +#include +#include +#include +#include NS_LOG_COMPONENT_DEFINE ("LrWpanMac"); @@ -52,11 +54,14 @@ LrWpanMac::GetTypeId (void) UintegerValue (), MakeUintegerAccessor (&LrWpanMac::m_macPanId), MakeUintegerChecker ()) + .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 > (); 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 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 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 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 p) } } - if (b2 == 4) + if (b2 == TX_OPTION_INDIRECT) { //TODO :indirect tx } @@ -301,43 +362,50 @@ LrWpanMac::McpsDataRequest (McpsDataRequestParams params, Ptr 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 csmaCa) +void +LrWpanMac::SetCsmaCa (Ptr csmaCa) { m_csmaCa = csmaCa; } -void LrWpanMac::SetPhy (Ptr phy) +void +LrWpanMac::SetPhy (Ptr phy) { m_phy = phy; } -Ptr LrWpanMac::GetPhy (void) +Ptr +LrWpanMac::GetPhy (void) { return m_phy; } @@ -355,38 +423,14 @@ LrWpanMac::SetMcpsDataConfirmCallback (McpsDataConfirmCallback c) } void -LrWpanMac::PdDataIndication (uint32_t psduLength, Ptr p, uint32_t lqi) +LrWpanMac::PdDataIndication (uint32_t psduLength, Ptr 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 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 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 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 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 ackPacket = Create (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 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 diff --git a/src/lr-wpan/model/lr-wpan-mac.h b/src/lr-wpan/model/lr-wpan-mac.h index 76f8bb33d..6868262a7 100644 --- a/src/lr-wpan/model/lr-wpan-mac.h +++ b/src/lr-wpan/model/lr-wpan-mac.h @@ -19,35 +19,44 @@ * Gary Pei * kwong yin * Tom Henderson + * Sascha Alexander Jopen */ #ifndef LR_WPAN_MAC_H #define LR_WPAN_MAC_H -#include -#include -#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 +#include +#include +#include +#include +#include +#include #include -#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 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 > McpsDataIndicationCallback; +typedef Callback > 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 p, uint32_t lqi); + void PdDataIndication (uint32_t psduLength, Ptr 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 txQPkt; + }; + + void SendAck (uint8_t seqno); + void RemoveFirstTxQElement (void); void ChangeMacState (LrWpanMacState newState); + void AckWaitTimeout (void); + bool PrepareRetransmission (void); + void CheckQueue (void); + + + TracedCallback, 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 m_txPkt; // XXX need packet buffer instead of single packet Mac16Address m_shortAddress; Mac64Address m_selfExt; - - struct TxQueueElement - { - uint8_t txQMsduHandle; - Ptr txQPkt; - }; std::deque m_txQueue; + uint8_t m_retransmission; + EventId m_ackWaitTimeout; + bool m_macRxOnWhenIdle; }; diff --git a/src/lr-wpan/model/lr-wpan-net-device.cc b/src/lr-wpan/model/lr-wpan-net-device.cc index 490ab73de..6305c8e92 100644 --- a/src/lr-wpan/model/lr-wpan-net-device.cc +++ b/src/lr-wpan/model/lr-wpan-net-device.cc @@ -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 + * Author: + * Tom Henderson + * Tommaso Pecorella + * Margherita Filippetti */ - -#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 +#include +#include +#include +#include +#include +#include +#include + NS_LOG_COMPONENT_DEFINE ("LrWpanNetDevice"); @@ -54,6 +60,10 @@ LrWpanNetDevice::GetTypeId (void) MakePointerAccessor (&LrWpanNetDevice::GetMac, &LrWpanNetDevice::SetMac), MakePointerChecker ()) + .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 ()); Ptr model = CreateObject (); 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, 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, 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) 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 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 { diff --git a/src/lr-wpan/model/lr-wpan-net-device.h b/src/lr-wpan/model/lr-wpan-net-device.h index 2e53492b3..7849e4d09 100644 --- a/src/lr-wpan/model/lr-wpan-net-device.h +++ b/src/lr-wpan/model/lr-wpan-net-device.h @@ -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 + * Author: + * Tom Henderson + * Tommaso Pecorella + * Margherita Filippetti */ #ifndef LR_WPAN_NET_DEVICE_H #define LR_WPAN_NET_DEVICE_H -#include -#include -#include "ns3/net-device.h" -#include "ns3/traced-callback.h" - +#include +#include +#include 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 mac); void SetPhy (Ptr phy); @@ -103,6 +103,8 @@ public: virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb); virtual bool SupportsSendFrom (void) const; + void McpsDataIndication (McpsDataIndicationParams params, Ptr pkt); + private: virtual void DoDispose (void); virtual void DoStart (void); @@ -116,13 +118,15 @@ private: Ptr m_csmaca; Ptr 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 */ diff --git a/src/lr-wpan/model/lr-wpan-phy.cc b/src/lr-wpan/model/lr-wpan-phy.cc index 09fe56849..b0f5ff166 100644 --- a/src/lr-wpan/model/lr-wpan-phy.cc +++ b/src/lr-wpan/model/lr-wpan-phy.cc @@ -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 + * Author: + * Gary Pei + * Sascha Alexander Jopen */ -#include "ns3/log.h" -#include "ns3/abort.h" -#include -#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 +#include +#include +#include +#include +#include +#include +#include +#include +#include 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, uint32_t > (); + m_pdDataIndicationCallback = MakeNullCallback< void, uint32_t, Ptr, 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 c) Ptr LrWpanPhy::GetChannel (void) { + NS_LOG_FUNCTION (this); return m_channel; } @@ -199,6 +218,7 @@ LrWpanPhy::GetChannel (void) Ptr LrWpanPhy::GetRxSpectrumModel () const { + NS_LOG_FUNCTION (this); if (m_txPsd) { return m_txPsd->GetSpectrumModel (); @@ -212,6 +232,7 @@ LrWpanPhy::GetRxSpectrumModel () const Ptr LrWpanPhy::GetRxAntenna () { + NS_LOG_FUNCTION (this); return m_antenna; } @@ -233,25 +254,53 @@ LrWpanPhy::StartRx (Ptr spectrumRxParams) Ptr lrWpanRxParams = DynamicCast (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 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 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 p = (lrWpanRxParams->packetBurst->GetPackets ()).front (); + m_phyRxDropTrace (p); + } + else + { + NS_LOG_DEBUG (this << " transceiver not in RX state"); + Ptr 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 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 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 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 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 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 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 txParams = Create (); txParams->duration = CalculateTxTime (p); txParams->txPhy = GetObject (); @@ -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 packet) { + NS_LOG_FUNCTION (this << packet); + Time txTime = Seconds (0); bool isData = true; @@ -911,6 +1079,8 @@ LrWpanPhy::CalculateTxTime (Ptr 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 diff --git a/src/lr-wpan/model/lr-wpan-phy.h b/src/lr-wpan/model/lr-wpan-phy.h index 05bd51974..b9fb98627 100644 --- a/src/lr-wpan/model/lr-wpan-phy.h +++ b/src/lr-wpan/model/lr-wpan-phy.h @@ -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 + * Author: + * Gary Pei + * Sascha Alexander Jopen */ #ifndef LR_WPAN_PHY_H #define LR_WPAN_PHY_H -#include -#include -#include -#include -#include "ns3/object.h" -#include #include -#include -#include -#include -#include -#include -#include -#include -#include +#include #include #include -#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, uint32_t > PdDataIndicationCallback; +typedef Callback< void, uint32_t, Ptr, 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 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 m_rxPsd; Ptr m_noise; Ptr 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; diff --git a/src/lr-wpan/model/lr-wpan-spectrum-signal-parameters.cc b/src/lr-wpan/model/lr-wpan-spectrum-signal-parameters.cc index ed4e59c2a..941f00dae 100644 --- a/src/lr-wpan/model/lr-wpan-spectrum-signal-parameters.cc +++ b/src/lr-wpan/model/lr-wpan-spectrum-signal-parameters.cc @@ -17,17 +17,16 @@ * * Author: Gary Pei */ - +#include "lr-wpan-spectrum-signal-parameters.h" #include #include -#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 -LrWpanSpectrumSignalParameters::Copy () +LrWpanSpectrumSignalParameters::Copy (void) { NS_LOG_FUNCTION (this); return Create (*this); diff --git a/src/lr-wpan/model/lr-wpan-spectrum-signal-parameters.h b/src/lr-wpan/model/lr-wpan-spectrum-signal-parameters.h index 5a5b03238..7383cd60d 100644 --- a/src/lr-wpan/model/lr-wpan-spectrum-signal-parameters.h +++ b/src/lr-wpan/model/lr-wpan-spectrum-signal-parameters.h @@ -37,12 +37,12 @@ struct LrWpanSpectrumSignalParameters : public SpectrumSignalParameters { // inherited from SpectrumSignalParameters - virtual Ptr Copy (); + virtual Ptr Copy (void); /** * default constructor */ - LrWpanSpectrumSignalParameters (); + LrWpanSpectrumSignalParameters (void); /** * copy constructor diff --git a/src/lr-wpan/model/lr-wpan-spectrum-value-helper.cc b/src/lr-wpan/model/lr-wpan-spectrum-value-helper.cc index 7bd1158a4..7428935f1 100644 --- a/src/lr-wpan/model/lr-wpan-spectrum-value-helper.cc +++ b/src/lr-wpan/model/lr-wpan-spectrum-value-helper.cc @@ -17,9 +17,12 @@ * * Author: Gary Pei */ -#include "ns3/log.h" - #include "lr-wpan-spectrum-value-helper.h" +#include +#include + +#include + NS_LOG_COMPONENT_DEFINE ("LrWpanSpectrumValueHelper"); namespace ns3 { @@ -29,13 +32,14 @@ Ptr 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 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; } diff --git a/src/lr-wpan/model/lr-wpan-spectrum-value-helper.h b/src/lr-wpan/model/lr-wpan-spectrum-value-helper.h index 3d9407aac..dc7b5c607 100644 --- a/src/lr-wpan/model/lr-wpan-spectrum-value-helper.h +++ b/src/lr-wpan/model/lr-wpan-spectrum-value-helper.h @@ -20,11 +20,12 @@ #ifndef LR_WPAN_SPECTRUM_VALUE_HELPER_H #define LR_WPAN_SPECTRUM_VALUE_HELPER_H -#include -#include +#include 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 psd); private: double m_noiseFactor; diff --git a/src/lr-wpan/model/wpan-address.cc b/src/lr-wpan/model/wpan-address.cc deleted file mode 100644 index 541f08553..000000000 --- a/src/lr-wpan/model/wpan-address.cc +++ /dev/null @@ -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 - */ - - -#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 diff --git a/src/lr-wpan/model/wpan-address.h b/src/lr-wpan/model/wpan-address.h deleted file mode 100644 index fb75b6e24..000000000 --- a/src/lr-wpan/model/wpan-address.h +++ /dev/null @@ -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 - */ - - -#ifndef WPANADDRESS_H_ -#define WPANADDRESS_H_ - -#include - -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_ */ diff --git a/src/lr-wpan/model/wpan-spectrum-propagation-loss-model.cc b/src/lr-wpan/model/wpan-spectrum-propagation-loss-model.cc deleted file mode 100644 index c800106de..000000000 --- a/src/lr-wpan/model/wpan-spectrum-propagation-loss-model.cc +++ /dev/null @@ -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 - */ - -#include -#include -#include - -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 () - .AddConstructor () - ; - return tid; -} - -Ptr -WpanSpectrumPropagationLossModel::DoCalcRxPowerSpectralDensity (Ptr txPsd, - Ptr a, - Ptr b) const -{ - Ptr rxPsd = Copy (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 a, - Ptr b) const -{ - double loss = 1.0; - - if (m_simpleLossModel) - { - loss = m_simpleLossModel->CalcRxPower (0.0, ConstCast (a), ConstCast (b)); - loss = pow (10.0, loss / 10.0); - loss = 1.0 / loss; - } - - return loss; -} - - -} diff --git a/src/lr-wpan/model/wpan-spectrum-propagation-loss-model.h b/src/lr-wpan/model/wpan-spectrum-propagation-loss-model.h deleted file mode 100644 index 18477155d..000000000 --- a/src/lr-wpan/model/wpan-spectrum-propagation-loss-model.h +++ /dev/null @@ -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 - */ -#ifndef WPAN_SPECTRUM_PROPAGATION_LOSS_MODEL_H -#define WPAN_SPECTRUM_PROPAGATION_LOSS_MODEL_H - -#include -#include - -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 DoCalcRxPowerSpectralDensity (Ptr txPsd, - Ptr a, - Ptr b) const; - - -private: - double CalculateLossFromSimpleLossModel (Ptr a, - Ptr b) const; - Ptr m_simpleLossModel; - -}; - -} - -#endif /* WPAN_SPECTRUM_PROPAGATION_LOSS_MODEL_H */ diff --git a/src/lr-wpan/test/lr-wpan-error-model-test.cc b/src/lr-wpan/test/lr-wpan-error-model-test.cc index 8846895c0..120dc9cdc 100644 --- a/src/lr-wpan/test/lr-wpan-error-model-test.cc +++ b/src/lr-wpan/test/lr-wpan-error-model-test.cc @@ -17,21 +17,20 @@ * * Author: Tom Henderson */ - #include -#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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include 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; diff --git a/src/lr-wpan/test/lr-wpan-packet-test.cc b/src/lr-wpan/test/lr-wpan-packet-test.cc index 3329d99b8..75ce6494d 100644 --- a/src/lr-wpan/test/lr-wpan-packet-test.cc +++ b/src/lr-wpan/test/lr-wpan-packet-test.cc @@ -17,14 +17,13 @@ * * Author: Tom Henderson */ - #include #include #include #include #include #include -#include "ns3/log.h" +#include NS_LOG_COMPONENT_DEFINE ("lr-wpan-packet-test"); diff --git a/src/lr-wpan/test/lr-wpan-pd-plme-sap-test.cc b/src/lr-wpan/test/lr-wpan-pd-plme-sap-test.cc index fc3190531..333d3472b 100644 --- a/src/lr-wpan/test/lr-wpan-pd-plme-sap-test.cc +++ b/src/lr-wpan/test/lr-wpan-pd-plme-sap-test.cc @@ -17,9 +17,9 @@ * * Author: Gary Pei */ - #include #include +#include #include #include #include @@ -36,7 +36,7 @@ public: private: virtual void DoRun (void); - void ReceivePdDataInndication (uint32_t psduLength, Ptr p, uint32_t lqi); + void ReceivePdDataInndication (uint32_t psduLength, Ptr p, uint8_t lqi); }; LrWpanPlmeAndPdInterfaceTestCase::LrWpanPlmeAndPdInterfaceTestCase () @@ -51,7 +51,7 @@ LrWpanPlmeAndPdInterfaceTestCase::~LrWpanPlmeAndPdInterfaceTestCase () void LrWpanPlmeAndPdInterfaceTestCase::ReceivePdDataInndication (uint32_t psduLength, Ptr p, - uint32_t lqi) + uint8_t lqi) { NS_LOG_UNCOND ("At: " << Simulator::Now () << " Received frame size: " << psduLength << " LQI: " << diff --git a/src/lr-wpan/test/lr-wpan-spectrum-value-helper-test.cc b/src/lr-wpan/test/lr-wpan-spectrum-value-helper-test.cc index 49cd3eefe..1c9e87974 100644 --- a/src/lr-wpan/test/lr-wpan-spectrum-value-helper-test.cc +++ b/src/lr-wpan/test/lr-wpan-spectrum-value-helper-test.cc @@ -17,10 +17,12 @@ * * Author: Tom Henderson */ - #include #include #include +#include + +#include 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); } } } diff --git a/src/lr-wpan/wscript b/src/lr-wpan/wscript index 985b34cf4..7311f67e6 100644 --- a/src/lr-wpan/wscript +++ b/src/lr-wpan/wscript @@ -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', ]