merged spectrum framework
authorNicola Baldo <nbaldo@cttc.es>
Fri, 11 Jun 2010 19:30:06 +0200
changeset 6349 4bab6b10a034
parent 6348 43e956769ceb
child 6350 2a88eb4e8dac
merged spectrum framework
examples/spectrum/adhoc-aloha-ideal-phy-with-microwave-oven.cc
examples/spectrum/adhoc-aloha-ideal-phy.cc
examples/spectrum/waf
examples/spectrum/wscript
src/common/friis-spectrum-propagation-loss.cc
src/common/friis-spectrum-propagation-loss.h
src/common/spectrum-converter.cc
src/common/spectrum-converter.h
src/common/spectrum-model.cc
src/common/spectrum-model.h
src/common/spectrum-propagation-loss-model.cc
src/common/spectrum-propagation-loss-model.h
src/common/spectrum-type.cc
src/common/spectrum-type.h
src/common/spectrum-value-test.cc
src/common/spectrum-value.cc
src/common/spectrum-value.h
src/common/wscript
src/devices/spectrum/aloha-noack-mac-header.cc
src/devices/spectrum/aloha-noack-mac-header.h
src/devices/spectrum/aloha-noack-net-device.cc
src/devices/spectrum/aloha-noack-net-device.h
src/devices/spectrum/half-duplex-ideal-phy.cc
src/devices/spectrum/half-duplex-ideal-phy.h
src/devices/spectrum/microwave-oven-spectrum-value-helper.cc
src/devices/spectrum/microwave-oven-spectrum-value-helper.h
src/devices/spectrum/multi-model-spectrum-channel.cc
src/devices/spectrum/multi-model-spectrum-channel.h
src/devices/spectrum/non-communicating-net-device.cc
src/devices/spectrum/non-communicating-net-device.h
src/devices/spectrum/single-model-spectrum-channel.cc
src/devices/spectrum/single-model-spectrum-channel.h
src/devices/spectrum/spectrum-analyzer.cc
src/devices/spectrum/spectrum-analyzer.h
src/devices/spectrum/spectrum-error-model.cc
src/devices/spectrum/spectrum-error-model.h
src/devices/spectrum/spectrum-interference-test.cc
src/devices/spectrum/spectrum-interference.cc
src/devices/spectrum/spectrum-interference.h
src/devices/spectrum/spectrum-model-300kHz-300GHz-log.cc
src/devices/spectrum/spectrum-model-300kHz-300GHz-log.h
src/devices/spectrum/spectrum-model-ism2400MHz-res1MHz.cc
src/devices/spectrum/spectrum-model-ism2400MHz-res1MHz.h
src/devices/spectrum/waveform-generator.cc
src/devices/spectrum/waveform-generator.h
src/devices/spectrum/wifi-spectrum-value-helper.cc
src/devices/spectrum/wifi-spectrum-value-helper.h
src/devices/spectrum/wscript
src/helper/adhoc-aloha-noack-ideal-phy-helper.cc
src/helper/adhoc-aloha-noack-ideal-phy-helper.h
src/helper/spectrum-analyzer-helper.cc
src/helper/spectrum-analyzer-helper.h
src/helper/spectrum-helper.cc
src/helper/spectrum-helper.h
src/helper/waveform-generator-helper.cc
src/helper/waveform-generator-helper.h
src/helper/wscript
src/node/phy-mac.h
src/node/spectrum-channel.cc
src/node/spectrum-channel.h
src/node/spectrum-phy.cc
src/node/spectrum-phy.h
src/node/wscript
src/wscript
test.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/spectrum/adhoc-aloha-ideal-phy-with-microwave-oven.cc	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,266 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+
+
+#include <iostream>
+
+#include <ns3/core-module.h>
+#include <ns3/common-module.h>
+#include <ns3/node-module.h>
+#include <ns3/simulator-module.h>
+#include <ns3/spectrum-model-ism2400MHz-res1MHz.h>
+#include <ns3/spectrum-model-300kHz-300GHz-log.h>
+#include <ns3/wifi-spectrum-value-helper.h>
+#include <ns3/multi-model-spectrum-channel.h>
+#include <ns3/waveform-generator.h>
+#include <ns3/spectrum-analyzer.h>
+#include <ns3/log.h>
+#include <string>
+#include <ns3/friis-spectrum-propagation-loss.h>
+#include <ns3/propagation-delay-model.h>
+#include <ns3/mobility-module.h>
+#include <ns3/spectrum-helper.h>
+#include <ns3/helper-module.h>
+#include <ns3/adhoc-aloha-noack-ideal-phy-helper.h>
+#include <ns3/waveform-generator-helper.h>
+#include <ns3/spectrum-analyzer-helper.h>
+#include <ns3/non-communicating-net-device.h>
+#include <ns3/microwave-oven-spectrum-value-helper.h>
+
+NS_LOG_COMPONENT_DEFINE ("OfdmWithWaveformGenerator");
+
+using namespace ns3;
+
+static bool g_verbose = false;
+
+
+void
+PhyTxStartTrace (std::string context, Ptr<const Packet> p)
+{  
+  if (g_verbose)
+    {
+      std::cout << context << " PHY TX START p: " << p << std::endl;
+    }
+}
+
+
+void
+PhyTxEndTrace (std::string context, Ptr<const Packet> p)
+{  
+  if (g_verbose)
+    {
+      std::cout << context << " PHY TX END p: " << p << std::endl;
+    }
+}
+
+void
+PhyRxStartTrace (std::string context, Ptr<const Packet> p)
+{
+  if (g_verbose)
+    {
+      std::cout << context << " PHY RX START p:" << p << std::endl; 
+    }
+}
+
+void
+PhyRxEndOkTrace (std::string context, Ptr<const Packet> p)
+{
+  if (g_verbose)
+    {
+      std::cout << context << " PHY RX END OK p:" << p << std::endl; 
+    }
+}
+
+void
+PhyRxEndErrorTrace (std::string context, Ptr<const Packet> p)
+{
+  if (g_verbose)
+    {
+      std::cout << context << " PHY RX END ERROR p:" << p << std::endl; 
+    }
+}
+
+
+void
+ReceivePacket (Ptr<Socket> socket)
+{
+  Ptr<Packet> packet;
+  uint64_t bytes = 0;
+  while (packet = socket->Recv ())
+    {
+      bytes += packet->GetSize ();
+    }
+  if (g_verbose)
+    {
+      std::cout << "SOCKET received " << bytes << " bytes" <<std::endl; 
+    }
+}
+
+Ptr<Socket>
+SetupPacketReceive (Ptr<Node> node)
+{
+  TypeId tid = TypeId::LookupByName ("ns3::PacketSocketFactory");
+  Ptr<Socket> sink = Socket::CreateSocket (node, tid);
+  sink->Bind ();
+  sink->SetRecvCallback (MakeCallback (&ReceivePacket));
+  return sink;
+}
+
+int main (int argc, char** argv)
+{
+  CommandLine cmd;
+  cmd.AddValue ("verbose", "Print trace information if true", g_verbose);
+  cmd.Parse (argc, argv);
+  
+  NodeContainer ofdmNodes;
+  NodeContainer waveformGeneratorNodes;
+  NodeContainer spectrumAnalyzerNodes;
+  NodeContainer allNodes;
+  
+  ofdmNodes.Create (2);
+  waveformGeneratorNodes.Create (1);
+  spectrumAnalyzerNodes.Create (1);
+  allNodes.Add (ofdmNodes);
+  allNodes.Add (waveformGeneratorNodes);
+  allNodes.Add (spectrumAnalyzerNodes);
+
+  MobilityHelper mobility;
+  Ptr<ListPositionAllocator> nodePositionList = CreateObject<ListPositionAllocator> ();
+  nodePositionList->Add (Vector (5.0, 0.0, 0.0));  // TX node
+  nodePositionList->Add (Vector (0.0, 0.0, 0.0));  // RX node
+  nodePositionList->Add (Vector (10.0, 0.0, 0.0)); // Microwave Oven
+  nodePositionList->Add (Vector (0.0, 0.0, 0.0));  // Spectrum Analyzer
+  mobility.SetPositionAllocator (nodePositionList);
+  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
+
+  mobility.Install (allNodes);
+
+   
+  SpectrumChannelHelper channelHelper = SpectrumChannelHelper::Default ();
+  channelHelper.SetChannel ("ns3::MultiModelSpectrumChannel");
+  Ptr<SpectrumChannel> channel = channelHelper.Create ();
+
+
+  /////////////////////////
+  // Configure ofdm nodes
+  ////////////////////////
+
+  WifiSpectrumValue5MhzFactory sf;
+
+  double txPower = 0.1; // Watts
+  uint32_t channelNumber = 2;
+  Ptr<SpectrumValue> txPsd =  sf.CreateTxPowerSpectralDensity (txPower, channelNumber);  
+  
+  // for the noise, we use the Power Spectral Density of thermal noise
+  // at room temperature. The value of the PSD will be constant over the band of interest.  
+  const double k = 1.381e-23; //Boltzmann's constant
+  const double T = 290; // temperature in Kelvin
+  double noisePsdValue = k*T; // watts per hertz
+  Ptr<SpectrumValue> noisePsd = sf.CreateConstant (noisePsdValue); 
+  
+
+  AdhocAlohaNoackIdealPhyHelper adhocAlohaOfdmHelper;
+  adhocAlohaOfdmHelper.SetChannel(channel);
+  adhocAlohaOfdmHelper.SetTxPowerSpectralDensity (txPsd);
+  adhocAlohaOfdmHelper.SetNoisePowerSpectralDensity (noisePsd);
+  adhocAlohaOfdmHelper.SetPhyAttribute ("Rate", DataRateValue (DataRate ("1Mbps")));
+  NetDeviceContainer ofdmDevices = adhocAlohaOfdmHelper.Install (ofdmNodes);
+
+  PacketSocketHelper packetSocket;
+  packetSocket.Install (ofdmNodes);
+
+  PacketSocketAddress socket;
+  socket.SetSingleDevice(ofdmDevices.Get (0)->GetIfIndex ());
+  socket.SetPhysicalAddress (ofdmDevices.Get (1)->GetAddress ());
+  socket.SetProtocol (1);
+
+  OnOffHelper onoff ("ns3::PacketSocketFactory", Address (socket));
+  onoff.SetAttribute ("OnTime", RandomVariableValue (ExponentialVariable (0.4)));
+  onoff.SetAttribute ("OffTime", RandomVariableValue (ExponentialVariable (0.1)));
+  onoff.SetAttribute ("DataRate", DataRateValue (DataRate ("0.4Mbps")));
+  onoff.SetAttribute ("PacketSize", UintegerValue (1500));
+
+  ApplicationContainer apps = onoff.Install (ofdmNodes.Get (0));
+  apps.Start (Seconds (0.0));
+  apps.Stop (Seconds (2));
+  
+  Ptr<Socket> recvSink = SetupPacketReceive (ofdmNodes.Get (1));
+
+
+
+
+  
+  /////////////////////////////////
+  // Configure waveform generator
+  /////////////////////////////////
+
+  Ptr<SpectrumValue> mwoPsd =  MicrowaveOvenSpectrumValueHelper::CreatePowerSpectralDensityMwo1 ();
+  NS_LOG_INFO ("mwoPsd : " << *mwoPsd);
+
+  WaveformGeneratorHelper waveformGeneratorHelper;
+  waveformGeneratorHelper.SetChannel(channel);
+  waveformGeneratorHelper.SetTxPowerSpectralDensity (mwoPsd);
+
+  waveformGeneratorHelper.SetPhyAttribute ("Period", TimeValue(Seconds(1.0/60)));   // corresponds to 60 Hz 
+  waveformGeneratorHelper.SetPhyAttribute ("DutyCycle", DoubleValue(0.5));
+  NetDeviceContainer waveformGeneratorDevices = waveformGeneratorHelper.Install (waveformGeneratorNodes);
+  
+  Simulator::Schedule(Seconds(0.1), &WaveformGenerator::Start, 
+  		      waveformGeneratorDevices.Get (0)->GetObject<NonCommunicatingNetDevice> ()->GetPhy ()->GetObject<WaveformGenerator> ());
+
+
+  
+  /////////////////////////////////
+  // Configure spectrum analyzer
+  /////////////////////////////////
+
+
+  SpectrumAnalyzerHelper spectrumAnalyzerHelper;
+  spectrumAnalyzerHelper.SetChannel(channel);
+  spectrumAnalyzerHelper.SetRxSpectrumModel (SpectrumModelIsm2400MhzRes1Mhz);
+  spectrumAnalyzerHelper.SetPhyAttribute ("Resolution", TimeValue(MilliSeconds (2)));   
+  spectrumAnalyzerHelper.SetPhyAttribute ("NoisePowerSpectralDensity", DoubleValue (1e-15));  // -120 dBm/Hz
+  spectrumAnalyzerHelper.EnableAsciiAll ("spectrum-analyzer-output");   
+  NetDeviceContainer spectrumAnalyzerDevices = spectrumAnalyzerHelper.Install (spectrumAnalyzerNodes);
+
+
+
+
+
+
+  Config::Connect ("/NodeList/*/DeviceList/*/Phy/TxStart", MakeCallback (&PhyTxStartTrace));
+  Config::Connect ("/NodeList/*/DeviceList/*/Phy/TxEnd", MakeCallback (&PhyTxEndTrace));
+  Config::Connect ("/NodeList/*/DeviceList/*/Phy/RxStart", MakeCallback (&PhyRxStartTrace));
+  Config::Connect ("/NodeList/*/DeviceList/*/Phy/RxEndOk", MakeCallback (&PhyRxEndOkTrace));
+  Config::Connect ("/NodeList/*/DeviceList/*/Phy/RxEndError", MakeCallback (&PhyRxEndErrorTrace));
+  
+
+
+
+Simulator::Stop (Seconds (0.3));
+
+Simulator::Run ();
+
+Simulator::Destroy ();
+
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/spectrum/adhoc-aloha-ideal-phy.cc	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,198 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+
+
+#include <iostream>
+
+#include <ns3/core-module.h>
+#include <ns3/common-module.h>
+#include <ns3/node-module.h>
+#include <ns3/simulator-module.h>
+#include <ns3/spectrum-model-ism2400MHz-res1MHz.h>
+#include <ns3/spectrum-model-300kHz-300GHz-log.h>
+#include <ns3/wifi-spectrum-value-helper.h>
+#include <ns3/single-model-spectrum-channel.h>
+#include <ns3/waveform-generator.h>
+#include <ns3/spectrum-analyzer.h>
+#include <ns3/log.h>
+#include <string>
+#include <ns3/friis-spectrum-propagation-loss.h>
+#include <ns3/propagation-delay-model.h>
+#include <ns3/mobility-module.h>
+#include <ns3/spectrum-helper.h>
+#include <ns3/helper-module.h>
+#include <ns3/adhoc-aloha-noack-ideal-phy-helper.h>
+
+NS_LOG_COMPONENT_DEFINE ("TestAdhocOfdmAloha");
+
+using namespace ns3;
+
+static bool g_verbose = false;
+
+void
+PhyTxStartTrace (std::string context, Ptr<const Packet> p)
+{  
+  if (g_verbose)
+    {
+      std::cout << context << " PHY TX START p: " << p << std::endl;
+    }
+}
+
+
+void
+PhyTxEndTrace (std::string context, Ptr<const Packet> p)
+{  
+  if (g_verbose)
+    {
+      std::cout << context << " PHY TX END p: " << p << std::endl;
+    }
+}
+
+void
+PhyRxStartTrace (std::string context, Ptr<const Packet> p)
+{
+  if (g_verbose)
+    {
+      std::cout << context << " PHY RX START p:" << p << std::endl; 
+    }
+}
+
+void
+PhyRxEndOkTrace (std::string context, Ptr<const Packet> p)
+{
+  if (g_verbose)
+    {
+      std::cout << context << " PHY RX END OK p:" << p << std::endl; 
+    }
+}
+
+void
+PhyRxEndErrorTrace (std::string context, Ptr<const Packet> p)
+{
+  if (g_verbose)
+    {
+      std::cout << context << " PHY RX END ERROR p:" << p << std::endl; 
+    }
+}
+
+
+void
+ReceivePacket (Ptr<Socket> socket)
+{
+  Ptr<Packet> packet;
+  uint64_t bytes = 0;
+  while (packet = socket->Recv ())
+    {
+      bytes += packet->GetSize ();
+    }
+  if (g_verbose)
+    {
+      std::cout << "SOCKET received " << bytes << " bytes" <<std::endl; 
+    }
+}
+
+Ptr<Socket>
+SetupPacketReceive (Ptr<Node> node)
+{
+  TypeId tid = TypeId::LookupByName ("ns3::PacketSocketFactory");
+  Ptr<Socket> sink = Socket::CreateSocket (node, tid);
+  sink->Bind ();
+  sink->SetRecvCallback (MakeCallback (&ReceivePacket));
+  return sink;
+}
+
+int main (int argc, char** argv)
+{
+  CommandLine cmd;
+  cmd.AddValue ("verbose", "Print trace information if true", g_verbose);
+  cmd.Parse (argc, argv);
+  
+  NodeContainer c;
+  c.Create (2);
+
+  MobilityHelper mobility;
+  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
+  positionAlloc->Add (Vector (0.0, 0.0, 0.0));
+  positionAlloc->Add (Vector (5.0, 0.0, 0.0));
+  mobility.SetPositionAllocator (positionAlloc);
+  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
+
+  mobility.Install (c);
+  
+   
+  SpectrumChannelHelper channelHelper = SpectrumChannelHelper::Default ();
+  Ptr<SpectrumChannel> channel = channelHelper.Create ();
+
+  WifiSpectrumValue5MhzFactory sf;
+
+  double txPower = 0.1; // Watts
+  uint32_t channelNumber = 1;
+  Ptr<SpectrumValue> txPsd =  sf.CreateTxPowerSpectralDensity (txPower, channelNumber);  
+  
+  // for the noise, we use the Power Spectral Density of thermal noise
+  // at room temperature. The value of the PSD will be constant over the band of interest.  
+  const double k = 1.381e-23; //Boltzmann's constant
+  const double T = 290; // temperature in Kelvin
+  double noisePsdValue = k*T; // watts per hertz
+  Ptr<SpectrumValue> noisePsd = sf.CreateConstant (noisePsdValue);   
+
+  AdhocAlohaNoackIdealPhyHelper deviceHelper;
+  deviceHelper.SetChannel(channel);
+  deviceHelper.SetTxPowerSpectralDensity (txPsd);
+  deviceHelper.SetNoisePowerSpectralDensity (noisePsd);
+  deviceHelper.SetPhyAttribute ("Rate", DataRateValue (DataRate ("1Mbps")));
+  NetDeviceContainer devices = deviceHelper.Install (c);
+
+  PacketSocketHelper packetSocket;
+  packetSocket.Install (c);
+
+  PacketSocketAddress socket;
+  socket.SetSingleDevice(devices.Get (0)->GetIfIndex ());
+  socket.SetPhysicalAddress (devices.Get (1)->GetAddress ());
+  socket.SetProtocol (1);
+
+  OnOffHelper onoff ("ns3::PacketSocketFactory", Address (socket));
+  onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (250)));
+  onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
+  onoff.SetAttribute ("DataRate", DataRateValue (DataRate ("0.5Mbps")));
+  onoff.SetAttribute ("PacketSize", UintegerValue (125));
+
+  ApplicationContainer apps = onoff.Install (c.Get (0));
+  apps.Start (Seconds (0.1));
+  apps.Stop (Seconds (0.104));
+  
+  Ptr<Socket> recvSink = SetupPacketReceive (c.Get (1));
+
+  Simulator::Stop (Seconds (10.0));
+
+  Config::Connect ("/NodeList/*/DeviceList/*/Phy/TxStart", MakeCallback (&PhyTxStartTrace));
+  Config::Connect ("/NodeList/*/DeviceList/*/Phy/TxEnd", MakeCallback (&PhyTxEndTrace));
+  Config::Connect ("/NodeList/*/DeviceList/*/Phy/RxStart", MakeCallback (&PhyRxStartTrace));
+  Config::Connect ("/NodeList/*/DeviceList/*/Phy/RxEndOk", MakeCallback (&PhyRxEndOkTrace));
+  Config::Connect ("/NodeList/*/DeviceList/*/Phy/RxEndError", MakeCallback (&PhyRxEndErrorTrace));
+
+
+  Simulator::Run ();
+
+  Simulator::Destroy ();
+
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/spectrum/waf	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,1 @@
+exec "`dirname "$0"`"/../../waf "$@"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/spectrum/wscript	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,12 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+def build(bld):
+    obj = bld.create_ns3_program('adhoc-aloha-ideal-phy',
+                                 ['spectrum'])
+    obj.source = 'adhoc-aloha-ideal-phy.cc'
+
+    obj = bld.create_ns3_program('adhoc-aloha-ideal-phy-with-microwave-oven',
+                                 ['spectrum'])
+    obj.source = 'adhoc-aloha-ideal-phy-with-microwave-oven.cc'
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/friis-spectrum-propagation-loss.cc	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,108 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+
+#include <ns3/mobility-model.h>
+#include <ns3/friis-spectrum-propagation-loss.h>
+#include <math.h>
+
+
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (FriisSpectrumPropagationLossModel);
+
+
+FriisSpectrumPropagationLossModel::FriisSpectrumPropagationLossModel ()
+{
+}
+
+FriisSpectrumPropagationLossModel::~FriisSpectrumPropagationLossModel ()
+{
+}
+
+
+TypeId
+FriisSpectrumPropagationLossModel::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::FriisSpectrumPropagationLossModel")
+    .SetParent<SpectrumPropagationLossModel> ()
+    .AddConstructor<FriisSpectrumPropagationLossModel> ()
+  ;
+  return tid;
+}
+
+
+Ptr<SpectrumValue>
+FriisSpectrumPropagationLossModel::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 /= CalculateLoss (fit->fc, d); // Prx = Ptx / loss
+      ++vit;
+      ++fit;
+    }
+  return rxPsd;
+}
+
+
+double
+FriisSpectrumPropagationLossModel::CalculateLoss (double f, double d) const
+{
+  NS_ASSERT (d >= 0);
+
+  if (d == 0)
+    {
+      return 1;
+    }
+
+  NS_ASSERT (f > 0);
+  double loss = ( d * f * f) / ((3e8 * 3e8) / (4 * M_PI)) ;
+
+  if (loss < 1)
+    {
+      loss = 1;
+    }
+  return loss;
+}
+
+
+
+
+
+
+
+
+
+
+
+}  // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/friis-spectrum-propagation-loss.h	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,78 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#ifndef FRIIS_SPECTRUM_PROPAGATION_LOSS_H
+#define FRIIS_SPECTRUM_PROPAGATION_LOSS_H
+
+
+#include <ns3/spectrum-propagation-loss-model.h>
+
+
+namespace ns3 {
+
+class MobilityModel;
+
+
+class FriisSpectrumPropagationLossModel : public SpectrumPropagationLossModel
+{
+
+public:
+  FriisSpectrumPropagationLossModel ();
+  ~FriisSpectrumPropagationLossModel ();
+
+  static TypeId GetTypeId ();
+
+
+  virtual Ptr<SpectrumValue> DoCalcRxPowerSpectralDensity (Ptr<const SpectrumValue> txPower,
+                                                           Ptr<const MobilityModel> a,
+                                                           Ptr<const MobilityModel> b) const;
+
+
+  /**
+   * Return the propagation loss L according to a simplified version of Friis'
+   * formula in which antenna gains are unitary:
+   *
+   *         4 * pi * d * f^2
+   * L = ----------------------
+   *               C^2
+   *
+   * where C = 3e8 m/s is the light speed in the vacuum. The intended
+   * use is to calculate Prx = Ptx * G
+   *
+   * @param f frequency in Hz
+   * @param d distance in m
+   *
+   * @return if Prx < Ptx then return Prx; else return Ptx
+   */
+  double CalculateLoss (double f, double d) const;
+
+protected:
+  double m_propagationSpeed;
+
+};
+
+
+
+
+
+
+} // namespace ns3
+
+#endif /* FRIIS_SPECTRUM_PROPAGATION_LOSS_MODEL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/spectrum-converter.cc	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,107 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#include <ns3/spectrum-converter.h>
+#include <ns3/assert.h>
+#include <ns3/log.h>
+#include <algorithm>
+
+
+
+NS_LOG_COMPONENT_DEFINE ("SpectrumConverter");
+
+namespace ns3 {
+
+
+SpectrumConverter::SpectrumConverter (Ptr<const SpectrumModel> fromSpectrumModel, Ptr<const SpectrumModel> toSpectrumModel)
+{
+  NS_LOG_FUNCTION (this);
+  m_fromSpectrumModel = fromSpectrumModel;
+  m_toSpectrumModel = toSpectrumModel;
+
+  for (Bands::const_iterator toit = toSpectrumModel->Begin (); toit != toSpectrumModel->End (); ++toit)
+    {
+      std::vector<double> coeffs;
+
+      for (Bands::const_iterator fromit = fromSpectrumModel->Begin (); fromit != fromSpectrumModel->End (); ++fromit)
+        {
+          double c = GetCoefficient (*fromit, *toit);
+          NS_LOG_LOGIC ("(" << fromit->fl << ","  << fromit->fh << ")"
+                            << " --> " <<
+                        "(" << toit->fl << "," << toit->fh << ")"
+                            << " = " << c);
+          coeffs.push_back (c);
+        }
+
+      m_conversionMatrix.push_back (coeffs);
+    }
+
+}
+
+
+double SpectrumConverter::GetCoefficient (const BandInfo& from, const BandInfo& to) const
+{
+  NS_LOG_FUNCTION (this);
+  double coeff = std::min (from.fh, to.fh) - std::max (from.fl, to.fl);
+  coeff = std::max (0.0, coeff);
+  coeff = std::min (1.0, coeff / (to.fh - to.fl));
+  return coeff;
+}
+
+
+
+Ptr<SpectrumValue>
+SpectrumConverter::Convert (Ptr<const SpectrumValue> fvvf) const
+{
+  NS_ASSERT ( *(fvvf->GetSpectrumModel ()) == *m_fromSpectrumModel);
+
+  Ptr<SpectrumValue> tvvf = Create<SpectrumValue> (m_toSpectrumModel);
+
+  Values::iterator tvit = tvvf->ValuesBegin ();
+
+
+  for (std::vector<std::vector<double> >::const_iterator toit = m_conversionMatrix.begin ();
+       toit != m_conversionMatrix.end ();
+       ++toit)
+    {
+      NS_ASSERT (tvit != tvvf->ValuesEnd ());
+      Values::const_iterator fvit = fvvf->ConstValuesBegin ();
+
+      double sum = 0;
+      for (std::vector<double>::const_iterator fromit = toit->begin ();
+           fromit != toit->end ();
+           ++fromit)
+        {
+          NS_ASSERT (fvit != fvvf->ConstValuesEnd ());
+          sum += (*fvit) * (*fromit);
+          ++fvit;
+        }
+      *tvit = sum;
+      ++tvit;
+    }
+
+  return tvvf;
+}
+
+
+
+
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/spectrum-converter.h	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,91 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#ifndef SPECTRUM_CONVERTER_H
+#define SPECTRUM_CONVERTER_H
+
+#include <ns3/spectrum-value.h>
+
+
+namespace ns3 {
+
+/**
+ * Class which implements a converter between SpectrumValue which are
+ * defined over different SpectrumModel. In more formal terms, this class
+ * allows conversion between different function spaces. In practical
+ * terms, this allows you to mix different spectrum representation
+ * within the same channel, such as a device using a coarse spectrum
+ * representation (e.g., one frequency for each IEEE 802.11 channel)
+ * and devices using a finer representation (e.g., one frequency for
+ * each OFDM subcarrier).
+ *
+ */
+class SpectrumConverter : public SimpleRefCount<SpectrumConverter>
+{
+public:
+  /**
+   * Create a SpectrumConverter class that will be able to convert ValueVsFreq
+   * instances defined over one SpectrumModel to corresponding ValueVsFreq
+   * instances defined over a diffent SpectrumModel
+   *
+   * @param fromSpectrumModel the SpectrumModel to convert from
+   * @param toSpectrumModel the SpectrumModel to convert to
+   */
+  SpectrumConverter (Ptr<const SpectrumModel> fromSpectrumModel, Ptr<const SpectrumModel> toSpectrumModel);
+
+
+
+  /**
+   * Convert a particular ValueVsFreq instance to
+   *
+   * @param vvf the ValueVsFreq instance to be converted
+   *
+   * @return the converted version of the provided ValueVsFreq
+   */
+  Ptr<SpectrumValue> Convert (Ptr<const SpectrumValue> vvf) const;
+
+
+private:
+  /**
+   * Calculate the coefficient for value conversion between elements
+   *
+   * @param from BandInfo to convert from
+   * @param to  BandInfo to convert to
+   *
+   * @return the fraction of the value of the "from" BandInfos that is
+   * mapped to the "to" BandInfo
+   */
+  double GetCoefficient (const BandInfo& from, const BandInfo& to) const;
+
+  std::vector<std::vector<double> > m_conversionMatrix; // /< matrix of conversion coefficients
+  Ptr<const SpectrumModel> m_fromSpectrumModel;  // /<  the SpectrumModel this SpectrumConverter instance can convert from
+  Ptr<const SpectrumModel> m_toSpectrumModel;    // /<  the SpectrumModel this SpectrumConverter instance can convert to
+
+};
+
+
+
+} // namespace ns3
+
+
+
+#endif /*  SPECTRUM_CONVERTER_H */
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/spectrum-model.cc	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,108 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil;  -*- */
+
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#include <ns3/spectrum-model.h>
+#include <math.h>
+#include <ns3/log.h>
+#include <ns3/assert.h>
+
+
+
+NS_LOG_COMPONENT_DEFINE ("SpectrumModel");
+
+
+
+namespace ns3 {
+
+
+bool operator== (const SpectrumModel& lhs, const SpectrumModel& rhs)
+{
+  return (lhs.m_uid == rhs.m_uid);
+}
+
+SpectrumModelUid_t SpectrumModel::m_uidCount = 0;
+
+SpectrumModel::SpectrumModel (std::vector<double> centerFreqs)
+{
+  NS_ASSERT (centerFreqs.size () > 1);
+  m_uid = ++m_uidCount;
+
+  for (std::vector<double>::const_iterator it = centerFreqs.begin ();
+       it != centerFreqs.end ();
+       ++it)
+    {
+      BandInfo e;
+      e.fc = *it;
+      if (it ==  centerFreqs.begin ())
+        {
+          double delta = ((*(it + 1)) - (*it)) / 2;
+          e.fl =  *it - delta;
+          e.fh =  *it + delta;
+        }
+      else if (it == centerFreqs.end () - 1 )
+        {
+          double delta = ((*it) - (*(it - 1))) / 2;
+          e.fl  =  *it - delta;
+          e.fh =  *it + delta;
+        }
+      else
+        {
+          e.fl  = ((*it) + (*(it - 1))) / 2;
+          e.fh = ((*(it + 1)) + (*it)) / 2;
+        }
+      m_bands.push_back (e);
+    }
+}
+
+SpectrumModel::SpectrumModel (Bands bands)
+{
+  m_uid = ++m_uidCount;
+  NS_LOG_INFO ("creating new SpectrumModel, m_uid=" << m_uid);
+  m_bands = bands;
+}
+
+Bands::const_iterator
+SpectrumModel::Begin () const
+{
+  return m_bands.begin ();
+}
+
+Bands::const_iterator
+SpectrumModel::End () const
+{
+  return m_bands.end ();
+}
+
+size_t
+SpectrumModel::GetNumBands () const
+{
+  return m_bands.size ();
+}
+
+SpectrumModelUid_t
+SpectrumModel::GetUid () const
+{
+  return m_uid;
+}
+
+
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/spectrum-model.h	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,114 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#ifndef SPECTRUM_MODEL_H
+#define SPECTRUM_MODEL_H
+
+#include <ns3/simple-ref-count.h>
+#include <vector>
+
+namespace ns3 {
+
+
+
+/**
+ * The building block of a SpectrumModel. This struct models
+ * a frequency band defined by the frequency interval [fl, fc] and
+ * with center frequency fc. Typically, the center frequency will be
+ * used for stuff such as propagation modeling, while the interval
+ * boundaries will be used for bandwidth calculation and for
+ * conversion between different SpectrumRepresentations.
+ *
+ */
+struct BandInfo
+{
+  double fl; ///< lower limit of subband
+  double fc; ///< center frequency
+  double fh; ///< upper limit of subband
+};
+
+
+typedef std::vector<BandInfo> Bands;
+typedef uint32_t SpectrumModelUid_t;
+
+/**
+ * Set of frequency values implementing the domain of the functions in
+ * the Function Space defined by SpectrumValue. Frequency values are in
+ * Hz. It is intended that frequency values are non-negative, though
+ * this is not enforced.
+ *
+ */
+class SpectrumModel : public SimpleRefCount<SpectrumModel>
+{
+public:
+  friend bool operator== (const SpectrumModel& lhs, const SpectrumModel& rhs);
+
+  /**
+   * This constructs a SpectrumModel based on a given set of frequencies,
+   * which is assumed to be sorted by increasing frequency. The lower
+   * (resp. upper) frequency band limit is determined as the mean value
+   * between the center frequency of the considered band and the
+   * center frequency of the adjacent lower (resp. upper) band.
+   *
+   * @param centerFreqs the vector of center frequencies.
+   *
+   * @return
+   */
+  SpectrumModel (std::vector<double> centerFreqs);
+
+
+  /**
+   * This construct a SpectrumModel based on the explicit values of
+   * center frequencies and boundaries of each subband.
+   *
+   * @param bands
+   *
+   * @return
+   */
+  SpectrumModel (Bands bands);
+
+  /**
+   *
+   * @return the number of frequencies in this SpectrumModel
+   */
+  size_t GetNumBands () const;
+
+
+  /**
+   *
+   * @return the unique id of this SpectrumModel
+   */
+  SpectrumModelUid_t GetUid () const;
+
+
+  Bands::const_iterator Begin () const;
+  Bands::const_iterator End () const;
+
+private:
+  Bands m_bands;         ///< actual definition of frequency bands
+                         /// within this SpectrumModel
+  SpectrumModelUid_t m_uid;        ///< unique id for a given set of frequencies
+  static SpectrumModelUid_t m_uidCount;    ///< counter to assign m_uids
+};
+
+
+} // namespace ns3
+
+#endif /* SPECTRUM_MODEL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/spectrum-propagation-loss-model.cc	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,75 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+
+#include "spectrum-propagation-loss-model.h"
+#include <ns3/log.h>
+
+NS_LOG_COMPONENT_DEFINE ("SpectrumPropagationLossModel");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (SpectrumPropagationLossModel);
+
+SpectrumPropagationLossModel::SpectrumPropagationLossModel ()
+  : m_next (0)
+{
+}
+
+SpectrumPropagationLossModel::~SpectrumPropagationLossModel ()
+{
+}
+
+void
+SpectrumPropagationLossModel::DoDispose ()
+{
+  m_next = 0;
+}
+
+TypeId
+SpectrumPropagationLossModel::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::SpectrumPropagationLossModel")
+    .SetParent<Object> ()
+  ;
+  return tid;
+}
+
+
+void SpectrumPropagationLossModel::SetNext (Ptr<SpectrumPropagationLossModel> next)
+{
+  m_next = next;
+}
+
+
+Ptr<SpectrumValue>
+SpectrumPropagationLossModel::CalcRxPowerSpectralDensity (Ptr<const SpectrumValue> txPsd,
+                                                          Ptr<const MobilityModel> a,
+                                                          Ptr<const MobilityModel> b) const
+{
+  Ptr<SpectrumValue> rxPsd = DoCalcRxPowerSpectralDensity (txPsd, a, b);
+  if (m_next != 0)
+    {
+      rxPsd = m_next->DoCalcRxPowerSpectralDensity (rxPsd, a, b);
+    }
+  return rxPsd;
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/spectrum-propagation-loss-model.h	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,107 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#ifndef SPECTRUM_PROPAGATION_LOSS_MODEL_H
+#define SPECTRUM_PROPAGATION_LOSS_MODEL_H
+
+
+#include <ns3/object.h>
+#include <ns3/mobility-model.h>
+#include <ns3/spectrum-value.h>
+
+namespace ns3 {
+
+
+
+
+/**
+ * \brief spectrum-aware propagation loss model
+ *
+ * Interface for propagation loss models to be adopted when
+ * transmissions are modeled with a power spectral density by means of
+ * the SpectrumValue class.
+ *
+ */
+class SpectrumPropagationLossModel : public Object
+{
+public:
+  SpectrumPropagationLossModel ();
+  virtual ~SpectrumPropagationLossModel ();
+
+  static TypeId GetTypeId ();
+
+
+  /**
+   * used to chain various instances of SpectrumPropagationLossModel
+   *
+   * @param next
+   */
+  void SetNext (Ptr<SpectrumPropagationLossModel> next);
+
+  /**
+   * This method is to be called to calculate
+   *
+   * @param txPsd the SpectrumValue representing the power spectral
+   * density of the transmission. Watt units are to be used for radio
+   * communications, and Pascal units for acoustic communications
+   * (e.g. underwater).
+   *
+   * @param a sender mobility
+   * @param b receiver mobility
+   *
+   * @return set of values vs frequency representing the received
+   * power in the same units used for the txPower parameter.
+   */
+  Ptr<SpectrumValue> CalcRxPowerSpectralDensity (Ptr<const SpectrumValue> txPsd,
+                                                 Ptr<const MobilityModel> a,
+                                                 Ptr<const MobilityModel> b) const;
+
+protected:
+  virtual void DoDispose ();
+  
+
+private:
+  /**
+   *
+   *
+   * @param txPower set of values vs frequency representing the
+   * transmission power. See SpectrumChannel for details.
+   *
+   * @param a sender mobility
+   * @param b receiver mobility
+   *
+   * @return set of values vs frequency representing the received
+   * power in the same units used for the txPower parameter.
+   */
+  virtual Ptr<SpectrumValue> DoCalcRxPowerSpectralDensity (Ptr<const SpectrumValue> txPsd,
+                                                           Ptr<const MobilityModel> a,
+                                                           Ptr<const MobilityModel> b) const = 0;
+
+  Ptr<SpectrumPropagationLossModel> m_next;
+};
+
+
+
+
+
+
+} // namespace ns3
+
+#endif /* SPECTRUM_PROPAGATION_LOSS_MODEL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/spectrum-type.cc	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,95 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#include "spectrum-type.h"
+#include <ns3/assert.h>
+
+
+namespace ns3 {
+
+
+
+std::vector<std::string> SpectrumTypeFactory::m_names;
+
+
+SpectrumType
+SpectrumTypeFactory::Create (std::string name)
+{
+  std::vector<std::string>::iterator it;
+  for (it = m_names.begin (); it != m_names.end (); ++it)
+    {
+      NS_ASSERT_MSG (name != *it, "name \"" << name << "\" already registered!");
+    }
+  m_names.push_back (name);
+  return SpectrumType (m_names.size () - 1);
+}
+
+
+
+std::string
+SpectrumTypeFactory::GetNameByUid (uint32_t uid)
+{
+  return m_names.at (uid);
+}
+
+
+
+SpectrumType::SpectrumType (uint32_t uid)
+  : m_uid (uid)
+{
+}
+
+uint32_t
+SpectrumType::GetUid () const
+{
+  return m_uid;
+}
+
+
+std::string
+SpectrumType::GetName () const
+{
+  return SpectrumTypeFactory::GetNameByUid (m_uid);
+}
+
+
+bool
+operator== (const SpectrumType& lhs, const SpectrumType& rhs)
+{
+  return (lhs.GetUid () == rhs.GetUid ());
+}
+
+
+bool
+operator!= (const SpectrumType& lhs, const SpectrumType& rhs)
+{
+  return (lhs.GetUid () != rhs.GetUid ());
+}
+
+std::ostream&
+operator<<  (std::ostream& os, const SpectrumType& rhs)
+{
+  os << rhs.GetName ();
+  return os;
+}
+
+
+} // namespace ns3
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/spectrum-type.h	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,80 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#ifndef SPECTRUM_TYPE_H
+#define SPECTRUM_TYPE_H
+
+#include <ns3/log.h>
+#include <iostream>
+#include <vector>
+#include <string>
+
+
+namespace ns3 {
+
+
+/**
+ * This class represent a type of signal that can be transmitted by
+ * SpectrumPhy instances over a SpectrumChannel. By means of this
+ * class a SpectrumPhy is able to recognize which type of signals it
+ * is able to decode (i.e., receive) and which are to be considered
+ * only as a source of interference. Note that this distinction of
+ * signal types is an abstraction which is introduced only for
+ * simulation purposes: in the real world a device needs to infer
+ * whether a signal is of a known type by examining at properties of the
+ * signal, such as preamble, CRC fields, etc.
+ *
+ */
+class SpectrumType
+{
+  friend class SpectrumTypeFactory;
+
+public:
+  uint32_t GetUid () const;
+  std::string GetName () const;
+
+private:
+  SpectrumType (uint32_t m_uid);
+  uint32_t m_uid;
+};
+
+
+bool operator== (const SpectrumType& lhs, const SpectrumType& rhs);
+bool operator!= (const SpectrumType& lhs, const SpectrumType& rhs);
+std::ostream& operator<< (std::ostream& os, const SpectrumType& rhs);
+
+
+
+class SpectrumTypeFactory
+{
+
+public:
+  static SpectrumType Create (std::string name);
+  static std::string GetNameByUid (uint32_t uid);
+
+private:
+  static std::vector<std::string> m_names;
+};
+
+
+} // namespace ns3
+
+
+#endif /*  SPECTRUM_TYPE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/spectrum-value-test.cc	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,370 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#include <ns3/object.h>
+#include <ns3/spectrum-value.h>
+#include <ns3/spectrum-converter.h>
+#include <ns3/log.h>
+#include <ns3/test.h>
+#include <iostream>
+#include <math.h>
+
+// NS_LOG_COMPONENT_DEFINE ("SpectrumValueTest");
+
+namespace ns3 {
+
+
+#define TOLERANCE 1e-6
+
+class SpectrumValueTestCase : public TestCase
+{
+public:
+  SpectrumValueTestCase (SpectrumValue a, SpectrumValue b, std::string name);
+  virtual ~SpectrumValueTestCase ();
+  virtual bool DoRun (void);
+
+private:
+  bool MoreOrLessEqual (SpectrumValue x, SpectrumValue y);
+  SpectrumValue m_a;
+  SpectrumValue m_b;
+};
+
+
+
+SpectrumValueTestCase::SpectrumValueTestCase (SpectrumValue a, SpectrumValue b, std::string name)
+  : TestCase (name),
+    m_a (a),
+    m_b (b)
+{
+}
+
+SpectrumValueTestCase::~SpectrumValueTestCase ()
+{
+}
+
+
+bool
+SpectrumValueTestCase::MoreOrLessEqual (SpectrumValue x, SpectrumValue y)
+{
+  SpectrumValue z = x - y;
+  return (Norm (z) < TOLERANCE);
+}
+
+bool
+SpectrumValueTestCase::DoRun (void)
+{
+  bool error = !MoreOrLessEqual (m_a, m_b);
+  std::cerr << m_a << std::endl
+            << m_b << std::endl;
+  if (error)
+    {
+      std::ostringstream actualStream;
+      actualStream << m_a;
+      std::ostringstream limitStream;
+      limitStream << m_b;
+      UpdateErrorStatus (error);
+      ReportTestFailure (std::string ("vector elements equal"),
+                         actualStream.str (),
+                         limitStream.str (),
+                         std::string ("no message"),
+                         __FILE__, __LINE__);
+    }
+  return error;
+}
+
+
+
+
+
+
+
+
+class SpectrumValueTestSuite : public TestSuite
+{
+public:
+  SpectrumValueTestSuite ();
+};
+
+SpectrumValueTestSuite::SpectrumValueTestSuite ()
+  : TestSuite ("spectrum-value", UNIT)
+{
+
+  // NS_LOG_INFO("creating SpectrumValueTestSuite");
+
+
+  std::vector<double> freqs;
+
+  for (int i = 1; i <= 5; i++)
+    {
+      freqs.push_back (i);
+    }
+
+  Ptr<SpectrumModel> f = Create<SpectrumModel> (freqs);
+
+  SpectrumValue v1 (f), v2 (f), v3 (f), v4 (f), v5 (f), v6 (f), v7 (f), v8 (f), v9 (f), v10 (f);
+  double nv1, nv2;
+
+  double doubleValue;
+
+
+  doubleValue =  1.12345600000000;
+
+  v1[0] =  0.700539792840;
+  v1[1] = -0.554277600423;
+  v1[2] =  0.750309319469;
+  v1[3] = -0.892299213192;
+  v1[4] =  0.987045234885;
+
+  v2[0] =  0.870441628737;
+  v2[1] =  0.271419263880;
+  v2[2] =  0.451557288312;
+  v2[3] =  0.968992859395;
+  v2[4] = -0.929186654705;
+
+  v3[0] =  1.570981421577;
+  v3[1] = -0.282858336543;
+  v3[2] =  1.201866607781;
+  v3[3] =  0.076693646203;
+  v3[4] =  0.057858580180;
+
+  v4[0] = -0.169901835897;
+  v4[1] = -0.825696864302;
+  v4[2] =  0.298752031158;
+  v4[3] = -1.861292072588;
+  v4[4] =  1.916231889590;
+
+  v5[0] =  0.609778998275;
+  v5[1] = -0.150441618292;
+  v5[2] =  0.338807641695;
+  v5[3] = -0.864631566028;
+  v5[4] = -0.917149259846;
+
+  v6[0] =  0.804809615846;
+  v6[1] = -2.042145397125;
+  v6[2] =  1.661603829438;
+  v6[3] = -0.920852207053;
+  v6[4] = -1.062267984465;
+
+  v7[0] =  1.823995792840;
+  v7[1] =  0.569178399577;
+  v7[2] =  1.873765319469;
+  v7[3] =  0.231156786808;
+  v7[4] =  2.110501234885;
+
+  v8[0] = -0.422916207160;
+  v8[1] = -1.677733600423;
+  v8[2] = -0.373146680531;
+  v8[3] = -2.015755213192;
+  v8[4] = -0.136410765115;
+
+  v9[0] =  0.787025633505;
+  v9[1] = -0.622706495860;
+  v9[2] =  0.842939506814;
+  v9[3] = -1.002458904856;
+  v9[4] =  1.108901891403;
+
+  v10[0] =  0.623557836569;
+  v10[1] = -0.493368320987;
+  v10[2] =  0.667858215604;
+  v10[3] = -0.794244913190;
+  v10[4] =  0.878579343459;
+
+  nv1 =  1.76957619675970;
+  nv2 =  1.68451062071783;
+
+
+
+
+  // std::cerr.precision(15);
+
+  // std::cerr<< nv1 << " "<<   v1.Norm() << std::endl;
+
+  SpectrumValue tv3 (f), tv4 (f), tv5 (f), tv6 (f);
+
+  tv3 = v1 + v2;
+  tv4 = v1 - v2;
+  tv5 = v1 * v2;
+  tv6 = v1 / v2;
+
+
+  AddTestCase (new SpectrumValueTestCase (tv3, v3, " tv3 = v1 + v2"));
+  AddTestCase (new SpectrumValueTestCase (tv4, v4, " tv4 = v1 - v2"));
+  AddTestCase (new SpectrumValueTestCase (tv5, v5, " tv5 = v1 * v2"));
+  AddTestCase (new SpectrumValueTestCase (tv6, v6, " tv6 = v1 / v2"));
+
+  // std::cerr << v6 << std::endl;
+  // std::cerr << tv6 << std::endl;
+
+
+  tv3 = v1;
+  tv4 = v1;
+  tv5 = v1;
+  tv6 = v1;
+
+  tv3 += v2;
+  tv4 -= v2;
+  tv5 *= v2;
+  tv6 /= v2;
+
+  AddTestCase (new SpectrumValueTestCase (tv3, v3, "tv3 += v2"));
+  AddTestCase (new SpectrumValueTestCase (tv4, v4, "tv4 -= v2"));
+  AddTestCase (new SpectrumValueTestCase (tv5, v5, "tv5 *= v2"));
+  AddTestCase (new SpectrumValueTestCase (tv6, v6, "tv6 /= v2"));
+
+  SpectrumValue tv7a (f), tv8a (f), tv9a (f), tv10a (f);
+  tv7a = v1 + doubleValue;
+  tv8a = v1 - doubleValue;
+  tv9a = v1 * doubleValue;
+  tv10a = v1 / doubleValue;
+  AddTestCase (new SpectrumValueTestCase (tv7a, v7, "tv7a = v1 + doubleValue"));
+  AddTestCase (new SpectrumValueTestCase (tv8a, v8, "tv8a = v1 - doubleValue"));
+  AddTestCase (new SpectrumValueTestCase (tv9a, v9, "tv9a = v1 * doubleValue"));
+  AddTestCase (new SpectrumValueTestCase (tv10a, v10, "tv10a = v1 / doubleValue"));
+
+  SpectrumValue tv7b (f), tv8b (f), tv9b (f), tv10b (f);
+  tv7b =  doubleValue + v1;
+  tv8b =  doubleValue - v1;
+  tv9b =  doubleValue * v1;
+  tv10b = doubleValue / v1;
+  AddTestCase (new SpectrumValueTestCase (tv7b, v7, "tv7b =  doubleValue + v1"));
+  AddTestCase (new SpectrumValueTestCase (tv8b, v8, "tv8b =  doubleValue - v1"));
+  AddTestCase (new SpectrumValueTestCase (tv9b, v9, "tv9b =  doubleValue * v1"));
+  AddTestCase (new SpectrumValueTestCase (tv10b, v10, "tv10b = doubleValue / v1"));
+
+
+
+
+
+  SpectrumValue v1ls3 (f), v1rs3 (f);
+  SpectrumValue tv1ls3 (f), tv1rs3 (f);
+
+  v1ls3[0] = v1[3];
+  v1ls3[1] = v1[4];
+  tv1ls3 = v1 << 3;
+  AddTestCase (new SpectrumValueTestCase (tv1ls3, v1ls3, "tv1ls3 = v1 << 3"));
+
+
+  v1rs3[3] = v1[0];
+  v1rs3[4] = v1[1];
+  tv1rs3 = v1 >> 3;
+  AddTestCase (new SpectrumValueTestCase (tv1rs3, v1rs3, "tv1rs3 = v1 >> 3"));
+
+
+}
+
+
+
+
+
+
+
+class SpectrumConverterTestSuite : public TestSuite
+{
+public:
+  SpectrumConverterTestSuite ();
+};
+
+SpectrumConverterTestSuite::SpectrumConverterTestSuite ()
+  : TestSuite ("spectrum-converter", UNIT)
+{
+  double f;
+
+
+  std::vector<double> f1;
+  for (f = 3; f <= 7; f += 2)
+    {
+      f1.push_back (f);
+    }
+  Ptr<SpectrumModel> sof1 = Create<SpectrumModel> (f1);
+
+
+
+  std::vector<double> f2;
+  for (f = 2; f <= 8; f += 1)
+    {
+      f2.push_back (f);
+    }
+  Ptr<SpectrumModel> sof2 = Create<SpectrumModel> (f2);
+
+
+
+  Ptr<SpectrumValue> res;
+
+
+  Ptr<SpectrumValue> v1 = Create<SpectrumValue> (sof1);
+  *v1 = 4;
+  SpectrumConverter c12 (sof1, sof2);
+  res = c12.Convert (v1);
+  SpectrumValue t12 (sof2);
+  t12 = 4;
+  t12[0] = 2;
+  t12[6] = 2;
+//   NS_LOG_LOGIC(*v1);
+//   NS_LOG_LOGIC(t12);
+//   NS_LOG_LOGIC(*res);
+
+  AddTestCase (new SpectrumValueTestCase (t12, *res, ""));
+  // TEST_ASSERT(MoreOrLessEqual(t12, *res));
+
+  Ptr<SpectrumValue> v2a = Create<SpectrumValue> (sof2);
+  *v2a = -2;
+  SpectrumConverter c21 (sof2, sof1);
+  res = c21.Convert (v2a);
+  SpectrumValue t21a (sof1);
+  t21a = -2;
+//   NS_LOG_LOGIC(*v2a);
+//   NS_LOG_LOGIC(t21a);
+//   NS_LOG_LOGIC(*res);
+  AddTestCase (new SpectrumValueTestCase (t21a, *res, ""));
+  // TEST_ASSERT(MoreOrLessEqual(t21a, *res));
+
+  Ptr<SpectrumValue> v2b = Create<SpectrumValue> (sof2);
+  (*v2b)[0] = 3;
+  (*v2b)[1] = 5;
+  (*v2b)[2] = 1;
+  (*v2b)[3] = 2;
+  (*v2b)[4] = 4;
+  (*v2b)[5] = 6;
+  (*v2b)[6] = 3;
+  res = c21.Convert (v2b);
+  SpectrumValue t21b (sof1);
+  t21b[0] = 3 * 0.25 + 5 * 0.5 + 1 * 0.25;
+  t21b[1] = 1 * 0.25 + 2 * 0.5 + 4 * 0.25;
+  t21b[2] = 4 * 0.25 + 6 * 0.5 + 3 * 0.25;
+//   NS_LOG_LOGIC(*v2b);
+//   NS_LOG_LOGIC(t21b);
+//   NS_LOG_LOGIC(*res);
+  AddTestCase (new SpectrumValueTestCase (t21b, *res, ""));
+
+
+}
+
+
+
+
+
+
+// static instance of test suites
+SpectrumValueTestSuite g_SpectrumValueTestSuite;
+SpectrumConverterTestSuite g_SpectrumConverterTestSuite;
+
+
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/spectrum-value.cc	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,670 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil;  -*- */
+
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#include <ns3/spectrum-value.h>
+#include <math.h>
+#include <ns3/log.h>
+
+
+
+NS_LOG_COMPONENT_DEFINE ("SpectrumValue");
+
+
+namespace ns3 {
+
+
+
+SpectrumValue::SpectrumValue (Ptr<const SpectrumModel> sof)
+  : m_spectrumModel (sof),
+    m_values (sof->GetNumBands ())
+{
+
+}
+
+double&
+SpectrumValue:: operator[] (size_t index)
+{
+  return m_values.at (index);
+}
+
+
+SpectrumModelUid_t
+SpectrumValue::GetSpectrumModelUid () const
+{
+  return m_spectrumModel->GetUid ();
+}
+
+
+Ptr<const SpectrumModel>
+SpectrumValue::GetSpectrumModel () const
+{
+  return m_spectrumModel;
+}
+
+
+Values::const_iterator
+SpectrumValue::ConstValuesBegin () const
+{
+  return m_values.begin ();
+}
+
+Values::const_iterator
+SpectrumValue::ConstValuesEnd () const
+{
+  return m_values.end ();
+}
+
+
+Values::iterator
+SpectrumValue::ValuesBegin ()
+{
+  return m_values.begin ();
+}
+
+Values::iterator
+SpectrumValue::ValuesEnd ()
+{
+  return m_values.end ();
+}
+
+Bands::const_iterator
+SpectrumValue::ConstBandsBegin () const
+{
+  return m_spectrumModel->Begin ();
+}
+
+Bands::const_iterator
+SpectrumValue::ConstBandsEnd () const
+{
+  return m_spectrumModel->End ();
+}
+
+
+void
+SpectrumValue::Add (const SpectrumValue& x)
+{
+  Values::iterator it1 = m_values.begin ();
+  Values::const_iterator it2 = x.m_values.begin ();
+
+  NS_ASSERT (m_spectrumModel == x.m_spectrumModel);
+
+  while (it1 != m_values.end ())
+    {
+      NS_ASSERT ( it2 != x.m_values.end ());
+      *it1 += *it2;
+      ++it1;
+      ++it2;
+    }
+}
+
+
+void
+SpectrumValue::Add (double s)
+{
+  Values::iterator it1 = m_values.begin ();
+
+  while (it1 != m_values.end ())
+    {
+      *it1 += s;
+      ++it1;
+    }
+}
+
+
+
+void
+SpectrumValue::Subtract (const SpectrumValue& x)
+{
+  Values::iterator it1 = m_values.begin ();
+  Values::const_iterator it2 = x.m_values.begin ();
+
+  NS_ASSERT (m_spectrumModel == x.m_spectrumModel);
+
+  while (it1 != m_values.end ())
+    {
+      NS_ASSERT ( it2 != x.m_values.end ());
+      *it1 -= *it2;
+      ++it1;
+      ++it2;
+    }
+}
+
+
+void
+SpectrumValue::Subtract (double s)
+{
+  Add (-s);
+}
+
+
+
+void
+SpectrumValue::Multiply (const SpectrumValue& x)
+{
+  Values::iterator it1 = m_values.begin ();
+  Values::const_iterator it2 = x.m_values.begin ();
+
+  NS_ASSERT (m_spectrumModel == x.m_spectrumModel);
+
+  while (it1 != m_values.end ())
+    {
+      NS_ASSERT ( it2 != x.m_values.end ());
+      *it1 *= *it2;
+      ++it1;
+      ++it2;
+    }
+}
+
+
+void
+SpectrumValue::Multiply (double s)
+{
+  Values::iterator it1 = m_values.begin ();
+
+  while (it1 != m_values.end ())
+    {
+      *it1 *= s;
+      ++it1;
+    }
+}
+
+
+
+
+void
+SpectrumValue::Divide (const SpectrumValue& x)
+{
+  Values::iterator it1 = m_values.begin ();
+  Values::const_iterator it2 = x.m_values.begin ();
+
+  NS_ASSERT (m_spectrumModel == x.m_spectrumModel);
+
+  while (it1 != m_values.end ())
+    {
+      NS_ASSERT ( it2 != x.m_values.end ());
+      *it1 /= *it2;
+      ++it1;
+      ++it2;
+    }
+}
+
+
+void
+SpectrumValue::Divide (double s)
+{
+  NS_LOG_FUNCTION (this << s);
+  Values::iterator it1 = m_values.begin ();
+
+  while (it1 != m_values.end ())
+    {
+      *it1 /= s;
+      ++it1;
+    }
+}
+
+
+
+
+void
+SpectrumValue::ChangeSign ()
+{
+  Values::iterator it1 = m_values.begin ();
+
+  while (it1 != m_values.end ())
+    {
+      *it1 = -(*it1);
+      ++it1;
+    }
+}
+
+
+void
+SpectrumValue::ShiftLeft (int n)
+{
+  int i = 0;
+  while (i < (int) m_values.size () - n)
+    {
+      m_values.at (i) = m_values.at (i + n);
+      i++;
+    }
+  while (i < (int)m_values.size ())
+    {
+      m_values.at (i) = 0;
+      i++;
+    }
+}
+
+
+void
+SpectrumValue::ShiftRight (int n)
+{
+  int i = m_values.size () - 1;
+  while (i - n >= 0)
+    {
+      m_values.at (i) = m_values.at (i - n);
+      i = i - 1;
+    }
+  while (i >= 0)
+    {
+      m_values.at (i) = 0;
+      --i;
+    }
+}
+
+
+
+void
+SpectrumValue::Pow (double exp)
+{
+  NS_LOG_FUNCTION (this << exp);
+  Values::iterator it1 = m_values.begin ();
+
+  while (it1 != m_values.end ())
+    {
+      *it1 = pow (*it1, exp);
+      ++it1;
+    }
+}
+
+
+void
+SpectrumValue::Exp (double base)
+{
+  NS_LOG_FUNCTION (this << base);
+  Values::iterator it1 = m_values.begin ();
+
+  while (it1 != m_values.end ())
+    {
+      *it1 = pow (base, *it1);
+      ++it1;
+    }
+}
+
+
+void
+SpectrumValue::Log10 ()
+{
+  NS_LOG_FUNCTION (this);
+  Values::iterator it1 = m_values.begin ();
+
+  while (it1 != m_values.end ())
+    {
+      *it1 = log10 (*it1);
+      ++it1;
+    }
+}
+
+void
+SpectrumValue::Log2 ()
+{
+  NS_LOG_FUNCTION (this);
+  Values::iterator it1 = m_values.begin ();
+
+  while (it1 != m_values.end ())
+    {
+      *it1 = log2 (*it1);
+      ++it1;
+    }
+}
+
+
+void
+SpectrumValue::Log ()
+{
+  NS_LOG_FUNCTION (this);
+  Values::iterator it1 = m_values.begin ();
+
+  while (it1 != m_values.end ())
+    {
+      *it1 = log (*it1);
+      ++it1;
+    }
+}
+
+double
+Norm (const SpectrumValue& x)
+{
+  double s = 0;
+  Values::const_iterator it1 = x.ConstValuesBegin ();
+  while (it1 != x.ConstValuesEnd ())
+    {
+      s += (*it1) * (*it1);
+      ++it1;
+    }
+  return sqrt (s);
+}
+
+
+double
+Sum (const SpectrumValue& x)
+{
+  double s = 0;
+  Values::const_iterator it1 = x.ConstValuesBegin ();
+  while (it1 != x.ConstValuesEnd ())
+    {
+      s += (*it1);
+      ++it1;
+    }
+  return s;
+}
+
+
+
+double
+Prod (const SpectrumValue& x)
+{
+  double s = 0;
+  Values::const_iterator it1 = x.ConstValuesBegin ();
+  while (it1 != x.ConstValuesEnd ())
+    {
+      s *= (*it1);
+      ++it1;
+    }
+  return s;
+}
+
+
+Ptr<SpectrumValue>
+SpectrumValue::Copy () const
+{
+  Ptr<SpectrumValue> p = Create<SpectrumValue> (m_spectrumModel);
+  *p = *this;
+  return p;
+
+  //  return Copy<SpectrumValue> (*this)
+}
+
+
+std::ostream&
+operator << (std::ostream& os, const SpectrumValue& pvf)
+{
+  Values::const_iterator it1 = pvf.ConstValuesBegin ();
+  while (it1 != pvf.ConstValuesEnd ())
+    {
+      os << *it1 << " " ;
+      ++it1;
+    }
+  os << std::endl;
+  return os;
+}
+
+
+
+SpectrumValue
+operator+ (const SpectrumValue& lhs, const SpectrumValue& rhs)
+{
+  SpectrumValue res = lhs;
+  res.Add (rhs);
+  return res;
+}
+
+
+SpectrumValue
+operator+ (const SpectrumValue& lhs, double rhs)
+{
+  SpectrumValue res = lhs;
+  res.Add (rhs);
+  return res;
+}
+
+
+SpectrumValue
+operator+ (double lhs, const SpectrumValue& rhs)
+{
+  SpectrumValue res = rhs;
+  res.Add (lhs);
+  return res;
+}
+
+
+SpectrumValue
+operator- (const SpectrumValue& lhs, const SpectrumValue& rhs)
+{
+  SpectrumValue res = rhs;
+  res.ChangeSign ();
+  res.Add (lhs);
+  return res;
+}
+
+
+
+SpectrumValue
+operator- (const SpectrumValue& lhs, double rhs)
+{
+  SpectrumValue res = lhs;
+  res.Subtract (rhs);
+  return res;
+}
+
+
+SpectrumValue
+operator- (double lhs, const SpectrumValue& rhs)
+{
+  SpectrumValue res = rhs;
+  res.Subtract (lhs);
+  return res;
+}
+
+SpectrumValue
+operator* (const SpectrumValue& lhs, const SpectrumValue& rhs)
+{
+  SpectrumValue res = lhs;
+  res.Multiply (rhs);
+  return res;
+}
+
+
+SpectrumValue
+operator* (const SpectrumValue& lhs, double rhs)
+{
+  SpectrumValue res = lhs;
+  res.Multiply (rhs);
+  return res;
+}
+
+
+SpectrumValue
+operator* (double lhs, const SpectrumValue& rhs)
+{
+  SpectrumValue res = rhs;
+  res.Multiply (lhs);
+  return res;
+}
+
+
+SpectrumValue
+operator/ (const SpectrumValue& lhs, const SpectrumValue& rhs)
+{
+  SpectrumValue res = lhs;
+  res.Divide (rhs);
+  return res;
+}
+
+
+SpectrumValue
+operator/ (const SpectrumValue& lhs, double rhs)
+{
+  SpectrumValue res = lhs;
+  res.Divide (rhs);
+  return res;
+}
+
+
+SpectrumValue
+operator/ (double lhs, const SpectrumValue& rhs)
+{
+  SpectrumValue res = rhs;
+  res.Divide (lhs);
+  return res;
+}
+
+
+SpectrumValue
+operator+ (const SpectrumValue& rhs)
+{
+  return rhs;
+}
+
+SpectrumValue
+operator- (const SpectrumValue& rhs)
+{
+  SpectrumValue res = rhs;
+  res.ChangeSign ();
+  return res;
+}
+
+
+SpectrumValue
+Pow (double lhs, const SpectrumValue& rhs)
+{
+  SpectrumValue res = rhs;
+  res.Exp (lhs);
+  return res;
+}
+
+
+SpectrumValue
+Pow (const SpectrumValue& lhs, double rhs)
+{
+  SpectrumValue res = lhs;
+  res.Pow (rhs);
+  return res;
+}
+
+
+SpectrumValue
+Log10 (const SpectrumValue& arg)
+{
+  SpectrumValue res = arg;
+  res.Log10 ();
+  return res;
+}
+
+SpectrumValue
+Log2 (const SpectrumValue& arg)
+{
+  SpectrumValue res = arg;
+  res.Log2 ();
+  return res;
+}
+
+SpectrumValue
+Log (const SpectrumValue& arg)
+{
+  SpectrumValue res = arg;
+  res.Log ();
+  return res;
+}
+
+SpectrumValue&
+SpectrumValue:: operator+= (const SpectrumValue& rhs)
+{
+  Add (rhs);
+  return *this;
+}
+
+SpectrumValue&
+SpectrumValue:: operator-= (const SpectrumValue& rhs)
+{
+  Subtract (rhs);
+  return *this;
+}
+
+SpectrumValue&
+SpectrumValue:: operator*= (const SpectrumValue& rhs)
+{
+  Multiply (rhs);
+  return *this;
+}
+
+SpectrumValue&
+SpectrumValue:: operator/= (const SpectrumValue& rhs)
+{
+  Divide (rhs);
+  return *this;
+}
+
+
+SpectrumValue&
+SpectrumValue:: operator+= (double rhs)
+{
+  Add (rhs);
+  return *this;
+}
+
+SpectrumValue&
+SpectrumValue:: operator-= (double rhs)
+{
+  Subtract (rhs);
+  return *this;
+}
+
+SpectrumValue&
+SpectrumValue:: operator*= (double rhs)
+{
+  Multiply (rhs);
+  return *this;
+}
+
+SpectrumValue&
+SpectrumValue:: operator/= (double rhs)
+{
+  Divide (rhs);
+  return *this;
+}
+
+
+SpectrumValue&
+SpectrumValue:: operator= (double rhs)
+{
+  Values::iterator it1 = m_values.begin ();
+
+  while (it1 != m_values.end ())
+    {
+      *it1 = rhs;
+      ++it1;
+    }
+  return *this;
+}
+
+
+
+SpectrumValue
+SpectrumValue:: operator<< (int n) const
+{
+  SpectrumValue res = *this;
+  res.ShiftLeft (n);
+  return res;
+}
+
+SpectrumValue
+SpectrumValue:: operator>> (int n) const
+{
+  SpectrumValue res = *this;
+  res.ShiftRight (n);
+  return res;
+}
+
+
+
+
+} // namespace ns3
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/spectrum-value.h	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,525 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#ifndef SPECTRUM_VALUE_H
+#define SPECTRUM_VALUE_H
+
+#include <ns3/ptr.h>
+#include <ns3/simple-ref-count.h>
+#include <ns3/spectrum-model.h>
+#include <ostream>
+#include <vector>
+
+namespace ns3 {
+
+
+typedef std::vector<double> Values;
+
+/**
+ * \brief Set of values corresponding to a given SpectrumModel
+ *
+ * This class implements a Function Space which can represent any
+ * function \f$ g: F \in {\sf
+ * R\hspace*{-0.9ex}\rule{0.15ex}{1.5ex}\hspace*{0.9ex}}^N \rightarrow {\sf R\hspace*{-0.9ex}\rule{0.15ex}{1.5ex}\hspace*{0.9ex}}  \f$
+ *
+ * Every instance of this class represent a particular function \f$ g(F) \f$.
+ * The domain of the function space, i.e., \f$ F \f$, is implemented by SetOfFreq.
+ * The codomain of the function space is implemented by SetOfValues
+ *
+ * To every possible value of \f$ F\f$ corresponds a different Function
+ * Space.
+ * Mathematical operations are defined in this Function Space; these
+ * operations are implemented by means of operator overloading.
+ *
+ * The intended use of this class is to represent frequency-dependent
+ * things, such as power spectral densities, frequency-dependent
+ * propagation losses, spectral masks, etc.
+ */
+class SpectrumValue : public SimpleRefCount<SpectrumValue>
+{
+public:
+  /**
+   * @brief SpectrumValue constructor
+   *
+   * @param sm pointer to the SpectrumModel which implements the set of frequencies to which the values
+   * will be referring.
+   *
+   * @warning the intended use if that sm points to a static object
+   * which will be there for the whole simulation. This is reasonable
+   * since the set of frequencies which are to be used in the
+   * simulation is normally known before the simulation starts. Make
+   * sure that the SpectrumModel instance which sm points to has already been
+   * initialized by the time this method is invoked. The main reason is
+   * that if you initialize the SpectrumModel instance afterwards, and
+   * the memory for the underlying std::vector gets reallocated, then
+   * sm will not be a valid reference anymore. Another reason is that
+   * m_values could end up having the wrong size.
+   */
+  SpectrumValue (Ptr<const SpectrumModel> sm);
+
+  /**
+   * Access value at given frequency index
+   *
+   * @param index the given frequency index
+   *
+   * @return reference to the value
+   */
+  double& operator[] (size_t index);
+
+
+
+  /**
+   *
+   * @return the uid of the embedded SpectrumModel
+   */
+  SpectrumModelUid_t GetSpectrumModelUid () const;
+
+
+  /**
+   *
+   * @return the  embedded SpectrumModel
+   */
+  Ptr<const SpectrumModel> GetSpectrumModel () const;
+
+
+  /**
+   *
+   *
+   * @return a const iterator pointing to the beginning of the embedded SpectrumModel
+   */
+  Bands::const_iterator ConstBandsBegin () const;
+
+  /**
+   *
+   *
+   * @return a const iterator pointing to the end of the embedded SpectrumModel
+   */
+  Bands::const_iterator ConstBandsEnd () const;
+
+
+  /**
+   *
+   *
+   * @return a const iterator pointing to the beginning of the embedded SpectrumModel
+   */
+  Values::const_iterator ConstValuesBegin () const;
+
+  /**
+   *
+   *
+   * @return a const iterator pointing to the end of the embedded SpectrumModel
+   */
+  Values::const_iterator ConstValuesEnd () const;
+
+  /**
+   *
+   *
+   * @return an iterator pointing to the beginning of the embedded SpectrumModel
+   */
+  Values::iterator ValuesBegin ();
+
+  /**
+   *
+   *
+   * @return an iterator pointing to the end of the embedded SpectrumModel
+   */
+  Values::iterator ValuesEnd ();
+
+
+
+  /**
+   *  addition operator
+   *
+   * @param lhs Left Hand Side of the operator
+   * @param rhs Right Hand Side of the operator
+   *
+   * @return the value of lhs + rhs
+   */
+  friend SpectrumValue operator+ (const SpectrumValue& lhs, const SpectrumValue& rhs);
+
+
+  /**
+   *  addition operator
+   *
+   * @param lhs Left Hand Side of the operator
+   * @param rhs Right Hand Side of the operator
+   *
+   * @return the value of lhs + rhs
+   */
+  friend SpectrumValue operator+ (const SpectrumValue& lhs, double rhs);
+
+  /**
+   *  addition operator
+   *
+   * @param lhs Left Hand Side of the operator
+   * @param rhs Right Hand Side of the operator
+   *
+   * @return the value of lhs + rhs
+   */
+  friend SpectrumValue operator+ (double lhs, const SpectrumValue& rhs);
+
+
+  /**
+   *  subtraction operator
+   *
+   * @param lhs Left Hand Side of the operator
+   * @param rhs Right Hand Side of the operator
+   *
+   * @return the value of lhs - rhs
+   */
+  friend SpectrumValue operator- (const SpectrumValue& lhs, const SpectrumValue& rhs);
+
+  /**
+   *  subtraction operator
+   *
+   * @param lhs Left Hand Side of the operator
+   * @param rhs Right Hand Side of the operator
+   *
+   * @return the value of lhs - rhs
+   */
+  friend SpectrumValue operator- (const SpectrumValue& lhs, double rhs);
+
+  /**
+   *  subtraction operator
+   *
+   * @param lhs Left Hand Side of the operator
+   * @param rhs Right Hand Side of the operator
+   *
+   * @return the value of lhs - rhs
+   */
+  friend SpectrumValue operator- (double, const SpectrumValue& rhs);
+
+  /**
+   *  multiplication component-by-component (Schur product)
+   *
+   * @param lhs Left Hand Side of the operator
+   * @param rhs Right Hand Side of the operator
+   *
+   * @return the value of lhs * rhs
+   */
+  friend SpectrumValue operator* (const SpectrumValue& lhs, const SpectrumValue& rhs);
+
+  /**
+   *  multiplication by a scalar
+   *
+   * @param lhs Left Hand Side of the operator
+   * @param rhs Right Hand Side of the operator
+   *
+   * @return the value of lhs * rhs
+   */
+  friend SpectrumValue operator* (const SpectrumValue& lhs, double rhs);
+
+  /**
+   *  multiplication of a scalar
+   *
+   * @param lhs Left Hand Side of the operator
+   * @param rhs Right Hand Side of the operator
+   *
+   * @return the value of lhs * rhs
+   */
+  friend SpectrumValue operator* (double lhs, const SpectrumValue& rhs);
+
+  /**
+   *  division component-by-component
+   *
+   * @param lhs Left Hand Side of the operator
+   * @param rhs Right Hand Side of the operator
+   *
+   * @return the value of lhs / rhs
+   */
+  friend SpectrumValue operator/ (const SpectrumValue& lhs, const SpectrumValue& rhs);
+
+  /**
+   * division by a scalar
+   *
+   * @param lhs Left Hand Side of the operator
+   * @param rhs Right Hand Side of the operator
+   *
+   * @return the value of *this / rhs
+   */
+  friend SpectrumValue operator/ (const SpectrumValue& lhs, double rhs);
+
+  /**
+   * division of a scalar
+   *
+   * @param lhs Left Hand Side of the operator
+   * @param rhs Right Hand Side of the operator
+   *
+   * @return the value of *this / rhs
+   */
+  friend SpectrumValue operator/ (double lhs, const SpectrumValue& rhs);
+
+  /**
+   * unary plus operator
+   *
+   *
+   * @return the value of *this
+   */
+  friend SpectrumValue operator+ (const SpectrumValue& rhs);
+
+  /**
+   * unary minus operator
+   *
+   *
+   * @return the value of - *this
+   */
+  friend SpectrumValue operator- (const SpectrumValue& rhs);
+
+
+  /**
+   * left shift operator
+   *
+   * @param n position to shift
+   *
+   * @return the value of *this left shifted by n positions. In other
+   * words, the function of the set of frequencies represented by
+   * *this is left-shifted in frequency by n positions.
+   */
+  SpectrumValue operator<< (int n) const;
+
+  /**
+    * right shift operator
+    *
+    * @param n position to shift
+    *
+    * @return the value of *this right shifted by n positions. In other
+    * words, the function of the set of frequencies represented by
+    * *this is left-shifted in frequency by n positions.
+    */
+  SpectrumValue operator>> (int n) const;
+
+
+
+  /**
+   * Add the Right Hand Side of the operator to *this, component by component
+   *
+   * @param rhs the Right Hand Side
+   *
+   * @return a reference to *this
+   */
+  SpectrumValue& operator+= (const SpectrumValue& rhs);
+
+  /**
+   * Subtract the Right Hand Side of the operator from *this, component by component
+   *
+   * @param rhs the Right Hand Side
+   *
+   * @return a reference to *this
+   */
+  SpectrumValue& operator-= (const SpectrumValue& rhs);
+
+  /**
+   * Multiply *this by the Right Hand Side of the operator, component by component
+   *
+   * @param rhs the Right Hand Side
+   *
+   * @return  a reference to *this
+   */
+  SpectrumValue& operator*= (const SpectrumValue& rhs);
+
+  /**
+   * Divide *this by the Right Hand Side of the operator, component by component
+   *
+   * @param rhs the Right Hand Side
+   *
+   * @return  a reference to *this
+   */
+  SpectrumValue& operator/= (const SpectrumValue& rhs);
+
+  /**
+   * Add the value of the Right Hand Side of the operator to all
+   * components of *this
+   *
+   * @param rhs the Right Hand Side
+   *
+   * @return a reference to *this
+   */
+  SpectrumValue& operator+= (double rhs);
+
+  /**
+   * Subtract the value of the Right Hand Side of the operator from all
+   * components of *this
+   *
+   * @param rhs the Right Hand Side
+   *
+   * @return a reference to *this
+   */
+  SpectrumValue& operator-= (double rhs);
+
+  /**
+   * Multiply every component of *this by the value of the Right Hand
+   * Side of the operator
+   *
+   * @param rhs the Right Hand Side
+   *
+   * @return  a reference to *this
+   */
+  SpectrumValue& operator*= (double rhs);
+
+  /**
+   * Divide every component of *this by the value of the Right Hand
+   * Side of the operator
+   *
+   * @param rhs the Right Hand Side
+   *
+   * @return  a reference to *this
+   */
+  SpectrumValue& operator/= (double rhs);
+
+
+  /**
+   * Assign each component of *this to the value of the Right Hand
+   * Side of the operator
+   *
+   * @param rhs
+   *
+   * @return
+   */
+  SpectrumValue& operator= (double rhs);
+
+
+
+  /**
+   *
+   * @param x the operand
+   *
+   * @return the euclidean norm, i.e., the sum of the squares of all
+   * the values in x
+   */
+  friend double Norm (const SpectrumValue& x);
+
+
+  /**
+   *
+   * @param x the operand
+   *
+   * @return the sum of all
+   * the values in x
+   */
+  friend double Sum (const SpectrumValue& x);
+
+
+  /**
+   * @param x the operand
+   *
+   * @return the product of all
+   * the values in x
+   */
+  friend double Prod (const SpectrumValue& x);
+
+
+  /**
+   *
+   *
+   * @param base the base
+   * @param exp  the exponent
+   *
+   * @return each value in base raised to the exponent
+   */
+  friend SpectrumValue Pow (const SpectrumValue& base, double exp);
+
+
+  /**
+   *
+   *
+   * @param base the base
+   * @param exp  the exponent
+   *
+   * @return the value in base raised to each value in the exponent
+   */
+  friend SpectrumValue Pow (double base, const SpectrumValue& exp);
+
+  /**
+   *
+   *
+   * @param arg the argument
+   *
+   * @return the logarithm in base 10 of all values in the argument
+   */
+  friend SpectrumValue Log10 (const SpectrumValue&  arg);
+
+
+  /**
+   *
+   *
+   * @param arg the argument
+   *
+   * @return the logarithm in base 2 of all values in the argument
+   */
+  friend SpectrumValue Log2 (const SpectrumValue&  arg);
+
+  /**
+   *
+   *
+   * @param arg the argument
+   *
+   * @return the logarithm in base e of all values in the argument
+   */
+  friend SpectrumValue Log (const SpectrumValue&  arg);
+
+  /**
+   *
+   * @return a Ptr to a copy of this instance
+   */
+  Ptr<SpectrumValue> Copy () const;
+
+
+
+private:
+  void Add (const SpectrumValue& x);
+  void Add (double s);
+  void Subtract (const SpectrumValue& x);
+  void Subtract (double s);
+  void Multiply (const SpectrumValue& x);
+  void Multiply (double s);
+  void Divide (const SpectrumValue& x);
+  void Divide (double s);
+  void ChangeSign ();
+  void ShiftLeft (int n);
+  void ShiftRight (int n);
+  void Pow (double exp);
+  void Exp (double base);
+  void Log10 ();
+  void Log2 ();
+  void Log ();
+
+  Ptr<const SpectrumModel> m_spectrumModel;
+
+
+/**
+ * Set of values which implement the codomain of the functions in
+ * the Function Space defined by SpectrumValue. There is no restriction
+ * on what these values represent (a transmission power density, a
+ * propagation loss, etc.).
+ *
+ */
+  Values m_values;
+
+
+};
+
+std::ostream& operator << (std::ostream& os, const SpectrumValue& pvf);
+
+
+
+} // namespace ns3
+
+
+#endif /* SPECTRUM_VALUE_H */
--- a/src/common/wscript	Fri Jun 11 19:25:18 2010 +0200
+++ b/src/common/wscript	Fri Jun 11 19:30:06 2010 +0200
@@ -27,6 +27,13 @@
         'propagation-loss-model-test-suite.cc',
         'jakes-propagation-loss-model.cc',
         'cost231-propagation-loss-model.cc',
+        'spectrum-model.cc',
+        'spectrum-value.cc',
+        'spectrum-value-test.cc',
+        'spectrum-converter.cc',
+        'spectrum-type.cc',
+        'spectrum-propagation-loss-model.cc',
+        'friis-spectrum-propagation-loss.cc',
         ]
 
     headers = bld.new_task_gen('ns3header')
@@ -54,4 +61,10 @@
         'propagation-loss-model.h',
         'jakes-propagation-loss-model.h',
         'cost231-propagation-loss-model.h',
+        'spectrum-model.h',
+        'spectrum-value.h',
+        'spectrum-converter.h',
+        'spectrum-type.h',
+        'spectrum-propagation-loss-model.h',
+        'friis-spectrum-propagation-loss.h',
         ]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/spectrum/aloha-noack-mac-header.cc	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,108 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#include <ns3/log.h>
+#include "aloha-noack-mac-header.h"
+
+
+NS_LOG_COMPONENT_DEFINE ("AlohaNoackMacHeader");
+
+namespace ns3 {
+
+TypeId
+AlohaNoackMacHeader::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("AlohaNoackMacHeader")
+    .SetParent<Header> ()
+    .AddConstructor<AlohaNoackMacHeader> ()
+  ;
+  return tid;
+}
+
+TypeId
+AlohaNoackMacHeader::GetInstanceTypeId (void) const
+{
+  return GetTypeId ();
+}
+
+
+
+uint32_t
+AlohaNoackMacHeader::GetSerializedSize (void) const
+{
+  return 12;
+}
+
+
+
+void
+AlohaNoackMacHeader::Serialize (Buffer::Iterator start) const
+{
+  WriteTo (start, m_destination);
+  WriteTo (start, m_source);
+}
+
+uint32_t
+AlohaNoackMacHeader::Deserialize (Buffer::Iterator start)
+{
+  ReadFrom (start, m_destination);
+  ReadFrom (start, m_source);
+  return GetSerializedSize ();
+}
+
+
+void
+AlohaNoackMacHeader::Print (std::ostream &os) const
+{
+  os << "src="  << m_source
+     << "dst="  << m_destination;
+}
+
+
+void
+AlohaNoackMacHeader::SetSource (Mac48Address source)
+{
+  m_source = source;
+}
+
+Mac48Address
+AlohaNoackMacHeader::GetSource () const
+{
+  return m_source;
+}
+
+void
+AlohaNoackMacHeader::SetDestination (Mac48Address dst)
+{
+  m_destination = dst;
+}
+
+Mac48Address
+AlohaNoackMacHeader::GetDestination () const
+{
+  return m_destination;
+}
+
+
+
+
+} // namespace ns3
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/spectrum/aloha-noack-mac-header.h	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,55 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009, 2010 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+
+#ifndef ALOHA_NOACK_MAC_HEADER_H
+#define ALOHA_NOACK_MAC_HEADER_H
+
+#include <ns3/header.h>
+#include <ns3/mac48-address.h>
+#include <ns3/address-utils.h>
+
+namespace ns3 {
+
+class AlohaNoackMacHeader : public Header
+{
+public:
+  static TypeId GetTypeId (void);
+  virtual TypeId GetInstanceTypeId (void) const;
+  virtual uint32_t GetSerializedSize (void) const;
+  virtual void Serialize (Buffer::Iterator start) const;
+  virtual uint32_t Deserialize (Buffer::Iterator start);
+  virtual void Print (std::ostream &os) const;
+
+  void SetSource (Mac48Address source);
+  void SetDestination (Mac48Address destination);
+  Mac48Address GetSource () const;
+  Mac48Address GetDestination () const;
+
+private:
+  Mac48Address m_source;
+  Mac48Address m_destination;
+};
+
+
+
+} // namespace ns3
+
+#endif /* ALOHA_NOACK_MAC_HEADER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/spectrum/aloha-noack-net-device.cc	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,488 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#include "ns3/log.h"
+#include "ns3/queue.h"
+#include "ns3/simulator.h"
+#include "ns3/enum.h"
+#include "ns3/boolean.h"
+#include "ns3/uinteger.h"
+#include "ns3/pointer.h"
+#include "ns3/channel.h"
+#include "ns3/trace-source-accessor.h"
+#include "aloha-noack-mac-header.h"
+#include "aloha-noack-net-device.h"
+#include "ns3/llc-snap-header.h"
+
+NS_LOG_COMPONENT_DEFINE ("AlohaNoackNetDevice");
+
+
+namespace ns3 {
+
+
+std::ostream& operator<< (std::ostream& os, AlohaNoackNetDevice::State state)
+{
+  switch (state)
+    {
+    case AlohaNoackNetDevice::IDLE:
+      os << "IDLE" ;
+      break;
+    case AlohaNoackNetDevice::TX:
+      os << "TX" ;
+      break;
+    case AlohaNoackNetDevice::RX:
+      os << "RX" ;
+      break;
+    }
+  return os;
+}
+
+
+NS_OBJECT_ENSURE_REGISTERED (AlohaNoackNetDevice);
+
+TypeId
+AlohaNoackNetDevice::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::AlohaNoackNetDevice")
+    .SetParent<NetDevice> ()
+    .AddConstructor<AlohaNoackNetDevice> ()
+    .AddAttribute ("Address",
+                   "The MAC address of this device.",
+                   Mac48AddressValue (Mac48Address ("12:34:56:78:90:12")),
+                   MakeMac48AddressAccessor (&AlohaNoackNetDevice::m_address),
+                   MakeMac48AddressChecker ())
+    .AddAttribute ("Queue",
+                   "packets being transmitted get queued here",
+                   PointerValue (),
+                   MakePointerAccessor (&AlohaNoackNetDevice::m_queue),
+                   MakePointerChecker<Queue> ())
+    .AddAttribute ("Mtu", "The Maximum Transmission Unit",
+                   UintegerValue (1500),
+                   MakeUintegerAccessor (&AlohaNoackNetDevice::SetMtu,
+                                         &AlohaNoackNetDevice::GetMtu),
+                   MakeUintegerChecker<uint16_t> (1,65535))
+    .AddAttribute ("Phy", "The PHY layer attached to this device.",
+                   PointerValue (),
+                   MakePointerAccessor (&AlohaNoackNetDevice::GetPhy,
+                                        &AlohaNoackNetDevice::SetPhy),
+                   MakePointerChecker<Object> ())
+    .AddTraceSource ("MacTx",
+                     "Trace source indicating a packet has arrived for transmission by this device",
+                     MakeTraceSourceAccessor (&AlohaNoackNetDevice::m_macTxTrace))
+    .AddTraceSource ("MacTxDrop",
+                     "Trace source indicating a packet has been dropped by the device before transmission",
+                     MakeTraceSourceAccessor (&AlohaNoackNetDevice::m_macTxDropTrace))
+    .AddTraceSource ("MacPromiscRx",
+                     "A packet has been received by this device, has been passed up from the physical layer "
+                     "and is being forwarded up the local protocol stack.  This is a promiscuous trace,",
+                     MakeTraceSourceAccessor (&AlohaNoackNetDevice::m_macPromiscRxTrace))
+    .AddTraceSource ("MacRx",
+                     "A packet has been received by this device, has been passed up from the physical layer "
+                     "and is being forwarded up the local protocol stack.  This is a non-promiscuous trace,",
+                     MakeTraceSourceAccessor (&AlohaNoackNetDevice::m_macRxTrace))
+  ;
+  return tid;
+}
+
+AlohaNoackNetDevice::AlohaNoackNetDevice ()
+  : m_state (IDLE)
+{
+  NS_LOG_FUNCTION (this);
+}
+  
+AlohaNoackNetDevice::~AlohaNoackNetDevice ()
+{
+  NS_LOG_FUNCTION (this);
+  m_queue = 0;
+}
+
+void
+AlohaNoackNetDevice::DoDispose ()
+{
+  NS_LOG_FUNCTION (this);
+  m_queue = 0;
+  m_node = 0;
+  m_channel = 0;
+  m_currentPkt = 0;
+  m_phy = 0;
+  m_phyMacTxStartCallback = MakeNullCallback< bool, Ptr<Packet> > ();
+  NetDevice::DoDispose ();
+}
+
+
+void
+AlohaNoackNetDevice::SetIfIndex (const uint32_t index)
+{
+  NS_LOG_FUNCTION (index);
+  m_ifIndex = index;
+}
+
+uint32_t
+AlohaNoackNetDevice::GetIfIndex (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return m_ifIndex;
+}
+
+bool
+AlohaNoackNetDevice::SetMtu (uint16_t mtu)
+{
+  NS_LOG_FUNCTION (mtu);
+  m_mtu = mtu;
+  return true;
+}
+
+uint16_t
+AlohaNoackNetDevice::GetMtu (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return m_mtu;
+}
+
+
+void
+AlohaNoackNetDevice::SetQueue (Ptr<Queue> q)
+{
+  NS_LOG_FUNCTION (q);
+  m_queue = q;
+}
+
+
+void
+AlohaNoackNetDevice::SetAddress (Address address)
+{
+  NS_LOG_FUNCTION (this);
+  m_address = Mac48Address::ConvertFrom (address);
+}
+
+Address
+AlohaNoackNetDevice::GetAddress (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return m_address;
+}
+
+bool
+AlohaNoackNetDevice::IsBroadcast (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return true;
+}
+
+Address
+AlohaNoackNetDevice::GetBroadcast (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return Mac48Address ("ff:ff:ff:ff:ff:ff");
+}
+
+bool
+AlohaNoackNetDevice::IsMulticast (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return true;
+}
+
+Address
+AlohaNoackNetDevice::GetMulticast (Ipv4Address addr) const
+{
+  NS_LOG_FUNCTION (addr);
+  Mac48Address ad = Mac48Address::GetMulticast (addr);
+  return ad;
+}
+
+
+Address AlohaNoackNetDevice::GetMulticast (Ipv6Address addr) const
+{
+  NS_LOG_FUNCTION (addr);
+  Mac48Address ad = Mac48Address::GetMulticast (addr);
+  return ad;
+}
+
+
+bool
+AlohaNoackNetDevice::IsPointToPoint (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return false;
+}
+
+bool
+AlohaNoackNetDevice::IsBridge (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return false;
+}
+
+
+Ptr<Node>
+AlohaNoackNetDevice::GetNode (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return m_node;
+}
+
+void
+AlohaNoackNetDevice::SetNode (Ptr<Node> node)
+{
+  NS_LOG_FUNCTION (node);
+
+  m_node = node;
+}
+
+void
+AlohaNoackNetDevice::SetPhy (Ptr<Object> phy)
+{
+  NS_LOG_FUNCTION (this << phy);
+  m_phy = phy;
+}
+
+
+Ptr<Object>
+AlohaNoackNetDevice::GetPhy () const
+{
+  NS_LOG_FUNCTION (this);
+  return m_phy;
+}
+
+
+
+Ptr<Channel>
+AlohaNoackNetDevice::GetChannel (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return m_channel;
+}
+
+
+bool
+AlohaNoackNetDevice::NeedsArp (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return true;
+}
+
+bool
+AlohaNoackNetDevice::IsLinkUp (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return m_linkUp;
+}
+
+void
+AlohaNoackNetDevice::AddLinkChangeCallback (Callback<void> callback)
+{
+  NS_LOG_FUNCTION (&callback);
+  m_linkChangeCallbacks.ConnectWithoutContext (callback);
+}
+
+void
+AlohaNoackNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb)
+{
+  NS_LOG_FUNCTION (&cb);
+  m_rxCallback = cb;
+}
+
+void
+AlohaNoackNetDevice::SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb)
+{
+  NS_LOG_FUNCTION (&cb);
+  m_promiscRxCallback = cb;
+}
+
+bool
+AlohaNoackNetDevice::SupportsSendFrom () const
+{
+  NS_LOG_FUNCTION (this);
+  return true;
+}
+
+
+bool
+AlohaNoackNetDevice::Send (Ptr<Packet> packet,const Address& dest, uint16_t protocolNumber)
+{
+  NS_LOG_FUNCTION (packet << dest << protocolNumber);
+  return SendFrom (packet, m_address, dest, protocolNumber);
+}
+
+bool
+AlohaNoackNetDevice::SendFrom (Ptr<Packet> packet, const Address& src, const Address& dest, uint16_t protocolNumber)
+{
+  NS_LOG_FUNCTION (packet << src << dest << protocolNumber);
+
+  LlcSnapHeader llc;
+  llc.SetType (protocolNumber);
+  packet->AddHeader (llc);
+
+  AlohaNoackMacHeader header;
+  header.SetSource (Mac48Address::ConvertFrom (src));
+  header.SetDestination (Mac48Address::ConvertFrom (dest));
+  packet->AddHeader (header);
+
+  m_macTxTrace (packet);
+
+
+
+  //
+  // If the device is idle, transmission starts immediately. Otherwise,
+  // the transmission will be started by NotifyTransmissionEnd
+  //
+  NS_LOG_LOGIC (this << " state=" << m_state);
+  if (m_state == IDLE)
+    {
+      if (m_queue->IsEmpty ())
+        {
+          NS_LOG_LOGIC ("new packet is head of queue, starting TX immediately");
+          m_currentPkt = packet;
+          StartTransmission ();
+        }
+      else
+        {
+          NS_LOG_LOGIC ("enqueueing new packet");
+          if (m_queue->Enqueue (packet) == false)
+            {
+              m_macTxDropTrace (packet);
+              return false;
+            }
+          NS_LOG_LOGIC ("transmitting head-of-queue packet");
+          m_currentPkt = m_queue->Dequeue ();
+          NS_ASSERT (m_currentPkt != 0);
+          StartTransmission ();
+        }
+    }
+  else
+    {
+      NS_LOG_LOGIC ("deferring TX, enqueueing new packet");
+      NS_ASSERT (m_queue);
+      if (m_queue->Enqueue (packet) == false)
+        {
+          m_macTxDropTrace (packet);
+          return false;
+        }
+    }
+  return true;
+}
+
+void
+AlohaNoackNetDevice::SetPhyMacTxStartCallback (PhyMacTxStartCallback c)
+{
+  NS_LOG_FUNCTION (this);
+  m_phyMacTxStartCallback = c;
+}
+
+void
+AlohaNoackNetDevice::StartTransmission ()
+{
+  NS_LOG_FUNCTION (this);
+
+  NS_ASSERT (m_currentPkt != 0);
+  NS_ASSERT (m_state == IDLE);
+
+  if (m_phyMacTxStartCallback (m_currentPkt))
+    {
+      NS_LOG_WARN ("PHY refused to start TX");
+    }
+  else
+    {
+      m_state = TX;
+    }
+}
+
+
+
+void
+AlohaNoackNetDevice::NotifyTransmissionEnd (Ptr<const Packet>)
+{
+  NS_LOG_FUNCTION (this);
+  NS_ASSERT_MSG (m_state == TX, "TX end notified while state != TX");
+  m_state = IDLE;
+  NS_ASSERT (m_queue);
+  if (m_queue->IsEmpty () == false)
+    {
+      m_currentPkt = m_queue->Dequeue ();
+      NS_ASSERT (m_currentPkt);
+      Simulator::ScheduleNow (&AlohaNoackNetDevice::StartTransmission, this);
+    }
+}
+
+
+void
+AlohaNoackNetDevice::NotifyReceptionStart ()
+{
+  NS_LOG_FUNCTION (this);
+}
+
+
+
+void
+AlohaNoackNetDevice::NotifyReceptionEndError ()
+{
+  NS_LOG_FUNCTION (this);
+}
+
+
+
+
+
+void
+AlohaNoackNetDevice::NotifyReceptionEndOk (Ptr<Packet> packet)
+{
+  NS_LOG_FUNCTION (this << packet);
+  AlohaNoackMacHeader header;
+  packet->RemoveHeader (header);
+  NS_LOG_LOGIC ("packet " << header.GetSource () << " --> " << header.GetDestination () << " (here: " << m_address << ")");
+
+  LlcSnapHeader llc;
+  packet->RemoveHeader (llc);
+
+  PacketType packetType;
+  if (header.GetDestination ().IsBroadcast ())
+    {
+      packetType = PACKET_BROADCAST;
+    }
+  else if (header.GetDestination ().IsGroup ())
+    {
+      packetType = PACKET_MULTICAST;
+    }
+  else if (header.GetDestination () == m_address)
+    {
+      packetType = PACKET_HOST;
+    }
+  else
+    {
+      packetType = PACKET_OTHERHOST;
+    }
+
+  NS_LOG_LOGIC ("packet type = " << packetType);
+
+  if (!m_promiscRxCallback.IsNull ())
+    {
+      m_promiscRxCallback (this, packet->Copy (), llc.GetType (), header.GetSource (), header.GetDestination (), packetType);
+    }
+
+  if (packetType != PACKET_OTHERHOST)
+    {
+      m_rxCallback (this, packet, llc.GetType (), header.GetSource () );
+    }
+}
+
+
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/spectrum/aloha-noack-net-device.h	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,227 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#ifndef ALOHA_NOACK_NET_DEVICE_H
+#define ALOHA_NOACK_NET_DEVICE_H
+
+#include <string.h>
+#include <ns3/node.h>
+#include <ns3/address.h>
+#include <ns3/net-device.h>
+#include <ns3/callback.h>
+#include <ns3/packet.h>
+#include <ns3/traced-callback.h>
+#include <ns3/nstime.h>
+#include <ns3/ptr.h>
+#include <ns3/mac48-address.h>
+#include <ns3/phy-mac.h>
+
+namespace ns3 {
+
+
+class SpectrumChannel;
+class Channel;
+class SpectrumErrorModel;
+class Queue;
+
+
+
+/**
+ * This devices implements the following features:
+ *  - layer 3 protocol multiplexing
+ *  - MAC addressing
+ *  - Aloha MAC:
+ *    + packets transmitted as soon as possible
+ *    + a new packet is queued if previous one is still being transmitted
+ *    + no acknowledgements, hence no retransmissions
+ *  - can support any PHY layer compatible with the API defined in phy-mac.h
+ *
+ */
+class AlohaNoackNetDevice : public NetDevice
+{
+public:
+  enum State {
+    IDLE, TX, RX
+  };
+
+  static TypeId GetTypeId (void);
+
+  AlohaNoackNetDevice ();
+  virtual ~AlohaNoackNetDevice ();
+
+
+  /**
+   * set the queue which is going to be used by this device
+   *
+   * @param queue
+   */
+  virtual void SetQueue (Ptr<Queue> queue);
+
+
+  /**
+   * Notify the MAC that the PHY has finished a previously started transmission
+   *
+   */
+  void NotifyTransmissionEnd (Ptr<const Packet>);
+
+  /**
+   * Notify the MAC that the PHY has started a reception
+   *
+   */
+  void NotifyReceptionStart ();
+
+
+  /**
+   * Notify the MAC that the PHY finished a reception with an error
+   *
+   */
+  void NotifyReceptionEndError ();
+
+  /**
+   * Notify the MAC that the PHY finished a reception successfully
+   *
+   * @param p the received packet
+   */
+  void NotifyReceptionEndOk (Ptr<Packet> p);
+
+
+  /**
+   * This class doesn't talk directly with the underlying channel (a
+   * dedicated PHY class is expected to do it), however the NetDevice
+   * specification features a GetChannel() method. This method here
+   * is therefore provide to allow AlohaNoackNetDevice::GetChannel() to have
+   * something meaningful to return.
+   *
+   * @param c the underlying channel
+   */
+  void SetChannel (Ptr<Channel> c);
+
+
+  /**
+   * set the callback used to instruct the lower layer to start a TX
+   *
+   * @param c
+   */
+  void SetPhyMacTxStartCallback (PhyMacTxStartCallback c);
+
+
+
+  /**
+   * Set the Phy object which is attached to this device.
+   * This object is needed so that we can set/get attributes and
+   * connect to trace sources of the PHY from the net device.
+   *
+   * @param phy the Phy object attached to the device.  Note that the
+   * API between the PHY and the above (this NetDevice which also
+   * implements the MAC) is implemented entirely by
+   * callbacks, so we do not require that the PHY inherits by any
+   * specific class.
+   */
+  void SetPhy (Ptr<Object> phy);
+
+  /**
+   * @return a reference to the PHY object embedded in this NetDevice.
+   */
+  Ptr<Object> GetPhy () const;
+
+
+
+  // inherited from NetDevice
+  virtual void SetIfIndex (const uint32_t index);
+  virtual uint32_t GetIfIndex (void) const;
+  virtual Ptr<Channel> GetChannel (void) const;
+  virtual bool SetMtu (const uint16_t mtu);
+  virtual uint16_t GetMtu (void) const;
+  virtual void SetAddress (Address address);
+  virtual Address GetAddress (void) const;
+  virtual bool IsLinkUp (void) const;
+  virtual void AddLinkChangeCallback (Callback<void> callback);
+  virtual bool IsBroadcast (void) const;
+  virtual Address GetBroadcast (void) const;
+  virtual bool IsMulticast (void) const;
+  virtual bool IsPointToPoint (void) const;
+  virtual bool IsBridge (void) const;
+  virtual bool Send (Ptr<Packet> packet, const Address& dest,
+                     uint16_t protocolNumber);
+  virtual bool SendFrom (Ptr<Packet> packet, const Address& source, const Address& dest,
+                         uint16_t protocolNumber);
+  virtual Ptr<Node> GetNode (void) const;
+  virtual void SetNode (Ptr<Node> node);
+  virtual bool NeedsArp (void) const;
+  virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
+  virtual Address GetMulticast (Ipv4Address addr) const;
+  virtual Address GetMulticast (Ipv6Address addr) const;
+  virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb);
+  virtual bool SupportsSendFrom (void) const;
+
+
+
+
+
+private:
+  void NotifyGuardIntervalEnd ();
+  virtual void DoDispose (void);
+
+  /**
+   * start the transmission of a packet by contacting the PHY layer
+   *
+   */
+  void StartTransmission ();
+
+
+  Ptr<Queue> m_queue;
+
+  TracedCallback<Ptr<const Packet> > m_macTxTrace;
+  TracedCallback<Ptr<const Packet> > m_macTxDropTrace;
+  TracedCallback<Ptr<const Packet> > m_macPromiscRxTrace;
+  TracedCallback<Ptr<const Packet> > m_macRxTrace;
+
+  Ptr<Node>    m_node;
+  Ptr<Channel> m_channel;
+
+  Mac48Address m_address;
+
+  NetDevice::ReceiveCallback m_rxCallback;
+  NetDevice::PromiscReceiveCallback m_promiscRxCallback;
+
+  PhyMacTxStartCallback m_phyMacTxStartCallback;
+
+  /**
+   * List of callbacks to fire if the link changes state (up or down).
+   */
+  TracedCallback<> m_linkChangeCallbacks;
+
+
+  uint32_t m_ifIndex;
+  mutable uint32_t m_mtu;
+  bool m_linkUp;
+
+
+  State m_state;
+
+  Ptr<Packet> m_currentPkt;
+
+  Ptr<Object> m_phy;
+};
+
+
+} // namespace ns3
+
+#endif // ALOHA_NOACK_NET_DEVICE_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/spectrum/half-duplex-ideal-phy.cc	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,431 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#include <ns3/waveform-generator.h>
+#include <ns3/object-factory.h>
+#include <ns3/log.h>
+#include <math.h>
+#include <ns3/simulator.h>
+#include <ns3/trace-source-accessor.h>
+#include <ns3/packet-burst.h>
+#include <ns3/callback.h>
+#include "half-duplex-ideal-phy.h"
+#include "spectrum-error-model.h"
+
+NS_LOG_COMPONENT_DEFINE ("HalfDuplexIdealPhy");
+
+namespace ns3 {
+
+
+NS_OBJECT_ENSURE_REGISTERED (HalfDuplexIdealPhy);
+
+HalfDuplexIdealPhy::HalfDuplexIdealPhy ()
+  : m_mobility (0),
+    m_netDevice (0),
+    m_channel (0),
+    m_txPsd (0),
+    m_state (IDLE)
+{
+  m_interference.SetErrorModel (CreateObject<ShannonSpectrumErrorModel> ());
+}
+
+
+HalfDuplexIdealPhy::~HalfDuplexIdealPhy ()
+{
+}
+
+void
+HalfDuplexIdealPhy::DoDispose ()
+{
+  NS_LOG_FUNCTION (this);
+  m_mobility = 0;
+  m_netDevice = 0;
+  m_channel = 0;
+  m_txPsd = 0;
+  m_rxPsd = 0;
+  m_txPacket = 0;
+  m_rxPacket = 0;
+  m_phyMacTxEndCallback      = MakeNullCallback< void, Ptr<const Packet> > ();
+  m_phyMacRxStartCallback    = MakeNullCallback< void > ();
+  m_phyMacRxEndErrorCallback = MakeNullCallback< void > ();
+  m_phyMacRxEndOkCallback    = MakeNullCallback< void, Ptr<Packet> >  ();
+  SpectrumPhy::DoDispose ();
+}
+
+std::ostream& operator<< (std::ostream& os, HalfDuplexIdealPhy::State s)
+{
+  switch (s)     
+    {
+    case HalfDuplexIdealPhy::IDLE:
+      os << "IDLE";
+      break;
+    case HalfDuplexIdealPhy::RX:
+      os << "RX";
+      break;
+    case HalfDuplexIdealPhy::TX:
+      os << "TX";
+      break;
+    default:
+      os << "UNKNOWN";
+      break;
+    }
+  return os;
+}
+
+
+TypeId
+HalfDuplexIdealPhy::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::HalfDuplexIdealPhy")
+    .SetParent<SpectrumPhy> ()
+    .AddConstructor<HalfDuplexIdealPhy> ()
+    .AddAttribute ("Rate",
+                   "The PHY rate used by this device",
+                   DataRateValue (DataRate ("1Mbps")),
+                   MakeDataRateAccessor (&HalfDuplexIdealPhy::SetRate,
+                                         &HalfDuplexIdealPhy::GetRate),
+                   MakeDataRateChecker ())
+    .AddTraceSource ("TxStart",
+                     "Trace fired when a new transmission is started",
+                     MakeTraceSourceAccessor (&HalfDuplexIdealPhy::m_phyTxStartTrace))
+    .AddTraceSource ("TxEnd",
+                     "Trace fired when a previosuly started transmission is finished",
+                     MakeTraceSourceAccessor (&HalfDuplexIdealPhy::m_phyTxEndTrace))
+    .AddTraceSource ("RxStart",
+                     "Trace fired when the start of a signal is detected",
+                     MakeTraceSourceAccessor (&HalfDuplexIdealPhy::m_phyRxStartTrace))
+    .AddTraceSource ("RxAbort",
+                     "Trace fired when a previously started RX is aborted before time",
+                     MakeTraceSourceAccessor (&HalfDuplexIdealPhy::m_phyRxAbortTrace))
+    .AddTraceSource ("RxEndOk",
+                     "Trace fired when a previosuly started RX terminates successfully",
+                     MakeTraceSourceAccessor (&HalfDuplexIdealPhy::m_phyRxEndOkTrace))
+    .AddTraceSource ("RxEndError",
+                     "Trace fired when a previosuly started RX terminates with an error (packet is corrupted)",
+                     MakeTraceSourceAccessor (&HalfDuplexIdealPhy::m_phyRxEndErrorTrace))
+  ;
+  return tid;
+}
+
+
+
+Ptr<Object>
+HalfDuplexIdealPhy::GetDevice ()
+{
+  NS_LOG_FUNCTION (this);
+  return m_netDevice;
+}
+
+
+Ptr<Object>
+HalfDuplexIdealPhy::GetMobility ()
+{
+  NS_LOG_FUNCTION (this);
+  return m_mobility;
+}
+
+
+void
+HalfDuplexIdealPhy::SetDevice (Ptr<Object> d)
+{
+  NS_LOG_FUNCTION (this << d);
+  m_netDevice = d;
+}
+
+
+void
+HalfDuplexIdealPhy::SetMobility (Ptr<Object> m)
+{
+  NS_LOG_FUNCTION (this << m);
+  m_mobility = m;
+}
+
+
+void
+HalfDuplexIdealPhy::SetChannel (Ptr<SpectrumChannel> c)
+{
+  NS_LOG_FUNCTION (this << c);
+  m_channel = c;
+}
+
+Ptr<const SpectrumModel> 
+HalfDuplexIdealPhy::GetRxSpectrumModel () const
+{
+  if (m_txPsd)
+    {
+      return m_txPsd->GetSpectrumModel ();
+    }
+  else
+    {
+      return 0;
+    }
+}
+
+
+SpectrumType
+HalfDuplexIdealPhy::GetSpectrumType ()
+{
+  NS_LOG_FUNCTION (this);
+  static SpectrumType st = SpectrumTypeFactory::Create ("IdealOfdm");
+  return st;
+}
+
+void
+HalfDuplexIdealPhy::SetTxPowerSpectralDensity (Ptr<SpectrumValue> txPsd)
+{
+  NS_LOG_FUNCTION (this << txPsd);
+  NS_ASSERT (txPsd);
+  m_txPsd = txPsd;
+  NS_LOG_INFO ( *txPsd << *m_txPsd);
+}
+
+void
+HalfDuplexIdealPhy::SetNoisePowerSpectralDensity (Ptr<const SpectrumValue> noisePsd)
+{
+  NS_LOG_FUNCTION (this << noisePsd);
+  NS_ASSERT (noisePsd);
+  m_interference.SetNoisePowerSpectralDensity (noisePsd);
+}
+
+void
+HalfDuplexIdealPhy::SetRate (DataRate rate)
+{
+  NS_LOG_FUNCTION (this << rate);
+  m_rate = rate;
+}
+
+DataRate
+HalfDuplexIdealPhy::GetRate () const
+{
+  NS_LOG_FUNCTION (this);
+  return m_rate;
+}
+
+
+void
+HalfDuplexIdealPhy::SetPhyMacTxEndCallback (PhyMacTxEndCallback c)
+{
+  NS_LOG_FUNCTION (this);
+  m_phyMacTxEndCallback = c;
+}
+
+void
+HalfDuplexIdealPhy::SetPhyMacRxStartCallback (PhyMacRxStartCallback c)
+{
+  NS_LOG_FUNCTION (this);
+  m_phyMacRxStartCallback = c;
+}
+
+
+void
+HalfDuplexIdealPhy::SetPhyMacRxEndErrorCallback (PhyMacRxEndErrorCallback c)
+{
+  NS_LOG_FUNCTION (this);
+  m_phyMacRxEndErrorCallback = c;
+}
+
+
+void
+HalfDuplexIdealPhy::SetPhyMacRxEndOkCallback (PhyMacRxEndOkCallback c)
+{
+  NS_LOG_FUNCTION (this);
+  m_phyMacRxEndOkCallback = c;
+}
+
+void 
+HalfDuplexIdealPhy::ChangeState (State newState)
+{
+  NS_LOG_LOGIC (this << " state: " << m_state << " -> " << newState);
+  m_state = newState;
+}
+
+bool
+HalfDuplexIdealPhy::StartTx (Ptr<Packet> p)
+{
+  NS_LOG_FUNCTION (this << p);
+  NS_LOG_LOGIC (this << "state: " << m_state);
+
+  m_phyTxStartTrace (p);
+
+  switch (m_state)
+    {
+    case RX:
+      AbortRx ();
+      // fall through
+
+    case IDLE:
+      {
+        m_txPacket = p;
+        ChangeState (TX);
+        double txTimeSeconds = m_rate.CalculateTxTime (p->GetSize ());
+        Ptr<PacketBurst> pb = Create<PacketBurst> ();
+        pb->AddPacket (p);
+        m_channel->StartTx (pb, m_txPsd, GetSpectrumType (), Seconds (txTimeSeconds), GetObject<SpectrumPhy> ());
+        Simulator::Schedule(Seconds (txTimeSeconds), &HalfDuplexIdealPhy::EndTx, this);
+      }
+      break;
+
+    case TX:
+
+      return true;
+      break;
+    }
+  return false;
+}
+
+
+void
+HalfDuplexIdealPhy::EndTx ()
+{
+  NS_LOG_FUNCTION (this);
+  NS_LOG_LOGIC (this << "state: " << m_state);
+
+  NS_ASSERT (m_state == TX);
+
+  m_phyTxEndTrace (m_txPacket);
+
+  if (!m_phyMacTxEndCallback.IsNull ())
+    {
+      m_phyMacTxEndCallback (m_txPacket);
+    }
+
+  m_txPacket = 0;
+  ChangeState (IDLE);
+}
+
+
+void
+HalfDuplexIdealPhy::StartRx (Ptr<PacketBurst> pb, Ptr <const SpectrumValue> rxPsd, SpectrumType st, Time duration)
+{
+  NS_LOG_FUNCTION (this << pb << rxPsd << st << duration);
+  NS_LOG_LOGIC (this << "state: " << m_state);
+
+  // interference will happen regardless of the state of the receiver
+  m_interference.AddSignal (rxPsd, duration);
+
+  // the device might start RX only if the signal is of a type understood by this device
+  // this corresponds in real device to preamble detection
+  if (st == GetSpectrumType ())
+    {
+      switch (m_state)
+        {
+        case TX:
+          // the PHY will not notice this incoming signal
+          break;
+
+        case RX:
+          // we should check if we should re-sync on a new incoming signal and discard the old one
+          // (somebody calls this the "capture" effect)
+          // criteria considered to do might include the following:
+          //  1) signal strength (e.g., as returned by rxPsd.Norm ())
+          //  2) how much time has passed since previous RX attempt started
+          // if re-sync (capture) is done, then we should call AbortRx ()
+          break;
+
+        case IDLE:
+          // preamble detection and synchronization is supposed to be always successful.
+          NS_LOG_LOGIC (this << " receiving " << pb->GetNPackets () << "  packet(s)" );          
+          NS_ASSERT (pb->GetNPackets () == 1); // this PHY only supports a single packet per waveform
+          Ptr<Packet> p = pb->GetPackets ().front ();
+          m_phyRxStartTrace (p);
+          m_rxPacket = p;
+          m_rxPsd = rxPsd;
+          ChangeState (RX);
+          if (!m_phyMacRxStartCallback.IsNull ())
+            {
+              NS_LOG_LOGIC (this << " calling m_phyMacRxStartCallback");
+              m_phyMacRxStartCallback ();
+            }
+          else
+            {
+              NS_LOG_LOGIC (this << " m_phyMacRxStartCallback is NULL");
+            }
+          m_interference.StartRx (p, rxPsd);
+          NS_LOG_LOGIC (this << " scheduling EndRx with delay " << duration);
+          m_endRxEventId = Simulator::Schedule (duration, &HalfDuplexIdealPhy::EndRx, this);
+
+          break;
+
+        }
+    }
+  
+  NS_LOG_LOGIC (this << "state: " << m_state);
+}
+
+
+void
+HalfDuplexIdealPhy::AbortRx ()
+{
+  NS_LOG_FUNCTION (this);
+  NS_LOG_LOGIC (this << "state: " << m_state);
+
+  NS_ASSERT (m_state == RX);
+  m_phyRxAbortTrace (m_rxPacket);
+  m_endRxEventId.Cancel ();
+  m_rxPacket = 0;
+  ChangeState (IDLE);
+}
+
+
+void
+HalfDuplexIdealPhy::EndRx ()
+{
+  NS_LOG_FUNCTION (this);
+  NS_LOG_LOGIC (this << "state: " << m_state);
+
+  NS_ASSERT (m_state == RX);
+
+  bool rxOk = m_interference.EndRx ();
+
+  if (rxOk)
+    {
+      m_phyRxEndOkTrace (m_rxPacket);
+      if (!m_phyMacRxEndOkCallback.IsNull ())
+        {
+          NS_LOG_LOGIC (this << " calling m_phyMacRxEndOkCallback");
+          m_phyMacRxEndOkCallback (m_rxPacket);
+        }
+      else
+        {
+          NS_LOG_LOGIC (this << " m_phyMacRxEndOkCallback is NULL");
+        }
+    }
+  else
+    {
+      m_phyRxEndErrorTrace (m_rxPacket);
+      if (!m_phyMacRxEndErrorCallback.IsNull ())
+        {
+          NS_LOG_LOGIC (this << " calling m_phyMacRxEndErrorCallback");
+          m_phyMacRxEndErrorCallback ();
+        }
+      else
+        {
+          NS_LOG_LOGIC (this << " m_phyMacRxEndErrorCallback is NULL");
+        }
+    }
+
+  ChangeState (IDLE);
+  m_rxPacket = 0;
+  m_rxPsd = 0;
+}
+
+
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/spectrum/half-duplex-ideal-phy.h	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,235 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#ifndef HALF_DUPLEX_IDEAL_PHY_H
+#define HALF_DUPLEX_IDEAL_PHY_H
+
+
+#include <ns3/spectrum-value.h>
+#include <ns3/mobility-model.h>
+#include <ns3/packet.h>
+#include <ns3/nstime.h>
+#include <ns3/net-device.h>
+#include <ns3/spectrum-phy.h>
+#include <ns3/spectrum-channel.h>
+#include <ns3/spectrum-type.h>
+#include <ns3/spectrum-interference.h>
+#include <ns3/data-rate.h>
+#include <ns3/phy-mac.h>
+
+namespace ns3 {
+
+
+
+/**
+ * This PHY layer implementation realizes an ideal OFDM PHY which
+ * transmits half-duplex (i.e., it can either receive or transmit at a
+ * given time). The device is ideal in the sense that:
+ * 1) it uses an error model based on the Shannon capacity, which
+ * assumes ideal channel coding;
+ * 2) it uses ideal signal acquisition, i.e., preamble detection and
+ * synchronization are always successful
+ * 3) it has no PHY layer overhead
+ *
+ * Being half duplex, if a RX is ongoing but a TX is requested, the RX
+ * is aborted and the TX is started. Of course, no RX can be performed
+ * while there is an ongoing TX.
+ *
+ * The use of OFDM is modeled by means of the Spectrum framework. By
+ * calling the method SetTxPowerSpectralDensity(), the
+ * user can specify how much of the spectrum is used, how many
+ * subcarriers are used, and what power is allocated to each
+ * subcarrier.
+ *
+ * The user can also specify the PHY rate
+ * at which communications take place by using SetRate(). This is
+ * equivalent to choosing a particular modulation and coding scheme.
+ *
+ * The use of the ShannonSpectrumErrorModel allows us to account for
+ * the following aspects in determining whether a
+ * transmission is successful or not:
+ * - the PHY rate (trades off communication speed with reliability)
+ * - the power spectral density (trade-off among total power consumed,
+ * total bandwidth used (i.e., how much of the spectrum is occupied),
+ * and communication reliability)
+ * - the signal propagation
+ */
+class HalfDuplexIdealPhy : public SpectrumPhy
+{
+
+public:
+  HalfDuplexIdealPhy ();
+  virtual ~HalfDuplexIdealPhy ();
+
+  /**
+   *  PHY states
+   *
+   */
+  enum State {
+    IDLE, TX, RX
+  };
+
+  static TypeId GetTypeId (void);
+
+  // inherited from SpectrumPhy
+  void SetChannel (Ptr<SpectrumChannel> c);
+  void SetMobility (Ptr<Object> m);
+  void SetDevice (Ptr<Object> d);
+  Ptr<Object> GetMobility ();
+  Ptr<Object> GetDevice ();
+  Ptr<const SpectrumModel> GetRxSpectrumModel () const;
+  void StartRx (Ptr<PacketBurst> p, Ptr <const SpectrumValue> rxPsd, SpectrumType st, Time duration);
+  
+
+
+  /**
+   * Get the SpectrumType used by this PHY
+   *
+   * @return
+   */
+  SpectrumType GetSpectrumType ();
+
+
+  /**
+   * set the Power Spectral Density of outgoing signals in power units
+   * (Watt, Pascal...) per Hz.
+   *
+   * @param txPsd
+   */
+  void SetTxPowerSpectralDensity (Ptr<SpectrumValue> txPsd);
+
+  /**
+   *
+   * @param noisePsd the Noise Power Spectral Density in power units
+   * (Watt, Pascal...) per Hz.
+   */
+  void SetNoisePowerSpectralDensity (Ptr<const SpectrumValue> noisePsd);
+
+
+  /**
+   * 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 PHY rate to be used by this PHY.
+   *
+   * @param rate
+   */
+  void SetRate (DataRate rate);
+
+  /**
+   *
+   * @return the PHY rate used by this PHY.
+   */
+  DataRate GetRate () const;
+
+  /**
+   * set the callback for the end of a TX, as part of the
+   * interconnections betweenthe PHY and the MAC
+   *
+   * @param c the callback
+   */
+  void SetPhyMacTxEndCallback (PhyMacTxEndCallback c);
+
+  /**
+   * set the callback for the start of RX, as part of the
+   * interconnections betweenthe PHY and the MAC
+   *
+   * @param c the callback
+   */
+  void SetPhyMacRxStartCallback (PhyMacRxStartCallback c);
+
+  /**
+   * set the callback for the end of a RX in error, as part of the
+   * interconnections betweenthe PHY and the MAC
+   *
+   * @param c the callback
+   */
+  void SetPhyMacRxEndErrorCallback (PhyMacRxEndErrorCallback c);
+
+  /**
+   * set the callback for the successful end of a RX, as part of the
+   * interconnections betweenthe PHY and the MAC
+   *
+   * @param c the callback
+   */
+  void SetPhyMacRxEndOkCallback (PhyMacRxEndOkCallback c);
+
+
+
+private:
+
+  virtual void DoDispose (void);
+  
+  void ChangeState (State newState);
+  void EndTx ();
+  void AbortRx ();
+  void EndRx ();
+
+  EventId m_endRxEventId;
+
+  Ptr<Object> m_mobility;
+  Ptr<Object> m_netDevice;
+  Ptr<SpectrumChannel> m_channel;
+
+  Ptr<SpectrumValue> m_txPsd;
+  Ptr<const SpectrumValue> m_rxPsd;
+  Ptr<Packet> m_txPacket;
+  Ptr<Packet> m_rxPacket;
+
+  DataRate m_rate;
+
+  State m_state;
+
+  TracedCallback<Ptr<const Packet> > m_phyTxStartTrace;
+  TracedCallback<Ptr<const Packet> > m_phyTxEndTrace;
+  TracedCallback<Ptr<const Packet> > m_phyRxStartTrace;
+  TracedCallback<Ptr<const Packet> > m_phyRxAbortTrace;
+  TracedCallback<Ptr<const Packet> > m_phyRxEndOkTrace;
+  TracedCallback<Ptr<const Packet> > m_phyRxEndErrorTrace;
+
+  PhyMacTxEndCallback        m_phyMacTxEndCallback;
+  PhyMacRxStartCallback      m_phyMacRxStartCallback;
+  PhyMacRxEndErrorCallback   m_phyMacRxEndErrorCallback;
+  PhyMacRxEndOkCallback      m_phyMacRxEndOkCallback;
+
+  SpectrumInterference m_interference;
+
+};
+
+
+
+
+
+
+}
+
+
+
+
+
+#endif /* HALF_DUPLEX_IDEAL_PHY_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/spectrum/microwave-oven-spectrum-value-helper.cc	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,165 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#include "ns3/log.h"
+#include "microwave-oven-spectrum-value-helper.h"
+
+NS_LOG_COMPONENT_DEFINE ("MicrowaveOvenSpectrumValue");
+
+namespace ns3 {
+
+  
+Ptr<SpectrumModel> g_MicrowaveOvenSpectrumModel5Mhz;
+Ptr<SpectrumModel> g_MicrowaveOvenSpectrumModel6Mhz;
+
+
+class MicrowaveOvenSpectrumModel5MhzInitializer
+{
+public:
+  MicrowaveOvenSpectrumModel5MhzInitializer ()
+  {
+    NS_LOG_FUNCTION(this);
+    Bands bands;
+   for (double fl = 2400e6; fl < 2499e6; fl += 5e6)
+      {
+        BandInfo bi;
+        bi.fl = fl;
+        bi.fc = fl + 5e6;
+        bi.fh = fl + 10e6;
+        bands.push_back (bi);
+      }
+   NS_LOG_LOGIC("bands.size () :" << bands.size ());
+   g_MicrowaveOvenSpectrumModel5Mhz = Create<SpectrumModel> (bands);
+  }
+} g_MicrowaveOvenSpectrumModel5MhzInitializerInstance;
+
+
+
+class MicrowaveOvenSpectrumModel6MhzInitializer
+{
+public:
+  MicrowaveOvenSpectrumModel6MhzInitializer ()
+  {
+    NS_LOG_FUNCTION(this);
+    Bands bands;
+    for (double fl = 2360e6; fl < 2479e6; fl += 6e6)
+      {
+        BandInfo bi;
+        bi.fl = fl;
+        bi.fc = fl + 6e6;
+        bi.fh = fl + 12e6;
+        bands.push_back (bi);
+      }
+    NS_LOG_LOGIC("bands.size () :" << bands.size ());
+    g_MicrowaveOvenSpectrumModel6Mhz = Create<SpectrumModel> (bands);
+  }
+} g_MicrowaveOvenSpectrumModel6MhzInitializerInstance;
+
+
+
+
+
+Ptr<SpectrumValue> 
+MicrowaveOvenSpectrumValueHelper::CreatePowerSpectralDensityMwo1 ()
+{  
+  Ptr<SpectrumValue> psd = Create <SpectrumValue> (g_MicrowaveOvenSpectrumModel6Mhz);
+
+  // values from this paper:
+  // Tanim M. Taher, Matthew J. Misurac, Joseph L. LoCicero, and Donald R. Ucci, 
+  // "MICROWAVE OVEN SIGNAL MODELING", in Proc. of IEEE WCNC, 2008,
+  // see Figure 3, "Experimental PSD of MWO #1"
+  // the figure has a resolution of 12 MHz per division; we use a
+  // SpectrumModel with a per-subband bandwidth of 6MHz, so we have
+  // two samples per division. The values used here are an approximation
+  // of what appears in the figure.
+
+  (*psd)[0] = -67.5;
+  (*psd)[1] = -67.5;
+  (*psd)[2] = -67.5;
+  (*psd)[3] = -67.5;
+  (*psd)[4] = -67.5;
+  (*psd)[5] = -66;
+  (*psd)[6] = -64;
+  (*psd)[7] = -63;
+  (*psd)[8] = -62.5;
+  (*psd)[9] = -63;
+  (*psd)[10] = -62.5;
+  (*psd)[11] = -62.5;
+  (*psd)[12] = -58;
+  (*psd)[13] = -53.5;
+  (*psd)[14] = -44;
+  (*psd)[15] = -38;
+  (*psd)[16] = -45;
+  (*psd)[17] = -65;
+  (*psd)[18] = -67.5;
+  (*psd)[19] = -67.5;
+
+  // convert to W/Hz
+  (*psd) = Pow(10.0, ((*psd) - 30)/10.0);
+
+  return psd;
+}
+
+
+
+Ptr<SpectrumValue> 
+MicrowaveOvenSpectrumValueHelper::CreatePowerSpectralDensityMwo2 ()
+{  
+  // values from this paper:
+  // Tanim M. Taher, Matthew J. Misurac, Joseph L. LoCicero, and Donald R. Ucci, 
+  // "MICROWAVE OVEN SIGNAL MODELING", in Proc. of IEEE WCNC, 2008,
+  // see Figure 9, "Experimental PSD of actual MWO #2"
+  // the figure has a resolution of 10 MHz per division; we use a
+  // SpectrumModel with a per-subband bandwidth of 5MHz, so we have
+  // two samples per division. The values used here are an approximation
+  // of what appears in the figure.
+
+  Ptr<SpectrumValue> psd = Create <SpectrumValue> (g_MicrowaveOvenSpectrumModel5Mhz);
+
+  (*psd)[0] = -68; 
+  (*psd)[1] = -68; 
+  (*psd)[2] = -68;
+  (*psd)[3] = -68;
+  (*psd)[4] = -65; 
+  (*psd)[5] = -62;
+  (*psd)[6] = -56; 
+  (*psd)[7] = -55; 
+  (*psd)[8] = -47;
+  (*psd)[9] = -40;
+  (*psd)[10] = -37;
+  (*psd)[11] = -33;
+  (*psd)[12] = -45;
+  (*psd)[13] = -67;
+  (*psd)[14] = -68;
+  (*psd)[15] = -68;
+  (*psd)[16] = -68;
+  (*psd)[17] = -68;
+  (*psd)[18] = -68;
+  (*psd)[19] = -68;
+
+  // convert to W/Hz
+  (*psd) = Pow(10.0, ((*psd) - 30)/10.0);
+
+  return psd;
+}
+
+
+
+} //namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/spectrum/microwave-oven-spectrum-value-helper.h	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,67 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#ifndef MICROWAVE_OVEN_SPECTRUM_VALUE_HELPER_H
+#define MICROWAVE_OVEN_SPECTRUM_VALUE_HELPER_H
+
+
+#include <ns3/spectrum-value.h>
+
+namespace ns3 {
+
+
+
+/** 
+ * This class provides methods for the creation of SpectrumValue
+ * instances that mimic the Power Spectral Density of commercial
+ * microwave ovens based on the measurements reported in the following paper:
+ * Tanim M. Taher, Matthew J. Misurac, Joseph L. LoCicero, and Donald R. Ucci, 
+ * "MICROWAVE OVEN SIGNAL MODELING", in Proc. of IEEE WCNC, 2008
+ *
+ */
+class MicrowaveOvenSpectrumValueHelper 
+{
+public:
+
+  /** 
+   * 
+   * @return the Power Spectral Density of Micro Wave Oven #1 in the
+   * cited paper
+   */
+  static Ptr<SpectrumValue> CreatePowerSpectralDensityMwo1 ();
+
+  /** 
+   * 
+   * @return the Power Spectral Density of Micro Wave Oven #2 in the
+   * cited paper
+   */  
+  static Ptr<SpectrumValue> CreatePowerSpectralDensityMwo2 ();
+
+};
+
+
+
+
+  
+} //namespace ns3
+
+
+
+#endif /*  MICROWAVE_OVEN_SPECTRUM_VALUE_HELPER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/spectrum/multi-model-spectrum-channel.cc	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,347 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#include <ns3/object.h>
+#include <ns3/simulator.h>
+#include <ns3/log.h>
+#include <ns3/packet.h>
+#include <ns3/packet-burst.h>
+#include <ns3/net-device.h>
+#include <ns3/node.h>
+#include <ns3/mobility-model.h>
+#include <ns3/spectrum-phy.h>
+#include <ns3/spectrum-converter.h>
+#include <iostream>
+#include <utility>
+#include "multi-model-spectrum-channel.h"
+
+
+NS_LOG_COMPONENT_DEFINE ("MultiModelSpectrumChannel");
+
+
+namespace ns3 {
+
+
+NS_OBJECT_ENSURE_REGISTERED (MultiModelSpectrumChannel);
+
+
+std::ostream& operator<< (std::ostream& lhs, TxSpectrumModelInfoMap_t& rhs)
+{
+  for (TxSpectrumModelInfoMap_t::iterator it = rhs.begin ();
+       it != rhs.end ();
+       ++it)
+    {
+      SpectrumConverterMap_t::iterator jt;
+      for (jt = it->second.m_spectrumConverterMap.begin ();
+           jt != it->second.m_spectrumConverterMap.end ();
+           ++jt)
+        {
+          lhs << "(" << it->first << "," << jt->first << ") ";
+        }
+    }
+  return lhs;
+}
+
+TxSpectrumModelInfo::TxSpectrumModelInfo (Ptr<const SpectrumModel> txSpectrumModel)
+  : m_txSpectrumModel (txSpectrumModel)
+{
+}
+
+
+RxSpectrumModelInfo::RxSpectrumModelInfo (Ptr<const SpectrumModel> rxSpectrumModel)
+  : m_rxSpectrumModel (rxSpectrumModel)
+{
+}
+
+
+MultiModelSpectrumChannel::MultiModelSpectrumChannel ()
+  : m_PropagationDelay (0),
+    m_PropagationLoss (0)
+{
+  NS_LOG_FUNCTION (this);
+}
+
+void
+MultiModelSpectrumChannel::DoDispose ()
+{
+  NS_LOG_FUNCTION (this);
+  m_PropagationLoss = 0;
+  m_PropagationDelay = 0;
+  m_txSpectrumModelInfoMap.clear ();
+  m_rxSpectrumModelInfoMap.clear ();
+  m_phyVector.clear ();
+}
+
+TypeId
+MultiModelSpectrumChannel::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::MultiModelSpectrumChannel")
+    .SetParent<SpectrumChannel> ()
+    .AddConstructor<MultiModelSpectrumChannel> ()
+  ;
+  return tid;
+}
+
+
+
+void
+MultiModelSpectrumChannel::AddRx (Ptr<SpectrumPhy> phy)
+{
+  NS_LOG_FUNCTION (this << phy);
+
+  Ptr<const SpectrumModel> rxSpectrumModel = phy->GetRxSpectrumModel ();
+
+  NS_ASSERT_MSG ((0 != rxSpectrumModel), "phy->GetRxSpectrumModel () returned 0. Please check that the RxSpectrumModel is already set for the phy before calling MultiModelSpectrumChannel::AddRx (phy)");
+
+  SpectrumModelUid_t rxSpectrumModelUid = rxSpectrumModel->GetUid ();
+    
+  std::vector<Ptr<SpectrumPhy> >::const_iterator it;
+
+  // make sure this phy had not been already added
+  for ( it = m_phyVector.begin (); it != m_phyVector.end (); ++it)
+    {
+      NS_ASSERT (*it != phy);
+    }
+  m_phyVector.push_back (phy);
+    
+  RxSpectrumModelInfoMap_t::iterator rxInfoIterator = m_rxSpectrumModelInfoMap.find (rxSpectrumModelUid);
+
+  if (rxInfoIterator == m_rxSpectrumModelInfoMap.end ())
+    {
+      // spectrum model unknown, add it to the list of RxSpectrumModels
+      std::pair<RxSpectrumModelInfoMap_t::iterator, bool> ret;
+      ret = m_rxSpectrumModelInfoMap.insert (std::make_pair (rxSpectrumModelUid, RxSpectrumModelInfo (rxSpectrumModel)));            
+      NS_ASSERT (ret.second);
+      // also add the phy to the newly created list of SpectrumPhy for this RxSpectrumModel
+      ret.first->second.m_rxPhyList.push_back (phy);
+      
+      // and create the necessary converters for all the TX spectrum models that we know of
+      for (TxSpectrumModelInfoMap_t::iterator txInfoIterator = m_txSpectrumModelInfoMap.begin ();
+           txInfoIterator != m_txSpectrumModelInfoMap.end ();
+           ++txInfoIterator)
+        {
+          Ptr<const SpectrumModel> txSpectrumModel = txInfoIterator->second.m_txSpectrumModel;
+          SpectrumModelUid_t txSpectrumModelUid = txSpectrumModel->GetUid ();
+          NS_LOG_LOGIC ("Creating converters between SpectrumModelUids " << txSpectrumModelUid << " and " << rxSpectrumModelUid );
+          SpectrumConverter converter (txSpectrumModel, rxSpectrumModel);
+          std::pair<SpectrumConverterMap_t::iterator, bool> ret2;
+          ret2 = txInfoIterator->second.m_spectrumConverterMap.insert (std::make_pair (rxSpectrumModelUid, converter));                     
+          NS_ASSERT (ret2.second);
+        }
+    }
+  else
+    {
+      // spectrum model is already known, just add the device to the corresponding list
+      rxInfoIterator->second.m_rxPhyList.push_back (phy);
+    }
+  
+}
+
+
+TxSpectrumModelInfoMap_t::const_iterator
+MultiModelSpectrumChannel::FindAndEventuallyAddTxSpectrumModel (Ptr<const SpectrumModel> txSpectrumModel)
+{
+  NS_LOG_FUNCTION (this << txSpectrumModel);
+  SpectrumModelUid_t txSpectrumModelUid = txSpectrumModel->GetUid ();
+  TxSpectrumModelInfoMap_t::iterator txInfoIterator = m_txSpectrumModelInfoMap.find (txSpectrumModelUid);
+  
+  if (txInfoIterator == m_txSpectrumModelInfoMap.end ())
+    {     
+      // first time we see this TX SpectrumModel
+      // we add it to the list
+      std::pair<TxSpectrumModelInfoMap_t::iterator, bool> ret;
+      ret = m_txSpectrumModelInfoMap.insert (std::make_pair (txSpectrumModelUid, TxSpectrumModelInfo (txSpectrumModel)));
+      NS_ASSERT (ret.second); 
+      txInfoIterator = ret.first;
+      
+      // and we create the converters for all the RX SpectrumModels that we know of
+      for (RxSpectrumModelInfoMap_t::const_iterator rxInfoIterator = m_rxSpectrumModelInfoMap.begin ();
+           rxInfoIterator != m_rxSpectrumModelInfoMap.end ();
+           ++rxInfoIterator)
+        {
+          Ptr<const SpectrumModel> rxSpectrumModel = rxInfoIterator->second.m_rxSpectrumModel;
+          SpectrumModelUid_t rxSpectrumModelUid = rxSpectrumModel->GetUid ();
+
+          if (rxSpectrumModelUid != txSpectrumModelUid)
+            {
+              NS_LOG_LOGIC ("Creating converters between SpectrumModelUids " << txSpectrumModelUid << " and " << rxSpectrumModelUid );
+
+              SpectrumConverter converter (txSpectrumModel, rxSpectrumModel);
+              std::pair<SpectrumConverterMap_t::iterator, bool> ret2;
+              ret2 = txInfoIterator->second.m_spectrumConverterMap.insert (std::make_pair (rxSpectrumModelUid, converter));                     
+              NS_ASSERT (ret2.second);
+            }
+        }                
+    }
+  else
+    {
+      NS_LOG_LOGIC ("SpectrumModelUid " << txSpectrumModelUid << " already present");     
+    }
+  return txInfoIterator;
+}
+
+
+void
+MultiModelSpectrumChannel::StartTx (Ptr<PacketBurst> p, Ptr <SpectrumValue> originalTxPowerSpectrum, SpectrumType st, Time duration, Ptr<SpectrumPhy> txPhy)
+{
+  NS_LOG_FUNCTION (this << p << *originalTxPowerSpectrum << duration << txPhy);
+
+  NS_ASSERT (txPhy);
+  NS_ASSERT (originalTxPowerSpectrum);
+  
+
+  Ptr<MobilityModel> txMobility = txPhy->GetMobility ()->GetObject<MobilityModel> ();
+  SpectrumModelUid_t txSpectrumModelUid = originalTxPowerSpectrum->GetSpectrumModelUid ();
+  NS_LOG_LOGIC (" txSpectrumModelUid " << txSpectrumModelUid);
+
+  //
+  TxSpectrumModelInfoMap_t::const_iterator txInfoIteratorerator = FindAndEventuallyAddTxSpectrumModel (originalTxPowerSpectrum->GetSpectrumModel ());
+  NS_ASSERT (txInfoIteratorerator != m_txSpectrumModelInfoMap.end ());
+
+  NS_LOG_LOGIC ("converter map for TX SpectrumModel with Uid " << txInfoIteratorerator->first);
+  NS_LOG_LOGIC ("converter map size: " << txInfoIteratorerator->second.m_spectrumConverterMap.size ());
+  NS_LOG_LOGIC ("converter map first element: " << txInfoIteratorerator->second.m_spectrumConverterMap.begin ()->first);
+
+  for (RxSpectrumModelInfoMap_t::const_iterator rxInfoIterator = m_rxSpectrumModelInfoMap.begin ();
+       rxInfoIterator != m_rxSpectrumModelInfoMap.end ();
+       ++rxInfoIterator)
+    {
+      SpectrumModelUid_t rxSpectrumModelUid = rxInfoIterator->second.m_rxSpectrumModel->GetUid ();
+      NS_LOG_LOGIC (" rxSpectrumModelUids " << rxSpectrumModelUid);
+
+      Ptr <SpectrumValue> convertedTxPowerSpectrum;
+
+      if (txSpectrumModelUid == rxSpectrumModelUid)
+        {
+          NS_LOG_LOGIC ("no conversion needed");
+          convertedTxPowerSpectrum = originalTxPowerSpectrum;
+        }
+      else
+        {
+          NS_LOG_LOGIC (" converting txPowerSpectrum SpectrumModelUids" << txSpectrumModelUid << " --> " << rxSpectrumModelUid);
+          SpectrumConverterMap_t::const_iterator rxConverterIterator = txInfoIteratorerator->second.m_spectrumConverterMap.find (rxSpectrumModelUid);
+          NS_ASSERT (rxConverterIterator != txInfoIteratorerator->second.m_spectrumConverterMap.end ());
+          convertedTxPowerSpectrum = rxConverterIterator->second.Convert (originalTxPowerSpectrum);
+        }
+
+      std::list<Ptr<SpectrumPhy> >::const_iterator rxPhyIterator = rxInfoIterator->second.m_rxPhyList.begin ();
+      while (rxPhyIterator != rxInfoIterator->second.m_rxPhyList.end ())
+        {
+          NS_ASSERT_MSG ((*rxPhyIterator)->GetRxSpectrumModel ()->GetUid () == rxSpectrumModelUid,
+                         "MultiModelSpectrumChannel only supports devices that use a single RxSpectrumModel that does not change for the whole simulation");
+          
+          if ((*rxPhyIterator) != txPhy)
+            {
+              Ptr <SpectrumValue> rxPowerSpectrum;
+              Time delay;
+              Ptr<MobilityModel> receiverMobility = (*rxPhyIterator)->GetMobility ()->GetObject<MobilityModel> ();
+
+              if (txMobility && receiverMobility)
+                {
+                  if (m_PropagationLoss)
+                    {
+                      rxPowerSpectrum = m_PropagationLoss->CalcRxPowerSpectralDensity (convertedTxPowerSpectrum, txMobility, receiverMobility);
+                    }
+                  else
+                    {
+                      // rxPowerSpectrum = Copy<SpectrumValue> (convertedTxPowerSpectrum);
+                      rxPowerSpectrum = convertedTxPowerSpectrum->Copy ();
+                    }
+
+                  if (m_PropagationDelay)
+                    {
+                      delay = m_PropagationDelay->GetDelay (txMobility, receiverMobility);
+                    }
+                  else
+                    {
+                      delay = MicroSeconds (0);
+                    }
+                }
+              else
+                {
+                  // rxPowerSpectrum = Copy<SpectrumValue> (convertedTxPowerSpectrum);
+                  rxPowerSpectrum = convertedTxPowerSpectrum->Copy ();
+                  delay = MicroSeconds (0);
+                }
+
+              Ptr<PacketBurst> pktBurstCopy = p->Copy ();
+              Ptr<Object> netDevObj = (*rxPhyIterator)->GetDevice ();
+              if (netDevObj)
+                {
+                  // the receiver has a NetDevice, so we expect that it is attached to a Node
+                  uint32_t dstNode =  netDevObj->GetObject<NetDevice> ()->GetNode ()->GetId ();
+                  Simulator::ScheduleWithContext (dstNode, delay, &MultiModelSpectrumChannel::StartRx, this,
+                                                  pktBurstCopy, rxPowerSpectrum, st, duration, *rxPhyIterator);
+                }
+              else
+                {
+                  // the receiver is not attached to a NetDevice, so we cannot assume that it is attached to a node
+                  Simulator::Schedule (delay, &MultiModelSpectrumChannel::StartRx, this,
+                                       pktBurstCopy, rxPowerSpectrum, st, duration, *rxPhyIterator);
+                }
+            }         
+          ++rxPhyIterator;
+        }
+
+    }
+
+}
+
+void
+MultiModelSpectrumChannel::StartRx (Ptr<PacketBurst> pb, Ptr <SpectrumValue> rxPsd, SpectrumType st, Time duration, Ptr<SpectrumPhy> receiver)
+{
+  NS_LOG_FUNCTION (this);
+  receiver->StartRx (pb, rxPsd, st, duration);
+}
+
+
+
+uint32_t
+MultiModelSpectrumChannel::GetNDevices (void) const
+{
+  return m_phyVector.size ();
+
+}
+
+
+Ptr<NetDevice>
+MultiModelSpectrumChannel::GetDevice (uint32_t i) const
+{
+  return m_phyVector.at (i)->GetDevice ()->GetObject<NetDevice> ();
+}
+
+
+
+void
+MultiModelSpectrumChannel::AddSpectrumPropagationLossModel (Ptr<SpectrumPropagationLossModel> loss)
+{
+  NS_ASSERT (m_PropagationLoss == 0);
+  m_PropagationLoss = loss;
+}
+
+void
+MultiModelSpectrumChannel::SetPropagationDelayModel (Ptr<PropagationDelayModel> delay)
+{
+  NS_ASSERT (m_PropagationDelay == 0);
+  m_PropagationDelay = delay;
+}
+
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/spectrum/multi-model-spectrum-channel.h	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,188 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+
+#ifndef MULTI_MODEL_SPECTRUM_CHANNEL_H
+#define MULTI_MODEL_SPECTRUM_CHANNEL_H
+
+#include <ns3/spectrum-value.h>
+#include <ns3/spectrum-converter.h>
+#include <ns3/spectrum-channel.h>
+#include <ns3/spectrum-propagation-loss-model.h>
+#include <ns3/propagation-delay-model.h>
+#include <map>
+#include <list>
+
+namespace ns3 {
+
+
+typedef std::map<SpectrumModelUid_t, SpectrumConverter> SpectrumConverterMap_t;
+
+
+class TxSpectrumModelInfo
+{
+public:
+  TxSpectrumModelInfo (Ptr<const SpectrumModel> txSpectrumModel);
+  
+  Ptr<const SpectrumModel> m_txSpectrumModel;
+  SpectrumConverterMap_t m_spectrumConverterMap;
+};
+
+typedef std::map<SpectrumModelUid_t, TxSpectrumModelInfo> TxSpectrumModelInfoMap_t;
+
+
+class RxSpectrumModelInfo
+{
+public:
+  RxSpectrumModelInfo (Ptr<const SpectrumModel> rxSpectrumModel);
+  
+  Ptr<const SpectrumModel> m_rxSpectrumModel;
+  std::list<Ptr<SpectrumPhy> > m_rxPhyList;  
+};
+
+typedef std::map<SpectrumModelUid_t, RxSpectrumModelInfo> RxSpectrumModelInfoMap_t;
+
+
+
+
+/**
+ * This SpectrumChannel implementation can handle the presence of
+ * SpectrumPhy instances which can use
+ * different spectrum models, i.e.,  different SpectrumModel. The only
+ * requirement is that every SpectrumPhy instance uses the same
+ * SpectrumModel for the whole simulation.
+ */
+class MultiModelSpectrumChannel : public SpectrumChannel
+{
+
+public:
+  MultiModelSpectrumChannel ();
+
+  static TypeId GetTypeId (void);
+
+  /**
+   *
+   *
+   * @param phy
+   */
+
+
+  // inherited from SpectrumChannel
+  virtual void AddSpectrumPropagationLossModel (Ptr<SpectrumPropagationLossModel> loss);
+  virtual void SetPropagationDelayModel (Ptr<PropagationDelayModel> delay);
+  virtual void AddRx (Ptr<SpectrumPhy> phy);
+  virtual void StartTx (Ptr<PacketBurst> p, Ptr <SpectrumValue> rxPsd, SpectrumType st, Time duration, Ptr<SpectrumPhy> sender);
+
+
+  // inherited from Channel
+  virtual uint32_t GetNDevices (void) const;
+  virtual Ptr<NetDevice> GetDevice (uint32_t i) const;
+
+
+protected:
+  void DoDispose ();
+
+
+
+private:
+ 
+
+  /** 
+   * this method checks if m_rxSpectrumModelInfoMap contains an entry
+   * for the given TX SpectrumModel. If such entry exists, it returns
+   * an interator pointing to it. If not, it creates a new entry in
+   * m_txSpectrumMpodelInfoMap, and returns an iterator to it.
+   * 
+   * @param txSpectrumModel the TX SpectrumModel  being considered
+   * 
+   * @return an iterator pointing to the corresponding entry in m_txSpectrumModelInfoMap
+   */
+  TxSpectrumModelInfoMap_t::const_iterator FindAndEventuallyAddTxSpectrumModel (Ptr<const SpectrumModel> txSpectrumModel);
+
+
+  /** 
+   * make sure that there are SpectrumConverters from any
+   * SpectrumPhy being used for TX to the given SpectrumModel being used for RX
+   * 
+   * @param rxPhy the RXing SpectrumPhy
+   * @param rxSpectrumModel the SpectrumModel used for RX by rxPhy
+   */
+  void CheckAddRxSpectrumModel (Ptr<SpectrumPhy> rxPhy, Ptr<const SpectrumModel> rxSpectrumModel);
+
+
+
+  /**
+   * used internally to reschedule transmission after the propagation delay
+   *
+   * @param p
+   * @param rxPowerSpectrum
+   * @param duration
+   * @param receiver
+   */
+  virtual void StartRx (Ptr<PacketBurst> p, Ptr <SpectrumValue> rxPowerSpectrum, SpectrumType st, Time duration, Ptr<SpectrumPhy> receiver);
+
+
+
+  /**
+   * propagation delay model to be used with this channel
+   *
+   */
+  Ptr<PropagationDelayModel> m_PropagationDelay;
+
+
+  /**
+   * propagation loss model to be used with this channel
+   *
+   */
+  Ptr<SpectrumPropagationLossModel> m_PropagationLoss;
+
+
+
+  /**
+   * data structure holding, for each TX SpectrumModel,  all the
+   * converters to any RX SpectrumModel, and all the corresponding
+   * SpectrumPhy instances. 
+   * 
+   */
+  TxSpectrumModelInfoMap_t m_txSpectrumModelInfoMap;
+
+
+  /**
+   * data structure holding, for each RX spectrum model, all the
+   * corresponding SpectrumPhy instances.
+   * 
+   */
+  RxSpectrumModelInfoMap_t m_rxSpectrumModelInfoMap;
+  
+  /**
+   * this is only used to provide a straighforward implementation of
+   * GetNDevices() and GetDevice()
+   *
+   */
+  std::vector<Ptr<SpectrumPhy> > m_phyVector;
+};
+
+
+
+}
+
+
+
+#endif /* MULTI_MODEL_SPECTRUM_CHANNEL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/spectrum/non-communicating-net-device.cc	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,263 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#include "ns3/log.h"
+#include "ns3/queue.h"
+#include "ns3/simulator.h"
+#include "ns3/enum.h"
+#include "ns3/boolean.h"
+#include "ns3/uinteger.h"
+#include "ns3/pointer.h"
+#include "ns3/channel.h"
+#include "non-communicating-net-device.h"
+
+
+NS_LOG_COMPONENT_DEFINE ("NonCommunicatingNetDevice");
+
+
+namespace ns3 {
+
+
+
+NS_OBJECT_ENSURE_REGISTERED (NonCommunicatingNetDevice);
+
+TypeId
+NonCommunicatingNetDevice::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::NonCommunicatingNetDevice")
+    .SetParent<NetDevice> ()
+    .AddConstructor<NonCommunicatingNetDevice> ()   
+    .AddAttribute ("Phy", "The PHY layer attached to this device.",
+                   PointerValue (),
+                   MakePointerAccessor (&NonCommunicatingNetDevice::GetPhy,
+                                        &NonCommunicatingNetDevice::SetPhy),
+                   MakePointerChecker<Object> ())
+  ;
+  return tid;
+}
+
+NonCommunicatingNetDevice::NonCommunicatingNetDevice ()
+{
+  NS_LOG_FUNCTION (this);
+}
+
+NonCommunicatingNetDevice::~NonCommunicatingNetDevice ()
+{
+  NS_LOG_FUNCTION (this);
+}
+
+void
+NonCommunicatingNetDevice::DoDispose ()
+{
+  NS_LOG_FUNCTION (this);
+  m_node = 0;
+  m_channel = 0;
+  m_phy = 0;
+  NetDevice::DoDispose ();
+}
+
+
+void
+NonCommunicatingNetDevice::SetIfIndex (const uint32_t index)
+{
+  NS_LOG_FUNCTION (index);
+  m_ifIndex = index;
+}
+
+uint32_t
+NonCommunicatingNetDevice::GetIfIndex (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return m_ifIndex;
+}
+
+bool
+NonCommunicatingNetDevice::SetMtu (uint16_t mtu)
+{
+  NS_LOG_FUNCTION (mtu);
+  return (mtu == 0);
+}
+
+uint16_t
+NonCommunicatingNetDevice::GetMtu (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return 0;
+}
+
+void
+NonCommunicatingNetDevice::SetAddress (Address address)
+{
+  NS_LOG_FUNCTION (this);
+}
+
+Address
+NonCommunicatingNetDevice::GetAddress (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return Address ();
+}
+
+bool
+NonCommunicatingNetDevice::IsBroadcast (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return false;
+}
+
+Address
+NonCommunicatingNetDevice::GetBroadcast (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return Address ();
+}
+
+bool
+NonCommunicatingNetDevice::IsMulticast (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return false;
+}
+
+Address
+NonCommunicatingNetDevice::GetMulticast (Ipv4Address addr) const
+{
+  NS_LOG_FUNCTION (addr);
+  return Address ();
+}
+
+Address
+NonCommunicatingNetDevice::GetMulticast (Ipv6Address addr) const
+{
+  NS_LOG_FUNCTION (addr);
+  return Address ();
+}
+
+bool
+NonCommunicatingNetDevice::IsPointToPoint (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return false;
+}
+
+bool
+NonCommunicatingNetDevice::IsBridge (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return false;
+}
+
+
+Ptr<Node>
+NonCommunicatingNetDevice::GetNode (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return m_node;
+}
+
+void
+NonCommunicatingNetDevice::SetNode (Ptr<Node> node)
+{
+  NS_LOG_FUNCTION (node);
+
+  m_node = node;
+}
+
+void
+NonCommunicatingNetDevice::SetPhy (Ptr<Object> phy)
+{
+  NS_LOG_FUNCTION (this << phy);
+  m_phy = phy;
+}
+
+
+Ptr<Object>
+NonCommunicatingNetDevice::GetPhy () const
+{
+  NS_LOG_FUNCTION (this);
+  return m_phy;
+}
+
+
+
+Ptr<Channel>
+NonCommunicatingNetDevice::GetChannel (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return m_channel;
+}
+
+
+bool
+NonCommunicatingNetDevice::NeedsArp (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return false;
+}
+
+bool
+NonCommunicatingNetDevice::IsLinkUp (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return false;
+}
+
+void
+NonCommunicatingNetDevice::AddLinkChangeCallback (Callback<void> callback)
+{
+  NS_LOG_FUNCTION (&callback);
+}
+
+void
+NonCommunicatingNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb)
+{
+  NS_LOG_FUNCTION (&cb);
+}
+
+void
+NonCommunicatingNetDevice::SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb)
+{
+  NS_LOG_FUNCTION (&cb);
+}
+
+bool
+NonCommunicatingNetDevice::SupportsSendFrom () const
+{
+  NS_LOG_FUNCTION (this);
+  return false;
+}
+
+
+bool
+NonCommunicatingNetDevice::Send (Ptr<Packet> packet,const Address& dest, uint16_t protocolNumber)
+{
+  NS_LOG_FUNCTION (packet << dest << protocolNumber);
+  return false;
+}
+
+bool
+NonCommunicatingNetDevice::SendFrom (Ptr<Packet> packet, const Address& src, const Address& dest, uint16_t protocolNumber)
+{
+  NS_LOG_FUNCTION (packet << src << dest << protocolNumber);
+  return false;
+}
+
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/spectrum/non-communicating-net-device.h	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,137 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#ifndef NON_COMMUNICATING_NET_DEVICE_H
+#define NON_COMMUNICATING_NET_DEVICE_H
+
+#include <string.h>
+#include <ns3/node.h>
+#include <ns3/address.h>
+#include <ns3/net-device.h>
+#include <ns3/callback.h>
+#include <ns3/packet.h>
+#include <ns3/traced-callback.h>
+#include <ns3/ptr.h>
+
+namespace ns3 {
+
+
+class SpectrumChannel;
+class Channel;
+class SpectrumErrorModel;
+class Queue;
+
+
+
+/**
+ * This class implements a device which does not communicate, in the
+ * sense that it does not interact with the above protocol stack. The
+ * purpose of this NetDevice is to be used for devices such as
+ * microwave ovens, waveform generators and spectrum
+ * analyzers. Since the ns-3 channel API is strongly based on the presence of
+ * NetDevice class instances, it is convenient to provide a NetDevice that can
+ * be used with such non-communicating devices.
+ */
+class NonCommunicatingNetDevice : public NetDevice
+{
+public:
+
+  static TypeId GetTypeId (void);
+
+  NonCommunicatingNetDevice ();
+  virtual ~NonCommunicatingNetDevice ();
+
+
+  /**
+   * This class doesn't talk directly with the underlying channel (a
+   * dedicated PHY class is expected to do it), however the NetDevice
+   * specification features a GetChannel() method. This method here
+   * is therefore provide to allow NonCommunicatingNetDevice::GetChannel() to have
+   * something meaningful to return.
+   *
+   * @param c the underlying channel
+   */
+  void SetChannel (Ptr<Channel> c);
+
+
+  /**
+   * Set the Phy object which is attached to this device.
+   * This object is needed so that we can set/get attributes and
+   * connect to trace sources of the PHY from the net device.
+   *
+   * @param phy the Phy object embedded within this device.
+   */
+  void SetPhy (Ptr<Object> phy);
+
+  /**
+   * @return a reference to the PHY object embedded in this NetDevice.
+   */
+  Ptr<Object> GetPhy () const;
+
+
+
+  // inherited from NetDevice
+  virtual void SetIfIndex (const uint32_t index);
+  virtual uint32_t GetIfIndex (void) const;
+  virtual Ptr<Channel> GetChannel (void) const;
+  virtual bool SetMtu (const uint16_t mtu);
+  virtual uint16_t GetMtu (void) const;
+  virtual void SetAddress (Address address);
+  virtual Address GetAddress (void) const;
+  virtual bool IsLinkUp (void) const;
+  virtual void AddLinkChangeCallback (Callback<void> callback);
+  virtual bool IsBroadcast (void) const;
+  virtual Address GetBroadcast (void) const;
+  virtual bool IsMulticast (void) const;
+  virtual bool IsPointToPoint (void) const;
+  virtual bool IsBridge (void) const;
+  virtual bool Send (Ptr<Packet> packet, const Address& dest,
+                     uint16_t protocolNumber);
+  virtual bool SendFrom (Ptr<Packet> packet, const Address& source, const Address& dest,
+                         uint16_t protocolNumber);
+  virtual Ptr<Node> GetNode (void) const;
+  virtual void SetNode (Ptr<Node> node);
+  virtual bool NeedsArp (void) const;
+  virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
+  virtual Address GetMulticast (Ipv4Address addr) const;
+  virtual Address GetMulticast (Ipv6Address addr) const;
+  virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb);
+  virtual bool SupportsSendFrom (void) const;
+
+
+
+
+
+private:
+
+  virtual void DoDispose (void);
+
+  Ptr<Node>    m_node;
+  Ptr<Channel> m_channel;
+
+  uint32_t m_ifIndex;
+
+  Ptr<Object> m_phy;
+};
+
+
+} // namespace ns3
+
+#endif // NON_COMMUNICATING_NET_DEVICE_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/spectrum/single-model-spectrum-channel.cc	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,215 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#include <ns3/object.h>
+#include <ns3/simulator.h>
+#include <ns3/log.h>
+#include <ns3/packet.h>
+#include <ns3/packet-burst.h>
+#include <ns3/net-device.h>
+#include <ns3/node.h>
+#include <ns3/mobility-model.h>
+#include <ns3/spectrum-phy.h>
+#include "single-model-spectrum-channel.h"
+
+
+NS_LOG_COMPONENT_DEFINE ("SingleModelSpectrumChannel");
+
+
+namespace ns3 {
+
+
+NS_OBJECT_ENSURE_REGISTERED (SingleModelSpectrumChannel);
+
+SingleModelSpectrumChannel::SingleModelSpectrumChannel ()
+  : m_spectrumModel (0),
+    m_PropagationDelay (0),
+    m_PropagationLoss (0)
+{
+  NS_LOG_FUNCTION (this);
+}
+
+void
+SingleModelSpectrumChannel::DoDispose ()
+{
+  NS_LOG_FUNCTION (this);
+  m_phyList.clear ();
+  m_spectrumModel = 0;
+  m_PropagationDelay = 0;
+  m_PropagationLoss = 0;
+  SpectrumChannel::DoDispose ();
+}
+
+TypeId
+SingleModelSpectrumChannel::GetTypeId (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  static TypeId tid = TypeId ("ns3::SingleModelSpectrumChannel")
+    .SetParent<SpectrumChannel> ()
+    .AddConstructor<SingleModelSpectrumChannel> ()
+  ;
+  return tid;
+}
+
+
+void
+SingleModelSpectrumChannel::AddRx (Ptr<SpectrumPhy> phy)
+{
+  NS_LOG_FUNCTION (this << phy);
+  m_phyList.push_back (phy);
+}
+
+
+void
+SingleModelSpectrumChannel::StartTx (Ptr<PacketBurst> p, Ptr <SpectrumValue> txPsd, SpectrumType st, Time duration, Ptr<SpectrumPhy> txPhy)
+{
+  NS_LOG_FUNCTION (this << p << *txPsd << st << duration << txPhy);
+  NS_ASSERT_MSG (p, "NULL PacketBurst");
+  NS_ASSERT_MSG (txPsd, "NULL txPsd");
+  NS_ASSERT_MSG (txPhy, "NULL txPhy");
+
+  // just a sanity check routine. We might want to remove it to save some computational load -- one "if" statement  ;-)
+  if (m_spectrumModel == 0)
+    {
+      // first pak, record SpectrumModel
+      m_spectrumModel = txPsd->GetSpectrumModel ();
+    }
+  else
+    {
+      // all attached SpectrumPhy instances must use the same SpectrumModel
+      NS_ASSERT (*(txPsd->GetSpectrumModel ()) == *m_spectrumModel);
+    }
+
+
+  PhyList::const_iterator rxPhyIterator = m_phyList.begin ();
+
+  Ptr<MobilityModel> senderMobility = txPhy->GetMobility ()->GetObject<MobilityModel> ();
+
+  NS_ASSERT (rxPhyIterator != m_phyList.end ());
+
+  while (rxPhyIterator != m_phyList.end ())
+    {
+      if ((*rxPhyIterator) != txPhy)
+        {
+          Ptr <SpectrumValue> rxPsd;
+          Time delay;
+          Ptr<MobilityModel> receiverMobility = (*rxPhyIterator)->GetMobility ()->GetObject<MobilityModel> ();
+
+          if (senderMobility && receiverMobility)
+            {
+
+
+              if (m_PropagationLoss)
+                {
+                  rxPsd = m_PropagationLoss->CalcRxPowerSpectralDensity (txPsd, senderMobility, receiverMobility);
+                }
+              else
+                {
+                  rxPsd = txPsd;
+                }
+
+              if (m_PropagationDelay)
+                {
+                  delay = m_PropagationDelay->GetDelay (senderMobility, receiverMobility);
+                }
+              else
+                {
+                  delay = MicroSeconds (0);
+                }
+            }
+          else
+            {
+              rxPsd = txPsd;
+              delay = MicroSeconds (0);
+            }
+
+          Ptr<PacketBurst> pktBurstCopy = p->Copy ();
+          Ptr<Object> netDevObj = (*rxPhyIterator)->GetDevice ();
+          if (netDevObj)
+            {
+              // the receiver has a NetDevice, so we expect that it is attached to a Node
+              uint32_t dstNode =  netDevObj->GetObject<NetDevice> ()->GetNode ()->GetId ();
+              Simulator::ScheduleWithContext (dstNode, delay, &SingleModelSpectrumChannel::StartRx, this,
+                                              pktBurstCopy, rxPsd, st, duration, *rxPhyIterator);
+            }
+          else
+            {
+              // the receiver is not attached to a NetDevice, so we cannot assume that it is attached to a node
+              Simulator::Schedule (delay, &SingleModelSpectrumChannel::StartRx, this,
+                                   pktBurstCopy, rxPsd, st, duration, *rxPhyIterator);
+            }
+        }
+      ++rxPhyIterator;
+    }
+
+}
+
+void
+SingleModelSpectrumChannel::StartRx (Ptr<PacketBurst> p, Ptr <SpectrumValue> rxPsd, SpectrumType st, Time duration, Ptr<SpectrumPhy> receiver)
+{
+  NS_LOG_FUNCTION (this << p << *rxPsd << st << duration << receiver);
+  receiver->StartRx (p, rxPsd, st, duration);
+}
+
+
+
+uint32_t
+SingleModelSpectrumChannel::GetNDevices (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return m_phyList.size ();
+}
+
+
+Ptr<NetDevice>
+SingleModelSpectrumChannel::GetDevice (uint32_t i) const
+{
+  NS_LOG_FUNCTION (this << i);
+  return m_phyList.at (i)->GetDevice ()->GetObject<NetDevice> ();
+}
+
+
+
+void
+SingleModelSpectrumChannel::AddSpectrumPropagationLossModel (Ptr<SpectrumPropagationLossModel> loss)
+{
+  NS_LOG_FUNCTION (this << loss);
+  NS_ASSERT (m_PropagationLoss == 0);
+  m_PropagationLoss = loss;
+}
+
+void
+SingleModelSpectrumChannel::SetPropagationDelayModel (Ptr<PropagationDelayModel> delay)
+{
+  NS_LOG_FUNCTION (this << delay);
+  NS_ASSERT (m_PropagationDelay == 0);
+  m_PropagationDelay = delay;
+}
+
+
+
+
+
+
+
+
+
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/spectrum/single-model-spectrum-channel.h	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,116 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#ifndef SINGLE_MODEL_SPECTRUM_CHANNEL_H
+#define SINGLE_MODEL_SPECTRUM_CHANNEL_H
+
+
+#include <ns3/spectrum-channel.h>
+#include <ns3/spectrum-propagation-loss-model.h>
+#include <ns3/propagation-delay-model.h>
+
+namespace ns3 {
+
+
+
+/**
+ * @brief SpectrumChannel implementation which handles a single spectrum model
+ *
+ * All SpectrumPhy layers attached to this SpectrumChannel
+ */
+class SingleModelSpectrumChannel : public SpectrumChannel
+{
+
+public:
+  SingleModelSpectrumChannel ();
+
+  static TypeId GetTypeId (void);
+
+
+  // inherited from SpectrumChannel
+  virtual void AddSpectrumPropagationLossModel (Ptr<SpectrumPropagationLossModel> loss);
+  virtual void SetPropagationDelayModel (Ptr<PropagationDelayModel> delay);
+  virtual void AddRx (Ptr<SpectrumPhy> phy);
+  virtual void StartTx (Ptr<PacketBurst> p, 
+                        Ptr <SpectrumValue> txPsd, 
+                        SpectrumType st, 
+                        Time duration, 
+                        Ptr<SpectrumPhy> sender);
+
+
+  // inherited from Channel
+  virtual uint32_t GetNDevices (void) const;
+  virtual Ptr<NetDevice> GetDevice (uint32_t i) const;
+
+
+  typedef std::vector<Ptr<SpectrumPhy> > PhyList;
+
+
+private:
+
+  virtual void DoDispose ();
+
+  /**
+   * used internally to reschedule transmission after the propagation delay
+   *
+   *
+   * @param p
+   * @param rxPowerSpectrum
+   * @param st
+   * @param duration
+   * @param receiver
+   */
+  virtual void StartRx (Ptr<PacketBurst> p, Ptr <SpectrumValue> rxPowerSpectrum, SpectrumType st, Time duration, Ptr<SpectrumPhy> receiver);
+
+  /**
+   * list of SpectrumPhy instances attached to
+   * the channel
+   */
+  PhyList m_phyList;
+
+  /**
+   * SpectrumModel that this channel instance
+   * is supporting
+   */
+  Ptr<const SpectrumModel> m_spectrumModel;
+
+
+  /**
+   * propagation delay model to be used with this channel
+   *
+   */
+  Ptr<PropagationDelayModel> m_PropagationDelay;
+
+
+  /**
+   * propagation loss model to be used with this channel
+   *
+   */
+  Ptr<SpectrumPropagationLossModel> m_PropagationLoss;
+
+};
+
+
+
+}
+
+
+
+#endif /* SINGLE_MODEL_SPECTRUM_CHANNEL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/spectrum/spectrum-analyzer.cc	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,238 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#include <ns3/spectrum-analyzer.h>
+#include <ns3/object-factory.h>
+#include <ns3/log.h>
+#include <ns3/double.h>
+#include <ns3/simulator.h>
+#include <ns3/trace-source-accessor.h>
+
+NS_LOG_COMPONENT_DEFINE ("SpectrumAnalyzer");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (SpectrumAnalyzer);
+
+SpectrumAnalyzer::SpectrumAnalyzer ()
+  : m_mobility (0),
+    m_netDevice (0),
+    m_channel (0),
+    m_spectrumModel (0),
+    m_sumPowerSpectralDensity (0),    
+    m_resolution (MilliSeconds (50)),
+    m_active (false)
+{
+  NS_LOG_FUNCTION (this);
+}
+
+
+
+SpectrumAnalyzer::~SpectrumAnalyzer ()
+{
+  NS_LOG_FUNCTION (this);
+}
+
+void
+SpectrumAnalyzer::DoDispose ()
+{
+  NS_LOG_FUNCTION (this);
+  m_mobility = 0;
+  m_netDevice = 0;
+  m_channel = 0;
+  m_spectrumModel = 0;
+  m_sumPowerSpectralDensity = 0;
+  m_energySpectralDensity = 0;
+  SpectrumPhy::DoDispose ();
+}
+
+TypeId
+SpectrumAnalyzer::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::SpectrumAnalyzer")
+    .SetParent<SpectrumPhy> ()
+    .AddConstructor<SpectrumAnalyzer> ()
+    .AddAttribute ("Resolution",
+                   "the lengh of the time interval over which the power spectral "
+                   "density of incoming signals is averaged",
+                   TimeValue (MilliSeconds (1)),
+                   MakeTimeAccessor (&SpectrumAnalyzer::m_resolution),
+                   MakeTimeChecker ())
+    .AddAttribute ("NoisePowerSpectralDensity",
+                   "the power spectral density of the measuring instrument noise, in Watt/Hz. Mostly useful to make spectrograms look more similar to those obtained by real devices. Defaults to the value for thermal noise at 300K.",
+                   DoubleValue (1.38e-23*300),
+                   MakeDoubleAccessor (&SpectrumAnalyzer::m_noisePowerSpectralDensity),
+                   MakeDoubleChecker<double> ())
+    .AddTraceSource ("AveragePowerSpectralDensityReport",
+                     "Trace fired whenever a new value for the average Power Spectral Density is calculated",
+                     MakeTraceSourceAccessor (&SpectrumAnalyzer::m_averagePowerSpectralDensityReportTrace))
+  ;
+  return tid;
+}
+
+
+
+Ptr<Object>
+SpectrumAnalyzer::GetDevice ()
+{
+  return m_netDevice;
+}
+
+
+Ptr<Object>
+SpectrumAnalyzer::GetMobility ()
+{
+  return m_mobility;
+}
+
+
+Ptr<const SpectrumModel> 
+SpectrumAnalyzer::GetRxSpectrumModel () const
+{
+  return m_spectrumModel;
+}
+
+void
+SpectrumAnalyzer::SetDevice (Ptr<Object> d)
+{
+  NS_LOG_FUNCTION (this << d);
+  m_netDevice = d;
+}
+
+
+void
+SpectrumAnalyzer::SetMobility (Ptr<Object> m)
+{
+  NS_LOG_FUNCTION (this << m);
+  m_mobility = m;
+}
+
+
+void
+SpectrumAnalyzer::SetChannel (Ptr<SpectrumChannel> c)
+{
+  NS_LOG_FUNCTION (this << c);
+  m_channel = c;
+}
+
+
+
+
+void
+SpectrumAnalyzer::StartRx (Ptr<PacketBurst> pb, 
+                           Ptr <const SpectrumValue> rxPowerSpectralDensity, 
+                           SpectrumType st, 
+                           Time duration)
+{
+  NS_LOG_FUNCTION ( this << st << duration << *rxPowerSpectralDensity);
+  AddSignal (rxPowerSpectralDensity);
+  Simulator::Schedule (duration, &SpectrumAnalyzer::SubtractSignal, this, rxPowerSpectralDensity);
+}
+
+
+void
+SpectrumAnalyzer::AddSignal  (Ptr<const SpectrumValue> psd)
+{
+  NS_LOG_FUNCTION (this << *psd);
+  UpdateEnergyReceivedSoFar ();
+  (*m_sumPowerSpectralDensity) += (*psd);
+}
+
+void
+SpectrumAnalyzer::SubtractSignal  (Ptr<const SpectrumValue> psd)
+{ 
+  NS_LOG_FUNCTION (this << *psd);
+  UpdateEnergyReceivedSoFar ();
+  (*m_sumPowerSpectralDensity) -= (*psd);
+}
+
+void
+SpectrumAnalyzer::UpdateEnergyReceivedSoFar  ()
+{
+  NS_LOG_FUNCTION (this);
+  if (m_lastChangeTime < Now ())
+    {
+      (*m_energySpectralDensity) += (*m_sumPowerSpectralDensity) * ((Now () - m_lastChangeTime).GetSeconds ());
+      m_lastChangeTime = Now ();
+    }
+  else
+    {
+      NS_ASSERT (m_lastChangeTime == Now ());
+    }
+}
+
+void
+SpectrumAnalyzer::GenerateReport ()
+{
+  NS_LOG_FUNCTION (this);
+
+  UpdateEnergyReceivedSoFar ();
+  Ptr<SpectrumValue> avgPowerSpectralDensity = Create<SpectrumValue> (m_sumPowerSpectralDensity->GetSpectrumModel ());
+  (*avgPowerSpectralDensity) = (*m_energySpectralDensity) / m_resolution.GetSeconds ();  
+  (*avgPowerSpectralDensity) += m_noisePowerSpectralDensity;
+  (*m_energySpectralDensity) = 0;
+
+  NS_LOG_INFO ("generating report");
+  m_averagePowerSpectralDensityReportTrace (avgPowerSpectralDensity);
+
+  *avgPowerSpectralDensity = 0;
+
+  if (m_active)
+    {
+      Simulator::Schedule (m_resolution, &SpectrumAnalyzer::GenerateReport, this);
+    }
+}
+
+
+
+void
+SpectrumAnalyzer::SetRxSpectrumModel (Ptr<SpectrumModel> f)
+{
+  NS_LOG_FUNCTION (this << f);
+  m_spectrumModel = f;
+  NS_ASSERT (!m_sumPowerSpectralDensity);
+  m_sumPowerSpectralDensity = Create<SpectrumValue> (f);
+  m_energySpectralDensity = Create<SpectrumValue> (f);
+  NS_ASSERT (m_sumPowerSpectralDensity);
+}
+
+
+
+
+void
+SpectrumAnalyzer::Start ()
+{
+  NS_LOG_FUNCTION (this);
+  if (!m_active)
+    {
+      NS_LOG_LOGIC ("activating");
+      m_active = true;
+      Simulator::Schedule (m_resolution, &SpectrumAnalyzer::GenerateReport, this);
+    }
+}
+
+
+void
+SpectrumAnalyzer::Stop ()
+{
+  m_active = false;
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/spectrum/spectrum-analyzer.h	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,123 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#ifndef SPECTRUM_ANALYZER_H
+#define SPECTRUM_ANALYZER_H
+
+
+#include <ns3/spectrum-value.h>
+#include <ns3/mobility-model.h>
+#include <ns3/packet.h>
+#include <ns3/nstime.h>
+#include <ns3/net-device.h>
+#include <ns3/spectrum-phy.h>
+#include <ns3/spectrum-channel.h>
+#include <string>
+#include <fstream>
+
+namespace ns3 {
+
+
+/**
+ * Simple SpectrumPhy implemetation that averages the spectrum power
+ * density of incoming transmissions to produce a spectrogram.
+ *
+ */
+class SpectrumAnalyzer : public SpectrumPhy
+{
+
+public:
+  SpectrumAnalyzer ();
+  virtual ~SpectrumAnalyzer ();
+
+  static TypeId GetTypeId (void);
+
+// inherited from SpectrumPhy
+  void SetChannel (Ptr<SpectrumChannel> c);
+  void SetMobility (Ptr<Object> m);
+  void SetDevice (Ptr<Object> d);
+  Ptr<Object> GetMobility ();
+  Ptr<Object> GetDevice ();
+  Ptr<const SpectrumModel> GetRxSpectrumModel () const;
+  void StartRx (Ptr<PacketBurst> pb, Ptr <const SpectrumValue> rxPowerSpectralDensity, SpectrumType st, Time duration);
+
+
+  /**
+   * Set the spectrum model used by the SpectrumAnalyzer to represent incoming signals
+   *
+   * @param m 
+   */
+  void SetRxSpectrumModel (Ptr<SpectrumModel> m);
+
+  
+  /**
+   * Start the spectrum analyzer
+   *
+   */
+  virtual void Start ();
+
+  /**
+   * Stop the spectrum analyzer
+   *
+   */
+  virtual void Stop ();
+
+
+protected:
+  
+  void DoDispose ();
+
+private:  
+
+
+  Ptr<Object> m_mobility;
+  Ptr<Object> m_netDevice;
+  Ptr<SpectrumChannel> m_channel;
+ 
+  virtual void GenerateReport ();
+
+  void AddSignal (Ptr<const SpectrumValue> psd);
+  void SubtractSignal  (Ptr<const SpectrumValue> psd);
+  void UpdateEnergyReceivedSoFar ();
+
+  Ptr<SpectrumModel> m_spectrumModel;
+  Ptr<SpectrumValue> m_sumPowerSpectralDensity;
+  Ptr<SpectrumValue> m_energySpectralDensity;
+  double m_noisePowerSpectralDensity;
+  Time m_resolution;
+  Time m_lastChangeTime;
+  bool m_active;
+
+  TracedCallback<Ptr<const SpectrumValue> > m_averagePowerSpectralDensityReportTrace;
+
+};
+
+
+
+
+
+
+}
+
+
+
+
+
+#endif /* SPECTRUM_ANALYZER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/spectrum/spectrum-error-model.cc	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,82 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#include "spectrum-error-model.h"
+
+#include <ns3/nstime.h>
+#include <ns3/log.h>
+
+NS_LOG_COMPONENT_DEFINE ("ShannonSpectrumErrorModel");
+
+namespace ns3 {
+
+SpectrumErrorModel::~SpectrumErrorModel ()
+{
+}
+
+void
+ShannonSpectrumErrorModel::DoDispose ()
+{
+  NS_LOG_FUNCTION (this);
+  SpectrumErrorModel::DoDispose ();
+}
+
+void
+ShannonSpectrumErrorModel::StartRx (Ptr<const Packet> p)
+{
+  NS_LOG_FUNCTION (this);
+  m_bytes = p->GetSize ();
+  NS_LOG_LOGIC ("bytes to deliver: " << m_bytes);
+  m_deliverableBytes = 0;
+}
+
+void
+ShannonSpectrumErrorModel::EvaluateChunk (const SpectrumValue& sinr, Time duration)
+{
+  NS_LOG_FUNCTION (this << sinr << duration);
+  SpectrumValue CapacityPerHertz = Log2 (1 + sinr);
+  double capacity = 0;
+
+  Bands::const_iterator bi = CapacityPerHertz.ConstBandsBegin ();
+  Values::const_iterator vi = CapacityPerHertz.ConstValuesBegin ();
+
+  while (bi != CapacityPerHertz.ConstBandsEnd ())
+    {
+      NS_ASSERT (vi != CapacityPerHertz.ConstValuesEnd ());
+      capacity += (bi->fh - bi->fl) * (*vi);
+      ++bi;
+      ++vi;
+    }
+  NS_ASSERT (vi == CapacityPerHertz.ConstValuesEnd ());
+  NS_LOG_LOGIC ("ChunkCapacity = " << capacity);
+  m_deliverableBytes += capacity * duration.GetSeconds () / 8;
+  NS_LOG_LOGIC ("DeliverableBytes = " << m_deliverableBytes);
+}
+
+
+bool
+ShannonSpectrumErrorModel::IsRxCorrect ()
+{
+  NS_LOG_FUNCTION (this);
+  return (m_deliverableBytes > m_bytes);
+}
+
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/spectrum/spectrum-error-model.h	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,98 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+
+#ifndef SPECTRUM_ERROR_MODEL_H
+#define SPECTRUM_ERROR_MODEL_H
+
+#include <ns3/spectrum-value.h>
+#include <ns3/ptr.h>
+#include <ns3/packet.h>
+#include <ns3/nstime.h>
+#include <ns3/object.h>
+
+namespace ns3 {
+
+
+
+class SpectrumErrorModel :  public Object
+{
+public:
+  virtual ~SpectrumErrorModel ();
+  virtual void StartRx (Ptr<const Packet> p) = 0;
+  virtual void EvaluateChunk (const SpectrumValue& sinr, Time duration) = 0;
+  virtual bool IsRxCorrect () = 0;
+};
+
+
+/**
+ * This class implements the error model described in this paper:
+ * N. Baldo and M. Miozzo, "Spectrum-aware Channel and PHY layer modeling
+ * for ns3", in Proceedings of International Workshop on Network
+ * Simulation Tools (NSTOOLS 2009), 19 October 2009, Pisa (Italy).
+ */
+class ShannonSpectrumErrorModel : public SpectrumErrorModel
+{
+protected:
+  virtual void DoDispose ();
+
+public:
+  // inherited from SpectrumErrorModel
+  void StartRx (Ptr<const Packet> p);
+  void EvaluateChunk (const SpectrumValue& sinr, Time duration);
+  bool IsRxCorrect ();
+
+private:
+  uint32_t m_bytes;
+  uint32_t m_deliverableBytes;
+
+};
+
+
+// class EffectiveSnrSpectrumErrorModel
+// {
+// public:
+
+//   enum ModulationAndCoding {
+//     BPSK_1_2,
+//     BPSK_1_3,
+//     QPSK_1_2,
+//     QPSK_1_3,
+//     QAM16_1_2,
+//     QAM64_1_2
+//   };
+
+//   void StartRx (uint32_t bytes);
+//   void EvaluateChunk (const SpectrumValue& sinr, Time duration);
+//   bool IsRxCorrect ();
+
+// protected:
+//   uint32_t m_bytes;
+//   uint32_t m_deliverableBytes;
+
+// };
+
+
+
+} // namespace ns3
+
+
+
+#endif /* SPECTRUM_ERROR_MODEL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/spectrum/spectrum-interference-test.cc	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,235 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#include <ns3/object.h>
+#include <ns3/spectrum-interference.h>
+#include <ns3/spectrum-error-model.h>
+#include <ns3/log.h>
+#include <ns3/test.h>
+#include <ns3/simulator.h>
+#include <ns3/packet.h>
+#include <ns3/ptr.h>
+#include <iostream>
+#include <math.h>
+
+NS_LOG_COMPONENT_DEFINE ("SpectrumInterferenceTest");
+
+namespace ns3 {
+
+
+
+
+class SpectrumInterferenceTestCase : public TestCase
+{
+public:
+  SpectrumInterferenceTestCase (Ptr<SpectrumValue> s, uint32_t txBytes, bool rxCorrect, std::string name);
+  virtual ~SpectrumInterferenceTestCase ();
+  virtual bool DoRun (void);
+  void RetrieveTestResult (SpectrumInterference* si);
+
+private:
+  Ptr<SpectrumValue> m_s;
+  uint32_t m_txBytes;
+  uint32_t m_rxCorrectKnownOutcome;
+  bool m_error;
+  Ptr<const SpectrumModel> m_mySpectrumModel;
+};
+
+
+
+SpectrumInterferenceTestCase::SpectrumInterferenceTestCase (Ptr<SpectrumValue> s, uint32_t txBytes, bool rxCorrect, std::string name)
+  : TestCase (name),
+    m_s (s),
+    m_txBytes (txBytes),
+    m_rxCorrectKnownOutcome (rxCorrect),
+    m_mySpectrumModel (s->GetSpectrumModel ())
+{
+}
+
+SpectrumInterferenceTestCase::~SpectrumInterferenceTestCase ()
+{
+}
+
+
+
+bool
+SpectrumInterferenceTestCase::DoRun (void)
+{
+  Ptr<SpectrumValue> n = Create<SpectrumValue> (m_mySpectrumModel);
+  Ptr<SpectrumValue> i1 = Create<SpectrumValue> (m_mySpectrumModel);
+  Ptr<SpectrumValue> i2 = Create<SpectrumValue> (m_mySpectrumModel);
+  Ptr<SpectrumValue> i3 = Create<SpectrumValue> (m_mySpectrumModel);
+  Ptr<SpectrumValue> i4 = Create<SpectrumValue> (m_mySpectrumModel);
+
+
+  (*n)[0] = 5.000000000000e-19;
+  (*n)[1] = 4.545454545455e-19;
+
+  (*i1)[0] = 5.000000000000e-18;
+  (*i2)[0] = 5.000000000000e-16;
+  (*i3)[0] = 1.581138830084e-16;
+  (*i4)[0] = 7.924465962306e-17;
+  (*i1)[1] = 1.437398936440e-18;
+  (*i2)[1] = 5.722388235428e-16;
+  (*i3)[1] = 7.204059965732e-17;
+  (*i4)[1] = 5.722388235428e-17;
+
+
+  SpectrumInterference si;
+  si.SetErrorModel (CreateObject<ShannonSpectrumErrorModel> ());
+  si.SetNoisePowerSpectralDensity (n);
+
+  Time ts  = Seconds (1);
+  Time ds  = Seconds (1);
+  Time ti1 = Seconds (0);
+  Time di1 = Seconds (3);
+  Time ti2 = Seconds (0.7);
+  Time di2 = Seconds (1);
+  Time ti3 = Seconds (1.2);
+  Time di3 = Seconds (1);
+  Time ti4 = Seconds (1.5);
+  Time di4 = Seconds (0.1);
+
+  Simulator::Schedule (ts,  &SpectrumInterference::AddSignal, &si, m_s,  ds);
+  Simulator::Schedule (ti1, &SpectrumInterference::AddSignal, &si, i1, di1);
+  Simulator::Schedule (ti2, &SpectrumInterference::AddSignal, &si, i2, di2);
+  Simulator::Schedule (ti3, &SpectrumInterference::AddSignal, &si, i3, di3);
+  Simulator::Schedule (ti4, &SpectrumInterference::AddSignal, &si, i4, di4);
+
+  Ptr<Packet> p = Create<Packet> (m_txBytes);
+  Simulator::Schedule (ts,  &SpectrumInterference::StartRx, &si, p, m_s);
+  Simulator::Schedule (ts + ds,  &SpectrumInterferenceTestCase::RetrieveTestResult, this, &si);
+
+  Simulator::Run ();
+  // the above will return and after RetrieveTestResults have
+  // been called and after all signals have expired
+
+  return m_error;
+}
+
+
+
+void
+SpectrumInterferenceTestCase::RetrieveTestResult (SpectrumInterference* si)
+{
+
+  bool rxOk = si->EndRx ();
+  m_error =  (m_rxCorrectKnownOutcome != rxOk);
+
+  std::ostringstream actualStream;
+  actualStream << rxOk;
+  std::ostringstream limitStream;
+  limitStream << m_rxCorrectKnownOutcome;
+
+  NS_LOG_LOGIC ("actual=" << actualStream.str () << " limit=" << limitStream.str ());
+
+  if (m_error)
+    {
+      UpdateErrorStatus (m_error);
+      ReportTestFailure (std::string ("wrong result"),
+                         actualStream.str (),
+                         limitStream.str (),
+                         std::string ("no message"),
+                         __FILE__, __LINE__);
+    }
+
+}
+
+
+
+class SpectrumInterferenceTestSuite : public TestSuite
+{
+public:
+  SpectrumInterferenceTestSuite ();
+};
+
+SpectrumInterferenceTestSuite::SpectrumInterferenceTestSuite ()
+  : TestSuite ("spectrum-interference", UNIT)
+{
+
+  NS_LOG_INFO ("creating SpectrumInterferenceTestSuite");
+
+  Ptr<const SpectrumModel> m;
+
+  Bands bands;
+  struct BandInfo bi;
+
+  bi.fl = 2.400e9;
+  bi.fc = 2.410e9;
+  bi.fh = 2.420e9;
+  bands.push_back (bi);
+
+  bi.fl = 2.420e9;
+  bi.fc = 2.431e9;
+  bi.fh = 2.442e9;
+  bands.push_back (bi);
+
+  m = Create<SpectrumModel> (bands);
+
+
+  double b; // max deliverable bytes
+
+  const double e = 1e-5; // max tolerated relative error for
+                         // deliverable bytes
+
+  // Power Spectral Density of the signal of interest  = [-46 -48] dBm;
+  Ptr<SpectrumValue> s1  = Create<SpectrumValue> (m);
+  (*s1)[0] = 1.255943215755e-15;
+  (*s1)[1] = 7.204059965732e-16;
+  b = 10067205.5632012;
+  AddTestCase (new SpectrumInterferenceTestCase (s1,   1, 1,            "sdBm  = [-46 -48]  tx bytes: 1"));
+  AddTestCase (new SpectrumInterferenceTestCase (s1, round (b * 0.5), 1,   "sdBm  = [-46 -48]  tx bytes: b*0.5"));
+  AddTestCase (new SpectrumInterferenceTestCase (s1, round (b * (1 - e)), 1, "sdBm  = [-46 -48]  tx bytes: b*(1-e)"));
+  AddTestCase (new SpectrumInterferenceTestCase (s1, round (b * (1 + e)), 0, "sdBm  = [-46 -48]  tx bytes: b*(1+e)"));
+  AddTestCase (new SpectrumInterferenceTestCase (s1, round (b * 1.5), 0,   "sdBm  = [-46 -48]  tx bytes: b*1.5"));
+  AddTestCase (new SpectrumInterferenceTestCase (s1, 0xffffffff, 0,     "sdBm  = [-46 -48]  tx bytes: 2^32-1"));
+
+  // Power Spectral Density of the signal of interest  =  [-63 -61] dBm;
+  Ptr<SpectrumValue> s2  = Create<SpectrumValue> (m);
+  (*s2)[0] = 2.505936168136e-17;
+  (*s2)[1] = 3.610582885110e-17;
+  b = 882401.591840728;
+  AddTestCase (new SpectrumInterferenceTestCase (s2,   1, 1,            "sdBm  = [-63 -61]  tx bytes: 1"));
+  AddTestCase (new SpectrumInterferenceTestCase (s2, round (b * 0.5), 1,   "sdBm  = [-63 -61]  tx bytes: b*0.5"));
+  AddTestCase (new SpectrumInterferenceTestCase (s2, round (b * (1 - e)), 1, "sdBm  = [-63 -61]  tx bytes: b*(1-e)"));
+  AddTestCase (new SpectrumInterferenceTestCase (s2, round (b * (1 + e)), 0, "sdBm  = [-63 -61]  tx bytes: b*(1+e)"));
+  AddTestCase (new SpectrumInterferenceTestCase (s2, round (b * 1.5), 0,   "sdBm  = [-63 -61]  tx bytes: b*1.5"));
+  AddTestCase (new SpectrumInterferenceTestCase (s2, 0xffffffff, 0,     "sdBm  = [-63 -61]  tx bytes: 2^32-1"));
+
+}
+
+
+
+
+
+
+} // namespace ns3
+
+
+using namespace ns3;
+
+int
+main (int argc, char** argv)
+{
+
+  SpectrumInterferenceTestSuite SpectrumInterferenceTestSuite;
+
+  return SpectrumInterferenceTestSuite.Run ();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/spectrum/spectrum-interference.cc	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,145 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+
+#include "spectrum-interference.h"
+#include "spectrum-error-model.h"
+
+#include <ns3/simulator.h>
+#include <ns3/log.h>
+
+
+NS_LOG_COMPONENT_DEFINE ("SpectrumInterference");
+
+namespace ns3 {
+
+
+SpectrumInterference::SpectrumInterference ()
+  : m_receiving (false),
+    m_rxSignal (0),
+    m_allSignals (0),
+    m_noise (0),
+    m_errorModel (0)
+{
+  NS_LOG_FUNCTION (this);
+}
+
+SpectrumInterference::~SpectrumInterference ()
+{
+  NS_LOG_FUNCTION (this);
+}
+
+void
+SpectrumInterference::DoDispose ()
+{
+  NS_LOG_FUNCTION (this);
+  m_rxSignal = 0;
+  m_allSignals = 0;
+  m_noise = 0;
+  m_errorModel = 0;  
+  Object::DoDispose ();
+}
+
+void
+SpectrumInterference::StartRx (Ptr<const Packet> p, Ptr<const SpectrumValue> rxPsd)
+{ 
+  NS_LOG_FUNCTION (this << p << *rxPsd);
+  m_rxSignal = rxPsd;
+  m_lastChangeTime = Now ();
+  m_receiving = true;
+  m_errorModel->StartRx (p);
+}
+
+
+bool
+SpectrumInterference::EndRx ()
+{
+  NS_LOG_FUNCTION (this);
+  ConditionallyEvaluateChunk ();
+  m_receiving = false;
+  return m_errorModel->IsRxCorrect ();
+}
+
+
+void
+SpectrumInterference::AddSignal (Ptr<const SpectrumValue> spd, const Time duration)
+{
+  NS_LOG_FUNCTION (this << *spd << duration);
+  DoAddSignal (spd);
+  Simulator::Schedule (duration, &SpectrumInterference::DoSubtractSignal, this, spd);
+}
+
+
+void
+SpectrumInterference::DoAddSignal  (Ptr<const SpectrumValue> spd)
+{ 
+  NS_LOG_FUNCTION (this << *spd);
+  ConditionallyEvaluateChunk ();
+  (*m_allSignals) += (*spd);
+  m_lastChangeTime = Now ();
+}
+
+void
+SpectrumInterference::DoSubtractSignal  (Ptr<const SpectrumValue> spd)
+{ 
+  NS_LOG_FUNCTION (this << *spd);
+  ConditionallyEvaluateChunk ();
+  (*m_allSignals) -= (*spd);
+  m_lastChangeTime = Now ();
+}
+
+
+void
+SpectrumInterference::ConditionallyEvaluateChunk ()
+{
+  NS_LOG_FUNCTION (this);
+  if (m_receiving && (Now () > m_lastChangeTime))
+    {
+      SpectrumValue sinr = (*m_rxSignal) / ((*m_allSignals) - (*m_rxSignal) + (*m_noise));
+      Time duration = Now () - m_lastChangeTime;
+      m_errorModel->EvaluateChunk (sinr, duration);
+    }
+}
+
+void
+SpectrumInterference::SetNoisePowerSpectralDensity (Ptr<const SpectrumValue> noisePsd)
+{
+  NS_LOG_FUNCTION (this << noisePsd);
+  m_noise = noisePsd;
+  // we can initialize m_allSignal only now, because earlier we
+  // didn't know what spectrum model was going to be used.
+  // we'll now create a zeroed SpectrumValue using the same
+  // SpectrumModel which is being specified for the noise.
+  m_allSignals = Create<SpectrumValue> (noisePsd->GetSpectrumModel ());
+}
+
+void
+SpectrumInterference::SetErrorModel (Ptr<SpectrumErrorModel> e)
+{
+  NS_LOG_FUNCTION (this << e);
+  m_errorModel = e;
+}
+
+
+
+
+} // namespace ns3
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/spectrum/spectrum-interference.h	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,141 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+
+#ifndef SPECTRUM_INTERFERENCE_H
+#define SPECTRUM_INTERFERENCE_H
+
+#include <ns3/object.h>
+#include <ns3/packet.h>
+#include <ns3/nstime.h>
+#include <ns3/spectrum-value.h>
+
+namespace ns3 {
+
+
+
+
+class SpectrumErrorModel;
+
+
+
+/**
+ * This class implements a gaussian interference model, i.e., all
+ * incoming signals are added to the total interference.
+ *
+ */
+class SpectrumInterference : public Object
+{
+public:
+  SpectrumInterference ();
+  virtual ~SpectrumInterference ();
+
+  /**
+   * set the SpectrumErrorModel to be used.
+   *
+   * @param e
+   */
+  void SetErrorModel (Ptr<SpectrumErrorModel> e);
+
+  /**
+   * notify that the PHY is starting a RX attempt
+   *
+   * @param p the packet corresponding to the signal being RX
+   * @param rxPsd the power spectral density of the signal being RX
+   */
+  void StartRx (Ptr<const Packet> p, Ptr<const SpectrumValue> rxPsd);
+
+
+  /**
+   * notify that the RX attempt has ended. The receiving PHY must call
+   * this method upon RX end in order to:
+   * 1) know if RX was successful or not
+   * 2) free up resources that might eventually be used for the
+   * calculation of interference. Note that for this reason this
+   * method must also be called when RX is aborted.
+   *
+   *
+   * @return true if RX was successful, false otherwise
+   */
+  bool EndRx ();
+
+
+  /**
+   * notify that a new signal is being perceived in the medium. This
+   * method is to be called for all incoming signal, regardless of
+   * wether they're useful signals or interferers.
+   *
+   * @param spd the power spectral density of the new signal
+   * @param duration the duration of the new signal
+   */
+  void AddSignal (Ptr<const SpectrumValue>, const Time duration);
+
+
+  /**
+   *
+   * @param noisePsd the Noise Power Spectral Density in power units
+   * (Watt, Pascal...) per Hz.
+   */
+  void SetNoisePowerSpectralDensity (Ptr<const SpectrumValue> noisePsd);
+
+
+protected:
+  
+  void DoDispose ();
+
+private:
+  void ConditionallyEvaluateChunk ();
+  void DoAddSignal  (Ptr<const SpectrumValue> spd);
+  void DoSubtractSignal  (Ptr<const SpectrumValue> spd);
+
+
+
+  bool m_receiving;
+
+  Ptr<const SpectrumValue> m_rxSignal; /**< stores the power spectral density of
+                                  * the signal whose RX is being
+                                  * attempted
+                                  */
+
+  Ptr<SpectrumValue> m_allSignals; /**< stores the spectral
+                                    * power density of the sum of incoming signals;
+                                    * does not include noise, includes the SPD of the signal being RX
+                                    */
+
+  Ptr<const SpectrumValue> m_noise;
+
+  Time m_lastChangeTime;     /**< the time of the last change in
+                                m_TotalPower */
+
+  Ptr<SpectrumErrorModel> m_errorModel;
+
+
+
+};
+
+
+
+} // namespace ns3
+
+
+
+
+
+#endif /* SPECTRUM_INTERFERENCE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/spectrum/spectrum-model-300kHz-300GHz-log.cc	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,51 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+
+#include <ns3/spectrum-model-300kHz-300GHz-log.h>
+
+namespace ns3 {
+
+
+Ptr<SpectrumModel> SpectrumModel300Khz300GhzLog;
+
+
+
+class static_SpectrumModel300Khz300GhzLog_initializer
+{
+public:
+  static_SpectrumModel300Khz300GhzLog_initializer ()
+  {
+
+    std::vector<double> freqs;
+    for (double f = 3e5; f < 3e11; f = f * 2)
+      {
+        freqs.push_back (f);
+      }
+    SpectrumModel300Khz300GhzLog = Create<SpectrumModel> (freqs);
+  }
+
+} static_SpectrumModel300Khz300GhzLog_initializer_instance;
+
+
+
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/spectrum/spectrum-model-300kHz-300GHz-log.h	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,38 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#ifndef FREQS_300KHZ_300GHZ_LOG_H
+#define FREQS_300KHZ_300GHZ_LOG_H
+
+
+#include <ns3/spectrum-value.h>
+
+namespace ns3 {
+
+
+extern Ptr<SpectrumModel> SpectrumModel300Khz300GhzLog;
+
+
+}
+
+
+
+
+#endif /*  FREQS_300KHZ_300GHZ_LOG_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/spectrum/spectrum-model-ism2400MHz-res1MHz.cc	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,53 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+
+#include <ns3/spectrum-model-ism2400MHz-res1MHz.h>
+
+namespace ns3 {
+
+
+Ptr<SpectrumModel> SpectrumModelIsm2400MhzRes1Mhz;
+
+
+
+class static_SpectrumModelIsm2400MhzRes1Mhz_initializer
+{
+public:
+  static_SpectrumModelIsm2400MhzRes1Mhz_initializer ()
+  {
+
+    std::vector<double> freqs;
+    for (int i = 0; i < 100; ++i)
+      {
+        freqs.push_back ((i + 2400) * 1e6);
+      }
+
+
+    SpectrumModelIsm2400MhzRes1Mhz = Create<SpectrumModel> (freqs);
+  }
+
+} static_SpectrumModelIsm2400MhzRes1Mhz_initializer_instance;
+
+
+
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/spectrum/spectrum-model-ism2400MHz-res1MHz.h	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,39 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#ifndef FREQS_ISM2400MHZ_RES1MHZ_H
+#define FREQS_ISM2400MHZ_RES1MHZ_H
+
+
+#include <ns3/spectrum-value.h>
+
+namespace ns3 {
+
+
+extern Ptr<SpectrumModel> SpectrumModelIsm2400MhzRes1Mhz;
+
+
+}
+
+
+
+
+
+#endif /* FREQS_ISM2400MHZ_RES1MHZ_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/spectrum/waveform-generator.cc	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,228 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#include <ns3/waveform-generator.h>
+#include <ns3/object-factory.h>
+#include <ns3/log.h>
+#include <ns3/simulator.h>
+#include <ns3/double.h>
+#include <ns3/packet-burst.h>
+
+
+NS_LOG_COMPONENT_DEFINE ("WaveformGenerator");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (WaveformGenerator);
+
+WaveformGenerator::WaveformGenerator ()
+  : m_mobility (0),
+    m_netDevice (0),
+    m_channel (0),
+    m_txPowerSpectralDensity (0),
+    m_startTime (Seconds (0)),
+    m_active (false)
+{
+
+}
+
+
+WaveformGenerator::~WaveformGenerator ()
+{
+
+}
+
+
+void
+WaveformGenerator::DoDispose (void)
+{
+  NS_LOG_FUNCTION (this);
+  m_channel = 0;
+  m_netDevice = 0;
+  m_mobility = 0;
+}
+
+TypeId
+WaveformGenerator::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::WaveformGenerator")
+    .SetParent<SpectrumPhy> ()
+    .AddConstructor<WaveformGenerator> ()
+    .AddAttribute ("Period",
+                   "the period (=1/frequency)",
+                   TimeValue (Seconds (1.0)),
+                   MakeTimeAccessor (&WaveformGenerator::SetPeriod,
+                                     &WaveformGenerator::GetPeriod),
+                   MakeTimeChecker ())
+    .AddAttribute ("DutyCycle",
+                   "the duty cycle of the generator, i.e., the fraction of the period that is occupied by a signal",
+                   DoubleValue (0.5),
+                   MakeDoubleAccessor (&WaveformGenerator::SetDutyCycle,
+                                       &WaveformGenerator::GetDutyCycle),
+                   MakeDoubleChecker<double> ())
+    .AddTraceSource ("TxStart",
+                     "Trace fired when a new transmission is started",
+                     MakeTraceSourceAccessor (&WaveformGenerator::m_phyTxStartTrace))
+    .AddTraceSource ("TxEnd",
+                     "Trace fired when a previosuly started transmission is finished",
+                     MakeTraceSourceAccessor (&WaveformGenerator::m_phyTxEndTrace))
+    ;
+  return tid;
+}
+
+
+
+Ptr<Object>
+WaveformGenerator::GetDevice ()
+{
+  return m_netDevice;
+}
+
+
+Ptr<Object>
+WaveformGenerator::GetMobility ()
+{
+  return m_mobility;
+}
+
+
+Ptr<const SpectrumModel> 
+WaveformGenerator::GetRxSpectrumModel () const
+{
+  // this device is not interested in RX
+  return 0;
+}
+
+void
+WaveformGenerator::SetDevice (Ptr<Object> d)
+{
+  m_netDevice = d;
+}
+
+
+void
+WaveformGenerator::SetMobility (Ptr<Object> m)
+{
+  m_mobility = m;
+}
+
+
+void
+WaveformGenerator::SetChannel (Ptr<SpectrumChannel> c)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_channel = c;
+}
+
+
+
+void
+WaveformGenerator::StartRx (Ptr<PacketBurst> pb, Ptr <const SpectrumValue> rxPowerSpectrum, SpectrumType st, Time duration)
+{
+  NS_LOG_FUNCTION (pb << rxPowerSpectrum << duration);
+}
+
+
+SpectrumType
+WaveformGenerator::GetSpectrumType ()
+{
+  static SpectrumType st = SpectrumTypeFactory::Create ("GenericWaveform");
+  return st;
+}
+
+void
+WaveformGenerator::SetTxPowerSpectralDensity (Ptr<SpectrumValue> txPsd)
+{
+  NS_LOG_FUNCTION (this << *txPsd);
+  m_txPowerSpectralDensity = txPsd;
+}
+
+
+
+void
+WaveformGenerator::SetPeriod (Time period)
+{
+  m_period = period;
+}
+
+Time
+WaveformGenerator::GetPeriod () const
+{
+  return m_period;
+}
+
+
+
+void
+WaveformGenerator::SetDutyCycle (double dutyCycle)
+{
+  m_dutyCycle = Scalar (dutyCycle);
+}
+
+double WaveformGenerator::GetDutyCycle () const
+{
+  return m_dutyCycle.GetDouble ();
+}
+
+
+
+void
+WaveformGenerator::GenerateWaveform ()
+{
+  NS_LOG_FUNCTION (this);
+
+  Ptr<PacketBurst> pb = Create<PacketBurst> ();
+  Time duration = m_period * m_dutyCycle;
+  
+  NS_LOG_LOGIC ("generating waveform : " << *m_txPowerSpectralDensity);
+  m_phyTxStartTrace (0);
+  m_channel->StartTx (pb, m_txPowerSpectralDensity, GetSpectrumType (), duration, GetObject<SpectrumPhy> ());
+  
+  if (m_active)
+    {
+      NS_LOG_LOGIC ("scheduling next waveform");
+      Simulator::Schedule (m_period, &WaveformGenerator::GenerateWaveform, this);
+    }
+}
+
+
+void
+WaveformGenerator::Start ()
+{
+  NS_LOG_FUNCTION (this);
+  if (!m_active)
+    {
+      NS_LOG_LOGIC ("generator was not active, now starting");
+      m_active = true;
+      m_startTime = Now ();
+      Simulator::ScheduleNow (&WaveformGenerator::GenerateWaveform, this);
+    }
+}
+
+
+void
+WaveformGenerator::Stop ()
+{
+  NS_LOG_FUNCTION (this);  
+  m_active = false;
+}
+
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/spectrum/waveform-generator.h	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,168 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#ifndef WAVEFORM_GENERATOR_H
+#define WAVEFORM_GENERATOR_H
+
+
+#include <ns3/spectrum-value.h>
+#include <ns3/mobility-model.h>
+#include <ns3/packet.h>
+#include <ns3/nstime.h>
+#include <ns3/net-device.h>
+#include <ns3/spectrum-phy.h>
+#include <ns3/spectrum-channel.h>
+#include <ns3/spectrum-type.h>
+#include <ns3/trace-source-accessor.h>
+
+namespace ns3 {
+
+
+
+/**
+ * Simple SpectrumPhy implementation that sends customizable waveform.
+ * The generated waveforms have a given Spectrum Power Density and
+ * duration (set with the SetResolution()) . The generator activates
+ * and deactivates periodically with a given period and with a duty
+ * cycle of 1/2.
+ */
+class WaveformGenerator : public SpectrumPhy
+{
+
+public:
+  WaveformGenerator ();
+  virtual ~WaveformGenerator ();
+
+  static TypeId GetTypeId (void);
+
+  // inherited from SpectrumPhy
+  void SetChannel (Ptr<SpectrumChannel> c);
+  void SetMobility (Ptr<Object> m);
+  void SetDevice (Ptr<Object> d);
+  Ptr<Object> GetMobility ();
+  Ptr<Object> GetDevice ();
+  Ptr<const SpectrumModel> GetRxSpectrumModel () const;
+  void StartRx (Ptr<PacketBurst> p, Ptr <const SpectrumValue> rxPowerSpectrum, SpectrumType st, Time duration); 
+
+
+  /**
+   * Set the Power Spectral Density used for outgoing waveforms
+   *
+   * @param txs the Power Spectral Density
+   */
+  void SetTxPowerSpectralDensity (Ptr<SpectrumValue> txs);
+
+
+  /**
+   * Get the SpectrumType used by this PHY
+   *
+   * @return
+   */
+  SpectrumType GetSpectrumType ();
+
+
+
+  /**
+   * Set the period according to which the WaveformGenerator switches
+   * on and off
+   *
+   * @param period
+   */
+  void SetPeriod (Time period);
+
+
+  /** 
+   * 
+   * @return the value of the period according to which the WaveformGenerator switches
+   * on and off
+   */
+  Time GetPeriod () const;
+  
+
+  /** 
+   * 
+   * @param value the value of the duty cycle
+   */
+  void SetDutyCycle (double value);
+
+  /** 
+   *
+   * @return the value of the duty cycle
+   */
+  double GetDutyCycle () const;
+
+
+
+
+  /**
+   * Set the time resolution of the generated waveforms.
+   *
+   * @param resolution time resolution of the generated
+   * waveforms. This determines both the duration of waveforms, and
+   * the time between subsequent waveforms (i.e., they are generated
+   * back to back during the active portion of the generator cycle).
+   */
+  void SetResolution (Time resolution);
+
+  /**
+   * Start the waveform generator
+   *
+   */
+  virtual void Start ();
+
+  /**
+   * Stop the waveform generator
+   *
+   */
+  virtual void Stop ();
+
+
+private:
+
+  virtual void DoDispose (void);
+
+  Ptr<Object> m_mobility;
+  Ptr<Object> m_netDevice;
+  Ptr<SpectrumChannel> m_channel;
+
+  virtual void GenerateWaveform ();
+
+  Ptr<SpectrumValue> m_txPowerSpectralDensity;
+  Time   m_period;
+  Scalar m_dutyCycle;
+  Time m_startTime;
+  bool m_active;
+
+  TracedCallback<Ptr<const Packet> > m_phyTxStartTrace;
+  TracedCallback<Ptr<const Packet> > m_phyTxEndTrace;
+};
+
+
+
+
+
+
+} // namespace ns3
+
+
+
+
+
+#endif /* WAVEFORM_GENERATOR_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/spectrum/wifi-spectrum-value-helper.cc	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,110 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+
+#include "wifi-spectrum-value-helper.h"
+
+namespace ns3 {
+
+  
+Ptr<SpectrumModel> g_WifiSpectrumModel5Mhz;
+
+
+class WifiSpectrumModel5MhzInitializer
+{
+public:
+  WifiSpectrumModel5MhzInitializer ()
+  {
+    Bands bands;
+    for (int i = -4; i < 13+7; i++)
+      {
+        BandInfo bi;
+        bi.fl = 2407.0e6 + i * 5.0e6;
+        bi.fh = 2407.0e6 + (i+1) * 5.0e6;
+        bi.fc = (bi.fl +  bi.fh)/2;
+        bands.push_back (bi);
+      }
+    g_WifiSpectrumModel5Mhz = Create<SpectrumModel> (bands);
+  }
+} g_WifiSpectrumModel5MhzInitializerInstance;
+
+
+
+Ptr<SpectrumValue> 
+WifiSpectrumValue5MhzFactory::CreateConstant (double v)
+{  
+  Ptr<SpectrumValue> c = Create <SpectrumValue> (g_WifiSpectrumModel5Mhz);
+  (*c) = v;
+  return c;
+}
+
+
+Ptr<SpectrumValue> 
+WifiSpectrumValue5MhzFactory::CreateTxPowerSpectralDensity (double txPower, uint32_t channel)
+{  
+  Ptr<SpectrumValue> txPsd = Create <SpectrumValue> (g_WifiSpectrumModel5Mhz);
+
+  // since the spectrum model has a resolution of 5 MHz, we model
+  // the transmitted signal with a constant density over a 20MHz
+  // bandwidth centered on the center frequency of the channel. The
+  // transmission power outside the transmission power density is
+  // calculated considering the transmit spectrum mask, see IEEE
+  // Std. 802.11-2007, Annex I
+
+  double txPowerDensity = txPower / 20e6; 
+
+  NS_ASSERT(channel >= 1);
+  NS_ASSERT(channel <= 13);
+
+  (*txPsd)[channel - 1] = txPowerDensity * 1e-4;      // -40dB
+  (*txPsd)[channel]     = txPowerDensity * 1e-4;      // -40dB
+  (*txPsd)[channel + 1] = txPowerDensity * 0.0015849; // -28dB
+  (*txPsd)[channel + 2] = txPowerDensity * 0.0015849; // -28dB
+  (*txPsd)[channel + 3] = txPowerDensity;
+  (*txPsd)[channel + 4] = txPowerDensity;
+  (*txPsd)[channel + 5] = txPowerDensity;
+  (*txPsd)[channel + 6] = txPowerDensity;
+  (*txPsd)[channel + 7] = txPowerDensity * 0.0015849; // -28dB
+  (*txPsd)[channel + 8] = txPowerDensity * 0.0015849; // -28dB
+  (*txPsd)[channel + 9] = txPowerDensity * 1e-4;      // -40dB
+  (*txPsd)[channel + 10] = txPowerDensity * 1e-4;      // -40dB
+
+  return txPsd;
+}
+
+
+Ptr<SpectrumValue> 
+WifiSpectrumValue5MhzFactory::CreateRfFilter (uint32_t channel)
+{  
+  Ptr<SpectrumValue> rf = Create <SpectrumValue> (g_WifiSpectrumModel5Mhz);
+
+  NS_ASSERT(channel >= 1);
+  NS_ASSERT(channel <= 13);
+
+  (*rf)[channel - 1] = 1;
+  (*rf)[channel    ] = 1;
+  (*rf)[channel + 1] = 1;
+  (*rf)[channel + 2] = 1;
+
+  return rf;
+}
+
+
+} //namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/spectrum/wifi-spectrum-value-helper.h	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,95 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#ifndef WIFI_SPECTRUM_VALUE_HELPER_H
+#define WIFI_SPECTRUM_VALUE_HELPER_H
+
+
+#include <ns3/spectrum-value.h>
+
+namespace ns3 {
+
+
+
+/** 
+ * this abstract class defines the interface for interacting with all WifiSpectrumValue implementations.
+ *
+ */
+class WifiSpectrumValueHelper 
+{
+public:
+
+  /*
+   *
+   * @param value the constant value
+   * 
+   * @return a Ptr to a newly created SpectrumValue instance which
+   * has a constant value for all frequencies
+   */
+  virtual Ptr<SpectrumValue> CreateConstant (double psd) = 0;
+
+  /*
+   *
+   * @param txPower the total TX power in W
+   * @param channel the number of the channel 
+   * 
+   * @return a Ptr to a newly created SpectrumValue instance which
+   * represents the TX Power Spectral Density  of a wifi device
+   * corresponding to the provided parameters
+   */
+  virtual Ptr<SpectrumValue> CreateTxPowerSpectralDensity (double txPower, uint32_t channel) = 0;
+
+  /*
+   *
+   * @param channel the number of the channel 
+   * 
+   * @return a Ptr to a newly created SpectrumValue instance which
+   * represents the frequency response of the RF filter which is used
+   * by a wifi device to receive signals when tuned to a particular channel
+   */
+  virtual Ptr<SpectrumValue> CreateRfFilter (uint32_t channel) = 0;
+  
+};
+
+
+
+/** 
+ * Implements WifiSpectrumValue for the 2.4 GHz ISM band only, with a
+ * 5 MHz spectrum resolution.
+ *
+ */
+class WifiSpectrumValue5MhzFactory
+{
+public:
+
+  // inherited from WifiSpectrumValue
+  virtual Ptr<SpectrumValue> CreateConstant (double psd);
+  virtual Ptr<SpectrumValue> CreateTxPowerSpectralDensity (double txPower, uint32_t channel);
+  virtual Ptr<SpectrumValue> CreateRfFilter (uint32_t channel);
+
+};
+
+
+  
+} //namespace ns3
+
+
+
+#endif /*  WIFI_SPECTRUM_VALUE_HELPER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/spectrum/wscript	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,43 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+def build(bld):
+
+    module = bld.create_ns3_module('spectrum', ['core'])
+    module.source = [
+        'single-model-spectrum-channel.cc',
+        'multi-model-spectrum-channel.cc',
+        'spectrum-interference.cc',
+        'spectrum-error-model.cc',
+        'spectrum-interference-test.cc',
+        'spectrum-model-ism2400MHz-res1MHz.cc',
+        'spectrum-model-300kHz-300GHz-log.cc', 
+        'wifi-spectrum-value-helper.cc',
+        'waveform-generator.cc',
+        'spectrum-analyzer.cc',
+        'aloha-noack-mac-header.cc',
+        'aloha-noack-net-device.cc',
+        'half-duplex-ideal-phy.cc',
+        'non-communicating-net-device.cc',
+        'microwave-oven-spectrum-value-helper.cc',
+        ]
+    
+    headers = bld.new_task_gen('ns3header')
+    headers.module = 'spectrum'
+    headers.source = [
+        'single-model-spectrum-channel.h', 
+        'multi-model-spectrum-channel.h',
+        'spectrum-interference.h',
+        'spectrum-error-model.h',
+        'spectrum-model-ism2400MHz-res1MHz.h',
+        'spectrum-model-300kHz-300GHz-log.h',
+        'wifi-spectrum-value-helper.h',
+        'waveform-generator.h',       
+        'spectrum-analyzer.h',
+        'aloha-noack-mac-header.h',
+        'aloha-noack-net-device.h',
+        'half-duplex-ideal-phy.h',
+        'non-communicating-net-device.h',
+        'microwave-oven-spectrum-value-helper.h',
+        ]
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/adhoc-aloha-noack-ideal-phy-helper.cc	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,156 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+#include "ns3/propagation-delay-model.h"
+#include "ns3/spectrum-propagation-loss-model.h"
+#include "ns3/mobility-model.h"
+#include "ns3/log.h"
+#include "ns3/config.h"
+#include "ns3/simulator.h"
+#include "ns3/names.h"
+#include "ns3/spectrum-channel.h"
+#include "ns3/half-duplex-ideal-phy.h"
+#include "ns3/mac48-address.h"
+#include "ns3/aloha-noack-net-device.h"
+#include "adhoc-aloha-noack-ideal-phy-helper.h"
+
+
+
+
+NS_LOG_COMPONENT_DEFINE ("AdhocAlohaNoackIdealPhyHelper");
+
+namespace ns3 {
+
+
+AdhocAlohaNoackIdealPhyHelper::AdhocAlohaNoackIdealPhyHelper ()
+{
+  m_phy.SetTypeId ("ns3::HalfDuplexIdealPhy");
+  m_device.SetTypeId ("ns3::AlohaNoackNetDevice");
+  m_queue.SetTypeId ("ns3::DropTailQueue");
+}
+
+AdhocAlohaNoackIdealPhyHelper::~AdhocAlohaNoackIdealPhyHelper ()
+{
+}
+
+void
+AdhocAlohaNoackIdealPhyHelper::SetChannel (Ptr<SpectrumChannel> channel)
+{
+  m_channel = channel;
+}
+
+void
+AdhocAlohaNoackIdealPhyHelper::SetChannel (std::string channelName)
+{
+  Ptr<SpectrumChannel> channel = Names::Find<SpectrumChannel> (channelName);
+  m_channel = channel;
+}
+
+void
+AdhocAlohaNoackIdealPhyHelper::SetTxPowerSpectralDensity (Ptr<SpectrumValue> txPsd)
+{
+  NS_LOG_FUNCTION (this << txPsd);
+  m_txPsd = txPsd;
+}
+
+void
+AdhocAlohaNoackIdealPhyHelper::SetNoisePowerSpectralDensity (Ptr<SpectrumValue> noisePsd)
+{
+  NS_LOG_FUNCTION (this << noisePsd);
+  m_noisePsd = noisePsd;
+}
+
+void
+AdhocAlohaNoackIdealPhyHelper::SetPhyAttribute (std::string name, const AttributeValue &v)
+{
+  m_phy.Set (name, v);
+}
+
+
+void
+AdhocAlohaNoackIdealPhyHelper::SetDeviceAttribute (std::string name, const AttributeValue &v)
+{
+  m_device.Set (name, v);
+}
+
+NetDeviceContainer
+AdhocAlohaNoackIdealPhyHelper::Install (NodeContainer c) const
+{
+  NetDeviceContainer devices;
+  for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
+    {
+      Ptr<Node> node = *i;
+
+      Ptr<AlohaNoackNetDevice> dev = (m_device.Create ())->GetObject<AlohaNoackNetDevice> ();
+      dev->SetAddress (Mac48Address::Allocate ());
+      Ptr<Queue> q = (m_queue.Create ())->GetObject<Queue> ();
+      dev->SetQueue (q);
+
+      // note that we could have used a SpectrumPhyHelper here, but
+      // given that it is straightforward to handle the configuration
+      // in this helper here, we avoid asking the user to pass us a
+      // SpectrumPhyHelper, so to spare him some typing.
+
+      Ptr<HalfDuplexIdealPhy>  phy = (m_phy.Create ())->GetObject<HalfDuplexIdealPhy> ();
+      NS_ASSERT (phy);
+
+      dev->SetPhy (phy);
+
+      NS_ASSERT (node);
+      phy->SetMobility (node);
+
+      NS_ASSERT (dev);
+      phy->SetDevice (dev);
+
+      NS_ASSERT_MSG (m_txPsd, "you forgot to call AdhocAlohaNoackIdealPhyHelper::SetTxPowerSpectralDensity ()");
+      phy->SetTxPowerSpectralDensity (m_txPsd);
+
+      NS_ASSERT_MSG (m_noisePsd, "you forgot to call AdhocAlohaNoackIdealPhyHelper::SetNoisePowerSpectralDensity ()");
+      phy->SetNoisePowerSpectralDensity (m_noisePsd);
+
+      NS_ASSERT_MSG (m_channel, "you forgot to call AdhocAlohaNoackIdealPhyHelper::SetChannel ()");
+      phy->SetChannel (m_channel);
+      m_channel->AddRx (phy);
+
+      phy->SetPhyMacTxEndCallback   (MakeCallback (&AlohaNoackNetDevice::NotifyTransmissionEnd, dev));
+      phy->SetPhyMacRxStartCallback (MakeCallback (&AlohaNoackNetDevice::NotifyReceptionStart, dev));
+      phy->SetPhyMacRxEndOkCallback (MakeCallback (&AlohaNoackNetDevice::NotifyReceptionEndOk, dev));
+      dev->SetPhyMacTxStartCallback (MakeCallback (&HalfDuplexIdealPhy::StartTx, phy));
+
+      node->AddDevice (dev);
+      devices.Add (dev);
+    }
+  return devices;
+}
+
+NetDeviceContainer
+AdhocAlohaNoackIdealPhyHelper::Install (Ptr<Node> node) const
+{
+  return Install (NodeContainer (node));
+}
+
+NetDeviceContainer
+AdhocAlohaNoackIdealPhyHelper::Install (std::string nodeName) const
+{
+  Ptr<Node> node = Names::Find<Node> (nodeName);
+  return Install (node);
+}
+
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/adhoc-aloha-noack-ideal-phy-helper.h	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,124 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#ifndef ADHOC_ALOHA_NOACK_IDEAL_PHY_HELPER_H
+#define ADHOC_ALOHA_NOACK_IDEAL_PHY_HELPER_H
+
+#include <string>
+#include <ns3/attribute.h>
+#include <ns3/object-factory.h>
+#include <ns3/node-container.h>
+#include <ns3/net-device-container.h>
+#include <ns3/queue.h>
+
+
+namespace ns3 {
+
+
+class SpectrumValue;
+class SpectrumChannel;
+
+/**
+ *
+ * create the NetDevice depicted in the figure
+ * @image html HdOfdmAlohaNoAck.png
+ *
+ */
+class AdhocAlohaNoackIdealPhyHelper
+{
+public:
+  AdhocAlohaNoackIdealPhyHelper ();
+  ~AdhocAlohaNoackIdealPhyHelper ();
+
+  /**
+   * set the SpectrumChannel that will be used by SpectrumPhy instances created by this helper
+   *
+   * @param channel
+   */
+  void SetChannel (Ptr<SpectrumChannel> channel);
+
+  /**
+   * set the SpectrumChannel that will be used by SpectrumPhy instances created by this helper
+   *
+   * @param channel
+   */
+  void SetChannel (std::string channelName);
+
+
+  /**
+   *
+   * @param txPsd the Power Spectral Density to be used for transmission by all created PHY instances
+   */
+  void SetTxPowerSpectralDensity (Ptr<SpectrumValue> txPsd);
+
+  /**
+   *
+   * @param noisePsd the Power Spectral Density to be used for transmission by all created PHY instances
+   */
+  void SetNoisePowerSpectralDensity (Ptr<SpectrumValue> noisePsd);
+
+  /**
+   * @param name the name of the attribute to set
+   * @param v the value of the attribute
+   *
+   * Set these attributes on each HdOfdmSpectrumPhy instance to be created
+   */
+  void SetPhyAttribute (std::string name, const AttributeValue &v);
+
+  /**
+   * @param n1 the name of the attribute to set
+   * @param v1 the value of the attribute to set
+   *
+   * Set these attributes on each AlohaNoackNetDevice created
+   */
+  void SetDeviceAttribute (std::string n1, const AttributeValue &v1);
+
+
+  /**
+    * @param c the set of nodes on which a device must be created
+    * @return a device container which contains all the devices created by this method.
+    */
+  NetDeviceContainer Install (NodeContainer c) const;
+  /**
+   * @param node the node on which a device must be created
+   * \returns a device container which contains all the devices created by this method.
+   */
+  NetDeviceContainer Install (Ptr<Node> node) const;
+  /**
+   * @param nodeName the name of node on which a device must be created
+   * @return a device container which contains all the devices created by this method.
+   */
+  NetDeviceContainer Install (std::string nodeName) const;
+
+
+protected:
+  ObjectFactory m_phy;
+  ObjectFactory m_device;
+  ObjectFactory m_queue;
+  Ptr<SpectrumChannel> m_channel;
+  Ptr<SpectrumValue> m_txPsd;
+  Ptr<SpectrumValue> m_noisePsd;
+};
+
+
+
+} // namespace ns3
+
+#endif /* ADHOC_ALOHA_NOACK_IDEAL_PHY_HELPER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/spectrum-analyzer-helper.cc	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,198 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+#include "ns3/propagation-delay-model.h"
+#include "ns3/spectrum-propagation-loss-model.h"
+#include "ns3/mobility-model.h"
+#include "ns3/log.h"
+#include "ns3/config.h"
+#include "ns3/simulator.h"
+#include "ns3/names.h"
+#include "ns3/spectrum-channel.h"
+#include "ns3/spectrum-analyzer.h"
+#include "ns3/non-communicating-net-device.h"
+#include "ns3/output-stream-wrapper.h"
+#include "ns3/trace-helper.h"
+#include "spectrum-analyzer-helper.h"
+
+
+
+
+NS_LOG_COMPONENT_DEFINE ("SpectrumAnalyzerHelper");
+
+namespace ns3 {
+
+
+static void 
+WriteAveragePowerSpectralDensityReport (Ptr<OutputStreamWrapper> streamWrapper, 
+                                        Ptr<const SpectrumValue> avgPowerSpectralDensity)
+{
+  NS_LOG_FUNCTION (streamWrapper << avgPowerSpectralDensity);
+  std::ostream* ostream = streamWrapper->GetStream ();
+  if (ostream->good ())
+    {
+      Bands::const_iterator fi = avgPowerSpectralDensity->ConstBandsBegin ();
+      Values::const_iterator vi = avgPowerSpectralDensity->ConstValuesBegin ();
+      while (fi != avgPowerSpectralDensity->ConstBandsEnd ())
+        {
+          NS_ASSERT (vi != avgPowerSpectralDensity->ConstValuesEnd ());
+          *ostream << Now ().GetSeconds () << " "
+                   << fi->fc << " "
+                   << *vi << std::endl;
+          ++fi;
+          ++vi;
+        }
+      // An additional line separates different spectrums sweeps
+      *ostream << std::endl;
+    }
+}
+  
+
+
+SpectrumAnalyzerHelper::SpectrumAnalyzerHelper ()
+{
+  NS_LOG_FUNCTION (this);
+  m_phy.SetTypeId ("ns3::SpectrumAnalyzer");
+  m_device.SetTypeId ("ns3::NonCommunicatingNetDevice");
+}
+
+SpectrumAnalyzerHelper::~SpectrumAnalyzerHelper ()
+{
+  NS_LOG_FUNCTION (this);
+}
+
+void
+SpectrumAnalyzerHelper::SetChannel (Ptr<SpectrumChannel> channel)
+{
+  NS_LOG_FUNCTION (this);
+  m_channel = channel;
+}
+
+void
+SpectrumAnalyzerHelper::SetChannel (std::string channelName)
+{
+  NS_LOG_FUNCTION (this);
+  Ptr<SpectrumChannel> channel = Names::Find<SpectrumChannel> (channelName);
+  m_channel = channel;
+}
+
+
+void
+SpectrumAnalyzerHelper::SetPhyAttribute (std::string name, const AttributeValue &v)
+{
+  NS_LOG_FUNCTION (this);
+  m_phy.Set (name, v);
+}
+
+
+void
+SpectrumAnalyzerHelper::SetDeviceAttribute (std::string name, const AttributeValue &v)
+{
+  NS_LOG_FUNCTION (this);
+  m_device.Set (name, v);
+}
+
+ 
+void
+SpectrumAnalyzerHelper::SetRxSpectrumModel (Ptr<SpectrumModel> m)
+{
+  NS_LOG_FUNCTION (this);
+  m_rxSpectrumModel = m;
+}
+
+void
+SpectrumAnalyzerHelper::EnableAsciiAll (std::string prefix)
+{
+  NS_LOG_FUNCTION (this);
+  m_prefix = prefix;
+}  
+
+
+
+NetDeviceContainer
+SpectrumAnalyzerHelper::Install (NodeContainer c) const
+{
+  NS_LOG_FUNCTION (this);
+  NetDeviceContainer devices;
+  for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
+    {
+      Ptr<Node> node = *i;
+
+      Ptr<NonCommunicatingNetDevice> dev = m_device.Create ()->GetObject<NonCommunicatingNetDevice> ();
+     
+      Ptr<SpectrumAnalyzer>  phy = m_phy.Create ()->GetObject<SpectrumAnalyzer> ();
+      NS_ASSERT (phy);
+
+      dev->SetPhy (phy);
+
+      NS_ASSERT (node);
+      phy->SetMobility (node);
+
+      NS_ASSERT (dev);
+      phy->SetDevice (dev);
+
+      NS_ASSERT_MSG (m_rxSpectrumModel, "you forgot to call SpectrumAnalyzerHelper::SetRxSpectrumModel ()");
+      phy->SetRxSpectrumModel (m_rxSpectrumModel);
+
+      NS_ASSERT_MSG (m_channel, "you forgot to call SpectrumAnalyzerHelper::SetChannel ()");
+      m_channel->AddRx (phy);
+
+      uint32_t devId = node->AddDevice (dev);
+      devices.Add (dev);
+
+      if (! m_prefix.empty ())
+        {
+          NS_LOG_LOGIC ("creating new output stream and binding it to the callback");
+          AsciiTraceHelper asciiTraceHelper;
+          std::string filename;
+          filename = asciiTraceHelper.GetFilenameFromDevice (m_prefix, dev);
+          Ptr<OutputStreamWrapper> stream = asciiTraceHelper.CreateFileStream (filename);
+
+          // note that we don't use AsciiTraceHelper to connect the trace sink, since we use a custom trace sink
+
+          // the following is inspired from YansWifiPhyHelper::EnableAsciiInternal
+          std::ostringstream oss;
+          oss.str (""); 
+          oss << "/NodeList/" << node->GetId () << "/DeviceList/" << devId << "/$ns3::NonCommunicatingNetDevice/Phy/AveragePowerSpectralDensityReport";
+          Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&WriteAveragePowerSpectralDensityReport, stream));
+
+          phy->Start ();
+
+        }
+    }
+  return devices;
+}
+
+NetDeviceContainer
+SpectrumAnalyzerHelper::Install (Ptr<Node> node) const
+{
+  NS_LOG_FUNCTION (this);
+  return Install (NodeContainer (node));
+}
+
+NetDeviceContainer
+SpectrumAnalyzerHelper::Install (std::string nodeName) const
+{
+  NS_LOG_FUNCTION (this);
+  Ptr<Node> node = Names::Find<Node> (nodeName);
+  return Install (node);
+}
+
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/spectrum-analyzer-helper.h	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,120 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#ifndef SPECTRUM_ANALYZER_HELPER_H
+#define SPECTRUM_ANALYZER_HELPER_H
+
+
+#include <string>
+#include <ns3/attribute.h>
+#include <ns3/object-factory.h>
+#include <ns3/node-container.h>
+#include <ns3/net-device-container.h>
+#include <ns3/queue.h>
+
+
+namespace ns3 {
+
+
+class SpectrumValue;
+class SpectrumChannel;
+class SpectrumModel;
+
+class SpectrumAnalyzerHelper
+{
+public:
+  SpectrumAnalyzerHelper ();
+  ~SpectrumAnalyzerHelper ();
+
+  /**
+   * set the SpectrumChannel that will be used by SpectrumPhy instances created by this helper
+   *
+   * @param channel
+   */
+  void SetChannel (Ptr<SpectrumChannel> channel);
+
+  /**
+   * set the SpectrumChannel that will be used by SpectrumPhy instances created by this helper
+   *
+   * @param channel
+   */
+  void SetChannel (std::string channelName);
+
+  /**
+   * @param name the name of the attribute to set
+   * @param v the value of the attribute
+   *
+   * Set these attributes on each HdOfdmSpectrumPhy instance to be created
+   */
+  void SetPhyAttribute (std::string name, const AttributeValue &v);
+
+  /**
+   * @param n1 the name of the attribute to set
+   * @param v1 the value of the attribute to set
+   *
+   * Set these attributes on each AlohaNoackNetDevice created
+   */
+  void SetDeviceAttribute (std::string n1, const AttributeValue &v1);
+
+  /**
+   * Set the spectrum model used by the created SpectrumAnalyzer instances to represent incoming signals
+   *
+   * @param m 
+   */
+  void SetRxSpectrumModel (Ptr<SpectrumModel> m);
+
+
+  /** 
+   * Enable ASCII output. This will create one filename for every created SpectrumAnalyzer instance.
+   * 
+   * @param prefix the prefix of the filename of the traces that will be created.
+   */
+  void EnableAsciiAll (std::string prefix);
+
+  /**
+    * @param c the set of nodes on which a device must be created
+    * @return a device container which contains all the devices created by this method.
+    */
+  NetDeviceContainer Install (NodeContainer c) const;
+  /**
+   * @param node the node on which a device must be created
+   * \returns a device container which contains all the devices created by this method.
+   */
+  NetDeviceContainer Install (Ptr<Node> node) const;
+  /**
+   * @param nodeName the name of node on which a device must be created
+   * @return a device container which contains all the devices created by this method.
+   */
+  NetDeviceContainer Install (std::string nodeName) const;
+
+
+private:
+  ObjectFactory m_phy;
+  ObjectFactory m_device;
+  Ptr<SpectrumChannel> m_channel;
+  Ptr<SpectrumModel> m_rxSpectrumModel;
+  std::string m_prefix;
+};
+
+
+} // namespace ns3
+
+
+#endif /* SPECTRUM_ANALYZER_HELPER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/spectrum-helper.cc	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,202 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+#include "spectrum-helper.h"
+#include <ns3/simulator.h>
+#include <ns3/config.h>
+#include <ns3/names.h>
+#include <ns3/spectrum-propagation-loss-model.h>
+#include <ns3/propagation-delay-model.h>
+#include <ns3/spectrum-channel.h>
+#include <ns3/spectrum-phy.h>
+#include <ns3/single-model-spectrum-channel.h>
+#include <ns3/multi-model-spectrum-channel.h>
+#include <ns3/half-duplex-ideal-phy.h>
+
+
+namespace ns3 {
+
+
+SpectrumChannelHelper
+SpectrumChannelHelper::Default (void)
+{
+  SpectrumChannelHelper h;
+  h.SetChannel ("ns3::SingleModelSpectrumChannel");
+  h.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
+  h.AddSpectrumPropagationLoss ("ns3::FriisSpectrumPropagationLossModel");
+  return h;
+}
+
+void
+SpectrumChannelHelper::SetChannel (std::string type,
+                                   std::string n0, const AttributeValue &v0,
+                                   std::string n1, const AttributeValue &v1,
+                                   std::string n2, const AttributeValue &v2,
+                                   std::string n3, const AttributeValue &v3,
+                                   std::string n4, const AttributeValue &v4,
+                                   std::string n5, const AttributeValue &v5,
+                                   std::string n6, const AttributeValue &v6,
+                                   std::string n7, const AttributeValue &v7)
+{
+  ObjectFactory factory;
+  m_channel.SetTypeId (type);
+  m_channel.Set (n0, v0);
+  m_channel.Set (n1, v1);
+  m_channel.Set (n2, v2);
+  m_channel.Set (n3, v3);
+  m_channel.Set (n4, v4);
+  m_channel.Set (n5, v5);
+  m_channel.Set (n6, v6);
+  m_channel.Set (n7, v7);
+}
+
+
+void
+SpectrumChannelHelper::AddSpectrumPropagationLoss (std::string type,
+                                                   std::string n0, const AttributeValue &v0,
+                                                   std::string n1, const AttributeValue &v1,
+                                                   std::string n2, const AttributeValue &v2,
+                                                   std::string n3, const AttributeValue &v3,
+                                                   std::string n4, const AttributeValue &v4,
+                                                   std::string n5, const AttributeValue &v5,
+                                                   std::string n6, const AttributeValue &v6,
+                                                   std::string n7, const AttributeValue &v7)
+{
+  ObjectFactory factory;
+  factory.SetTypeId (type);
+  factory.Set (n0, v0);
+  factory.Set (n1, v1);
+  factory.Set (n2, v2);
+  factory.Set (n3, v3);
+  factory.Set (n4, v4);
+  factory.Set (n5, v5);
+  factory.Set (n6, v6);
+  factory.Set (n7, v7);
+  m_spectrumPropagationLoss.push_back (factory);
+}
+
+void
+SpectrumChannelHelper::SetPropagationDelay (std::string type,
+                                            std::string n0, const AttributeValue &v0,
+                                            std::string n1, const AttributeValue &v1,
+                                            std::string n2, const AttributeValue &v2,
+                                            std::string n3, const AttributeValue &v3,
+                                            std::string n4, const AttributeValue &v4,
+                                            std::string n5, const AttributeValue &v5,
+                                            std::string n6, const AttributeValue &v6,
+                                            std::string n7, const AttributeValue &v7)
+{
+  ObjectFactory factory;
+  factory.SetTypeId (type);
+  factory.Set (n0, v0);
+  factory.Set (n1, v1);
+  factory.Set (n2, v2);
+  factory.Set (n3, v3);
+  factory.Set (n4, v4);
+  factory.Set (n5, v5);
+  factory.Set (n6, v6);
+  factory.Set (n7, v7);
+  m_propagationDelay = factory;
+}
+
+Ptr<SpectrumChannel>
+SpectrumChannelHelper::Create (void) const
+{
+  Ptr<SpectrumChannel> channel = (m_channel.Create ())->GetObject<SpectrumChannel> ();
+  Ptr<SpectrumPropagationLossModel> prev = 0;
+  for (std::vector<ObjectFactory>::const_iterator i = m_spectrumPropagationLoss.begin (); i != m_spectrumPropagationLoss.end (); ++i)
+    {
+      Ptr<SpectrumPropagationLossModel> cur = (*i).Create<SpectrumPropagationLossModel> ();
+      if (prev == 0)
+        {
+          channel->AddSpectrumPropagationLossModel (cur);
+        }
+      else
+        {
+          prev->SetNext (cur);
+        }
+      prev = cur;
+    }
+  Ptr<PropagationDelayModel> delay = m_propagationDelay.Create<PropagationDelayModel> ();
+  channel->SetPropagationDelayModel (delay);
+  return channel;
+}
+
+
+
+
+
+
+void
+SpectrumPhyHelper::SetPhy (std::string type,
+                           std::string n0, const AttributeValue &v0,
+                           std::string n1, const AttributeValue &v1,
+                           std::string n2, const AttributeValue &v2,
+                           std::string n3, const AttributeValue &v3,
+                           std::string n4, const AttributeValue &v4,
+                           std::string n5, const AttributeValue &v5,
+                           std::string n6, const AttributeValue &v6,
+                           std::string n7, const AttributeValue &v7)
+{
+  m_phy.SetTypeId (type);
+  m_phy.Set (n0, v0);
+  m_phy.Set (n1, v1);
+  m_phy.Set (n2, v2);
+  m_phy.Set (n3, v3);
+  m_phy.Set (n4, v4);
+  m_phy.Set (n5, v5);
+  m_phy.Set (n6, v6);
+  m_phy.Set (n7, v7);
+}
+
+
+
+void
+SpectrumPhyHelper::SetChannel (Ptr<SpectrumChannel> channel)
+{
+  m_channel = channel;
+}
+
+void
+SpectrumPhyHelper::SetChannel (std::string channelName)
+{
+  Ptr<SpectrumChannel> channel = Names::Find<SpectrumChannel> (channelName);
+  m_channel = channel;
+}
+
+void
+SpectrumPhyHelper::SetPhyAttribute (std::string name, const AttributeValue &v)
+{
+  m_phy.Set (name, v);
+}
+
+
+Ptr<SpectrumPhy>
+SpectrumPhyHelper::Create (Ptr<Node> node, Ptr<NetDevice> device) const
+{
+  NS_ASSERT (m_channel);
+  Ptr<SpectrumPhy> phy = (m_phy.Create ())->GetObject<SpectrumPhy> ();
+  phy->SetChannel (m_channel);
+  phy->SetMobility (node);
+  phy->SetDevice (device);
+  return phy;
+}
+
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/spectrum-helper.h	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,224 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#ifndef SPECTRUM_HELPER_H
+#define SPECTRUM_HELPER_H
+
+#include <string>
+#include <ns3/attribute.h>
+#include <ns3/object-factory.h>
+#include <ns3/node-container.h>
+#include <ns3/net-device-container.h>
+
+namespace ns3 {
+
+class SpectrumPhy;
+class SpectrumChannel;
+class Node;
+class NetDevice;
+
+
+class SpectrumChannelHelper
+{
+public:
+  static SpectrumChannelHelper Default ();
+
+  /**
+   * \param type the type of the SpectrumChannel to use
+   * \param n0 the name of the attribute to set
+   * \param v0 the value of the attribute to set
+   * \param n1 the name of the attribute to set
+   * \param v1 the value of the attribute to set
+   * \param n2 the name of the attribute to set
+   * \param v2 the value of the attribute to set
+   * \param n3 the name of the attribute to set
+   * \param v3 the value of the attribute to set
+   * \param n4 the name of the attribute to set
+   * \param v4 the value of the attribute to set
+   * \param n5 the name of the attribute to set
+   * \param v5 the value of the attribute to set
+   * \param n6 the name of the attribute to set
+   * \param v6 the value of the attribute to set
+   * \param n7 the name of the attribute to set
+   * \param v7 the value of the attribute to set
+   */
+  void SetChannel (std::string type,
+                   std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
+                   std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
+                   std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
+                   std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
+                   std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
+                   std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
+                   std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
+                   std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
+
+  /**
+   * \param name the name of the model to set
+   * \param n0 the name of the attribute to set
+   * \param v0 the value of the attribute to set
+   * \param n1 the name of the attribute to set
+   * \param v1 the value of the attribute to set
+   * \param n2 the name of the attribute to set
+   * \param v2 the value of the attribute to set
+   * \param n3 the name of the attribute to set
+   * \param v3 the value of the attribute to set
+   * \param n4 the name of the attribute to set
+   * \param v4 the value of the attribute to set
+   * \param n5 the name of the attribute to set
+   * \param v5 the value of the attribute to set
+   * \param n6 the name of the attribute to set
+   * \param v6 the value of the attribute to set
+   * \param n7 the name of the attribute to set
+   * \param v7 the value of the attribute to set
+   *
+   * Add a new spectrum propagation loss to this channel helper.
+   */
+  void AddSpectrumPropagationLoss (std::string name,
+                                   std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
+                                   std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
+                                   std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
+                                   std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
+                                   std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
+                                   std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
+                                   std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
+                                   std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
+  /**
+   * \param name the name of the model to set
+   * \param n0 the name of the attribute to set
+   * \param v0 the value of the attribute to set
+   * \param n1 the name of the attribute to set
+   * \param v1 the value of the attribute to set
+   * \param n2 the name of the attribute to set
+   * \param v2 the value of the attribute to set
+   * \param n3 the name of the attribute to set
+   * \param v3 the value of the attribute to set
+   * \param n4 the name of the attribute to set
+   * \param v4 the value of the attribute to set
+   * \param n5 the name of the attribute to set
+   * \param v5 the value of the attribute to set
+   * \param n6 the name of the attribute to set
+   * \param v6 the value of the attribute to set
+   * \param n7 the name of the attribute to set
+   * \param v7 the value of the attribute to set
+   *
+   * Configure a propagation delay for this channel.
+   */
+  void SetPropagationDelay (std::string name,
+                            std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
+                            std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
+                            std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
+                            std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
+                            std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
+                            std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
+                            std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
+                            std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
+
+  /**
+   * \returns a new channel
+   *
+   * Create a channel based on the configuration parameters set previously.
+   */
+  Ptr<SpectrumChannel> Create (void) const;
+
+private:
+  std::vector<ObjectFactory> m_spectrumPropagationLoss;
+  ObjectFactory m_propagationDelay;
+  ObjectFactory m_channel;
+};
+
+
+
+/**
+ * create and configure several SpectrumPhy instances and connect them to a channel.
+ */
+class SpectrumPhyHelper
+{
+public:
+  /**
+   * \param name the type of SpectrumPhy to use
+   * \param n0 the name of the attribute to set
+   * \param v0 the value of the attribute to set
+   * \param n1 the name of the attribute to set
+   * \param v1 the value of the attribute to set
+   * \param n2 the name of the attribute to set
+   * \param v2 the value of the attribute to set
+   * \param n3 the name of the attribute to set
+   * \param v3 the value of the attribute to set
+   * \param n4 the name of the attribute to set
+   * \param v4 the value of the attribute to set
+   * \param n5 the name of the attribute to set
+   * \param v5 the value of the attribute to set
+   * \param n6 the name of the attribute to set
+   * \param v6 the value of the attribute to set
+   * \param n7 the name of the attribute to set
+   * \param v7 the value of the attribute to set
+   */
+  void SetPhy (std::string name,
+               std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
+               std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
+               std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
+               std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
+               std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
+               std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
+               std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
+               std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
+
+  /**
+   * set the channel that will be used by SpectrumPhy instances created by this helper
+   *
+   * @param channel
+   */
+  void SetChannel (Ptr<SpectrumChannel> channel);
+
+  /**
+   * set the channel that will be used by SpectrumPhy instances created by this helper
+   *
+   * @param channel
+   */
+  void SetChannel (std::string channelName);
+
+  /**
+   * \param name the name of the attribute to set
+   * \param v the value of the attribute
+   *
+   * Set an attribute of the SpectrumPhy instances to be created
+   */
+  void SetPhyAttribute (std::string name, const AttributeValue &v);
+
+  /**
+   *
+   * @param node
+   * @param device
+   *
+   * @return a  newly created SpectrumPhy instance
+   */
+  Ptr<SpectrumPhy> Create (Ptr<Node> node, Ptr<NetDevice> device) const;
+
+
+
+private:
+  ObjectFactory m_phy;
+  Ptr<SpectrumChannel> m_channel;
+};
+
+
+} // namespace ns3
+
+#endif /* SPECTRUM_HELPER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/waveform-generator-helper.cc	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,133 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+#include "ns3/propagation-delay-model.h"
+#include "ns3/spectrum-propagation-loss-model.h"
+#include "ns3/mobility-model.h"
+#include "ns3/log.h"
+#include "ns3/config.h"
+#include "ns3/simulator.h"
+#include "ns3/names.h"
+#include "ns3/spectrum-channel.h"
+#include "ns3/waveform-generator.h"
+#include "ns3/non-communicating-net-device.h"
+#include "waveform-generator-helper.h"
+
+
+
+
+NS_LOG_COMPONENT_DEFINE ("WaveformGeneratorHelper");
+
+namespace ns3 {
+
+
+WaveformGeneratorHelper::WaveformGeneratorHelper ()
+{
+  m_phy.SetTypeId ("ns3::WaveformGenerator");
+  m_device.SetTypeId ("ns3::NonCommunicatingNetDevice");
+}
+
+WaveformGeneratorHelper::~WaveformGeneratorHelper ()
+{
+}
+
+void
+WaveformGeneratorHelper::SetChannel (Ptr<SpectrumChannel> channel)
+{
+  m_channel = channel;
+}
+
+void
+WaveformGeneratorHelper::SetChannel (std::string channelName)
+{
+  Ptr<SpectrumChannel> channel = Names::Find<SpectrumChannel> (channelName);
+  m_channel = channel;
+}
+
+void
+WaveformGeneratorHelper::SetTxPowerSpectralDensity (Ptr<SpectrumValue> txPsd)
+{
+  NS_LOG_FUNCTION (this << txPsd);
+  m_txPsd = txPsd;
+}
+
+
+void
+WaveformGeneratorHelper::SetPhyAttribute (std::string name, const AttributeValue &v)
+{
+  m_phy.Set (name, v);
+}
+
+
+void
+WaveformGeneratorHelper::SetDeviceAttribute (std::string name, const AttributeValue &v)
+{
+  m_device.Set (name, v);
+}
+
+
+NetDeviceContainer
+WaveformGeneratorHelper::Install (NodeContainer c) const
+{
+  NetDeviceContainer devices;
+  for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
+    {
+      Ptr<Node> node = *i;
+
+      Ptr<NonCommunicatingNetDevice> dev = m_device.Create ()->GetObject<NonCommunicatingNetDevice> ();
+     
+      Ptr<WaveformGenerator>  phy = m_phy.Create ()->GetObject<WaveformGenerator> ();
+      NS_ASSERT (phy);
+
+      dev->SetPhy (phy);
+
+      NS_ASSERT (node);
+      phy->SetMobility (node);
+
+      NS_ASSERT (dev);
+      phy->SetDevice (dev);
+
+      NS_ASSERT_MSG (m_txPsd, "you forgot to call WaveformGeneratorHelper::SetTxPowerSpectralDensity ()");
+      phy->SetTxPowerSpectralDensity (m_txPsd);
+
+      NS_ASSERT_MSG (m_channel, "you forgot to call WaveformGeneratorHelper::SetChannel ()");
+      phy->SetChannel (m_channel);
+      //m_channel->AddRx (phy);
+
+      node->AddDevice (dev);
+      devices.Add (dev);
+    }
+  return devices;
+}
+
+NetDeviceContainer
+WaveformGeneratorHelper::Install (Ptr<Node> node) const
+{
+  return Install (NodeContainer (node));
+}
+
+NetDeviceContainer
+WaveformGeneratorHelper::Install (std::string nodeName) const
+{
+  Ptr<Node> node = Names::Find<Node> (nodeName);
+  return Install (node);
+}
+
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/waveform-generator-helper.h	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,113 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#ifndef WAVEFORM_GENERATOR_HELPER_H
+#define WAVEFORM_GENERATOR_HELPER_H
+
+
+#include <string>
+#include <ns3/attribute.h>
+#include <ns3/object-factory.h>
+#include <ns3/node-container.h>
+#include <ns3/net-device-container.h>
+#include <ns3/queue.h>
+
+
+namespace ns3 {
+
+
+class SpectrumValue;
+class SpectrumChannel;
+
+
+class WaveformGeneratorHelper
+{
+public:
+  WaveformGeneratorHelper ();
+  ~WaveformGeneratorHelper ();
+
+  /**
+   * set the SpectrumChannel that will be used by SpectrumPhy instances created by this helper
+   *
+   * @param channel
+   */
+  void SetChannel (Ptr<SpectrumChannel> channel);
+
+  /**
+   * set the SpectrumChannel that will be used by SpectrumPhy instances created by this helper
+   *
+   * @param channel
+   */
+  void SetChannel (std::string channelName);
+
+
+  /**
+   *
+   * @param txPsd the Power Spectral Density to be used for transmission by all created PHY instances
+   */
+  void SetTxPowerSpectralDensity (Ptr<SpectrumValue> txPsd);
+
+
+  /**
+   * @param name the name of the attribute to set
+   * @param v the value of the attribute
+   *
+   * Set these attributes on each HdOfdmSpectrumPhy instance to be created
+   */
+  void SetPhyAttribute (std::string name, const AttributeValue &v);
+
+  /**
+   * @param n1 the name of the attribute to set
+   * @param v1 the value of the attribute to set
+   *
+   * Set these attributes on each AlohaNoackNetDevice created
+   */
+  void SetDeviceAttribute (std::string n1, const AttributeValue &v1);
+
+
+  /**
+    * @param c the set of nodes on which a device must be created
+    * @return a device container which contains all the devices created by this method.
+    */
+  NetDeviceContainer Install (NodeContainer c) const;
+  /**
+   * @param node the node on which a device must be created
+   * \returns a device container which contains all the devices created by this method.
+   */
+  NetDeviceContainer Install (Ptr<Node> node) const;
+  /**
+   * @param nodeName the name of node on which a device must be created
+   * @return a device container which contains all the devices created by this method.
+   */
+  NetDeviceContainer Install (std::string nodeName) const;
+
+
+protected:
+  ObjectFactory m_phy;
+  ObjectFactory m_device;
+  Ptr<SpectrumChannel> m_channel;
+  Ptr<SpectrumValue> m_txPsd;
+};
+
+
+} // namespace ns3
+
+
+#endif /* WAVEFORM_GENERATOR_HELPER_H */
--- a/src/helper/wscript	Fri Jun 11 19:25:18 2010 +0200
+++ b/src/helper/wscript	Fri Jun 11 19:30:06 2010 +0200
@@ -1,7 +1,7 @@
 ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
 
 def build(bld):
-    helper = bld.create_ns3_module('helper', ['internet-stack', 'wifi', 'point-to-point', 'csma', 'olsr', 'global-routing', 'onoff', 'packet-sink', 'udp-echo'])
+    helper = bld.create_ns3_module('helper', ['internet-stack', 'wifi', 'point-to-point', 'csma', 'olsr', 'global-routing', 'onoff', 'packet-sink', 'udp-echo', 'spectrum'])
     helper.source = [
         'node-container.cc',
         'net-device-container.cc',
@@ -22,6 +22,8 @@
         'udp-echo-helper.cc',
         'bridge-helper.cc',
         'yans-wifi-helper.cc',
+        'spectrum-helper.cc',
+        'adhoc-aloha-noack-ideal-phy-helper.cc',
         'v4ping-helper.cc',
         'nqos-wifi-mac-helper.cc',
         'qos-wifi-mac-helper.cc',
@@ -51,6 +53,8 @@
         'trace-helper.cc',
         'wimax-helper.cc',
         'topology-reader-helper.cc',
+        'waveform-generator-helper.cc',
+        'spectrum-analyzer-helper.cc',
         ]
 
     headers = bld.new_task_gen('ns3header')
@@ -75,6 +79,8 @@
         'udp-echo-helper.h',
         'bridge-helper.h',
         'yans-wifi-helper.h',
+        'spectrum-helper.h',
+        'adhoc-aloha-noack-ideal-phy-helper.h',
         'v4ping-helper.h',
         'nqos-wifi-mac-helper.h',
         'qos-wifi-mac-helper.h',
@@ -105,6 +111,8 @@
         'trace-helper.h',
         'wimax-helper.h',
         'topology-reader-helper.h',
+        'waveform-generator-helper.h',
+        'spectrum-analyzer-helper.h',
         ]
 
     env = bld.env_of_name('default')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/phy-mac.h	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,73 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c)  2010 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#ifndef PHY_MAC_H
+#define PHY_MAC_H
+
+#include <ns3/callback.h>
+
+namespace ns3 {
+
+
+/**
+ * This method allows the MAC to instruct the PHY to start a
+ * transmission of a given packet
+ *
+ * @param packet the Packet to be transmitted
+ * @return this method returns false if the PHY will start TX,
+ * true if the PHY refuses to start the TX. If false, the MAC layer
+ * will expect that PhyMacTxEndCallback is invoked at some point later.
+ */
+typedef Callback< bool, Ptr<Packet> > PhyMacTxStartCallback;
+
+/**
+ * this method is invoked by the PHY to notify the MAC that the
+ * transmission of a given packet has been completed.
+ *
+ * @param packet the Packet whose TX has been completed.
+ */
+typedef Callback< void, Ptr<const Packet> > PhyMacTxEndCallback;
+
+/**
+ * This method is used by the PHY to notify the MAC that a RX
+ * attempt is being started, i.e., a valid signal has been
+ * recognized by the PHY.
+ *
+ */
+typedef Callback< void > PhyMacRxStartCallback;
+
+/**
+ * This method is used by the PHY to notify the MAC that a
+ * previously started TX attempt has terminated without success.
+ */
+typedef Callback< void > PhyMacRxEndErrorCallback;
+
+/**
+ * This method is used by the PHY to notify the MAC that a
+ * previously started TX attempt has been successfully completed.
+ *
+ * @param packet the received Packet
+ */
+typedef Callback< void, Ptr<Packet> > PhyMacRxEndOkCallback;
+
+} // namespace ns3
+
+
+#endif /* PHY_MAC_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/spectrum-channel.cc	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,42 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#include "spectrum-channel.h"
+
+
+namespace ns3 {
+
+
+NS_OBJECT_ENSURE_REGISTERED (SpectrumChannel);
+
+TypeId
+SpectrumChannel::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::SpectrumChannel")
+    .SetParent<Channel> ()
+  ;
+  return tid;
+}
+
+SpectrumChannel::~SpectrumChannel ()
+{
+}
+
+} // namespace
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/spectrum-channel.h	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,105 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+
+#ifndef SPECTRUM_CHANNEL_H
+#define SPECTRUM_CHANNEL_H
+
+#include <ns3/object.h>
+#include <ns3/nstime.h>
+#include <ns3/channel.h>
+#include <ns3/spectrum-type.h>
+
+namespace ns3 {
+
+
+class PacketBurst;
+class SpectrumValue;
+class SpectrumPhy;
+class SpectrumPropagationLossModel;
+class PropagationDelayModel;
+
+/**
+ * Defines the interface for spectrum-aware channel implementations
+ *
+ */
+class SpectrumChannel : public Channel
+{
+public:
+  
+  virtual ~SpectrumChannel ();
+  static TypeId GetTypeId (void);
+
+
+  /**
+   * set the propagation loss model to be used
+   * \param loss Ptr to the propagation loss model to be used.
+   */
+  virtual void AddSpectrumPropagationLossModel (Ptr<SpectrumPropagationLossModel> loss) = 0;
+
+  /**
+   * set the  propagation delay model to be used
+   * \param delay Ptr to the propagation delay model to be used.
+   */
+  virtual void SetPropagationDelayModel (Ptr<PropagationDelayModel> delay) = 0;
+
+
+  /**
+   * Used by attached PHY instances to transmit waveforms on the channel
+   *
+   * @param p the PacketBurst associated with the waveform being transmitted
+   * @param txPowerSpectrum the Power Spectral Density of the
+   * waveform, in linear units. The exact unit will depend on the
+   * type of transmission medium involved: W for radio communications, Pa for
+   * underwater acoustic communications. Other transmission media to be defined.
+   * @param duration duration of the packet transmission. It is
+   * assumed that the Power Spectral Density remains constant for the
+   * whole duration of the transmission. In other words, all waveform
+   * have a rect shape with respect to time.
+   * @param sender the SpectrumPhy instance making this function call
+   */
+  virtual void StartTx (Ptr<PacketBurst> p, Ptr <SpectrumValue> txPsd, SpectrumType st, Time duration, Ptr<SpectrumPhy> sender) = 0;
+
+  /**
+   * @brief add a SpectrumPhy to a channel, so it can receive packets
+   *
+   * This method is used to attach a SpectrumPhy instance to a
+   * SpectrumChannel instance, so that the SpectrumPhy can receive
+   * packets sent on that channel. Note that a SpectrumPhy that only
+   * transmits (without receiveing ever) does not need to be added to
+   * the channel. 
+   *
+   * This method is to be implemented by all classes inheriting from
+   * SpectrumChannel. 
+   *
+   * @param phy the SpectrumPhy instance to be added to the channel as
+   * a receiver. 
+   */
+  virtual void AddRx (Ptr<SpectrumPhy> phy) = 0;
+
+};
+
+
+
+}
+
+
+
+#endif /* SPECTRUM_CHANNEL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/spectrum-phy.cc	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,52 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#include "spectrum-phy.h"
+#include <ns3/net-device.h>
+#include <ns3/mobility-model.h>
+#include <ns3/spectrum-value.h>
+#include <ns3/spectrum-channel.h>
+#include <ns3/log.h>
+
+NS_LOG_COMPONENT_DEFINE ("SpectrumPhy");
+
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (SpectrumPhy);
+
+
+TypeId 
+SpectrumPhy::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::SpectrumPhy")
+    .SetParent<Object> ()
+    ;
+  return tid;
+}
+
+  
+SpectrumPhy::~SpectrumPhy ()
+{
+  NS_LOG_FUNCTION (this);
+}
+
+
+} // namespace
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/spectrum-phy.h	Fri Jun 11 19:30:06 2010 +0200
@@ -0,0 +1,123 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#ifndef SPECTRUM_PHY_H
+#define SPECTRUM_PHY_H
+
+
+#include <ns3/object.h>
+#include <ns3/nstime.h>
+#include <ns3/spectrum-type.h>
+
+namespace ns3 {
+
+class PacketBurst;
+class SpectrumChannel;
+class MobilityModel;
+class SpectrumValue;
+class SpectrumModel;
+class NetDevice;
+
+/**
+ * Abstract base class for Spectrum-aware PHY layers
+ *
+ */
+class SpectrumPhy  : public Object
+{
+
+public:
+
+
+  virtual ~SpectrumPhy ();
+  
+  static TypeId GetTypeId (void); 
+
+  /**
+   * set the associated NetDevice instance
+   *
+   * @param d the NetDevice instance
+   */
+  virtual void SetDevice (Ptr<Object> d) = 0;
+
+  /**
+   * get the associated NetDevice instance
+   *
+   * @return a Ptr to the associated NetDevice instance
+   */
+  virtual Ptr<Object> GetDevice () = 0;
+
+  /**
+   * Set the mobility model associated with this device.
+   *
+   * @param m the mobility model
+   */
+  virtual void SetMobility (Ptr<Object> m) = 0;
+
+  /**
+   * get the associated MobilityModel instance
+   *
+   * @return a Ptr to the associated NetDevice instance
+   */
+  virtual Ptr<Object> GetMobility () = 0;
+
+
+  /**
+   * Set the channel attached to this device.
+   *
+   * @param c the channel
+   */
+  virtual void SetChannel (Ptr<SpectrumChannel> c) = 0;
+
+  /** 
+   * 
+   * @return returns the SpectrumModel that this SpectrumPhy expects to be used
+   * for all SpectrumValues that are passed to StartRx. If 0 is
+   * returned, it means that any model will be accepted.
+   */
+  virtual Ptr<const SpectrumModel> GetRxSpectrumModel () const = 0;
+
+  /**
+   * 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 duration the duration of the incoming waveform
+   */
+  virtual void StartRx (Ptr<PacketBurst> p, Ptr <const SpectrumValue> rxPsd, SpectrumType st, Time duration) = 0;
+  
+
+};
+
+
+
+
+
+
+
+
+
+} // namespace ns3 
+
+
+
+
+
+#endif /* SPECTRUM_PHY_H */
--- a/src/node/wscript	Fri Jun 11 19:25:18 2010 +0200
+++ b/src/node/wscript	Fri Jun 11 19:30:06 2010 +0200
@@ -49,6 +49,8 @@
         'packetbb.cc',
         'packetbb-test-suite.cc',
         'radiotap-header.cc',
+        'spectrum-phy.cc',
+        'spectrum-channel.cc',        
         ]
 
     headers = bld.new_task_gen('ns3header')
@@ -98,4 +100,7 @@
         'ipv6-routing-protocol.h',
         'packetbb.h',
         'radiotap-header.h',
+        'spectrum-phy.h',
+        'spectrum-channel.h',
+        'phy-mac.h',
         ]
--- a/src/wscript	Fri Jun 11 19:25:18 2010 +0200
+++ b/src/wscript	Fri Jun 11 19:30:06 2010 +0200
@@ -43,7 +43,8 @@
     'helper',
     'contrib/stats',
     'applications/v4ping',
-    'devices/mesh',
+    'devices/spectrum',
+    'devices/mesh',   
     'devices/mesh/dot11s',
     'devices/mesh/flame',
     'applications/ping6',
--- a/test.py	Fri Jun 11 19:25:18 2010 +0200
+++ b/test.py	Fri Jun 11 19:30:06 2010 +0200
@@ -119,6 +119,9 @@
     ("routing/static-routing-slash32", "True", "True"),
     ("routing/aodv", "True", "True"),
 
+    ("spectrum/adhoc-aloha-ideal-phy", "True", "True"),
+    ("spectrum/adhoc-aloha-ideal-phy-with-microwave-oven", "True", "True"),
+
     ("stats/wifi-example-sim", "True", "True"),
 
     ("tap/tap-wifi-dumbbell", "False", "True"), # Requires manual configuration