diff --git a/src/devices/mesh/dot11s/hwmp-rtable.cc b/src/devices/mesh/dot11s/hwmp-rtable.cc index 198b66d12..f33ad6a6e 100644 --- a/src/devices/mesh/dot11s/hwmp-rtable.cc +++ b/src/devices/mesh/dot11s/hwmp-rtable.cc @@ -42,23 +42,18 @@ HwmpRtable::GetTypeId () .AddConstructor (); return tid; } - HwmpRtable::HwmpRtable () { DeleteProactivePath (); } - HwmpRtable::~HwmpRtable () { - DoDispose (); } - void HwmpRtable::DoDispose () { m_routes.clear (); } - void HwmpRtable::AddReactivePath ( Mac48Address destination, @@ -83,7 +78,6 @@ HwmpRtable::AddReactivePath ( i->second.whenExpire = Simulator::Now() + lifetime; i->second.seqnum = seqnum; } - void HwmpRtable::AddProactivePath ( uint32_t metric, @@ -101,7 +95,6 @@ HwmpRtable::AddProactivePath ( m_root.seqnum = seqnum; m_root.interface = interface; } - void HwmpRtable::AddPrecursor (Mac48Address destination, uint32_t precursorInterface, Mac48Address precursorAddress) { @@ -129,7 +122,6 @@ HwmpRtable::AddPrecursor (Mac48Address destination, uint32_t precursorInterface, return; m_root.precursors.push_back(precursor); } - void HwmpRtable::DeleteProactivePath () { @@ -140,14 +132,12 @@ HwmpRtable::DeleteProactivePath () m_root.seqnum = 0; m_root.whenExpire = Simulator::Now (); } - void HwmpRtable::DeleteProactivePath (Mac48Address root) { if(m_root.root == root) DeleteProactivePath (); } - void HwmpRtable::DeleteReactivePath (Mac48Address destination) { @@ -155,7 +145,6 @@ HwmpRtable::DeleteReactivePath (Mac48Address destination) if (i != m_routes.end ()) m_routes.erase (i); } - HwmpRtable::LookupResult HwmpRtable::LookupReactive (Mac48Address destination) { @@ -169,7 +158,6 @@ HwmpRtable::LookupReactive (Mac48Address destination) } return LookupReactiveExpired (destination); } - HwmpRtable::LookupResult HwmpRtable::LookupReactiveExpired (Mac48Address destination) { @@ -183,7 +171,6 @@ HwmpRtable::LookupReactiveExpired (Mac48Address destination) i->second.whenExpire - Simulator::Now () ); } - HwmpRtable::LookupResult HwmpRtable::LookupProactive () { @@ -194,13 +181,11 @@ HwmpRtable::LookupProactive () } return LookupProactiveExpired (); } - HwmpRtable::LookupResult HwmpRtable::LookupProactiveExpired () { return LookupResult(m_root.retransmitter, m_root.interface, m_root.metric, m_root.seqnum, m_root.whenExpire - Simulator::Now ()); } - std::vector HwmpRtable::GetUnreachableDestinations (Mac48Address peerAddress) { @@ -223,7 +208,6 @@ HwmpRtable::GetUnreachableDestinations (Mac48Address peerAddress) } return retval; } - HwmpRtable::PrecursorList HwmpRtable::GetPrecursors (Mac48Address destination) { @@ -248,7 +232,6 @@ HwmpRtable::GetPrecursors (Mac48Address destination) } return retval; } - bool HwmpRtable::LookupResult::operator==(const HwmpRtable::LookupResult & o) const { return (retransmitter == o.retransmitter @@ -257,7 +240,6 @@ bool HwmpRtable::LookupResult::operator==(const HwmpRtable::LookupResult & o) co && seqnum == o.seqnum ); } - bool HwmpRtable::LookupResult::IsValid() const { return !( retransmitter == Mac48Address::GetBroadcast () @@ -266,9 +248,7 @@ bool HwmpRtable::LookupResult::IsValid() const && seqnum == 0 ); } - #ifdef RUN_SELF_TESTS - /// Unit test for HwmpRtable class HwmpRtableTest : public Test { @@ -305,7 +285,6 @@ private: Ptr table; std::vector precursors; }; - /// Test instance static HwmpRtableTest g_HwmpRtableTest; @@ -322,7 +301,6 @@ HwmpRtableTest::HwmpRtableTest () : Test ("Mesh/802.11s/HwmpRtable"), precursors.push_back (Mac48Address ("00:11:22:33:44:55")); precursors.push_back (Mac48Address ("00:01:02:03:04:05")); } - void HwmpRtableTest::TestLookup () { HwmpRtable::LookupResult correct (hop, iface, metric, seqnum); @@ -339,13 +317,11 @@ void HwmpRtableTest::TestLookup () table->DeleteProactivePath (dst); NS_TEST_ASSERT (! table->LookupProactive ().IsValid ()); } - void HwmpRtableTest::TestAddPath () { table->AddReactivePath (dst, hop, iface, metric, expire, seqnum); table->AddProactivePath (metric, dst, hop, iface, expire, seqnum); } - void HwmpRtableTest::TestExpire () { // this is assumed to be called when path records are already expired @@ -356,7 +332,6 @@ void HwmpRtableTest::TestExpire () NS_TEST_ASSERT (! table->LookupReactive (dst).IsValid ()); NS_TEST_ASSERT (! table->LookupProactive ().IsValid ()); } - void HwmpRtableTest::TestPrecursorAdd () { for (std::vector::const_iterator i = precursors.begin (); i != precursors.end (); i ++) @@ -366,7 +341,6 @@ void HwmpRtableTest::TestPrecursorAdd () table->AddPrecursor (dst, iface, *i); } } - void HwmpRtableTest::TestPrecursorFind () { HwmpRtable::PrecursorList precursorList = table->GetPrecursors (dst); @@ -392,8 +366,6 @@ bool HwmpRtableTest::RunTests () return result; } - #endif // RUN_SELF_TESTS - } //namespace dot11s } //namespace ns3 diff --git a/src/devices/mesh/flame/flame-protocol-mac.cc b/src/devices/mesh/flame/flame-protocol-mac.cc new file mode 100644 index 000000000..5b43b5002 --- /dev/null +++ b/src/devices/mesh/flame/flame-protocol-mac.cc @@ -0,0 +1,25 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2009 IITP RAS + * + * 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: Kirill Andreev + */ + +#include "flame-protocol-mac.h" +namespace ns3 { +namespace flame { +} //namespace flame +} //namespace ns3 diff --git a/src/devices/mesh/flame/flame-protocol-mac.h b/src/devices/mesh/flame/flame-protocol-mac.h new file mode 100644 index 000000000..a221494e1 --- /dev/null +++ b/src/devices/mesh/flame/flame-protocol-mac.h @@ -0,0 +1,53 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2009 IITP RAS + * + * 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: Kirill Andreev + */ + +#ifndef FLAME_PROTOCOL_MAC_H +#define FLAME_PROTOCOL_MAC_H + +#include "ns3/mesh-wifi-interface-mac.h" +#include "flame-protocol.h" + +namespace ns3 { +namespace flame { +/** + * \ingroup flame + * + * \brief Interface MAC plugin FLAME routing protocol + */ +class FlameMacPlugin : public MeshWifiInterfaceMacPlugin +{ +public: + FlameMacPlugin (uint32_t, Ptr); + ~FlameMacPlugin (); + ///\name Inherited from MAC plugin + //\{ + void SetParent (Ptr parent); + bool Receive (Ptr packet, const WifiMacHeader & header); + bool UpdateOutcomingFrame (Ptr packet, WifiMacHeader & header, Mac48Address from, Mac48Address to); + /// Update beacon is empty, because HWMP does not know anything about beacons + void UpdateBeacon (MeshWifiBeacon & beacon) const {}; + //\} + +private: + +}; +} //namespace flame +} //namespace ns3 +#endif /* FLAME_PROTOCOL_MAC_H */ diff --git a/src/devices/mesh/flame/flame-protocol.cc b/src/devices/mesh/flame/flame-protocol.cc new file mode 100644 index 000000000..34251015b --- /dev/null +++ b/src/devices/mesh/flame/flame-protocol.cc @@ -0,0 +1,25 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2009 IITP RAS + * + * 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: Kirill Andreev + */ + +#include "flame-protocol.h" +namespace ns3 { +namespace flame { +} //namespace flame +} //namespace ns3 diff --git a/src/devices/mesh/flame/flame-protocol.h b/src/devices/mesh/flame/flame-protocol.h index e69de29bb..316346477 100644 --- a/src/devices/mesh/flame/flame-protocol.h +++ b/src/devices/mesh/flame/flame-protocol.h @@ -0,0 +1,60 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2009 IITP RAS + * + * 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: Kirill Andreev + */ + +#ifndef FLAME_PROTOCOL_H +#define FLAME_PROTOCOL_H + +#include "ns3/mesh-l2-routing-protocol.h" +namespace ns3 { +namespace flame { +/** + * \ingroup flame + * + * \brief FLAME = Forwarding Layer for Meshing + */ + +class FlameProtocol : public MeshL2RoutingProtocol +{ +public: + static TypeId GetTypeId (); + FlameProtocol (); + ~FlameProtocol (); + void DoDispose (); + + /// Route request, inherited from MeshL2RoutingProtocol + bool RequestRoute (uint32_t sourceIface, const Mac48Address source, const Mac48Address destination, + Ptr packet, uint16_t protocolType, RouteReplyCallback routeReply); + /** + * \brief Install FLAME on given mesh point. + * + * Installing protocol cause installing its interface MAC plugins. + * + * Also MP aggregates all installed protocols, FLAME protocol can be accessed + * via MeshPointDevice::GetObject(); + */ + bool Install (Ptr); + ///\brief Statistics: + void Report (std::ostream &) const; + void ResetStats (); +private: +}; +} //namespace flame +} //namespace ns3 +#endif /* FLAME_PROTOCOL_H */ diff --git a/src/devices/mesh/flame/flame-rtable.cc b/src/devices/mesh/flame/flame-rtable.cc new file mode 100644 index 000000000..880e45253 --- /dev/null +++ b/src/devices/mesh/flame/flame-rtable.cc @@ -0,0 +1,197 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2009 IITP RAS + * + * 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: Kirill Andreev + */ +#include "ns3/assert.h" +#include "ns3/simulator.h" +#include "ns3/test.h" +#include "ns3/log.h" + +#include "flame-rtable.h" +namespace ns3 { +namespace flame { + +NS_LOG_COMPONENT_DEFINE ("FlameRtable"); + +NS_OBJECT_ENSURE_REGISTERED (FlameRtable); + +TypeId +FlameRtable::GetTypeId () +{ + static TypeId tid = TypeId ("ns3::flame::FlameRtable") + .SetParent () + .AddConstructor (); + return tid; +} + +FlameRtable::FlameRtable () + : m_lifetime (Seconds (120)) +{} + +FlameRtable::~FlameRtable () +{ +} + +void +FlameRtable::DoDispose () +{ + m_routes.clear (); +} + +void +FlameRtable::AddPath ( + Mac48Address destination, + Mac48Address retransmitter, + uint32_t interface, + uint8_t cost, + uint16_t seqnum +) +{ + std::map::iterator i = m_routes.find (destination); + if (i == m_routes.end ()) + { + Route newroute; + newroute.cost = cost; + newroute.retransmitter = retransmitter; + newroute.interface = interface; + newroute.whenExpire = Simulator::Now() + m_lifetime; + newroute.seqnum = seqnum; + m_routes[destination] = newroute; + return; + } + NS_ASSERT (i != m_routes.end()); + if (i->second.cost < cost) + return; + i->second.retransmitter = retransmitter; + i->second.interface = interface; + i->second.cost = cost; + i->second.whenExpire = Simulator::Now() + m_lifetime; + i->second.seqnum = seqnum; +} +FlameRtable::LookupResult +FlameRtable::Lookup (Mac48Address destination) +{ + std::map::iterator i = m_routes.find (destination); + if (i == m_routes.end ()) + return LookupResult (); + if ((i->second.whenExpire < Simulator::Now ())) + { + NS_LOG_DEBUG ("Route has expired, sorry."); + m_routes.erase (i); + return LookupResult(); + } + return LookupResult (i->second.retransmitter, i->second.interface, i->second.cost, i->second.seqnum); +} +bool FlameRtable::LookupResult::operator==(const FlameRtable::LookupResult & o) const +{ + return (retransmitter == o.retransmitter + && ifIndex == o.ifIndex + && cost == o.cost + && seqnum == o.seqnum + ); +} + +bool FlameRtable::LookupResult::IsValid() const +{ + return !( retransmitter == Mac48Address::GetBroadcast () + && ifIndex == INTERFACE_ANY + && cost == MAX_COST + && seqnum == 0 + ); +} + + +#ifdef RUN_SELF_TESTS +/// Unit test for FlameRtable +class FlameRtableTest : public Test +{ +public: + FlameRtableTest (); + virtual bool RunTests(); + +private: + /// Test Add apth and lookup path; + void TestLookup (); + /** + * \name Test add path and try to lookup after entry has expired + * \{ + */ + void TestAddPath (); + void TestExpire (); + ///\} +private: + bool result; + + Mac48Address dst; + Mac48Address hop; + uint32_t iface; + uint8_t cost; + uint16_t seqnum; + Ptr table; +}; + +/// Test instance +static FlameRtableTest g_FlameRtableTest; + +FlameRtableTest::FlameRtableTest () : Test ("Mesh/flame/FlameRtable"), + result(true), + dst ("01:00:00:01:00:01"), + hop ("01:00:00:01:00:03"), + iface (8010), + cost (10), + seqnum (1) +{ +} + +void FlameRtableTest::TestLookup () +{ + FlameRtable::LookupResult correct (hop, iface, cost, seqnum); + + table->AddPath (dst, hop, iface, cost, seqnum); + NS_TEST_ASSERT (table->Lookup (dst) == correct); +} + +void FlameRtableTest::TestAddPath () +{ + table->AddPath (dst, hop, iface, cost, seqnum); +} + +void FlameRtableTest::TestExpire () +{ + // this is assumed to be called when path records are already expired + FlameRtable::LookupResult correct (hop, iface, cost, seqnum); + NS_TEST_ASSERT (! table->Lookup (dst).IsValid ()); +} +bool FlameRtableTest::RunTests () +{ + table = CreateObject (); + + Simulator::Schedule (Seconds (0), & FlameRtableTest::TestLookup, this); + Simulator::Schedule (Seconds (1), & FlameRtableTest::TestAddPath, this); + Simulator::Schedule (Seconds (122), & FlameRtableTest::TestExpire, this); + + Simulator::Run (); + Simulator::Destroy (); + + return result; +} + +#endif // RUN_SELF_TESTS + +} //namespace flame +} //namespace ns3 diff --git a/src/devices/mesh/flame/flame-rtable.h b/src/devices/mesh/flame/flame-rtable.h new file mode 100644 index 000000000..7855b2e97 --- /dev/null +++ b/src/devices/mesh/flame/flame-rtable.h @@ -0,0 +1,104 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2009 IITP RAS + * + * 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: Kirill Andreev + */ + +#ifndef FLAME_RTABLE_H +#define FLAME_RTABLE_H + +#include +#include "ns3/nstime.h" +#include "ns3/object.h" +#include "ns3/mac48-address.h" + +namespace ns3 { +namespace flame { +/** + * \ingroup flame + * + * \brief Routing table for FLAME + */ +class FlameRtable : public Object +{ +public: + /// Means all interfaces + const static uint32_t INTERFACE_ANY = 0xffffffff; + /// Maximum (the best?) path cost + const static uint32_t MAX_COST = 0xff; + + /// Route lookup result, return type of LookupXXX methods + struct LookupResult + { + Mac48Address retransmitter; + uint32_t ifIndex; + uint8_t cost; + uint16_t seqnum; + LookupResult(Mac48Address r = Mac48Address::GetBroadcast (), + uint32_t i = INTERFACE_ANY, + uint8_t c = MAX_COST, + uint16_t s = 0) + : retransmitter (r), + ifIndex (i), + cost (c), + seqnum (s) + { + } + /// True for valid route + bool IsValid() const; + /// Compare route lookup results, used by tests + bool operator==(const LookupResult & o) const; + }; +public: + static TypeId GetTypeId (); + FlameRtable (); + ~FlameRtable (); + void DoDispose (); + + ///\name Add/delete paths + //\{ + void AddPath ( + Mac48Address destination, + Mac48Address retransmitter, + uint32_t interface, + uint8_t cost, + uint16_t seqnum + ); + /** + * Lookup path to destination + * \returns Broadcast if not found + */ + LookupResult Lookup (Mac48Address destination); +private: + /// Routing table entry + struct Route + { + Mac48Address retransmitter; + uint32_t interface; + uint32_t cost; + Time whenExpire; + uint32_t seqnum; + }; + /// Lifetime parameter: + Time m_lifetime; + /// List of routes + std::map m_routes; +}; + +} //namespace flame +} //namespace ns3 +#endif /* FLAME_PROTOCOL_H */ diff --git a/src/devices/mesh/flame/wscript b/src/devices/mesh/flame/wscript index 8a26a0f8b..6b39918ee 100644 --- a/src/devices/mesh/flame/wscript +++ b/src/devices/mesh/flame/wscript @@ -4,6 +4,9 @@ def build(bld): obj = bld.create_ns3_module('flame', ['mesh']) obj.source = [ 'flame-header.cc', + 'flame-rtable.cc', + 'flame-protocol-mac.cc', + 'flame-protocol.cc', ] headers = bld.new_task_gen('ns3header') headers.module = 'flame'