Initial lr-wpan checkin

This commit is contained in:
Tom Henderson committed 2011-05-29 14:38:53 -07:00
1 parent 6318da07a6
commit 7e4b11dade
28 files changed
+4798

No files matched your search

+176
View File
@@ -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*).
+131
View File
@@ -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 <ns3/single-model-spectrum-channel.h>
#include <ns3/constant-position-mobility-model.h>
#include <iostream>
using namespace ns3;
static void DataIndication (Ptr<Packet> 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<LrWpanMac> mac0 = CreateObject<LrWpanMac> ();
Ptr<LrWpanMac> mac1 = CreateObject<LrWpanMac> ();
Ptr<LrWpanPhy> phy0 = CreateObject<LrWpanPhy> ();
Ptr<LrWpanPhy> phy1 = CreateObject<LrWpanPhy> ();
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<LrWpanCsmaCa> csmaca0 = CreateObject<LrWpanCsmaCa> ();
mac0->SetCsmaCa (csmaca0);
csmaca0->SetMac (mac0);
Ptr<LrWpanCsmaCa> csmaca1 = CreateObject<LrWpanCsmaCa> ();
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<SingleModelSpectrumChannel> channel = CreateObject<SingleModelSpectrumChannel> ();
phy0->SetChannel (channel);
phy1->SetChannel (channel);
channel->AddRx (phy0);
channel->AddRx (phy1);
// CONFIGURE MOBILITY
Ptr<ConstantPositionMobilityModel> senderMobility = CreateObject<ConstantPositionMobilityModel> ();
phy0->SetMobility (senderMobility);
Ptr<ConstantPositionMobilityModel> receiverMobility = CreateObject<ConstantPositionMobilityModel> ();
phy1->SetMobility (receiverMobility);
McpsDataConfirmCallback cb0;
cb0 = MakeCallback (&DataConfirm);
mac0->SetMcpsDataConfirmCallback (cb0);
McpsDataIndicationCallback cb1;
cb1 = MakeCallback (&DataIndication);
mac1->SetMcpsDataIndicationCallback (cb1);
Ptr<Packet> p = Create<Packet> (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;
}
@@ -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 <iostream>
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<Packet> p = Create<Packet> (20); // 20 bytes of dummy data
p->AddHeader (macHdr);
p->AddTrailer (macTrailer);
p->Print (std::cout);
std::cout << std::endl;
return 0;
}
+94
View File
@@ -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 <guangyu.pei@boeing.com>
*/
#include <ns3/log.h>
#include <ns3/test.h>
#include <ns3/lr-wpan-phy.h>
#include <ns3/lr-wpan-mac.h>
#include <ns3/simulator.h>
#include <ns3/single-model-spectrum-channel.h>
#include <ns3/constant-position-mobility-model.h>
using namespace ns3;
void GetSetTRXStateConfirm (LrWpanPhyEnumeration status)
{
NS_LOG_UNCOND ("At: " << Simulator::Now ()
<< " Received Set TRX Confirm: " << status);
}
void
ReceivePdDataIndication (uint32_t psduLength,
Ptr<Packet> p,
uint32_t lqi)
{
NS_LOG_UNCOND ("At: " << Simulator::Now ()
<< " Received frame size: " << psduLength << " LQI: " <<
lqi);
}
void SendOnePacket (Ptr<LrWpanPhy> sender, Ptr<LrWpanPhy> receiver)
{
uint32_t n = 10;
Ptr<Packet> p = Create<Packet> (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<LrWpanPhy> sender = CreateObject<LrWpanPhy> ();
Ptr<LrWpanPhy> receiver = CreateObject<LrWpanPhy> ();
Ptr<SingleModelSpectrumChannel> channel = CreateObject<SingleModelSpectrumChannel> ();
sender->SetChannel (channel);
receiver->SetChannel (channel);
channel->AddRx (sender);
channel->AddRx (receiver);
// CONFIGURE MOBILITY
Ptr<ConstantPositionMobilityModel> senderMobility = CreateObject<ConstantPositionMobilityModel> ();
sender->SetMobility (senderMobility);
Ptr<ConstantPositionMobilityModel> receiverMobility = CreateObject<ConstantPositionMobilityModel> ();
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;
}
+11
View File
@@ -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'
+92
View File
@@ -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 <guangyu.pei@boeing.com>
*/
#include "lr-wpan-helper.h"
#include "ns3/log.h"
NS_LOG_COMPONENT_DEFINE ("LrWpanHelper");
namespace ns3 {
LrWpanHelper::LrWpanHelper (void)
{
m_channel = CreateObject<SingleModelSpectrumChannel> ();
Ptr<WpanSpectrumPropagationLossModel> model = CreateObject<WpanSpectrumPropagationLossModel> ();
m_channel->AddSpectrumPropagationLossModel (model);
}
LrWpanHelper::~LrWpanHelper (void)
{
m_channel = 0;
}
void
LrWpanHelper::AddMobility (Ptr<LrWpanPhy> phy, Ptr<MobilityModel> m)
{
phy->SetMobility (m);
}
NetDeviceContainer
LrWpanHelper::Install (NodeContainer c)
{
NetDeviceContainer devices;
for (NodeContainer::Iterator i = c.Begin (); i != c.End (); i++)
{
Ptr<Node> node = *i;
Ptr<LrWpanMac> mac = CreateObject<LrWpanMac> ();
Ptr<LrWpanPhy> phy = CreateObject<LrWpanPhy> ();
Ptr<LrWpanCsmaCa> csmaca = CreateObject<LrWpanCsmaCa> ();
// 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
+76
View File
@@ -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 <guangyu.pei@boeing.com>
*/
#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<LrWpanPhy> phy, Ptr<MobilityModel>m);
/**
* \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<SingleModelSpectrumChannel> m_channel;
};
}
#endif /* LR_WPAN_HELPER_H */
+339
View File
@@ -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 <kwong-sang.yin@boeing.com>
*/
#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<Object> ()
.AddConstructor<LrWpanCsmaCa> ()
;
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<LrWpanMac> mac)
{
m_mac = mac;
}
Ptr<LrWpanMac>
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
+139
View File
@@ -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 <kwong-sang.yin@boeing.com>
*/
#ifndef LRWPANCSMACA_H
#define LRWPANCSMACA_H
#include <stdint.h>
#include "ns3/object.h"
#include "ns3/nstime.h"
#include "ns3/random-variable.h"
#include "ns3/packet.h"
#include "ns3/lr-wpan-phy.h"
#include "ns3/lr-wpan-mac.h"
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<LrWpanMac> mac);
Ptr<LrWpanMac> 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<LrWpanMac> 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 */
@@ -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 <guangyu.pei@boeing.com>
*/
#include "ns3/lr-wpan-error-rate-model.h"
#include "ns3/log.h"
NS_LOG_COMPONENT_DEFINE ("LrWpanErrorRateModel");
namespace ns3 {
NS_OBJECT_ENSURE_REGISTERED (LrWpanErrorRateModel);
TypeId
LrWpanErrorRateModel::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::LrWpanErrorRateModel")
.SetParent<Object> ()
.AddConstructor<LrWpanErrorRateModel> ()
;
return tid;
}
LrWpanErrorRateModel::LrWpanErrorRateModel ()
{
}
double
LrWpanErrorRateModel::GetChunkSuccessRate (double snr, uint32_t nbits) const
{
double ber = 0.0;
for (uint32_t k = 2; k <= 16; k++)
{
ber += pow (-1.0, (double) k) * BinomialCoefficient (k,16) * exp (20.0 * snr * (1.0 / k - 1.0));
}
ber = ber * 8.0 / 15.0 / 16.0;
ber = std::min (ber, 1.0);
double retval = pow (1.0 - ber, nbits);
return retval;
}
uint64_t
LrWpanErrorRateModel::Factorial (uint32_t k) const
{
uint64_t fact = 1;
while (k > 0)
{
fact *= k;
k--;
}
return fact;
}
uint32_t LrWpanErrorRateModel::BinomialCoefficient (uint32_t k, uint32_t n) const
{
uint32_t retval = Factorial (n) / Factorial (k) / Factorial (n - k);
return retval;
}
} // namespace ns3
@@ -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 <guangyu.pei@boeing.com>
*/
#ifndef LR_WPAN_ERROR_RATE_MODEL_H
#define LR_WPAN_ERROR_RATE_MODEL_H
#include <stdint.h>
#include <math.h>
#include "ns3/object.h"
namespace ns3 {
/**
* Model the error rate for IEEE 802.15.4 2.4 GHz AWGN channel for OQPSK
* the model description can be found in IEEE Std 802.15.4-2006, section
* E.4.1.7
*/
class LrWpanErrorRateModel : public Object
{
public:
static TypeId GetTypeId (void);
LrWpanErrorRateModel ();
double GetChunkSuccessRate (double snr, uint32_t nbits) const;
private:
uint64_t Factorial (uint32_t k) const;
uint32_t BinomialCoefficient (uint32_t k, uint32_t n) const;
};
} // namespace ns3
#endif /* LR_WPAN_ERROR_RATE_MODEL_H */
+824
View File
@@ -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 <kwong-sang.yin@boeing.com>
*/
#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<Header> ()
.AddConstructor<LrWpanMacHeader> ();
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
+231
View File
@@ -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 <kwong-sang.yin@boeing.com>
*/
/**
* 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 <stdint.h>
#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 */
// ----------------------------------------------------------------------------------------------------------
+60
View File
@@ -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<Trailer> ()
.AddConstructor<LrWpanMacTrailer> ()
;
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
+36
View File
@@ -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 <stdint.h>
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_ */
+204
View File
@@ -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 <guangyu.pei@boeing.com>
* kwong yin <kwong-sang.yin@boeing.com>
*/
#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<Object> ()
.AddConstructor<LrWpanMac> ()
;
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<Packet> > ();
m_mcpsDataConfirmCallback = MakeNullCallback< void, LrWpanMcpsDataConfirmStatus > ();
}
void
LrWpanMac::McpsDataRequest (Ptr<Packet> 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<LrWpanCsmaCa> csmaCa)
{
m_csmaCa = csmaCa;
}
void LrWpanMac::SetPhy (Ptr<LrWpanPhy> phy)
{
m_phy = phy;
}
Ptr<LrWpanPhy> 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<Packet> 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
+189
View File
@@ -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 <guangyu.pei@boeing.com>
* kwong yin <kwong-sang.yin@boeing.com>
*/
#ifndef LR_WPAN_MAC_H
#define LR_WPAN_MAC_H
#include <stdint.h>
#include <math.h>
#include "ns3/object.h"
#include "ns3/callback.h"
#include "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<Packet> > 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<Packet> p);
void SetCsmaCa (Ptr<LrWpanCsmaCa> csmaCa);
void SetPhy (Ptr<LrWpanPhy> phy);
Ptr<LrWpanPhy> 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<Packet> 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<LrWpanPhy> m_phy;
Ptr<LrWpanCsmaCa> m_csmaCa;
McpsDataIndicationCallback m_mcpsDataIndicationCallback;
McpsDataConfirmCallback m_mcpsDataConfirmCallback;
LrWpanMacState m_lrWpanMacState;
Ptr<Packet> m_txPkt; // XXX need packet buffer instead of single packet
};
} // namespace ns3
#endif /* LR_WPAN_MAC_H */
+859
View File
@@ -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 <guangyu.pei@boeing.com>
*/
#include "ns3/log.h"
#include <math.h>
#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<Object> ()
.AddConstructor<LrWpanPhy> ()
;
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 <Packet> 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<Packet>, 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<Object>
LrWpanPhy::GetDevice ()
{
NS_LOG_FUNCTION (this);
return m_device;
}
Ptr<Object>
LrWpanPhy::GetMobility ()
{
NS_LOG_FUNCTION (this);
return m_mobility;
}
void
LrWpanPhy::SetDevice (Ptr<Object> d)
{
NS_LOG_FUNCTION (this << d);
m_device = d;
}
void
LrWpanPhy::SetMobility (Ptr<Object> m)
{
NS_LOG_FUNCTION (this << m);
m_mobility = m;
}
void
LrWpanPhy::SetChannel (Ptr<SpectrumChannel> c)
{
NS_LOG_FUNCTION (this << c);
m_channel = c;
}
Ptr<SpectrumChannel>
LrWpanPhy::GetChannel (void)
{
return m_channel;
}
Ptr<const SpectrumModel>
LrWpanPhy::GetRxSpectrumModel () const
{
if (m_txPsd)
{
return m_txPsd->GetSpectrumModel ();
}
else
{
return 0;
}
}
void
LrWpanPhy::StartRx (Ptr<PacketBurst> pb, Ptr <const SpectrumValue> rxPsd, SpectrumType st, Time duration)
{
NS_LOG_FUNCTION (this << pb << rxPsd << st << duration);
if (st == GetSpectrumType ())
{
Ptr<Packet> 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<Packet> p = m_currentRxPacket.first;
m_pdDataIndicationCallback (p->GetSize (), p, 0);
}
}
void
LrWpanPhy::PdDataRequest (const uint32_t psduLength, Ptr<Packet> 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<PacketBurst> pb = CreateObject<PacketBurst> ();
pb->AddPacket (p);
m_channel->StartTx (pb, m_txPsd, GetSpectrumType (), txTime, GetObject<SpectrumPhy> ());
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 <aTurnaroundTime> 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<Packet> 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<const Packet> 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<SpectrumValue> 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<const SpectrumValue> noisePsd)
{
NS_LOG_FUNCTION (this << noisePsd);
NS_LOG_INFO ("\t computed noise_psd: " << *noisePsd );
NS_ASSERT (noisePsd);
m_noise = noisePsd;
}
Ptr<const SpectrumValue>
LrWpanPhy::GetNoisePowerSpectralDensity (void)
{
NS_LOG_FUNCTION (this);
return m_noise;
}
} // namespace ns3
+421
View File
@@ -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 <guangyu.pei@boeing.com>
*/
#ifndef LR_WPAN_PHY_H
#define LR_WPAN_PHY_H
#include <stdint.h>
#include <math.h>
#include <ns3/callback.h>
#include "ns3/object.h"
#include <ns3/packet-burst.h>
#include <ns3/spectrum-phy.h>
#include <ns3/spectrum-channel.h>
#include <ns3/spectrum-type.h>
#include <ns3/spectrum-interference.h>
#include <ns3/spectrum-value.h>
#include <ns3/lr-wpan-spectrum-value-helper.h>
#include <ns3/mobility-model.h>
#include <ns3/packet.h>
#include <ns3/nstime.h>
#include <ns3/net-device.h>
#include <ns3/event-id.h>
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<Packet>, 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<Ptr<Packet>, bool> PacketAndStatus;
static TypeId GetTypeId (void);
LrWpanPhy ();
virtual ~LrWpanPhy ();
// inherited from SpectrumPhy
void SetMobility (Ptr<Object> m);
Ptr<Object> GetMobility ();
void SetChannel (Ptr<SpectrumChannel> c);
Ptr<SpectrumChannel> GetChannel (void);
void SetDevice (Ptr<Object> d);
Ptr<Object> GetDevice ();
virtual Ptr<const SpectrumModel> 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<SpectrumValue> 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<const SpectrumValue> noisePsd);
/**
* \brief get the noise power spectral density
* @return the Noise Power Spectral Density
*/
Ptr<const SpectrumValue> 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<PacketBurst> p, Ptr <const SpectrumValue> 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<Packet> 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<Packet> 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<const Packet> packet);
double GetPpduHeaderTxTime (void);
bool ChannelSupported (uint8_t);
Ptr<Object> m_mobility;
Ptr<Object> m_device;
Ptr<SpectrumChannel> m_channel;
Ptr<SpectrumValue> m_txPsd;
Ptr<const SpectrumValue> m_rxPsd;
Ptr<const SpectrumValue> 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 */
@@ -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 <guangyu.pei@boeing.com>
*/
#include "lr-wpan-spectrum-value-helper.h"
namespace ns3 {
Ptr<SpectrumModel> 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<SpectrumModel> (bands);
}
} g_LrWpanSpectrumModelInitializerInstance;
LrWpanSpectrumValueHelper::LrWpanSpectrumValueHelper ()
{
m_noiseFigure = 1.0;
}
LrWpanSpectrumValueHelper::~LrWpanSpectrumValueHelper ()
{
}
Ptr<SpectrumValue>
LrWpanSpectrumValueHelper::CreateTxPowerSpectralDensity (double txPower, uint32_t channel)
{
Ptr<SpectrumValue> txPsd = Create <SpectrumValue> (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<SpectrumValue>
LrWpanSpectrumValueHelper::CreateNoisePowerSpectralDensity (uint32_t channel)
{
Ptr<SpectrumValue> noisePsd = Create <SpectrumValue> (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
@@ -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 <guangyu.pei@boeing.com>
*/
#ifndef LR_WPAN_SPECTRUM_VALUE_HELPER_H
#define LR_WPAN_SPECTRUM_VALUE_HELPER_H
#include <ns3/spectrum-value.h>
#include <cmath>
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<SpectrumValue> 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<SpectrumValue> CreateNoisePowerSpectralDensity (uint32_t channel);
private:
double m_noiseFigure;
};
} //namespace ns3
#endif /* LR_WPAN_SPECTRUM_VALUE_HELPER_H */
+68
View File
@@ -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 <kwong-sang.yin@boeing.com>
*/
#include "ns3/wpan-address.h"
namespace ns3 {
WpanAddress::WpanAddress ()
{
}
WpanAddress::WpanAddress (uint16_t addr)
{
SetAddress (addr);
}
WpanAddress::WpanAddress (uint64_t addr)
{
SetAddress (addr);
}
WpanAddress::~WpanAddress ()
{
}
void WpanAddress::SetAddress (uint64_t addr)
{
m_addr64 = addr;
}
void WpanAddress::SetAddress (uint16_t addr)
{
m_addr16 = addr;
}
uint16_t WpanAddress::GetShortAddress (void) const
{
return(m_addr16);
}
uint64_t WpanAddress::GetExtAddress (void) const
{
return(m_addr64);
}
} // namespace ns3
+53
View File
@@ -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 <kwong-sang.yin@boeing.com>
*/
#ifndef WPANADDRESS_H_
#define WPANADDRESS_H_
#include <stdint.h>
namespace ns3 {
class WpanAddress
{
public:
WpanAddress ();
WpanAddress (uint16_t addr);
WpanAddress (uint64_t addr);
~WpanAddress ();
void SetAddress (uint64_t addr);
void SetAddress (uint16_t addr);
uint16_t GetShortAddress (void) const;
uint64_t GetExtAddress (void) const;
private:
union
{
uint64_t m_addr64; //8 octet for ext addr
uint16_t m_addr16; //2 octet for short addr
};
};
} //namespace ns3
#endif /* WPANADDRESS_H_ */
@@ -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 <guangyu.pei@boeing.com>
*/
#include <ns3/mobility-model.h>
#include <ns3/wpan-spectrum-propagation-loss-model.h>
#include <math.h>
namespace ns3 {
NS_OBJECT_ENSURE_REGISTERED (WpanSpectrumPropagationLossModel);
WpanSpectrumPropagationLossModel::WpanSpectrumPropagationLossModel ()
{
m_simpleLossModel = 0;
}
WpanSpectrumPropagationLossModel::~WpanSpectrumPropagationLossModel ()
{
m_simpleLossModel = 0;
}
TypeId
WpanSpectrumPropagationLossModel::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::WpanSpectrumPropagationLossModel")
.SetParent<SpectrumPropagationLossModel> ()
.AddConstructor<WpanSpectrumPropagationLossModel> ()
;
return tid;
}
Ptr<SpectrumValue>
WpanSpectrumPropagationLossModel::DoCalcRxPowerSpectralDensity (Ptr<const SpectrumValue> txPsd,
Ptr<const MobilityModel> a,
Ptr<const MobilityModel> b) const
{
Ptr<SpectrumValue> rxPsd = Copy<SpectrumValue> (txPsd);
Values::iterator vit = rxPsd->ValuesBegin ();
Bands::const_iterator fit = rxPsd->ConstBandsBegin ();
NS_ASSERT (a);
NS_ASSERT (b);
//double d = a->GetDistanceFrom (b);
while (vit != rxPsd->ValuesEnd ())
{
NS_ASSERT (fit != rxPsd->ConstBandsEnd ());
*vit /= CalculateLossFromSimpleLossModel (a, b); // Prx = Ptx / loss
++vit;
++fit;
}
return rxPsd;
}
double
WpanSpectrumPropagationLossModel::CalculateLossFromSimpleLossModel (Ptr<const MobilityModel> a,
Ptr<const MobilityModel> b) const
{
double loss = 1.0;
if (m_simpleLossModel)
{
loss = m_simpleLossModel->CalcRxPower (0.0, ConstCast<MobilityModel> (a), ConstCast<MobilityModel> (b));
loss = pow (10.0, loss / 10.0);
loss = 1.0 / loss;
}
return loss;
}
}
@@ -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 <guangyu.pei@boeing.com>
*/
#ifndef WPAN_SPECTRUM_PROPAGATION_LOSS_MODEL_H
#define WPAN_SPECTRUM_PROPAGATION_LOSS_MODEL_H
#include <ns3/spectrum-propagation-loss-model.h>
#include <ns3/propagation-loss-model.h>
namespace ns3 {
class MobilityModel;
/**
* \brief propagation loss model for WPAN that uses simple PropagationLossModel
*/
class WpanSpectrumPropagationLossModel : public SpectrumPropagationLossModel
{
public:
WpanSpectrumPropagationLossModel ();
~WpanSpectrumPropagationLossModel ();
static TypeId GetTypeId ();
virtual Ptr<SpectrumValue> DoCalcRxPowerSpectralDensity (Ptr<const SpectrumValue> txPsd,
Ptr<const MobilityModel> a,
Ptr<const MobilityModel> b) const;
private:
double CalculateLossFromSimpleLossModel (Ptr<const MobilityModel> a,
Ptr<const MobilityModel> b) const;
Ptr<PropagationLossModel> m_simpleLossModel;
};
}
#endif /* WPAN_SPECTRUM_PROPAGATION_LOSS_MODEL_H */
+146
View File
@@ -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 <ns3/test.h>
#include <ns3/packet.h>
#include <ns3/lr-wpan-mac-header.h>
#include <ns3/lr-wpan-mac-trailer.h>
#include <ns3/wpan-address.h>
#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<Packet> p = Create<Packet> (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<Packet> p2 = Create<Packet> (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;
@@ -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 <guangyu.pei@boeing.com>
*/
#include <ns3/log.h>
#include <ns3/test.h>
#include <ns3/lr-wpan-phy.h>
#include <ns3/lr-wpan-mac.h>
#include <ns3/simulator.h>
#include <ns3/single-model-spectrum-channel.h>
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<Packet> 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<Packet> 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<LrWpanPhy> sender = CreateObject<LrWpanPhy> ();
Ptr<LrWpanPhy> receiver = CreateObject<LrWpanPhy> ();
Ptr<SingleModelSpectrumChannel> channel = CreateObject<SingleModelSpectrumChannel> ();
sender->SetChannel (channel);
receiver->SetChannel (channel);
receiver->SetPdDataIndicationCallback (MakeCallback (
&LrWpanPlmeAndPdInterfaceTestCase::ReceivePdDataInndication,
this));
uint32_t n = 10;
Ptr<Packet> p = Create<Packet> (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;
+35
View File
@@ -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')