From 7e4b11dade87bbe75b1ea8de463c3f08eff0bdab Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Sun, 29 May 2011 14:38:53 -0700 Subject: [PATCH] Initial lr-wpan checkin --- src/lr-wpan/doc/lr-wpan.rst | 176 ++++ src/lr-wpan/examples/lr-wpan-data.cc | 131 +++ src/lr-wpan/examples/lr-wpan-packet-print.cc | 60 ++ src/lr-wpan/examples/lr-wpan-phy-test.cc | 94 ++ src/lr-wpan/examples/wscript | 11 + src/lr-wpan/helper/lr-wpan-helper.cc | 92 ++ src/lr-wpan/helper/lr-wpan-helper.h | 76 ++ src/lr-wpan/model/lr-wpan-csmaca.cc | 339 +++++++ src/lr-wpan/model/lr-wpan-csmaca.h | 139 +++ 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-mac-header.cc | 824 +++++++++++++++++ src/lr-wpan/model/lr-wpan-mac-header.h | 231 +++++ src/lr-wpan/model/lr-wpan-mac-trailer.cc | 60 ++ src/lr-wpan/model/lr-wpan-mac-trailer.h | 36 + src/lr-wpan/model/lr-wpan-mac.cc | 204 +++++ src/lr-wpan/model/lr-wpan-mac.h | 189 ++++ src/lr-wpan/model/lr-wpan-phy.cc | 859 ++++++++++++++++++ src/lr-wpan/model/lr-wpan-phy.h | 421 +++++++++ .../model/lr-wpan-spectrum-value-helper.cc | 117 +++ .../model/lr-wpan-spectrum-value-helper.h | 59 ++ 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-packet-test.cc | 146 +++ src/lr-wpan/test/lr-wpan-pd-plme-sap-test.cc | 99 ++ src/lr-wpan/wscript | 35 + 28 files changed, 4798 insertions(+) create mode 100644 src/lr-wpan/doc/lr-wpan.rst create mode 100644 src/lr-wpan/examples/lr-wpan-data.cc create mode 100644 src/lr-wpan/examples/lr-wpan-packet-print.cc create mode 100644 src/lr-wpan/examples/lr-wpan-phy-test.cc create mode 100644 src/lr-wpan/examples/wscript create mode 100644 src/lr-wpan/helper/lr-wpan-helper.cc create mode 100644 src/lr-wpan/helper/lr-wpan-helper.h create mode 100644 src/lr-wpan/model/lr-wpan-csmaca.cc create mode 100644 src/lr-wpan/model/lr-wpan-csmaca.h create mode 100644 src/lr-wpan/model/lr-wpan-error-rate-model.cc create mode 100644 src/lr-wpan/model/lr-wpan-error-rate-model.h create mode 100644 src/lr-wpan/model/lr-wpan-mac-header.cc create mode 100644 src/lr-wpan/model/lr-wpan-mac-header.h create mode 100644 src/lr-wpan/model/lr-wpan-mac-trailer.cc create mode 100644 src/lr-wpan/model/lr-wpan-mac-trailer.h create mode 100644 src/lr-wpan/model/lr-wpan-mac.cc create mode 100644 src/lr-wpan/model/lr-wpan-mac.h create mode 100644 src/lr-wpan/model/lr-wpan-phy.cc create mode 100644 src/lr-wpan/model/lr-wpan-phy.h create mode 100644 src/lr-wpan/model/lr-wpan-spectrum-value-helper.cc create mode 100644 src/lr-wpan/model/lr-wpan-spectrum-value-helper.h create mode 100644 src/lr-wpan/model/wpan-address.cc create mode 100644 src/lr-wpan/model/wpan-address.h create mode 100644 src/lr-wpan/model/wpan-spectrum-propagation-loss-model.cc create mode 100644 src/lr-wpan/model/wpan-spectrum-propagation-loss-model.h create mode 100644 src/lr-wpan/test/lr-wpan-packet-test.cc create mode 100644 src/lr-wpan/test/lr-wpan-pd-plme-sap-test.cc create mode 100644 src/lr-wpan/wscript diff --git a/src/lr-wpan/doc/lr-wpan.rst b/src/lr-wpan/doc/lr-wpan.rst new file mode 100644 index 000000000..0846efc26 --- /dev/null +++ b/src/lr-wpan/doc/lr-wpan.rst @@ -0,0 +1,176 @@ +PageBreak + +Low-Rate Wireless Personal Area Network (LR-WPAN) +------------------------------------------------- + +This chapter describes the implementation of ns-3 models for the +low-rate, wireless personal area network (LR-WPAN) as specified by +IEEE standard 802.15.4 (2006). + +Model Description +***************** + +The source code for the lr-wpan module lives in the directory ``src/lr-wpan``. + +Design +====== + +The model design closely follows the standard from an architectural standpoint. + +.. _fig-lr-wpan-arch: + +.. figure:: figures/lr-wpan-arch.* + + Architecture and scope of lr-wpan models + +The grey areas in the figure (adapted from Fig 3. of IEEE Std. 802.15.4-2006) +show the scope of the model. + +The Spectrum NetDevice from Nicola Baldo is the basis for the implementation. + +The implementation also borrows from the ns-2 models developed by Zheng +and Lee, and certain aspects of those models have been ported over. + +APIs +#### + +The APIs closely follow the standard, adapted for ns-3 naming conventions +and idioms. The APIs are organized around the concept of service primitives +as shown in the following figure adapted from Figure 14 of +IEEE Std. 802.15.4-2006. + +.. _fig-lr-wpan-arch: + +.. figure:: figures/lr-wpan-primitives.* + + Service primitives + +The APIs are organized around four conceptual services and service access +points (SAP): + +* MAC data service (MCPS) +* MAC management service (MLME) +* PHY data service (PD) +* PHY management service (PLME) + +In general, primitives are standardized as follows (e.g. Sec 7.1.1.1.1 +of IEEE 802.15.4-2006)::: + + MCPS-DATA.request ( + SrcAddrMode, + DstAddrMode, + DstPANId, + DstAddr, + msduLength, + msdu, + msduHandle, + TxOptions, + SecurityLevel, + KeyIdMode, + KeySource, + KeyIndex + ) + +This maps to ns-3 classes and methods such as::: + + struct McpsDataRequestParameters + { + uint8_t m_srcAddrMode; + uint8_t m_dstAddrMode; + ... + }; + + void + LrWpanMac::McpsDataRequest (McpsDataRequestParameters params) + { + ... + } + +MAC +### + +To be written. Focuses on unslotted CSMA/CA. + +PHY +### + +The physical layer components consist of a Phy model, an error rate model, +and a loss model. The error rate model presently models 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. The Phy model is +based on SpectrumPhy and it follows specification described in section 6 +of IEEE Std 802.15.4-2006. It models PHY service specifications, PPDU +formats, PHY constants and PIB attributes. It currently only supports +the transmit power spectral density mask specified in 2.4 GHz per section +6.5.3.1. The noise power density assumes uniformly distributed thermal +noise across the frequency bands. The loss model can fully utilize all +existing simple (non-spectrum phy) loss models. The Phy model uses +the existing single spectrum channel model. + +Scope and Limitations +===================== + +Future versions of this document will contain a PICS proforma similar to +Appendix D of IEEE 802.15.4-2006. The current emphasis is on the +unslotted mode of 802.15.4 operation for use in Zigbee, and the scope +is extremely limited, to the point of just getting some basic end-to-end +frames flowing. + +References +========== + +* Wireless Medium Access Control (MAC) and Physical Layer (PHY) +Specifications for Low-Rate Wireless Personal Area Networks (WPANs), +IEEE Computer Society, IEEE Std 802.15.4-2006, 8 September 2006. +* J. Zheng and Myung J. Lee, "A comprehensive performance study of IEEE +802.15.4," Sensor Network Operations, IEEE Press, Wiley Interscience, +Chapter 4, pp. 218-237, 2006. + +Usage +***** + +Enabling lr-wpan +================ + +Add ``lr-wpan`` to the list of modules built with ns-3. + +Helper +====== + +TBD, this is similar to other device helpers for ns-3. + +Examples +======== + +The following examples have been written, which can be found in ``src/lr-wpan/examples/``: + +* ``lr-wpan-data.cc``: A simple example showing end-to-end data transfer. +* ``lr-wpan-packet-print.cc``: An example to print out the MAC header fields. +* ``lr-wpan-phy-test.cc``: An example to test the phy. + +In particular, the module enables a very simplified end-to-end data +transfer scenario, implemented in ``lr-wpan-data.cc``. The figure +shows a sequence of events that are triggered when the MAC receives +a DataRequest from the higher layer. It invokes a Clear Channel +Assessment (CCA) from the PHY, and if successful, sends the frame +down to the PHY where it is transmitted over the channel and results +in a DataIndication on the peer node. + +.. _fig-lr-wpan-data: + +.. figure:: figures/lr-wpan-data-example.* + + Data example for simple LR-WPAN data transfer end-to-end + +Tests +===== + +The following tests have been written, which can be found in ``src/lr-wpan/tests/``: + +* ``lr-wpan-packet-test.cc``: Test the 802.15.4 MAC header/trailer classes +* ``lr-wpan-pd-plme-sap-test.cc``: Test the PLME and PD SAP per IEEE 802.15.4 + +Validation +********** + +This model has been tested as follows (*to be completed*). diff --git a/src/lr-wpan/examples/lr-wpan-data.cc b/src/lr-wpan/examples/lr-wpan-data.cc new file mode 100644 index 000000000..7cd81b548 --- /dev/null +++ b/src/lr-wpan/examples/lr-wpan-data.cc @@ -0,0 +1,131 @@ +/* -*- 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 + * + */ + +/* + * Try to send data end-to-end through a LrWpanMac <-> LrWpanPhy <-> + * SpectrumChannel <-> LrWpanPhy <-> LrWpanMac chain + */ + +#include "ns3/core-module.h" +#include "ns3/lr-wpan-module.h" +#include "ns3/simulator.h" +#include +#include + +#include + +using namespace ns3; + +static void DataIndication (Ptr p) +{ + NS_LOG_UNCOND ("Received packet of size " << p->GetSize ()); +} + +static void DataConfirm (LrWpanMcpsDataConfirmStatus status) +{ + NS_LOG_UNCOND ("LrWpanMcpsDataConfirmStatus = " << status); +} + +int main (int argc, char *argv[]) +{ + LrWpanHelper lrWpanHelper; + lrWpanHelper.EnableLogComponents (); + + Ptr mac0 = CreateObject (); + Ptr mac1 = CreateObject (); + Ptr phy0 = CreateObject (); + Ptr phy1 = CreateObject (); + + phy0->SetPdDataIndicationCallback (MakeCallback (&LrWpanMac::PdDataIndication, mac0)); + phy0->SetPdDataConfirmCallback (MakeCallback (&LrWpanMac::PdDataConfirm, mac0)); + phy0->SetPlmeEdConfirmCallback (MakeCallback (&LrWpanMac::PlmeEdConfirm, mac0)); + phy0->SetPlmeGetAttributeConfirmCallback (MakeCallback (&LrWpanMac::PlmeGetAttributeConfirm, mac0)); + phy0->SetPlmeSetTRXStateConfirmCallback (MakeCallback (&LrWpanMac::PlmeSetTRXStateConfirm, mac0)); + phy0->SetPlmeSetAttributeConfirmCallback (MakeCallback (&LrWpanMac::PlmeSetAttributeConfirm, mac0)); + + phy1->SetPdDataIndicationCallback (MakeCallback (&LrWpanMac::PdDataIndication, mac1)); + phy1->SetPdDataConfirmCallback (MakeCallback (&LrWpanMac::PdDataConfirm, mac1)); + phy1->SetPlmeEdConfirmCallback (MakeCallback (&LrWpanMac::PlmeEdConfirm, mac1)); + phy1->SetPlmeGetAttributeConfirmCallback (MakeCallback (&LrWpanMac::PlmeGetAttributeConfirm, mac1)); + phy1->SetPlmeSetTRXStateConfirmCallback (MakeCallback (&LrWpanMac::PlmeSetTRXStateConfirm, mac1)); + phy1->SetPlmeSetAttributeConfirmCallback (MakeCallback (&LrWpanMac::PlmeSetAttributeConfirm, mac1)); + + mac0->SetPhy (phy0); + mac1->SetPhy (phy1); + + Ptr csmaca0 = CreateObject (); + mac0->SetCsmaCa (csmaca0); + csmaca0->SetMac (mac0); + Ptr csmaca1 = CreateObject (); + mac1->SetCsmaCa (csmaca1); + csmaca1->SetMac (mac1); + + csmaca0->SetLrWpanMacStateCallback (MakeCallback (&LrWpanMac::SetLrWpanMacState, mac0)); + csmaca1->SetLrWpanMacStateCallback (MakeCallback (&LrWpanMac::SetLrWpanMacState, mac1)); + + phy0->SetPlmeCcaConfirmCallback (MakeCallback (&LrWpanCsmaCa::PlmeCcaConfirm, csmaca0)); + phy1->SetPlmeCcaConfirmCallback (MakeCallback (&LrWpanCsmaCa::PlmeCcaConfirm, csmaca1)); + + phy0->SetPdDataIndicationCallback (MakeCallback (&LrWpanMac::PdDataIndication, mac0)); + phy1->SetPdDataIndicationCallback (MakeCallback (&LrWpanMac::PdDataIndication, mac1)); + Ptr channel = CreateObject (); + + phy0->SetChannel (channel); + phy1->SetChannel (channel); + channel->AddRx (phy0); + channel->AddRx (phy1); + + // CONFIGURE MOBILITY + Ptr senderMobility = CreateObject (); + phy0->SetMobility (senderMobility); + Ptr receiverMobility = CreateObject (); + phy1->SetMobility (receiverMobility); + + McpsDataConfirmCallback cb0; + cb0 = MakeCallback (&DataConfirm); + mac0->SetMcpsDataConfirmCallback (cb0); + + McpsDataIndicationCallback cb1; + cb1 = MakeCallback (&DataIndication); + mac1->SetMcpsDataIndicationCallback (cb1); + + Ptr p = Create (20); // 20 bytes of dummy data + + // 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 + mac0->McpsDataRequest (p); + + Simulator::Run (); + + // Break reference cycles + phy0->Dispose (); + phy1->Dispose (); + mac0->Dispose (); + mac1->Dispose (); + // Clean up allocated memory + senderMobility = receiverMobility = 0; + channel = 0; + csmaca0 = csmaca1 = 0; + phy0 = phy1 = 0; + mac0 = mac1 = 0; + Simulator::Destroy (); + return 0; + +} diff --git a/src/lr-wpan/examples/lr-wpan-packet-print.cc b/src/lr-wpan/examples/lr-wpan-packet-print.cc new file mode 100644 index 000000000..94f813580 --- /dev/null +++ b/src/lr-wpan/examples/lr-wpan-packet-print.cc @@ -0,0 +1,60 @@ +/* -*- 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 + * + */ + +#include "ns3/core-module.h" +#include "ns3/lr-wpan-module.h" + +#include + +using namespace ns3; + +int main (int argc, char *argv[]) +{ + Packet::EnablePrinting (); + Packet::EnableChecking (); + LrWpanMacHeader macHdr (LrWpanMacHeader::LRWPAN_MAC_BEACON, 0); //sequence number set to 0 + macHdr.SetSrcAddrMode (2); // short addr + // ... other setters + + + uint16_t shortAddr = 66; + //uint64_t extAddr = 77; + uint16_t srcPanId = 100; + WpanAddress srcWpanAddr; + /*uint16_t dstPanId = 200; + WpanAddress dstWpanAddr;*/ + + srcWpanAddr.SetAddress (shortAddr); + //srcWpanAddr.SetAddress(extAddr); + macHdr.SetSrcAddrFields (srcPanId,srcWpanAddr ); + /*dstWpanAddr.SetAddress(extAddr); + macHdr.SetDstAddrFields(dstPanId,dstWpanAddr );*/ + + LrWpanMacTrailer macTrailer; + + Ptr p = Create (20); // 20 bytes of dummy data + + p->AddHeader (macHdr); + p->AddTrailer (macTrailer); + + p->Print (std::cout); + std::cout << std::endl; + return 0; + +} diff --git a/src/lr-wpan/examples/lr-wpan-phy-test.cc b/src/lr-wpan/examples/lr-wpan-phy-test.cc new file mode 100644 index 000000000..3b2056c14 --- /dev/null +++ b/src/lr-wpan/examples/lr-wpan-phy-test.cc @@ -0,0 +1,94 @@ +/* -*- 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 +#include +#include +#include +#include +#include +#include + +using namespace ns3; + +void GetSetTRXStateConfirm (LrWpanPhyEnumeration status) +{ + NS_LOG_UNCOND ("At: " << Simulator::Now () + << " Received Set TRX Confirm: " << status); +} + +void +ReceivePdDataIndication (uint32_t psduLength, + Ptr p, + uint32_t lqi) +{ + NS_LOG_UNCOND ("At: " << Simulator::Now () + << " Received frame size: " << psduLength << " LQI: " << + lqi); +} + +void SendOnePacket (Ptr sender, Ptr receiver) +{ + uint32_t n = 10; + Ptr p = Create (n); + sender->PdDataRequest (p->GetSize (), p); +} + + +int main (int argc, char *argv[]) +{ + LogComponentEnableAll (LOG_PREFIX_FUNC); + LogComponentEnable ("LrWpanPhy", LOG_LEVEL_ALL); + LogComponentEnable ("SingleModelSpectrumChannel", LOG_LEVEL_ALL); + + Ptr sender = CreateObject (); + Ptr receiver = CreateObject (); + + Ptr channel = CreateObject (); + sender->SetChannel (channel); + receiver->SetChannel (channel); + channel->AddRx (sender); + channel->AddRx (receiver); + + // CONFIGURE MOBILITY + Ptr senderMobility = CreateObject (); + sender->SetMobility (senderMobility); + Ptr receiverMobility = CreateObject (); + receiver->SetMobility (senderMobility); + + + sender->SetPlmeSetTRXStateConfirmCallback (MakeCallback (&GetSetTRXStateConfirm)); + receiver->SetPlmeSetTRXStateConfirmCallback (MakeCallback (&GetSetTRXStateConfirm)); + + sender->PlmeSetTRXStateRequest (IEEE_802_15_4_PHY_TX_ON); + receiver->PlmeSetTRXStateRequest (IEEE_802_15_4_PHY_RX_ON); + + receiver->SetPdDataIndicationCallback (MakeCallback (&ReceivePdDataIndication)); + + Simulator::Schedule (Seconds (1.0), &SendOnePacket, sender, receiver); + + Simulator::Stop (Seconds (10.0)); + + Simulator::Run (); + + Simulator::Destroy (); + + return 0; +} diff --git a/src/lr-wpan/examples/wscript b/src/lr-wpan/examples/wscript new file mode 100644 index 000000000..fe9e67e17 --- /dev/null +++ b/src/lr-wpan/examples/wscript @@ -0,0 +1,11 @@ +## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- + +def build(bld): + obj = bld.create_ns3_program('lr-wpan-packet-print', ['lr-wpan']) + obj.source = 'lr-wpan-packet-print.cc' + + obj = bld.create_ns3_program('lr-wpan-phy-test', ['lr-wpan']) + obj.source = 'lr-wpan-phy-test.cc' + + obj = bld.create_ns3_program('lr-wpan-data', ['lr-wpan']) + obj.source = 'lr-wpan-data.cc' diff --git a/src/lr-wpan/helper/lr-wpan-helper.cc b/src/lr-wpan/helper/lr-wpan-helper.cc new file mode 100644 index 000000000..539984d28 --- /dev/null +++ b/src/lr-wpan/helper/lr-wpan-helper.cc @@ -0,0 +1,92 @@ +/* -*- 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 "lr-wpan-helper.h" +#include "ns3/log.h" + +NS_LOG_COMPONENT_DEFINE ("LrWpanHelper"); + +namespace ns3 { + +LrWpanHelper::LrWpanHelper (void) +{ + m_channel = CreateObject (); + Ptr model = CreateObject (); + m_channel->AddSpectrumPropagationLossModel (model); +} + +LrWpanHelper::~LrWpanHelper (void) +{ + m_channel = 0; +} + +void +LrWpanHelper::AddMobility (Ptr phy, Ptr m) +{ + phy->SetMobility (m); +} + + +NetDeviceContainer +LrWpanHelper::Install (NodeContainer c) +{ + NetDeviceContainer devices; + for (NodeContainer::Iterator i = c.Begin (); i != c.End (); i++) + { + Ptr node = *i; + + Ptr mac = CreateObject (); + Ptr phy = CreateObject (); + Ptr csmaca = CreateObject (); + // Set MAC-PHY SAPs + phy->SetPdDataIndicationCallback (MakeCallback (&LrWpanMac::PdDataIndication, mac)); + phy->SetPdDataConfirmCallback (MakeCallback (&LrWpanMac::PdDataConfirm, mac)); + phy->SetPlmeEdConfirmCallback (MakeCallback (&LrWpanMac::PlmeEdConfirm, mac)); + phy->SetPlmeGetAttributeConfirmCallback (MakeCallback (&LrWpanMac::PlmeGetAttributeConfirm, mac)); + phy->SetPlmeSetTRXStateConfirmCallback (MakeCallback (&LrWpanMac::PlmeSetTRXStateConfirm, mac)); + phy->SetPlmeSetAttributeConfirmCallback (MakeCallback (&LrWpanMac::PlmeSetAttributeConfirm, mac)); + + mac->SetCsmaCa (csmaca); + csmaca->SetMac (mac); + csmaca->SetLrWpanMacStateCallback (MakeCallback (&LrWpanMac::SetLrWpanMacState, mac)); + phy->SetPlmeCcaConfirmCallback (MakeCallback (&LrWpanCsmaCa::PlmeCcaConfirm, csmaca)); + + // Set Channel + phy->SetChannel (m_channel); + m_channel->AddRx (phy); + } + return devices; +} + +void +LrWpanHelper::EnableLogComponents (void) +{ + LogComponentEnableAll (LOG_PREFIX_TIME); + LogComponentEnableAll (LOG_PREFIX_FUNC); + LogComponentEnable ("LrWpanCsmaCa", LOG_LEVEL_ALL); + LogComponentEnable ("LrWpanPhy", LOG_LEVEL_ALL); + LogComponentEnable ("LrWpanMac", LOG_LEVEL_ALL); + LogComponentEnable ("LrWpanErrorRateModel", LOG_LEVEL_ALL); +} + + +} // namespace ns3 + diff --git a/src/lr-wpan/helper/lr-wpan-helper.h b/src/lr-wpan/helper/lr-wpan-helper.h new file mode 100644 index 000000000..0468e3b38 --- /dev/null +++ b/src/lr-wpan/helper/lr-wpan-helper.h @@ -0,0 +1,76 @@ +/* -*- 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 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/lr-wpan-error-rate-model.h" +#include "ns3/wpan-spectrum-propagation-loss-model.h" +#include "ns3/single-model-spectrum-channel.h" + +namespace ns3 { + +/** + * \brief helps to manage and create ieee.15.4 NetDevice objects + * + * This class can help to create a ieee.15.4 NetDevice objects + * and to configure their attributes during creation. + */ + +class LrWpanHelper +{ +public: + /** + * \brief Create a LrWpan helper in an empty state. + */ + LrWpanHelper (void); + ~LrWpanHelper (void); + + /** + * \brief Add mobility model to a physical device + * \param phy the physical device + * \param m the mobility model + */ + void AddMobility (Ptr phy, Ptrm); + + /** + * \param c a set of nodes + * \param type device type to create + */ + NetDeviceContainer Install (NodeContainer c); + + /** + * Helper to enable all LrWpan log components with one statement + */ + void EnableLogComponents (void); + +private: + Ptr m_channel; + +}; + +} + +#endif /* LR_WPAN_HELPER_H */ diff --git a/src/lr-wpan/model/lr-wpan-csmaca.cc b/src/lr-wpan/model/lr-wpan-csmaca.cc new file mode 100644 index 000000000..260e49bd1 --- /dev/null +++ b/src/lr-wpan/model/lr-wpan-csmaca.cc @@ -0,0 +1,339 @@ +/* -*- 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/simulator.h" +#include "ns3/lr-wpan-csmaca.h" +#include "ns3/log.h" + +NS_LOG_COMPONENT_DEFINE ("LrWpanCsmaCa"); + +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) +{ + static TypeId tid = TypeId ("ns3::LrWpanCsmaCa") + .SetParent () + .AddConstructor () + ; + return tid; +} + +LrWpanCsmaCa::LrWpanCsmaCa () +{ + // TODO-- make these into ns-3 attributes + + m_isSlotted = false; + m_macMinBE = 3; + m_macMaxBE = 5; + m_macMaxCSMABackoffs = 4; + m_aUnitBackoffPeriod = 20; //20 symbols +} + +LrWpanCsmaCa::~LrWpanCsmaCa () +{ + m_mac = 0; +} + +void +LrWpanCsmaCa::SetMac (Ptr mac) +{ + m_mac = mac; +} + +Ptr +LrWpanCsmaCa::GetMac (void) const +{ + return m_mac; +} + +void +LrWpanCsmaCa::setSlottedCsmaCa (void) +{ + NS_LOG_FUNCTION (this); + m_isSlotted = true; +} + +void +LrWpanCsmaCa::setUnSlottedCsmaCa (void) +{ + NS_LOG_FUNCTION (this); + m_isSlotted = false; +} + +bool +LrWpanCsmaCa::isSlottedCsmaCa (void) const +{ + NS_LOG_FUNCTION (this); + return (m_isSlotted); +} + +bool +LrWpanCsmaCa::isUnSlottedCsmaCa (void) const +{ + NS_LOG_FUNCTION (this); + return (!m_isSlotted); +} + +void +LrWpanCsmaCa::setMacMinBE (uint8_t macMinBE) +{ + NS_LOG_FUNCTION (this << macMinBE); + m_macMinBE = macMinBE; +} + +uint8_t +LrWpanCsmaCa::getMacMinBE (void) const +{ + NS_LOG_FUNCTION (this); + return m_macMinBE; +} + +void +LrWpanCsmaCa::setMacMaxBE (uint8_t macMaxBE) +{ + NS_LOG_FUNCTION (this << macMaxBE); + m_macMinBE = macMaxBE; +} + +uint8_t +LrWpanCsmaCa::getMacMaxBE (void) const +{ + NS_LOG_FUNCTION (this); + return m_macMaxBE; +} + +void +LrWpanCsmaCa::setmacMaxCSMABackoffs (uint8_t macMaxCSMABackoffs) +{ + NS_LOG_FUNCTION (this << macMaxCSMABackoffs); + m_macMaxCSMABackoffs = macMaxCSMABackoffs; +} + +uint8_t +LrWpanCsmaCa::getmacMaxCSMABackoffs (void) const +{ + NS_LOG_FUNCTION (this); + return m_macMaxCSMABackoffs; +} + +void +LrWpanCsmaCa::setUnitBackoffPeriod (uint64_t unitBackoffPeriod) +{ + NS_LOG_FUNCTION (this << unitBackoffPeriod); + m_aUnitBackoffPeriod = unitBackoffPeriod; +} + +uint64_t +LrWpanCsmaCa::getUnitBackoffPeriod (void) const +{ + NS_LOG_FUNCTION (this); + return m_aUnitBackoffPeriod; +} + +void +LrWpanCsmaCa::Start () + +{ + NS_LOG_FUNCTION (this); + uint8_t backoffBoundary = 0; + m_NB = 0; + if (isSlottedCsmaCa ()) + { + m_CW = 2; + if (m_BLE) + { + m_BE = MIN (2, m_macMinBE); + } + else + { + m_BE = m_macMinBE; + } + //TODO: for slotted, set backoffBoundary to next backoff period boundary + Simulator::Schedule (Seconds (backoffBoundary),&LrWpanCsmaCa::RandomBackoffDelay,this); + } + else + { + m_BE = m_macMinBE; + Simulator::ScheduleNow (&LrWpanCsmaCa::RandomBackoffDelay,this); + } + /* + * TODO: If using Backoff.cc (will need to modify Backoff::GetBackoffTime) + * Backoff.m_minSlots = 0; + * Backoff.m_ceiling = m_BE; + * Backoff.ResetBackoffTime(); //m_NB is same as m_numBackoffRetries in Backoff.h + * Backoff.m_maxRetries = macMaxCSMABackoffs; + * Backoff.m_slotTime = m_backoffPeriod; + */ +} + +void +LrWpanCsmaCa::Cancel () +{ +} + + +/* + * Delay for backoff period in the range 0 to 2^BE -1 units + * TODO: If using Backoff.cc (Backoff::GetBackoffTime) will need to be slightly modified + */ +void +LrWpanCsmaCa::RandomBackoffDelay () +{ + NS_LOG_FUNCTION (this); + + UniformVariable uniformVar; + uint64_t upperBound = (uint64_t) pow (2, m_BE) - 1; + uint64_t backoffPeriod; + Time randomBackoff; + uint64_t symbolRate; + bool isData = false; + + + symbolRate = (uint64_t) m_mac->GetPhy ()->GetDataOrSymbolRate (isData); //symbols per second + uniformVar = UniformVariable (0, upperBound); + backoffPeriod = (uint64_t)uniformVar.GetValue (); //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); + } + else + { + NS_LOG_LOGIC ("Slotted: proceeding after backoff of " << randomBackoff.GetMicroSeconds () << " us"); + Simulator::Schedule (randomBackoff,&LrWpanCsmaCa::CanProceed,this); + } +} + +// TODO : Determine if transmission can be completed before end of CAP for the slotted csmaca +// If not delay to the next CAP +void +LrWpanCsmaCa::CanProceed () +{ + NS_LOG_FUNCTION (this); + uint8_t backoffBoundary = 0; + uint8_t nextCap = 0; + bool canProceed = true; + + if (m_BLE) + { + } + else + { + } + + if (canProceed) + { + // TODO: Perform CCA on the backoff boundary for the slotted CSCMA-CA + Simulator::Schedule (Seconds (backoffBoundary),&LrWpanCsmaCa::RequestCCA,this); + } + else + { + Simulator::Schedule (Seconds (nextCap),&LrWpanCsmaCa::RandomBackoffDelay,this); + } +} + +void +LrWpanCsmaCa::RequestCCA () +{ + NS_LOG_FUNCTION (this); + m_mac->GetPhy ()->PlmeCcaRequest (); +} + +/* + * This function is called when the phy calls back after completing a PlmeCcaRequest + */ +void +LrWpanCsmaCa::PlmeCcaConfirm (LrWpanPhyEnumeration status) +{ + NS_LOG_FUNCTION (this << status); + + if (status == IEEE_802_15_4_PHY_IDLE) + { + if (isSlottedCsmaCa ()) + { + 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); + 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"); + m_mac->m_mcpsDataConfirmCallback (IEEE_802_15_4_CHANNEL_ACCESS_FAILURE); + } + else + { + NS_LOG_DEBUG ("Perform another backoff; m_NB = " << m_NB); + Simulator::ScheduleNow (&LrWpanCsmaCa::RandomBackoffDelay,this); //Perform another backoff (step 2) + } + } +} + +void +LrWpanCsmaCa::SetLrWpanMacStateCallback (LrWpanMacStateCallback c) +{ + NS_LOG_FUNCTION (this); + m_lrWpanMacStateCallback = c; +} + +} //namespace ns3 diff --git a/src/lr-wpan/model/lr-wpan-csmaca.h b/src/lr-wpan/model/lr-wpan-csmaca.h new file mode 100644 index 000000000..a34076205 --- /dev/null +++ b/src/lr-wpan/model/lr-wpan-csmaca.h @@ -0,0 +1,139 @@ +/* -*- 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 LRWPANCSMACA_H +#define LRWPANCSMACA_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" + +namespace ns3 { + +/* This method informs MAC that channel is idle or busy */ +typedef Callback< void, LrWpanMacState> LrWpanMacStateCallback; + +/** + * This class is a helper for the LrWpanMac to manage the Csma/CA + * state machine. + */ +class LrWpanCsmaCa : public Object +{ + +public: + static TypeId GetTypeId (); + + LrWpanCsmaCa (); + ~LrWpanCsmaCa (); + + void SetMac (Ptr mac); + Ptr GetMac (void) const; + void setSlottedCsmaCa (void); + void setUnSlottedCsmaCa (void); + bool isSlottedCsmaCa (void) const; + bool isUnSlottedCsmaCa (void) const; + + void setMacMinBE (uint8_t macMinBE); + uint8_t getMacMinBE (void) const; + void setMacMaxBE (uint8_t macMaxBE); + uint8_t getMacMaxBE (void) const; + void setmacMaxCSMABackoffs (uint8_t macMaxCSMABackoffs); + uint8_t getmacMaxCSMABackoffs (void) const; + + void setUnitBackoffPeriod (uint64_t unitBackoffPeriod); + uint64_t getUnitBackoffPeriod (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 + */ + void Cancel (); + + /* + * In step 2 of the CSMA-CA, perform a random backoff in the range of 0 to 2^BE -1 + */ + void RandomBackoffDelay (); + + /* + * 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. + */ + void CanProceed (); + + /* + * Request the Phy to perform CCA (Step 3) + * + */ + void RequestCCA (); + + /** + * IEEE 802.15.4-2006 section 6.2.2.2 + * PLME-CCA.confirm status + * @param status TRX_OFF, BUSY or IDLE + * + * When Phy has completed CCA, it calls back here which in turn execute the final steps + * of the CSMA-CA algorithm. + * It checks to see if the Channel is idle, if so check the Contention window before + * permitting transmission (step 5). If channel is busy, either backoff and perform CCA again or + * treat as channel access failure (step 4). + */ + 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 + */ + void SetLrWpanMacStateCallback (LrWpanMacStateCallback macState); + +private: + LrWpanMacStateCallback m_lrWpanMacStateCallback; + bool m_isSlotted; // beacon-enabled slotted or nonbeacon-enabled unslotted CSMA-CA + // beacon order == 15 means nonbeacon-enabled + + 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 + uint8_t m_macMinBE; //0-macMaxBE default 3 + uint8_t m_macMaxBE; //3-8 default 5 + uint8_t m_macMaxCSMABackoffs; //0-5 default 4 + bool m_BLE; //Battery Life Extension + + uint64_t m_aUnitBackoffPeriod; // 20 symbols in each backoff periods +}; + +} + +// namespace ns-3 + +#endif /* LRWPANCSMACA_H */ diff --git a/src/lr-wpan/model/lr-wpan-error-rate-model.cc b/src/lr-wpan/model/lr-wpan-error-rate-model.cc new file mode 100644 index 000000000..b5dae66e6 --- /dev/null +++ b/src/lr-wpan/model/lr-wpan-error-rate-model.cc @@ -0,0 +1,79 @@ +/* -*- 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 new file mode 100644 index 000000000..84463e5df --- /dev/null +++ b/src/lr-wpan/model/lr-wpan-error-rate-model.h @@ -0,0 +1,51 @@ +/* -*- 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-mac-header.cc b/src/lr-wpan/model/lr-wpan-mac-header.cc new file mode 100644 index 000000000..1b74f85c3 --- /dev/null +++ b/src/lr-wpan/model/lr-wpan-mac-header.cc @@ -0,0 +1,824 @@ +/* -*- 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/lr-wpan-mac-header.h" +#include "ns3/wpan-address.h" + + + + +namespace ns3 { + +NS_OBJECT_ENSURE_REGISTERED (LrWpanMacHeader); + +// TODO: Test Compressed PAN Id, Security Enabled, different size Key + + + +LrWpanMacHeader::LrWpanMacHeader () +{ + SetType (LRWPAN_MAC_DATA); // Assume Data frame + SetSecDisable (); // Assume there is No Aux Sec but + SetNoFrmPend (); // No Frame Pending + SetNoAckReq (); // No Ack Frame will be expected from recepient + SetNoPanIdComp (); // No PAN Id Compression since no addresses + SetFrmCtrlRes (0); // Initialize the 3 reserved bits to 0 + SetDstAddrMode (NOADDR); // Assume there will be no src and dst address + SetSrcAddrMode (NOADDR); + SetFrameVer (1); //Indicates an IEEE 802.15.4 frame +} + + +LrWpanMacHeader::LrWpanMacHeader (enum LrWpanMacType wpanMacType, + uint8_t seqNum) +{ + SetType (wpanMacType); + SetSeqNum (seqNum); + SetSecDisable (); // Assume there is No Aux Sec but + SetNoFrmPend (); // No Frame Pending + SetNoAckReq (); // No Ack Frame will be expected from recepient + SetNoPanIdComp (); // No PAN Id Compression since no addresses + SetFrmCtrlRes (0); // Initialize the 3 reserved bits to 0 + SetDstAddrMode (NOADDR); // Assume there will be no src and dst address + SetSrcAddrMode (NOADDR); + SetFrameVer (1); //Indicates an IEEE 802.15.4 frame +} + + +LrWpanMacHeader::~LrWpanMacHeader () +{ +} + + +enum LrWpanMacHeader::LrWpanMacType +LrWpanMacHeader::GetType (void) const +{ + switch (m_fctrlFrmType) + { + case 0: + return LRWPAN_MAC_BEACON; + break; + case 1: + return LRWPAN_MAC_DATA; + break; + case 2: + return LRWPAN_MAC_ACKNOWLEDGMENT; + break; + case 3: + return LRWPAN_MAC_COMMAND; + break; + default: + return LRWPAN_MAC_ERROR; + } +} + + + +uint16_t +LrWpanMacHeader::GetFrameControl (void) const +{ + uint16_t val = 0; + + val = m_fctrlFrmType & (0x07); // Bit 0-2 + val |= (m_fctrlSecU << 3) & (0x01 << 3); // Bit 3 + val |= (m_fctrlFrmPending << 4) & (0x01 << 4); // Bit 4 + val |= (m_fctrlAckReq << 5) & (0x01 << 5); // Bit 5 + val |= (m_fctrlPanIdComp << 6) & (0x01 << 6); // Bit 6 + val |= (m_fctrlReserved << 7) & (0x07 << 7); // Bit 7-9 + val |= (m_fctrlDstAddrMode << 10) & (0x03 << 10); // Bit 10-11 + val |= (m_fctrlFrmVer << 12) & (0x03 << 12); // Bit 12-13 + val |= (m_fctrlSrcAddrMode << 14) & (0x03 << 14); // Bit 14-15 + return val; + +} + +bool +LrWpanMacHeader::IsSecEnable (void) const +{ + return (m_fctrlSecU == 1); +} + +bool +LrWpanMacHeader::IsSecDisable (void) const +{ + return (m_fctrlSecU == 0); +} + +bool +LrWpanMacHeader::IsFrmPend (void) const +{ + return (m_fctrlFrmPending == 1); +} + +bool +LrWpanMacHeader::IsNoFrmPend (void) const +{ + return (m_fctrlFrmPending == 0); +} + +bool +LrWpanMacHeader::IsAckReq (void) const +{ + return (m_fctrlAckReq == 1); +} + +bool +LrWpanMacHeader::IsNoAckReq (void) const +{ + return (m_fctrlAckReq == 0); +} + +bool +LrWpanMacHeader::IsPanIdComp (void) const +{ + return (m_fctrlPanIdComp == 1); +} + +bool +LrWpanMacHeader::IsNoPanIdComp (void) const +{ + return (m_fctrlPanIdComp == 0); +} + +uint8_t +LrWpanMacHeader::GetFrmCtrlRes (void) const +{ + return (m_fctrlReserved); +} + +uint8_t +LrWpanMacHeader::GetDstAddrMode (void) const +{ + return m_fctrlDstAddrMode; +} + +uint8_t +LrWpanMacHeader::GetFrameVer (void) const +{ + return m_fctrlFrmVer; +} + +uint8_t +LrWpanMacHeader::GetSrcAddrMode (void) const +{ + return m_fctrlSrcAddrMode; +} + + +uint8_t +LrWpanMacHeader::GetSeqNum (void) const +{ + return(m_SeqNum); +} + + +uint16_t +LrWpanMacHeader::GetDstPanId (void) const +{ + return(m_addrDstPanId); +} + + +WpanAddress +LrWpanMacHeader::GetDstAddr (void) const +{ + return(m_addrDstAddr); +} + + +uint16_t +LrWpanMacHeader::GetSrcPanId (void) const +{ + return(m_addrSrcPanId); +} + + +WpanAddress +LrWpanMacHeader::GetSrcAddr (void) const +{ + return(m_addrSrcAddr); +} + +uint8_t +LrWpanMacHeader::GetSecControl (void) const +{ + uint8_t val = 0; + + val = m_secctrlSecLevel & (0x7); // Bit 0-2 + val |= (m_secctrlKeyIdMode << 3) & (0x3 << 3); // Bit 3-4 + val |= (m_secctrlReserved << 5) & (0x7 << 5); // Bit 5-7 + + return(val); +} + +uint32_t +LrWpanMacHeader::GetFrmCounter (void) const +{ + return(m_auxFrmCntr); +} + +uint8_t +LrWpanMacHeader::GetSecLevel (void) const +{ + return (m_secctrlSecLevel); +} + +uint8_t +LrWpanMacHeader::GetKeyIdMode (void) const +{ + return(m_secctrlKeyIdMode); +} + +uint8_t +LrWpanMacHeader::GetsecctrlReserved (void) const +{ + return (m_secctrlReserved); +} + +uint32_t +LrWpanMacHeader::GetKeyIdSrc32 (void) const +{ + return(m_auxKeyIdKeySrc32); +} + +uint64_t +LrWpanMacHeader::GetKeyIdSrc64 (void) const +{ + + return(m_auxKeyIdKeySrc64); +} + +uint8_t +LrWpanMacHeader::GetKeyIdIndex (void) const +{ + return(m_auxKeyIdKeyIndex); +} + + +bool +LrWpanMacHeader::IsBeacon (void) const +{ + return(m_fctrlFrmType == LRWPAN_MAC_BEACON); +} + + + +bool +LrWpanMacHeader::IsData (void) const +{ + return(m_fctrlFrmType == LRWPAN_MAC_DATA); +} + + + +bool +LrWpanMacHeader::IsAcknowledgment (void) const +{ + return(m_fctrlFrmType == LRWPAN_MAC_ACKNOWLEDGMENT); +} + + + +bool +LrWpanMacHeader::IsCommand (void) const +{ + return(m_fctrlFrmType == LRWPAN_MAC_COMMAND); +} + + + +void +LrWpanMacHeader::SetType (enum LrWpanMacType wpanMacType) +{ + m_fctrlFrmType = wpanMacType; +} + + +void +LrWpanMacHeader::SetFrameControl (uint16_t frameControl) +{ + m_fctrlFrmType = (frameControl) & (0x07); // Bit 0-2 + m_fctrlSecU = (frameControl >> 3) & (0x01); // Bit 3 + m_fctrlFrmPending = (frameControl >> 4) & (0x01); // Bit 4 + m_fctrlAckReq = (frameControl >> 5) & (0x01); // Bit 5 + m_fctrlPanIdComp = (frameControl >> 6) & (0x01); // Bit 6 + m_fctrlReserved = (frameControl >> 7) & (0x07); // Bit 7-9 + m_fctrlDstAddrMode = (frameControl >> 10) & (0x03); // Bit 10-11 + m_fctrlFrmVer = (frameControl >> 12) & (0x03); // Bit 12-13 + m_fctrlSrcAddrMode = (frameControl >> 14) & (0x03); // Bit 14-15 +} + + +void +LrWpanMacHeader::SetSecEnable (void) +{ + m_fctrlSecU = 1; +} + + +void +LrWpanMacHeader::SetSecDisable (void) +{ + m_fctrlSecU = 0; +} + + +void +LrWpanMacHeader::SetFrmPend (void) +{ + m_fctrlFrmPending = 1; +} + + +void +LrWpanMacHeader::SetNoFrmPend (void) +{ + m_fctrlFrmPending = 0; +} + + +void +LrWpanMacHeader::SetAckReq (void) +{ + m_fctrlAckReq = 1; +} + + +void +LrWpanMacHeader::SetNoAckReq (void) +{ + m_fctrlAckReq = 0; +} + + +void +LrWpanMacHeader::SetPanIdComp (void) +{ + m_fctrlPanIdComp = 1; +} + + +void LrWpanMacHeader::SetNoPanIdComp (void) +{ + m_fctrlPanIdComp = 0; +} + +void +LrWpanMacHeader::SetFrmCtrlRes (uint8_t res) +{ + m_fctrlReserved = res; +} + +void +LrWpanMacHeader::SetDstAddrMode (uint8_t addrMode) +{ + m_fctrlDstAddrMode = addrMode; +} + + +void +LrWpanMacHeader::SetFrameVer (uint8_t ver) +{ + m_fctrlFrmVer = ver; +} + + +void +LrWpanMacHeader::SetSrcAddrMode (uint8_t addrMode) +{ + m_fctrlSrcAddrMode = addrMode; +} + + +void +LrWpanMacHeader::SetSeqNum (uint8_t seqNum) +{ + m_SeqNum = seqNum; +} + + +void +LrWpanMacHeader::SetSrcAddrFields (uint16_t panId, + WpanAddress addr) +{ + m_addrSrcPanId = panId; + m_addrSrcAddr = addr; +} + + +void +LrWpanMacHeader::SetDstAddrFields (uint16_t panId, + WpanAddress addr) +{ + m_addrDstPanId = panId; + m_addrDstAddr = addr; +} + + +void +LrWpanMacHeader::SetSecControl (uint8_t secControl) +{ + m_secctrlSecLevel = (secControl) & (0x07); // Bit 0-2 + m_secctrlKeyIdMode = (secControl >> 3) & (0x03); // Bit 3-4 + m_secctrlReserved = (secControl >> 5) & (0x07); // Bit 5-7 +} + +void +LrWpanMacHeader::SetFrmCounter (uint32_t frmCntr) +{ + m_auxFrmCntr = frmCntr; +} + +void +LrWpanMacHeader::SetSecLevel (uint8_t secLevel) +{ + m_secctrlSecLevel = secLevel; +} + +void +LrWpanMacHeader::SetKeyIdMode (uint8_t keyIdMode) +{ + m_secctrlKeyIdMode = keyIdMode; +} + +void +LrWpanMacHeader::SetsecctrlReserved (uint8_t res) +{ + m_secctrlReserved = res; +} + +void +LrWpanMacHeader::SetKeyId (uint8_t keyIndex) +{ + m_auxKeyIdKeyIndex = keyIndex; +} + + +void +LrWpanMacHeader::SetKeyId (uint32_t keySrc, + uint8_t keyIndex) +{ + m_auxKeyIdKeyIndex = keyIndex; + m_auxKeyIdKeySrc32 = keySrc; +} + + +void +LrWpanMacHeader::SetKeyId (uint64_t keySrc, + uint8_t keyIndex) +{ + m_auxKeyIdKeyIndex = keyIndex; + m_auxKeyIdKeySrc64 = keySrc; +} + + +std::string +LrWpanMacHeader::GetName (void) const +{ + return "LrWpan MAC Header"; +} + +TypeId +LrWpanMacHeader::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::LrWpanMacHeader") + .SetParent
() + .AddConstructor (); + return tid; +} + + +TypeId +LrWpanMacHeader::GetInstanceTypeId (void) const +{ + return GetTypeId (); +} + +void +LrWpanMacHeader::PrintFrameControl (std::ostream &os) const +{ + os << " Frame Type = " << (uint32_t) m_fctrlFrmType << ", Sec Enable = " << (uint32_t) m_fctrlSecU + << ", Frame Pending = " << (uint32_t) m_fctrlFrmPending << ", Ack Request = " << (uint32_t) m_fctrlAckReq + << ", PAN ID Compress = " << (uint32_t) m_fctrlPanIdComp << ", Frame Vers = " << (uint32_t) m_fctrlFrmVer + << ", Dst Addrs Mode = " << (uint32_t) m_fctrlDstAddrMode << ", Src Addr Mode = " << (uint32_t) m_fctrlSrcAddrMode; +} + +void +LrWpanMacHeader::Print (std::ostream &os) const +{ + + PrintFrameControl (os); + os << ", Sequence Num = " << (uint32_t) m_SeqNum; + + switch (m_fctrlDstAddrMode) + { + case NOADDR: + break; + case SHORTADDR: + os << ", Dst Addr Pan ID = " << (uint32_t) m_addrDstPanId + << ", m_addrSrcAddr = " << (uint32_t) m_addrDstAddr.GetShortAddress (); + break; + case EXTADDR: + os << ", Dst Addr Pan ID = " << (uint32_t) m_addrDstPanId + << ", m_addrDstAddr = " << (uint64_t) m_addrDstAddr.GetExtAddress (); + break; + } + + switch (m_fctrlSrcAddrMode) + { + case NOADDR: + break; + case SHORTADDR: + os << ", Src Addr Pan ID = " << (uint32_t) m_addrSrcPanId + << ", m_addrSrcAddr = " << (uint32_t) m_addrSrcAddr.GetShortAddress (); + break; + case EXTADDR: + os << ", Src Addr Pan ID = " << (uint32_t) m_addrSrcPanId + << ", m_addrSrcAddr = " << (uint64_t) m_addrSrcAddr.GetExtAddress (); + break; + } + + if (IsSecEnable ()) + { + os << " Security Level = " << (uint32_t) m_secctrlSecLevel + << ", Key Id Mode = " << (uint32_t) m_secctrlKeyIdMode + << ", Frame Counter = " << (uint32_t) m_auxFrmCntr; + + switch (m_secctrlKeyIdMode) + { + case IMPLICIT: + break; + case NOKEYSOURCE: + os << ", Key Id - Key Index = " << (uint32_t) m_auxKeyIdKeyIndex; + break; + case SHORTKEYSOURCE: + os << ", Key Id - Key Source 32 =" << (uint32_t) m_auxKeyIdKeySrc32 + << ", Key Id - Key Index = " << (uint32_t) m_auxKeyIdKeyIndex; + break; + case LONGKEYSOURCE: + os << ", Key Id - Key Source 64 =" << (uint64_t) m_auxKeyIdKeySrc64 + << ", Key Id - Key Index = " << (uint32_t) m_auxKeyIdKeyIndex; + break; + } + } +} + +uint32_t +LrWpanMacHeader::GetSerializedSize (void) const +{ + /* + * Each mac header will have + * Frame Control : 2 octet + * Sequence Number : 1 Octet + * Dst PAN Id : 0/2 Octet + * Dst Address : 0/2/8 octet + * Src PAN Id : 0/2 octet + * Src Address : 0/2/8 octet + * Aux Sec Header : 0/5/6/10/14 octet + */ + + uint32_t size = 3; + + switch (m_fctrlDstAddrMode) + { + case NOADDR: + break; + case SHORTADDR: + size += 4; + break; + case EXTADDR: + size += 10; + break; + } + + switch (m_fctrlSrcAddrMode) + { + case NOADDR: + break; + case SHORTADDR: + // check if PAN Id compression is enabled + if (IsNoPanIdComp ()) + { + size += 4; + } + else + { + size += 2; + } + break; + case EXTADDR: + // check if PAN Id compression is enabled + if (IsNoPanIdComp ()) + { + size += 10; + } + else + { + size += 8; + } + break; + } + + + // check if security is enabled + if (IsSecEnable ()) + { + size += 5; + switch (m_secctrlKeyIdMode) + { + case IMPLICIT: + break; + case NOKEYSOURCE: + size += 1; + break; + case SHORTKEYSOURCE: + size += 5; + break; + case LONGKEYSOURCE: + size += 9; + break; + } + } + return (size); +} + + +void +LrWpanMacHeader::Serialize (Buffer::Iterator start) const +{ + Buffer::Iterator i = start; + uint16_t frameControl = GetFrameControl (); + + i.WriteHtolsbU16 (frameControl); + i.WriteU8 (GetSeqNum ()); + + switch (m_fctrlDstAddrMode) + { + case NOADDR: + break; + case SHORTADDR: + i.WriteHtolsbU16 (GetDstPanId ()); + i.WriteHtolsbU16 (m_addrDstAddr.GetShortAddress ()); + break; + case EXTADDR: + i.WriteHtolsbU16 (GetDstPanId ()); + i.WriteHtolsbU64 (m_addrDstAddr.GetExtAddress ()); + break; + } + + switch (m_fctrlSrcAddrMode) + { + case NOADDR: + break; + case SHORTADDR: + if (IsNoPanIdComp ()) + { + i.WriteHtolsbU16 (GetSrcPanId ()); + } + i.WriteHtolsbU16 (m_addrSrcAddr.GetShortAddress ()); + break; + case EXTADDR: + if (IsNoPanIdComp ()) + { + i.WriteHtolsbU16 (GetSrcPanId ()); + } + i.WriteHtolsbU64 (m_addrSrcAddr.GetExtAddress ()); + break; + } + + if (IsSecEnable ()) + { + i.WriteU8 (GetSecControl ()); + i.WriteHtolsbU32 (GetFrmCounter ()); + + switch (m_secctrlKeyIdMode) + { + case IMPLICIT: + break; + case NOKEYSOURCE: + i.WriteU8 (GetKeyIdIndex ()); + break; + case SHORTKEYSOURCE: + i.WriteHtolsbU32 (GetKeyIdSrc32 ()); + i.WriteU8 (GetKeyIdIndex ()); + break; + case LONGKEYSOURCE: + i.WriteHtolsbU64 (GetKeyIdSrc64 ()); + i.WriteU8 (GetKeyIdIndex ()); + break; + } + } +} + + +uint32_t +LrWpanMacHeader::Deserialize (Buffer::Iterator start) +{ + uint16_t addr16; + uint64_t addr64; + + Buffer::Iterator i = start; + uint16_t frameControl = i.ReadLsbtohU16 (); + SetFrameControl (frameControl); + + SetSeqNum (i.ReadU8 ()); + switch (m_fctrlDstAddrMode) + { + case NOADDR: + break; + case SHORTADDR: + m_addrDstPanId = i.ReadLsbtohU16 (); + addr16 = i.ReadLsbtohU16 (); + m_addrDstAddr.SetAddress (addr16); + break; + case EXTADDR: + m_addrDstPanId = i.ReadLsbtohU16 (); + addr64 = i.ReadLsbtohU64 (); + m_addrDstAddr.SetAddress (addr64); + break; + } + + switch (m_fctrlSrcAddrMode) + { + case NOADDR: + break; + case SHORTADDR: + if (IsNoPanIdComp ()) + { + m_addrSrcPanId = i.ReadLsbtohU16 (); + } + else + { + if (m_fctrlDstAddrMode > 0) + { + m_addrSrcPanId = m_addrDstPanId; + } + } + addr16 = i.ReadLsbtohU16 (); + m_addrSrcAddr.SetAddress (addr16); + break; + case EXTADDR: + if (IsNoPanIdComp ()) + { + m_addrSrcPanId = i.ReadLsbtohU16 (); + } + else + { + if (m_fctrlDstAddrMode > 0) + { + m_addrSrcPanId = m_addrDstPanId; + } + } + addr64 = i.ReadLsbtohU64 (); + m_addrSrcAddr.SetAddress (addr64); + break; + } + + if (IsSecEnable ()) + { + SetSecControl (i.ReadU8 ()); + SetFrmCounter (i.ReadLsbtohU32 ()); + + switch (m_secctrlKeyIdMode) + { + case IMPLICIT: + break; + case NOKEYSOURCE: + SetKeyId (i.ReadU8 ()); + break; + case SHORTKEYSOURCE: + SetKeyId (i.ReadLsbtohU32 (),i.ReadU8 ()); + break; + case LONGKEYSOURCE: + SetKeyId (i.ReadLsbtohU64 (),i.ReadU8 ()); + break; + } + } + return i.GetDistanceFrom (start); +} + +// ---------------------------------------------------------------------------------------------------------- + + +} //namespace ns3 + + diff --git a/src/lr-wpan/model/lr-wpan-mac-header.h b/src/lr-wpan/model/lr-wpan-mac-header.h new file mode 100644 index 000000000..a0a7be766 --- /dev/null +++ b/src/lr-wpan/model/lr-wpan-mac-header.h @@ -0,0 +1,231 @@ +/* -*- 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 + */ + +/** + * the following classes implements the 802.15.4 Mac Header + * There are 4 types of 802.15.4 Mac Headers Frames, and they have these fields + * + * Headers Frames : Fields + * ------------------------------------------------------------------------------------------- + * Beacon : Frame Control, Sequence Number, Address Fields+, Auxiliary Security Header++. + * Data : Frame Control, Sequence Number, Address Fields++, Auxiliary Security Header++. + * Acknowledgment : Frame Control, Sequence Number. + * Command : Frame Control, Sequence Number, Address Fields++, Auxiliary Security Header++. + * + * + - The Address fields in Beacon frame is made up of the Source PAN Id and address only and size + * is 4 or 8 octets whereas the other frames may contain the Destination PAN Id and address as + * well. (see specs). + * ++ - These fields are optional and of variable size + */ + +#ifndef LRWPAN_MAC_HEADER_H +#define LRWPAN_MAC_HEADER_H + +#include +#include "ns3/header.h" +#include "ns3/nstime.h" +#include "ns3/wpan-address.h" + + +namespace ns3 { + + +/* Represent the Mac Header with the Frame Control and Sequence Number fields */ + +class LrWpanMacHeader : public Header +{ + +public: + enum LrWpanMacType + { + LRWPAN_MAC_BEACON = 0, + LRWPAN_MAC_DATA = 1, + LRWPAN_MAC_ACKNOWLEDGMENT = 2, + LRWPAN_MAC_COMMAND = 3, + LRWPAN_MAC_ERROR + }; + + enum AddrModeType + { + NOADDR = 0, + RESADDR = 1, + SHORTADDR = 2, + EXTADDR = 3 + }; + + enum KeyIdModeType + { + IMPLICIT = 0, + NOKEYSOURCE = 1, + SHORTKEYSOURCE = 2, + LONGKEYSOURCE = 3 + }; + + LrWpanMacHeader (void); + + LrWpanMacHeader (enum LrWpanMacType wpanMacType, // Data, ACK, Control MAC Header must have + uint8_t seqNum); // frame control and sequence number. + // Beacon MAC Header must have frame control, + // sequence number, source PAN Id, source address. + + ~LrWpanMacHeader (void); + + + enum LrWpanMacType GetType (void) const; + uint16_t GetFrameControl (void) const; + bool IsSecEnable (void) const; + bool IsSecDisable (void) const; + bool IsFrmPend (void) const; + bool IsNoFrmPend (void) const; + bool IsAckReq (void) const; + bool IsNoAckReq (void) const; + bool IsPanIdComp (void) const; + bool IsNoPanIdComp (void) const; + uint8_t GetFrmCtrlRes (void) const; + uint8_t GetDstAddrMode (void) const; + uint8_t GetFrameVer (void) const; + uint8_t GetSrcAddrMode (void) const; + + uint8_t GetSeqNum (void) const; + + uint16_t GetDstPanId (void) const; + WpanAddress GetDstAddr (void) const; + uint16_t GetSrcPanId (void) const; + WpanAddress GetSrcAddr (void) const; + + uint8_t GetSecControl (void) const; + uint32_t GetFrmCounter (void) const; + + uint8_t GetSecLevel (void) const; + uint8_t GetKeyIdMode (void) const; + uint8_t GetsecctrlReserved (void) const; + + uint32_t GetKeyIdSrc32 (void) const; + uint64_t GetKeyIdSrc64 (void) const; + uint8_t GetKeyIdIndex (void) const; + + + bool IsBeacon (void) const; + bool IsData (void) const; + bool IsAcknowledgment (void) const; + bool IsCommand (void) const; + + + void SetType (enum LrWpanMacType wpanMacType); + void SetFrameControl (uint16_t frameControl); + void SetSecEnable (void); + void SetSecDisable (void); + void SetFrmPend (void); + void SetNoFrmPend (void); + void SetAckReq (void); + void SetNoAckReq (void); + void SetPanIdComp (void); + void SetNoPanIdComp (void); + void SetFrmCtrlRes (uint8_t res); + void SetDstAddrMode (uint8_t addrMode); + void SetFrameVer (uint8_t ver); + void SetSrcAddrMode (uint8_t addrMode); + + void SetSeqNum (uint8_t seqNum); + + /* The Source/Destination Addressing fields are only set if SrcAddrMode/DstAddrMode are set */ + void SetSrcAddrFields (uint16_t panId, + WpanAddress addr); + void SetDstAddrFields (uint16_t panId, + WpanAddress addr); + + /* Auxiliary Security Header is only set if Sec Enable (SecU) field is set to 1 */ + void SetSecControl (uint8_t secLevel); + void SetFrmCounter (uint32_t frmCntr); + + void SetSecLevel (uint8_t secLevel); + void SetKeyIdMode (uint8_t keyIdMode); + void SetsecctrlReserved (uint8_t res); + + /* Variable length will be dependent on Key Id Mode*/ + void SetKeyId (uint8_t keyIndex); + void SetKeyId (uint32_t keySrc, + uint8_t keyIndex); + void SetKeyId (uint64_t keySrc, + uint8_t keyIndex); + + + std::string GetName (void) const; + static TypeId GetTypeId (void); + virtual TypeId GetInstanceTypeId (void) const; + void PrintFrameControl (std::ostream &os) const; + void Print (std::ostream &os) const; + uint32_t GetSerializedSize (void) const; + void Serialize (Buffer::Iterator start) const; + uint32_t Deserialize (Buffer::Iterator start); + + +private: + /* Frame Control 2 Octets */ + /* Frame Control fields */ + uint8_t m_fctrlFrmType; // Bit 0-2 = 0 - Beacon, 1 - Data, 2 - Ack, 3 - Command + uint8_t m_fctrlSecU; // Bit 3 = 0 - no AuxSecHdr , 1 - security enabled AuxSecHdr present + uint8_t m_fctrlFrmPending; // Bit 4 + uint8_t m_fctrlAckReq; // Bit 5 + uint8_t m_fctrlPanIdComp; // Bit 6 = 0 - no compression, 1 - using only DstPanId for both Src and DstPanId + uint8_t m_fctrlReserved; // Bit 7-9 + uint8_t m_fctrlDstAddrMode; // Bit 10-11 = 0 - No DstAddr, 2 - ShtDstAddr, 3 - ExtDstAddr + uint8_t m_fctrlFrmVer; // Bit 12-13 + uint8_t m_fctrlSrcAddrMode; // Bit 14-15 = 0 - No DstAddr, 2 - ShtDstAddr, 3 - ExtDstAddr + + /* Sequence Number */ + uint8_t m_SeqNum; // 1 Octet + + /* Addressing fields */ + uint16_t m_addrDstPanId; // 0 or 2 Octet + WpanAddress m_addrDstAddr; // 0, 2 or 8 Octet + uint16_t m_addrSrcPanId; // 0 or 2 Octet + WpanAddress m_addrSrcAddr; // 0, 2 or 8 Octet + + /* Auxiliary Security Header // 0, 5, 6, 10 or 14 Octets */ + uint8_t m_auxSecCtrl; // 1 Octet see below + uint32_t m_auxFrmCntr; // 4 Octet + + /* Security Control fields */ + uint8_t m_secctrlSecLevel; // Bit 0-2 + uint8_t m_secctrlKeyIdMode; // Bit 3-4 will indicate size of Key Id + // = 0 - Key is determined implicitly + // from originator and receipient + // = 1 - 1 Octet Key Index + // = 2 - 1 octet Key Index and 4 oct Key src + // = 3 - 1 octet Key Index and 8 oct Key src + + uint8_t m_secctrlReserved; // Bit 5-7 + + union + { + uint32_t m_auxKeyIdKeySrc32; // 4 octets + uint64_t m_auxKeyIdKeySrc64; // 8 octets + }; + + uint8_t m_auxKeyIdKeyIndex; // 1 octet + +}; //LrWpanMacHeader +}; // namespace ns-3 +#endif /* LRWPAN_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 new file mode 100644 index 000000000..27ab179e9 --- /dev/null +++ b/src/lr-wpan/model/lr-wpan-mac-trailer.cc @@ -0,0 +1,60 @@ +/* + * lr-wpan-mac-trailer.cc + * + * Created on: Mar 4, 2011 + * Author: kwong + */ + +#include "lr-wpan-mac-trailer.h" +#include "ns3/object.h" + +namespace ns3 { + +NS_OBJECT_ENSURE_REGISTERED (LrWpanMacTrailer); + +LrWpanMacTrailer::LrWpanMacTrailer () +{ + +} + +LrWpanMacTrailer::~LrWpanMacTrailer () +{ + +} + +TypeId LrWpanMacTrailer::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::LrWpanMacTrailer") + .SetParent () + .AddConstructor () + ; + return tid; +} + +TypeId LrWpanMacTrailer::GetInstanceTypeId (void) const +{ + return GetTypeId (); +} + +void LrWpanMacTrailer::Print (std::ostream &os) const +{ + +} + +uint32_t LrWpanMacTrailer::GetSerializedSize (void) const +{ + return LRWPAN_MAC_FCS_LENGTH; +} + +void LrWpanMacTrailer::Serialize (Buffer::Iterator start) const +{ + start.Prev (LRWPAN_MAC_FCS_LENGTH); + start.WriteU16 (0); +} + +uint32_t LrWpanMacTrailer::Deserialize (Buffer::Iterator start) +{ + return LRWPAN_MAC_FCS_LENGTH; +} + +} //namespace ns3 diff --git a/src/lr-wpan/model/lr-wpan-mac-trailer.h b/src/lr-wpan/model/lr-wpan-mac-trailer.h new file mode 100644 index 000000000..8f02bbf23 --- /dev/null +++ b/src/lr-wpan/model/lr-wpan-mac-trailer.h @@ -0,0 +1,36 @@ +/* + * lr-wpan-mac-trailer.h + * + * Created on: Mar 4, 2011 + * Author: kwong + */ + +#ifndef LRWPANMACTRAILER_H_ +#define LRWPANMACTRAILER_H_ + +#include "ns3/trailer.h" +#include + +namespace ns3 { + +/** + * The length in octets of the IEEE 802.15.4 MAC FCS field + */ + +static const uint16_t LRWPAN_MAC_FCS_LENGTH = 2; + +class LrWpanMacTrailer : public Trailer +{ +public: + LrWpanMacTrailer (); + ~LrWpanMacTrailer (); + + static TypeId GetTypeId (void); + 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); +}; +} // namespace ns3 +#endif /* LRWPANMACTRAILER_H_ */ diff --git a/src/lr-wpan/model/lr-wpan-mac.cc b/src/lr-wpan/model/lr-wpan-mac.cc new file mode 100644 index 000000000..3460c27ec --- /dev/null +++ b/src/lr-wpan/model/lr-wpan-mac.cc @@ -0,0 +1,204 @@ +/* -*- 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 + * kwong yin + */ +#include "ns3/simulator.h" +#include "ns3/lr-wpan-mac.h" +#include "ns3/log.h" +#include "ns3/lr-wpan-csmaca.h" + +NS_LOG_COMPONENT_DEFINE ("LrWpanMac"); + +namespace ns3 { + +NS_OBJECT_ENSURE_REGISTERED (LrWpanMac); + +TypeId +LrWpanMac::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::LrWpanMac") + .SetParent () + .AddConstructor () + ; + return tid; +} + +LrWpanMac::LrWpanMac () +{ + m_lrWpanMacState = MAC_IDLE; +} + +LrWpanMac::~LrWpanMac () +{ +} + +void +LrWpanMac::DoDispose () +{ + m_csmaCa->Dispose (); + m_csmaCa = 0; + m_txPkt = 0; + m_phy = 0; + m_mcpsDataIndicationCallback = MakeNullCallback< void, Ptr > (); + m_mcpsDataConfirmCallback = MakeNullCallback< void, LrWpanMcpsDataConfirmStatus > (); +} + +void +LrWpanMac::McpsDataRequest (Ptr p) +{ + NS_LOG_FUNCTION (this << p); + if (!m_mcpsDataConfirmCallback.IsNull ()) + { + // XXX for now, we are very accepting of whatever is passed down to us + m_mcpsDataConfirmCallback (IEEE_802_15_4_SUCCESS); + } + + LrWpanMacHeader macHdr (LrWpanMacHeader::LRWPAN_MAC_DATA, 0); // sequence number set to 0 + macHdr.SetSrcAddrMode (LrWpanMacHeader::SHORTADDR); // short addr + macHdr.SetDstAddrMode (LrWpanMacHeader::NOADDR); + macHdr.SetSecDisable (); + macHdr.SetNoPanIdComp (); + uint16_t shortAddr = 66; + uint16_t srcPanId = 100; + WpanAddress srcWpanAddr; + srcWpanAddr.SetAddress (shortAddr); + macHdr.SetSrcAddrFields (srcPanId,srcWpanAddr ); + p->AddHeader (macHdr); + + LrWpanMacTrailer macTrailer; + p->AddTrailer (macTrailer); + + m_txPkt = p; + + // Start CCA process for this packet + Simulator::ScheduleNow (&LrWpanCsmaCa::Start, m_csmaCa); + +} + +void LrWpanMac::SetCsmaCa (Ptr csmaCa) +{ + m_csmaCa = csmaCa; +} + +void LrWpanMac::SetPhy (Ptr phy) +{ + m_phy = phy; +} + +Ptr LrWpanMac::GetPhy (void) +{ + return m_phy; +} + +void +LrWpanMac::SetMcpsDataIndicationCallback (McpsDataIndicationCallback c) +{ + m_mcpsDataIndicationCallback = c; +} + +void +LrWpanMac::SetMcpsDataConfirmCallback (McpsDataConfirmCallback c) +{ + m_mcpsDataConfirmCallback = c; +} + +void +LrWpanMac::PdDataIndication (uint32_t psduLength, Ptr p, uint32_t lqi) +{ + NS_LOG_FUNCTION (this << psduLength << p << lqi); + + LrWpanMacHeader receivedMacHdr; + p->RemoveHeader (receivedMacHdr); + LrWpanMacTrailer receivedMacTrailer; + p->RemoveTrailer (receivedMacTrailer); + + if (!m_mcpsDataIndicationCallback.IsNull ()) + { + // All packets are successfully received for now + m_mcpsDataIndicationCallback (p); + } + +} + + +void +LrWpanMac::PdDataConfirm (LrWpanPhyEnumeration status) +{ + NS_LOG_FUNCTION (this << status); + m_phy->PlmeSetTRXStateRequest (IEEE_802_15_4_PHY_RX_ON); + m_txPkt = 0; +} + +void +LrWpanMac::PlmeCcaConfirm (LrWpanPhyEnumeration status) +{ + NS_LOG_FUNCTION (this << status); + // Direct this call through the csmaCa object + m_csmaCa->PlmeCcaConfirm (status); +} + +void +LrWpanMac::PlmeEdConfirm (LrWpanPhyEnumeration status, uint8_t energyLevel) +{ + NS_LOG_FUNCTION (this << status << energyLevel); + +} + +void +LrWpanMac::PlmeGetAttributeConfirm (LrWpanPhyEnumeration status, + LrWpanPibAttributeIdentifier id, + LrWpanPhyPIBAttributes* attribute) +{ + NS_LOG_FUNCTION (this << status << id << attribute); +} + +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_txPkt) && (m_lrWpanMacState == SET_PHY_TX_ON)) + { + m_phy->PdDataRequest (m_txPkt->GetSize (), m_txPkt); + } + } +} + +void +LrWpanMac::PlmeSetAttributeConfirm (LrWpanPhyEnumeration status, + LrWpanPibAttributeIdentifier id) +{ + NS_LOG_FUNCTION (this << status << id); +} + +void +LrWpanMac::SetLrWpanMacState (LrWpanMacState macState) +{ + NS_LOG_FUNCTION (this << macState); + m_lrWpanMacState = macState; + if ((m_lrWpanMacState == CHANNEL_IDLE) && (m_txPkt)) + { + // Channel is idle, set transmitter to TX_ON + m_lrWpanMacState = SET_PHY_TX_ON; + m_phy->PlmeSetTRXStateRequest (IEEE_802_15_4_PHY_TX_ON); + } +} +} // namespace ns3 diff --git a/src/lr-wpan/model/lr-wpan-mac.h b/src/lr-wpan/model/lr-wpan-mac.h new file mode 100644 index 000000000..66ab208f1 --- /dev/null +++ b/src/lr-wpan/model/lr-wpan-mac.h @@ -0,0 +1,189 @@ +/* -*- 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 + * kwong yin + */ +#ifndef LR_WPAN_MAC_H +#define LR_WPAN_MAC_H + +#include +#include +#include "ns3/object.h" +#include "ns3/callback.h" +#include "lr-wpan-phy.h" +#include "lr-wpan-mac-header.h" +#include "lr-wpan-mac-trailer.h" + + +namespace ns3 { + +typedef enum +{ + MAC_IDLE, + CHANNEL_BUSY, + CHANNEL_IDLE, + SET_PHY_TX_ON +} LrWpanMacState; + +/* + * Table 42 of 802.15.4-2006 + */ +typedef enum +{ + IEEE_802_15_4_SUCCESS = 0, + IEEE_802_15_4_TRANSACTION_OVERFLOW = 1, + IEEE_802_15_4_TRANSACTION_EXPIRED = 2, + IEEE_802_15_4_CHANNEL_ACCESS_FAILURE = 3, + IEEE_802_15_4_INVALID_ADDRESS = 4, + IEEE_802_15_4_INVALID_GTS = 5, + IEEE_802_15_4_NO_ACK = 6, + IEEE_802_15_4_COUNTER_ERROR = 7, + IEEE_802_15_4_FRAME_TOO_LONG = 8, + IEEE_802_15_4_UNAVAILABLE_KEY = 9, + IEEE_802_15_4_UNSUPPORTED_SECURITY = 10, + IEEE_802_15_4_INVALID_PARAMETER = 11 +} LrWpanMcpsDataConfirmStatus; + +// 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, LrWpanMcpsDataConfirmStatus > 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, Ptr > McpsDataIndicationCallback; + +class LrWpanCsmaCa; + +/** + * Class that implements the LR-WPAN Mac state machine + */ +class LrWpanMac : public Object +{ + friend class LrWpanCsmaCa; +public: + static TypeId GetTypeId (void); + + LrWpanMac (); + virtual ~LrWpanMac (); + + // interface between SSCS and MAC + /** + * specified in Section 7.1.1.1 + * + * XXX for now, we do not send down all of the parameters detailed in + * section 7.1.1.1.1 but just send down the packet. + * @param p the packet to send + */ + void McpsDataRequest (Ptr p); + + void SetCsmaCa (Ptr csmaCa); + void SetPhy (Ptr phy); + Ptr GetPhy (void); + + void SetMcpsDataIndicationCallback (McpsDataIndicationCallback c); + void SetMcpsDataConfirmCallback (McpsDataConfirmCallback c); + + // interfaces between MAC and PHY + /** + * IEEE 802.15.4-2006 section 6.2.1.3 + * PD-DATA.indication + * Indicates the transfer of an MPDU from PHY to MAC (receiving) + * @param psduLength number of bytes in the PSDU + * @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); + + /** + * IEEE 802.15.4-2006 section 6.2.1.2 + * Confirm the end of transmission of an MPDU to MAC + * @param status to report to MAC + * PHY PD-DATA.confirm status + */ + void PdDataConfirm (LrWpanPhyEnumeration status); + + /** + * IEEE 802.15.4-2006 section 6.2.2.2 + * PLME-CCA.confirm status + * @param status TRX_OFF, BUSY or IDLE + */ + void PlmeCcaConfirm (LrWpanPhyEnumeration status); + + /** + * IEEE 802.15.4-2006 section 6.2.2.4 + * PLME-ED.confirm status and energy level + * @param status SUCCESS, TRX_OFF or TX_ON + * @param energyLevel 0x00-0xff ED level for the channel + */ + void PlmeEdConfirm (LrWpanPhyEnumeration status, uint8_t energyLevel); + + /** + * IEEE 802.15.4-2006 section 6.2.2.6 + * PLME-GET.confirm + * Get attributes per definition from Table 23 in section 6.4.2 + * @param status SUCCESS or UNSUPPORTED_ATTRIBUTE + * @param id the attributed identifier + * @param * attribute the attribute value + */ + void PlmeGetAttributeConfirm (LrWpanPhyEnumeration status, + LrWpanPibAttributeIdentifier id, + LrWpanPhyPIBAttributes* attribute); + + /** + * IEEE 802.15.4-2006 section 6.2.2.8 + * PLME-SET-TRX-STATE.confirm + * Set PHY state + * @param state in RX_ON,TRX_OFF,FORCE_TRX_OFF,TX_ON + */ + void PlmeSetTRXStateConfirm (LrWpanPhyEnumeration status); + + /** + * IEEE 802.15.4-2006 section 6.2.2.10 + * PLME-SET.confirm + * Set attributes per definition from Table 23 in section 6.4.2 + * @param status SUCCESS, UNSUPPORTED_ATTRIBUTE, INVALID_PARAMETER, or READ_ONLY + * @param id the attributed identifier + */ + void PlmeSetAttributeConfirm (LrWpanPhyEnumeration status, + LrWpanPibAttributeIdentifier id); + + + /** + * CSMA-CA algorithm calls back the MAC after executing channel assessment + */ + void SetLrWpanMacState (LrWpanMacState macState); + +private: + virtual void DoDispose (void); + Ptr m_phy; + Ptr m_csmaCa; + McpsDataIndicationCallback m_mcpsDataIndicationCallback; + McpsDataConfirmCallback m_mcpsDataConfirmCallback; + LrWpanMacState m_lrWpanMacState; + Ptr m_txPkt; // XXX need packet buffer instead of single packet +}; + + +} // namespace ns3 + +#endif /* LR_WPAN_MAC_H */ diff --git a/src/lr-wpan/model/lr-wpan-phy.cc b/src/lr-wpan/model/lr-wpan-phy.cc new file mode 100644 index 000000000..d07f0f074 --- /dev/null +++ b/src/lr-wpan/model/lr-wpan-phy.cc @@ -0,0 +1,859 @@ +/* -*- 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/log.h" +#include +#include "ns3/simulator.h" +#include "ns3/lr-wpan-phy.h" + +NS_LOG_COMPONENT_DEFINE ("LrWpanPhy"); + +namespace ns3 { + +NS_OBJECT_ENSURE_REGISTERED (LrWpanPhy); + +// Table 22 in section 6.4.1 of ieee802.15.4 +const uint32_t LrWpanPhy::aMaxPhyPacketSize = 127; // max PSDU in octets +const uint32_t LrWpanPhy::aTurnaroundTime = 12; // RX-to-TX or TX-to-RX in symbol periods +// IEEE802.15.4-2006 Table 2 in section 6.1.2 (kb/s and ksymbol/s) +// The index follows LrWpanPhyOption +const LrWpanPhyDataAndSymbolRates +LrWpanPhy::dataSymbolRates[7] = { { 20.0, 20.0}, + { 40.0, 40.0}, + { 250.0, 12.5}, + { 250.0, 50.0}, + { 100.0, 25.0}, + { 250.0, 62.5}, + { 250.0, 62.5}}; +// IEEE802.15.4-2006 Table 19 and Table 20 in section 6.3. +// The PHR is 1 octet and it follows phySymbolsPerOctet in Table 23 +// The index follows LrWpanPhyOption +const LrWpanPhyPpduHeaderSymbolNumber +LrWpanPhy::ppduHeaderSymbolNumbers[7] = { { 32.0, 8.0, 8.0}, + { 32.0, 8.0, 8.0}, + { 2.0, 1.0, 0.4}, + { 6.0, 1.0, 1.6}, + { 8.0, 2.0, 2.0}, + { 8.0, 2.0, 2.0}, + { 8.0, 2.0, 2.0}}; + +TypeId +LrWpanPhy::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::LrWpanPhy") + .SetParent () + .AddConstructor () + ; + return tid; +} + +LrWpanPhy::LrWpanPhy () + : m_edRequest (), + m_setTRXState () +{ + m_trxState = IEEE_802_15_4_PHY_RX_ON; + m_trxStateDeferSet = IEEE_802_15_4_PHY_IDLE; + m_state = IEEE_802_15_4_PHY_IDLE; + m_sensedChannelState = IEEE_802_15_4_PHY_IDLE; + + // default PHY PIB attributes + m_phyPIBAttributes.phyCurrentChannel = 11; + m_phyPIBAttributes.phyTransmitPower = 0; + m_phyPIBAttributes.phyCurrentPage = 0; + for (uint32_t i = 0; i < 32; i++) + { + m_phyPIBAttributes.phyChannelsSupported[i] = 0x07ffffff; + } + m_phyPIBAttributes.phyCCAMode = 1; + + SetMyPhyOption (); + + m_rxEdPeakPower = 0.0; + m_rxTotalPower = 0.0; + m_rxTotalNum = 0; + // default -85 dBm in W for 2.4 GHz + m_rxSensitivity = pow (10.0, -85.0 / 10.0) / 1000.0; + LrWpanSpectrumValueHelper psdHelper; + m_txPsd = psdHelper.CreateTxPowerSpectralDensity (m_phyPIBAttributes.phyTransmitPower, + m_phyPIBAttributes.phyCurrentChannel); + m_noise = psdHelper.CreateNoisePowerSpectralDensity (m_phyPIBAttributes.phyCurrentChannel); + m_rxPsd = 0; + Ptr none = 0; + m_currentRxPacket = std::make_pair (none, true); + m_currentTxPacket = std::make_pair (none, true); +} + +LrWpanPhy::~LrWpanPhy () +{ +} + +void +LrWpanPhy::DoDispose () +{ + NS_LOG_FUNCTION (this); + m_mobility = 0; + m_device = 0; + m_channel = 0; + m_txPsd = 0; + m_rxPsd = 0; + m_noise = 0; + m_pdDataIndicationCallback = MakeNullCallback< void, uint32_t, Ptr, uint32_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_plmeSetTRXStateConfirmCallback = MakeNullCallback< void, LrWpanPhyEnumeration > (); + m_plmeSetAttributeConfirmCallback = MakeNullCallback< void, LrWpanPhyEnumeration, LrWpanPibAttributeIdentifier > (); + + SpectrumPhy::DoDispose (); +} + +Ptr +LrWpanPhy::GetDevice () +{ + NS_LOG_FUNCTION (this); + return m_device; +} + + +Ptr +LrWpanPhy::GetMobility () +{ + NS_LOG_FUNCTION (this); + return m_mobility; +} + + +void +LrWpanPhy::SetDevice (Ptr d) +{ + NS_LOG_FUNCTION (this << d); + m_device = d; +} + + +void +LrWpanPhy::SetMobility (Ptr m) +{ + NS_LOG_FUNCTION (this << m); + m_mobility = m; +} + + +void +LrWpanPhy::SetChannel (Ptr c) +{ + NS_LOG_FUNCTION (this << c); + m_channel = c; +} + + +Ptr +LrWpanPhy::GetChannel (void) +{ + return m_channel; +} + + +Ptr +LrWpanPhy::GetRxSpectrumModel () const +{ + if (m_txPsd) + { + return m_txPsd->GetSpectrumModel (); + } + else + { + return 0; + } +} + +void +LrWpanPhy::StartRx (Ptr pb, Ptr rxPsd, SpectrumType st, Time duration) +{ + NS_LOG_FUNCTION (this << pb << rxPsd << st << duration); + if (st == GetSpectrumType ()) + { + Ptr p = (pb->GetPackets ()).front (); + m_currentRxPacket = std::make_pair (p, false); + m_rxPsd = rxPsd; + Simulator::Schedule (duration, &LrWpanPhy::EndRx, this); + } + NS_LOG_LOGIC (this << " state: " << m_state); +} + +void LrWpanPhy::EndRx () +{ + NS_LOG_FUNCTION (this); + NS_LOG_LOGIC (this << "state: " << m_state); + if (!m_pdDataIndicationCallback.IsNull ()) + { + Ptr p = m_currentRxPacket.first; + m_pdDataIndicationCallback (p->GetSize (), p, 0); + } +} + +void +LrWpanPhy::PdDataRequest (const uint32_t psduLength, Ptr p) +{ + NS_LOG_FUNCTION (this << psduLength << p); + + if (psduLength > aMaxPhyPacketSize) + { + if (!m_pdDataConfirmCallback.IsNull ()) + { + m_pdDataConfirmCallback (IEEE_802_15_4_PHY_UNSPECIFIED); + } + NS_LOG_DEBUG ("Drop packet because psduLength" << psduLength); + return; + } + + if (m_trxState == IEEE_802_15_4_PHY_TX_ON) + { + if (m_state == IEEE_802_15_4_PHY_IDLE) + { + //send down + ChangeState (IEEE_802_15_4_PHY_BUSY); // for carrier sensing + NS_ASSERT (m_channel); + Time txTime = CalculateTxTime (p); + Ptr pb = CreateObject (); + pb->AddPacket (p); + m_channel->StartTx (pb, m_txPsd, GetSpectrumType (), txTime, GetObject ()); + m_pdDataRequest = Simulator::Schedule (txTime, &LrWpanPhy::EndTx, this); + } + else + { + NS_ASSERT_MSG (false, "impossible, should not happen"); + } + } + else + { + if (!m_pdDataConfirmCallback.IsNull ()) + { + m_pdDataConfirmCallback (m_trxState); + } + } + +} + +void +LrWpanPhy::PlmeCcaRequest (void) +{ + NS_LOG_FUNCTION (this); + if (m_trxState == IEEE_802_15_4_PHY_RX_ON) + { + Time ccaTime = Seconds (8.0 / GetDataOrSymbolRate (false)); + Simulator::Schedule (ccaTime, &LrWpanPhy::EndCca, this); + } + else + { + if (!m_plmeCcaConfirmCallback.IsNull ()) + { + m_plmeCcaConfirmCallback (m_trxState); + } + } +} + +void +LrWpanPhy::PlmeEdRequest (void) +{ + NS_LOG_FUNCTION (this); + if (m_trxState == IEEE_802_15_4_PHY_RX_ON) + { + m_rxEdPeakPower = m_rxTotalPower; + Time edTime = Seconds (8.0 / GetDataOrSymbolRate (false)); + m_edRequest = Simulator::Schedule (edTime, &LrWpanPhy::EndEd, this); + } + else + { + if (!m_plmeEdConfirmCallback.IsNull ()) + { + m_plmeEdConfirmCallback (m_trxState,0); + } + } +} + +void +LrWpanPhy::PlmeGetAttributeRequest (LrWpanPibAttributeIdentifier id) +{ + NS_LOG_FUNCTION (this << id); + LrWpanPhyEnumeration status; + + switch (id) + { + case phyCurrentChannel: + case phyChannelsSupported: + case phyTransmitPower: + case phyCCAMode: + case phyCurrentPage: + case phyMaxFrameDuration: + case phySHRDuration: + case phySymbolsPerOctet: + { + status = IEEE_802_15_4_PHY_SUCCESS; + break; + } + default: + { + status = IEEE_802_15_4_PHY_UNSUPPORTED_ATTRIBUTE; + break; + } + } + if (!m_plmeGetAttributeConfirmCallback.IsNull ()) + { + LrWpanPhyPIBAttributes retValue; + memcpy (&retValue, &m_phyPIBAttributes, sizeof(LrWpanPhyPIBAttributes)); + m_plmeGetAttributeConfirmCallback (status,id,&retValue); + } +} + +void +LrWpanPhy::PlmeSetTRXStateRequest (LrWpanPhyEnumeration state) +{ + NS_LOG_FUNCTION (this << state); + + bool delay; + LrWpanPhyEnumeration status; + + // ignore any pending request + if (m_trxStateDeferSet != IEEE_802_15_4_PHY_IDLE) + { + m_trxStateDeferSet = IEEE_802_15_4_PHY_IDLE; + } + else if (m_setTRXState.IsRunning ()) + { + m_setTRXState.Cancel (); + } + + status = m_trxState; + + if (state != m_trxState) + { + delay = false; + + if (((state == IEEE_802_15_4_PHY_RX_ON) || (state == IEEE_802_15_4_PHY_TRX_OFF)) + && (m_state == IEEE_802_15_4_PHY_BUSY)) + { + status = IEEE_802_15_4_PHY_BUSY; + m_trxStateDeferSet = state; + } + else if (((state == IEEE_802_15_4_PHY_TX_ON) + ||(state == IEEE_802_15_4_PHY_TRX_OFF)) + && (m_currentRxPacket.first) &&(!m_currentRxPacket.second)) + { //if after received a valid SFD + status = IEEE_802_15_4_PHY_BUSY_RX; + m_trxStateDeferSet = state; + } + else if (state == IEEE_802_15_4_PHY_FORCE_TRX_OFF) + { + if (m_trxState == IEEE_802_15_4_PHY_TRX_OFF) + { + status = IEEE_802_15_4_PHY_TRX_OFF; + } + else + { + status = IEEE_802_15_4_PHY_SUCCESS; + } + + m_trxState = IEEE_802_15_4_PHY_TRX_OFF; + + if (m_currentRxPacket.first) + { //terminate reception if needed + //incomplete reception -- force packet discard + m_currentRxPacket.second = true; + } + + if (m_state == IEEE_802_15_4_PHY_BUSY) + { //terminate transmission if needed + m_currentTxPacket.second = true; + m_currentTxPacket.first = 0; + m_pdDataRequest.Cancel (); + m_state = IEEE_802_15_4_PHY_IDLE; + if (!m_pdDataConfirmCallback.IsNull ()) + { + m_pdDataConfirmCallback (IEEE_802_15_4_PHY_TRX_OFF); + } + if (m_trxStateDeferSet != IEEE_802_15_4_PHY_IDLE) + { + m_trxStateDeferSet = IEEE_802_15_4_PHY_IDLE; + } + } + } + else + { + status = IEEE_802_15_4_PHY_SUCCESS; + if (((state == IEEE_802_15_4_PHY_RX_ON)&&(m_trxState == IEEE_802_15_4_PHY_TX_ON)) + ||((state == IEEE_802_15_4_PHY_TX_ON)&&(m_trxState == IEEE_802_15_4_PHY_RX_ON))) + { + m_trxStateTurnaround = state; + delay = true; + } + else + { + m_trxState = state; + } + } + + //we need to delay symbols if Tx2Rx or Rx2Tx + if (delay) + { //should be disabled immediately + //(further transmission/reception will not succeed) + m_trxState = IEEE_802_15_4_PHY_TRX_OFF; + + Time setTime = Seconds ( (double) aTurnaroundTime / GetDataOrSymbolRate (false)); + m_setTRXState = Simulator::Schedule (setTime, &LrWpanPhy::EndSetTRXState, this); + } + else + { + if (!m_plmeSetTRXStateConfirmCallback.IsNull ()) + { + m_plmeSetTRXStateConfirmCallback (status); + } + } + } + else + { + if (!m_plmeSetTRXStateConfirmCallback.IsNull ()) + { + m_plmeSetTRXStateConfirmCallback (status); + } + } + + NS_LOG_LOGIC (this << " SetTRXRequest old: " << m_trxState << " request: " << state + << " return: " << status); +} + +bool +LrWpanPhy::ChannelSupported (uint8_t channel) +{ + NS_LOG_FUNCTION (this << channel); + bool retValue = false; + + for (uint32_t i = 0; i < 32; i++) + { + if ((m_phyPIBAttributes.phyChannelsSupported[i] & (1 << channel)) != 0) + { + retValue = true; + break; + } + } + + return retValue; +} + +void +LrWpanPhy::PlmeSetAttributeRequest (LrWpanPibAttributeIdentifier id, + LrWpanPhyPIBAttributes* attribute) +{ + NS_ASSERT (attribute); + NS_LOG_FUNCTION (this << id << attribute); + LrWpanPhyEnumeration status = IEEE_802_15_4_PHY_SUCCESS; + + switch (id) + { + case phyCurrentChannel: + { + if (!ChannelSupported (attribute->phyCurrentChannel)) + { + status = IEEE_802_15_4_PHY_INVALID_PARAMETER; + } + if (m_phyPIBAttributes.phyCurrentChannel != attribute->phyCurrentChannel) + { //any packet in transmission or reception will be corrupted + if (m_currentRxPacket.first) + { + m_currentRxPacket.second = true; + } + if (m_state == IEEE_802_15_4_PHY_BUSY) + { + m_currentTxPacket.second = true; + m_pdDataRequest.Cancel (); + m_currentTxPacket.first = 0; + m_state = IEEE_802_15_4_PHY_IDLE; + if (!m_pdDataConfirmCallback.IsNull ()) + { + m_pdDataConfirmCallback (IEEE_802_15_4_PHY_TRX_OFF); + } + + if (m_trxStateDeferSet != IEEE_802_15_4_PHY_IDLE) + { + m_trxStateDeferSet = IEEE_802_15_4_PHY_IDLE; + } + } + m_phyPIBAttributes.phyCurrentChannel = attribute->phyCurrentChannel; + } + break; + } + case phyChannelsSupported: + { // only the first element is considered in the array + if ((attribute->phyChannelsSupported[0] & 0xf8000000) != 0) + { //5 MSBs reserved + status = IEEE_802_15_4_PHY_INVALID_PARAMETER; + } + else + { + m_phyPIBAttributes.phyChannelsSupported[0] = attribute->phyChannelsSupported[0]; + } + break; + } + case phyTransmitPower: + { + if (attribute->phyTransmitPower > 0xbf) + { + status = IEEE_802_15_4_PHY_INVALID_PARAMETER; + } + else + { + m_phyPIBAttributes.phyTransmitPower = attribute->phyTransmitPower; + } + break; + } + case phyCCAMode: + { + if ((attribute->phyCCAMode < 1) || (attribute->phyCCAMode > 3)) + { + status = IEEE_802_15_4_PHY_INVALID_PARAMETER; + } + else + { + m_phyPIBAttributes.phyCCAMode = attribute->phyCCAMode; + } + break; + } + default: + { + status = IEEE_802_15_4_PHY_UNSUPPORTED_ATTRIBUTE; + break; + } + } + + if (!m_plmeSetAttributeConfirmCallback.IsNull ()) + { + m_plmeSetAttributeConfirmCallback (status, id); + } +} + +bool +LrWpanPhy::StartTx (Ptr p) +{ + NS_LOG_UNCOND ("StartTx " << this << "pkt " << p); + NS_LOG_FUNCTION (this << p); + return true; +} + +void +LrWpanPhy::SetPdDataIndicationCallback (PdDataIndicationCallback c) +{ + NS_LOG_FUNCTION (this); + m_pdDataIndicationCallback = c; +} + +void +LrWpanPhy::SetPdDataConfirmCallback (PdDataConfirmCallback c) +{ + NS_LOG_FUNCTION (this); + m_pdDataConfirmCallback = c; +} + +void +LrWpanPhy::SetPlmeCcaConfirmCallback (PlmeCcaConfirmCallback c) +{ + NS_LOG_FUNCTION (this); + m_plmeCcaConfirmCallback = c; +} + +void +LrWpanPhy::SetPlmeEdConfirmCallback (PlmeEdConfirmCallback c) +{ + NS_LOG_FUNCTION (this); + m_plmeEdConfirmCallback = c; +} + +void +LrWpanPhy::SetPlmeGetAttributeConfirmCallback (PlmeGetAttributeConfirmCallback c) +{ + NS_LOG_FUNCTION (this); + m_plmeGetAttributeConfirmCallback = c; +} + +void +LrWpanPhy::SetPlmeSetTRXStateConfirmCallback (PlmeSetTRXStateConfirmCallback c) +{ + NS_LOG_FUNCTION (this); + m_plmeSetTRXStateConfirmCallback = c; +} + +void +LrWpanPhy::SetPlmeSetAttributeConfirmCallback (PlmeSetAttributeConfirmCallback c) +{ + NS_LOG_FUNCTION (this); + m_plmeSetAttributeConfirmCallback = c; +} + +void +LrWpanPhy::ChangeState (LrWpanPhyEnumeration newState) +{ + NS_LOG_LOGIC (this << " state: " << m_state << " -> " << newState); + m_state = newState; +} + +void +LrWpanPhy::EndEd () +{ + NS_LOG_FUNCTION (this); + uint8_t energyLevel; + + // Per IEEE802.15.4-2006 sec 6.9.7 + double ratio = m_rxEdPeakPower / m_rxSensitivity; + ratio = 10.0 * log10 (ratio); + if (ratio <= 10.0) + { // less than 10 dB + energyLevel = 0; + } + else if (ratio >= 40.0) + { // less than 40 dB + energyLevel = 255; + } + else + { + // in-between with linear increase per sec 6.9.7 + energyLevel = (uint8_t)((ratio / 10.0 - 1.0) * (255.0 / 3.0)); + } + + if (!m_plmeEdConfirmCallback.IsNull ()) + { + m_plmeEdConfirmCallback (IEEE_802_15_4_PHY_SUCCESS, energyLevel); + } +} + +void +LrWpanPhy::EndCca () +{ + NS_LOG_FUNCTION (this); + + if ((m_state == IEEE_802_15_4_PHY_BUSY)||(m_rxTotalNum > 0)) + { + m_sensedChannelState = IEEE_802_15_4_PHY_BUSY; + } + else if (m_phyPIBAttributes.phyCCAMode == 1) + { //sec 6.9.9 ED detection + // -- ED threshold at most 10 dB above receiver sensitivity. + if (m_rxTotalPower / m_rxSensitivity >= 10.0) + { + m_sensedChannelState = IEEE_802_15_4_PHY_BUSY; + } + else + { + m_sensedChannelState = IEEE_802_15_4_PHY_IDLE; + } + } + else if (m_phyPIBAttributes.phyCCAMode == 2) + { //sec 6.9.9 carrier sense only + if (m_rxTotalNum > 0) + { + m_sensedChannelState = IEEE_802_15_4_PHY_BUSY; + } + else + { + m_sensedChannelState = IEEE_802_15_4_PHY_IDLE; + } + } + else if (m_phyPIBAttributes.phyCCAMode == 3) + { //sect 6.9.9 both + if ((m_rxTotalPower / m_rxSensitivity >= 10.0) + && (m_rxTotalNum > 0)) + { + m_sensedChannelState = IEEE_802_15_4_PHY_BUSY; + } + else + { + m_sensedChannelState = IEEE_802_15_4_PHY_IDLE; + } + } + else + { + NS_ASSERT_MSG (false, "Invalid CCA mode"); + } + + NS_LOG_LOGIC (this << "state: " << m_sensedChannelState); + + if (!m_plmeCcaConfirmCallback.IsNull ()) + { + m_plmeCcaConfirmCallback (m_sensedChannelState); + } +} + +void +LrWpanPhy::EndSetTRXState () +{ + NS_LOG_FUNCTION (this); + + m_trxState = m_trxStateTurnaround; + + if (!m_plmeSetTRXStateConfirmCallback.IsNull ()) + { + m_plmeSetTRXStateConfirmCallback (m_trxState); + } +} + +void +LrWpanPhy::EndTx () +{ + NS_LOG_FUNCTION (this); + NS_LOG_LOGIC (this << "state: " << m_state); + + NS_ASSERT (m_state == IEEE_802_15_4_PHY_BUSY); + + ChangeState (IEEE_802_15_4_PHY_IDLE); + if (!m_pdDataConfirmCallback.IsNull ()) + { + m_pdDataConfirmCallback (IEEE_802_15_4_PHY_SUCCESS); + } +} + +Time +LrWpanPhy::CalculateTxTime (Ptr packet) +{ + Time txTime = Seconds (0); + bool isData = true; + + txTime = Seconds (GetPpduHeaderTxTime () + + packet->GetSize () * 8.0 / GetDataOrSymbolRate (isData)); + + return txTime; +} + +SpectrumType +LrWpanPhy::GetSpectrumType () +{ + NS_LOG_FUNCTION (this); + static SpectrumType st = SpectrumTypeFactory::Create ("Ieee802.15.4"); + return st; +} + +double +LrWpanPhy::GetDataOrSymbolRate (bool isData) +{ + double rate = 0.0; + + NS_ASSERT (m_phyOption < IEEE_802_15_4_INVALID_PHY_OPTION); + + if (isData) + { + rate = dataSymbolRates [m_phyOption].bitRate; + } + else + { + rate = dataSymbolRates [m_phyOption].symbolRate; + } + + return (rate * 1000.0); +} + +double +LrWpanPhy::GetPpduHeaderTxTime (void) +{ + bool isData = false; + double totalPpduHdrSymbols; + + NS_ASSERT (m_phyOption < IEEE_802_15_4_INVALID_PHY_OPTION); + + totalPpduHdrSymbols = ppduHeaderSymbolNumbers[m_phyOption].shrPreamble + + ppduHeaderSymbolNumbers[m_phyOption].shrSfd + + ppduHeaderSymbolNumbers[m_phyOption].phr; + + return totalPpduHdrSymbols / GetDataOrSymbolRate (isData); +} + +// IEEE802.15.4-2006 Table 2 in section 6.1.2 +void +LrWpanPhy::SetMyPhyOption (void) +{ + m_phyOption = IEEE_802_15_4_INVALID_PHY_OPTION; + + if (m_phyPIBAttributes.phyCurrentPage == 0) + { + if (m_phyPIBAttributes.phyCurrentChannel == 0) + { // 868 MHz BPSK + m_phyOption = IEEE_802_15_4_868MHZ_BPSK; + } + else if (m_phyPIBAttributes.phyCurrentChannel <= 10) + { // 915 MHz BPSK + m_phyOption = IEEE_802_15_4_915MHZ_BPSK; + } + else if (m_phyPIBAttributes.phyCurrentChannel <= 26) + { // 2.4 GHz MHz O-QPSK + m_phyOption = IEEE_802_15_4_2_4GHZ_OQPSK; + } + } + else if (m_phyPIBAttributes.phyCurrentPage == 1) + { + if (m_phyPIBAttributes.phyCurrentChannel == 0) + { // 868 MHz ASK + m_phyOption = IEEE_802_15_4_868MHZ_ASK; + } + else if (m_phyPIBAttributes.phyCurrentChannel <= 10) + { // 915 MHz ASK + m_phyOption = IEEE_802_15_4_915MHZ_ASK; + } + } + else if (m_phyPIBAttributes.phyCurrentPage == 2) + { + if (m_phyPIBAttributes.phyCurrentChannel == 0) + { // 868 MHz O-QPSK + m_phyOption = IEEE_802_15_4_868MHZ_OQPSK; + } + else if (m_phyPIBAttributes.phyCurrentChannel <= 10) + { // 915 MHz O-QPSK + m_phyOption = IEEE_802_15_4_915MHZ_OQPSK; + } + } +} + +LrWpanPhyOption +LrWpanPhy::GetMyPhyOption (void) +{ + return m_phyOption; +} + +void +LrWpanPhy::SetTxPowerSpectralDensity (Ptr txPsd) +{ + NS_LOG_FUNCTION (this << txPsd); + NS_ASSERT (txPsd); + m_txPsd = txPsd; + NS_LOG_INFO ("\t computed tx_psd: " << *txPsd << "\t stored tx_psd: " << *m_txPsd); +} + +void +LrWpanPhy::SetNoisePowerSpectralDensity (Ptr noisePsd) +{ + NS_LOG_FUNCTION (this << noisePsd); + NS_LOG_INFO ("\t computed noise_psd: " << *noisePsd ); + NS_ASSERT (noisePsd); + m_noise = noisePsd; +} + +Ptr +LrWpanPhy::GetNoisePowerSpectralDensity (void) +{ + NS_LOG_FUNCTION (this); + return m_noise; +} + +} // namespace ns3 diff --git a/src/lr-wpan/model/lr-wpan-phy.h b/src/lr-wpan/model/lr-wpan-phy.h new file mode 100644 index 000000000..e3299b085 --- /dev/null +++ b/src/lr-wpan/model/lr-wpan-phy.h @@ -0,0 +1,421 @@ +/* -*- 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_PHY_H +#define LR_WPAN_PHY_H + +#include +#include +#include +#include "ns3/object.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ns3 { + +/** + * IEEE802.15.4-2006 Table 1 and 2 in section 6.1.1 and 6.1.2 + */ +typedef struct +{ + double bitRate; + double symbolRate; +} LrWpanPhyDataAndSymbolRates; + +/** + * IEEE802.15.4-2006 Figure 16, Table 19 and 20 in section 6.3 + * this data structure provides number of symbols for the PPDU headers: SHR and PHR + */ +typedef struct +{ + double shrPreamble; + double shrSfd; + double phr; +} LrWpanPhyPpduHeaderSymbolNumber; + +/** + * This Phy option will be used to index various Tables in IEEE802.15.4-2006 + */ +typedef enum +{ + IEEE_802_15_4_868MHZ_BPSK = 0, + IEEE_802_15_4_915MHZ_BPSK = 1, + IEEE_802_15_4_868MHZ_ASK = 2, + IEEE_802_15_4_915MHZ_ASK = 3, + IEEE_802_15_4_868MHZ_OQPSK = 4, + IEEE_802_15_4_915MHZ_OQPSK = 5, + IEEE_802_15_4_2_4GHZ_OQPSK = 6, + IEEE_802_15_4_INVALID_PHY_OPTION = 7 +} LrWpanPhyOption; + +/** + * IEEE802.15.4-2006 PHY Emumerations Table 18 + * in section 6.2.3 + */ +typedef enum +{ + IEEE_802_15_4_PHY_BUSY = 0x00, + IEEE_802_15_4_PHY_BUSY_RX = 0x01, + IEEE_802_15_4_PHY_BUSY_TX = 0x02, + IEEE_802_15_4_PHY_FORCE_TRX_OFF = 0x03, + IEEE_802_15_4_PHY_IDLE = 0x04, + IEEE_802_15_4_PHY_INVALID_PARAMETER = 0x05, + IEEE_802_15_4_PHY_RX_ON = 0x06, + IEEE_802_15_4_PHY_SUCCESS = 0x07, + IEEE_802_15_4_PHY_TRX_OFF = 0x08, + IEEE_802_15_4_PHY_TX_ON = 0x09, + IEEE_802_15_4_PHY_UNSUPPORTED_ATTRIBUTE = 0xa, + IEEE_802_15_4_PHY_READ_OLNY = 0xb, + IEEE_802_15_4_PHY_UNSPECIFIED = 0xc // all cases not covered by ieee802.15.4 +} LrWpanPhyEnumeration; + +/** IEEE802.15.4-2006 PHY PIB Attributes Table 23 + * in section 6.4.2 + */ +typedef enum +{ + phyCurrentChannel = 0x00, + phyChannelsSupported = 0x01, + phyTransmitPower = 0x02, + phyCCAMode = 0x03, + phyCurrentPage = 0x04, + phyMaxFrameDuration = 0x05, + phySHRDuration = 0x06, + phySymbolsPerOctet = 0x07 +} LrWpanPibAttributeIdentifier; + +typedef struct +{ + uint8_t phyCurrentChannel; + uint32_t phyChannelsSupported[32]; + uint8_t phyTransmitPower; + uint8_t phyCCAMode; + uint32_t phyCurrentPage; + uint32_t phyMaxFrameDuration; + uint32_t phySHRDuration; + double phySymbolsPerOctet; +} LrWpanPhyPIBAttributes; + +/** + * This method implements the PD SAP: PdDataIndication + * + * @param psduLength number of bytes in the PSDU + * @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; + +/** + * This method implements the PD SAP: PdDataConfirm + * + * @param status the status to be transmitted + */ +typedef Callback< void, LrWpanPhyEnumeration > PdDataConfirmCallback; + +/** + * This method implements the PD SAP: PlmeCcaConfirm + * + * @param status the status of CCA + */ +typedef Callback< void, LrWpanPhyEnumeration > PlmeCcaConfirmCallback; + +/** + * This method implements the PD SAP: PlmeEdConfirm + * + * @param status the status of ED + * @param energyLevel the energy level of ED + */ +typedef Callback< void, LrWpanPhyEnumeration,uint8_t > PlmeEdConfirmCallback; + +/** + * This method implements the PD SAP: PlmeGetAttributeConfirm + * + * @param status the status of PlmeGetAttributeRequest + * @param id the identifier of attribute + * @param attribute the pointer to attribute struct + */ +typedef Callback< void, LrWpanPhyEnumeration, + LrWpanPibAttributeIdentifier, + LrWpanPhyPIBAttributes* > PlmeGetAttributeConfirmCallback; + +/** + * This method implements the PD SAP: PlmeSetTRXStateConfirm + * + * @param status the status of PlmeSetTRXStateRequest + */ +typedef Callback< void, LrWpanPhyEnumeration > PlmeSetTRXStateConfirmCallback; + +/** + * This method implements the PD SAP: PlmeSetAttributeConfirm + * + * @param status the status of PlmeSetAttributeRequest + * @param id the identifier of attribute + */ +typedef Callback< void, LrWpanPhyEnumeration, + LrWpanPibAttributeIdentifier > PlmeSetAttributeConfirmCallback; + +/** + * Make LrWpanPhy a SpectrumPhy so we can enable the eventual modeling of + * device interference + */ +class LrWpanPhy : public SpectrumPhy +{ + +public: + // The second is true if the first is flagged as error + typedef std::pair, bool> PacketAndStatus; + + static TypeId GetTypeId (void); + + LrWpanPhy (); + virtual ~LrWpanPhy (); + + // inherited from SpectrumPhy + void SetMobility (Ptr m); + Ptr GetMobility (); + void SetChannel (Ptr c); + Ptr GetChannel (void); + void SetDevice (Ptr d); + Ptr GetDevice (); + virtual Ptr GetRxSpectrumModel () const; + /** + * Get the SpectrumType used by this PHY + * + * @return + */ + SpectrumType GetSpectrumType (); + + /** + * set the Power Spectral Density of outgoing signals in W/Hz. + * + * @param txPsd + */ + void SetTxPowerSpectralDensity (Ptr txPsd); + + /** + * \brief 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 + * @return the Noise Power Spectral Density + */ + Ptr GetNoisePowerSpectralDensity (void); + + /** + * Notify the SpectrumPhy instance of an incoming waveform + * + * @param p the PacketBurst associated with the incoming waveform + * @param rxPsd the Power Spectral Density of the incoming + * waveform. The units of the PSD are the same specified for SpectrumChannel::StartTx(). + * @param st spectrum type + * @param duration the duration of the incoming waveform + */ + virtual void StartRx (Ptr p, Ptr rxPsd, SpectrumType st, Time duration); + + /** + * IEEE 802.15.4-2006 section 6.2.1.1 + * PD-DATA.request + * Request to transfer MPDU from MAC (transmitting) + * @param psduLength number of bytes in the PSDU + * @param p the packet to be transmitted + */ + void PdDataRequest (const uint32_t psduLength, Ptr p); + + /** + * IEEE 802.15.4-2006 section 6.2.2.1 + * PLME-CCA.request + * Perform a CCA per section 6.9.9 + */ + void PlmeCcaRequest (void); + + /** + * IEEE 802.15.4-2006 section 6.2.2.3 + * PLME-ED.request + * Perform an ED per section 6.9.7 + */ + void PlmeEdRequest (void); + + /** + * IEEE 802.15.4-2006 section 6.2.2.5 + * PLME-GET.request + * Get attributes per definition from Table 23 in section 6.4.2 + * @param id the attributed identifier + */ + void PlmeGetAttributeRequest (LrWpanPibAttributeIdentifier id); + + /** + * IEEE 802.15.4-2006 section 6.2.2.7 + * PLME-SET-TRX-STATE.request + * Set PHY state + * @param state in RX_ON,TRX_OFF,FORCE_TRX_OFF,TX_ON + */ + void PlmeSetTRXStateRequest (LrWpanPhyEnumeration state); + + /** + * IEEE 802.15.4-2006 section 6.2.2.9 + * PLME-SET.request + * Set attributes per definition from Table 23 in section 6.4.2 + * @param id the attributed identifier + * @param * attribute the attribute value + */ + void PlmeSetAttributeRequest (LrWpanPibAttributeIdentifier id, LrWpanPhyPIBAttributes* attribute); + + /** + * Start a transmission + * + * + * @param p the packet to be transmitted + * + * @return true if an error occurred and the transmission was not + * started, false otherwise. + */ + bool StartTx (Ptr p); + + /** + * set the callback for the end of a RX, as part of the + * interconnections betweenthe PHY and the MAC. The callback + * implements PD Indication SAP. + * @param c the callback + */ + void SetPdDataIndicationCallback (PdDataIndicationCallback c); + + /** + * set the callback for the end of a TX, as part of the + * interconnections betweenthe PHY and the MAC. The callback + * implements PD SAP. + * @param c the callback + */ + void SetPdDataConfirmCallback (PdDataConfirmCallback c); + + /** + * set the callback for the end of a CCA, as part of the + * interconnections betweenthe PHY and the MAC. The callback + * implement PLME CCA confirm SAP + * @param c the callback + */ + void SetPlmeCcaConfirmCallback (PlmeCcaConfirmCallback c); + + /** + * set the callback for the end of an ED, as part of the + * interconnections betweenthe PHY and the MAC. The callback + * implement PLME ED confirm SAP + * @param c the callback + */ + void SetPlmeEdConfirmCallback (PlmeEdConfirmCallback c); + + /** + * set the callback for the end of an GetAttribute, as part of the + * interconnections betweenthe PHY and the MAC. The callback + * implement PLME GetAttribute confirm SAP + * @param c the callback + */ + void SetPlmeGetAttributeConfirmCallback (PlmeGetAttributeConfirmCallback c); + + /** + * set the callback for the end of an SetTRXState, as part of the + * interconnections betweenthe PHY and the MAC. The callback + * implement PLME SetTRXState confirm SAP + * @param c the callback + */ + void SetPlmeSetTRXStateConfirmCallback (PlmeSetTRXStateConfirmCallback c); + + /** + * set the callback for the end of an SetAttribute, as part of the + * interconnections betweenthe PHY and the MAC. The callback + * implement PLME SetAttribute confirm SAP + * @param c the callback + */ + void SetPlmeSetAttributeConfirmCallback (PlmeSetAttributeConfirmCallback c); + + /** + * implement PLME SetAttribute confirm SAP + * @param isData is true for data rate or false for symbol rate + * @return the rate value of this PHY + */ + double GetDataOrSymbolRate (bool isData); + +protected: + 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 + static const LrWpanPhyDataAndSymbolRates dataSymbolRates[7]; + static const LrWpanPhyPpduHeaderSymbolNumber ppduHeaderSymbolNumbers[7]; + +private: + virtual void DoDispose (void); + void ChangeState (LrWpanPhyEnumeration newState); + void SetMyPhyOption (void); + LrWpanPhyOption GetMyPhyOption (void); + void EndTx (); + void EndRx (); + void EndEd (); + void EndCca (); + void EndSetTRXState (); + Time CalculateTxTime (Ptr packet); + double GetPpduHeaderTxTime (void); + bool ChannelSupported (uint8_t); + Ptr m_mobility; + Ptr m_device; + Ptr m_channel; + Ptr m_txPsd; + Ptr m_rxPsd; + Ptr m_noise; + LrWpanPhyPIBAttributes m_phyPIBAttributes; + LrWpanPhyEnumeration m_trxState; + LrWpanPhyEnumeration m_trxStateDeferSet; + LrWpanPhyEnumeration m_trxStateTurnaround; + LrWpanPhyEnumeration m_sensedChannelState; + LrWpanPhyEnumeration m_state; + PdDataIndicationCallback m_pdDataIndicationCallback; + PdDataConfirmCallback m_pdDataConfirmCallback; + PlmeCcaConfirmCallback m_plmeCcaConfirmCallback; + PlmeEdConfirmCallback m_plmeEdConfirmCallback; + PlmeGetAttributeConfirmCallback m_plmeGetAttributeConfirmCallback; + PlmeSetTRXStateConfirmCallback m_plmeSetTRXStateConfirmCallback; + PlmeSetAttributeConfirmCallback m_plmeSetAttributeConfirmCallback; + LrWpanPhyOption m_phyOption; + double m_rxEdPeakPower; + double m_rxTotalPower; + uint32_t m_rxTotalNum; + double m_rxSensitivity; + PacketAndStatus m_currentRxPacket; + PacketAndStatus m_currentTxPacket; + + EventId m_edRequest; + EventId m_setTRXState; + EventId m_pdDataRequest; +}; + + +} // namespace ns3 + +#endif /* LR_WPAN_PHY_H */ diff --git a/src/lr-wpan/model/lr-wpan-spectrum-value-helper.cc b/src/lr-wpan/model/lr-wpan-spectrum-value-helper.cc new file mode 100644 index 000000000..3746f4aca --- /dev/null +++ b/src/lr-wpan/model/lr-wpan-spectrum-value-helper.cc @@ -0,0 +1,117 @@ +/* -*- 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 "lr-wpan-spectrum-value-helper.h" + +namespace ns3 { + +Ptr g_LrWpanSpectrumModel; + +class LrWpanSpectrumModelInitializer +{ +public: + LrWpanSpectrumModelInitializer () + { + + Bands bands; + // 1 MHz resolution from 2400 to 2483 MHz (center freq) + for (int i = -1; i < 83; i++) + { + BandInfo bi; + bi.fl = 2400.5e6 + i * 1.0e6; + bi.fh = 2400.5e6 + (i + 1) * 1.0e6; + bi.fc = (bi.fl + bi.fh) / 2; + bands.push_back (bi); + } + g_LrWpanSpectrumModel = Create (bands); + } + +} g_LrWpanSpectrumModelInitializerInstance; + +LrWpanSpectrumValueHelper::LrWpanSpectrumValueHelper () +{ + m_noiseFigure = 1.0; +} + +LrWpanSpectrumValueHelper::~LrWpanSpectrumValueHelper () +{ +} + +Ptr +LrWpanSpectrumValueHelper::CreateTxPowerSpectralDensity (double txPower, uint32_t channel) +{ + Ptr txPsd = Create (g_LrWpanSpectrumModel); + + // txPower is expressed in dBm. We must convert it into natural unit. + txPower = pow (10., (txPower - 30) / 10); + + 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 + (*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.5; // -10 dB + (*txPsd)[2405 + 5 * (channel - 11) - 2400 + 3 ] = txPowerDensity * 0.5; // -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 + + return txPsd; +} + +Ptr +LrWpanSpectrumValueHelper::CreateNoisePowerSpectralDensity (uint32_t channel) +{ + Ptr noisePsd = Create (g_LrWpanSpectrumModel); + + static const double BOLTZMANN = 1.3803e-23; + // Nt is the power of thermal noise in W + double Nt = BOLTZMANN * 290.0; + // noise Floor (W) which accounts for thermal noise and non-idealities of the receiver + double noisePowerDensity = m_noiseFigure * Nt; + + 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] = 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; +} + + + + +} // namespace ns3 diff --git a/src/lr-wpan/model/lr-wpan-spectrum-value-helper.h b/src/lr-wpan/model/lr-wpan-spectrum-value-helper.h new file mode 100644 index 000000000..30ecb4414 --- /dev/null +++ b/src/lr-wpan/model/lr-wpan-spectrum-value-helper.h @@ -0,0 +1,59 @@ +/* -*- 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_SPECTRUM_VALUE_HELPER_H +#define LR_WPAN_SPECTRUM_VALUE_HELPER_H + +#include +#include + +namespace ns3 { + +/** + * \brief This class defines all functions to create spectrum model for LrWpan + */ +class LrWpanSpectrumValueHelper +{ +public: + LrWpanSpectrumValueHelper (); + virtual ~LrWpanSpectrumValueHelper (); + + /** + * \brief create spectrum value + * \param txPower the power transmission in dBm + * \param channel the channel number per IEEE802.15.4 + * \return a Ptr to a newly created SpectrumValue instance + */ + Ptr CreateTxPowerSpectralDensity (double txPower, uint32_t channel); + + /** + * \brief create spectrum value for noise + * \param channel the channel number per IEEE802.15.4 + * \return a Ptr to a newly created SpectrumValue instance + */ + Ptr CreateNoisePowerSpectralDensity (uint32_t channel); + +private: + double m_noiseFigure; + +}; + +} //namespace ns3 + +#endif /* LR_WPAN_SPECTRUM_VALUE_HELPER_H */ diff --git a/src/lr-wpan/model/wpan-address.cc b/src/lr-wpan/model/wpan-address.cc new file mode 100644 index 000000000..541f08553 --- /dev/null +++ b/src/lr-wpan/model/wpan-address.cc @@ -0,0 +1,68 @@ +/* -*- 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 new file mode 100644 index 000000000..fb75b6e24 --- /dev/null +++ b/src/lr-wpan/model/wpan-address.h @@ -0,0 +1,53 @@ +/* -*- 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 new file mode 100644 index 000000000..c800106de --- /dev/null +++ b/src/lr-wpan/model/wpan-spectrum-propagation-loss-model.cc @@ -0,0 +1,91 @@ +/* -*- 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 new file mode 100644 index 000000000..18477155d --- /dev/null +++ b/src/lr-wpan/model/wpan-spectrum-propagation-loss-model.h @@ -0,0 +1,58 @@ +/* -*- 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-packet-test.cc b/src/lr-wpan/test/lr-wpan-packet-test.cc new file mode 100644 index 000000000..7bc8a8016 --- /dev/null +++ b/src/lr-wpan/test/lr-wpan-packet-test.cc @@ -0,0 +1,146 @@ +/* -*- 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 + * + */ + +#include +#include +#include +#include +#include +#include "ns3/log.h" + + +NS_LOG_COMPONENT_DEFINE ("lr-wpan-packet-test"); + +using namespace ns3; + +// This is an example TestCase. +class LrWpanPacketTestCase : public TestCase +{ +public: + LrWpanPacketTestCase (); + virtual ~LrWpanPacketTestCase (); + +private: + virtual void DoRun (void); +}; + +LrWpanPacketTestCase::LrWpanPacketTestCase () + : TestCase ("Test the 802.15.4 MAC header/trailer classes") +{ +} + +LrWpanPacketTestCase::~LrWpanPacketTestCase () +{ +} + +void +LrWpanPacketTestCase::DoRun (void) +{ + + //Packet::EnablePrinting(); + //Packet::EnableChecking(); + LrWpanMacHeader macHdr (LrWpanMacHeader::LRWPAN_MAC_BEACON, 0); //sequence number set to 0 + macHdr.SetSrcAddrMode (LrWpanMacHeader::SHORTADDR); // short addr + macHdr.SetDstAddrMode (LrWpanMacHeader::NOADDR); + macHdr.SetSecDisable (); + macHdr.SetNoPanIdComp (); + //macHdr.SetSrcAddrMode(3); // ext addr + // ... other setters + //macHdr.SetDstAddrMode(3); // ext addr + + uint16_t shortAddr = 66; + //uint64_t extAddr = 77; + uint16_t srcPanId = 100; + WpanAddress srcWpanAddr; + /*uint16_t dstPanId = 200; + WpanAddress dstWpanAddr;*/ + + srcWpanAddr.SetAddress (shortAddr); + //srcWpanAddr.SetAddress(extAddr); + macHdr.SetSrcAddrFields (srcPanId,srcWpanAddr ); + /*dstWpanAddr.SetAddress(extAddr); + macHdr.SetDstAddrFields(dstPanId,dstWpanAddr );*/ + + macHdr.Print (std::cout); + std::cout << " <--Mac Header created " << std::endl; + + + LrWpanMacTrailer macTrailer; + + + Ptr p = Create (20); // 20 bytes of dummy data + NS_TEST_ASSERT_MSG_EQ (p->GetSize (), 20, "Packet created with unexpected size"); + p->AddHeader (macHdr); + std::cout << " <--Mac Header added " << std::endl; + + NS_TEST_ASSERT_MSG_EQ (p->GetSize (), 27, "Packet wrong size after macHdr addition"); + p->AddTrailer (macTrailer); + NS_TEST_ASSERT_MSG_EQ (p->GetSize (), 29, "Packet wrong size after macTrailer addition"); + + + p->Print (std::cout); + std::cout << " <--Packet P" << std::endl; + + + // Test serialization and deserialization + uint32_t size = p->GetSerializedSize (); + uint8_t buffer[size]; + p->Serialize (buffer, size); + Ptr p2 = Create (buffer, size, true); + + + p2->Print (std::cout); + std::cout << " <--Packet P2 " << std::endl; + + + NS_TEST_ASSERT_MSG_EQ (p2->GetSize (), 29, "Packet wrong size after deserialization"); + + + LrWpanMacHeader receivedMacHdr; + p2->RemoveHeader (receivedMacHdr); + + receivedMacHdr.Print (std::cout); + std::cout << " <--P2 Mac Header " << std::endl; + + NS_LOG_UNCOND ("Src Addr Mode" << receivedMacHdr.GetSrcAddrMode () ); + + + NS_TEST_ASSERT_MSG_EQ (p2->GetSize (), 22, "Packet wrong size after removing machdr"); + + LrWpanMacTrailer receivedMacTrailer; + p2->RemoveTrailer (receivedMacTrailer); + NS_TEST_ASSERT_MSG_EQ (p2->GetSize (), 20, "Packet wrong size after removing headers and trailers"); + // Compare macHdr with receivedMacHdr, macTrailer with receivedMacTrailer,... + +} + +// ============================================================================== +class LrWpanPacketTestSuite : public TestSuite +{ +public: + LrWpanPacketTestSuite (); +}; + +LrWpanPacketTestSuite::LrWpanPacketTestSuite () + : TestSuite ("lr-wpan-packet", UNIT) +{ + AddTestCase (new LrWpanPacketTestCase); +} + +static LrWpanPacketTestSuite lrWpanPacketTestSuite; 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 new file mode 100644 index 000000000..fc3190531 --- /dev/null +++ b/src/lr-wpan/test/lr-wpan-pd-plme-sap-test.cc @@ -0,0 +1,99 @@ +/* -*- 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 +#include +#include +#include +#include +#include + +using namespace ns3; + +// This is an example TestCase. +class LrWpanPlmeAndPdInterfaceTestCase : public TestCase +{ +public: + LrWpanPlmeAndPdInterfaceTestCase (); + virtual ~LrWpanPlmeAndPdInterfaceTestCase (); + +private: + virtual void DoRun (void); + void ReceivePdDataInndication (uint32_t psduLength, Ptr p, uint32_t lqi); +}; + +LrWpanPlmeAndPdInterfaceTestCase::LrWpanPlmeAndPdInterfaceTestCase () + : TestCase ("Test the PLME and PD SAP per IEEE 802.15.4") +{ +} + +LrWpanPlmeAndPdInterfaceTestCase::~LrWpanPlmeAndPdInterfaceTestCase () +{ +} + +void +LrWpanPlmeAndPdInterfaceTestCase::ReceivePdDataInndication (uint32_t psduLength, + Ptr p, + uint32_t lqi) +{ + NS_LOG_UNCOND ("At: " << Simulator::Now () + << " Received frame size: " << psduLength << " LQI: " << + lqi); +} + +void +LrWpanPlmeAndPdInterfaceTestCase::DoRun (void) +{ + LogComponentEnableAll (LOG_PREFIX_FUNC); + LogComponentEnable ("LrWpanPhy", LOG_LEVEL_ALL); + + Ptr sender = CreateObject (); + Ptr receiver = CreateObject (); + + Ptr channel = CreateObject (); + sender->SetChannel (channel); + receiver->SetChannel (channel); + + receiver->SetPdDataIndicationCallback (MakeCallback ( + &LrWpanPlmeAndPdInterfaceTestCase::ReceivePdDataInndication, + this)); + + uint32_t n = 10; + Ptr p = Create (n); + sender->PdDataRequest (p->GetSize (), p); + + Simulator::Destroy (); +} + +// ============================================================================== +class LrWpanPlmeAndPdInterfaceTestSuite : public TestSuite +{ +public: + LrWpanPlmeAndPdInterfaceTestSuite (); +}; + +LrWpanPlmeAndPdInterfaceTestSuite::LrWpanPlmeAndPdInterfaceTestSuite () + : TestSuite ("lr-wpan-plme-pd-sap", UNIT) +{ + AddTestCase (new LrWpanPlmeAndPdInterfaceTestCase); +} + +// Do not forget to allocate an instance of this TestSuite +static LrWpanPlmeAndPdInterfaceTestSuite lrWpanPlmeAndPdInterfaceTestSuite; diff --git a/src/lr-wpan/wscript b/src/lr-wpan/wscript new file mode 100644 index 000000000..d52cb0a24 --- /dev/null +++ b/src/lr-wpan/wscript @@ -0,0 +1,35 @@ +## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- + +def build(bld): + obj = bld.create_ns3_module('lr-wpan', ['core', 'network', 'spectrum']) + obj.source = [ + 'model/lr-wpan-error-rate-model.cc', + 'model/lr-wpan-phy.cc', + 'model/lr-wpan-mac.cc', + 'model/lr-wpan-mac-header.cc', + 'model/lr-wpan-mac-trailer.cc', + 'model/lr-wpan-csmaca.cc', + 'model/wpan-address.cc', + 'model/wpan-spectrum-propagation-loss-model.cc', + 'model/lr-wpan-spectrum-value-helper.cc', + 'test/lr-wpan-pd-plme-sap-test.cc', + 'test/lr-wpan-packet-test.cc', + 'helper/lr-wpan-helper.cc', + ] + headers = bld.new_task_gen('ns3header') + headers.module = 'lr-wpan' + headers.source = [ + 'model/lr-wpan-error-rate-model.h', + 'model/lr-wpan-phy.h', + 'model/lr-wpan-mac.h', + 'model/lr-wpan-mac-header.h', + 'model/lr-wpan-mac-trailer.h', + 'model/lr-wpan-csmaca.h', + 'model/wpan-address.h', + 'model/wpan-spectrum-propagation-loss-model.h', + 'model/lr-wpan-spectrum-value-helper.h', + 'helper/lr-wpan-helper.h', + ] + if (bld.env['ENABLE_EXAMPLES']): + bld.add_subdirs('examples') +