diff --git a/src/lr-wpan/model/lr-wpan-csmaca.cc b/src/lr-wpan/model/lr-wpan-csmaca.cc index d5b651e0e..844e20b57 100644 --- a/src/lr-wpan/model/lr-wpan-csmaca.cc +++ b/src/lr-wpan/model/lr-wpan-csmaca.cc @@ -21,8 +21,10 @@ */ #include "lr-wpan-csmaca.h" +#include #include #include +#include NS_LOG_COMPONENT_DEFINE ("LrWpanCsmaCa"); @@ -30,14 +32,6 @@ namespace ns3 { NS_OBJECT_ENSURE_REGISTERED (LrWpanCsmaCa); -#ifndef MAX -#define MAX(x,y) (((x) > (y)) ? (x) : (y)) -#endif - -#ifndef MIN -#define MIN(x,y) (((x) < (y)) ? (x) : (y)) -#endif - TypeId LrWpanCsmaCa::GetTypeId (void) { @@ -60,7 +54,7 @@ LrWpanCsmaCa::LrWpanCsmaCa () m_macMaxBE = 5; m_macMaxCSMABackoffs = 4; m_aUnitBackoffPeriod = 20; //20 symbols - m_random = UniformVariable (); + m_random = CreateObject (); m_BE = m_macMinBE; m_ccaRequestRunning = false; } @@ -174,15 +168,14 @@ LrWpanCsmaCa::GetUnitBackoffPeriod (void) const return m_aUnitBackoffPeriod; } -//TODO: -uint64_t +Time LrWpanCsmaCa::GetTimeToNextSlot (void) const { NS_LOG_FUNCTION (this); - uint64_t diffT = 0; + // TODO: Calculate the offset to the next slot. - return(diffT); + return Seconds (0); } void @@ -190,22 +183,21 @@ LrWpanCsmaCa::Start () { NS_LOG_FUNCTION (this); - uint64_t backoffBoundary = 0; m_NB = 0; if (IsSlottedCsmaCa ()) { m_CW = 2; if (m_BLE) { - m_BE = MIN (2, m_macMinBE); + m_BE = std::min (static_cast (2), m_macMinBE); } else { m_BE = m_macMinBE; } //TODO: for slotted, locate backoff period boundary. i.e. delay to the next slot boundary - backoffBoundary = GetTimeToNextSlot (); - m_randomBackoffEvent = Simulator::Schedule (Seconds (backoffBoundary), &LrWpanCsmaCa::RandomBackoffDelay, this); + Time backoffBoundary = GetTimeToNextSlot (); + m_randomBackoffEvent = Simulator::Schedule (backoffBoundary, &LrWpanCsmaCa::RandomBackoffDelay, this); } else { @@ -247,7 +239,7 @@ LrWpanCsmaCa::RandomBackoffDelay () symbolRate = (uint64_t) m_mac->GetPhy ()->GetDataOrSymbolRate (isData); //symbols per second - backoffPeriod = (uint64_t)m_random.GetValue (0, upperBound); //num backoff periods + backoffPeriod = (uint64_t)m_random->GetValue (0, upperBound); //num backoff periods randomBackoff = MicroSeconds (backoffPeriod * GetUnitBackoffPeriod () * 1000 * 1000 / symbolRate); if (IsUnSlottedCsmaCa ()) @@ -268,8 +260,7 @@ void LrWpanCsmaCa::CanProceed () { NS_LOG_FUNCTION (this); - uint64_t backoffBoundary = 0; - uint8_t nextCap = 0; + bool canProceed = true; if (m_BLE) @@ -282,12 +273,13 @@ LrWpanCsmaCa::CanProceed () if (canProceed) { // TODO: For slotted, Perform CCA on backoff period boundary i.e. delay to next slot boundary - backoffBoundary = GetTimeToNextSlot (); - m_requestCcaEvent = Simulator::Schedule (Seconds (backoffBoundary), &LrWpanCsmaCa::RequestCCA, this); + Time backoffBoundary = GetTimeToNextSlot (); + m_requestCcaEvent = Simulator::Schedule (backoffBoundary, &LrWpanCsmaCa::RequestCCA, this); } else { - m_randomBackoffEvent = Simulator::Schedule (Seconds (nextCap), &LrWpanCsmaCa::RandomBackoffDelay, this); + Time nextCap = Seconds (0); + m_randomBackoffEvent = Simulator::Schedule (nextCap, &LrWpanCsmaCa::RandomBackoffDelay, this); } } @@ -349,7 +341,7 @@ LrWpanCsmaCa::PlmeCcaConfirm (LrWpanPhyEnumeration status) { m_CW = 2; } - m_BE = MIN (m_BE + 1, m_macMaxBE); + m_BE = std::min (static_cast (m_BE + 1), static_cast (m_macMaxBE)); m_NB++; if (m_NB > m_macMaxCSMABackoffs) { diff --git a/src/lr-wpan/model/lr-wpan-csmaca.h b/src/lr-wpan/model/lr-wpan-csmaca.h index dd908322e..b694341fc 100644 --- a/src/lr-wpan/model/lr-wpan-csmaca.h +++ b/src/lr-wpan/model/lr-wpan-csmaca.h @@ -24,80 +24,179 @@ #define LR_WPAN_CSMACA_H #include -#include #include #include namespace ns3 { -/* This method informs MAC that channel is idle or busy */ +class UniformRandomVariable; + +/** + * This method informs the MAC whether the channel is idle or busy. + */ typedef Callback LrWpanMacStateCallback; /** * \ingroup lr-wpan * * This class is a helper for the LrWpanMac to manage the Csma/CA - * state machine. + * state machine according to IEEE 802.15.4-2006, section 7.5.1.4. */ class LrWpanCsmaCa : public Object { public: + /** + * Get the type ID. + * + * \return the object TypeId + */ static TypeId GetTypeId (void); + /** + * Default constructor. + */ LrWpanCsmaCa (void); virtual ~LrWpanCsmaCa (void); + /** + * Set the MAC to which this CSMA/CA implementation is attached to. + * + * \param mac the used MAC + */ void SetMac (Ptr mac); + + /** + * Get the MAC to which this CSMA/CA implementation is attached to. + * + * \return the used MAC + */ Ptr GetMac (void) const; + + /** + * Configure for the use of the slotted CSMA/CA version. + */ void SetSlottedCsmaCa (void); + + /** + * Configure for the use of the unslotted CSMA/CA version. + */ void SetUnSlottedCsmaCa (void); + + /** + * Check if the slotted CSMA/CA version is being used. + * + * \return true, if slotted CSMA/CA is used, false otherwise. + */ bool IsSlottedCsmaCa (void) const; + + /** + * Check if the unslotted CSMA/CA version is being used. + * + * \return true, if unslotted CSMA/CA is used, false otherwise. + */ bool IsUnSlottedCsmaCa (void) const; + /** + * Set the minimum backoff exponent value. + * See IEEE 802.15.4-2006, section 7.4.2, Table 86. + * + * \param macMinBE the minimum backoff exponent value + */ void SetMacMinBE (uint8_t macMinBE); + + /** + * Get the minimum backoff exponent value. + * See IEEE 802.15.4-2006, section 7.4.2, Table 86. + * + * \return the minimum backoff exponent value + */ uint8_t GetMacMinBE (void) const; + + /** + * Set the maximum backoff exponent value. + * See IEEE 802.15.4-2006, section 7.4.2, Table 86. + * + * \param macMaxBE the maximum backoff exponent value + */ void SetMacMaxBE (uint8_t macMaxBE); + + /** + * Get the maximum backoff exponent value. + * See IEEE 802.15.4-2006, section 7.4.2, Table 86. + * + * \return the maximum backoff exponent value + */ uint8_t GetMacMaxBE (void) const; + + /** + * Set the maximum number of backoffs. + * See IEEE 802.15.4-2006, section 7.4.2, Table 86. + * + * \param macMaxCSMABackoffs the maximum number of backoffs + */ void SetMacMaxCSMABackoffs (uint8_t macMaxCSMABackoffs); + + /** + * Get the maximum number of backoffs. + * See IEEE 802.15.4-2006, section 7.4.2, Table 86. + * + * \return the maximum number of backoffs + */ uint8_t GetMacMaxCSMABackoffs (void) const; + /** + * Set the number of symbols forming the basic time period used by the + * CSMA-CA algorithm. + * See IEEE 802.15.4-2006, section 7.4.1, Table 85. + * + * \param unitBackoffPeriod the period length in symbols + */ void SetUnitBackoffPeriod (uint64_t unitBackoffPeriod); + + /** + * Get the number of symbols forming the basic time period used by the + * CSMA-CA algorithm. + * See IEEE 802.15.4-2006, section 7.4.1, Table 85. + * + * \return the period length in symbols + */ uint64_t GetUnitBackoffPeriod (void) const; - /* - * Amount of time from now to the beginning of the next slot + /** + * Get the amount of time from now to the beginning of the next slot. + * + * \return time offset to the next slot */ - uint64_t GetTimeToNextSlot (void) const; + Time GetTimeToNextSlot (void) const; - /* + /** * Start CSMA-CA algorithm (step 1), initialize NB, BE for both slotted and unslotted * CSMA-CA. For the slotted intialize CW plus also start on the backoff boundary */ void Start (void); - /* - * cancel CSMA-CA algorithm + /** + * Cancel CSMA-CA algorithm. */ void Cancel (void); - /* + /** * In step 2 of the CSMA-CA, perform a random backoff in the range of 0 to 2^BE -1 */ void RandomBackoffDelay (void); - /* - * In the slotted CSMA-CA, after random backoff, Determine if the remaining - * CSMA-CA operation can proceed ie. Can the entire transactions can be transmitted - * before the end of the CAP. This step is performed between step 2 and 3. - * This step is NOT performed for the unslotted CSMA-CA. If it can proceed - * function CCAconfirmed() is called. + /** + * In the slotted CSMA-CA, after random backoff, determine if the remaining + * CSMA-CA operation can proceed, i.e. can the entire transactions can be + * transmitted before the end of the CAP. This step is performed between step + * 2 and 3. This step is NOT performed for the unslotted CSMA-CA. If it can + * proceed function RequestCCA() is called. */ void CanProceed (void); - /* + /** * Request the Phy to perform CCA (Step 3) - * */ void RequestCCA (void); @@ -115,33 +214,97 @@ public: void PlmeCcaConfirm (LrWpanPhyEnumeration status); /** - * set the callback function. Used at the end of a Channel Assessment, as part of the - * interconnections between the CSMA-CA and the MAC. The callback - * lets MAc know a channel is either idle or busy - */ + * Set the callback function to the MAC. Used at the end of a Channel Assessment, as part of the + * interconnections between the CSMA-CA and the MAC. The callback + * lets MAC know a channel is either idle or busy. + * + * \param macState the mac state callback + */ void SetLrWpanMacStateCallback (LrWpanMacStateCallback macState); private: virtual void DoDispose (void); + + /** + * The callback to inform the configured MAC of the CSMA/CA result. + */ LrWpanMacStateCallback m_lrWpanMacStateCallback; - bool m_isSlotted; // beacon-enabled slotted or nonbeacon-enabled unslotted CSMA-CA - // beacon order == 15 means nonbeacon-enabled + /** + * Beacon-enabled slotted or nonbeacon-enabled unslotted CSMA-CA. + */ + bool m_isSlotted; + + /** + * The MAC instance for which this CSMAƄ/CA implemenation is configured. + */ Ptr m_mac; - uint8_t m_NB; // number of backoffs for the current transmission - uint8_t m_CW; // contention window length (used in slotted ver only) - uint8_t m_BE; // backoff exponent - bool m_BLE; // Battery Life Extension - uint8_t m_macMinBE; //0-macMaxBE default 3 - 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; + /** + * Number of backoffs for the current transmission. + */ + uint8_t m_NB; + /** + * Contention window length (used in slotted ver only). + */ + uint8_t m_CW; + + /** + * Backoff exponent. + */ + uint8_t m_BE; + + /** + * Battery Life Extension. + */ + bool m_BLE; + + /** + * Minimum backoff exponent. 0 - macMaxBE, default 3 + */ + uint8_t m_macMinBE; // + + /** + * Maximum backoff exponent. 3 - 8, default 5 + */ + uint8_t m_macMaxBE; + + /** + * Maximum number of backoffs. 0 - 5, default 4 + */ + uint8_t m_macMaxCSMABackoffs; + + /** + * Number of symbols per CSMA/CA time unit, default 20 symbols. + */ + uint64_t m_aUnitBackoffPeriod; + + /** + * Uniform random variable stream. + */ + Ptr m_random; + + /** + * Scheduler event for the start of the next random backoff/slot. + */ EventId m_randomBackoffEvent; + + /** + * Scheduler event when to start the CCA after a random backoff. + */ EventId m_requestCcaEvent; + + /** + * Scheduler event for checking if we can complete the transmission before the + * end of the CAP. + */ EventId m_canProceedEvent; + + /** + * Flag indicating that the PHY is currently running a CCA. Used to prevent + * reporting the channel status to the MAC while canceling the CSMA algorithm. + */ bool m_ccaRequestRunning; }; diff --git a/src/lr-wpan/model/lr-wpan-error-model.h b/src/lr-wpan/model/lr-wpan-error-model.h index 38bc18f8d..8182bb507 100644 --- a/src/lr-wpan/model/lr-wpan-error-model.h +++ b/src/lr-wpan/model/lr-wpan-error-model.h @@ -34,12 +34,18 @@ namespace ns3 { class LrWpanErrorModel : public Object { public: + /** + * Get the type ID. + * + * \return the object TypeId + */ static TypeId GetTypeId (void); LrWpanErrorModel (void); /** - * return chunk success rate for given SNR + * Return chunk success rate for given SNR. + * * \return success rate (i.e. 1 - chunk error rate) * \param snr SNR expressed as a power ratio (i.e. not in dB) * \param nbits number of bits in the chunk @@ -47,6 +53,9 @@ public: double GetChunkSuccessRate (double snr, uint32_t nbits) const; private: + /** + * Array of precalculated binomial coefficients. + */ double m_binomialCoefficients[17]; }; diff --git a/src/lr-wpan/model/lr-wpan-interference-helper.cc b/src/lr-wpan/model/lr-wpan-interference-helper.cc index fb3827d61..f8e11925c 100644 --- a/src/lr-wpan/model/lr-wpan-interference-helper.cc +++ b/src/lr-wpan/model/lr-wpan-interference-helper.cc @@ -28,11 +28,12 @@ NS_LOG_COMPONENT_DEFINE ("LrWpanInterferenceHelper"); namespace ns3 { LrWpanInterferenceHelper::LrWpanInterferenceHelper (Ptr spectrumModel) : - m_spectrumModel (spectrumModel), m_dirty(true) + m_spectrumModel (spectrumModel), m_dirty (false) { + m_signal = Create (m_spectrumModel); } -LrWpanInterferenceHelper::~LrWpanInterferenceHelper () +LrWpanInterferenceHelper::~LrWpanInterferenceHelper (void) { m_spectrumModel = 0; m_signal = 0; @@ -76,7 +77,7 @@ LrWpanInterferenceHelper::RemoveSignal (Ptr signal) } void -LrWpanInterferenceHelper::ClearSignals () +LrWpanInterferenceHelper::ClearSignals (void) { NS_LOG_FUNCTION (this); @@ -85,7 +86,7 @@ LrWpanInterferenceHelper::ClearSignals () } Ptr -LrWpanInterferenceHelper::GetSignalPsd () const +LrWpanInterferenceHelper::GetSignalPsd (void) const { NS_LOG_FUNCTION (this); diff --git a/src/lr-wpan/model/lr-wpan-interference-helper.h b/src/lr-wpan/model/lr-wpan-interference-helper.h index 3ceff33a4..2491288c9 100644 --- a/src/lr-wpan/model/lr-wpan-interference-helper.h +++ b/src/lr-wpan/model/lr-wpan-interference-helper.h @@ -18,8 +18,8 @@ * Author: * Sascha Alexander Jopen */ -#ifndef LR_WPAN_LR_WPAN_INTERFERENCE_HELPER_H -#define LR_WPAN_LR_WPAN_INTERFERENCE_HELPER_H +#ifndef LR_WPAN_INTERFERENCE_HELPER_H +#define LR_WPAN_INTERFERENCE_HELPER_H #include #include @@ -30,24 +30,85 @@ namespace ns3 { class SpectrumValue; class SpectrumModel; +/** + * \ingroup lr-wpan + * + * \brief This class provides helper functions for LrWpan interference handling. + */ class LrWpanInterferenceHelper : public SimpleRefCount { public: + /** + * Create a new interference helper for the given SpectrumModel. + * + * \param spectrumModel the SpectrumModel to be used + */ LrWpanInterferenceHelper (Ptr spectrumModel); - ~LrWpanInterferenceHelper (); + ~LrWpanInterferenceHelper (void); + + /** + * Add the given signal to the set of accumulated signals. Never add the same + * signal more than once. The SpectrumModels of the signal and the one used + * for instantiation of the helper have to be the same. + * + * \param signal the signal to be added + * \return false, if the signal was not added because the SpectrumModel of the + * signal does not match the one of the helper, true otherwise. + */ bool AddSignal (Ptr signal); + + /** + * Remove the given signal to the set of accumulated signals. + * + * \param signal the signal to be removed + * \return false, if the signal was not removed (because it was not added + * before), true otherwise. + */ bool RemoveSignal (Ptr signal); - void ClearSignals (); - Ptr GetSignalPsd () const; - Ptr GetSpectrumModel () const; + + /** + * Remove all currently accumulated signals. + */ + void ClearSignals (void); + + /** + * Get the sum of all accumulated signals. + * + * \return the sum of the signals + */ + Ptr GetSignalPsd (void) const; + + /** + * Get the SpectrumModel used by the helper. + * + * \return the helpers SpectrumModel + */ + Ptr GetSpectrumModel (void) const; private: + + /** + * The helpers SpectrumModel. + */ Ptr m_spectrumModel; + + /** + * The set of accumulated signals. + */ std::set > m_signals; + + /** + * The precomputed sum of all accumulated signals. + */ mutable Ptr m_signal; + + /** + * Mark m_signal as dirty, whenever a signal is added or removed. m_signal has + * to be recomputed before next use. + */ mutable bool m_dirty; }; } -#endif /* LR_WPAN_LR_WPAN_INTERFERENCE_HELPER_H */ +#endif /* LR_WPAN_INTERFERENCE_HELPER_H */ diff --git a/src/lr-wpan/model/lr-wpan-lqi-tag.h b/src/lr-wpan/model/lr-wpan-lqi-tag.h index f88821216..e4c44bb6f 100644 --- a/src/lr-wpan/model/lr-wpan-lqi-tag.h +++ b/src/lr-wpan/model/lr-wpan-lqi-tag.h @@ -25,16 +25,20 @@ namespace ns3 { -class Tag; - class LrWpanLqiTag : public Tag { public: + /** + * Get the type ID. + * + * \return the object TypeId + */ static TypeId GetTypeId (void); + virtual TypeId GetInstanceTypeId (void) const; /** - * Create a LrWpanLqiTag with the default LQI 0 . + * Create a LrWpanLqiTag with the default LQI 0. */ LrWpanLqiTag (void); @@ -51,16 +55,21 @@ public: /** * Set the LQI to the given value. * - * @param lqi the value of the LQI to set + * \param lqi the value of the LQI to set */ void Set (uint8_t lqi); + /** * Get the LQI value. * - * @return the LQI value + * \return the LQI value */ uint8_t Get (void) const; private: + + /** + * The current LQI value of the tag. + */ uint8_t m_lqi; }; diff --git a/src/lr-wpan/model/lr-wpan-mac-header.h b/src/lr-wpan/model/lr-wpan-mac-header.h index 45fc4a378..968111154 100644 --- a/src/lr-wpan/model/lr-wpan-mac-header.h +++ b/src/lr-wpan/model/lr-wpan-mac-header.h @@ -232,8 +232,7 @@ private: uint8_t m_auxKeyIdKeyIndex; // 1 octet }; //LrWpanMacHeader + }; // namespace ns-3 + #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 4048bdf98..08bf9eab7 100644 --- a/src/lr-wpan/model/lr-wpan-mac-trailer.cc +++ b/src/lr-wpan/model/lr-wpan-mac-trailer.cc @@ -27,8 +27,10 @@ namespace ns3 { NS_OBJECT_ENSURE_REGISTERED (LrWpanMacTrailer); -LrWpanMacTrailer::LrWpanMacTrailer () : - m_fcs (0), m_calcFcs (false) +const uint16_t LrWpanMacTrailer::LR_WPAN_MAC_FCS_LENGTH = 2; + +LrWpanMacTrailer::LrWpanMacTrailer (void) + : m_fcs (0), m_calcFcs (false) { } @@ -57,23 +59,23 @@ LrWpanMacTrailer::Print (std::ostream &os) const uint32_t LrWpanMacTrailer::GetSerializedSize (void) const { - return LRWPAN_MAC_FCS_LENGTH; + return LR_WPAN_MAC_FCS_LENGTH; } void LrWpanMacTrailer::Serialize (Buffer::Iterator start) const { - start.Prev (LRWPAN_MAC_FCS_LENGTH); + start.Prev (LR_WPAN_MAC_FCS_LENGTH); start.WriteU16 (m_fcs); } uint32_t LrWpanMacTrailer::Deserialize (Buffer::Iterator start) { - start.Prev (LRWPAN_MAC_FCS_LENGTH); + start.Prev (LR_WPAN_MAC_FCS_LENGTH); m_fcs = start.ReadU16 (); - return LRWPAN_MAC_FCS_LENGTH; + return LR_WPAN_MAC_FCS_LENGTH; } uint16_t @@ -124,10 +126,18 @@ void LrWpanMacTrailer::EnableFcs (bool enable) { m_calcFcs = enable; + if (!enable) + { + m_fcs = 0; + } +} + +bool +LrWpanMacTrailer::IsFcsEnabled (void) +{ + return m_calcFcs; } -/* 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) { diff --git a/src/lr-wpan/model/lr-wpan-mac-trailer.h b/src/lr-wpan/model/lr-wpan-mac-trailer.h index 7ddbfccfc..04ab7910e 100644 --- a/src/lr-wpan/model/lr-wpan-mac-trailer.h +++ b/src/lr-wpan/model/lr-wpan-mac-trailer.h @@ -31,32 +31,101 @@ namespace ns3 { class Packet; /** - * The length in octets of the IEEE 802.15.4 MAC FCS field + * \ingroup lr-wpan + * + * Represent the Mac Trailer with the Frame Check Sequence field. */ - -static const uint16_t LRWPAN_MAC_FCS_LENGTH = 2; - class LrWpanMacTrailer : public Trailer { public: - LrWpanMacTrailer (); + /** + * The length in octets of the IEEE 802.15.4 MAC FCS field + */ + static const uint16_t LR_WPAN_MAC_FCS_LENGTH; + /** + * Get the type ID. + * + * \return the object TypeId + */ static TypeId GetTypeId (void); + + /** + * Default constructor for a MAC trailer with disabled FCS calculation. + */ + LrWpanMacTrailer (void); + + // Inherited from the Trailer class. virtual TypeId GetInstanceTypeId (void) const; virtual void Print (std::ostream &os) const; virtual uint32_t GetSerializedSize (void) const; virtual void Serialize (Buffer::Iterator start) const; virtual uint32_t Deserialize (Buffer::Iterator start); + /** + * Get this trailers FCS value. If FCS calculation is disabled for this + * trailer, the returned value is always 0. + * + * \return the FCS value. + */ uint16_t GetFcs (void) const; + + /** + * Calculate and set the FCS value based on the given packet. + * + * \param p the packet for which the FCS should be calculated + */ void SetFcs (Ptr p); + + /** + * Check the FCS of a given packet against the FCS value stored in the + * trailer. The packet itself should contain no trailer. If FCS calculation is + * disabled for this trailer, CheckFcs() will always return true. + * + * \param the packet to be checked + * \return false, if the FCS values do not match, true otherwise + */ bool CheckFcs (Ptr p); + + /** + * Enable or disable FCS calculation for this trailer. + * + * \param enable flag, indicating if FCS calculation should be enabled or not + */ void EnableFcs (bool enable); + /** + * Query if FCS calculation is enabled for this trailer. + * + * \return true, if FCS calculation is enabled, false otherwise. + */ + bool IsFcsEnabled (void); + private: - uint16_t m_fcs; - bool m_calcFcs; + /** + * Calculate the 16-bit FCS value. + * CRC16-CCITT with a generator polynomial = ^16 + ^12 + ^5 + 1, LSB first and + * initial value = 0x0000. + * + * \param data the checksum will be calculated over this data + * \param length the length of the data + * \return the checksum + */ uint16_t GenerateCrc16 (uint8_t *data, int length); + + /** + * The FCS value stored in this trailer. + */ + uint16_t m_fcs; + + /** + * Only if m_calcFcs is true, FCS values will be calculated and used in the + * trailer + */ + bool m_calcFcs; + }; + } // namespace ns3 + #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 c3cb8d16b..599b5f834 100644 --- a/src/lr-wpan/model/lr-wpan-mac.cc +++ b/src/lr-wpan/model/lr-wpan-mac.cc @@ -31,6 +31,8 @@ #include #include #include +#include +#include NS_LOG_COMPONENT_DEFINE ("LrWpanMac"); @@ -106,9 +108,10 @@ LrWpanMac::LrWpanMac () m_retransmission = 0; m_txPkt = 0; - UniformVariable uniformVar; - uniformVar = UniformVariable (0, 255); - m_macDsn = SequenceNumber8 (uniformVar.GetValue ()); + Ptr uniformVar = CreateObject (); + uniformVar->SetAttribute ("Min", DoubleValue (0.0)); + uniformVar->SetAttribute ("Max", DoubleValue (255.0)); + m_macDsn = SequenceNumber8 (uniformVar->GetValue ()); m_shortAddress = Mac16Address ("00:00"); } diff --git a/src/lr-wpan/model/lr-wpan-net-device.cc b/src/lr-wpan/model/lr-wpan-net-device.cc index 785f64745..55d2acd53 100644 --- a/src/lr-wpan/model/lr-wpan-net-device.cc +++ b/src/lr-wpan/model/lr-wpan-net-device.cc @@ -225,6 +225,7 @@ LrWpanNetDevice::LinkUp (void) m_linkUp = true; m_linkChanges (); } + void LrWpanNetDevice::LinkDown (void) { @@ -233,13 +234,13 @@ LrWpanNetDevice::LinkDown (void) m_linkChanges (); } - Ptr LrWpanNetDevice::DoGetChannel (void) const { NS_LOG_FUNCTION (this); return m_phy->GetChannel (); } + void LrWpanNetDevice::SetAddress (Address address) { diff --git a/src/lr-wpan/model/lr-wpan-net-device.h b/src/lr-wpan/model/lr-wpan-net-device.h index 7849e4d09..c61045b06 100644 --- a/src/lr-wpan/model/lr-wpan-net-device.h +++ b/src/lr-wpan/model/lr-wpan-net-device.h @@ -38,11 +38,11 @@ class Node; /** * \ingroup lr-wpan * - * \brief Network layer to device interface + * \brief Network layer to device interface. * - * The ns3::NetDevice includes IP-specific API such as GetMulticast(), and - * the Send() and SendTo() methods do not map well the the 802.15.4 MAC - * MCPS DataRequest primitive. So, the basic design is to provide, as + * The ns3::NetDevice includes IP-specific API such as GetMulticast(), Send() + * and SendTo() methods, which do not map well the the 802.15.4 MAC MCPS + * DataRequest primitive. So, the basic design is to provide, as * much as makes sense, the class ns3::NetDevice API, but rely on the user * accessing the LrWpanMac pointer to make 802.15.4-specific API calls. * As such, this is really just an encapsulating class. @@ -50,24 +50,64 @@ class Node; class LrWpanNetDevice : public NetDevice { public: + /** + * Get the type ID. + * + * \return the object TypeId + */ static TypeId GetTypeId (void); LrWpanNetDevice (void); virtual ~LrWpanNetDevice (void); - void SetMac (Ptr mac); - void SetPhy (Ptr phy); - void SetCsmaCa (Ptr csmaca); - void SetChannel (Ptr channel); /** - * We disallow the conventional Send/SendFrom methods in this NetDevice, - * preferring instead that the higher layer access the LrWpanMac object - * directly (with its specific API). + * Set the MAC to be used by this NetDevice. * - * \return pointer to the LrWpanMac/Phy/Csmaca object + * \param mac the MAC to be used + */ + void SetMac (Ptr mac); + + /** + * Set the PHY to be used by the MAC and this NetDevice. + * + * \param phy the PHY to be used + */ + void SetPhy (Ptr phy); + + /** + * Set the CSMA/CA implementation to be used by the MAC and this NetDevice. + * + * \param csmaca the CSMA/CA implementation to be used + */ + void SetCsmaCa (Ptr csmaca); + + /** + * Set the channel to which the NetDevice, and therefore the PHY, should be + * attached to. + * + * \param channel the channel to be used + */ + void SetChannel (Ptr channel); + + /** + * Get the MAC used by this NetDevice. + * + * \return the MAC object */ Ptr GetMac (void) const; + + /** + * Get the PHY used by this NetDevice. + * + * \return the PHY object + */ Ptr GetPhy (void) const; + + /** + * Get the CSMA/CA implementation used by this NetDevice. + * + * \return the CSMA/CA implementation object + */ Ptr GetCsmaCa (void) const; // From class NetDevice @@ -103,27 +143,93 @@ public: virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb); virtual bool SupportsSendFrom (void) const; + /** + * The callback used by the MAC to hand over incoming packets to the + * NetDevice. This callback will in turn use the ReceiveCallback set by + * SetReceiveCallback() to notify upper layers. + * + * \param params 802.15.4 specific parameters, including source and destination addresses + * \param pkt the packet do be delivered + */ void McpsDataIndication (McpsDataIndicationParams params, Ptr pkt); private: + // Inherited from NetDevice/Object virtual void DoDispose (void); virtual void DoStart (void); + + /** + * Mark NetDevice link as up. + */ void LinkUp (void); + + /** + * Mark NetDevice link as down. + */ void LinkDown (void); + + /** + * Attribute accessor method for the "Channel" attribute. + * + * \return the channel to which this NetDevice is attached + */ Ptr DoGetChannel (void) const; + + /** + * Configure PHY, MAC and CSMA/CA. + */ void CompleteConfig (void); + /** + * The MAC for this NetDevice. + */ Ptr m_mac; + + /** + * The PHY for this NetDevice. + */ Ptr m_phy; + + /** + * The CSMA/CA implementation for this NetDevice. + */ Ptr m_csmaca; + + /** + * The node associated with this NetDevice. + */ Ptr m_node; + + /** + * True if MAC, PHY and CSMA/CA where successfully configured and the + * NetDevice is ready for being used. + */ bool m_configComplete; + + /** + * Configure the NetDevice to request MAC layer acknowledgements when sending + * packets using the Send() API. + */ bool m_useAcks; + /** + * Is the link/device currently up and running? + */ bool m_linkUp; + + /** + * The interface index of this NetDevice. + */ uint32_t m_ifIndex; + /** + * Trace source for link up/down changes. + */ TracedCallback<> m_linkChanges; + + /** + * Upper layer callback used for notification of new data packet arrivals. + */ ReceiveCallback m_receiveCallback; }; diff --git a/src/lr-wpan/model/lr-wpan-phy.cc b/src/lr-wpan/model/lr-wpan-phy.cc index 6db6cd869..a0967dc61 100644 --- a/src/lr-wpan/model/lr-wpan-phy.cc +++ b/src/lr-wpan/model/lr-wpan-phy.cc @@ -35,6 +35,8 @@ #include #include #include +#include +#include NS_LOG_COMPONENT_DEFINE ("LrWpanPhy"); @@ -136,6 +138,11 @@ LrWpanPhy::LrWpanPhy () m_currentTxPacket = std::make_pair (none_packet, true); m_errorModel = 0; + m_random = CreateObject (); + m_random->SetAttribute ("Min", DoubleValue (0.0)); + m_random->SetAttribute ("Max", DoubleValue (1.0)); + + ChangeTrxState (IEEE_802_15_4_PHY_TRX_OFF); } @@ -379,7 +386,7 @@ LrWpanPhy::CheckInterference () tag.Set (lqi - (per * lqi)); currentPacket->ReplacePacketTag (tag); - if (m_random.GetValue () < per) + if (m_random->GetValue () < per) { // The packet was destroyed, drop the packet after reception. m_currentRxPacket.second = true; diff --git a/src/lr-wpan/model/lr-wpan-phy.h b/src/lr-wpan/model/lr-wpan-phy.h index f653fc801..dfb52e18a 100644 --- a/src/lr-wpan/model/lr-wpan-phy.h +++ b/src/lr-wpan/model/lr-wpan-phy.h @@ -27,7 +27,6 @@ #include #include #include -#include namespace ns3 { @@ -40,6 +39,7 @@ class SpectrumChannel; class SpectrumModel; class AntennaModel; class NetDevice; +class UniformRandomVariable; /** * Helper structure to manage the power measurement during ED. @@ -205,50 +205,79 @@ class LrWpanPhy : public SpectrumPhy { public: - // The second is true if the first is flagged as error - typedef std::pair, bool> PacketAndStatus; - + /** + * Get the type ID. + * + * \return the object TypeId + */ static TypeId GetTypeId (void); - static const uint32_t aMaxPhyPacketSize; // Table 22 in section 6.4.1 of ieee802.15.4 - static const uint32_t aTurnaroundTime; // Table 22 in section 6.4.1 of ieee802.15.4 + /** + * The maximum packet size accepted by the PHY. + * See Table 22 in section 6.4.1 of IEEE 802.15.4-2006 + */ + static const uint32_t aMaxPhyPacketSize; - LrWpanPhy (); - virtual ~LrWpanPhy (); + /** + * The turnaround time for switching the transceiver from RX to TX or vice + * versa. + * See Table 22 in section 6.4.1 of IEEE 802.15.4-2006 + */ + static const uint32_t aTurnaroundTime; + + /** + * Default constructor. + */ + LrWpanPhy (void); + virtual ~LrWpanPhy (void); // inherited from SpectrumPhy void SetMobility (Ptr m); - Ptr GetMobility (); + Ptr GetMobility (void); void SetChannel (Ptr c); - Ptr GetChannel (void); - void SetDevice (Ptr d); - Ptr GetDevice (); - void SetAntenna (Ptr a); - Ptr GetRxAntenna (); - virtual Ptr GetRxSpectrumModel () const; /** - * set the Power Spectral Density of outgoing signals in W/Hz. + * Get the currently attached channel. * - * @param txPsd + * \return the channel + */ + Ptr GetChannel (void); + void SetDevice (Ptr d); + Ptr GetDevice (void); + + /** + * Set the attached antenna. + * + * \param a the antenna + */ + void SetAntenna (Ptr a); + Ptr GetRxAntenna (void); + virtual Ptr GetRxSpectrumModel (void) const; + + /** + * Set the Power Spectral Density of outgoing signals in W/Hz. + * + * @param txPsd the Power Spectral Density value */ void SetTxPowerSpectralDensity (Ptr txPsd); /** - * \brief set the noise power spectral density + * Set the noise power spectral density. + * * @param noisePsd the Noise Power Spectral Density in power units * (Watt, Pascal...) per Hz. */ void SetNoisePowerSpectralDensity (Ptr noisePsd); /** - * \brief get the noise power spectral density + * Get the noise power spectral density. + * * @return the Noise Power Spectral Density */ Ptr GetNoisePowerSpectralDensity (void); /** - * Notify the SpectrumPhy instance of an incoming waveform + * Notify the SpectrumPhy instance of an incoming waveform. * * @param params the SpectrumSignalParameters associated with the incoming waveform */ @@ -379,45 +408,145 @@ public: */ Ptr GetErrorModel (void) const; + /** + * Get the duration of the SHR (preamble and SFD) in symbols, depending on + * the currently selected channel. + * + * \return the SHR duration in symbols + */ uint64_t GetPhySHRDuration (void) const; + + /** + * Get the number of symbols per octet, depending on the currently selected + * channel. + * + * \return the number of symbols per octet + */ double GetPhySymbolsPerOctet (void) const; protected: + /** + * The data and symbol rates for the different PHY options. + * See Table 2 in section 6.1.2 IEEE 802.15.4-2006 + */ static const LrWpanPhyDataAndSymbolRates dataSymbolRates[7]; + /** + * The preamble, SFD, and PHR lengths in symbols for the different PHY options. + * See Table 19 and Table 20 in section 6.3 IEEE 802.15.4-2006 + */ static const LrWpanPhyPpduHeaderSymbolNumber ppduHeaderSymbolNumbers[7]; private: - virtual void DoDispose (void); - void ChangeState (LrWpanPhyEnumeration newState); - void ChangeTrxState (LrWpanPhyEnumeration newState); - void SetMyPhyOption (void); - LrWpanPhyOption GetMyPhyOption (void); - void EndTx (); - void CheckInterference (); + /** + * The second is true if the first is flagged as error/invalid. + */ + typedef std::pair, bool> PacketAndStatus; + // Inherited from Object. + virtual void DoDispose (void); + + /** + * Change the PHY state to the given new state, firing the state change trace. + * + * \param newState the new state + */ + void ChangeTrxState (LrWpanPhyEnumeration newState); + + /** + * Configure the PHY option according to the current channel and channel page. + * See IEEE 802.15.4-2006, section 6.1.2, Table 2. + */ + void SetMyPhyOption (void); + + /** + * Get the currently configured PHY option. + * See IEEE 802.15.4-2006, section 6.1.2, Table 2. + * + * \return the PHY option + */ + LrWpanPhyOption GetMyPhyOption (void); + + /** + * Finish the transmission of a frame. This is called at the end of a frame + * transmission, applying possibly pending PHY state changes and fireing the + * appropriate trace sources and confirm callbacks to the MAC. + */ + void EndTx (void); + + /** + * Check if the interference destroys a frame currently received. Called + * whenever a change in interference is detected. + */ + void CheckInterference (void); + + /** + * Finish the reception of a frame. This is called at the end of a frame + * reception, applying possibly pending PHY state changes and fireing the + * appropriate trace sources and indication callbacks to the MAC. A frame + * destroyed by noise/interference is dropped here, but not during reception. + * This method is also called for every packet which only contributes to + * interference. + * + * \param params signal parameters of the packet + */ void EndRx (Ptr params); + + /** + * Cancel an ongoing ED procedure. This is called when the transceiver is + * switched off or set to TX mode. This calls the appropiate confirm callback + * of the MAC. + * + * \param state the new state which is the cause for canceling ED + */ void CancelEd (LrWpanPhyEnumeration state); - void EndEd (); - void EndCca (); - void EndSetTRXState (); - Time CalculateTxTime (Ptr packet); - Time GetPpduHeaderTxTime (void); - bool ChannelSupported (uint8_t); - Ptr m_mobility; - Ptr m_device; - Ptr m_channel; - Ptr m_antenna; - Ptr m_txPsd; - Ptr m_noise; - Ptr m_errorModel; - LrWpanPhyPibAttributes m_phyPIBAttributes; + /** + * Called at the end of the ED procedure. The average energy detected is + * reported to the MAC. + */ + void EndEd (void); - // State variables - LrWpanPhyEnumeration m_trxState; /// transceiver state - TracedCallback m_trxStateLogger; - LrWpanPhyEnumeration m_trxStatePending; /// pending state change - bool PhyIsBusy (void) const; /// helper function + /** + * Called at the end of the CCA. The channel condition (busy or idle) is + * reported to the MAC or CSMA/CA. + */ + void EndCca (void); + + /** + * Called after applying a deferred transceiver state switch. The result of + * the state switch is reported to the MAC. + */ + void EndSetTRXState (void); + + /** + * Calculate the time required for sending the given packet, including + * preamble, SFD and PHR. + * + * \param packet the packet for which the transmission time should be calculated + */ + Time CalculateTxTime (Ptr packet); + + /** + * Calculate the time required for sending the PPDU header, that is the + * preamble, SFD and PHR. + */ + Time GetPpduHeaderTxTime (void); + + /** + * Check if the given channel is supported by the PHY. + * + * \param channel the channel to check + * \return true, if the channel is supported, false otherwise + */ + bool ChannelSupported (uint8_t channel); + + /** + * Check if the PHY is busy, which is the case if the PHY is currently sending + * or receiving a frame. + * + * \return true, if the PHY is busy, false otherwise + */ + bool PhyIsBusy (void) const; // Trace sources /** @@ -467,6 +596,20 @@ private: */ TracedCallback > m_phyRxDropTrace; + Ptr m_mobility; + Ptr m_device; + Ptr m_channel; + Ptr m_antenna; + Ptr m_txPsd; + Ptr m_noise; + Ptr m_errorModel; + LrWpanPhyPibAttributes m_phyPIBAttributes; + + // State variables + LrWpanPhyEnumeration m_trxState; /// transceiver state + TracedCallback m_trxStateLogger; + LrWpanPhyEnumeration m_trxStatePending; /// pending state change + PdDataIndicationCallback m_pdDataIndicationCallback; PdDataConfirmCallback m_pdDataConfirmCallback; PlmeCcaConfirmCallback m_plmeCcaConfirmCallback; @@ -487,7 +630,11 @@ private: EventId m_edRequest; EventId m_setTRXState; EventId m_pdDataRequest; - UniformVariable m_random; + + /** + * Uniform random variable stream. + */ + Ptr m_random; }; 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 7383cd60d..f8b00d16e 100644 --- a/src/lr-wpan/model/lr-wpan-spectrum-signal-parameters.h +++ b/src/lr-wpan/model/lr-wpan-spectrum-signal-parameters.h @@ -29,9 +29,9 @@ namespace ns3 { class PacketBurst; /** - * \ingroup lte + * \ingroup lr-wpan * - * Signal parameters for LrWpan + * Signal parameters for LrWpan. */ struct LrWpanSpectrumSignalParameters : public SpectrumSignalParameters { 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 dea753c20..64b5963a7 100644 --- a/src/lr-wpan/model/lr-wpan-spectrum-value-helper.cc +++ b/src/lr-wpan/model/lr-wpan-spectrum-value-helper.cc @@ -60,6 +60,7 @@ LrWpanSpectrumValueHelper::LrWpanSpectrumValueHelper (void) LrWpanSpectrumValueHelper::~LrWpanSpectrumValueHelper (void) { + NS_LOG_FUNCTION (this); } Ptr 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 647439e87..163421e3d 100644 --- a/src/lr-wpan/model/lr-wpan-spectrum-value-helper.h +++ b/src/lr-wpan/model/lr-wpan-spectrum-value-helper.h @@ -54,12 +54,15 @@ public: /** * \brief total average power of the signal is the integral of the PSD - * \param power spectral density + * \param psd spectral density * \return total power (using composite trap. rule to numerally integrate */ static double TotalAvgPower (Ptr psd); private: + /** + * A scaling factor for the noise power. + */ double m_noiseFactor; };