From 13e4bf1aa79d43e954e642095025e91bee656ad1 Mon Sep 17 00:00:00 2001 From: Tim Schubert Date: Sat, 20 Jun 2020 16:14:00 +0200 Subject: [PATCH] init --- .gitignore | 1 + doc/leo.rst | 98 ++++ examples/isl-example.cc | 66 +++ examples/leo-example.cc | 26 + examples/wscript | 9 + helper/isl-helper.cc | 258 ++++++++++ helper/isl-helper.h | 169 +++++++ helper/leo-helper.cc | 11 + helper/leo-helper.h | 14 + model/isl-channel.cc | 200 ++++++++ model/isl-channel.h | 107 ++++ model/isl-net-device.cc | 742 ++++++++++++++++++++++++++++ model/isl-net-device.h | 499 +++++++++++++++++++ model/isl-propagation-loss-model.cc | 73 +++ model/isl-propagation-loss-model.h | 62 +++ model/leo-mobility-model.cc | 69 +++ model/leo-mobility-model.h | 64 +++ model/leo.cc | 11 + model/leo.h | 12 + test/leo-test-suite.cc | 68 +++ wscript | 42 ++ 21 files changed, 2601 insertions(+) create mode 100644 .gitignore create mode 100644 doc/leo.rst create mode 100644 examples/isl-example.cc create mode 100644 examples/leo-example.cc create mode 100644 examples/wscript create mode 100644 helper/isl-helper.cc create mode 100644 helper/isl-helper.h create mode 100644 helper/leo-helper.cc create mode 100644 helper/leo-helper.h create mode 100644 model/isl-channel.cc create mode 100644 model/isl-channel.h create mode 100644 model/isl-net-device.cc create mode 100644 model/isl-net-device.h create mode 100644 model/isl-propagation-loss-model.cc create mode 100644 model/isl-propagation-loss-model.h create mode 100644 model/leo-mobility-model.cc create mode 100644 model/leo-mobility-model.h create mode 100644 model/leo.cc create mode 100644 model/leo.h create mode 100644 test/leo-test-suite.cc create mode 100644 wscript diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1377554 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.swp diff --git a/doc/leo.rst b/doc/leo.rst new file mode 100644 index 0000000..3dcd9d2 --- /dev/null +++ b/doc/leo.rst @@ -0,0 +1,98 @@ +Example Module Documentation +---------------------------- + +.. include:: replace.txt +.. highlight:: cpp + +.. heading hierarchy: + ------------- Chapter + ************* Section (#.#) + ============= Subsection (#.#.#) + ############# Paragraph (no number) + +This is a suggested outline for adding new module documentation to |ns3|. +See ``src/click/doc/click.rst`` for an example. + +The introductory paragraph is for describing what this code is trying to +model. + +For consistency (italicized formatting), please use |ns3| to refer to +ns-3 in the documentation (and likewise, |ns2| for ns-2). These macros +are defined in the file ``replace.txt``. + +Model Description +***************** + +The source code for the new module lives in the directory ``src/leo``. + +Add here a basic description of what is being modeled. + +Design +====== + +Briefly describe the software design of the model and how it fits into +the existing ns-3 architecture. + +Scope and Limitations +===================== + +What can the model do? What can it not do? Please use this section to +describe the scope and limitations of the model. + +References +========== + +Add academic citations here, such as if you published a paper on this +model, or if readers should read a particular specification or other work. + +Usage +***** + +This section is principally concerned with the usage of your model, using +the public API. Focus first on most common usage patterns, then go +into more advanced topics. + +Building New Module +=================== + +Include this subsection only if there are special build instructions or +platform limitations. + +Helpers +======= + +What helper API will users typically use? Describe it here. + +Attributes +========== + +What classes hold attributes, and what are the key ones worth mentioning? + +Output +====== + +What kind of data does the model generate? What are the key trace +sources? What kind of logging output can be enabled? + +Advanced Usage +============== + +Go into further details (such as using the API outside of the helpers) +in additional sections, as needed. + +Examples +======== + +What examples using this new code are available? Describe them here. + +Troubleshooting +=============== + +Add any tips for avoiding pitfalls, etc. + +Validation +********** + +Describe how the model has been tested/validated. What tests run in the +test suite? How much API and code is covered by the tests? Again, +references to outside published work may help here. diff --git a/examples/isl-example.cc b/examples/isl-example.cc new file mode 100644 index 0000000..76f70f9 --- /dev/null +++ b/examples/isl-example.cc @@ -0,0 +1,66 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ + +#include "ns3/core-module.h" +#include "ns3/network-module.h" +#include "ns3/internet-module.h" +#include "ns3/applications-module.h" +#include "ns3/node-container.h" + +#include "ns3/leo-module.h" + +using namespace ns3; + +NS_LOG_COMPONENT_DEFINE ("IslExample"); + +int +main (int argc, char *argv[]) +{ + CommandLine cmd; + cmd.Parse (argc, argv); + + Time::SetResolution (Time::NS); + LogComponentEnable ("UdpEchoClientApplication", LOG_LEVEL_INFO); + LogComponentEnable ("UdpEchoServerApplication", LOG_LEVEL_INFO); + LogComponentEnable ("UdpClient", LOG_LEVEL_DEBUG); + LogComponentEnable ("IslChannel", LOG_LEVEL_LOGIC); + + NodeContainer nodes; + nodes.Create (2); + + IslHelper isl; + isl.SetDeviceAttribute ("DataRate", StringValue ("5Gbps")); + isl.SetChannelAttribute ("PropagationDelay", StringValue ("ns3::ConstantSpeedPropagationDelayModel")); + isl.SetChannelAttribute ("PropagationLoss", StringValue ("ns3::IslPropagationLossModel")); + isl.SetDeviceAttribute ("MobilityModel", StringValue ("ns3::LeoMobilityModel")); + + NetDeviceContainer devices; + devices = isl.Install (nodes); + + InternetStackHelper stack; + stack.Install (nodes); + + Ipv6AddressHelper address; + + Ipv6InterfaceContainer interfaces = address.Assign (devices); + + UdpEchoServerHelper echoServer (9); + + ApplicationContainer serverApps = echoServer.Install (nodes.Get (1)); + serverApps.Start (Seconds (1.0)); + serverApps.Stop (Seconds (10.0)); + + Address destAddress = interfaces.GetAddress (1, 0); + UdpEchoClientHelper echoClient (destAddress, 9); + echoClient.SetAttribute ("MaxPackets", UintegerValue (10)); + echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.0))); + echoClient.SetAttribute ("PacketSize", UintegerValue (1024)); + + ApplicationContainer clientApps = echoClient.Install (nodes.Get (0)); + clientApps.Start (Seconds (2.0)); + clientApps.Stop (Seconds (10.0)); + + Simulator::Run (); + Simulator::Destroy (); + + return 0; +} diff --git a/examples/leo-example.cc b/examples/leo-example.cc new file mode 100644 index 0000000..da74093 --- /dev/null +++ b/examples/leo-example.cc @@ -0,0 +1,26 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ + +#include "ns3/core-module.h" +#include "ns3/leo-helper.h" + +using namespace ns3; + + +int +main (int argc, char *argv[]) +{ + bool verbose = true; + + CommandLine cmd; + cmd.AddValue ("verbose", "Tell application to log if true", verbose); + + cmd.Parse (argc,argv); + + /* ... */ + + Simulator::Run (); + Simulator::Destroy (); + return 0; +} + + diff --git a/examples/wscript b/examples/wscript new file mode 100644 index 0000000..ed4a77c --- /dev/null +++ b/examples/wscript @@ -0,0 +1,9 @@ +# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- + +def build(bld): + obj = bld.create_ns3_program('leo-example', ['leo']) + obj.source = 'leo-example.cc' + + obj = bld.create_ns3_program('isl-example', ['leo']) + obj.source = 'isl-example.cc' + diff --git a/helper/isl-helper.cc b/helper/isl-helper.cc new file mode 100644 index 0000000..3af9480 --- /dev/null +++ b/helper/isl-helper.cc @@ -0,0 +1,258 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2008 INRIA + * + * 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: Mathieu Lacage + */ + +#include "ns3/abort.h" +#include "ns3/log.h" +#include "ns3/simulator.h" +#include "ns3/point-to-point-net-device.h" +#include "ns3/point-to-point-channel.h" +#include "ns3/point-to-point-remote-channel.h" +#include "ns3/queue.h" +#include "ns3/config.h" +#include "ns3/packet.h" +#include "ns3/names.h" +#include "ns3/trace-helper.h" + +#include "../model/isl-net-device.h" +#include "../model/isl-channel.h" +#include "isl-helper.h" + +namespace ns3 { + +NS_LOG_COMPONENT_DEFINE ("IslHelper"); + +IslHelper::IslHelper () +{ + m_queueFactory.SetTypeId ("ns3::DropTailQueue"); + m_deviceFactory.SetTypeId ("ns3::IslNetDevice"); + m_channelFactory.SetTypeId ("ns3::IslChannel"); +} + +void +IslHelper::SetQueue (std::string type, + std::string n1, const AttributeValue &v1, + std::string n2, const AttributeValue &v2, + std::string n3, const AttributeValue &v3, + std::string n4, const AttributeValue &v4) +{ + QueueBase::AppendItemTypeIfNotPresent (type, "Packet"); + + m_queueFactory.SetTypeId (type); + m_queueFactory.Set (n1, v1); + m_queueFactory.Set (n2, v2); + m_queueFactory.Set (n3, v3); + m_queueFactory.Set (n4, v4); +} + +void +IslHelper::SetDeviceAttribute (std::string n1, const AttributeValue &v1) +{ + m_deviceFactory.Set (n1, v1); +} + +void +IslHelper::SetChannelAttribute (std::string n1, const AttributeValue &v1) +{ + m_channelFactory.Set (n1, v1); +} + +void +IslHelper::EnablePcapInternal (std::string prefix, Ptr nd, bool promiscuous, bool explicitFilename) +{ + // + // All of the Pcap enable functions vector through here including the ones + // that are wandering through all of devices on perhaps all of the nodes in + // the system. We can only deal with devices of type IslNetDevice. + // + Ptr device = nd->GetObject (); + if (device == 0) + { + NS_LOG_INFO ("IslHelper::EnablePcapInternal(): Device " << device << " not of type ns3::IslNetDevice"); + return; + } + + PcapHelper pcapHelper; + + std::string filename; + if (explicitFilename) + { + filename = prefix; + } + else + { + filename = pcapHelper.GetFilenameFromDevice (prefix, device); + } + + Ptr file = pcapHelper.CreateFile (filename, std::ios::out, + PcapHelper::DLT_PPP); + pcapHelper.HookDefaultSink (device, "PromiscSniffer", file); +} + +void +IslHelper::EnableAsciiInternal ( + Ptr stream, + std::string prefix, + Ptr nd, + bool explicitFilename) +{ + // + // All of the ascii enable functions vector through here including the ones + // that are wandering through all of devices on perhaps all of the nodes in + // the system. We can only deal with devices of type IslNetDevice. + // + Ptr device = nd->GetObject (); + if (device == 0) + { + NS_LOG_INFO ("IslHelper::EnableAsciiInternal(): Device " << device << + " not of type ns3::IslNetDevice"); + return; + } + + // + // Our default trace sinks are going to use packet printing, so we have to + // make sure that is turned on. + // + Packet::EnablePrinting (); + + // + // If we are not provided an OutputStreamWrapper, we are expected to create + // one using the usual trace filename conventions and do a Hook*WithoutContext + // since there will be one file per context and therefore the context would + // be redundant. + // + if (stream == 0) + { + // + // Set up an output stream object to deal with private ofstream copy + // constructor and lifetime issues. Let the helper decide the actual + // name of the file given the prefix. + // + AsciiTraceHelper asciiTraceHelper; + + std::string filename; + if (explicitFilename) + { + filename = prefix; + } + else + { + filename = asciiTraceHelper.GetFilenameFromDevice (prefix, device); + } + + Ptr theStream = asciiTraceHelper.CreateFileStream (filename); + + // + // The MacRx trace source provides our "r" event. + // + asciiTraceHelper.HookDefaultReceiveSinkWithoutContext (device, "MacRx", theStream); + + // + // The "+", '-', and 'd' events are driven by trace sources actually in the + // transmit queue. + // + Ptr > queue = device->GetQueue (); + asciiTraceHelper.HookDefaultEnqueueSinkWithoutContext > (queue, "Enqueue", theStream); + asciiTraceHelper.HookDefaultDropSinkWithoutContext > (queue, "Drop", theStream); + asciiTraceHelper.HookDefaultDequeueSinkWithoutContext > (queue, "Dequeue", theStream); + + // PhyRxDrop trace source for "d" event + asciiTraceHelper.HookDefaultDropSinkWithoutContext (device, "PhyRxDrop", theStream); + + return; + } + + // + // If we are provided an OutputStreamWrapper, we are expected to use it, and + // to providd a context. We are free to come up with our own context if we + // want, and use the AsciiTraceHelper Hook*WithContext functions, but for + // compatibility and simplicity, we just use Config::Connect and let it deal + // with the context. + // + // Note that we are going to use the default trace sinks provided by the + // ascii trace helper. There is actually no AsciiTraceHelper in sight here, + // but the default trace sinks are actually publicly available static + // functions that are always there waiting for just such a case. + // + uint32_t nodeid = nd->GetNode ()->GetId (); + uint32_t deviceid = nd->GetIfIndex (); + std::ostringstream oss; + + oss << "/NodeList/" << nd->GetNode ()->GetId () << "/DeviceList/" << deviceid << "/$ns3::IslNetDevice/MacRx"; + Config::Connect (oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultReceiveSinkWithContext, stream)); + + oss.str (""); + oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::IslNetDevice/TxQueue/Enqueue"; + Config::Connect (oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultEnqueueSinkWithContext, stream)); + + oss.str (""); + oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::IslNetDevice/TxQueue/Dequeue"; + Config::Connect (oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultDequeueSinkWithContext, stream)); + + oss.str (""); + oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::IslNetDevice/TxQueue/Drop"; + Config::Connect (oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultDropSinkWithContext, stream)); + + oss.str (""); + oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::IslNetDevice/PhyRxDrop"; + Config::Connect (oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultDropSinkWithContext, stream)); +} + +NetDeviceContainer +IslHelper::Install (NodeContainer c) +{ + std::vector > nodes = std::vector >(c.Begin(), c.End()); + return Install (nodes); +} + +NetDeviceContainer +IslHelper::Install (std::vector > &nodes) +{ + Ptr channel = m_channelFactory.Create (); + + NetDeviceContainer container; + + for (Ptr node: nodes) + { + Ptr dev = m_deviceFactory.Create (); + dev->SetAddress (Mac48Address::Allocate ()); + node->AddDevice (dev); + Ptr > queue = m_queueFactory.Create > (); + dev->SetQueue (queue); + dev->Attach (channel); + container.Add (dev); + } + + return container; +} + +NetDeviceContainer +IslHelper::Install (std::vector &names) +{ + std::vector > nodes; + for (std::string name : names) + { + Ptr node = Names::Find(name); + nodes.push_back (node); + } + + return Install (nodes); +} + +} // namespace ns3 diff --git a/helper/isl-helper.h b/helper/isl-helper.h new file mode 100644 index 0000000..a811058 --- /dev/null +++ b/helper/isl-helper.h @@ -0,0 +1,169 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2008 INRIA + * + * 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: Mathieu Lacage + */ +#ifndef ISL_HELPER_H +#define ISL_HELPER_H + +#include + +#include +#include +#include + +#include + +namespace ns3 { + +class NetDevice; +class Node; + +/** + * \brief Build a set of IslNetDevice objects + * + * Normally we eschew multiple inheritance, however, the classes + * PcapUserHelperForDevice and AsciiTraceUserHelperForDevice are + * "mixins". + */ +class IslHelper : public PcapHelperForDevice, + public AsciiTraceHelperForDevice +{ +public: + /** + * Create a IslHelper to make life easier when creating ISL networks. + */ + IslHelper (); + virtual ~IslHelper () {} + + /** + * Each point to point net device must have a queue to pass packets through. + * This method allows one to set the type of the queue that is automatically + * created when the device is created and attached to a node. + * + * \param type the type of queue + * \param n1 the name of the attribute to set on the queue + * \param v1 the value of the attribute to set on the queue + * \param n2 the name of the attribute to set on the queue + * \param v2 the value of the attribute to set on the queue + * \param n3 the name of the attribute to set on the queue + * \param v3 the value of the attribute to set on the queue + * \param n4 the name of the attribute to set on the queue + * \param v4 the value of the attribute to set on the queue + * + * Set the type of queue to create and associated to each + * IslNetDevice created through IslHelper::Install. + */ + void SetQueue (std::string type, + 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 ()); + + + /** + * Set an attribute value to be propagated to each NetDevice created by the + * helper. + * + * \param name the name of the attribute to set + * \param value the value of the attribute to set + * + * Set these attributes on each ns3::IslNetDevice created + * by IslHelper::Install + */ + void SetDeviceAttribute (std::string name, const AttributeValue &value); + + /** + * Set an attribute value to be propagated to each Channel created by the + * helper. + * + * \param name the name of the attribute to set + * \param value the value of the attribute to set + * + * Set these attribute on each ns3::IslChannel created + * by IslHelper::Install + */ + void SetChannelAttribute (std::string name, const AttributeValue &value); + + /** + * \param c a set of nodes + * \return a NetDeviceContainer for nodes + * + * This method creates a ns3::IslChannel with the + * attributes configured by IslHelper::SetChannelAttribute, + * then, for each node in the input container, we create a + * ns3::IslNetDevice with the requested attributes, + * a queue for this ns3::NetDevice, and associate the resulting + * ns3::NetDevice with the ns3::Node and ns3::IslChannel. + */ + NetDeviceContainer Install (NodeContainer c); + + /** + * \param nodes Nodes + * \return a NetDeviceContainer for nodes + * + * Saves you from having to construct a temporary NodeContainer. + */ + NetDeviceContainer Install (std::vector > &nodes); + + /** + * \param nodes Names of the nodes + * \return a NetDeviceContainer for nodes + * + * Saves you from having to construct a temporary NodeContainer. + */ + NetDeviceContainer Install (std::vector &nodes); + +private: + /** + * \brief Enable pcap output the indicated net device. + * + * NetDevice-specific implementation mechanism for hooking the trace and + * writing to the trace file. + * + * \param prefix Filename prefix to use for pcap files. + * \param nd Net device for which you want to enable tracing. + * \param promiscuous If true capture all possible packets available at the device. + * \param explicitFilename Treat the prefix as an explicit filename if true + */ + virtual void EnablePcapInternal (std::string prefix, Ptr nd, bool promiscuous, bool explicitFilename); + + /** + * \brief Enable ascii trace output on the indicated net device. + * + * NetDevice-specific implementation mechanism for hooking the trace and + * writing to the trace file. + * + * \param stream The output stream object to use when logging ascii traces. + * \param prefix Filename prefix to use for ascii trace files. + * \param nd Net device for which you want to enable tracing. + * \param explicitFilename Treat the prefix as an explicit filename if true + */ + virtual void EnableAsciiInternal ( + Ptr stream, + std::string prefix, + Ptr nd, + bool explicitFilename); + + ObjectFactory m_queueFactory; //!< Queue Factory + ObjectFactory m_channelFactory; //!< Channel Factory + ObjectFactory m_deviceFactory; //!< Device Factory +}; + +} // namespace ns3 + +#endif /* ISL_HELPER_H */ diff --git a/helper/leo-helper.cc b/helper/leo-helper.cc new file mode 100644 index 0000000..e8bf307 --- /dev/null +++ b/helper/leo-helper.cc @@ -0,0 +1,11 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ + +#include "leo-helper.h" + +namespace ns3 { + +/* ... */ + + +} + diff --git a/helper/leo-helper.h b/helper/leo-helper.h new file mode 100644 index 0000000..c2cfe88 --- /dev/null +++ b/helper/leo-helper.h @@ -0,0 +1,14 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +#ifndef LEO_HELPER_H +#define LEO_HELPER_H + +#include "ns3/leo.h" + +namespace ns3 { + +/* ... */ + +} + +#endif /* LEO_HELPER_H */ + diff --git a/model/isl-channel.cc b/model/isl-channel.cc new file mode 100644 index 0000000..71ceb6b --- /dev/null +++ b/model/isl-channel.cc @@ -0,0 +1,200 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2007, 2008 University of Washington + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include "isl-channel.h" + +namespace ns3 { + +NS_LOG_COMPONENT_DEFINE ("IslChannel"); + +NS_OBJECT_ENSURE_REGISTERED (IslChannel); + +TypeId +IslChannel::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::IslChannel") + .SetParent () + .SetGroupName ("Leo") + .AddConstructor () + .AddAttribute ("PropagationDelay", + "A propagation delay model for the channel.", + PointerValue (), + MakePointerAccessor (&IslChannel::m_propagationDelay), + MakePointerChecker ()) + .AddAttribute ("PropagationLoss", + "A propagation loss model for the channel.", + PointerValue (), + MakePointerAccessor (&IslChannel::m_propagationLoss), + MakePointerChecker ()) + .AddTraceSource ("TxRxIslChannel", + "Trace source indicating transmission of packet " + "from the IslChannel, used by the Animation " + "interface.", + MakeTraceSourceAccessor (&IslChannel::m_txrxIsl), + "ns3::IslChannel::TxRxAnimationCallback") + ; + return tid; +} + +// +// By default, you get a channel that +// has an "infitely" fast transmission speed and zero processing delay. +IslChannel::IslChannel() : Channel (), m_link (0) +{ + NS_LOG_FUNCTION_NOARGS (); +} + +IslChannel::~IslChannel() +{ +} + +bool +IslChannel::Detach (uint32_t deviceId) +{ + NS_LOG_FUNCTION (this << deviceId); + if (deviceId < m_link.size ()) + { + if (!m_link[deviceId]->IsLinkUp ()) + { + NS_LOG_WARN ("IslChannel::Detach(): Device is already detached (" << deviceId << ")"); + return false; + } + + m_link[deviceId]->NotifyLinkDown (); + } + else + { + return false; + } + return true; +} + +int32_t +IslChannel::Attach (Ptr device) +{ + NS_LOG_FUNCTION (this << device); + NS_ASSERT (device != 0); + m_link.push_back(device); + return m_link.size() - 1; +} + +std::size_t +IslChannel::GetNDevices (void) const +{ + NS_LOG_FUNCTION_NOARGS (); + return m_link.size (); +} + +Ptr +IslChannel::GetDevice (std::size_t i) const +{ + NS_LOG_FUNCTION_NOARGS (); + return m_link[i]; +} + +bool IslChannel::Deliver ( + Ptr p, + Ptr src, + Ptr dst, + Time txTime) +{ + Time delay = GetDelay (src, dst, txTime); + + /* Check if there is LOS between the source and destination */ + if (m_propagationLoss->CalcRxPower(1, src->GetMobilityModel(), dst->GetMobilityModel()) > 0) + { + Simulator::ScheduleWithContext (dst->GetNode ()->GetId (), + delay, + &IslNetDevice::Receive, + dst, + p->Copy ()); + + // Call the tx anim callback on the net device + m_txrxIsl (p, src, dst, txTime, delay); + return true; + } + else + { + NS_LOG_LOGIC (dst << " unreachable from " << src); + + return false; + } +} + +bool +IslChannel::TransmitStart ( + Ptr p, + uint32_t srcId, + Address destAddr, + Time txTime) +{ + NS_LOG_FUNCTION (destAddr << this << p << srcId); + NS_LOG_LOGIC ("UID is " << p->GetUid () << ")"); + + Ptr src = m_link[srcId]; + Ptr dst = GetDevice (destAddr); + + if (dst == nullptr) + { + NS_LOG_LOGIC ("destination address " << destAddr << " unknown on channel"); + for (uint32_t i = 0; i < m_link.size (); i++) + { + Deliver (p, src, m_link[i], txTime); + } + return true; + } + else + { + return Deliver (p, src, dst, txTime); + } +} + +Time +IslChannel::GetDelay (Ptr src, Ptr dst, Time txTime) const +{ + NS_LOG_DEBUG ("Get delay from " << src << " to " << dst); + + Ptr modSrc = src->GetMobilityModel (); + Ptr modDst = dst->GetMobilityModel (); + + Time propagationDelay = m_propagationDelay->GetDelay (modSrc, modDst); + + return txTime + propagationDelay; +} + +// TODO optimize +Ptr +IslChannel::GetDevice (Address &addr) const +{ + for (Ptr dev : m_link) + { + if (dev->GetAddress () == addr) + { + return dev; + } + } + + return 0; +} + +} // namespace ns3 diff --git a/model/isl-channel.h b/model/isl-channel.h new file mode 100644 index 0000000..de0c8c8 --- /dev/null +++ b/model/isl-channel.h @@ -0,0 +1,107 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * 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 + */ + +#ifndef ISL_CHANNEL_H +#define ISL_CHANNEL_H + +#include +#include + +#include "ns3/object.h" +#include "ns3/ptr.h" +#include "ns3/channel.h" +#include "ns3/mobility-model.h" +#include "ns3/net-device.h" +#include "ns3/time-data-calculators.h" +#include "ns3/traced-callback.h" +#include "ns3/mobility-module.h" +#include "ns3/propagation-delay-model.h" +#include "ns3/propagation-loss-model.h" +#include "isl-net-device.h" + +namespace ns3 { + +class IslNetDevice; + +/** + * \ingroup network + * \defgroup channel Channel + */ +/** + * \ingroup channel + * \brief Simplified inter-satellite channel + * + * A perfect channel with varariable delay (time-of-flight). + * + */ +class IslChannel : public Channel +{ +public: + static TypeId GetTypeId (void); + + IslChannel (); + virtual ~IslChannel (); + + /** + * \brief Attach a device to the channel. + * \param device Device to attach to the channel + * \return Index of the device inside the devices list + */ + int32_t Attach (Ptr device); + + /** + * \brief Detach a given netdevice from this channel + * \param device pointer to the netdevice to detach from the channel + * \return true on success, false on failure + */ + bool Detach (uint32_t deviceId); + virtual std::size_t GetNDevices (void) const; + virtual Ptr GetDevice (std::size_t i) const; + virtual bool TransmitStart (Ptr p, uint32_t devId, Address dst, Time txTime); + +protected: + /** + * \brief Get the delay associated with this channel + * \returns Time delay + */ + Time GetDelay (Ptr first, Ptr second, Time txTime) const; + +private: + + Ptr GetDevice (Address &addr) const; + + TracedCallback, // Packet being transmitted + Ptr, // Transmitting NetDevice + Ptr, // Receiving NetDevice + Time, // Amount of time to transmit the pkt + Time // Last bit receive time (relative to now) + > m_txrxIsl; + /** + * \brief Propagation delay model to be used with this channel + */ + Ptr m_propagationDelay; + /** + * \brief Propagation loss model to be used with this channel + */ + Ptr m_propagationLoss; + std::vector > m_link; + + bool Deliver (Ptr p, Ptr src, Ptr dst, Time txTime); +}; // class IslChannel + +} // namespace ns3 + +#endif /* ISL_CHANNEL_H */ diff --git a/model/isl-net-device.cc b/model/isl-net-device.cc new file mode 100644 index 0000000..00399e9 --- /dev/null +++ b/model/isl-net-device.cc @@ -0,0 +1,742 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2007, 2008 University of Washington + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "ns3/log.h" +#include "ns3/queue.h" +#include "ns3/simulator.h" +#include "ns3/mac48-address.h" +#include "ns3/llc-snap-header.h" +#include "ns3/error-model.h" +#include "ns3/trace-source-accessor.h" +#include "ns3/uinteger.h" +#include "ns3/pointer.h" +#include "ns3/net-device-queue-interface.h" +#include "ns3/ppp-header.h" +#include "isl-channel.h" +#include "isl-net-device.h" + +namespace ns3 { + +NS_LOG_COMPONENT_DEFINE ("IslNetDevice"); + +NS_OBJECT_ENSURE_REGISTERED (IslNetDevice); + +TypeId +IslNetDevice::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::IslNetDevice") + .SetParent () + .SetGroupName ("Leo") + .AddConstructor () + .AddAttribute ("Mtu", "The MAC-level Maximum Transmission Unit", + UintegerValue (DEFAULT_MTU), + MakeUintegerAccessor (&IslNetDevice::SetMtu, + &IslNetDevice::GetMtu), + MakeUintegerChecker ()) + .AddAttribute ("Address", + "The MAC address of this device.", + Mac48AddressValue (Mac48Address ("ff:ff:ff:ff:ff:ff")), + MakeMac48AddressAccessor (&IslNetDevice::m_address), + MakeMac48AddressChecker ()) + .AddAttribute ("DataRate", + "The default data rate for point to point links", + DataRateValue (DataRate ("32768b/s")), + MakeDataRateAccessor (&IslNetDevice::m_bps), + MakeDataRateChecker ()) + .AddAttribute ("ReceiveErrorModel", + "The receiver error model used to simulate packet loss", + PointerValue (), + MakePointerAccessor (&IslNetDevice::m_receiveErrorModel), + MakePointerChecker ()) + .AddAttribute ("InterframeGap", + "The time to wait between packet (frame) transmissions", + TimeValue (Seconds (0.0)), + MakeTimeAccessor (&IslNetDevice::m_tInterframeGap), + MakeTimeChecker ()) + + // + // Transmit queueing discipline for the device which includes its own set + // of trace hooks. + // + .AddAttribute ("TxQueue", + "A queue to use as the transmit queue in the device.", + PointerValue (), + MakePointerAccessor (&IslNetDevice::m_queue), + MakePointerChecker > ()) + .AddAttribute ("MobilityModel", "The mobility model of the device", + PointerValue (), + MakePointerAccessor (&IslNetDevice::SetMobilityModel, + &IslNetDevice::GetMobilityModel), + MakePointerChecker ()) + // + // Trace sources at the "top" of the net device, where packets transition + // to/from higher layers. + // + .AddTraceSource ("MacTx", + "Trace source indicating a packet has arrived " + "for transmission by this device", + MakeTraceSourceAccessor (&IslNetDevice::m_macTxTrace), + "ns3::Packet::TracedCallback") + .AddTraceSource ("MacTxDrop", + "Trace source indicating a packet has been dropped " + "by the device before transmission", + MakeTraceSourceAccessor (&IslNetDevice::m_macTxDropTrace), + "ns3::Packet::TracedCallback") + .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 (&IslNetDevice::m_macPromiscRxTrace), + "ns3::Packet::TracedCallback") + .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 (&IslNetDevice::m_macRxTrace), + "ns3::Packet::TracedCallback") +#if 0 + // Not currently implemented for this device + .AddTraceSource ("MacRxDrop", + "Trace source indicating a packet was dropped " + "before being forwarded up the stack", + MakeTraceSourceAccessor (&IslNetDevice::m_macRxDropTrace), + "ns3::Packet::TracedCallback") +#endif + // + // Trace sources at the "bottom" of the net device, where packets transition + // to/from the channel. + // + .AddTraceSource ("PhyTxBegin", + "Trace source indicating a packet has begun " + "transmitting over the channel", + MakeTraceSourceAccessor (&IslNetDevice::m_phyTxBeginTrace), + "ns3::Packet::TracedCallback") + .AddTraceSource ("PhyTxEnd", + "Trace source indicating a packet has been " + "completely transmitted over the channel", + MakeTraceSourceAccessor (&IslNetDevice::m_phyTxEndTrace), + "ns3::Packet::TracedCallback") + .AddTraceSource ("PhyTxDrop", + "Trace source indicating a packet has been " + "dropped by the device during transmission", + MakeTraceSourceAccessor (&IslNetDevice::m_phyTxDropTrace), + "ns3::Packet::TracedCallback") +#if 0 + // Not currently implemented for this device + .AddTraceSource ("PhyRxBegin", + "Trace source indicating a packet has begun " + "being received by the device", + MakeTraceSourceAccessor (&IslNetDevice::m_phyRxBeginTrace), + "ns3::Packet::TracedCallback") +#endif + .AddTraceSource ("PhyRxEnd", + "Trace source indicating a packet has been " + "completely received by the device", + MakeTraceSourceAccessor (&IslNetDevice::m_phyRxEndTrace), + "ns3::Packet::TracedCallback") + .AddTraceSource ("PhyRxDrop", + "Trace source indicating a packet has been " + "dropped by the device during reception", + MakeTraceSourceAccessor (&IslNetDevice::m_phyRxDropTrace), + "ns3::Packet::TracedCallback") + + // + // Trace sources designed to simulate a packet sniffer facility (tcpdump). + // Note that there is really no difference between promiscuous and + // non-promiscuous traces in a point-to-point link. + // + .AddTraceSource ("Sniffer", + "Trace source simulating a non-promiscuous packet sniffer " + "attached to the device", + MakeTraceSourceAccessor (&IslNetDevice::m_snifferTrace), + "ns3::Packet::TracedCallback") + .AddTraceSource ("PromiscSniffer", + "Trace source simulating a promiscuous packet sniffer " + "attached to the device", + MakeTraceSourceAccessor (&IslNetDevice::m_promiscSnifferTrace), + "ns3::Packet::TracedCallback") + ; + return tid; +} + +IslNetDevice::IslNetDevice () + : + m_txMachineState (READY), + m_channel (0), + m_linkUp (false), + m_currentPkt (0) +{ + NS_LOG_FUNCTION (this); +} + +IslNetDevice::~IslNetDevice () +{ + NS_LOG_FUNCTION (this); +} + +void +IslNetDevice::AddHeader (Ptr p, uint16_t protocolNumber) +{ + NS_LOG_FUNCTION (this << p << protocolNumber); + PppHeader ppp; + ppp.SetProtocol (EtherToPpp (protocolNumber)); + p->AddHeader (ppp); +} + +bool +IslNetDevice::ProcessHeader (Ptr p, uint16_t& param) +{ + NS_LOG_FUNCTION (this << p << param); + PppHeader ppp; + p->RemoveHeader (ppp); + param = PppToEther (ppp.GetProtocol ()); + return true; +} + +void +IslNetDevice::DoInitialize (void) +{ + if (m_queueInterface) + { + NS_ASSERT_MSG (m_queue != 0, "A Queue object has not been attached to the device"); + + // connect the traced callbacks of m_queue to the static methods provided by + // the NetDeviceQueue class to support flow control and dynamic queue limits. + // This could not be done in NotifyNewAggregate because at that time we are + // not guaranteed that a queue has been attached to the netdevice + m_queueInterface->GetTxQueue (0)->ConnectQueueTraces (m_queue); + } + + NetDevice::DoInitialize (); +} + +void +IslNetDevice::NotifyNewAggregate (void) +{ + NS_LOG_FUNCTION (this); + if (m_queueInterface == 0) + { + Ptr ndqi = this->GetObject (); + //verify that it's a valid netdevice queue interface and that + //the netdevice queue interface was not set before + if (ndqi != 0) + { + m_queueInterface = ndqi; + } + } + NetDevice::NotifyNewAggregate (); +} + +void +IslNetDevice::DoDispose () +{ + NS_LOG_FUNCTION (this); + m_node = 0; + m_channel = 0; + m_receiveErrorModel = 0; + m_currentPkt = 0; + m_queue = 0; + m_queueInterface = 0; + NetDevice::DoDispose (); +} + +void +IslNetDevice::SetDataRate (DataRate bps) +{ + NS_LOG_FUNCTION (this); + m_bps = bps; +} + +void +IslNetDevice::SetInterframeGap (Time t) +{ + NS_LOG_FUNCTION (this << t.GetSeconds ()); + m_tInterframeGap = t; +} + +bool +IslNetDevice::TransmitStart (Ptr p, const Address &dest) +{ + NS_LOG_FUNCTION (this << p); + NS_LOG_LOGIC ("UID is " << p->GetUid () << ")"); + + // + // This function is called to start the process of transmitting a packet. + // We need to tell the channel that we've started wiggling the wire and + // schedule an event that will be executed when the transmission is complete. + // + NS_ASSERT_MSG (m_txMachineState == READY, "Must be READY to transmit"); + m_txMachineState = BUSY; + m_currentPkt = p; + m_phyTxBeginTrace (m_currentPkt); + + Time txTime = m_bps.CalculateBytesTxTime (p->GetSize ()); + Time txCompleteTime = txTime + m_tInterframeGap; + + NS_LOG_LOGIC ("Schedule TransmitCompleteEvent in " << txCompleteTime.GetSeconds () << "sec"); + Simulator::Schedule (txCompleteTime, &IslNetDevice::TransmitComplete, this, dest); + + bool result = m_channel->TransmitStart (p, m_channelDevId, dest, txTime); + if (result == false) + { + m_phyTxDropTrace (p); + } + return result; +} + +void +IslNetDevice::TransmitComplete (const Address &dest) +{ + NS_LOG_FUNCTION (this); + + // + // This function is called to when we're all done transmitting a packet. + // We try and pull another packet off of the transmit queue. If the queue + // is empty, we are done, otherwise we need to start transmitting the + // next packet. + // + NS_ASSERT_MSG (m_txMachineState == BUSY, "Must be BUSY if transmitting"); + m_txMachineState = READY; + + NS_ASSERT_MSG (m_currentPkt != 0, "IslNetDevice::TransmitComplete(): m_currentPkt zero"); + + m_phyTxEndTrace (m_currentPkt); + m_currentPkt = 0; + + Ptr p = m_queue->Dequeue (); + if (p == 0) + { + NS_LOG_LOGIC ("No pending packets in device queue after tx complete"); + return; + } + + // + // Got another packet off of the queue, so start the transmit process again. + // + m_snifferTrace (p); + m_promiscSnifferTrace (p); + TransmitStart (p, dest); +} + +bool +IslNetDevice::Attach (Ptr ch) +{ + NS_LOG_FUNCTION (this << &ch); + + m_channel = ch; + + m_channelDevId = m_channel->Attach (this); + + // + // This device is up whenever it is attached to a channel. A better plan + // would be to have the link come up when both devices are attached, but this + // is not done for now. + // + NotifyLinkUp (); + return true; +} + +void +IslNetDevice::SetQueue (Ptr > q) +{ + NS_LOG_FUNCTION (this << q); + m_queue = q; +} + +void +IslNetDevice::SetReceiveErrorModel (Ptr em) +{ + NS_LOG_FUNCTION (this << em); + m_receiveErrorModel = em; +} + +void +IslNetDevice::Receive (Ptr packet) +{ + NS_LOG_FUNCTION (this << packet); + uint16_t protocol = 0; + + if (m_receiveErrorModel && m_receiveErrorModel->IsCorrupt (packet) ) + { + // + // If we have an error model and it indicates that it is time to lose a + // corrupted packet, don't forward this packet up, let it go. + // + m_phyRxDropTrace (packet); + } + else + { + // + // Hit the trace hooks. All of these hooks are in the same place in this + // device because it is so simple, but this is not usually the case in + // more complicated devices. + // + m_snifferTrace (packet); + m_promiscSnifferTrace (packet); + m_phyRxEndTrace (packet); + + // + // Trace sinks will expect complete packets, not packets without some of the + // headers. + // + Ptr originalPacket = packet->Copy (); + + // + // Strip off the point-to-point protocol header and forward this packet + // up the protocol stack. Since this is a simple point-to-point link, + // there is no difference in what the promisc callback sees and what the + // normal receive callback sees. + // + ProcessHeader (packet, protocol); + + if (!m_promiscCallback.IsNull ()) + { + m_macPromiscRxTrace (originalPacket); + m_promiscCallback (this, packet, protocol, GetRemote (), GetAddress (), NetDevice::PACKET_HOST); + } + + m_macRxTrace (originalPacket); + m_rxCallback (this, packet, protocol, GetRemote ()); + } +} + +Ptr > +IslNetDevice::GetQueue (void) const +{ + NS_LOG_FUNCTION (this); + return m_queue; +} + +void +IslNetDevice::NotifyLinkUp (void) +{ + NS_LOG_FUNCTION (this); + m_linkUp = true; + m_linkChangeCallbacks (); +} + +void +IslNetDevice::NotifyLinkDown (void) +{ + NS_LOG_FUNCTION (this); + m_linkUp = false; + m_linkChangeCallbacks (); +} + +void +IslNetDevice::SetIfIndex (const uint32_t index) +{ + NS_LOG_FUNCTION (this); + m_ifIndex = index; +} + +uint32_t +IslNetDevice::GetIfIndex (void) const +{ + return m_ifIndex; +} + +Ptr +IslNetDevice::GetChannel (void) const +{ + return m_channel; +} + +// +// This is a point-to-point device, so we really don't need any kind of address +// information. However, the base class NetDevice wants us to define the +// methods to get and set the address. Rather than be rude and assert, we let +// clients get and set the address, but simply ignore them. + +void +IslNetDevice::SetAddress (Address address) +{ + NS_LOG_FUNCTION (this << address); + m_address = Mac48Address::ConvertFrom (address); +} + +Address +IslNetDevice::GetAddress (void) const +{ + return m_address; +} + +bool +IslNetDevice::IsLinkUp (void) const +{ + NS_LOG_FUNCTION (this); + return m_linkUp; +} + +void +IslNetDevice::AddLinkChangeCallback (Callback callback) +{ + NS_LOG_FUNCTION (this); + m_linkChangeCallbacks.ConnectWithoutContext (callback); +} + +// +// This is a point-to-point device, so every transmission is a broadcast to +// all of the devices on the network. +// +bool +IslNetDevice::IsBroadcast (void) const +{ + NS_LOG_FUNCTION (this); + return true; +} + +// +// We don't really need any addressing information since this is a +// point-to-point device. The base class NetDevice wants us to return a +// broadcast address, so we make up something reasonable. +// +Address +IslNetDevice::GetBroadcast (void) const +{ + NS_LOG_FUNCTION (this); + return Mac48Address ("ff:ff:ff:ff:ff:ff"); +} + +bool +IslNetDevice::IsMulticast (void) const +{ + NS_LOG_FUNCTION (this); + return true; +} + +Address +IslNetDevice::GetMulticast (Ipv4Address multicastGroup) const +{ + NS_LOG_FUNCTION (this); + return Mac48Address ("01:00:5e:00:00:00"); +} + +Address +IslNetDevice::GetMulticast (Ipv6Address addr) const +{ + NS_LOG_FUNCTION (this << addr); + return Mac48Address ("33:33:00:00:00:00"); +} + +bool +IslNetDevice::IsIsl (void) const +{ + NS_LOG_FUNCTION (this); + return true; +} + +bool +IslNetDevice::IsBridge (void) const +{ + NS_LOG_FUNCTION (this); + return false; +} + +bool +IslNetDevice::Send ( + Ptr packet, + const Address &dest, + uint16_t protocolNumber) +{ + NS_LOG_FUNCTION (this << packet << dest << protocolNumber); + NS_LOG_LOGIC ("p=" << packet << ", dest=" << &dest); + NS_LOG_LOGIC ("UID is " << packet->GetUid ()); + + // + // If IsLinkUp() is false it means there is no channel to send any packet + // over so we just hit the drop trace on the packet and return an error. + // + if (IsLinkUp () == false) + { + m_macTxDropTrace (packet); + return false; + } + + // + // Stick a point to point protocol header on the packet in preparation for + // shoving it out the door. + // + AddHeader (packet, protocolNumber); + + m_macTxTrace (packet); + + // + // We should enqueue and dequeue the packet to hit the tracing hooks. + // + if (m_queue->Enqueue (packet)) + { + // + // If the channel is ready for transition we send the packet right now + // + if (m_txMachineState == READY) + { + packet = m_queue->Dequeue (); + m_snifferTrace (packet); + m_promiscSnifferTrace (packet); + bool ret = TransmitStart (packet, dest); + return ret; + } + return true; + } + + // Enqueue may fail (overflow) + + m_macTxDropTrace (packet); + return false; +} + +bool +IslNetDevice::SendFrom (Ptr packet, + const Address &source, + const Address &dest, + uint16_t protocolNumber) +{ + NS_LOG_FUNCTION (this << packet << source << dest << protocolNumber); + return false; +} + +Ptr +IslNetDevice::GetNode (void) const +{ + return m_node; +} + +void +IslNetDevice::SetNode (Ptr node) +{ + NS_LOG_FUNCTION (this); + m_node = node; +} + +bool +IslNetDevice::NeedsArp (void) const +{ + NS_LOG_FUNCTION (this); + return true; +} + +void +IslNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb) +{ + m_rxCallback = cb; +} + +void +IslNetDevice::SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb) +{ + m_promiscCallback = cb; +} + +bool +IslNetDevice::SupportsSendFrom (void) const +{ + NS_LOG_FUNCTION (this); + return false; +} + +void +IslNetDevice::DoMpiReceive (Ptr p) +{ + NS_LOG_FUNCTION (this << p); + Receive (p); +} + +Address +IslNetDevice::GetRemote (void) const +{ + NS_LOG_FUNCTION (this); + NS_ASSERT (m_channel->GetNDevices () == 2); + for (std::size_t i = 0; i < m_channel->GetNDevices (); ++i) + { + Ptr tmp = m_channel->GetDevice (i); + if (tmp != this) + { + return tmp->GetAddress (); + } + } + NS_ASSERT (false); + // quiet compiler. + return Address (); +} + +bool +IslNetDevice::SetMtu (uint16_t mtu) +{ + NS_LOG_FUNCTION (this << mtu); + m_mtu = mtu; + return true; +} + +uint16_t +IslNetDevice::GetMtu (void) const +{ + NS_LOG_FUNCTION (this); + return m_mtu; +} + +uint16_t +IslNetDevice::PppToEther (uint16_t proto) +{ + NS_LOG_FUNCTION_NOARGS(); + switch(proto) + { + case 0x0021: return 0x0800; //IPv4 + case 0x0057: return 0x86DD; //IPv6 + case 2054: return 0x0806; //ARP + default: NS_ASSERT_MSG (false, "PPP Protocol number not defined!"); + } + return 0; +} + +uint16_t +IslNetDevice::EtherToPpp (uint16_t proto) +{ + NS_LOG_FUNCTION_NOARGS(); + switch(proto) + { + case 0x0800: return 0x0021; //IPv4 + case 0x86DD: return 0x0057; //IPv6 + case 0x0806: return 2054; //ARP + default: NS_ASSERT_MSG (false, "PPP Protocol number not defined!"); + } + return 0; +} + +Ptr +IslNetDevice::GetMobilityModel (void) const +{ + return m_mobilityModel; +} + +void +IslNetDevice::SetMobilityModel (Ptr model) +{ + NS_LOG_FUNCTION (this); + m_mobilityModel = model; +} + +bool +IslNetDevice::IsPointToPoint() const +{ + return true; +} + +} // namespace ns3 diff --git a/model/isl-net-device.h b/model/isl-net-device.h new file mode 100644 index 0000000..a87619f --- /dev/null +++ b/model/isl-net-device.h @@ -0,0 +1,499 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2007, 2008 University of Washington + * + * 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 + */ + +#ifndef ISL_NET_DEVICE_H +#define ISL_NET_DEVICE_H + +#include + +#include "ns3/address.h" +#include "ns3/node.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/data-rate.h" +#include "ns3/ptr.h" +#include "ns3/mac48-address.h" +#include "ns3/mobility-model.h" + +namespace ns3 { + +template class Queue; +class NetDeviceQueueInterface; +class IslChannel; +class ErrorModel; + +/** + * \defgroup point-to-point Point-To-Point Network Device + * This section documents the API of the ns-3 point-to-point module. For a + * functional description, please refer to the ns-3 manual here: + * http://www.nsnam.org/docs/models/html/point-to-point.html + * + * Be sure to read the manual BEFORE going down to the API. + */ + +/** + * \ingroup point-to-point + * \class IslNetDevice + * \brief A Device for a Point to Point Network Link. + * + * This IslNetDevice class specializes the NetDevice abstract + * base class. Together with a IslChannel (and a peer + * IslNetDevice), the class models, with some level of + * abstraction, a generic point-to-point or serial link. + * Key parameters or objects that can be specified for this device + * include a queue, data rate, and interframe transmission gap (the + * propagation delay is set in the IslChannel). + */ +class IslNetDevice : public NetDevice +{ +public: + /** + * \brief Get the TypeId + * + * \return The TypeId for this class + */ + static TypeId GetTypeId (void); + + /** + * Construct a IslNetDevice + * + * This is the constructor for the IslNetDevice. It takes as a + * parameter a pointer to the Node to which this device is connected, + * as well as an optional DataRate object. + */ + IslNetDevice (); + + /** + * Destroy a IslNetDevice + * + * This is the destructor for the IslNetDevice. + */ + virtual ~IslNetDevice (); + + /** + * Set the Data Rate used for transmission of packets. The data rate is + * set in the Attach () method from the corresponding field in the channel + * to which the device is attached. It can be overridden using this method. + * + * \param bps the data rate at which this object operates + */ + void SetDataRate (DataRate bps); + + /** + * Set the interframe gap used to separate packets. The interframe gap + * defines the minimum space required between packets sent by this device. + * + * \param t the interframe gap time + */ + void SetInterframeGap (Time t); + + /** + * Attach the device to a channel. + * + * \param ch Ptr to the channel to which this object is being attached. + * \return true if the operation was successful (always true actually) + */ + bool Attach (Ptr ch); + + /** + * Attach a queue to the IslNetDevice. + * + * The IslNetDevice "owns" a queue that implements a queueing + * method such as DropTailQueue or RedQueue + * + * \param queue Ptr to the new queue. + */ + void SetQueue (Ptr > queue); + + /** + * Get a copy of the attached Queue. + * + * \returns Ptr to the queue. + */ + Ptr > GetQueue (void) const; + + /** + * Attach a receive ErrorModel to the IslNetDevice. + * + * The IslNetDevice may optionally include an ErrorModel in + * the packet receive chain. + * + * \param em Ptr to the ErrorModel. + */ + void SetReceiveErrorModel (Ptr em); + + /** + * Receive a packet from a connected IslChannel. + * + * The IslNetDevice receives packets from its connected channel + * and forwards them up the protocol stack. This is the public method + * used by the channel to indicate that the last bit of a packet has + * arrived at the device. + * + * \param p Ptr to the received packet. + */ + void Receive (Ptr p); + + // The remaining methods are documented in ns3::NetDevice* + + virtual void SetIfIndex (const uint32_t index); + virtual uint32_t GetIfIndex (void) const; + + virtual Ptr GetChannel (void) const; + + virtual void SetAddress (Address address); + virtual Address GetAddress (void) const; + + virtual bool SetMtu (const uint16_t mtu); + virtual uint16_t GetMtu (void) const; + + virtual bool IsLinkUp (void) const; + + virtual void AddLinkChangeCallback (Callback callback); + + virtual bool IsBroadcast (void) const; + virtual Address GetBroadcast (void) const; + + virtual bool IsMulticast (void) const; + virtual Address GetMulticast (Ipv4Address multicastGroup) const; + + virtual bool IsIsl (void) const; + virtual bool IsBridge (void) const; + + virtual bool IsPointToPoint() const; + + virtual bool Send (Ptr packet, const Address &dest, uint16_t protocolNumber); + virtual bool SendFrom (Ptr packet, const Address& source, const Address& dest, uint16_t protocolNumber); + + virtual Ptr GetNode (void) const; + virtual void SetNode (Ptr node); + + virtual bool NeedsArp (void) const; + + virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb); + + virtual Address GetMulticast (Ipv6Address addr) const; + + virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb); + virtual bool SupportsSendFrom (void) const; + + Ptr GetMobilityModel (void) const; + void SetMobilityModel (Ptr model); + void NotifyLinkDown (void); + +protected: + /** + * \brief Handler for MPI receive event + * + * \param p Packet received + */ + void DoMpiReceive (Ptr p); + + virtual void DoInitialize (void); + virtual void NotifyNewAggregate (void); + +private: + + /** + * \brief Assign operator + * + * The method is private, so it is DISABLED. + * + * \param o Other NetDevice + * \return New instance of the NetDevice + */ + IslNetDevice& operator = (const IslNetDevice &o); + + /** + * \brief Copy constructor + * + * The method is private, so it is DISABLED. + + * \param o Other NetDevice + */ + IslNetDevice (const IslNetDevice &o); + + /** + * \brief Dispose of the object + */ + virtual void DoDispose (void); + +private: + + /** + * \returns the address of the remote device connected to this device + * through the point to point channel. + */ + Address GetRemote (void) const; + + /** + * Adds the necessary headers and trailers to a packet of data in order to + * respect the protocol implemented by the agent. + * \param p packet + * \param protocolNumber protocol number + */ + void AddHeader (Ptr p, uint16_t protocolNumber); + + /** + * Removes, from a packet of data, all headers and trailers that + * relate to the protocol implemented by the agent + * \param p Packet whose headers need to be processed + * \param param An integer parameter that can be set by the function + * \return Returns true if the packet should be forwarded up the + * protocol stack. + */ + bool ProcessHeader (Ptr p, uint16_t& param); + + /** + * Start Sending a Packet Down the Wire. + * + * The TransmitStart method is the method that is used internally in the + * IslNetDevice to begin the process of sending a packet out on + * the channel. The corresponding method is called on the channel to let + * it know that the physical device this class represents has virtually + * started sending signals. An event is scheduled for the time at which + * the bits have been completely transmitted. + * + * \see IslChannel::TransmitStart () + * \see TransmitComplete() + * \param p a reference to the packet to send + * \returns true if success, false on failure + */ + bool TransmitStart (Ptr p, const Address &dest); + + /** + * Stop Sending a Packet Down the Wire and Begin the Interframe Gap. + * + * The TransmitComplete method is used internally to finish the process + * of sending a packet out on the channel. + */ + void TransmitComplete (const Address &dest); + + /** + * \brief Make the link up and running + * + * It calls also the linkChange callback. + */ + void NotifyLinkUp (void); + + /** + * Enumeration of the states of the transmit machine of the net device. + */ + enum TxMachineState + { + READY, /**< The transmitter is ready to begin transmission of a packet */ + BUSY /**< The transmitter is busy transmitting a packet */ + }; + /** + * The state of the Net Device transmit state machine. + */ + TxMachineState m_txMachineState; + + /** + * The data rate that the Net Device uses to simulate packet transmission + * timing. + */ + DataRate m_bps; + + /** + * The interframe gap that the Net Device uses to throttle packet + * transmission + */ + Time m_tInterframeGap; + + /** + * The IslChannel to which this IslNetDevice has been + * attached. + */ + Ptr m_channel; + + /** + * The Queue which this IslNetDevice uses as a packet source. + * Management of this Queue has been delegated to the IslNetDevice + * and it has the responsibility for deletion. + * \see class DropTailQueue + */ + Ptr > m_queue; + + /** + * Error model for receive packet events + */ + Ptr m_receiveErrorModel; + + /** + * The trace source fired when packets come into the "top" of the device + * at the L3/L2 transition, before being queued for transmission. + */ + TracedCallback > m_macTxTrace; + + /** + * The trace source fired when packets coming into the "top" of the device + * at the L3/L2 transition are dropped before being queued for transmission. + */ + TracedCallback > m_macTxDropTrace; + + /** + * The trace source fired for packets successfully received by the device + * immediately before being forwarded up to higher layers (at the L2/L3 + * transition). This is a promiscuous trace (which doesn't mean a lot here + * in the point-to-point device). + */ + TracedCallback > m_macPromiscRxTrace; + + /** + * The trace source fired for packets successfully received by the device + * immediately before being forwarded up to higher layers (at the L2/L3 + * transition). This is a non-promiscuous trace (which doesn't mean a lot + * here in the point-to-point device). + */ + TracedCallback > m_macRxTrace; + + /** + * The trace source fired for packets successfully received by the device + * but are dropped before being forwarded up to higher layers (at the L2/L3 + * transition). + */ + TracedCallback > m_macRxDropTrace; + + /** + * The trace source fired when a packet begins the transmission process on + * the medium. + */ + TracedCallback > m_phyTxBeginTrace; + + /** + * The trace source fired when a packet ends the transmission process on + * the medium. + */ + TracedCallback > m_phyTxEndTrace; + + /** + * The trace source fired when the phy layer drops a packet before it tries + * to transmit it. + */ + TracedCallback > m_phyTxDropTrace; + + /** + * The trace source fired when a packet begins the reception process from + * the medium -- when the simulated first bit(s) arrive. + */ + TracedCallback > m_phyRxBeginTrace; + + /** + * The trace source fired when a packet ends the reception process from + * the medium. + */ + TracedCallback > m_phyRxEndTrace; + + /** + * The trace source fired when the phy layer drops a packet it has received. + * This happens if the receiver is not enabled or the error model is active + * and indicates that the packet is corrupt. + */ + TracedCallback > m_phyRxDropTrace; + + /** + * A trace source that emulates a non-promiscuous protocol sniffer connected + * to the device. Unlike your average everyday sniffer, this trace source + * will not fire on PACKET_OTHERHOST events. + * + * On the transmit size, this trace hook will fire after a packet is dequeued + * from the device queue for transmission. In Linux, for example, this would + * correspond to the point just before a device \c hard_start_xmit where + * \c dev_queue_xmit_nit is called to dispatch the packet to the PF_PACKET + * ETH_P_ALL handlers. + * + * On the receive side, this trace hook will fire when a packet is received, + * just before the receive callback is executed. In Linux, for example, + * this would correspond to the point at which the packet is dispatched to + * packet sniffers in \c netif_receive_skb. + */ + TracedCallback > m_snifferTrace; + + /** + * A trace source that emulates a promiscuous mode protocol sniffer connected + * to the device. This trace source fire on packets destined for any host + * just like your average everyday packet sniffer. + * + * On the transmit size, this trace hook will fire after a packet is dequeued + * from the device queue for transmission. In Linux, for example, this would + * correspond to the point just before a device \c hard_start_xmit where + * \c dev_queue_xmit_nit is called to dispatch the packet to the PF_PACKET + * ETH_P_ALL handlers. + * + * On the receive side, this trace hook will fire when a packet is received, + * just before the receive callback is executed. In Linux, for example, + * this would correspond to the point at which the packet is dispatched to + * packet sniffers in \c netif_receive_skb. + */ + TracedCallback > m_promiscSnifferTrace; + + Ptr m_node; //!< Node owning this NetDevice + Ptr m_queueInterface; //!< NetDevice queue interface + Mac48Address m_address; //!< Mac48Address of this NetDevice + NetDevice::ReceiveCallback m_rxCallback; //!< Receive callback + NetDevice::PromiscReceiveCallback m_promiscCallback; //!< Receive callback + // (promisc data) + uint32_t m_ifIndex; //!< Index of the interface + bool m_linkUp; //!< Identify if the link is up or not + TracedCallback<> m_linkChangeCallbacks; //!< Callback for the link change event + + static const uint16_t DEFAULT_MTU = 1500; //!< Default MTU + + /** + * \brief The Maximum Transmission Unit + * + * This corresponds to the maximum + * number of bytes that can be transmitted as seen from higher layers. + * This corresponds to the 1500 byte MTU size often seen on IP over + * Ethernet. + */ + uint32_t m_mtu; + + /** + * \brief The index into the network device list of the channel. + * + * This is written to when the device is attached. + */ + uint32_t m_channelDevId; + + Ptr m_currentPkt; //!< Current packet processed + + Ptr m_mobilityModel; + + /** + * \brief PPP to Ethernet protocol number mapping + * \param protocol A PPP protocol number + * \return The corresponding Ethernet protocol number + */ + static uint16_t PppToEther (uint16_t protocol); + + /** + * \brief Ethernet to PPP protocol number mapping + * \param protocol An Ethernet protocol number + * \return The corresponding PPP protocol number + */ + static uint16_t EtherToPpp (uint16_t protocol); +}; + +} // namespace ns3 + +#endif /* ISL_NET_DEVICE_H */ diff --git a/model/isl-propagation-loss-model.cc b/model/isl-propagation-loss-model.cc new file mode 100644 index 0000000..de6622b --- /dev/null +++ b/model/isl-propagation-loss-model.cc @@ -0,0 +1,73 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2005,2006,2007 INRIA + * + * 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: Mathieu Lacage + * Contributions: Timo Bingmann + * Contributions: Gary Pei for fixed RSS + * Contributions: Tom Hewer for two ray ground model + * Pavel Boyko for matrix + */ + +#include "isl-propagation-loss-model.h" + +namespace ns3 { + +NS_LOG_COMPONENT_DEFINE ("IslPropagationLossModel"); + +NS_OBJECT_ENSURE_REGISTERED (IslPropagationLossModel); + +TypeId +IslPropagationLossModel::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::IslPropagationLossModel") + .SetParent () + .SetGroupName ("Leo") + .AddConstructor () + ; + return tid; +} + +IslPropagationLossModel::IslPropagationLossModel () +{ +} + +IslPropagationLossModel::~IslPropagationLossModel () +{ +} + +double +IslPropagationLossModel::DoCalcRxPower (double txPowerDbm, + Ptr a, + Ptr b) const +{ + //Vector aPos = a->GetPosition (); + //Vector bPos = b->GetPosition (); + + // TODO perform line-earth intersection (ray tracing) + + double rxc = 0;//-m_variable->GetValue (); + NS_LOG_DEBUG ("attenuation coefficient="< + * Contributions: Timo Bingmann + * Contributions: Gary Pei for fixed RSS + * Contributions: Tom Hewer for two ray ground model + * Pavel Boyko for matrix + */ + +#ifndef ISL_PROPAGATION_LOSS_MODEL_H +#define ISL_PROPAGATION_LOSS_MODEL_H + +#include "leo-mobility-model.h" +#include +#include + +namespace ns3 { + +class IslPropagationLossModel : public PropagationLossModel +{ +public: + static TypeId GetTypeId (void); + IslPropagationLossModel (); + virtual ~IslPropagationLossModel (); +private: + /** + * Returns the Rx Power taking into account only the particular + * PropagationLossModel. + * + * \param txPowerDbm current transmission power (in dBm) + * \param a the mobility model of the source + * \param b the mobility model of the destination + * \returns the reception power after adding/multiplying propagation loss (in dBm) + */ + virtual double DoCalcRxPower (double txPowerDbm, + Ptr a, + Ptr b) const; + /** + * Subclasses must implement this; those not using random variables + * can return zero + */ + virtual int64_t DoAssignStreams (int64_t stream); +}; + +} + +#endif /* SATELLITE_ISL_PROPAGATION_LOSS_MODEL_H */ diff --git a/model/leo-mobility-model.cc b/model/leo-mobility-model.cc new file mode 100644 index 0000000..50c9931 --- /dev/null +++ b/model/leo-mobility-model.cc @@ -0,0 +1,69 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2007, 2008 University of Washington + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "leo-mobility-model.h" + +namespace ns3 { + +NS_LOG_COMPONENT_DEFINE ("LeoMobilityModel"); + +NS_OBJECT_ENSURE_REGISTERED (LeoMobilityModel); + +TypeId +LeoMobilityModel::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::LeoMobilityModel") + .SetParent () + .SetGroupName ("Leo") + .AddConstructor () + ; + return tid; +} + +LeoMobilityModel::~LeoMobilityModel () +{ +} + +Vector +LeoMobilityModel::DoGetPosition (void) const +{ + // TODO + return Vector(); +} + +void +LeoMobilityModel::DoSetPosition (const Vector &position) +{ + // TODO +} + +Vector +LeoMobilityModel::DoGetVelocity (void) const +{ + // TODO + return Vector(); +} + +int64_t +LeoMobilityModel::DoAssignStreams (int64_t start) +{ + // TODO + return 0; +} + +}; diff --git a/model/leo-mobility-model.h b/model/leo-mobility-model.h new file mode 100644 index 0000000..cd0f4c9 --- /dev/null +++ b/model/leo-mobility-model.h @@ -0,0 +1,64 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2007, 2008 University of Washington + * + * 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 + */ + +#ifndef LEO_MOBILITY_MODEL_H +#define LEO_MOBILITY_MODEL_H +#include "ns3/log.h" +#include "ns3/mobility-model.h" + +namespace ns3 { + +class LeoMobilityModel : public MobilityModel { +public: + static TypeId GetTypeId (void); + virtual ~LeoMobilityModel (); + +private: + /** + * \return the current position. + * + * Concrete subclasses of this base class must + * implement this method. + */ + virtual Vector DoGetPosition (void) const; + /** + * \param position the position to set. + * + * Concrete subclasses of this base class must + * implement this method. + */ + virtual void DoSetPosition (const Vector &position); + /** + * \return the current velocity. + * + * Concrete subclasses of this base class must + * implement this method. + */ + virtual Vector DoGetVelocity (void) const; + /** + * The default implementation does nothing but return the passed-in + * parameter. Subclasses using random variables are expected to + * override this. + * \param start starting stream index + * \return the number of streams used + */ + virtual int64_t DoAssignStreams (int64_t start); + }; +}; + +#endif /* LEO_MOBILITY_MODEL_H */ diff --git a/model/leo.cc b/model/leo.cc new file mode 100644 index 0000000..3c44b06 --- /dev/null +++ b/model/leo.cc @@ -0,0 +1,11 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ + +#include "leo.h" + +namespace ns3 { + +/* ... */ + + +} + diff --git a/model/leo.h b/model/leo.h new file mode 100644 index 0000000..f9163d8 --- /dev/null +++ b/model/leo.h @@ -0,0 +1,12 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +#ifndef LEO_H +#define LEO_H + +namespace ns3 { + +/* ... */ + +} + +#endif /* LEO_H */ + diff --git a/test/leo-test-suite.cc b/test/leo-test-suite.cc new file mode 100644 index 0000000..595270b --- /dev/null +++ b/test/leo-test-suite.cc @@ -0,0 +1,68 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ + +// Include a header file from your module to test. +#include "ns3/leo.h" + +// An essential include is test.h +#include "ns3/test.h" + +// Do not put your test classes in namespace ns3. You may find it useful +// to use the using directive to access the ns3 namespace directly +using namespace ns3; + +// This is an example TestCase. +class LeoTestCase1 : public TestCase +{ +public: + LeoTestCase1 (); + virtual ~LeoTestCase1 (); + +private: + virtual void DoRun (void); +}; + +// Add some help text to this case to describe what it is intended to test +LeoTestCase1::LeoTestCase1 () + : TestCase ("Leo test case (does nothing)") +{ +} + +// This destructor does nothing but we include it as a reminder that +// the test case should clean up after itself +LeoTestCase1::~LeoTestCase1 () +{ +} + +// +// This method is the pure virtual method from class TestCase that every +// TestCase must implement +// +void +LeoTestCase1::DoRun (void) +{ + // A wide variety of test macros are available in src/core/test.h + NS_TEST_ASSERT_MSG_EQ (true, true, "true doesn't equal true for some reason"); + // Use this one for floating point comparisons + NS_TEST_ASSERT_MSG_EQ_TOL (0.01, 0.01, 0.001, "Numbers are not equal within tolerance"); +} + +// The TestSuite class names the TestSuite, identifies what type of TestSuite, +// and enables the TestCases to be run. Typically, only the constructor for +// this class must be defined +// +class LeoTestSuite : public TestSuite +{ +public: + LeoTestSuite (); +}; + +LeoTestSuite::LeoTestSuite () + : TestSuite ("leo", UNIT) +{ + // TestDuration for TestCase can be QUICK, EXTENSIVE or TAKES_FOREVER + AddTestCase (new LeoTestCase1, TestCase::QUICK); +} + +// Do not forget to allocate an instance of this TestSuite +static LeoTestSuite leoTestSuite; + diff --git a/wscript b/wscript new file mode 100644 index 0000000..11f9c7e --- /dev/null +++ b/wscript @@ -0,0 +1,42 @@ +# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- + +# def options(opt): +# pass + +# def configure(conf): +# conf.check_nonfatal(header_name='stdint.h', define_name='HAVE_STDINT_H') + +def build(bld): + module = bld.create_ns3_module('leo', ['core','internet', 'propagation', 'stats', 'traffic', 'flow-monitor', 'applications']) + module.source = [ + 'model/leo.cc', + 'model/isl-net-device.cc', + 'model/isl-channel.cc', + 'model/isl-propagation-loss-model.cc', + 'model/leo-mobility-model.cc', + 'helper/leo-helper.cc', + 'helper/isl-helper.cc', + ] + + module_test = bld.create_ns3_module_test_library('leo') + module_test.source = [ + 'test/leo-test-suite.cc', + ] + + headers = bld(features='ns3header') + headers.module = 'leo' + headers.source = [ + 'model/leo.h', + 'model/isl-net-device.h', + 'model/isl-channel.h', + 'model/isl-propagation-loss-model.h', + 'model/leo-mobility-model.h', + 'helper/leo-helper.h', + 'helper/isl-helper.h', + ] + + if bld.env.ENABLE_EXAMPLES: + bld.recurse('examples') + + # bld.ns3_python_bindings() +