Merge 802.11s code.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/mesh.cc Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,108 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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
+ *
+ * Authors: Kirill Andreev <andreev@iitp.ru>
+ * Evgeny Khorov <horov@frtk.ru>
+ */
+
+
+#include "ns3/core-module.h"
+#include "ns3/simulator-module.h"
+#include "ns3/node-module.h"
+#include "ns3/helper-module.h"
+#include "ns3/global-routing-module.h"
+#include "ns3/wifi-module.h"
+#include "ns3/mobility-module.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("TestMeshScript");
+
+int
+main(int argc, char *argv[])
+{
+ // Creating square topology with nNodes x nNodes grid:
+ int xSize = 5;
+ int ySize = 5;
+ double step = 100.0; //Grid with one-hop edge
+ double randomStart = 0.1; //One beacon interval
+ NodeContainer nodes;
+ CommandLine cmd;
+ MobilityHelper mobility;
+ MeshWifiHelper wifi;
+ NetDeviceContainer meshDevices;
+ // Defining a size of our network:
+ cmd.AddValue("x-size", "Number of nodes in a row grid", xSize);
+ cmd.AddValue("y-size", "Number of rows in a grid", ySize);
+ cmd.AddValue("step", "Size of edge in our grid", step);
+ cmd.AddValue("start", "Random start parameter", randomStart);
+ cmd.Parse (argc, argv);
+ NS_LOG_DEBUG("Grid:"<<xSize<<"*"<<ySize);
+ // Creating nodes:
+ nodes.Create (ySize*xSize);
+
+ // Setting channel:
+ YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
+ YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
+ wifiPhy.SetChannel (wifiChannel.Create ());
+ // Setting Wifi:
+ //wifi.SetPhy("ns3::WifiPhy");
+ wifi.SetRemoteStationManager("ns3::AarfWifiManager");
+ Ssid ssid = Ssid("MyMeSH");
+ wifi.SetMac ("ns3::MeshWifiMac",
+ "Ssid", SsidValue (ssid),
+ "RandomStart", TimeValue (Seconds (randomStart))
+ );
+ wifi.SetPeerLinkManager ("ns3::WifiPeerManager");
+ wifi.SetL2RoutingProtocol ("ns3::Hwmp");
+ wifi.SetL2RoutingNetDevice ("ns3::L2RoutingNetDevice");
+ meshDevices = wifi.Install (wifiPhy,nodes,1);
+ // Installing Mobility.
+ mobility.SetPositionAllocator
+ ("ns3::GridPositionAllocator",
+ "MinX", DoubleValue (0.0),
+ "MinY", DoubleValue (0.0),
+ "DeltaX", DoubleValue (step),
+ "DeltaY", DoubleValue (step),
+ "GridWidth", UintegerValue (xSize),
+ "LayoutType", StringValue("RowFirst"));
+ mobility.SetMobilityModel ("ns3::StaticMobilityModel");
+ mobility.Install (nodes);
+
+ // Setting Internet Stack:
+ InternetStackHelper stack;
+ stack.Install(nodes);
+ Ipv4AddressHelper address;
+ address.SetBase ("10.1.1.0", "255.255.255.0");
+ Ipv4InterfaceContainer interfaces = address.Assign (meshDevices);
+ UdpEchoServerHelper echoServer (9);
+ ApplicationContainer serverApps = echoServer.Install (nodes.Get (0));
+ serverApps.Start (Seconds (1.0));
+ serverApps.Stop (Seconds (10.0));
+ UdpEchoClientHelper echoClient (interfaces.GetAddress (0), 9);
+ echoClient.SetAttribute ("MaxPackets", UintegerValue (1000));
+ echoClient.SetAttribute ("Interval", TimeValue (Seconds (0.001)));
+ echoClient.SetAttribute ("PacketSize", UintegerValue (1024));
+ ApplicationContainer clientApps = echoClient.Install (nodes.Get (1));
+ clientApps.Start (Seconds (2.0));
+ clientApps.Stop (Seconds (10.0));
+ //end
+ Simulator::Stop (Seconds (10.0));
+ Simulator::Run();
+ Simulator::Destroy();
+ return 0;
+}
--- a/examples/wscript Wed Feb 25 12:27:00 2009 -0500
+++ b/examples/wscript Sat Feb 28 14:21:05 2009 +0300
@@ -120,6 +120,10 @@
['core', 'simulator', 'mobility', 'wifi'])
obj.source = 'wifi-ap.cc'
+ obj = bld.create_ns3_program('mesh',
+ ['core', 'simulator', 'mobility', 'wifi'])
+ obj.source = 'mesh.cc'
+
bld.add_subdirs('stats')
obj = bld.create_ns3_program('wifi-wired-bridging',
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/l2-routing/l2-routing-hwmp/hwmp-rtable.cc Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,282 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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 <andreev@iitp.ru>
+ */
+
+
+#include "ns3/object.h"
+#include "ns3/assert.h"
+#include "ns3/simulator.h"
+#include "ns3/ptr.h"
+#include "ns3/log.h"
+#include "ns3/node.h"
+#include "hwmp-rtable.h"
+
+NS_LOG_COMPONENT_DEFINE ("HwmpRtable");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (HwmpRtable);
+
+TypeId
+HwmpRtable::GetTypeId(void)
+{
+ static TypeId tid = TypeId ("ns3::HwmpRtable")
+ .SetParent<Object> ()
+ .AddConstructor<HwmpRtable> ();
+ return tid;
+
+}
+
+HwmpRtable::HwmpRtable()
+{
+}
+
+HwmpRtable::~HwmpRtable()
+{
+ DoDispose();
+}
+
+void
+HwmpRtable::DoDispose()
+{
+ NS_LOG_UNCOND("RTABLE DISPOSE STARTED");
+ m_routes.clear();
+ m_roots.clear();
+}
+
+void
+HwmpRtable::AddReactivePath(
+ Mac48Address destination,
+ Mac48Address retransmitter,
+ uint32_t port,
+ uint32_t metric,
+ Time lifetime,
+ uint32_t seqnum
+ )
+{
+ std::map<Mac48Address, struct ReactiveRoute, addrcmp>::iterator i = m_routes.find(destination);
+ if(i == m_routes.end())
+ {
+ struct ReactiveRoute newroute;
+ m_routes[destination] = newroute;
+ }
+ else
+ {
+ /**
+ * if outport differs from stored, routing info is
+ * actual and metric is worse - we ignore this
+ * information
+ */
+ if(
+ (i->second.port != port) &&
+ (i->second.metric < metric) &&
+ /**
+ * The routing info is actual or it
+ * was received from peer
+ */
+ ((i->second.whenExpire > Simulator::Now())||(i->second.whenExpire == Seconds(0)))
+ )
+ return;
+ }
+ i = m_routes.find(destination);
+ NS_ASSERT(i != m_routes.end());
+ i->second.retransmitter = retransmitter;
+ i->second.port = port;
+ i->second.metric = metric;
+ if(lifetime != Seconds(0))
+ i->second.whenExpire = MilliSeconds(Simulator::Now().GetMilliSeconds() + lifetime.GetMilliSeconds());
+ else
+ /**
+ * Information about peer does not have lifetime
+ */
+ i->second.whenExpire = Seconds(0);
+ i->second.seqnum = seqnum;
+}
+
+void
+HwmpRtable::AddProactivePath(
+ uint32_t metric,
+ Mac48Address root,
+ Mac48Address retransmitter,
+ uint32_t port,
+ Time lifetime,
+ uint32_t seqnum
+ )
+{
+ struct ProactiveRoute newroute;
+ m_roots[port] = newroute;
+ std::map<uint32_t,struct ProactiveRoute>::iterator i = m_roots.find(port);
+ NS_ASSERT(i != m_roots.end());
+ i->second.root = root;
+ i->second.retransmitter = retransmitter;
+ i->second.metric = metric;
+ i->second.whenExpire = MilliSeconds(Simulator::Now().GetMilliSeconds() + lifetime.GetMilliSeconds());
+ i->second.seqnum = seqnum;
+
+}
+
+void
+HwmpRtable::AddPrecursor(Mac48Address destination, uint32_t port, Mac48Address precursor)
+{
+ bool should_add = true;
+ std::map<Mac48Address, struct ReactiveRoute, addrcmp>::iterator i = m_routes.find(destination);
+ if((i != m_routes.end()) && (i->second.port == port))
+ {
+ for(unsigned int j = 0 ; j < i->second.precursors.size(); j ++)
+ if(i->second.precursors[j] == precursor)
+ {
+ should_add = false;
+ break;
+ }
+ if(should_add)
+ i->second.precursors.push_back(precursor);
+ }
+ std::map<uint32_t,struct ProactiveRoute>::iterator k = m_roots.find(port);
+ if(k!= m_roots.end())
+ {
+ for(unsigned int j = 0 ; j < k->second.precursors.size(); j ++)
+ if(k->second.precursors[j] == precursor)
+ return;
+ k->second.precursors.push_back(precursor);
+ return;
+ }
+}
+
+void
+HwmpRtable::DeleteProactivePath(uint32_t port)
+{
+ std::map<uint32_t,struct ProactiveRoute>::iterator j = m_roots.find(port);
+ if(j != m_roots.end())
+ m_roots.erase(j);
+
+}
+void
+HwmpRtable::DeleteProactivePath(Mac48Address root, uint32_t port)
+{
+ std::map<uint32_t,struct ProactiveRoute>::iterator j = m_roots.find(port);
+ if((j != m_roots.end())&&(j->second.root == root))
+ m_roots.erase(j);
+
+}
+
+void
+HwmpRtable::DeleteReactivePath(Mac48Address destination, uint32_t port)
+{
+ std::map<Mac48Address, struct ReactiveRoute, addrcmp>::iterator i = m_routes.find(destination);
+ if(i != m_routes.end())
+ if(i->second.port == port)
+ m_routes.erase(i);
+}
+
+struct HwmpRtable::LookupResult
+HwmpRtable::LookupReactive(Mac48Address destination)
+{
+ struct LookupResult result;
+ result.retransmitter = Mac48Address::GetBroadcast();
+ result.metric = MAX_METRIC;
+ result.ifIndex = PORT_ANY;
+
+ std::map<Mac48Address, struct ReactiveRoute, addrcmp>::iterator i = m_routes.find(destination);
+ if(i == m_routes.end())
+ return result;
+ result.ifIndex = i->second.port;
+ //Seconds(0) means that this is routing
+ if(i->second.whenExpire < Simulator::Now())
+ if(i->second.retransmitter != destination)
+ return result;
+ result.retransmitter = i->second.retransmitter;
+ result.metric = i->second.metric;
+ result.seqnum = i->second.seqnum;
+ return result;
+}
+
+struct HwmpRtable::LookupResult
+HwmpRtable::LookupProactive(uint32_t port)
+{
+ struct LookupResult result;
+ result.retransmitter = Mac48Address::GetBroadcast();
+ result.metric = MAX_METRIC;
+ result.ifIndex = PORT_ANY;
+ std::map<uint32_t, struct ProactiveRoute, addrcmp>::iterator i = m_roots.find(port);
+ if(i == m_roots.end())
+ return result;
+ result.ifIndex = i->first;
+ if(i->second.whenExpire < Simulator::Now())
+ return result;
+ result.retransmitter = i->second.retransmitter;
+ result.metric = i->second.metric;
+ result.seqnum = i->second.seqnum;
+ return result;
+}
+
+std::vector<struct HwmpRtable::FailedDestination>
+HwmpRtable::GetUnreachableDestinations(Mac48Address peerAddress, uint32_t port)
+{
+ std::vector<struct FailedDestination> retval;
+ for(std::map<Mac48Address, struct ReactiveRoute, addrcmp>::iterator i = m_routes.begin(); i!= m_routes.end(); i++)
+ if((i->second.retransmitter == peerAddress)&&(i->second.port == port))
+ {
+ struct FailedDestination dst;
+ dst.destination = i->first;
+ i->second.seqnum ++;
+ dst.seqnum = i->second.seqnum;
+ retval.push_back(dst);
+ }
+ /**
+ * Lookup a path to root
+ */
+ std::map<uint32_t, struct ProactiveRoute, addrcmp>::iterator i = m_roots.find(port);
+ if((i != m_roots.end())&&(i->second.retransmitter == peerAddress))
+ {
+ struct FailedDestination dst;
+ dst.destination = i->second.root;
+ dst.seqnum = i->second.seqnum;
+ retval.push_back(dst);
+ }
+ return retval;
+}
+uint32_t
+HwmpRtable::RequestSeqnum(Mac48Address destination)
+{
+ std::map<Mac48Address, struct ReactiveRoute, addrcmp>::iterator i = m_routes.find(destination);
+ if(i == m_routes.end())
+ return 0;
+ return i->second.seqnum;
+}
+
+std::vector<Mac48Address>
+HwmpRtable::GetPrecursors(Mac48Address destination, uint32_t port)
+{
+ std::vector<Mac48Address> retval;
+ std::map<uint32_t, struct ProactiveRoute, addrcmp>::iterator root = m_roots.find(port);
+ if((root != m_roots.end()) &&(root->second.root == destination))
+ {
+ for(unsigned int i = 0; i < root->second.precursors.size(); i ++)
+ retval.push_back(root->second.precursors[i]);
+ }
+ std::map<Mac48Address, struct ReactiveRoute, addrcmp>::iterator route = m_routes.find(destination);
+ if( (route != m_routes.end()) && (route->second.port == port) )
+ {
+ for(unsigned int i = 0; i < route->second.precursors.size(); i ++)
+ retval.push_back(route->second.precursors[i]);
+ }
+ return retval;
+}
+
+}//namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/l2-routing/l2-routing-hwmp/hwmp-rtable.h Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,125 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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 <andreev@iitp.ru>
+ */
+
+
+#ifndef HWMP_RTABLE_H
+#define HWMP_RTABLE_H
+
+#include <list>
+#include <map>
+#include "ns3/nstime.h"
+#include "ns3/mac48-address.h"
+#include "ns3/net-device.h"
+#include "ns3/event-id.h"
+#include "ns3/packet.h"
+namespace ns3 {
+
+
+ class HwmpRtable : public Object
+ {
+ public:
+ static TypeId GetTypeId (void);
+ HwmpRtable();
+ ~HwmpRtable();
+ void DoDispose();
+ void AddReactivePath(
+ Mac48Address destination,
+ Mac48Address retransmitter,
+ uint32_t port,
+ uint32_t metric,
+ Time lifetime,
+ uint32_t seqnum
+ );
+ void AddProactivePath(
+ uint32_t metric,
+ Mac48Address root,
+ Mac48Address retransmitter,
+ uint32_t port,
+ Time lifetime,
+ uint32_t seqnum
+ );
+ void AddPrecursor(Mac48Address destination, uint32_t port, Mac48Address precursor);
+ void DeleteProactivePath(uint32_t port);
+ void DeleteProactivePath(Mac48Address root, uint32_t port);
+ void DeleteReactivePath(Mac48Address destination, uint32_t port);
+ struct LookupResult
+ {
+ Mac48Address retransmitter;
+ uint32_t ifIndex;
+ uint32_t metric;
+ uint32_t seqnum;
+ };
+ struct LookupResult
+ LookupReactive(Mac48Address destination);
+ struct LookupResult
+ LookupProactive(uint32_t port);
+ //path error routines:
+ struct FailedDestination
+ {
+ Mac48Address destination;
+ uint32_t seqnum;
+ };
+ std::vector<struct FailedDestination>
+ GetUnreachableDestinations(Mac48Address peerAddress, uint32_t port);
+ uint32_t
+ RequestSeqnum(Mac48Address dst);
+ std::vector<Mac48Address>
+ GetPrecursors(Mac48Address destination, uint32_t port);
+ const static uint32_t PORT_ANY = 0xffffffff;
+ const static uint32_t MAX_METRIC = 0xffffffff;
+ private:
+ struct ReactiveRoute
+ {
+ Mac48Address retransmitter;
+ uint32_t port;
+ uint32_t metric;
+ Time whenExpire;
+ uint32_t seqnum;
+ std::vector<Mac48Address> precursors;
+ };
+ struct ProactiveRoute
+ {
+ Mac48Address root;
+ Mac48Address retransmitter;
+ uint32_t metric;
+ Time whenExpire;
+ uint32_t seqnum;
+ std::vector<Mac48Address> precursors;
+ };
+ struct addrcmp
+ {
+ bool operator()(const Mac48Address addr1, const Mac48Address addr2) const
+ {
+ uint8_t s1[6], s2[6];
+ addr1.CopyTo(s1);
+ addr2.CopyTo(s2);
+ for(int i = 0; i < 6; i ++)
+ if(s1[i] > s2[i])
+ return true;
+ return false;
+ }
+ };
+ std::map<Mac48Address, struct ReactiveRoute, addrcmp>
+ m_routes;
+ std::map<uint32_t, struct ProactiveRoute>
+ m_roots;
+ };
+} //namespace ns3
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/l2-routing/l2-routing-hwmp/hwmp-state.cc Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,539 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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 <andreev@iitp.ru>
+ */
+
+
+#include "hwmp-state.h"
+#include "ns3/simulator.h"
+#include "ns3/nstime.h"
+#include "ns3/log.h"
+namespace ns3 {
+
+
+NS_LOG_COMPONENT_DEFINE ("HwmpState");
+TypeId
+HwmpState::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::HwmpState")
+ .SetParent<Object> ()
+ .AddConstructor<HwmpState> ()
+ ;
+ return tid;
+}
+
+HwmpState::HwmpState()
+{
+ m_myPreq = m_preqQueue.end();
+ m_preqId = 1;
+ m_myDsn = 1;
+ m_maxTtl = 10;
+ m_disabled = false;
+}
+void
+HwmpState::SetRequestRouteCallback(
+ Callback<struct HwmpRtable::LookupResult, const Mac48Address&> cb)
+{
+ m_requestRouteCallback = cb;
+}
+
+void
+HwmpState::SetRequestRootPathCallback(
+ Callback<struct HwmpRtable::LookupResult, uint32_t> cb)
+{
+ m_requestRootPathCallback = cb;
+}
+
+//Setting MAC
+void
+HwmpState::SetMac(Ptr<MeshWifiMac> mac)
+{
+ mac->SetPeerStatusCallback(MakeCallback(&HwmpState::PeerStatus, this));
+ mac->SetPreqReceivedCallback(MakeCallback(&HwmpState::ReceivePreq, this));
+ mac->SetPrepReceivedCallback(MakeCallback(&HwmpState::ReceivePrep, this));
+ mac->SetPerrReceivedCallback(MakeCallback(&HwmpState::ReceivePerr, this));
+ m_address = mac->GetAddress();
+ m_preqCallback = MakeCallback(&MeshWifiMac::SendPreq, mac);
+ m_prepCallback = MakeCallback(&MeshWifiMac::SendPrep, mac);
+ m_perrCallback = MakeCallback(&MeshWifiMac::SendPerr, mac);
+}
+HwmpState::~HwmpState()
+{
+ m_preqQueue.clear();
+}
+//Interaction with HWMP:
+void
+HwmpState::SetRoutingInfoCallback(
+ Callback<void, INFO> cb
+ )
+{
+ m_routingInfoCallback = cb;
+}
+
+void
+HwmpState::SetRetransmittersOfPerrCallback(
+ Callback<std::vector<Mac48Address>, std::vector<struct HwmpRtable::FailedDestination>, uint32_t> cb)
+{
+ m_retransmittersOfPerrCallback = cb;
+}
+
+void
+HwmpState::RequestDestination(Mac48Address dst)
+{
+ if(m_preqQueue.end() == m_myPreq)
+ {
+ WifiPreqInformationElement preq;
+ //fill PREQ:
+ preq.SetHopcount(0);
+ preq.SetTTL(m_maxTtl);
+ preq.SetPreqID(m_preqId++);
+ if(m_preqId == MAX_PREQ_ID)
+ m_preqId = 0;
+ preq.SetLifetime(TIME_TO_TU(dot11sParameters::dot11MeshHWMPactivePathTimeout));
+ preq.SetOriginatorSeqNumber(m_myDsn++);
+ if(m_myDsn == MAX_DSN)
+ m_myDsn = 0;
+ preq.SetOriginatorAddress(m_address);
+ preq.AddDestinationAddressElement(false, false, dst, 0); //DO = 0, RF = 0
+ if(m_preqTimer.IsRunning())
+ {
+ NS_LOG_DEBUG("No my preq");
+ m_preqQueue.push_back(preq);
+ //set iterator position to my preq:
+ m_myPreq = m_preqQueue.end() -1;
+ }
+ else
+ {
+ NS_LOG_DEBUG("Send PREQ now, "<<preq.GetPreqID()<<" destinations, now is "<<Simulator::Now());
+ m_preqCallback(preq);
+ NS_ASSERT(!m_preqTimer.IsRunning());
+ m_preqTimer = Simulator::Schedule(dot11sParameters::dot11MeshHWMPpreqMinInterval, &HwmpState::SendOnePreq, this);
+ }
+ }
+ else
+ {
+ NS_ASSERT(m_myPreq->GetOriginatorAddress() == m_address);
+ NS_LOG_DEBUG("add a destination "<<dst);
+ m_myPreq->AddDestinationAddressElement(false, false, dst, 0); //DO = 0, RF = 0
+ }
+}
+void
+HwmpState::SendPathError(std::vector<struct HwmpRtable::FailedDestination> destinations)
+{
+ std::vector<Mac48Address> receivers = m_retransmittersOfPerrCallback(destinations, m_ifIndex);
+ NS_LOG_DEBUG("SendPathError started");
+ if(receivers.size()== 0)
+ return;
+ NS_LOG_DEBUG(m_address<<" Should Send PERR to");
+ for(unsigned int i = 0; i < receivers.size(); i ++)
+ {
+ AddPerrReceiver(receivers[i]);
+ NS_LOG_DEBUG(receivers[i]);
+ }
+ NS_LOG_DEBUG("To tel about failure with");
+ for(unsigned int i = 0; i < destinations.size(); i ++)
+ {
+ m_myPerr.AddAddressUnit(destinations[i]);
+ NS_LOG_DEBUG(destinations[i].destination);
+ }
+ if(!m_perrTimer.IsRunning())
+ {
+ m_perrCallback(m_myPerr,m_myPerrReceivers);
+ m_myPerr.ResetPerr();
+ m_perrTimer = Simulator::Schedule(dot11sParameters::dot11MeshHWMPperrMinInterval,&HwmpState::SendOnePerr,this);
+ }
+}
+//needed to fill routing information structure
+void
+HwmpState::SetAssociatedIfaceId(uint32_t interface)
+{
+ m_ifIndex = interface;
+}
+
+uint32_t
+HwmpState::GetAssociatedIfaceId()
+{
+ return m_ifIndex;
+}
+
+//Interaction with MAC:
+void
+HwmpState::ReceivePreq(WifiPreqInformationElement& preq, const Mac48Address& from, const uint32_t& metric)
+{
+ if(m_disabled)
+ return;
+ if(preq.GetOriginatorAddress() == m_address)
+ return;
+ preq.DecrementTtl();
+ preq.IncrementMetric(metric);
+ if(preq.GetTtl() == 0)
+ return;
+ //acceptance cretirea:
+ std::map<Mac48Address, uint32_t, addrcmp>::iterator i = m_dsnDatabase.find(preq.GetOriginatorAddress());
+ if(i == m_dsnDatabase.end())
+ {
+ m_dsnDatabase[preq.GetOriginatorAddress()] = preq.GetOriginatorSeqNumber();
+ m_preqMetricDatabase[preq.GetOriginatorAddress()] = preq.GetMetric();
+ }
+ else
+ {
+ if(i->second > preq.GetOriginatorSeqNumber())
+ return;
+ if(i->second == preq.GetOriginatorSeqNumber())
+ {
+ //find metric
+ std::map<Mac48Address, uint32_t, addrcmp>::iterator j =
+ m_preqMetricDatabase.find(preq.GetOriginatorAddress());
+ NS_ASSERT(j != m_dsnDatabase.end());
+ if(j->second <= preq.GetMetric())
+ return;
+ }
+ m_dsnDatabase[preq.GetOriginatorAddress()] = preq.GetOriginatorSeqNumber();
+ m_preqMetricDatabase[preq.GetOriginatorAddress()] = preq.GetMetric();
+ }
+ NS_LOG_DEBUG(
+ "PREQ from "<< preq.GetOriginatorAddress()
+ <<", at "<< m_address
+ <<", TTL ="<< (int)preq.GetTtl()
+ <<", metric = "<< preq.GetMetric()
+ <<", hopcount = "<< (int)preq.GetHopCount()
+ <<", preqId = "<< preq.GetPreqID()
+ <<", transmitter is "<<from);
+ //fill routingTable
+ INFO newInfo;
+ newInfo.me = m_address;
+ newInfo.destination = preq.GetOriginatorAddress();
+ newInfo.nextHop = from;
+ newInfo.metric = preq.GetMetric();
+ newInfo.lifetime = TU_TO_TIME(preq.GetLifetime());
+ newInfo.outPort = m_ifIndex;
+ newInfo.dsn = preq.GetOriginatorSeqNumber();
+ newInfo.type = INFO_PREQ;
+ //check if can answer:
+ std::vector<Ptr<DestinationAddressUnit> > destinations = preq.GetDestinationList ();
+ for(std::vector<Ptr<DestinationAddressUnit> >::iterator i = destinations.begin(); i!= destinations.end(); i++)
+ {
+ if((*i)->GetDestinationAddress() == Mac48Address::GetBroadcast())
+ {
+ //only proactive PREQ contains destination
+ //address as broadcast! Proactive preq MUST
+ //have destination count equal to 1 and
+ //per destination flags DO and RF
+ NS_ASSERT(preq.GetDestCount() == 1);
+ NS_ASSERT(((*i)->IsDo()) && ((*i)->IsRf()));
+ NS_LOG_DEBUG("PROACTIVE PREQ RECEIVED");
+ newInfo.type = INFO_PROACTIVE;
+ m_routingInfoCallback(newInfo);
+ if(!preq.IsNeedNotPrep())
+ {
+ SendPrep(
+ preq.GetOriginatorAddress(),
+ m_address,
+ from,
+ preq.GetMetric(),
+ preq.GetOriginatorSeqNumber(),
+ m_myDsn ++,
+ preq.GetLifetime()
+ );
+ if(m_myDsn == MAX_DSN)
+ m_myDsn = 0;
+ }
+ break;
+ }
+ if((*i)->GetDestinationAddress()==m_address)
+ {
+ preq.DelDestinationAddressElement((*i)->GetDestinationAddress());
+ SendPrep(
+ preq.GetOriginatorAddress(),
+ m_address,
+ from,
+ 0,
+ preq.GetOriginatorSeqNumber(),
+ m_myDsn++,
+ preq.GetLifetime()
+ );
+ if(m_myDsn == MAX_DSN)
+ m_myDsn = 0;
+ continue;
+ }
+ //check if can answer:
+ struct HwmpRtable::LookupResult result = m_requestRouteCallback((*i)->GetDestinationAddress());
+ if((!((*i)->IsDo())) && (result.retransmitter!=Mac48Address::GetBroadcast()))
+ {
+ //have a valid information and acn answer
+ if((*i)->IsRf())
+ (*i)->SetFlags(true, false); //DO = 1, RF = 0 (as it was)
+ else
+ {
+ //send a PREP and delete destination
+ preq.DelDestinationAddressElement((*i)->GetDestinationAddress());
+ SendPrep(
+ preq.GetOriginatorAddress(),
+ (*i)->GetDestinationAddress(),
+ result.retransmitter,
+ result.metric,
+ preq.GetOriginatorSeqNumber(),
+ result.seqnum,
+ preq.GetLifetime()
+ );
+ continue;
+ }
+ }
+ }
+ m_routingInfoCallback(newInfo);
+ //chack if must retransmit:
+ if(preq.GetDestCount() == 0)
+ return;
+ if(m_preqTimer.IsRunning())
+ {
+ m_preqQueue.push_back(preq);
+ }
+ else
+ {
+ m_preqCallback(preq);
+ NS_ASSERT(!m_preqTimer.IsRunning());
+ m_preqTimer = Simulator::Schedule(dot11sParameters::dot11MeshHWMPpreqMinInterval, &HwmpState::SendOnePreq, this);
+ }
+}
+
+void
+HwmpState::ReceivePrep(WifiPrepInformationElement& prep, const Mac48Address& from, const uint32_t& metric)
+{
+ if(m_disabled)
+ return;
+ prep.DecrementTtl();
+ prep.IncrementMetric(metric);
+ //acceptance cretirea:
+ std::map<Mac48Address, uint32_t, addrcmp>::iterator i = m_dsnDatabase.find(prep.GetDestinationAddress());
+ if(i == m_dsnDatabase.end())
+ {
+ m_dsnDatabase[prep.GetDestinationAddress()] = prep.GetDestinationSeqNumber();
+ }
+ else
+ if(i->second > prep.GetDestinationSeqNumber())
+ return;
+ //update routing info
+ struct HwmpRtable::LookupResult result = m_requestRouteCallback(prep.GetDestinationAddress());
+ if(result.retransmitter == Mac48Address::GetBroadcast())
+ //try to look for default route
+ result = m_requestRootPathCallback(m_ifIndex);
+ if((result.retransmitter == Mac48Address::GetBroadcast())&&(m_address != prep.GetDestinationAddress()))
+ return;
+ INFO newInfo;
+ newInfo.me = m_address;
+ newInfo.destination = prep.GetOriginatorAddress();
+ newInfo.source = prep.GetDestinationAddress();
+ newInfo.nextHop = from;
+ newInfo.metric = prep.GetMetric();
+ newInfo.lifetime = TU_TO_TIME(prep.GetLifetime());
+ newInfo.outPort = m_ifIndex;
+ newInfo.dsn = prep.GetOriginatorSeqNumber();
+ newInfo.prevHop = result.retransmitter;
+ newInfo.type = INFO_PREP;
+ NS_LOG_DEBUG("Path to "<<newInfo.source<<", i am "<<m_address<<", precursor is "<<from);
+ NS_LOG_DEBUG("Path to "<<newInfo.destination<<", i am "<<m_address<<", precursor is "<<result.retransmitter);
+ m_routingInfoCallback(newInfo);
+ if(prep.GetDestinationAddress() == m_address)
+ {
+ NS_LOG_DEBUG("Destination resolved"<<newInfo.destination);
+ return;
+ }
+ m_prepCallback(prep, result.retransmitter);
+}
+
+void
+HwmpState::ReceivePerr(WifiPerrInformationElement& perr, const Mac48Address& from)
+{
+ if(m_disabled)
+ return;
+ NS_LOG_DEBUG(m_address<<" RECEIVED PERR from "<<from);
+ /**
+ * Check forwarding conditions:
+ */
+ std::vector<HwmpRtable::FailedDestination> destinations = perr.GetAddressUnitVector();
+ for(unsigned int i = 0; i < destinations.size(); i ++)
+ {
+ /**
+ * Lookup for a valid routing information
+ */
+ struct HwmpRtable::LookupResult result = m_requestRouteCallback(destinations[i].destination);
+ if(
+ (result.retransmitter != from)
+ ||(result.seqnum >= destinations[i].seqnum)
+ )
+
+ perr.DeleteAddressUnit(destinations[i].destination);
+ }
+ NS_LOG_DEBUG("Retransmit "<<(int)perr.GetNumOfDest());
+ if(perr.GetNumOfDest() == 0)
+ return;
+ destinations = perr.GetAddressUnitVector();
+ SendPathError(destinations);
+}
+
+void
+HwmpState::PeerStatus(const Mac48Address peerAddress, const bool status, const uint32_t metric)
+{
+ INFO newInfo;
+ newInfo.me = m_address;
+ newInfo.destination = peerAddress;
+ newInfo.nextHop = peerAddress;
+ newInfo.metric = metric;
+ newInfo.outPort = m_ifIndex;
+ newInfo.dsn = 0;
+ if(status)
+ newInfo.type = INFO_NEW_PEER;
+ else
+ newInfo.type = INFO_FAILED_PEER;
+ m_routingInfoCallback(newInfo);
+}
+
+bool
+HwmpState::SetRoot()
+{
+#if 0
+ //TODO:: delete this lines!!!!!!!
+ if(m_address != Mac48Address("00:00:00:00:00:10"))
+ return false;
+ //TODO
+#endif
+ Simulator::Schedule(dot11sParameters::dot11MeshHWMPactiveRootTimeout, &HwmpState::SendProactivePreq, this);
+ return true;
+}
+
+void
+HwmpState::SendProactivePreq()
+{
+ NS_LOG_DEBUG("Sending proactive PREQ");
+ WifiPreqInformationElement preq;
+ //By default: must answer
+ preq.SetHopcount(0);
+ preq.SetTTL(m_maxTtl);
+ preq.SetPreqID(m_preqId++);
+ if(m_preqId == MAX_PREQ_ID)
+ m_preqId = 0;
+ preq.SetLifetime(TIME_TO_TU(dot11sParameters::dot11MeshHWMPpathToRootInterval));
+ preq.SetOriginatorSeqNumber(m_myDsn++);
+ if(m_myDsn == MAX_DSN)
+ m_myDsn = 0;
+ preq.SetOriginatorAddress(m_address);
+ preq.AddDestinationAddressElement(
+ true,
+ true,
+ Mac48Address::GetBroadcast()
+ ,0);
+ if(m_preqTimer.IsRunning())
+ m_preqQueue.push_back(preq);
+ else
+ {
+ NS_LOG_DEBUG("Send now "<<preq.GetPreqID());
+ m_preqCallback(preq);
+ NS_ASSERT(!m_preqTimer.IsRunning());
+ m_preqTimer = Simulator::Schedule(dot11sParameters::dot11MeshHWMPpreqMinInterval, &HwmpState::SendOnePreq, this);
+ }
+ Simulator::Schedule(dot11sParameters::dot11MeshHWMPactiveRootTimeout, &HwmpState::SendProactivePreq, this);
+}
+
+void
+HwmpState::AddPerrReceiver(Mac48Address receiver)
+{
+ /**
+ * add new vector of addresses to m_perrReceiversand check
+ * duplicates
+ */
+ for(unsigned int j = 0; j < m_myPerrReceivers.size(); j++)
+ if(m_myPerrReceivers[j] == receiver)
+ return;
+ m_myPerrReceivers.push_back(receiver);
+}
+
+void
+HwmpState::UnSetRoot()
+{
+}
+
+void
+HwmpState::Disable()
+{
+ m_disabled = true;
+}
+
+void
+HwmpState::Enable()
+{
+ m_disabled = false;
+}
+
+Mac48Address
+HwmpState::GetAddress()
+{
+ return m_address;
+}
+
+void
+HwmpState::SendOnePreq()
+{
+ if(m_preqQueue.size() == 0)
+ return;
+ if(m_myPreq == m_preqQueue.begin())
+ m_myPreq == m_preqQueue.end();
+ WifiPreqInformationElement preq = m_preqQueue[0];
+ NS_LOG_DEBUG(
+ "Sending PREQ from "<<preq.GetOriginatorAddress() <<
+ " destinations are "<<(int)preq.GetDestCount()<<
+ ", at "<<Simulator::Now()<<
+ ", store in queue "<<m_preqQueue.size()<<
+ " preqs"<<", I am "<<m_address);
+ m_preqCallback(preq);
+ //erase first!
+ m_preqQueue.erase(m_preqQueue.begin());
+ //reschedule sending PREQ
+ NS_ASSERT(!m_preqTimer.IsRunning());
+ m_preqTimer = Simulator::Schedule(dot11sParameters::dot11MeshHWMPpreqMinInterval, &HwmpState::SendOnePreq, this);
+}
+
+void
+HwmpState::SendPrep(Mac48Address dst,
+ Mac48Address src,
+ Mac48Address retransmitter,
+ uint32_t initMetric,
+ uint32_t dsn,
+ uint32_t originatorDsn,
+ uint32_t lifetime)
+{
+ WifiPrepInformationElement prep;
+ prep.SetHopcount(0);
+ prep.SetTTL(m_maxTtl);
+ prep.SetDestinationAddress(dst);
+ prep.SetDestinationSeqNumber(dsn);
+ prep.SetLifetime(lifetime);
+ prep.SetMetric(0);
+ prep.SetOriginatorAddress(src);
+ prep.SetOriginatorSeqNumber(originatorDsn);
+ m_prepCallback(prep, retransmitter);
+}
+
+void
+HwmpState::SendOnePerr()
+{
+ if(m_myPerr.GetNumOfDest() == 0)
+ return;
+ m_perrCallback(m_myPerr, m_myPerrReceivers);
+ m_myPerr.ResetPerr();
+}
+}//namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/l2-routing/l2-routing-hwmp/hwmp-state.h Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,206 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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 <andreev@iitp.ru>
+ */
+
+
+#ifndef HWMP_STATE_H
+#define HWMP_STATE_H
+#include <map>
+#include "ns3/event-id.h"
+#include "ns3/ptr.h"
+#include "ns3/hwmp-rtable.h"
+#include "ns3/packet.h"
+#include "ns3/wifi-net-device.h"
+#include "ns3/mesh-wifi-mac.h"
+#include "ns3/mesh-wifi-preq-information-element.h"
+#include "ns3/mesh-wifi-prep-information-element.h"
+#include "ns3/mesh-wifi-perr-information-element.h"
+#include "ns3/dot11s-parameters.h"
+namespace ns3 {
+ /**
+ * \brief Handles HWMP state machine at each real interface
+ * \details Implements the following:
+ * 1. Keep it's own DSN,
+ * 2. Keep PREQ and PREP timers adn send this frames in
+ * accordance with HWMP-limitations
+ * 3. Deliver routing information to Hwmp main class
+ * 4. Notify about broken peers
+ */
+ class HwmpState : public Object {
+ public:
+ static TypeId GetTypeId();
+ HwmpState();
+ ~HwmpState();
+
+ /**
+ * \brief Interface with HWMP - Hwmp can only
+ * request address and collect routing
+ * information
+ */
+ void SetRequestRouteCallback(
+ Callback<struct HwmpRtable::LookupResult, const Mac48Address&> cb);
+ void SetRequestRootPathCallback(
+ Callback<struct HwmpRtable::LookupResult, uint32_t> cb);
+
+ enum InfoType {
+ INFO_PREQ,
+ INFO_PREP,
+ INFO_PERR,
+ INFO_PROACTIVE,
+ INFO_NEW_PEER,
+ INFO_FAILED_PEER
+ };
+ typedef struct RoutingInfo{
+ Mac48Address me;
+ Mac48Address destination;
+ Mac48Address source;
+ Mac48Address nextHop;
+ Mac48Address prevHop;
+ uint32_t outPort;
+ uint32_t metric;
+ std::vector<Mac48Address>
+ failedDestinations;
+ uint32_t dsn;
+ Time lifetime;
+ enum InfoType type;
+ } INFO;
+ void SetRoutingInfoCallback(
+ Callback<void, INFO> cb
+ );
+ void SetRetransmittersOfPerrCallback(
+ Callback<std::vector<Mac48Address>, std::vector<struct HwmpRtable::FailedDestination>, uint32_t> cb);
+ void RequestDestination(Mac48Address dest);
+ void SendPathError(std::vector<struct HwmpRtable::FailedDestination> destinations);
+ void SetAssociatedIfaceId(uint32_t interface);
+ uint32_t
+ GetAssociatedIfaceId();
+ //Mac interaction:
+ void SetMac(Ptr<MeshWifiMac> mac);
+ void SetSendPreqCallback(
+ Callback<void, const WifiPreqInformationElement&> cb);
+ void SetSendPrepCallback(
+ Callback<void, const WifiPrepInformationElement&> cb);
+ void SetSendPerrCallback(
+ Callback<void, const WifiPerrInformationElement&, std::vector<Mac48Address> > cb);
+ void ReceivePreq(WifiPreqInformationElement&, const Mac48Address& from, const uint32_t& metric);
+ void ReceivePrep(WifiPrepInformationElement&, const Mac48Address& from, const uint32_t& metric);
+ void ReceivePerr(WifiPerrInformationElement&, const Mac48Address& from);
+ void PeerStatus(
+ const Mac48Address peerAddress,
+ const bool status,
+ const uint32_t metric
+ );
+ //Proactive mode routines:
+ bool SetRoot();
+ void UnSetRoot();
+ //external handling:
+ void Disable();
+ void Enable();
+ //DEBUG purpose:
+ Mac48Address GetAddress();
+ private:
+ static const uint32_t MAX_PREQ_ID = 0xffffffff;
+ static const uint32_t MAX_DSN = 0xffffffff;
+ //information about associated port:
+ Mac48Address m_address;
+ //index when HWMP state is attached
+ uint32_t m_ifIndex;
+ //timers for PREQ and PREP:
+ EventId m_preqTimer;
+ void SendOnePreq();
+ std::vector<WifiPreqInformationElement>
+ m_preqQueue;
+ //true means that we can add a destination to
+ //existing PREQ element
+ //False means that we must send
+ EventId m_prepTimer;
+ void SendPrep(
+ Mac48Address dst, //dst is PREQ's originator address
+ Mac48Address src, //src is PREQ's destination address
+ Mac48Address retransmitter,
+ uint32_t initMetric,
+ uint32_t dsn,/* taken form PREQ*/
+ uint32_t originatorDsn, //taken from rtable or as m_myDsn ++;
+ uint32_t lifetime //taken from PREQ
+ );
+ std::vector<WifiPreqInformationElement>::iterator
+ m_myPreq;
+ //HWMP interaction callbacks:
+ Callback<void, INFO>
+ m_routingInfoCallback;
+ Callback<std::vector<Mac48Address>, std::vector<struct HwmpRtable::FailedDestination>, uint32_t>
+ m_retransmittersOfPerrCallback;
+ Callback<struct HwmpRtable::LookupResult, const Mac48Address&>
+ m_requestRouteCallback;
+ Callback<struct HwmpRtable::LookupResult, uint32_t>
+ m_requestRootPathCallback;
+ //Mac interaction callbacks:
+ Callback<void, const WifiPreqInformationElement&>
+ m_preqCallback;
+ Callback<void, const WifiPrepInformationElement&, const Mac48Address&>
+ m_prepCallback;
+ Callback<void, const WifiPerrInformationElement&, std::vector<Mac48Address> >
+ m_perrCallback;
+ //HwmpCounters:
+ uint32_t m_preqId;
+ uint32_t m_myDsn;
+ //Seqno and metric database
+ struct addrcmp
+ {
+ bool operator()(const Mac48Address addr1, Mac48Address addr2) const
+ {
+ uint8_t s1[6], s2[6];
+ addr1.CopyTo(s1);
+ addr2.CopyTo(s2);
+ for(int i = 0; i < 6; i ++)
+ if(s1[i] > s2[i])
+ return true;
+ return false;
+ }
+ };
+ std::map<Mac48Address, uint32_t, addrcmp>
+ m_dsnDatabase;
+ std::map<Mac48Address, uint32_t, addrcmp>
+ m_preqMetricDatabase;
+ //Disable/enable functionality
+ bool m_disabled;
+ //Proactive PREQ mechanism:
+ EventId m_proactivePreqTimer;
+ void SendProactivePreq();
+ /**
+ * \brief Two PERRs may not be sent closer to
+ * each other than
+ * dot11MeshHWMPperrMinInterval, so, each HWMP
+ * state collects all unreachable destinations
+ * and once in dot11MeshHWMPperrMinInterval
+ * should send PERR, and PERR element should
+ * be cleared
+ */
+ WifiPerrInformationElement
+ m_myPerr;
+ std::vector<Mac48Address>
+ m_myPerrReceivers;
+ void AddPerrReceiver(Mac48Address receiver);
+ EventId m_perrTimer;
+ void SendOnePerr();
+ //Configurable parameters:
+ uint8_t m_maxTtl;
+ };
+} //namespace ns3
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/l2-routing/l2-routing-hwmp/hwmp.cc Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,699 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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
+ *
+ * Authors: Kirill Andreev <andreev@iitp.ru>
+ * Aleksey Kovalenko <kovalenko@iitp.ru>
+ */
+
+
+#include "ns3/hwmp.h"
+#include "ns3/log.h"
+#include "ns3/simulator.h"
+
+NS_LOG_COMPONENT_DEFINE ("Hwmp");
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (Hwmp);
+NS_OBJECT_ENSURE_REGISTERED (HwmpTag);
+//Class HwmpTag:
+HwmpTag::HwmpTag()
+{
+}
+
+HwmpTag::~HwmpTag()
+{
+}
+
+void
+HwmpTag::SetAddress(Mac48Address retransmitter)
+{
+ m_address = retransmitter;
+}
+
+Mac48Address
+HwmpTag::GetAddress()
+{
+ return m_address;
+}
+
+void
+HwmpTag::SetTtl(uint8_t ttl)
+{
+ m_ttl = ttl;
+}
+
+uint8_t
+HwmpTag::GetTtl()
+{
+ return m_ttl;
+}
+
+void
+HwmpTag::SetMetric(uint32_t metric)
+{
+ m_metric = metric;
+}
+
+uint32_t
+HwmpTag::GetMetric()
+{
+ return m_metric;
+}
+
+void
+HwmpTag::SetSeqno(uint32_t seqno)
+{
+ m_seqno = seqno;
+}
+
+uint32_t
+HwmpTag::GetSeqno()
+{
+ return m_seqno;
+}
+
+TypeId
+HwmpTag::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::HwmpTag")
+ .SetParent<Tag> ()
+ .AddConstructor<HwmpTag> ()
+ ;
+ return tid;
+}
+
+TypeId
+HwmpTag::GetInstanceTypeId(void) const
+{
+ return GetTypeId();
+}
+
+uint32_t
+HwmpTag::GetSerializedSize(void) const
+{
+
+ return 6 //address
+ +1 //ttl
+ +4; //metric
+}
+
+void
+HwmpTag::Serialize(TagBuffer i) const
+{
+ uint8_t address[6];
+ int j;
+ m_address.CopyTo(address);
+ i.WriteU8(m_ttl);
+ i.WriteU32(m_metric);
+ for(j = 0;j < 6;j ++)
+ i.WriteU8(address[j]);
+}
+
+void
+HwmpTag::Deserialize (TagBuffer i)
+{
+ uint8_t address[6];
+ int j;
+ m_ttl = i.ReadU8();
+ m_metric = i.ReadU32();
+ for(j = 0;j < 6;j ++)
+ address[j] = i.ReadU8();
+ m_address.CopyFrom(address);
+}
+
+void
+HwmpTag::Print (std::ostream &os) const
+{
+ os << "address=" << m_address;
+ os << "ttl=" << m_ttl;
+ os << "metrc=" << m_metric;
+}
+void
+HwmpTag::DecrementTtl()
+{
+ m_ttl --;
+}
+//Class HWMP:
+TypeId
+Hwmp::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::Hwmp")
+ .SetParent<L2RoutingProtocol> ()
+ .AddConstructor<Hwmp>();
+ return tid;
+}
+Hwmp::Hwmp()
+{
+ m_maxTtl = 32;
+ m_broadcastPerr = false;
+ m_rtable = CreateObject<HwmpRtable> ();
+}
+
+Hwmp::~Hwmp()
+{
+}
+
+void
+Hwmp::DoDispose()
+{
+ for(std::map<Mac48Address, EventId, addrcmp>::iterator i = m_timeoutDatabase.begin(); i != m_timeoutDatabase.end(); i ++)
+ i->second.Cancel();
+ m_timeoutDatabase.clear();
+ m_seqnoDatabase.clear();
+ m_rtable = 0;
+
+ /**
+ * clear routing queue:
+ */
+ for(
+ std::map<Mac48Address, std::queue<struct QueuedPacket> >::iterator i = m_rqueue.begin();
+ i != m_rqueue.end();
+ i++
+ )
+ {
+ while(1)
+ {
+ if(i->second.empty())
+ break;
+ i->second.pop();
+ }
+ }
+ m_rqueue.clear();
+ /**
+ * clear HWMP states
+ */
+ for(unsigned int i = 0; i < m_hwmpStates.size(); i ++)
+ m_hwmpStates[i] = 0;
+ m_hwmpStates.clear();
+}
+
+bool
+Hwmp::RequestRoute(
+ uint32_t sourceIface,
+ const Mac48Address source,
+ const Mac48Address destination,
+ Ptr<Packet> packet,
+ uint16_t protocolType, //ethrnet 'Protocol' field
+ L2RoutingProtocol::RouteReplyCallback routeReply
+ )
+{
+ struct HwmpRtable::LookupResult result;
+ HwmpTag tag;
+ if(sourceIface == m_interface)
+ {
+ if(destination == Mac48Address::GetBroadcast())
+ {
+ //set seqno!
+ tag.SetSeqno(m_seqno++);
+ if(m_seqno == MAX_SEQNO)
+ m_seqno = 0;
+ }
+ tag.SetTtl(m_maxTtl);
+ }
+ else
+ {
+ NS_ASSERT(packet->FindFirstMatchingTag(tag));
+ //check seqno!
+ if(destination == Mac48Address::GetBroadcast())
+ {
+ std::map<Mac48Address, uint32_t, addrcmp>::iterator i = m_seqnoDatabase.find(source);
+ if(i == m_seqnoDatabase.end())
+ m_seqnoDatabase[source] = tag.GetSeqno();
+ else
+ {
+ if(i->second >= tag.GetSeqno())
+ return false;
+ m_seqnoDatabase[source] = tag.GetSeqno();
+ }
+ }
+ }
+ tag.SetAddress(Mac48Address::GetBroadcast());
+ if(tag.GetTtl() == 0)
+ return false;
+ tag.DecrementTtl();
+ if(destination == Mac48Address::GetBroadcast())
+ {
+ //add RA tag RA = broadcast
+ packet->RemoveAllTags();
+ packet->AddTag(tag);
+ routeReply(
+ true,
+ packet,
+ source,
+ destination,
+ protocolType,
+ HwmpRtable::PORT_ANY
+ );
+ return true;
+ }
+ result = m_rtable->LookupReactive(destination);
+ if (result.retransmitter == Mac48Address::GetBroadcast())
+ {
+ //no actual route exists, queue packet and start route
+ //discover procedure
+ if(sourceIface != m_interface)
+ {
+ //Start path error procedure:
+ NS_LOG_DEBUG("Must Send PERR");
+ std::vector<struct HwmpRtable::FailedDestination> destinations;
+ struct HwmpRtable::FailedDestination dst;
+ dst.seqnum = m_rtable->RequestSeqnum(destination);
+ dst.destination = destination;
+ destinations.push_back(dst);
+ StartPathErrorProcedure(destinations, result.ifIndex);
+ }
+ struct L2RoutingProtocol::QueuedPacket pkt;
+ packet->RemoveAllTags();
+ packet->AddTag(tag);
+ pkt.pkt = packet;
+ pkt.dst = destination;
+ pkt.src = source;
+ pkt.protocol = protocolType;
+ pkt.reply = routeReply;
+ pkt.inPort = sourceIface;
+ QueuePacket(pkt);
+ for(unsigned int i = 0; i< m_requestCallback.size(); i++)
+ {
+ if((m_modes[i] == REACTIVE) || (m_modes[i] == ROOT))
+ {
+ if(ShouldSendPreq(destination))
+ m_requestCallback[i](destination);
+ }
+ else
+ {
+ NS_ASSERT(false);
+ //PROACTIVE mode
+ //lookup a default route
+ result = m_rtable->LookupProactive(m_hwmpStates[i]->GetAssociatedIfaceId());
+ if(result.retransmitter == Mac48Address::GetBroadcast())
+ {
+ m_rtable->DeleteProactivePath(m_hwmpStates[i]->GetAssociatedIfaceId());
+ m_modes[i] = REACTIVE;
+ if(ShouldSendPreq(destination))
+ m_requestCallback[i](destination);
+ continue;
+ }
+ tag.SetAddress(result.retransmitter);
+ packet->RemoveAllTags();
+ packet->AddTag(tag);
+ routeReply(
+ true,
+ packet,
+ source,
+ destination,
+ protocolType,
+ result.ifIndex
+ );
+ }
+ }
+ for(unsigned int i = 0; i< m_requestCallback.size(); i++)
+ {
+ m_requestCallback[i](Mac48Address("00:00:00:00:00:19"));
+
+ }
+ }
+ else
+ {
+ tag.SetAddress(result.retransmitter);
+ packet->RemoveAllTags();
+ packet->AddTag(tag);
+ routeReply(
+ true,
+ packet,
+ source,
+ destination,
+ protocolType,
+ result.ifIndex
+ );
+ }
+ return true;
+}
+bool
+Hwmp::AttachPorts(std::vector<Ptr<NetDevice> > ports)
+{
+ for(std::vector<Ptr<NetDevice> >::iterator i = ports.begin(); i != ports.end(); i++)
+ {
+ //Checking netdevice:
+ const WifiNetDevice * wifiNetDev = dynamic_cast<const WifiNetDevice *> (PeekPointer (*i));
+ if(wifiNetDev == NULL)
+ return false;
+ MeshWifiMac * meshWifiMac = dynamic_cast<MeshWifiMac *> (PeekPointer (wifiNetDev->GetMac()));
+ if(meshWifiMac == NULL)
+ return false;
+ //Adding HWMP-state
+ Ptr<HwmpState> hwmpState = CreateObject<HwmpState> ();
+ hwmpState->SetRoutingInfoCallback(MakeCallback(&Hwmp::ObtainRoutingInformation, this));
+ hwmpState->SetMac(meshWifiMac);
+ hwmpState->SetRequestRouteCallback(MakeCallback(&Hwmp::RequestRouteForAddress, this));
+ hwmpState->SetRequestRootPathCallback(MakeCallback(&Hwmp::RequestRootPathForPort, this));
+ hwmpState->SetAssociatedIfaceId(wifiNetDev->GetIfIndex());
+ hwmpState->SetRetransmittersOfPerrCallback(MakeCallback(&Hwmp::GetRetransmittersForFailedDestinations,this));
+ m_hwmpStates.push_back(hwmpState);
+ m_requestCallback.push_back(MakeCallback(&HwmpState::RequestDestination, hwmpState));
+ m_pathErrorCallback.push_back(MakeCallback(&HwmpState::SendPathError, hwmpState));
+ //Default mode is reactive, default state is enabled
+ enum DeviceState state = ENABLED;
+ enum DeviceMode mode = REACTIVE;
+ m_states.push_back(state);
+ m_modes.push_back(mode);
+ }
+ return true;
+}
+
+void
+Hwmp::SetIfIndex(uint32_t interface)
+{
+ m_interface = interface;
+}
+
+void
+Hwmp::DisablePort(uint32_t port)
+{
+ int position = 0;
+ for(std::vector<Ptr<HwmpState> >::iterator i = m_hwmpStates.begin(); i!= m_hwmpStates.end(); i++)
+ {
+ if((*i)->GetAssociatedIfaceId() == port)
+ {
+ m_states[position] = DISABLED;
+ m_hwmpStates[position]->Disable();
+ return;
+ }
+ position ++;
+ }
+}
+
+void
+Hwmp::EnablePort(uint32_t port)
+{
+ int position = 0;
+ for(std::vector<Ptr<HwmpState> >::iterator i = m_hwmpStates.begin(); i!= m_hwmpStates.end(); i++)
+ {
+ if((*i)->GetAssociatedIfaceId() == port)
+ {
+ m_states[position] = ENABLED;
+ m_hwmpStates[position]->Enable();
+ return;
+ }
+ position ++;
+ }
+}
+
+void
+Hwmp::SetRoot(uint32_t port)
+{
+ int position = 0;
+ for(std::vector<Ptr<HwmpState> >::iterator i = m_hwmpStates.begin(); i!= m_hwmpStates.end(); i++)
+ {
+ if(((*i)->GetAssociatedIfaceId() == port)||(port == HwmpRtable::PORT_ANY))
+ {
+ if(m_hwmpStates[position]->SetRoot())
+ {
+ m_modes[position] = ROOT;
+ NS_LOG_DEBUG("I am proactive");
+ }
+ }
+ position ++;
+ }
+}
+void
+Hwmp::SetProactive(uint32_t port)
+{
+ int position = 0;
+ for(std::vector<Ptr<HwmpState> >::iterator i = m_hwmpStates.begin(); i!= m_hwmpStates.end(); i++)
+ {
+ if((*i)->GetAssociatedIfaceId() == port)
+ {
+ m_modes[position] = PROACTIVE;
+ return;
+ }
+ position ++;
+ }
+}
+bool
+Hwmp::IsRoot(uint32_t port)
+{
+ int position = 0;
+ for(std::vector<Ptr<HwmpState> >::iterator i = m_hwmpStates.begin(); i!= m_hwmpStates.end(); i++)
+ {
+ if((*i)->GetAssociatedIfaceId() == port)
+ if(m_modes[position] == ROOT)
+ return true;
+ position ++;
+ }
+ return false;
+}
+void
+Hwmp::UnSetRoot(uint32_t port)
+{
+ int position = 0;
+ for(std::vector<Ptr<HwmpState> >::iterator i = m_hwmpStates.begin(); i!= m_hwmpStates.end(); i++)
+ {
+ if(((*i)->GetAssociatedIfaceId() == port)||(port == HwmpRtable::PORT_ANY))
+ {
+ m_modes[position] = REACTIVE;
+ m_hwmpStates[position]->UnSetRoot();
+ }
+ position ++;
+ }
+}
+
+void
+Hwmp::ObtainRoutingInformation(
+ HwmpState::INFO info
+ )
+{
+ switch(info.type)
+ {
+ case HwmpState::INFO_PREP:
+ if(info.me != info.source)
+ {
+ m_rtable->AddPrecursor(info.source, info.outPort, info.nextHop);
+ m_rtable->AddPrecursor(info.destination, info.outPort, info.prevHop);
+ NS_LOG_DEBUG("path to "<<info.source<<" precursor is "<<info.nextHop);
+ NS_LOG_DEBUG("path to "<<info.destination<<" precursor is "<<info.prevHop);
+ }
+ case HwmpState::INFO_PREQ:
+ m_rtable->AddReactivePath(
+ info.destination,
+ info.nextHop,
+ info.outPort,
+ info.metric,
+ info.lifetime,
+ info.dsn);
+ SendAllPossiblePackets(info.destination);
+ break;
+ case HwmpState::INFO_PERR:
+ //delete first subentry
+ case HwmpState::INFO_PROACTIVE:
+ //add information to the root MP.
+ m_rtable->AddProactivePath(
+ info.metric,
+ info.destination,
+ info.nextHop,
+ info.outPort,
+ info.lifetime,
+ info.dsn);
+ //Set mode as PROACTIVE:
+ SetProactive(info.outPort);
+ break;
+ case HwmpState::INFO_NEW_PEER:
+#if 0
+ m_rtable->AddReactivePath(
+ info.destination,
+ info.nextHop,
+ info.outPort,
+ info.metric,
+ Seconds(0),
+ 0);
+#endif
+ break;
+ case HwmpState::INFO_FAILED_PEER:
+ /**
+ * Conditions for generating PERR
+ */
+ {
+ NS_LOG_DEBUG("Failed peer"<<info.destination);
+ std::vector<struct HwmpRtable::FailedDestination> failedDestinations =
+ m_rtable->GetUnreachableDestinations(info.destination, info.outPort);
+ /**
+ * Entry about peer does not contain seqnum
+ */
+ struct HwmpRtable::FailedDestination peer;
+ peer.destination = info.destination;
+ peer.seqnum = 0;
+ failedDestinations.push_back(peer);
+ StartPathErrorProcedure(failedDestinations, info.outPort);
+ }
+ break;
+ default:
+ return;
+ }
+}
+
+struct HwmpRtable::LookupResult
+Hwmp::RequestRouteForAddress(const Mac48Address& dst)
+{
+ return m_rtable->LookupReactive(dst);
+}
+
+struct HwmpRtable::LookupResult
+Hwmp::RequestRootPathForPort(uint32_t port)
+{
+ return m_rtable->LookupProactive(port);
+}
+
+void
+Hwmp::StartPathErrorProcedure(std::vector<struct HwmpRtable::FailedDestination> destinations, uint32_t port)
+{
+ NS_LOG_DEBUG("START PERR");
+ for(unsigned int i = 0; i < m_hwmpStates.size(); i++)
+ if(m_hwmpStates[i]->GetAssociatedIfaceId() == port)
+ m_pathErrorCallback[i](destinations);
+}
+std::vector<Mac48Address>
+Hwmp::GetRetransmittersForFailedDestinations(std::vector<struct HwmpRtable::FailedDestination> failedDest, uint32_t port)
+{
+ std::vector<Mac48Address> retransmitters;
+ if(m_broadcastPerr)
+ retransmitters.push_back(Mac48Address::GetBroadcast());
+ else
+ for(unsigned int i = 0; i< failedDest.size(); i ++)
+ {
+ std::vector<Mac48Address> precursors =
+ m_rtable->GetPrecursors(failedDest[i].destination, port);
+ for(unsigned int j = 0; j < precursors.size(); j++)
+ {
+ for(unsigned int k = 0; k < retransmitters.size(); k ++)
+ if(retransmitters[k] == precursors[j])
+ break;
+ retransmitters.push_back(precursors[j]);
+ }
+ }
+ for(unsigned int i = 0; i < failedDest.size(); i ++)
+ {
+ m_rtable->DeleteReactivePath(failedDest[i].destination, port);
+ m_rtable->DeleteProactivePath(failedDest[i].destination, port);
+ }
+ return retransmitters;
+}
+void
+Hwmp::SetMaxQueueSize(int maxPacketsPerDestination)
+{
+ m_maxQueueSize = maxPacketsPerDestination;
+}
+
+bool
+Hwmp::QueuePacket(struct L2RoutingProtocol::QueuedPacket packet)
+{
+ if((int)m_rqueue[packet.dst].size() > m_maxQueueSize)
+ return false;
+ m_rqueue[packet.dst].push(packet);
+ return true;
+}
+
+struct L2RoutingProtocol::QueuedPacket
+Hwmp::DequeuePacket(Mac48Address dst)
+{
+ struct L2RoutingProtocol::QueuedPacket retval;
+ retval.pkt = NULL;
+ //Ptr<Packet> in this structure is NULL when queue is empty
+ std::map<Mac48Address, std::queue<struct QueuedPacket>, addrcmp>:: iterator i = m_rqueue.find(dst);
+ if(i == m_rqueue.end())
+ return retval;
+ if((int)m_rqueue[dst].size() == 0)
+ return retval;
+ if((int)i->second.size() == 0)
+ {
+ m_rqueue.erase(i);
+ return retval;
+ }
+ retval = m_rqueue[dst].front();
+ m_rqueue[dst].pop();
+ return retval;
+}
+
+void
+Hwmp::SendAllPossiblePackets(Mac48Address dst)
+{
+ struct HwmpRtable::LookupResult result = m_rtable->LookupReactive(dst);
+ struct L2RoutingProtocol::QueuedPacket packet;
+ while(1)
+
+ {
+ packet = DequeuePacket(dst);
+ if(packet.pkt == NULL)
+ return;
+ //set RA tag for retransmitter:
+ HwmpTag tag;
+ NS_ASSERT(packet.pkt->FindFirstMatchingTag(tag));
+ tag.SetAddress(result.retransmitter);
+ NS_ASSERT(result.retransmitter!=Mac48Address::GetBroadcast());
+ packet.pkt->RemoveAllTags();
+ packet.pkt->AddTag(tag);
+ packet.reply(true, packet.pkt, packet.src, packet.dst, packet.protocol, result.ifIndex);
+ }
+}
+
+bool
+Hwmp::ShouldSendPreq(Mac48Address dst)
+{
+ std::map<Mac48Address, EventId, addrcmp>::iterator i = m_timeoutDatabase.find(dst);
+ if(i == m_timeoutDatabase.end())
+ {
+ m_timeoutDatabase[dst] = Simulator::Schedule(
+ MilliSeconds(2*(dot11sParameters::dot11MeshHWMPnetDiameterTraversalTime.GetMilliSeconds())),
+ &Hwmp::RetryPathDiscovery, this, dst, 0);
+ return true;
+ }
+ return false;
+}
+void
+Hwmp::RetryPathDiscovery(Mac48Address dst, uint8_t numOfRetry)
+{
+ struct HwmpRtable::LookupResult result = m_rtable->LookupReactive(dst);
+ if(result.retransmitter != Mac48Address::GetBroadcast())
+ {
+ std::map<Mac48Address, EventId, addrcmp>::iterator i = m_timeoutDatabase.find(dst);
+ NS_ASSERT(i!= m_timeoutDatabase.end());
+ m_timeoutDatabase.erase(i);
+ return;
+ }
+ numOfRetry++;
+ if(numOfRetry > dot11sParameters::dot11MeshHWMPmaxPREQretries)
+ {
+ struct L2RoutingProtocol::QueuedPacket packet;
+ //purge queue and delete entry from retryDatabase
+ while(1)
+ {
+ packet = DequeuePacket(dst);
+ if(packet.pkt == NULL)
+ break;
+ packet.reply(false, packet.pkt, packet.src, packet.dst, packet.protocol, HwmpRtable::MAX_METRIC);
+ }
+ std::map<Mac48Address, EventId, addrcmp>::iterator i = m_timeoutDatabase.find(dst);
+ NS_ASSERT(i!= m_timeoutDatabase.end());
+ m_timeoutDatabase.erase(i);
+ return;
+ }
+ for(unsigned int i = 0; i< m_requestCallback.size(); i++)
+ if((m_modes[i] == REACTIVE) || (m_modes[i] == ROOT))
+ m_requestCallback[i](dst);
+ m_timeoutDatabase[dst] = Simulator::Schedule(
+ MilliSeconds(2*(dot11sParameters::dot11MeshHWMPnetDiameterTraversalTime.GetMilliSeconds())),
+ &Hwmp::RetryPathDiscovery, this, dst, numOfRetry);
+}
+} //namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/l2-routing/l2-routing-hwmp/hwmp.h Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,303 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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
+ *
+ * Authors: Kirill Andreev <andreev@iitp.ru>
+ * Aleksey Kovalenko <kovalenko@iitp.ru>
+ */
+
+
+#ifndef HWMP_H
+#define HWMP_H
+#include <map>
+#include <queue>
+#include "ns3/tag.h"
+#include "ns3/object.h"
+#include "ns3/mac48-address.h"
+#include "ns3/l2-routing-protocol.h"
+#include "ns3/packet.h"
+#include "ns3/ptr.h"
+#include "hwmp-state.h"
+namespace ns3 {
+ class HwmpState;
+ /**
+ * \brief Hwmp tag implements interaction between HWMP
+ * protocol and MeshWifiMac
+ * \details Hwmp tag keeps the following:
+ * 1. When packet is passed from Hwmp to 11sMAC:
+ * - retransmitter address,
+ * - TTL value,
+ * 2. When packet is passed to Hwmp from 11sMAC:
+ * - lasthop address,
+ * - TTL value,
+ * - metric value (metric of link is recalculated
+ * at each packet, but routing table stores metric
+ * obtained during path discovery procedure)
+ */
+ class HwmpTag : public Tag
+ {
+ public:
+ HwmpTag();
+ ~HwmpTag();
+ void SetAddress(Mac48Address retransmitter);
+ Mac48Address GetAddress();
+ void SetTtl(uint8_t ttl);
+ uint8_t GetTtl();
+ void SetMetric(uint32_t metric);
+ uint32_t GetMetric();
+ void SetSeqno(uint32_t seqno);
+ uint32_t GetSeqno();
+ void DecrementTtl();
+
+ static TypeId GetTypeId (void);
+ virtual TypeId GetInstanceTypeId (void) const;
+ virtual uint32_t GetSerializedSize (void) const;
+ virtual void Serialize (TagBuffer i) const;
+ virtual void Deserialize (TagBuffer i);
+ virtual void Print (std::ostream &os) const;
+ private:
+ Mac48Address m_address;
+ uint8_t m_ttl;
+ uint32_t m_metric;
+ uint32_t m_seqno;
+ };
+ class Hwmp : public L2RoutingProtocol
+ {
+ public:
+ static TypeId GetTypeId();
+ Hwmp();
+ ~Hwmp();
+ void DoDispose();
+ //intheritedfrom L2RoutingProtocol
+ /**
+ * \brief L2Routing protocol base class metod
+ *
+ * \details Route resolving procedure consits
+ * of the following steps:
+ * 1. Find reactive route and send a packet.
+ * 2. Find all ports which are operate in
+ * 'Proactive' mode and find a proper default
+ * routes. and send packet to all proactive
+ * 'ports'.
+ * 3. If there are ports which are operate in
+ * reactive mode - queue packet and start
+ * route reactive path discovery
+ *
+ * \bug Now packet is sent to the 'best root'
+ * rather than to the best root at each port
+ */
+ bool RequestRoute(
+ uint32_t sourceIface,
+ const Mac48Address source,
+ const Mac48Address destination,
+ Ptr<Packet> packet,
+ uint16_t protocolType,
+ L2RoutingProtocol::RouteReplyCallback
+ routeReply
+ );
+ bool AttachPorts(std::vector<Ptr<NetDevice> >);
+ void SetIfIndex(uint32_t interface);
+ /**
+ * \brief Disables port by index.
+ * \details Needed for external modules like
+ * clusterization.
+ */
+ void DisablePort(uint32_t port);
+ /**
+ * \brief enables port
+ */
+ void EnablePort(uint32_t port);
+ /**
+ * \brief Setting proative mode.
+ * \details To enable proactive mode you must
+ * set a root node. Choosing the route is made
+ * in accordance with the following:
+ * 1. Find 'reactive' route. If route is
+ * found - send a packet using this
+ * information
+ * 2. If there is no reactive route -
+ * find proactive or 'default' route.
+ * \attention Comparsion between proactive and
+ * reactive routes is incorrect, because we
+ * have metric to root MP in te first case and
+ * metric to the destination in the second
+ * case.
+ * \param port is the port where proactive
+ * mode should be activated
+ */
+ void SetRoot(uint32_t port);
+ /**
+ * \brief Disable root functionality at a
+ * given port
+ */
+ void UnSetRoot(uint32_t port);
+ /**
+ * \brief HwmpState retrns to Hwmp class all
+ * routing information obtained from all HWMP
+ * action frames
+ */
+ void ObtainRoutingInformation(
+ HwmpState::INFO info
+ );
+ /**
+ * \brief Hwmp state noyifyes that neighbour
+ * is dissapeared. Hwmp state knows about peer
+ * failure from MAC
+ */
+ void PeerFailure(Mac48Address peerAddress);
+ void SetMaxTtl(uint8_t ttl);
+ uint8_t
+ GetMaxTtl();
+ private:
+ static const uint32_t MAX_SEQNO = 0xffffffff;
+ //candidate queue is implemented inside the
+ //protocol:
+ void SetMaxQueueSize(int maxPacketsPerDestination);
+ int m_maxQueueSize;
+ bool QueuePacket(struct L2RoutingProtocol::QueuedPacket packet);
+ struct L2RoutingProtocol::QueuedPacket
+ DequeuePacket(Mac48Address dst);
+ void SendAllPossiblePackets(Mac48Address dst);
+ struct addrcmp
+ {
+ bool operator()(const Mac48Address addr1, Mac48Address addr2) const
+ {
+ uint8_t s1[6], s2[6];
+ addr1.CopyTo(s1);
+ addr2.CopyTo(s2);
+ for(int i = 0; i < 6; i ++)
+ if(s1[i] > s2[i])
+ return true;
+ return false;
+ }
+ };
+ std::map<Mac48Address, std::queue<struct QueuedPacket> >
+ m_rqueue;
+ //devices and HWMP states:
+ enum DeviceState {
+ ENABLED,
+ DISABLED
+ };
+ enum DeviceMode {
+ REACTIVE,
+ PROACTIVE,
+ ROOT
+ };
+ std::vector<enum DeviceState>
+ m_states;
+ std::vector<enum DeviceMode>
+ m_modes;
+ std::vector<Ptr<HwmpState> >
+ m_hwmpStates;
+ //Routing table:
+ Ptr<HwmpRtable>
+ m_rtable;
+ //Proactive routines:
+ /**
+ * \brief Set port state as proactive.
+ * \details mode is supposed to be proactive
+ * when proatcive PREQ with a valid
+ * information was received.
+ */
+ void SetProactive(uint32_t port);
+ /**
+ * \brief Checks if the port is root, if true
+ * - no default routes must be used at this
+ * port
+ */
+ bool IsRoot(uint32_t port);
+ /**
+ * \brief Interaction with HwmpState class -
+ * request for starting routing discover
+ * procedure (reactive route discovery!)
+ * \param Mac48Address is destination to be
+ * resolved
+ */
+ std::vector< Callback<void, Mac48Address> >
+ m_requestCallback;
+ /**
+ * \brief Callback that shall be executed when
+ * need to send Path error
+ * \param std::vector<Mac48Address> is the
+ * list of unreachable destinations
+ * \param std::vector<Mac48Address> is
+ * receivers of PERR
+ */
+ std::vector<Callback<void,std::vector<struct HwmpRtable::FailedDestination> > >
+ m_pathErrorCallback;
+ void StartPathErrorProcedure(
+ std::vector<struct HwmpRtable::FailedDestination> destinations,
+ uint32_t port);
+ /**
+ * \brief HwmpState need to know where to
+ * retransmit PERR, only HWMP knows how to
+ * retransmit it (broadcast/unicast) and only
+ * HWMP has accessto routing table
+ */
+ std::vector<Mac48Address>
+ GetRetransmittersForFailedDestinations(
+ std::vector<struct HwmpRtable::FailedDestination> failedDest,
+ uint32_t port);
+ /**
+ * \brief Needed by HwmpState to find routes in case
+ * of intermediate reply and choosing the
+ * better route
+ *
+ */
+ struct HwmpRtable::LookupResult
+ RequestRouteForAddress(const Mac48Address& destination);
+ struct HwmpRtable::LookupResult
+ RequestRootPathForPort(uint32_t port);
+
+ /**
+ * \brief interface which is the HWMP attached to
+ * (Virtual netdevice)
+ */
+ uint32_t m_interface;
+ /**
+ * \attention mesh seqno is processed at HWMP
+ */
+ uint32_t m_seqno;
+ std::map<Mac48Address, uint32_t, addrcmp>
+ m_seqnoDatabase;
+ //Timers:
+ /**
+ * /brief checks when last preq was initiated, returns
+ * false when retry has not expired
+ */
+ bool ShouldSendPreq(Mac48Address dst);
+ /**
+ * \brief Generates PREQ retry when route is
+ * still unresolved after first PREQ
+ * If number of retries greater than
+ * dot11sParameters::dot11MeshHWMPmaxPREQretries,
+ * we return all packets to upper layers
+ */
+ void RetryPathDiscovery(Mac48Address dst, uint8_t numOfRetry);
+ /**
+ * Keeps PREQ retry timers for every
+ * destination
+ */
+ std::map<Mac48Address, EventId, addrcmp>
+ m_timeoutDatabase;
+ /**
+ * Configurable parameters:
+ */
+ uint8_t m_maxTtl;
+ bool m_broadcastPerr;
+ };
+} //namespace ns3
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/l2-routing/l2-routing-hwmp/waf Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,1 @@
+exec "`dirname "$0"`"/../../../../waf "$@"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/l2-routing/l2-routing-hwmp/wscript Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,16 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+def build(bld):
+ obj = bld.create_ns3_module('l2-routing-hwmp', ['node', 'l2-routing-main'])
+ obj.source = [
+ 'hwmp-rtable.cc',
+ 'hwmp-state.cc',
+ 'hwmp.cc',
+ ]
+ headers = bld.new_task_gen('ns3header')
+ headers.module = 'l2-routing-hwmp'
+ headers.source = [
+ 'hwmp-rtable.h',
+ 'hwmp-state.h',
+ 'hwmp.h',
+ ]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/l2-routing/l2-routing-main/l2-routing-net-device.cc Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,355 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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 <andreev@iitp.ru>
+ */
+
+
+#include "ns3/node.h"
+#include "ns3/channel.h"
+#include "ns3/packet.h"
+#include "ns3/log.h"
+#include "ns3/boolean.h"
+#include "ns3/simulator.h"
+#include "ns3/l2-routing-net-device.h"
+
+NS_LOG_COMPONENT_DEFINE ("L2RoutingNetDevice");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (L2RoutingNetDevice);
+
+
+TypeId
+L2RoutingNetDevice::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::L2RoutingNetDevice")
+ .SetParent<NetDevice> ()
+ .AddConstructor<L2RoutingNetDevice> ()
+ ;
+ return tid;
+}
+
+
+L2RoutingNetDevice::L2RoutingNetDevice ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_channel = CreateObject<BridgeChannel> ();
+}
+
+L2RoutingNetDevice::~L2RoutingNetDevice()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+ void
+L2RoutingNetDevice::DoDispose ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ for (std::vector< Ptr<NetDevice> >::iterator iter = m_ports.begin (); iter != m_ports.end (); iter++)
+ *iter = 0;
+ m_ports.clear ();
+ m_node = 0;
+ NetDevice::DoDispose ();
+
+}
+
+ void
+L2RoutingNetDevice::ReceiveFromDevice (Ptr<NetDevice> incomingPort, Ptr<const Packet> packet, uint16_t protocol,
+ Address const &src, Address const &dst, PacketType packetType)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ NS_LOG_DEBUG ("UID is " << packet->GetUid ());
+ const Mac48Address src48 = Mac48Address::ConvertFrom (src);
+ const Mac48Address dst48 = Mac48Address::ConvertFrom (dst);
+ if (!m_promiscRxCallback.IsNull ())
+ m_promiscRxCallback (this, packet, protocol, src, dst, packetType);
+ switch (packetType)
+ {
+ case PACKET_HOST:
+ if (dst48 == m_address)
+ m_rxCallback (this, packet, protocol, src);
+ break;
+ case PACKET_BROADCAST:
+ case PACKET_MULTICAST:
+ m_rxCallback (this, packet, protocol, src);
+ case PACKET_OTHERHOST:
+ Forward (incomingPort, packet->Copy(), protocol, src48, dst48);
+ break;
+ }
+
+}
+
+void
+L2RoutingNetDevice::Forward (Ptr<NetDevice> inport, Ptr<Packet> packet,
+ uint16_t protocol, const Mac48Address src, const Mac48Address dst)
+{
+ //pass through routing protocol
+ m_requestRoute(inport->GetIfIndex(), src, dst, packet, protocol, m_myResponse);
+}
+
+uint32_t
+L2RoutingNetDevice::GetNPorts (void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_ports.size ();
+}
+
+Ptr<NetDevice>
+L2RoutingNetDevice::GetPort (uint32_t n) const
+{
+ NS_ASSERT(m_ports.size () > n);
+ return m_ports[n];
+}
+
+void
+L2RoutingNetDevice::AddPort (Ptr<NetDevice> routingPort)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ NS_ASSERT (routingPort != this);
+ if (!Mac48Address::IsMatchingType (routingPort->GetAddress ()))
+ NS_FATAL_ERROR ("Device does not support eui 48 addresses: cannot be added to bridge.");
+ if (!routingPort->SupportsSendFrom ())
+ NS_FATAL_ERROR ("Device does not support SendFrom: cannot be added to bridge.");
+ m_address = Mac48Address::ConvertFrom (routingPort->GetAddress ());
+ NS_LOG_DEBUG ("RegisterProtocolHandler for " << routingPort->GetName ());
+ m_node->RegisterProtocolHandler (MakeCallback (&L2RoutingNetDevice::ReceiveFromDevice, this),
+ 0, routingPort, true);
+ m_ports.push_back (routingPort);
+ m_channel->AddChannel (routingPort->GetChannel ());
+}
+
+ void
+L2RoutingNetDevice::SetName(const std::string name)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_name = name;
+}
+
+std::string
+L2RoutingNetDevice::GetName(void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_name;
+}
+
+ void
+L2RoutingNetDevice::SetIfIndex(const uint32_t index)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_ifIndex = index;
+}
+
+uint32_t
+L2RoutingNetDevice::GetIfIndex(void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_ifIndex;
+}
+
+Ptr<Channel>
+L2RoutingNetDevice::GetChannel (void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_channel;
+}
+
+Address
+L2RoutingNetDevice::GetAddress (void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_address;
+}
+
+ bool
+L2RoutingNetDevice::SetMtu (const uint16_t mtu)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_mtu = mtu;
+ return true;
+}
+
+uint16_t
+L2RoutingNetDevice::GetMtu (void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return 1500;
+}
+
+
+bool
+L2RoutingNetDevice::IsLinkUp (void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return true;
+}
+
+
+ void
+L2RoutingNetDevice::SetLinkChangeCallback (Callback<void> callback)
+{}
+
+bool
+L2RoutingNetDevice::IsBroadcast (void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return true;
+}
+
+
+Address
+L2RoutingNetDevice::GetBroadcast (void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return Mac48Address ("ff:ff:ff:ff:ff:ff");
+}
+
+bool
+L2RoutingNetDevice::IsMulticast (void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return true;
+}
+
+Address
+L2RoutingNetDevice::GetMulticast (Ipv4Address multicastGroup) const
+{
+ NS_LOG_FUNCTION (this << multicastGroup);
+ Mac48Address multicast = Mac48Address::GetMulticast (multicastGroup);
+ return multicast;
+}
+
+
+bool
+L2RoutingNetDevice::IsPointToPoint (void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return false;
+}
+
+bool
+L2RoutingNetDevice::IsBridge (void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return false;
+}
+
+
+bool
+L2RoutingNetDevice::Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
+{
+
+ const Mac48Address dst48 = Mac48Address::ConvertFrom (dest);
+ return m_requestRoute(m_ifIndex, m_address, dst48, packet, protocolNumber, m_myResponse);
+}
+
+bool
+L2RoutingNetDevice::SendFrom (Ptr<Packet> packet, const Address& src, const Address& dest, uint16_t protocolNumber)
+{
+ const Mac48Address src48 = Mac48Address::ConvertFrom (src);
+ const Mac48Address dst48 = Mac48Address::ConvertFrom (dest);
+ return m_requestRoute(m_ifIndex, src48, dst48, packet, protocolNumber, m_myResponse);
+}
+
+
+Ptr<Node>
+L2RoutingNetDevice::GetNode (void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_node;
+}
+
+
+ void
+L2RoutingNetDevice::SetNode (Ptr<Node> node)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_node = node;
+}
+
+
+bool
+L2RoutingNetDevice::NeedsArp (void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return true;
+}
+
+
+ void
+L2RoutingNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_rxCallback = cb;
+}
+
+ void
+L2RoutingNetDevice::SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_promiscRxCallback = cb;
+}
+
+bool
+L2RoutingNetDevice::SupportsSendFrom () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return true;
+}
+
+Address
+L2RoutingNetDevice::GetMulticast (Ipv6Address addr) const
+{
+ NS_LOG_FUNCTION (this << addr);
+ return Mac48Address::GetMulticast (addr);
+}
+//L2RouitingSpecific methods:
+
+bool
+L2RoutingNetDevice::AttachProtocol(Ptr<L2RoutingProtocol> protocol)
+{
+ m_requestRoute = MakeCallback(&L2RoutingProtocol::RequestRoute, protocol);
+ m_myResponse = MakeCallback(&L2RoutingNetDevice::ProtocolResponse, this);
+ protocol->SetIfIndex(m_ifIndex);
+ return protocol->AttachPorts(m_ports);
+}
+
+void
+L2RoutingNetDevice::ProtocolResponse(
+ bool success,
+ Ptr<Packet> packet,
+ Mac48Address src,
+ Mac48Address dst,
+ uint16_t protocol,
+ uint32_t outPort
+ )
+{
+ if(!success)
+ {
+ NS_LOG_UNCOND("Resolve failed");
+ //TODO: SendError callback
+ return;
+ }
+ //just do sendFrom!
+ if(outPort!=0xffffffff)
+ GetPort(outPort)->SendFrom(packet, src, dst, protocol);
+ else
+ for(std::vector<Ptr<NetDevice> >::iterator i = m_ports.begin(); i!= m_ports.end(); i++)
+ (*i) -> SendFrom(packet, src, dst, protocol);
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/l2-routing/l2-routing-main/l2-routing-net-device.h Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,167 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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 <andreev@iitp.ru>
+ */
+
+
+#ifndef L2ROUTING_NET_DEVICE_H
+#define L2ROUTING_NET_DEVICE_H
+
+#include "ns3/net-device.h"
+#include "ns3/mac48-address.h"
+#include "ns3/nstime.h"
+#include "ns3/bridge-net-device.h"
+#include "ns3/bridge-channel.h"
+#include "ns3/l2-routing-protocol.h"
+
+namespace ns3 {
+ class Node;
+ /**
+ * \ingroup devices
+ * \defgroup L2RoutingNetDevice L2routingNetDevice
+ */
+ /**
+ * \ingroup L2RoutingNetDevice
+ * \brief a virtual net device that may forward packets
+ * between real network devices using routing protocols of
+ * MAC-layer
+ * \details This is a virtual netdevice, which aggreagates
+ * real netdevices and uses interface of L2RoutingProtocol to
+ * forward packets
+ * \attention The idea of L2RoutingNetDevice is similar to
+ * BridgeNetDevice, but the packets, which going through
+ * L2RoutingNetDevice may be changed (because routing protocol
+ * may require its own headers or tags).
+ */
+ class L2RoutingNetDevice : public NetDevice
+ {
+ public:
+ static TypeId GetTypeId (void);
+ L2RoutingNetDevice ();
+ virtual ~L2RoutingNetDevice ();
+ /**
+ * \brief Attaches a 'port' to a virtual
+ * L2RoutingNetDevice, and this port is handled
+ * by L2RoutingProtocol.
+ * \attention Like in a bridge,
+ * L2RoutingNetDevice's ports must not have IP
+ * addresses, and only L2RoutingNetDevice
+ * itself may have an IP address.
+ *
+ * \attention L2RoutingNetDevice may be a port
+ * of BridgeNetDevice.
+ */
+ void AddPort (Ptr<NetDevice> port);
+ /**
+ * \returns number of ports attached to
+ * L2RoutingNetDevice
+ */
+ uint32_t GetNPorts (void) const;
+ /**
+ * \returns a pointer to netdevice
+ * \param n is device ID to be returned
+ */
+ Ptr<NetDevice> GetPort (uint32_t n) const;
+ //inherited from netdevice:
+ virtual void SetName(const std::string name);
+ virtual std::string GetName(void) const;
+ virtual void SetIfIndex(const uint32_t index);
+ virtual uint32_t GetIfIndex(void) const;
+ virtual Ptr<Channel> GetChannel (void) const;
+ 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 SetLinkChangeCallback (Callback<void> callback);
+ virtual bool IsBroadcast (void) const;
+ virtual Address GetBroadcast (void) const;
+ virtual bool IsMulticast (void) const;
+ virtual Address GetMulticast (Ipv4Address multicastGroup) const;
+ virtual bool IsPointToPoint (void) const;
+ virtual bool IsBridge (void) const;
+ virtual bool Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber);
+ virtual bool SendFrom (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber);
+ virtual Ptr<Node> GetNode (void) const;
+ virtual void SetNode (Ptr<Node> node);
+ virtual bool NeedsArp (void) const;
+ virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
+ virtual void SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb);
+ virtual bool SupportsSendFrom () const;
+ virtual Address GetMulticast (Ipv6Address addr) const;
+ virtual void DoDispose (void);
+ /**
+ * \brief Attaches protocol to a given virtual
+ * device
+ * \returns true if success
+ */
+ virtual bool AttachProtocol(Ptr<L2RoutingProtocol> protocol);
+ protected:
+ /**
+ * \brief This is similar to BridgeNetDevice
+ * method
+ */
+ void ReceiveFromDevice (Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol,
+ Address const &source, Address const &destination, PacketType packetType);
+ /**
+ * \brief This is similar to BridgeNetDevice
+ * method
+ */
+ void Forward (Ptr<NetDevice> incomingPort, Ptr<Packet> packet,
+ uint16_t protocol, const Mac48Address src, const Mac48Address dst);
+ /**
+ * \brief This is a function, which should be
+ * passed to L2RoutingProtocol as response
+ * callback (see L2RoutingProtocol).
+ */
+ virtual void ProtocolResponse(
+ bool success,
+ Ptr<Packet>,
+ Mac48Address src,
+ Mac48Address dst,
+ uint16_t protocol,
+ uint32_t outPort
+ );
+ private:
+ NetDevice::ReceiveCallback
+ m_rxCallback;
+ NetDevice::PromiscReceiveCallback
+ m_promiscRxCallback;
+ Mac48Address m_address;
+ Ptr<Node> m_node;
+ std::string m_name;
+ std::vector< Ptr<NetDevice> >
+ m_ports;
+ uint32_t m_ifIndex;
+ uint16_t m_mtu;
+ Ptr<BridgeChannel>
+ m_channel;
+ Callback<
+ bool,
+ uint32_t,
+ Mac48Address,
+ Mac48Address,
+ Ptr<Packet>,
+ uint16_t,
+ L2RoutingProtocol::RouteReplyCallback>
+ m_requestRoute;
+ //What we give to L2Routing
+ L2RoutingProtocol::RouteReplyCallback
+ m_myResponse;
+ };
+} //namespace ns3
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/l2-routing/l2-routing-main/waf Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,1 @@
+exec "`dirname "$0"`"/../../../../waf "$@"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/l2-routing/l2-routing-main/wscript Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,12 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+def build(bld):
+ obj = bld.create_ns3_module('l2-routing-main', ['node', 'bridge'])
+ obj.source = [
+ 'l2-routing-net-device.cc',
+ ]
+ headers = bld.new_task_gen('ns3header')
+ headers.module = 'l2-routing-main'
+ headers.source = [
+ 'l2-routing-net-device.h',
+ ]
--- a/src/devices/wifi/dca-txop.h Wed Feb 25 12:27:00 2009 -0500
+++ b/src/devices/wifi/dca-txop.h Sat Feb 28 14:21:05 2009 +0300
@@ -161,6 +161,7 @@
bool m_accessOngoing;
Ptr<const Packet> m_currentPacket;
WifiMacHeader m_currentHdr;
+ uint8_t m_currentRetry;
uint8_t m_fragmentNumber;
};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/dot11s-codes.h Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,89 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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
+ *
+ * Authors: Aleksey Kovalenko <kovalenko@iitp.ru>
+ * Kirill Andreev <andreev@iitp.ru>
+ */
+
+
+#ifndef DOT11S_CODES_H
+#define DOT11S_CODES_H
+
+namespace ns3 {
+
+enum dot11sElementID {
+ MESH_CONFIGURATION = 18,
+ MESH_ID,
+ LINK_METRIC_REPORT,
+ CONGESTION_NOTIFICATION,
+ PEER_LINK_MANAGEMENT,
+ MESH_CHANNEL_SWITCH_ANNOUNCEMENT,
+ MESH_TIM,
+ AWAKE_WINDOW,
+ SYNCHRONIZATION_PROTOCOL,
+ BEACON_TIMING,
+ MDAOP_SETUP_REQUEST,
+ MDAOP_SETUP_REPLY,
+ MDAOP_ADVERTISEMENT,
+ MDAOP_SET_TEARDOWN,
+ CONNECTIVITY_REPORT,
+ PORTAL_ANNOUNCEMENT,
+ ROOT_ANNOUCEMENT,
+ PATH_REQUEST,
+ PATH_REPLY,
+ PATH_ERROR,
+ PROXY_UPDATE,
+ PROXY_UPDATE_CONFIRMATION,
+ MSCIE,
+ MSAIE,
+};
+
+enum dot11sReasonCode {
+ PEER_LINK_CANCELLED,
+ MESH_MAX_PEERS,
+ MESH_CAPABILITY_POLICY_VIOLATION,
+ MESH_CLOSE_RCVD,
+ MESH_MAX_RETRIES,
+ MESH_CONFIRM_TIMEOUT,
+ MESH_SECURITY_ROLE_NEGOTIATION_DIFFERS,
+ MESH_SECURITY_AUTHENTICATION_IMPOSSIBLE,
+ MESH_SECURITY_FAILED_VERIFICATION,
+ MESH_INVALID_GTK,
+ MESH_MISMATCH_GTK,
+ MESH_INCONSISTENT_PARAMETERS,
+ MESH_CONFIGURATION_POLICY_VIOLATION,
+ DOT11S_REASON_RESERVED,
+};
+
+enum dot11sStatusCode {
+ PEAR_LINK_ESTABLISHED,
+ PEAR_LINK_CLOSED,
+ NO_LISTED_KEY_HOLDER,
+ MESH_KEY_HANDSHAKE_MALFORMED,
+ PEAR_LINK_MAX_RETRIES,
+ PEAR_LINK_NO_PMK,
+ PEAR_LINK_ALT_PMK,
+ PEAR_LINK_NO_AKM,
+ PEAR_LINK_ALT_AKM,
+ PEAR_LINK_NO_KDF,
+ PEAR_LINK_SA_ESTABLISHED,
+ AUTHENTICATION_REJECTED_CLOGGING,
+ DOT11S_STATUS_RESERVED,
+};
+
+}
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/dot11s-parameters.cc Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,43 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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
+ *
+ * Authors: Aleksey Kovalenko <kovalenko@iitp.ru>
+ * Kirill Andreev <andreev@iitp.ru>
+ */
+
+
+#include "ns3/dot11s-parameters.h"
+
+namespace ns3
+{
+
+uint8_t dot11sParameters::dot11MeshMaxRetries = 4;
+Time dot11sParameters::dot11MeshRetryTimeout = TU_TO_TIME(40);
+Time dot11sParameters::dot11MeshHoldingTimeout = TU_TO_TIME(40);
+Time dot11sParameters::dot11MeshConfirmTimeout = TU_TO_TIME(40);
+
+
+uint8_t dot11sParameters::dot11MeshHWMPmaxPREQretries = 3;
+Time dot11sParameters::dot11MeshHWMPnetDiameterTraversalTime = TU_TO_TIME(10);
+Time dot11sParameters::dot11MeshHWMPpreqMinInterval = TU_TO_TIME(100);
+Time dot11sParameters::dot11MeshHWMPperrMinInterval = TU_TO_TIME(100);
+Time dot11sParameters::dot11MeshHWMPactiveRootTimeout = TU_TO_TIME(5000);
+Time dot11sParameters::dot11MeshHWMPactivePathTimeout = TU_TO_TIME(5000);
+Time dot11sParameters::dot11MeshHWMPpathToRootInterval = TU_TO_TIME(5000);
+Time dot11sParameters::dot11MeshHWMPrannInterval = TU_TO_TIME(1000);
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/dot11s-parameters.h Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,53 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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
+ *
+ * Authors: Aleksey Kovalenko <kovalenko@iitp.ru>
+ * Kirill Andreev <andreev@iitp.ru>
+ */
+
+
+#ifndef DOT11S_PARAMETERS_H
+#define DOT11S_PARAMETERS_H
+#include "ns3/uinteger.h"
+#include "ns3/nstime.h"
+
+namespace ns3
+{
+
+#define TU_TO_TIME(x) MicroSeconds(x*1024)
+#define TIME_TO_TU(x) x.GetMicroSeconds()/1024
+
+struct dot11sParameters
+{
+ /** Peer Link */
+ static uint8_t dot11MeshMaxRetries;
+ static Time dot11MeshRetryTimeout;
+ static Time dot11MeshHoldingTimeout;
+ static Time dot11MeshConfirmTimeout;
+ /** HWMP */
+ static uint8_t dot11MeshHWMPmaxPREQretries;
+ static Time dot11MeshHWMPnetDiameterTraversalTime;
+ static Time dot11MeshHWMPpreqMinInterval;
+ static Time dot11MeshHWMPperrMinInterval;
+ static Time dot11MeshHWMPactiveRootTimeout;
+ static Time dot11MeshHWMPactivePathTimeout;
+ static Time dot11MeshHWMPpathToRootInterval;
+ static Time dot11MeshHWMPrannInterval;
+};
+
+};
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/dot11s-peer-management-element.cc Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,134 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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
+ *
+ * Authors: Kirill Andreev <andreev@iitp.ru>
+ * Aleksey Kovalenko <kovalenko@iitp.ru>
+ */
+
+
+#include "dot11s-peer-management-element.h"
+#include "ns3/assert.h"
+
+
+//NS_LOG_COMPONENT_DEFINE ("MeshPeerLinkManagementelement");
+
+namespace ns3 {
+
+PeerLinkManagementElement::PeerLinkManagementElement ():
+ m_length(0),
+ m_subtype(PEER_OPEN),
+ m_localLinkId(0),
+ m_peerLinkId(0),
+ m_reasonCode(DOT11S_REASON_RESERVED)
+{}
+
+
+void
+PeerLinkManagementElement::SetPeerOpen(uint16_t localLinkId)
+{
+ m_length = 3;
+ m_subtype=PEER_OPEN;
+ m_localLinkId = localLinkId;
+}
+void
+PeerLinkManagementElement::SetPeerClose(uint16_t localLinkId, uint16_t peerLinkId, dot11sReasonCode reasonCode)
+{
+ m_length = 7;
+ m_subtype=PEER_CLOSE;
+ m_localLinkId = localLinkId;
+ m_peerLinkId = peerLinkId;
+ m_reasonCode = reasonCode;
+}
+
+void
+PeerLinkManagementElement::SetPeerConfirm(uint16_t localLinkId, uint16_t peerLinkId)
+{
+ m_length = 5;
+ m_subtype=PEER_CONFIRM;
+ m_localLinkId = localLinkId;
+ m_peerLinkId = peerLinkId;
+}
+
+dot11sReasonCode
+PeerLinkManagementElement::GetReasonCode() const
+{
+ return m_reasonCode;
+}
+
+uint16_t
+PeerLinkManagementElement::GetLocalLinkId() const
+{
+ return m_localLinkId;
+}
+
+uint16_t
+PeerLinkManagementElement::GetPeerLinkId() const
+{
+ return m_peerLinkId;
+}
+
+uint32_t
+PeerLinkManagementElement::GetSerializedSize (void) const
+{
+ return m_length+2;
+}
+
+bool
+PeerLinkManagementElement::SubtypeIsOpen() const
+{
+ return (m_subtype == PEER_OPEN);
+}
+bool
+PeerLinkManagementElement::SubtypeIsClose() const
+{
+ return (m_subtype == PEER_CLOSE);
+}
+bool
+PeerLinkManagementElement::SubtypeIsConfirm() const
+{
+ return (m_subtype == PEER_CONFIRM);
+}
+
+Buffer::Iterator
+PeerLinkManagementElement::Serialize (Buffer::Iterator i) const
+{
+ i.WriteU8(PEER_LINK_MANAGEMENT);
+ i.WriteU8(m_length);
+ i.WriteU8(m_subtype);
+ i.WriteHtonU16(m_localLinkId);
+ if(m_length > 3)
+ i.WriteHtonU16(m_peerLinkId);
+ if(m_length > 5)
+ i.WriteHtonU16(m_reasonCode);
+ return i;
+}
+Buffer::Iterator
+PeerLinkManagementElement::Deserialize (Buffer::Iterator i)
+{
+ dot11sElementID ElementId;
+ ElementId = (dot11sElementID)i.ReadU8();
+ NS_ASSERT(ElementId == PEER_LINK_MANAGEMENT);
+ m_length = i.ReadU8();
+ m_subtype = i.ReadU8();
+ m_localLinkId = i.ReadNtohU16();
+ if(m_length > 3)
+ m_peerLinkId = i.ReadNtohU16();
+ if(m_length > 5)
+ m_reasonCode = (dot11sReasonCode)i.ReadNtohU16();
+ return i;
+}
+} //namespace NS3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/dot11s-peer-management-element.h Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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
+ *
+ * Authors: Kirill Andreev <andreev@iitp.ru>
+ * Aleksey Kovalenko <kovalenko@iitp.ru>
+ */
+
+
+#ifndef MESH_PEER_MAN_ELEMENT
+#define MESH_PEER_MAN_ELEMENT
+
+#include <stdint.h>
+#include "ns3/buffer.h"
+#include "dot11s-codes.h"
+
+namespace ns3
+{
+class PeerLinkManagementElement
+{
+ public:
+ enum Subtype {
+ PEER_OPEN = 0,
+ PEER_CLOSE = 1,
+ PEER_CONFIRM = 2,
+ };
+ public:
+ PeerLinkManagementElement ();
+
+ void SetPeerOpen(uint16_t localLinkId);
+ void SetPeerClose(uint16_t localLinkID, uint16_t peerLinkId, dot11sReasonCode reasonCode);
+ void SetPeerConfirm(uint16_t localLinkID, uint16_t peerLinkId);
+
+ dot11sReasonCode GetReasonCode() const;
+ uint16_t GetLocalLinkId() const;
+ uint16_t GetPeerLinkId() const;
+ bool SubtypeIsOpen() const;
+ bool SubtypeIsClose() const;
+ bool SubtypeIsConfirm() const ;
+
+ uint32_t GetSerializedSize (void) const;
+ Buffer::Iterator Serialize (Buffer::Iterator i) const;
+ Buffer::Iterator Deserialize (Buffer::Iterator i);
+ private:
+ uint8_t m_length;
+ uint8_t m_subtype;
+ uint16_t m_localLinkId; //always is present
+ uint16_t m_peerLinkId; //only in confirm and may be present in close frame
+ dot11sReasonCode m_reasonCode; //only in close frame
+};
+} //namespace NS3
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/mesh-configuration-element.cc Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,178 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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
+ *
+ * Authors: Kirill Andreev <andreev@iitp.ru>
+ * Aleksey Kovalenko <kovalenko@iitp.ru>
+ */
+
+
+#include "mesh-configuration-element.h"
+#include "ns3/assert.h"
+#include "dot11s-codes.h"
+
+//NS_LOG_COMPONENT_DEFINE ("MeshConfigurationElement");
+
+namespace ns3 {
+
+dot11sMeshCapability::dot11sMeshCapability():
+ acceptPeerLinks(true),
+ MDAEnabled(false),
+ forwarding(true),
+ beaconTimingReport(false),
+ TBTTAdjustment(false),
+ powerSaveLevel(false)
+{}
+
+uint32_t dot11sMeshCapability::GetSerializedSize (void) const
+{
+ return 2;
+}
+
+Buffer::Iterator dot11sMeshCapability::Serialize (Buffer::Iterator i) const
+{
+ uint16_t result = 0;
+ if(acceptPeerLinks)
+ result |= 1 << 0;
+ if(MDAEnabled)
+ result |= 1 << 1;
+ if(forwarding)
+ result |= 1 << 2;
+ if(beaconTimingReport)
+ result |= 1 << 3;
+ if(TBTTAdjustment)
+ result |= 1 << 4;
+ if(powerSaveLevel)
+ result |= 1 << 5;
+ i.WriteHtonU16(result);
+ return i;
+}
+
+Buffer::Iterator dot11sMeshCapability::Deserialize (Buffer::Iterator i)
+{
+ uint16_t cap = i.ReadNtohU16();
+ acceptPeerLinks = Is(cap,0);
+ MDAEnabled = Is(cap,1);
+ forwarding = Is(cap,2);
+ beaconTimingReport = Is(cap,3);
+ TBTTAdjustment = Is(cap,4);
+ powerSaveLevel = Is(cap,5);
+ return i;
+}
+
+bool dot11sMeshCapability::Is(uint16_t cap, uint8_t n) const
+{
+ uint16_t mask = 1<<n;
+ return (cap & mask) == mask;
+}
+
+MeshConfigurationElement::MeshConfigurationElement ():
+ m_APSId(PROTOCOL_HWMP),
+ m_APSMId(METRIC_AIRTIME),
+ m_CCMId(CONGESTION_DEFAULT),
+ m_CP(CHANNEL_PRECEDENCE_OFF)
+{}
+
+uint32_t
+MeshConfigurationElement::GetSerializedSize (void) const
+{
+ return 1 // ID
+ + 1 // Length
+ + 1 // Version
+ + 4 // APSPId
+ + 4 // APSMId
+ + 4 // CCMId
+ + 4 // CP
+ + m_meshCap.GetSerializedSize()
+ ;
+}
+
+Buffer::Iterator
+MeshConfigurationElement::Serialize (Buffer::Iterator i) const
+{
+
+ i.WriteU8 (MESH_CONFIGURATION);
+ i.WriteU8 (GetSerializedSize()); // Length
+ i.WriteU8 (1); //Version
+ // Active Path Selection Protocol ID:
+ i.WriteHtonU32(m_APSId);
+ // Active Path Metric ID:
+ i.WriteHtonU32(m_APSMId);
+ // Congestion Control Mode ID:
+ i.WriteU32(m_CCMId);
+ // Channel Precedence:
+ i.WriteU32(m_CP);
+ i = m_meshCap.Serialize(i);
+ return i;
+}
+
+Buffer::Iterator
+MeshConfigurationElement::Deserialize (Buffer::Iterator i)
+{
+
+ uint8_t elementId;
+ uint8_t size;
+ uint8_t version;
+ elementId = i.ReadU8 ();
+
+ NS_ASSERT (elementId == MESH_CONFIGURATION);
+
+ size = i.ReadU8 ();
+ version = i.ReadU8();
+ // Active Path Selection Protocol ID:
+ m_APSId = (dot11sPathSelectionProtocol)i.ReadNtohU32();
+ // Active Path Metric ID:
+ m_APSMId = (dot11sPathSelectionMetric)i.ReadNtohU32();
+ // Congestion Control Mode ID:
+ m_CCMId = (dot11sCongestionControlMode)i.ReadU32();
+ // Channel Precedence:
+ m_CP = (dot11sChannelPrecedence)i.ReadU32();
+ i = m_meshCap.Deserialize(i);
+ return i;
+
+
+}
+
+void
+MeshConfigurationElement::SetRouting(dot11sPathSelectionProtocol routingId)
+{
+ m_APSId = routingId ;
+}
+
+void
+MeshConfigurationElement::SetMetric(dot11sPathSelectionMetric metricId)
+{
+ m_APSMId = metricId;
+}
+
+bool
+MeshConfigurationElement::IsHWMP(void)
+{
+ return (m_APSId == PROTOCOL_HWMP);
+}
+
+bool
+MeshConfigurationElement::IsAirtime(void)
+{
+ return (m_APSMId == METRIC_AIRTIME);
+}
+
+dot11sMeshCapability const& MeshConfigurationElement::MeshCapability()
+{
+ return m_meshCap;
+}
+
+} //namespace NS3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/mesh-configuration-element.h Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,101 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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
+ *
+ * Authors: Kirill Andreev <andreev@iitp.ru>
+ * Aleksey Kovalenko <kovalenko@iitp.ru>
+ */
+
+
+#ifndef MESH_CONFIGURATION_H
+#define MESH_CONFIGURATION_H
+
+#include <stdint.h>
+#include "ns3/buffer.h"
+
+namespace ns3
+{
+
+enum dot11sPathSelectionProtocol
+{
+ PROTOCOL_HWMP = 0x000fac00,
+ PROTOCOL_NULL = 0x000facff,
+};
+
+enum dot11sPathSelectionMetric
+{
+ METRIC_AIRTIME = 0x000fac00,
+ METRIC_NULL = 0x000facff,
+};
+
+enum dot11sCongestionControlMode
+{
+ CONGESTION_DEFAULT = 0x000fac00,
+ CONGESTION_NULL = 0x000facff,
+};
+
+enum dot11sChannelPrecedence
+{
+ CHANNEL_PRECEDENCE_OFF = 0x000fac00,
+};
+
+
+class dot11sMeshCapability
+{
+ public:
+ dot11sMeshCapability();
+ uint32_t GetSerializedSize (void) const;
+ Buffer::Iterator Serialize (Buffer::Iterator i) const;
+ Buffer::Iterator Deserialize (Buffer::Iterator i);
+ bool acceptPeerLinks;
+ bool MDAEnabled;
+ bool forwarding;
+ bool beaconTimingReport;
+ bool TBTTAdjustment;
+ bool powerSaveLevel;
+ private:
+ bool Is(uint16_t cap,uint8_t n) const;
+};
+
+class MeshConfigurationElement
+{
+ public:
+ MeshConfigurationElement();
+ void SetRouting(dot11sPathSelectionProtocol routingId);
+ void SetMetric(dot11sPathSelectionMetric metricId);
+ bool IsHWMP(void);
+ bool IsAirtime(void);
+
+ dot11sMeshCapability const& MeshCapability();
+
+ uint32_t GetSerializedSize (void) const;
+ Buffer::Iterator Serialize (Buffer::Iterator i) const;
+ Buffer::Iterator Deserialize (Buffer::Iterator i);
+ // TODO: Release and fill other fields in configuration
+ // element
+ private:
+ /** Active Path Selection Protocol ID */
+ dot11sPathSelectionProtocol m_APSId;
+ /** Active Path Metric ID */
+ dot11sPathSelectionMetric m_APSMId;
+ /** Congestion Control Mode ID */
+ dot11sCongestionControlMode m_CCMId;
+ /* Channel Precedence */
+ dot11sChannelPrecedence m_CP;
+ dot11sMeshCapability m_meshCap;
+};
+} //name space NS3
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/mesh-mgt-headers.cc Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,226 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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
+ *
+ * Authors: Kirill Andreev <andreev@iitp.ru>
+ * Yana Podkosova <yanapdk@rambler.ru>
+ * Aleksey Kovalenko <kovalenko@iitp.ru>
+ */
+
+
+#include "mesh-mgt-headers.h"
+#include "ns3/address-utils.h"
+#include "ns3/simulator.h"
+#include "ns3/assert.h"
+
+namespace ns3
+{
+/***********************************************************
+* PeerLinkOpen frame:
+************************************************************/
+NS_OBJECT_ENSURE_REGISTERED (MeshMgtPeerLinkManFrame);
+
+MeshMgtPeerLinkManFrame::MeshMgtPeerLinkManFrame()
+{
+}
+
+void
+MeshMgtPeerLinkManFrame::SetAid(uint16_t aid)
+{
+ Aid = aid;
+}
+
+void
+MeshMgtPeerLinkManFrame::SetSupportedRates(SupportedRates rates)
+{
+ Rates = rates;
+}
+
+void
+MeshMgtPeerLinkManFrame::SetQosField(uint16_t qos)
+{
+ QoS= qos;
+}
+
+void
+MeshMgtPeerLinkManFrame::SetMeshId(Ssid Id)
+{
+ MeshId = Id;
+}
+
+void
+MeshMgtPeerLinkManFrame::SetMeshConfigurationElement(MeshConfigurationElement MeshConf)
+{
+ MeshConfig = MeshConf;
+}
+
+void
+MeshMgtPeerLinkManFrame::SetPeerLinkManagementElement(PeerLinkManagementElement MeshPeerElement)
+{
+ PeerLinkMan = MeshPeerElement;
+}
+
+uint16_t
+MeshMgtPeerLinkManFrame::GetAid()
+{
+ return Aid;
+}
+
+SupportedRates
+MeshMgtPeerLinkManFrame::GetSupportedRates()
+{
+ return Rates;
+}
+
+uint16_t
+MeshMgtPeerLinkManFrame::GetQosField()
+{
+ return QoS;
+}
+
+Ssid
+MeshMgtPeerLinkManFrame::GetMeshId()
+{
+ return MeshId;
+}
+
+MeshConfigurationElement
+MeshMgtPeerLinkManFrame::GetMeshConfigurationElement()
+{
+ return MeshConfig;
+}
+
+PeerLinkManagementElement
+MeshMgtPeerLinkManFrame::GetPeerLinkManagementElement()
+{
+ return PeerLinkMan;
+}
+
+TypeId
+MeshMgtPeerLinkManFrame::GetTypeId(void)
+{
+ static TypeId tid =
+ TypeId ("ns3::MeshMgtPeerLinkManFrame")
+ .SetParent<Header> ()
+ .AddConstructor<MeshMgtPeerLinkManFrame> ()
+ ;
+ return tid;
+}
+
+TypeId
+MeshMgtPeerLinkManFrame::GetInstanceTypeId(void) const
+{
+ return GetTypeId();
+}
+
+void
+MeshMgtPeerLinkManFrame::Print(std::ostream &os) const
+{
+ //TODO:fill this method
+}
+
+uint32_t
+MeshMgtPeerLinkManFrame::GetSerializedSize(void) const
+{
+ uint32_t size = 1; //Subtype
+ if(MESH_MGT_HEADER_PEER_CONFIRM == Subtype)
+ size +=2; //AID of remote peer
+ if(MESH_MGT_HEADER_PEER_CLOSE != Subtype)
+ {
+ size += Rates.GetSerializedSize ();
+ size +=2;
+ size += MeshId.GetSerializedSize ();
+ size += MeshConfig.GetSerializedSize ();
+ }
+ size += PeerLinkMan.GetSerializedSize ();
+ return size;
+}
+
+void
+MeshMgtPeerLinkManFrame::Serialize(Buffer::Iterator start) const
+{
+ Buffer::Iterator i = start;
+ i.WriteU8(Subtype); //Like a Category in Standart
+ if(MESH_MGT_HEADER_PEER_CONFIRM == Subtype)
+
+ i.WriteHtonU16(Aid);
+ if(MESH_MGT_HEADER_PEER_CLOSE != Subtype)
+ {
+ i = Rates.Serialize(i);
+ //now QoS capabilities
+ i.WriteHtonU16(QoS);
+ i = MeshId.Serialize (i);
+ i = MeshConfig.Serialize (i);
+ }
+ i = PeerLinkMan.Serialize (i);
+}
+
+uint32_t
+MeshMgtPeerLinkManFrame::Deserialize(Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+ Subtype = i.ReadU8();
+ if(MESH_MGT_HEADER_PEER_CONFIRM == Subtype)
+ Aid = i.ReadNtohU16();
+ if(MESH_MGT_HEADER_PEER_CLOSE != Subtype)
+ {
+ i = Rates.Deserialize(i);
+ QoS = i.ReadNtohU16();
+ i = MeshId.Deserialize (i);
+ i = MeshConfig.Deserialize (i);
+ }
+ i = PeerLinkMan.Deserialize (i);
+ return i.GetDistanceFrom (start);
+}
+void
+MeshMgtPeerLinkManFrame::SetOpen()
+{
+ Subtype = MESH_MGT_HEADER_PEER_OPEN;
+}
+
+void
+MeshMgtPeerLinkManFrame::SetConfirm()
+{
+ Subtype = MESH_MGT_HEADER_PEER_CONFIRM;
+}
+
+void
+MeshMgtPeerLinkManFrame::SetClose()
+{
+ Subtype = MESH_MGT_HEADER_PEER_CLOSE;
+}
+
+bool
+MeshMgtPeerLinkManFrame::IsOpen()
+{
+ return (Subtype==MESH_MGT_HEADER_PEER_OPEN);
+}
+
+bool
+MeshMgtPeerLinkManFrame::IsConfirm()
+{
+ return (Subtype==MESH_MGT_HEADER_PEER_CONFIRM);
+}
+
+bool
+MeshMgtPeerLinkManFrame::IsClose()
+{
+ return (Subtype==MESH_MGT_HEADER_PEER_CLOSE);
+}
+
+} //namespace NS3
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/mesh-mgt-headers.h Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,95 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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
+ *
+ * Authors: Kirill Andreev <andreev@iitp.ru>
+ * Yana Podkosova <yanapdk@rambler.ru>
+ * Aleksey Kovalenko <kovalenko@iitp.ru>
+ */
+
+
+#ifndef MESH_MGT_HEADERS_H
+#define MESH_MGT_HEADERS_H
+
+#include <stdint.h>
+
+#include "ns3/header.h"
+#include "status-code.h"
+#include "dot11s-peer-management-element.h"
+#include "supported-rates.h"
+#include "mesh-configuration-element.h"
+#include "mesh-wifi-preq-information-element.h"
+#include "mesh-wifi-prep-information-element.h"
+#include "mesh-wifi-perr-information-element.h"
+#include "mesh-wifi-rann-information-element.h"
+#include "ssid.h"
+
+namespace ns3 {
+
+class MeshMgtPeerLinkManFrame : public Header
+{
+ public:
+ MeshMgtPeerLinkManFrame ();
+ void SetAid(uint16_t aid);
+ void SetSupportedRates(SupportedRates rates);
+ void SetQosField(uint16_t qos);
+ void SetMeshId(Ssid Id);
+ void SetMeshConfigurationElement(MeshConfigurationElement MeshConf);
+ void SetPeerLinkManagementElement(PeerLinkManagementElement MeshPeerElement);
+
+ uint16_t GetAid();
+ SupportedRates GetSupportedRates();
+ uint16_t GetQosField();
+ Ssid GetMeshId();
+ MeshConfigurationElement GetMeshConfigurationElement();
+ PeerLinkManagementElement GetPeerLinkManagementElement();
+
+ static TypeId GetTypeId(void);
+ virtual TypeId GetInstanceTypeId(void) const;
+ virtual void Print(std::ostream &os) const;
+ virtual uint32_t GetSerializedSize(void) const;
+ virtual void Serialize(Buffer::Iterator start) const;
+ virtual uint32_t Deserialize(Buffer::Iterator start);
+ //Subtype defining methods:
+ void SetOpen();
+ void SetConfirm();
+ void SetClose();
+
+ bool IsOpen();
+ bool IsConfirm();
+ bool IsClose();
+
+ private:
+ uint8_t Subtype;
+ static const uint8_t MESH_MGT_HEADER_PEER_OPEN = 1;
+ static const uint8_t MESH_MGT_HEADER_PEER_CONFIRM = 2;
+ static const uint8_t MESH_MGT_HEADER_PEER_CLOSE = 3;
+ // Standart is also requires a ReasonCode to be within
+ // PeerLinkClose frame format, but it is present within
+ // PeerLinkManagementElement, so we did not duplicate
+ // it.
+ uint16_t Aid; //only in Confirm
+ SupportedRates Rates; //only in Open and Confirm
+ uint16_t QoS; //only in Open and Confirm
+ Ssid MeshId; //only in Open and Confirm
+ MeshConfigurationElement MeshConfig; //only in Open and Confirm
+ PeerLinkManagementElement PeerLinkMan; //in all types of frames
+};
+
+}//namespace NS3
+#endif
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/mesh-wifi-beacon-timing-element.cc Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,195 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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 <andreev@iitp.ru>
+ */
+
+
+#include "mesh-wifi-beacon-timing-element.h"
+#define ELEMENT_ID (19)
+namespace ns3 {
+/*******************************************
+ * WifiBeaconTimingElementUnit
+ *******************************************/
+WifiBeaconTimingElementUnit::WifiBeaconTimingElementUnit()
+{
+ AID = 0;
+ LastBeacon = 0;
+ BeaconInterval = 0;
+}
+
+void
+WifiBeaconTimingElementUnit::SetAID(uint8_t aid)
+{
+ AID = aid;
+}
+
+void
+WifiBeaconTimingElementUnit::SetLastBeacon(uint16_t last_beacon)
+{
+ LastBeacon = last_beacon;
+}
+
+void
+WifiBeaconTimingElementUnit::SetBeaconInterval(uint16_t beacon_interval)
+{
+ BeaconInterval = beacon_interval;
+}
+
+uint8_t
+WifiBeaconTimingElementUnit::GetAID()
+{
+ return AID;
+}
+
+uint16_t
+WifiBeaconTimingElementUnit::GetLastBeacon()
+{
+ return LastBeacon;
+}
+
+uint16_t
+WifiBeaconTimingElementUnit::GetBeaconInterval()
+{
+ return BeaconInterval;
+}
+
+/*******************************************
+ * WifiBeaconTimingElement
+ *******************************************/
+WifiBeaconTimingElement::WifiBeaconTimingElement()
+{
+ m_maxSize = DEFAULT_MAX_SIZE;
+ m_numOfUnits = 0;
+}
+
+NeighboursTimingUnitsList
+WifiBeaconTimingElement::GetNeighboursTimingElementsList()
+{
+ return m_neighbours;
+}
+
+void
+WifiBeaconTimingElement::AddNeighboursTimingElementUnit(
+ uint16_t aid,
+ Time last_beacon, //MicroSeconds!
+ Time beacon_interval //MicroSeconds!
+ )
+{
+ //Firs we lookup if this element already exists
+ for(NeighboursTimingUnitsList::iterator i = m_neighbours.begin(); i!= m_neighbours.end(); i++)
+ if(
+ ((*i)->GetAID() == AID_TO_U8(aid))
+ && ((*i)->GetLastBeacon() == TIMESTAMP_TO_U16(last_beacon))
+ && ((*i)->GetBeaconInterval() == BEACON_INTERVAL_TO_U16(beacon_interval))
+ )
+ return;
+ Ptr<WifiBeaconTimingElementUnit>new_element = Create<WifiBeaconTimingElementUnit>();
+ new_element->SetAID(AID_TO_U8(aid));
+ new_element->SetLastBeacon(TIMESTAMP_TO_U16(last_beacon));
+ new_element->SetBeaconInterval(BEACON_INTERVAL_TO_U16(beacon_interval));
+ m_neighbours.push_back(new_element);
+ m_numOfUnits++;
+}
+
+void
+WifiBeaconTimingElement::DelNeighboursTimingElementUnit(
+ uint16_t aid,
+ Time last_beacon, //MicroSeconds!
+ Time beacon_interval //MicroSeconds!
+ )
+{
+ for(NeighboursTimingUnitsList::iterator i = m_neighbours.begin(); i!= m_neighbours.end(); i++)
+ if(
+ ((*i)->GetAID() == AID_TO_U8(aid))
+ && ((*i)->GetLastBeacon() == TIMESTAMP_TO_U16(last_beacon))
+ && ((*i)->GetBeaconInterval() == BEACON_INTERVAL_TO_U16(beacon_interval))
+ )
+ {
+ m_neighbours.erase(i);
+ m_numOfUnits--;
+ break;
+ }
+
+}
+
+void
+WifiBeaconTimingElement::ClearTimingElement()
+{
+ uint16_t to_delete = 0;
+ uint16_t i;
+ for(NeighboursTimingUnitsList::iterator j = m_neighbours.begin(); j!= m_neighbours.end(); j++)
+ {
+ to_delete++;
+ (*j) = 0;
+ }
+ for(i = 0; i < to_delete; i ++)
+ m_neighbours.pop_back();
+ m_neighbours.clear();
+
+}
+
+uint32_t
+WifiBeaconTimingElement::GetSerializedSize (void) const
+{
+ return (2+5*m_numOfUnits > m_maxSize) ? 2+((m_maxSize-2)/5)*5 : 2+5*m_numOfUnits;
+}
+Buffer::Iterator
+WifiBeaconTimingElement::Serialize (Buffer::Iterator i) const
+{
+ uint8_t can_be_written = (2+5*m_numOfUnits > m_maxSize) ? ((m_maxSize-2)/5) : m_numOfUnits;
+ int actually_written = 0;
+ i.WriteU8 (ELEMENT_ID);
+ i.WriteU8 (can_be_written);
+ for(NeighboursTimingUnitsList::const_iterator j = m_neighbours.begin(); j!= m_neighbours.end(); j++)
+ {
+ i.WriteU8 ((*j)->GetAID());
+ i.WriteHtonU16 ((*j)->GetLastBeacon());
+ i.WriteHtonU16 ((*j)->GetBeaconInterval());
+ actually_written++;
+ if(actually_written > can_be_written)
+ break;
+ }
+ if(can_be_written < m_numOfUnits)
+ {
+ //move written units to the end of our list, so they
+ //can be sent in timing element with next beacon
+ //TODO:swap elements
+
+ }
+ return i;
+}
+Buffer::Iterator
+WifiBeaconTimingElement::Deserialize (Buffer::Iterator i)
+{
+ uint8_t elementId;
+ uint8_t num_to_read = 0;
+ int j;
+ elementId = i.ReadU8();
+ NS_ASSERT(elementId == ELEMENT_ID);
+ num_to_read = i.ReadU8();
+ for(j=0;j<num_to_read; j++)
+ {
+ Ptr<WifiBeaconTimingElementUnit> new_element = Create<WifiBeaconTimingElementUnit>();
+ new_element->SetAID(i.ReadU8());
+ new_element->SetLastBeacon(i.ReadNtohU16());
+ new_element->SetBeaconInterval(i.ReadNtohU16());
+ m_neighbours.push_back(new_element);
+ }
+ return i;
+};
+} //namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/mesh-wifi-beacon-timing-element.h Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,103 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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 <andreev@iitp.ru>
+ */
+
+
+#ifndef WIFI_TIMING_ELEMENT_H
+#define WIFI_TIMING_ELEMENT_H
+
+#include <stdint.h>
+#include "ns3/buffer.h"
+#include "ns3/nstime.h"
+#include <list>
+namespace ns3
+{
+class WifiBeaconTimingElementUnit : public RefCountBase
+{
+ public:
+ WifiBeaconTimingElementUnit();
+ void SetAID(uint8_t aid);
+ void SetLastBeacon(uint16_t last_beacon);
+ void SetBeaconInterval(uint16_t beacon_interval);
+
+ uint8_t GetAID();
+ uint16_t GetLastBeacon();
+ uint16_t GetBeaconInterval();
+ private:
+ //Least significant octet of AID:
+ uint8_t AID;
+ //Last time we received a beacon in accordance with a
+ //local TSF measured in 256 microseconds unit:
+ uint16_t LastBeacon;
+ //Beacon interval of remote mesh point:
+ uint16_t BeaconInterval;
+};
+//This type is a list of timing elements obtained from neigbours with their beacons:
+typedef Ptr<WifiBeaconTimingElementUnit> WifiBeaconTimingElementPointer;
+typedef std::list<WifiBeaconTimingElementPointer> NeighboursTimingUnitsList;
+
+class WifiBeaconTimingElement
+{
+ public:
+ WifiBeaconTimingElement();
+ //This methods are needed for beacon collision
+ //avoidance module:
+ NeighboursTimingUnitsList
+ GetNeighboursTimingElementsList();
+ //The arguments of the following methods are different
+ //from internalBeaconTimingElementUnint. This was made
+ //for better communication with peer manager.
+ //BeaconTimingElement class should convert it into
+ //proper types:
+ void AddNeighboursTimingElementUnit(
+ uint16_t aid,
+ Time last_beacon, //MicroSeconds!
+ Time beacon_interval //MicroSeconds!
+ );
+ void DelNeighboursTimingElementUnit(
+ uint16_t aid,
+ Time last_beacon, //MicroSeconds!
+ Time beacon_interval //MicroSeconds!
+ );
+ void ClearTimingElement();
+ uint16_t TIMESTAMP_TO_U16(Time x)
+ {
+ return ((uint16_t)((x.GetMicroSeconds() >> 8)&0xffff));
+ };
+ uint16_t BEACON_INTERVAL_TO_U16(Time x)
+ {
+ return ((uint16_t)(x.GetMicroSeconds() >>10)&0xffff);
+ };
+ uint8_t AID_TO_U8(uint16_t x)
+ {
+ return (uint8_t)(x&0xff);
+ };
+ //Serialize-deserialize methods:
+ uint32_t GetSerializedSize (void) const;
+ Buffer::Iterator Serialize (Buffer::Iterator i) const;
+ Buffer::Iterator Deserialize (Buffer::Iterator i);
+ private:
+ NeighboursTimingUnitsList m_neighbours;
+ //The maximum size of this element:
+ const static uint16_t DEFAULT_MAX_SIZE = 255*5 +2;
+ uint16_t m_maxSize;
+ uint16_t m_numOfUnits;
+};
+}//namespace ns3
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/mesh-wifi-mac.cc Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,957 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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
+ *
+ * Authors: Kirill Andreev <andreev@iitp.ru>
+ * Ivan Pustogarov <chinsa1@rambler.ru>
+ * Evgeny Khorov <horov@frtk.ru>
+ */
+
+
+#include "ns3/assert.h"
+#include "ns3/log.h"
+#include "ns3/simulator.h"
+#include "ns3/node.h"
+#include "ns3/random-variable.h"
+
+#include "mesh-wifi-mac.h"
+#include "dca-txop.h"
+#include "wifi-mac-header.h"
+#include "mgt-headers.h"
+#include "wifi-phy.h"
+#include "dcf-manager.h"
+#include "mac-rx-middle.h"
+#include "mac-low.h"
+#include "ns3/tx-statistics.h"
+#include "ns3/hwmp.h"
+
+NS_LOG_COMPONENT_DEFINE ("MeshWifiMac");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (MeshWifiMac);
+
+TypeId
+MeshWifiMac::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::MeshWifiMac")
+ .SetParent<WifiMac> ()
+ .AddConstructor<MeshWifiMac> ()
+ .AddAttribute ("BeaconInterval", "Beacon Interval",
+ TimeValue (Seconds (1.0)),
+ MakeTimeAccessor (&MeshWifiMac::m_beaconInterval),
+ MakeTimeChecker ()
+ )
+ .AddAttribute ("RandomStart", "Window when beacon generating starts (uniform random) in seconds",
+ TimeValue (Seconds (0.1)),
+ MakeTimeAccessor (&MeshWifiMac::m_randomStart),
+ MakeTimeChecker ()
+ )
+ .AddAttribute ("SoftwareDelay", "Window of uniformely distributed random software handling delay",
+ TimeValue (MicroSeconds (500)),
+ MakeTimeAccessor (&MeshWifiMac::m_softwareDelay),
+ MakeTimeChecker ()
+ )
+ .AddAttribute ("BeaconGeneration", "Enable/Disable Beaconing.",
+ BooleanValue (true),
+ MakeBooleanAccessor (
+ &MeshWifiMac::SetBeaconGeneration,
+ &MeshWifiMac::GetBeaconGeneration
+ ),
+ MakeBooleanChecker ()
+ );
+ return tid;
+}
+
+MeshWifiMac::MeshWifiMac ()
+{
+ NS_LOG_FUNCTION (this);
+ m_rxMiddle = new MacRxMiddle ();
+ m_rxMiddle->SetForwardCallback (MakeCallback (&MeshWifiMac::Receive, this));
+
+ m_low = CreateObject<MacLow> ();
+ m_low->SetRxCallback (MakeCallback (&MacRxMiddle::Receive, m_rxMiddle));
+
+ m_dcfManager = new DcfManager ();
+ m_dcfManager->SetupLowListener (m_low);
+
+ m_beaconDca = CreateObject<DcaTxop> ();
+ m_beaconDca->SetLow (m_low);
+ m_beaconDca->SetMinCw (0);
+ m_beaconDca->SetMaxCw (0);
+ m_beaconDca->SetAifsn(1);
+ m_beaconDca->SetManager (m_dcfManager);
+
+ m_VO = CreateObject<DcaTxop> ();
+ m_VO->SetLow (m_low);
+ m_VO->SetMinCw (3);
+ m_VO->SetMaxCw (7);
+ m_VO->SetManager (m_dcfManager);
+ m_VO->SetTxOkCallback (MakeCallback (&MeshWifiMac::TxOk, this));
+ m_VO->SetTxFailedCallback (MakeCallback (&MeshWifiMac::TxFailed, this));
+
+ m_BE = CreateObject<DcaTxop> ();
+ m_BE->SetLow (m_low);
+ m_BE->SetManager (m_dcfManager);
+ m_BE->SetTxOkCallback (MakeCallback (&MeshWifiMac::TxOk, this));
+ m_BE->SetTxFailedCallback (MakeCallback (&MeshWifiMac::TxFailed, this));
+}
+
+MeshWifiMac::~MeshWifiMac ()
+{
+ NS_LOG_FUNCTION (this);
+}
+/*
+ * Public Methods:
+ */
+void
+MeshWifiMac::SetSlot (Time slotTime)
+{
+ NS_LOG_FUNCTION (this << slotTime);
+ m_dcfManager->SetSlot (slotTime);
+ m_slot = slotTime;
+}
+
+void
+MeshWifiMac::SetSifs (Time sifs)
+{
+ NS_LOG_FUNCTION (this << sifs);
+ m_dcfManager->SetSifs (sifs);
+ m_sifs = sifs;
+}
+void
+MeshWifiMac::SetAckTimeout (Time ackTimeout)
+{
+ m_low->SetAckTimeout (ackTimeout);
+}
+
+void
+MeshWifiMac::SetCtsTimeout (Time ctsTimeout)
+{
+ m_low->SetCtsTimeout (ctsTimeout);
+}
+
+void
+MeshWifiMac::SetPifs (Time pifs)
+{
+ NS_LOG_FUNCTION (this << pifs);
+ m_pifs = pifs;
+}
+void
+MeshWifiMac::SetEifsNoDifs (Time eifsNoDifs)
+{
+ NS_LOG_FUNCTION (this << eifsNoDifs);
+ m_dcfManager->SetEifsNoDifs (eifsNoDifs);
+ m_eifsNoDifs = eifsNoDifs;
+}
+
+Time
+MeshWifiMac::GetSlot (void) const
+{
+ return m_slot;
+}
+
+Time
+MeshWifiMac::GetSifs (void) const
+{
+ return m_sifs;
+}
+
+Time
+MeshWifiMac::GetEifsNoDifs (void) const
+{
+ return m_eifsNoDifs;
+}
+
+Time
+MeshWifiMac::GetAckTimeout (void) const
+{
+ return m_low->GetAckTimeout ();
+}
+
+Time
+MeshWifiMac::GetCtsTimeout (void) const
+{
+ return m_low->GetCtsTimeout ();
+}
+
+Time
+MeshWifiMac::GetPifs (void) const
+{
+ return m_low->GetPifs ();
+}
+
+void
+MeshWifiMac::SetWifiPhy (Ptr<WifiPhy> phy)
+{
+ NS_LOG_FUNCTION (this << phy);
+ m_phy = phy;
+ m_dcfManager->SetupPhyListener (phy);
+ m_low->SetPhy (phy);
+}
+
+void
+MeshWifiMac::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager)
+{
+ NS_LOG_FUNCTION (this << stationManager);
+ m_stationManager = stationManager;
+ m_BE->SetWifiRemoteStationManager (stationManager);
+ m_VO->SetWifiRemoteStationManager (stationManager);
+ m_beaconDca->SetWifiRemoteStationManager (stationManager);
+ m_low->SetWifiRemoteStationManager (stationManager);
+}
+
+void
+MeshWifiMac::SetPeerLinkManager (Ptr<WifiPeerManager> manager)
+{
+ m_peerManager = manager;
+}
+
+void
+MeshWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to, Mac48Address from)
+{
+ NS_LOG_FUNCTION (this << packet << to << from);
+ ForwardDown (packet, from, to);
+}
+
+void
+MeshWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to)
+{
+ NS_LOG_FUNCTION (this << packet << to);
+ ForwardDown (packet, m_low->GetAddress (), to);
+}
+
+bool
+MeshWifiMac::SupportsSendFrom (void) const
+{
+ return true;
+}
+
+void
+MeshWifiMac::SetForwardUpCallback (Callback<void,Ptr<Packet>, Mac48Address, Mac48Address> upCallback)
+{
+ NS_LOG_FUNCTION (this);
+ m_upCallback = upCallback;
+}
+
+void
+MeshWifiMac::SetLinkUpCallback (Callback<void> linkUp)
+{
+ NS_LOG_FUNCTION (this);
+ if (!linkUp.IsNull ())
+ {
+ linkUp ();
+ }
+}
+
+void
+MeshWifiMac::SetLinkDownCallback (Callback<void> linkDown)
+{
+ NS_LOG_FUNCTION (this);
+}
+
+Mac48Address
+MeshWifiMac::GetAddress (void) const
+{
+ return m_address;
+}
+Mac48Address
+MeshWifiMac::GetBssid (void) const
+{
+ return m_address;
+}
+
+Ssid
+MeshWifiMac::GetSsid (void) const
+{
+ return m_MeshId;
+}
+
+void
+MeshWifiMac::SetAddress (Mac48Address address)
+{
+ NS_LOG_FUNCTION (address);
+ m_low->SetAddress(address);
+ m_address = address;
+}
+
+void
+MeshWifiMac::SetSsid (Ssid ssid)
+{
+ NS_LOG_FUNCTION (ssid);
+ m_MeshId = ssid;
+}
+
+void
+MeshWifiMac::SetBeaconInterval (Time interval)
+{
+ NS_LOG_FUNCTION (this << interval);
+ m_beaconInterval = interval;
+}
+
+void
+MeshWifiMac::DoDispose (void)
+{
+ delete m_rxMiddle;
+ delete m_dcfManager;
+ //Delete smart pointers:
+ m_beaconSendEvent.Cancel ();
+ m_beaconFormEvent.Cancel ();
+ m_low = 0;
+ m_BE = 0;
+ m_VO = 0;
+ m_beaconDca = 0;
+ m_phy = 0;
+ m_peerManager=0;
+ WifiMac::DoDispose ();
+}
+
+void
+MeshWifiMac::ForwardUp (Ptr<Packet> packet, Mac48Address src, Mac48Address dst)
+{
+ NS_LOG_FUNCTION (this << packet << src);
+ m_upCallback (packet, src, dst);
+}
+
+void
+MeshWifiMac::ForwardDown (Ptr<const Packet> packet, Mac48Address from, Mac48Address to)
+{
+ //TODO:Classify and queue
+ WifiMacHeader hdr;
+ Ptr<Packet> packet_to_send = packet->Copy();
+ WifiMeshHeader meshHdr;
+ //Address 1 we receive from HWMP tag
+ HwmpTag tag;
+ NS_ASSERT(packet->FindFirstMatchingTag(tag));
+ meshHdr.SetMeshTtl(tag.GetTtl());
+ meshHdr.SetMeshSeqno(tag.GetSeqno());
+#if 0
+ NS_LOG_DEBUG(
+ "TX Packet sa = "<<from<<
+ ", da = "<<to<<
+ ", ra = "<<tag.GetAddress()<<
+ ", I am "<<GetAddress()<<
+ ", ttl = "<<(int)meshHdr.GetMeshTtl()
+ );
+#endif
+ if(to!= Mac48Address::GetBroadcast())
+ NS_ASSERT(tag.GetAddress()!=Mac48Address::GetBroadcast());
+ hdr.SetTypeData ();
+ hdr.SetAddr1 (tag.GetAddress());
+ hdr.SetAddr2 (GetAddress ());
+ hdr.SetAddr3 (to);
+ hdr.SetAddr4(from);
+ hdr.SetDsFrom ();
+ hdr.SetDsTo ();
+ //TODO: classify should be fixed!
+ packet_to_send->AddHeader(meshHdr);
+ WifiRemoteStation *destination = m_stationManager->Lookup (to);
+
+ if (destination->IsBrandNew ())
+ {
+ // in adhoc mode, we assume that every destination
+ // supports all the rates we support.
+ for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
+ {
+ destination->AddSupportedMode (m_phy->GetMode (i));
+ }
+ destination->RecordDisassociated ();
+ }
+ m_BE->Queue (packet_to_send, hdr);
+}
+
+SupportedRates
+MeshWifiMac::GetSupportedRates (void) const
+{
+ // send the set of supported rates and make sure that we indicate
+ // the Basic Rate set in this set of supported rates.
+ SupportedRates rates;
+ for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
+ {
+ WifiMode mode = m_phy->GetMode (i);
+ rates.AddSupportedRate (mode.GetDataRate ());
+ }
+ // set the basic rates
+ for (uint32_t j = 0; j < m_stationManager->GetNBasicModes (); j++)
+ {
+ WifiMode mode = m_stationManager->GetBasicMode (j);
+ rates.SetBasicRate (mode.GetDataRate ());
+ }
+ return rates;
+}
+
+void
+MeshWifiMac::SendOneBeacon (void)
+{
+ NS_LOG_FUNCTION (this);
+ NS_LOG_DEBUG(GetAddress()<<" is sending beacon");
+ //Software delay should never be bigger than beacon interval!
+ NS_ASSERT(!m_beaconSendEvent.IsRunning());
+ Time last_software_delay = m_beaconFormingRandomDelay;
+ MgtMeshBeaconHeader beacon;
+ beacon.SetSsid (GetSsid ());
+ beacon.SetSupportedRates (GetSupportedRates ());
+ beacon.SetBeaconIntervalUs (m_beaconInterval.GetMicroSeconds ());
+ beacon.SetWifiBeaconTimingElement(m_peerManager->GetWifiBeaconTimingElementForMyBeacon(GetAddress()));
+ m_beaconSendEvent = Simulator::Schedule(
+ m_beaconFormingRandomDelay,
+ &MeshWifiMac::QueueOneBeacon,
+ this,
+ beacon);
+ UniformVariable coefficient(0.0, m_beaconFormingRandomDelay.GetSeconds());
+ m_beaconFormingRandomDelay = Seconds(coefficient.GetValue());
+
+ //MBCA functionality, TODO: add the switch off/on MBCA mechanism capability
+ //Let's find when we send the next beacon
+ Time myNextTBTT = Simulator::Now ()+m_beaconInterval+last_software_delay;
+ //The mext function compares my TBTT with neighbor's TBTTs using timing elemnt
+ //and returns time shift for the next beacon if future collision is detected
+ Time nextBeaconShift = m_peerManager->GetNextBeaconShift(GetAddress(), myNextTBTT);
+
+ m_beaconFormEvent = Simulator::Schedule (m_beaconInterval-m_beaconFormingRandomDelay+last_software_delay+nextBeaconShift, &MeshWifiMac::SendOneBeacon, this);
+}
+
+void
+MeshWifiMac::QueueOneBeacon (MgtMeshBeaconHeader beacon_hdr)
+{
+ WifiMacHeader hdr;
+ hdr.SetBeacon ();
+ hdr.SetAddr1 (Mac48Address::GetBroadcast ());
+ hdr.SetAddr2 (GetAddress ());
+ hdr.SetAddr3 (GetAddress ());
+ hdr.SetDsNotFrom ();
+ hdr.SetDsNotTo ();
+ Ptr<Packet> packet = Create<Packet> ();
+
+ packet->AddHeader (beacon_hdr);
+ m_beaconDca->Queue(packet, hdr);
+ m_peerManager->SetSentBeaconTimers(
+ GetAddress(),
+ Simulator::Now (),
+ MicroSeconds(beacon_hdr.GetBeaconIntervalUs())
+ );
+
+}
+void
+MeshWifiMac::SetBeaconGeneration (bool enable)
+{
+ NS_LOG_FUNCTION (this << enable);
+ if (enable)
+ {
+ UniformVariable coefficient(0.0, m_randomStart.GetSeconds());
+ Time randomStart = Seconds(coefficient.GetValue());
+ // Beacons must be sent with a random delay,
+ // otherwise, they will all be broken
+ m_beaconFormEvent = Simulator::Schedule (randomStart, &MeshWifiMac::SendOneBeacon, this);
+ }
+ else
+ m_beaconFormEvent.Cancel ();
+}
+
+bool
+MeshWifiMac::GetBeaconGeneration (void) const
+{
+ return m_beaconFormEvent.IsRunning ();
+}
+
+void
+MeshWifiMac::TxOk (WifiMacHeader const &hdr)
+{
+}
+
+void
+MeshWifiMac::TxFailed (WifiMacHeader const &hdr)
+{
+}
+
+void
+MeshWifiMac::Receive (Ptr<Packet> packet, WifiMacHeader const *hdr)
+{
+ if (hdr->IsBeacon ())
+ {
+ MgtMeshBeaconHeader beacon;
+ Mac48Address from = hdr->GetAddr2();
+ packet->RemoveHeader (beacon);
+ NS_LOG_DEBUG("Beacon received from "<<hdr->GetAddr2()<<
+ " to "<<GetAddress()<<
+ " at "<<Simulator::Now ().GetMicroSeconds ()<<
+ " microseconds");
+#if 0
+ NeighboursTimingUnitsList neighbours;
+ neighbours = beacon.GetWifiBeaconTimingElement().GetNeighboursTimingElementsList();
+ for(NeighboursTimingUnitsList::const_iterator j = neighbours.begin(); j!= neighbours.end(); j++)
+ fprintf(
+ stderr,
+ "neigbours:\nAID=%u, last_beacon=%u ,beacon_interval=%u\n",
+ (*j)->GetAID(),
+ (*j)->GetLastBeacon(),
+ (*j)->GetBeaconInterval()
+ );
+#endif
+ m_peerManager->SetReceivedBeaconTimers(
+ GetAddress(),
+ from,
+ Simulator::Now (),
+ MicroSeconds(beacon.GetBeaconIntervalUs()),
+ beacon.GetWifiBeaconTimingElement()
+ );
+ if(!beacon.GetSsid().IsEqual(GetSsid()))
+ return;
+ SupportedRates rates = beacon.GetSupportedRates ();
+ WifiRemoteStation *peerSta = m_stationManager->Lookup (hdr->GetAddr2 ());
+ for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
+ {
+ WifiMode mode = m_phy->GetMode (i);
+ if (rates.IsSupportedRate (mode.GetDataRate ()))
+ {
+ peerSta->AddSupportedMode (mode);
+ if (rates.IsBasicRate (mode.GetDataRate ()))
+ {
+ m_stationManager->AddBasicMode (mode);
+ }
+ }
+ }
+ // TODO:Chack MeshConfigurationElement(now is nothing
+ // to be checked)
+ m_peerManager->AskIfOpenNeeded(GetAddress(), from);
+ return;
+ }
+ if(hdr->IsMultihopAction())
+ {
+ WifiMeshHeader meshHdr;
+ //no mesh header parameters are needed here:
+ //TODO: check TTL
+ packet->RemoveHeader(meshHdr);
+ WifiMeshMultihopActionHeader multihopHdr;
+ //parse multihop action header:
+ packet->RemoveHeader(multihopHdr);
+ WifiMeshMultihopActionHeader::ACTION_VALUE
+ actionValue = multihopHdr.GetAction();
+ switch(multihopHdr.GetCategory())
+ {
+ case WifiMeshMultihopActionHeader::MESH_PEER_LINK_MGT:
+ {
+ Mac48Address peerAddress;
+ MeshMgtPeerLinkManFrame peer_frame;
+ if(hdr->GetAddr1 () != GetAddress ())
+ return;
+ peerAddress = hdr->GetAddr2();
+ packet->RemoveHeader (peer_frame);
+ if(actionValue.peerLink != WifiMeshMultihopActionHeader::PEER_LINK_CLOSE)
+ {
+ //check Supported Rates
+ SupportedRates rates = peer_frame.GetSupportedRates();
+ for (uint32_t i = 0; i < m_stationManager->GetNBasicModes (); i++)
+ {
+ WifiMode mode = m_stationManager->GetBasicMode (i);
+ if (!rates.IsSupportedRate (mode.GetDataRate ()))
+ {
+ m_peerManager->ConfigurationMismatch(GetAddress(), peerAddress);
+ return;
+ }
+ }
+ //Check SSID
+ if(!peer_frame.GetMeshId().IsEqual(GetSsid()))
+ {
+ m_peerManager->ConfigurationMismatch(GetAddress(), peerAddress);
+ return;
+ }
+ }
+ switch(actionValue.peerLink)
+ {
+ case WifiMeshMultihopActionHeader::PEER_LINK_CONFIRM:
+ m_peerManager->SetConfirmReceived(
+ GetAddress(),
+ peerAddress,
+ peer_frame.GetAid(),
+ peer_frame.GetPeerLinkManagementElement(),
+ m_meshConfig
+ );
+ return;
+ case WifiMeshMultihopActionHeader::PEER_LINK_OPEN:
+ m_peerManager->SetOpenReceived(
+ GetAddress(),
+ peerAddress,
+ peer_frame.GetPeerLinkManagementElement(),
+ m_meshConfig
+ );
+ return;
+ case WifiMeshMultihopActionHeader::PEER_LINK_CLOSE:
+ m_peerManager->SetCloseReceived(
+ GetAddress(),
+ peerAddress,
+ peer_frame.GetPeerLinkManagementElement()
+ );
+ return;
+ default:
+ return;
+ }
+ break;
+ }
+ case WifiMeshMultihopActionHeader::MESH_PATH_SELECTION:
+ {
+ if(!m_peerManager->IsActiveLink(GetAddress(), hdr->GetAddr2()))
+ return;
+ switch(actionValue.pathSelection)
+ {
+ case WifiMeshMultihopActionHeader::PATH_REQUEST:
+ {
+ WifiPreqInformationElement preq;
+ packet->RemoveHeader(preq);
+ //TODO:recalculate
+ //metric
+ m_preqReceived(preq, hdr->GetAddr2(), CalculateMetric(hdr->GetAddr2()));
+ return;
+ }
+ case WifiMeshMultihopActionHeader::PATH_REPLY:
+ {
+ WifiPrepInformationElement prep;
+ packet->RemoveHeader(prep);
+ m_prepReceived(prep, hdr->GetAddr2(), CalculateMetric(hdr->GetAddr2()));
+ }
+ return;
+ case WifiMeshMultihopActionHeader::PATH_ERROR:
+ {
+ WifiPerrInformationElement perr;
+ packet->RemoveHeader(perr);
+ m_perrReceived(perr, hdr->GetAddr2());
+ }
+ return;
+ case WifiMeshMultihopActionHeader::ROOT_ANNOUNCEMENT:
+ return;
+ }
+ }
+ default:
+ break;
+ }
+ }
+ if(hdr->IsData())
+ {
+ NS_ASSERT((hdr->IsFromDs()) && (hdr->IsToDs()));
+ NS_ASSERT(hdr->GetAddr4()!=Mac48Address::GetBroadcast());
+ //check seqno
+ WifiMeshHeader meshHdr;
+ packet->RemoveHeader(meshHdr);
+ NS_LOG_DEBUG(
+ "DATA TA="<< hdr->GetAddr2()<<
+ ", da="<<hdr->GetAddr3()<<
+ ", sa="<<hdr->GetAddr4()<<
+ ", TTL="<<(int)meshHdr.GetMeshTtl());
+ HwmpTag tag;
+ //mesh header is present within DATA and multihop action frames, so it must be done within MAC
+ tag.SetSeqno(meshHdr.GetMeshSeqno());
+ tag.SetAddress(hdr->GetAddr2());
+ tag.SetTtl(meshHdr.GetMeshTtl());
+ //metric should be later
+ packet->RemoveAllTags();
+ packet->AddTag(tag);
+ if(m_peerManager->IsActiveLink(GetAddress(), hdr->GetAddr2()))
+ ForwardUp(packet, hdr->GetAddr4(), hdr->GetAddr3());
+ }
+}
+
+Time
+MeshWifiMac::CalcSwDelay()
+{
+ UniformVariable coefficient(0.0, m_softwareDelay.GetSeconds());
+ Time delay = Seconds(coefficient.GetValue());
+ if(delay.GetSeconds() + Simulator::Now().GetSeconds() < m_lastMgtFrame.GetSeconds())
+ delay = Seconds(m_lastMgtFrame.GetSeconds() - Simulator::Now().GetSeconds());
+ m_lastMgtFrame = Seconds(Simulator::Now().GetSeconds()+delay.GetSeconds());
+ NS_ASSERT(delay.GetSeconds() >= 0);
+ return delay;
+}
+
+void
+MeshWifiMac::SendPeerLinkOpen(PeerLinkManagementElement peer_element, Mac48Address peerAddress)
+{
+ MeshMgtPeerLinkManFrame open;
+ open.SetOpen();
+ open.SetMeshConfigurationElement(m_meshConfig);
+ open.SetPeerLinkManagementElement(peer_element);
+ Simulator::Schedule(CalcSwDelay() ,&MeshWifiMac::QueuePeerLinkFrame, this, open, peerAddress);
+}
+
+void
+MeshWifiMac::SendPeerLinkConfirm(PeerLinkManagementElement peer_element, Mac48Address peerAddress, uint16_t aid)
+{
+ MeshMgtPeerLinkManFrame confirm;
+ confirm.SetConfirm();
+ confirm.SetMeshConfigurationElement(m_meshConfig);
+ confirm.SetPeerLinkManagementElement(peer_element);
+ confirm.SetAid(aid);
+ Simulator::Schedule(CalcSwDelay() ,&MeshWifiMac::QueuePeerLinkFrame, this, confirm, peerAddress);
+
+}
+
+void
+MeshWifiMac::SendPeerLinkClose(PeerLinkManagementElement peer_element, Mac48Address peerAddress)
+{
+ MeshMgtPeerLinkManFrame close;
+ close.SetClose();
+ close.SetMeshConfigurationElement(m_meshConfig);
+ close.SetPeerLinkManagementElement(peer_element);
+ Simulator::Schedule(CalcSwDelay() ,&MeshWifiMac::QueuePeerLinkFrame, this, close, peerAddress);
+
+}
+
+void
+MeshWifiMac::PeerLinkStatus(Mac48Address peerAddress, bool status)
+{
+ //pass information to HwmpState
+ m_peerStatusCallback(peerAddress, status, CalculateMetric(peerAddress));
+}
+void
+MeshWifiMac::QueuePeerLinkFrame(MeshMgtPeerLinkManFrame peer_frame, Mac48Address peerAddress)
+{
+ Ptr<Packet> packet = Create<Packet> ();
+ //Setting peer frame:
+ peer_frame.SetSupportedRates(GetSupportedRates ());
+ peer_frame.SetQosField(0);
+ peer_frame.SetMeshId(GetSsid());
+ packet->AddHeader (peer_frame);
+ //multihop header:
+ WifiMeshMultihopActionHeader multihopHdr;
+ if(peer_frame.IsOpen())
+ {
+ WifiMeshMultihopActionHeader::ACTION_VALUE action;
+ action.peerLink = WifiMeshMultihopActionHeader::PEER_LINK_OPEN;
+ multihopHdr.SetAction(WifiMeshMultihopActionHeader::MESH_PEER_LINK_MGT, action);
+ }
+ if(peer_frame.IsConfirm())
+ {
+ WifiMeshMultihopActionHeader::ACTION_VALUE action;
+ action.peerLink = WifiMeshMultihopActionHeader::PEER_LINK_CONFIRM;
+ multihopHdr.SetAction(WifiMeshMultihopActionHeader::MESH_PEER_LINK_MGT, action);
+ }
+ if(peer_frame.IsClose())
+ {
+ WifiMeshMultihopActionHeader::ACTION_VALUE action;
+ action.peerLink = WifiMeshMultihopActionHeader::PEER_LINK_CLOSE;
+ multihopHdr.SetAction(WifiMeshMultihopActionHeader::MESH_PEER_LINK_MGT, action);
+ }
+ packet->AddHeader(multihopHdr);
+ //mesh header:
+ WifiMeshHeader meshHdr;
+ meshHdr.SetMeshTtl(1);
+ meshHdr.SetMeshSeqno(0);
+ packet->AddHeader(meshHdr);
+ //Wifi Mac header:
+ WifiMacHeader hdr;
+ hdr.SetMultihopAction();
+ hdr.SetAddr1 (peerAddress);
+ hdr.SetAddr2 (GetAddress ());
+ hdr.SetAddr3 (GetAddress ());
+ hdr.SetDsNotFrom ();
+ hdr.SetDsNotTo ();
+ //queue:
+ m_VO->Queue(packet,hdr);
+}
+
+void
+MeshWifiMac::SetSoftwareDelay(Time delay)
+{
+ m_softwareDelay = delay;
+}
+
+Time
+MeshWifiMac::GetSoftwareDelay()
+{
+ return m_softwareDelay;
+}
+
+void
+MeshWifiMac::SendPreq(const WifiPreqInformationElement& preq)
+{
+ //Add a PREQ
+ Ptr<Packet> packet = Create<Packet> ();
+ packet->AddHeader(preq);
+ //Add a Action values:
+ WifiMeshMultihopActionHeader multihopHdr;
+ WifiMeshMultihopActionHeader::ACTION_VALUE action;
+ action.pathSelection = WifiMeshMultihopActionHeader::PATH_REQUEST;
+ multihopHdr.SetAction(WifiMeshMultihopActionHeader::MESH_PATH_SELECTION, action);
+ packet->AddHeader(multihopHdr);
+ //Add a mesh Header
+ WifiMeshHeader meshHdr;
+ //TODO: normal seqno!
+ meshHdr.SetMeshTtl(1);
+ meshHdr.SetMeshSeqno(0);
+ packet->AddHeader(meshHdr);
+ //Add a wifi header:
+ WifiMacHeader hdr;
+ hdr.SetMultihopAction();
+ hdr.SetAddr1 (Mac48Address::GetBroadcast ());
+ hdr.SetAddr2 (GetAddress ());
+ hdr.SetAddr3 (Mac48Address("00:00:00:00:00:00"));
+ hdr.SetDsNotFrom ();
+ hdr.SetDsNotTo ();
+ Simulator::Schedule(CalcSwDelay() ,&MeshWifiMac::QueuePathSelectionFrame, this, packet, hdr);
+ //m_VO->Queue(packet,hdr);
+
+}
+
+void
+MeshWifiMac::SendPrep(const WifiPrepInformationElement& prep, const Mac48Address& to)
+{
+ if(!m_peerManager->IsActiveLink(GetAddress(), to))
+ return;
+ Ptr<Packet> packet = Create<Packet> ();
+ packet->AddHeader(prep);
+ //Add a Action values:
+ WifiMeshMultihopActionHeader multihopHdr;
+ WifiMeshMultihopActionHeader::ACTION_VALUE action;
+ action.pathSelection = WifiMeshMultihopActionHeader::PATH_REPLY;
+ multihopHdr.SetAction(WifiMeshMultihopActionHeader::MESH_PATH_SELECTION, action);
+ packet->AddHeader(multihopHdr);
+ //Add a mesh Header
+ WifiMeshHeader meshHdr;
+ //TODO: normal seqno!
+ meshHdr.SetMeshTtl(1);
+ meshHdr.SetMeshSeqno(0);
+ packet->AddHeader(meshHdr);
+ //Add a wifi header:
+ WifiMacHeader hdr;
+ hdr.SetMultihopAction();
+ hdr.SetDsNotTo();
+ hdr.SetDsNotFrom();
+ hdr.SetAddr1(to);
+ hdr.SetAddr2(GetAddress());
+ hdr.SetAddr3(Mac48Address("00:00:00:00:00:00"));
+ //m_VO->Queue(packet,hdr);
+ Simulator::Schedule(CalcSwDelay() ,&MeshWifiMac::QueuePathSelectionFrame, this, packet, hdr);
+}
+
+void
+MeshWifiMac::SendPerr(const WifiPerrInformationElement& perr, std::vector<Mac48Address> receivers)
+{
+ NS_ASSERT(receivers.size()!=0);
+ Ptr<Packet> packet = Create<Packet> ();
+ packet->AddHeader(perr);
+ //Add a Action values:
+ WifiMeshMultihopActionHeader multihopHdr;
+ WifiMeshMultihopActionHeader::ACTION_VALUE action;
+ action.pathSelection = WifiMeshMultihopActionHeader::PATH_ERROR;
+ multihopHdr.SetAction(WifiMeshMultihopActionHeader::MESH_PATH_SELECTION, action);
+ packet->AddHeader(multihopHdr);
+ //Add a mesh Header
+ WifiMeshHeader meshHdr;
+ //TODO: normal seqno!
+ meshHdr.SetMeshTtl(1);
+ meshHdr.SetMeshSeqno(0);
+ packet->AddHeader(meshHdr);
+ //Add a wifi header:
+ WifiMacHeader hdr;
+ hdr.SetMultihopAction();
+ hdr.SetDsNotTo();
+ hdr.SetDsNotFrom();
+ hdr.SetAddr2(GetAddress());
+ hdr.SetAddr3(Mac48Address("00:00:00:00:00:00"));
+ //m_VO->Queue(packet,hdr);
+ for(unsigned int i = 0; i < receivers.size(); i ++)
+ {
+ NS_LOG_DEBUG(GetAddress()<<" is sending PERR to "<<receivers[i]);
+ hdr.SetAddr1(receivers[i]);
+ Simulator::Schedule(CalcSwDelay() ,&MeshWifiMac::QueuePathSelectionFrame, this, packet, hdr);
+ }
+}
+void
+MeshWifiMac::QueuePathSelectionFrame(Ptr<Packet> packet, const WifiMacHeader hdr)
+{
+ m_VO->Queue(packet, hdr);
+}
+void
+MeshWifiMac::SetPreqReceivedCallback(
+ Callback<void, WifiPreqInformationElement&, const Mac48Address&, const uint32_t&> cb)
+{
+ m_preqReceived = cb;
+}
+
+void
+MeshWifiMac::SetPrepReceivedCallback(
+ Callback<void, WifiPrepInformationElement&, const Mac48Address&, const uint32_t&> cb)
+{
+ m_prepReceived = cb;
+}
+
+void
+MeshWifiMac::SetPerrReceivedCallback(
+ Callback<void, WifiPerrInformationElement&, const Mac48Address&> cb)
+{
+ m_perrReceived = cb;
+}
+
+void
+MeshWifiMac::SetPeerStatusCallback(
+ Callback<void, Mac48Address, bool, uint32_t> cb)
+{
+ m_peerStatusCallback = cb;
+}
+
+uint32_t
+MeshWifiMac::CalculateMetric(Mac48Address peerAddress)
+{
+ //suppose Bt == 1000 bytes;
+ uint32_t testLength = 1000;
+ WifiRemoteStation *peerSta = m_stationManager->Lookup (peerAddress);
+ WifiTxStatistics::RATE_LENGTH_STAT stats = peerSta->GetTxStat().statistics;
+ Time overhead = m_sifs + MicroSeconds(32) + MicroSeconds(8);
+ uint32_t metric = (uint32_t)((double)overhead.GetNanoSeconds()/102.4);
+ uint32_t maxRate = 0;
+ uint32_t packet_sent = 0;
+ for(WifiTxStatistics::RATE_LENGTH_STAT::iterator lengthPos = stats.begin(); lengthPos !=stats.end(); lengthPos++)
+ {
+ if(lengthPos->first > testLength)
+ continue;
+ for(
+ WifiTxStatistics::RATE_STAT::iterator ratePos = lengthPos->second.begin();
+ ratePos != lengthPos->second.end();
+ ratePos ++
+ )
+ {
+#if 0
+ NS_LOG_DEBUG("Rate is "<<ratePos->first
+ <<": SUCCESS = "<<ratePos->second.packetsAcked
+ <<", RRETRY = " <<ratePos->second.packetsRetried
+ <<", FAILURE = "<<ratePos->second.packetsFailed);
+#endif
+ double coefficient =
+ (double)(
+ ratePos->second.packetsRetried
+ + ratePos->second.packetsAcked
+ )/((double)ratePos->second.packetsAcked);
+ uint16_t avgLength = 0;
+ if(ratePos->second.packetsAcked == 0)
+ avgLength = lengthPos->first;
+ else
+ avgLength = ratePos->second.bytesAcked/ratePos->second.packetsAcked;
+ uint32_t payload = (uint32_t)((double)avgLength / ((double)ratePos->first)*1e9);
+ if(packet_sent < ratePos->second.packetsAcked)
+ {
+ metric = (uint32_t)(coefficient*((double)overhead.GetNanoSeconds() + (double)payload)/10240);
+ packet_sent = ratePos->second.packetsAcked;
+ maxRate = ratePos->first;
+ }
+ }
+ }
+
+ //NS_LOG_DEBUG("RATE is "<<maxRate<<" metric is "<<metric);
+ //peerSta->ResetTxStat();
+ NS_ASSERT(metric !=0);
+ return metric;
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/mesh-wifi-mac.h Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,399 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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
+ *
+ * Authors: Kirill Andreev <andreev@iitp.ru>
+ * Evgeny Khorov <horov@frtk.ru>
+ */
+
+
+#ifndef MAC_HIGH_MESH_H
+#define MAC_HIGH_MESH_H
+
+#include <stdint.h>
+#include <map>
+#include "ns3/mac48-address.h"
+#include "mgt-headers.h"
+#include "mesh-mgt-headers.h"
+#include "ns3/callback.h"
+#include "ns3/packet.h"
+#include "ns3/nstime.h"
+#include "mesh-wifi-beacon-timing-element.h"
+#include "wifi-remote-station-manager.h"
+#include "mesh-wifi-peer-manager.h"
+#include "wifi-mac.h"
+
+namespace ns3 {
+
+ class WifiMacHeader;
+ class DcaTxop;
+ class WifiPhy;
+ class DcfManager;
+ class MacRxMiddle;
+ class MacLow;
+ class WifiPeerManager;
+ /**
+ * \brief Implements MAC-layer of mesh point: beaconing and
+ * peer link management.
+ *
+ * \details Handles sending and receiving beacons. Tells all
+ * needed information about beacons to MeshWifiPeerManager class, which
+ * handles peer link management state machine. Asks
+ * WifiPeerManager wether
+ * receive or discard frame obtained from neighbour.
+ * Now only three output queues are used:
+ * one for beacons (PIFS and no backoff),
+ * one for background traffic,
+ * one for management and priority traffic.
+ */
+ class MeshWifiMac : public WifiMac
+ {
+ public:
+ static TypeId GetTypeId (void);
+
+ MeshWifiMac ();
+ ~MeshWifiMac ();
+ // inherited from WifiMac.
+ virtual void SetSlot (Time slotTime);
+ virtual void SetSifs (Time sifs);
+ virtual void SetPifs (Time pifs);
+ virtual void SetCtsTimeout (Time ctsTimeout);
+ virtual void SetAckTimeout (Time ackTimeout);
+ virtual void SetEifsNoDifs (Time eifsNoDifs);
+ virtual Time GetSlot (void) const;
+ virtual Time GetSifs (void) const;
+ virtual Time GetPifs (void) const;
+ virtual Time GetCtsTimeout (void) const;
+ virtual Time GetAckTimeout (void) const;
+ virtual Time GetEifsNoDifs (void) const;
+ virtual void SetWifiPhy (Ptr<WifiPhy> phy);
+ virtual void SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager);
+ virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to, Mac48Address from);
+ virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to);
+ virtual bool SupportsSendFrom (void) const;
+ virtual void SetForwardUpCallback (Callback<void,Ptr<Packet>, Mac48Address, Mac48Address> upCallback);
+ virtual void SetLinkUpCallback (Callback<void> linkUp);
+ virtual void SetLinkDownCallback (Callback<void> linkDown);
+ virtual Mac48Address GetAddress (void) const;
+ virtual Mac48Address GetBssid (void) const;
+ virtual Ssid GetSsid (void) const;
+ virtual void SetAddress (Mac48Address address);
+ virtual void SetSsid (Ssid ssid);
+ /**
+ * \param interval is an interval between two
+ * successive beacons
+ */
+ void SetBeaconInterval (Time interval);
+ /**
+ * \returns interval between two beacons
+ */
+ Time GetBeaconInterval (void) const;
+ /**
+ * \param delay is the maximum software delay.
+ *
+ * \details Software delay is calculated as uniformely
+ * distributed random value between zero and
+ * given parameter.
+ *
+ * All management frames are sent after software delay is passed,
+ * for example, beacon is formed at software
+ * delay before putting it to the queue.
+ *
+ * \attention The software delay is supposed
+ * to be independent from traffic intensity.
+ *
+ */
+ void SetSoftwareDelay(Time delay);
+ /**
+ * \returns software delay parameter
+ */
+ Time GetSoftwareDelay();
+ /**
+ * \param manager is pointer to the
+ * WifiPeerManager class, which implements
+ * peer-link management state machine.
+ *
+ * \details The purpose of peer manager is
+ * obtaining all needed information from
+ * beacons and send peer link management
+ * frames.
+ *
+ * This funcion sets all needed callbacks to
+ * a given peer manager
+ */
+ void SetPeerLinkManager(Ptr<WifiPeerManager> manager);
+ virtual void SetPreqReceivedCallback(
+ Callback<void, WifiPreqInformationElement&, const Mac48Address&, const uint32_t&> cb);
+ /**
+ * \brief this callback is set by Hwmp routing
+ * protocol and executed when MAC has received
+ * PREP.
+ * \param cb is a callback to be executed when
+ * receiving PREP.
+ */
+ virtual void SetPrepReceivedCallback(
+ Callback<void, WifiPrepInformationElement&, const Mac48Address&, const uint32_t&> cb);
+ /**
+ * \brief this callback is set by Hwmp routing
+ * protocol and executed when MAC has received
+ * PERR.
+ * \param cb is a callback to be executed when
+ * receiving PERR.
+ */
+ virtual void SetPerrReceivedCallback(
+ Callback<void, WifiPerrInformationElement&, const Mac48Address&> cb);
+
+ /**
+ * \brief this callback is set by Hwmp routing
+ * protocol and executed when MAC has detected
+ * the peer link failure
+ * \param cb is a callback to be executed when
+ * peer failure has ben detected
+ */
+ virtual void SetPeerStatusCallback(
+ Callback<void, Mac48Address, bool, uint32_t> cb);
+ /**
+ * \brief Sends a PREQ frame.
+ * \param preq is preq information element
+ * formed by protocol. This function just adds
+ * a proper WifiMacHeader
+ * \attention This method is public, because
+ * HWMP makes a callback using this method
+ */
+ virtual void SendPreq(const WifiPreqInformationElement& preq);
+ /**
+ * \brief Sends a PREP frame.
+ * \param prep is prep information element
+ * formed by protocol. This function just adds
+ * a proper WifiMacHeader
+ * \param to is an address of retransmitter of
+ * the prep
+ * \attention This method is public, because
+ * HWMP makes a callback using this method
+ */
+
+ virtual void SendPrep(const WifiPrepInformationElement& prep, const Mac48Address& to);
+ /**
+ * \brief Sends a PERR frame.
+ * \param perr is perr information element
+ * formed by protocol. This function just adds
+ * a proper WifiMacHeader.
+ * \param receivers is list of addresses where
+ * to send PERR (unicast PERR case)
+ * \attention This method is public, because
+ * HWMP makes a callback using this method
+ */
+ virtual void SendPerr(const WifiPerrInformationElement& perr, std::vector<Mac48Address> receivers);
+ /**
+ * \brief Sends PeerLinkOpen frame to a given
+ * address. Mac only forms a proper
+ * WifiMacHeader.
+ * \param peer_element is peer link frame to
+ * be sent
+ * \param peerAddress is the address of
+ * destination of given frame
+ */
+ void SendPeerLinkOpen(
+ PeerLinkManagementElement peer_element,
+ Mac48Address peerAddress
+ );
+ /**
+ * \brief Sends PeerLinkConfirm frame to a given
+ * address. Mac only forms a proper
+ * WifiMacHeader.
+ * \param peer_element is peer link frame to
+ * be sent
+ * \param peerAddress is the address of
+ * destination of given frame
+ * \param aid is the assocciation ID stored in
+ * peer manager
+ */
+ void SendPeerLinkConfirm(
+ PeerLinkManagementElement peer_element,
+ Mac48Address peerAddress,
+ uint16_t aid
+ );
+ /**
+ * \brief Sends PeerLinkClose frame to a given
+ * address. Mac only forms a proper
+ * WifiMacHeader.
+ * \param peer_element is peer link frame to
+ * be sent
+ * \param peerAddress is the address of
+ * destination of given frame
+ */
+ void SendPeerLinkClose(
+ PeerLinkManagementElement peer_element,
+ Mac48Address peerAddress
+ );
+ /**
+ * \brief this method is executed by peer
+ * manager when peer link opened or closed
+ * \param status true when link was opened,
+ * false if link was closed
+ * \param peerAddress is the address of
+ * destination of given frame
+ */
+ virtual void PeerLinkStatus(Mac48Address peerAddress, bool status);
+
+ /**
+ * \brief Peer Manager notifyes MAC about new
+ * peer link or peer link failure.
+ * \details This method should pass this event
+ * to HWMP, and it should generate new routing
+ * information or should generate Path Error
+ * \param peerAddress it the address of
+ * neighbour
+ * \param status If true - new peer link, perr
+ * link failure otherwise
+ */
+ void PeerEvent(
+ Mac48Address peerAddress,
+ bool status
+ );
+ private:
+ void Receive (Ptr<Packet> packet, WifiMacHeader const *hdr);
+ virtual void ForwardUp (Ptr<Packet> packet, Mac48Address src, Mac48Address dst);
+ void ForwardDown(
+ Ptr<const Packet> packet,
+ Mac48Address from,
+ Mac48Address to
+ );
+ void TxOk (WifiMacHeader const &hdr);
+ void TxFailed (WifiMacHeader const &hdr);
+ /**
+ * \brief At the software delay before TBTT
+ * SendOneBeacon is ececuted. It forms a
+ * beacon frame body. Then calculates software
+ * delay and schedules QueueOneBeacon
+ */
+ void SendOneBeacon (void);
+ /**
+ * \brief Puts a formed beacon to the output
+ * queue. SendOneBeacon forms a beacon and
+ * after software delay QueueOneBeacon is
+ * executed
+ * \param beacon_hdr is beacon to be queued
+ */
+ void QueueOneBeacon (MgtMeshBeaconHeader beacon_hdr);
+ /**
+ * \brief Executed after software delay by
+ * SendPeerLinkOpen/Confirm/Close frames and
+ * puts this frame to the output queue.
+ * \param peer_frame peer link management
+ * frame
+ * \param peerAddress the address of
+ * destination.
+ */
+ void QueuePeerLinkFrame(MeshMgtPeerLinkManFrame peer_frame, Mac48Address peerAddress);
+ /**
+ * \brief Executed after software delay by
+ * SendPreq/Prep/Perr frames and
+ * puts this frame to the output queue.
+ * \param packet is packet body,
+ * \param hdr is WifiMacHeader
+ */
+ void QueuePathSelectionFrame(Ptr<Packet> packet, const WifiMacHeader hdr);
+ void SetBeaconGeneration (bool enable);
+ bool GetBeaconGeneration (void) const;
+ SupportedRates GetSupportedRates (void) const;
+ virtual void DoDispose (void);
+
+ Ptr<DcaTxop> m_BE;
+ Ptr<DcaTxop> m_BK;
+ Ptr<DcaTxop> m_VI;
+ Ptr<DcaTxop> m_VO;
+ Ptr<DcaTxop> m_beaconDca;
+ Ptr<WifiRemoteStationManager> m_stationManager;
+ Ptr<WifiPhy> m_phy;
+ Callback<void,Ptr<Packet>, Mac48Address, Mac48Address>
+ m_upCallback;
+ Time m_beaconInterval;
+ Time m_randomStart;
+
+ DcfManager * m_dcfManager;
+ MacRxMiddle * m_rxMiddle;
+ Ptr<MacLow> m_low;
+ Mac48Address m_address;
+ Ssid m_MeshId;
+ EventId m_beaconFormEvent;
+ EventId m_beaconSendEvent;
+ Time m_slot;
+ Time m_sifs;
+ Time m_pifs;
+ Time m_ackTimeout;
+ Time m_ctsTimeout;
+
+ Time m_eifsNoDifs;
+ MeshConfigurationElement m_meshConfig; //Stores my configuration;
+ //Peer Descriptor pointer:
+ Ptr<WifiPeerManager> m_peerManager;
+ Time m_softwareDelay;
+ /**
+ * \attention Software delay is used for management
+ * frames, so, if this delay is calculated
+ * independenly, the packet order may be
+ * broken, so the last mgt frame sending time
+ * should be keeped within MAC
+ */
+ Time m_lastMgtFrame;
+ /**
+ * \returns the value of software delay
+ * uniformely distributed between 0 and
+ * m_softwareDealy (initiated by
+ * SetSoftwareDelay method).
+ */
+ Time CalcSwDelay();
+ /**
+ * \brief keeps delay for sending first
+ * beacon. this delay is uniformely
+ * distributed between 0 and given value
+ */
+ Time m_beaconFormingRandomDelay;
+ Callback<void, WifiPreqInformationElement&, const Mac48Address&, const uint32_t&>
+ m_preqReceived;
+ Callback<void, WifiPrepInformationElement&, const Mac48Address&, const uint32_t&>
+ m_prepReceived;
+ Callback<void, WifiPerrInformationElement&, const Mac48Address&>
+ m_perrReceived;
+ Callback<void, Mac48Address, bool, uint32_t>
+ m_peerStatusCallback;
+ /**
+ * \brief metric calculation parameters
+ */
+ uint32_t CalculateMetric(Mac48Address peerAddress);
+ struct addrcmp
+ {
+ bool operator()(const Mac48Address addr1, Mac48Address addr2) const
+ {
+ uint8_t s1[6], s2[6];
+ addr1.CopyTo(s1);
+ addr2.CopyTo(s2);
+ for(int i = 0; i < 6; i ++)
+ if(s1[i] > s2[i])
+ return true;
+ return false;
+ }
+ };
+
+ std::map<Mac48Address, uint32_t, addrcmp>
+ m_metricDatabase;
+ };
+
+} // namespace ns3
+
+
+#endif /* MAC_HIGH_MESH_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/mesh-wifi-peer-manager.cc Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,987 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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
+ *
+ * Authors: Kirill Andreev <andreev@iitp.ru>
+ * Aleksey Kovalenko <kovalenko@iitp.ru>
+ * Ivan Pustogarov <chinsa1@rambler.ru>
+ * Evgeny Khorov <horov@frtk.ru>
+ */
+
+
+#include "mesh-wifi-peer-manager.h"
+#include "dot11s-parameters.h"
+#include "ns3/simulator.h"
+#include "ns3/assert.h"
+#include "ns3/log.h"
+#include "ns3/random-variable.h"
+NS_LOG_COMPONENT_DEFINE ("WifiPeerManager");
+namespace ns3 {
+/***************************************************
+ * PeerLinkDescriptor
+ ***************************************************/
+WifiPeerLinkDescriptor::WifiPeerLinkDescriptor():
+ m_localLinkId(0),
+ m_peerLinkId(0),
+ m_state(IDLE),
+ m_retryCounter(0),
+ m_maxBeaconLoss(3)
+{}
+
+ void
+WifiPeerLinkDescriptor::SetPeerAddress(Mac48Address macaddr)
+{
+ m_peerAddress = macaddr;
+}
+
+ void
+WifiPeerLinkDescriptor::SetLocalAddress(Mac48Address macaddr)
+{
+ m_localAddress = macaddr;
+}
+
+ void
+WifiPeerLinkDescriptor::SetLocalLinkId(uint16_t id)
+{
+ m_localLinkId = id;
+}
+ void
+WifiPeerLinkDescriptor::SetLocalAid(uint16_t aid)
+{
+ m_assocId = aid;
+}
+ void
+WifiPeerLinkDescriptor::SetBeaconInformation(Time lastBeacon, Time beaconInterval)
+{
+ m_lastBeacon = lastBeacon;
+ m_beaconInterval = beaconInterval;
+ m_beaconLossTimer.Cancel();
+ Time delay = Seconds(beaconInterval.GetSeconds()*m_maxBeaconLoss);
+ NS_ASSERT(delay.GetMicroSeconds()!= 0);
+ m_beaconLossTimer = Simulator::Schedule(delay, &WifiPeerLinkDescriptor::BeaconLoss, this);
+}
+
+ void
+WifiPeerLinkDescriptor::SetMaxBeaconLoss(uint8_t maxBeaconLoss)
+{
+ m_maxBeaconLoss = maxBeaconLoss;
+}
+
+ void
+WifiPeerLinkDescriptor::SetLinkStatusCallback(Callback<void, Mac48Address, Mac48Address, bool> cb)
+{
+ m_linkStatusCallback = cb;
+}
+ void
+WifiPeerLinkDescriptor::BeaconLoss()
+{
+ StateMachine(CNCL);
+}
+
+ void
+WifiPeerLinkDescriptor::SetBeaconTimingElement(WifiBeaconTimingElement beaconTiming)
+{
+ m_beaconTiming = beaconTiming;
+}
+
+Mac48Address
+WifiPeerLinkDescriptor::GetPeerAddress() const
+{
+ return m_peerAddress;
+}
+
+Mac48Address
+WifiPeerLinkDescriptor::GetLocalAddress() const
+{
+ return m_localAddress;
+}
+
+
+uint16_t
+WifiPeerLinkDescriptor::GetLocalAid()const
+{
+ return m_assocId;
+}
+
+Time
+WifiPeerLinkDescriptor::GetLastBeacon() const
+{
+ return m_lastBeacon;
+}
+
+Time
+WifiPeerLinkDescriptor::GetBeaconInterval() const
+{
+ return m_beaconInterval;
+}
+WifiBeaconTimingElement
+WifiPeerLinkDescriptor::GetBeaconTimingElement() const
+{
+ return m_beaconTiming;
+}
+
+ void
+WifiPeerLinkDescriptor::ClearTimingElement()
+{
+ m_beaconTiming.ClearTimingElement();
+}
+
+
+void WifiPeerLinkDescriptor::MLMECancelPeerLink(dot11sReasonCode reason)
+{
+ StateMachine(CNCL,reason);
+}
+
+void WifiPeerLinkDescriptor::MLMEPassivePeerLinkOpen()
+{
+ StateMachine(PASOPN);
+}
+
+void WifiPeerLinkDescriptor::MLMEActivePeerLinkOpen()
+{
+ StateMachine(ACTOPN);
+}
+void WifiPeerLinkDescriptor::MLMEPeeringRequestReject()
+{
+ StateMachine(REQ_RJCT, PEER_LINK_CANCELLED);
+}
+#if 0
+void WifiPeerLinkDescriptor::MLMEBindSecurityAssociation()
+{
+ StateMachine(BNDSA);
+}
+#endif
+ void
+WifiPeerLinkDescriptor::SetMac(Ptr<MeshWifiMac> mac)
+{
+ m_mac = mac;
+}
+void WifiPeerLinkDescriptor::PeerLinkClose(uint16_t localLinkId,uint16_t peerLinkId, dot11sReasonCode reason)
+{
+ if( peerLinkId != 0 && m_localLinkId != peerLinkId)
+ return;
+ if( m_peerLinkId == 0)
+ m_peerLinkId = localLinkId;
+ else if ( m_peerLinkId != localLinkId )
+ return;
+ StateMachine(CLS_ACPT,reason);
+}
+
+void WifiPeerLinkDescriptor::PeerLinkOpenAccept(uint16_t localLinkId, MeshConfigurationElement conf)
+{
+ if( m_peerLinkId == 0)
+ m_peerLinkId = localLinkId;
+ m_configuration = conf;
+ StateMachine(OPN_ACPT);
+}
+
+void WifiPeerLinkDescriptor::PeerLinkOpenReject(uint16_t localLinkId, MeshConfigurationElement conf,dot11sReasonCode reason)
+{
+ if( m_peerLinkId == 0)
+ m_peerLinkId = localLinkId;
+ m_configuration = conf;
+ StateMachine(OPN_RJCT,reason);
+}
+
+ void
+WifiPeerLinkDescriptor::PeerLinkConfirmAccept(uint16_t localLinkId,uint16_t peerLinkId, uint16_t peerAid, MeshConfigurationElement conf)
+{
+ if( m_localLinkId != peerLinkId)
+ return;
+ if( m_peerLinkId == 0)
+ m_peerLinkId = localLinkId;
+ else if ( m_peerLinkId != localLinkId )
+ return;
+ m_configuration = conf;
+ m_peerAssocId = peerAid;
+ StateMachine(CNF_ACPT);
+}
+
+void WifiPeerLinkDescriptor:: PeerLinkConfirmReject(uint16_t localLinkId, uint16_t peerLinkId,
+ MeshConfigurationElement conf,dot11sReasonCode reason)
+{
+ if( m_localLinkId != peerLinkId)
+ return;
+ if( m_peerLinkId == 0)
+ m_peerLinkId = localLinkId;
+ else if ( m_peerLinkId != localLinkId )
+ return;
+ m_configuration = conf;
+ StateMachine(CNF_RJCT,reason);
+}
+
+bool
+WifiPeerLinkDescriptor::LinkIsEstab() const
+{
+ if(m_state == ESTAB)
+ return true;
+ return false;
+}
+
+bool
+WifiPeerLinkDescriptor::LinkIsIdle() const
+{
+ if(m_state == IDLE)
+ return true;
+ return false;
+}
+
+ void
+WifiPeerLinkDescriptor::StateMachine(PeerEvent event,dot11sReasonCode reasoncode)
+{
+ switch(m_state)
+ {
+ case IDLE:
+ switch(event)
+ {
+ case PASOPN:
+ m_state = LISTEN;
+ break;
+ case ACTOPN:
+ m_state = OPN_SNT;
+ SendPeerLinkOpen();
+ SetRetryTimer();
+ break;
+ default:{}
+ }
+ break;
+ case LISTEN:
+ switch(event)
+ {
+ case CNCL:
+ case CLS_ACPT:
+ m_state=IDLE;
+ // TODO Callback MLME-SignalPeerLinkStatus
+ break;
+ case REQ_RJCT:
+ SendPeerLinkClose(reasoncode);
+ break;
+ case ACTOPN:
+ m_state=OPN_SNT;
+ SendPeerLinkOpen();
+ SetRetryTimer();
+ break;
+ case OPN_ACPT:
+ m_state = OPN_RCVD;
+ SendPeerLinkConfirm();
+ SendPeerLinkOpen();
+ SetRetryTimer();
+ break;
+ default:{}
+ }
+ break;
+ case OPN_SNT:
+ switch(event)
+ {
+ case TOR1:
+ SendPeerLinkOpen();
+ m_retryCounter++;
+ SetRetryTimer();
+ break;
+ case CNF_ACPT:
+ m_state = CNF_RCVD;
+ ClearRetryTimer();
+ SetConfirmTimer();
+ break;
+ case OPN_ACPT:
+ m_state = OPN_RCVD;
+ SendPeerLinkConfirm();
+ break;
+ case CLS_ACPT:
+ m_state = HOLDING;
+ ClearRetryTimer();
+ SendPeerLinkClose(MESH_CLOSE_RCVD);
+ SetHoldingTimer();
+ break;
+ case OPN_RJCT:
+ case CNF_RJCT:
+ m_state = HOLDING;
+ ClearRetryTimer();
+ SendPeerLinkClose(reasoncode);
+ SetHoldingTimer();
+ break;
+ case TOR2:
+ m_state = HOLDING;
+ ClearRetryTimer();
+ SendPeerLinkClose(MESH_MAX_RETRIES);
+ SetHoldingTimer();
+ break;
+ case CNCL:
+ m_state = HOLDING;
+ ClearRetryTimer();
+ SendPeerLinkClose(PEER_LINK_CANCELLED);
+ SetHoldingTimer();
+ break;
+ default:{}
+ }
+ break;
+ case CNF_RCVD:
+ switch(event)
+ {
+ case CNF_ACPT:
+ break;
+ case OPN_ACPT:
+ m_state = ESTAB;
+NS_LOG_DEBUG("I am "<<m_localAddress<<", established link with "<<m_peerAddress<<", at "<<Simulator::Now());
+ ClearConfirmTimer();
+ SendPeerLinkConfirm();
+ m_linkStatusCallback(m_localAddress, m_peerAddress, true);
+ // TODO Callback MLME-SignalPeerLinkStatus
+ break;
+ case CLS_ACPT:
+ m_state = HOLDING;
+ ClearConfirmTimer();
+ SendPeerLinkClose(MESH_CLOSE_RCVD);
+ SetHoldingTimer();
+ break;
+ case CNF_RJCT:
+ case OPN_RJCT:
+ m_state = HOLDING;
+ ClearConfirmTimer();
+ SendPeerLinkClose(reasoncode);
+ SetHoldingTimer();
+ break;
+ case CNCL:
+ m_state = HOLDING;
+ ClearConfirmTimer();
+ SendPeerLinkClose(PEER_LINK_CANCELLED);
+ SetHoldingTimer();
+ break;
+ case TOC:
+ m_state = HOLDING;
+ SendPeerLinkClose(MESH_CONFIRM_TIMEOUT);
+ SetHoldingTimer();
+ break;
+ default:{}
+ }
+ break;
+ case OPN_RCVD:
+ switch(event)
+ {
+ case TOR1:
+ SendPeerLinkOpen();
+ m_retryCounter++;
+ SetRetryTimer();
+ break;
+ case CNF_ACPT:
+NS_LOG_DEBUG("I am "<<m_localAddress<<", established link with "<<m_peerAddress<<", at "<<Simulator::Now());
+ m_state = ESTAB;
+ ClearRetryTimer();
+ m_linkStatusCallback(m_localAddress, m_peerAddress, true);
+ // TODO Callback MLME-SignalPeerLinkStatus
+ break;
+ case CLS_ACPT:
+ m_state = HOLDING;
+ ClearRetryTimer();
+ SendPeerLinkClose(MESH_CLOSE_RCVD);
+ SetHoldingTimer();
+ break;
+ case OPN_RJCT:
+ case CNF_RJCT:
+ m_state = HOLDING;
+ ClearRetryTimer();
+ SendPeerLinkClose(reasoncode);
+ SetHoldingTimer();
+ break;
+ case TOR2:
+ m_state = HOLDING;
+ ClearRetryTimer();
+ SendPeerLinkClose(MESH_MAX_RETRIES);
+ SetHoldingTimer();
+ break;
+ case CNCL:
+ m_state = HOLDING;
+ ClearRetryTimer();
+ SendPeerLinkClose(PEER_LINK_CANCELLED);
+ SetHoldingTimer();
+ break;
+ default:{}
+ }
+ break;
+ case ESTAB:
+ switch(event)
+ {
+#if 0
+ case BNDSA:
+ m_state = ESTAB;
+ // TODO Callback MLME-SignalPeerLinkStatus
+ // TODO
+ break;
+#endif
+ case OPN_ACPT:
+ SendPeerLinkConfirm();
+ break;
+ case CLS_ACPT:
+NS_LOG_DEBUG("I am "<<m_localAddress<<", CLOSED link with "<<m_peerAddress<<", at "<<Simulator::Now()<<" Close received");
+ m_state = HOLDING;
+ SendPeerLinkClose(MESH_CLOSE_RCVD);
+ SetHoldingTimer();
+ m_linkStatusCallback(m_localAddress, m_peerAddress, false);
+ break;
+ case OPN_RJCT:
+ case CNF_RJCT:
+NS_LOG_DEBUG("I am "<<m_localAddress<<", CLOSED link with "<<m_peerAddress<<", at "<<Simulator::Now()<<" Rejected open or confirm");
+ m_state = HOLDING;
+ ClearRetryTimer();
+ SendPeerLinkClose(reasoncode);
+ SetHoldingTimer();
+ m_linkStatusCallback(m_localAddress, m_peerAddress, false);
+ break;
+ case CNCL:
+NS_LOG_DEBUG("I am "<<m_localAddress<<", CLOSED link with "<<m_peerAddress<<", at "<<Simulator::Now()<<" Link cancelled");
+ m_state = HOLDING;
+ SendPeerLinkClose(PEER_LINK_CANCELLED);
+ SetHoldingTimer();
+ m_linkStatusCallback(m_localAddress, m_peerAddress, false);
+ break;
+ default:{}
+ }
+ break;
+ case HOLDING:
+ switch(event)
+ {
+ case CLS_ACPT:
+ ClearHoldingTimer();
+ case TOH:
+ m_state = IDLE;
+ // TODO Callback MLME-SignalPeerLinkStatus
+ break;
+ case OPN_ACPT:
+ case CNF_ACPT:
+ m_state = HOLDING;
+ // reason not spec in D2.0
+ SendPeerLinkClose(PEER_LINK_CANCELLED);
+ break;
+ case OPN_RJCT:
+ case CNF_RJCT:
+ m_state = HOLDING;
+ SendPeerLinkClose(reasoncode);
+ break;
+ default:{}
+ }
+ break;
+ }
+}
+
+void WifiPeerLinkDescriptor::ClearRetryTimer()
+{
+ m_retryTimer.Cancel();
+}
+
+void WifiPeerLinkDescriptor::ClearConfirmTimer()
+{
+ m_confirmTimer.Cancel();
+}
+
+void WifiPeerLinkDescriptor::ClearHoldingTimer()
+{
+ m_holdingTimer.Cancel();
+}
+
+void WifiPeerLinkDescriptor::SendPeerLinkClose(dot11sReasonCode reasoncode)
+{
+ PeerLinkManagementElement peerElement;
+ peerElement.SetPeerClose(m_localLinkId, m_peerLinkId, reasoncode);
+ m_mac->SendPeerLinkClose(peerElement,m_peerAddress);
+}
+
+void WifiPeerLinkDescriptor::SendPeerLinkOpen()
+{
+ PeerLinkManagementElement peerElement;
+ peerElement.SetPeerOpen(m_localLinkId);
+ NS_ASSERT(m_mac!=NULL);
+ m_mac->SendPeerLinkOpen(peerElement,m_peerAddress);
+}
+
+void WifiPeerLinkDescriptor::SendPeerLinkConfirm()
+{
+ PeerLinkManagementElement peerElement;
+ peerElement.SetPeerConfirm(m_localLinkId, m_peerLinkId);
+ m_mac->SendPeerLinkConfirm(peerElement,m_peerAddress, m_assocId);
+}
+
+void WifiPeerLinkDescriptor::SetHoldingTimer()
+{
+ m_holdingTimer = Simulator::Schedule(dot11sParameters::dot11MeshHoldingTimeout,&WifiPeerLinkDescriptor::HoldingTimeout,this);
+}
+
+void WifiPeerLinkDescriptor::HoldingTimeout()
+{
+ StateMachine(TOH);
+}
+
+void WifiPeerLinkDescriptor::SetRetryTimer()
+{
+ m_retryTimer = Simulator::Schedule(dot11sParameters::dot11MeshRetryTimeout,&WifiPeerLinkDescriptor::RetryTimeout,this);
+}
+
+void WifiPeerLinkDescriptor::RetryTimeout()
+{
+ if( m_retryCounter < dot11sParameters::dot11MeshMaxRetries)
+ StateMachine(TOR1);
+ else
+ StateMachine(TOR2);
+}
+
+void WifiPeerLinkDescriptor::SetConfirmTimer()
+{
+ m_confirmTimer = Simulator::Schedule(dot11sParameters::dot11MeshConfirmTimeout,&WifiPeerLinkDescriptor::ConfirmTimeout,this);
+}
+
+void WifiPeerLinkDescriptor::ConfirmTimeout()
+{
+ StateMachine(TOC);
+}
+
+
+/***************************************************
+ * PeerManager
+ ***************************************************/
+NS_OBJECT_ENSURE_REGISTERED (WifiPeerManager);
+
+ TypeId
+WifiPeerManager::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::WifiPeerManager")
+ .SetParent<Object> ()
+ .AddConstructor<WifiPeerManager> ()
+ //peerLinkCleanupTimeout. This constant is not specified in Draft 2.0
+ .AddAttribute ("PeerLinkCleanupPeriod",
+ "PeerLinkCleanupPeriod",
+ TimeValue (MilliSeconds (80)),
+ MakeTimeAccessor (&WifiPeerManager::m_peerLinkCleanupPeriod),
+ MakeTimeChecker ()
+ )
+ //MaxBeaconLost. This constant is not specified in Draft 2.0
+ .AddAttribute ("MaxBeaconLost", "Max Beacon Lost",
+ UintegerValue (3),
+ MakeUintegerAccessor (&WifiPeerManager::m_maxBeaconLoss),
+ MakeUintegerChecker<uint8_t> ()
+ )
+ //maximum number of peer links.
+ .AddAttribute ("MaxNumberOfPeerLinks",
+ "Maximum number of peer links ",
+ UintegerValue (32),
+ MakeUintegerAccessor (&WifiPeerManager::m_maxNumberOfPeerLinks),
+ MakeUintegerChecker<uint8_t> ()
+ );
+ return tid;
+
+}
+WifiPeerManager::WifiPeerManager()
+{
+ m_assocId = 0;
+ m_numberOfActivePeers = 0;
+ // firs peerLinkId is 1, because 0 means "unknown"
+ m_localLinkId = 1;
+ m_cleanupEvent = Simulator::Schedule (m_peerLinkCleanupPeriod, &WifiPeerManager::PeerCleanup, this);
+}
+WifiPeerManager::~WifiPeerManager()
+{
+ m_cleanupEvent.Cancel();
+ //TODO: delete a list of descriptors
+ for(
+ PeerDescriptorsMap::iterator j = m_peerDescriptors.begin();
+ j!= m_peerDescriptors.end();
+ j++)
+ {
+ int to_delete = 0;
+ for(std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = j->second.begin(); i!= j->second.end(); i++)
+ {
+ to_delete ++;
+ (*i)->ClearTimingElement();
+ (*i) = 0;
+ }
+ for(int i = 0; i < to_delete; i ++)
+ j->second.pop_back();
+ j->second.clear();
+ }
+ m_peerDescriptors.clear();
+
+}
+void
+WifiPeerManager::SetSentBeaconTimers(
+ Mac48Address portAddress,
+ Time ReferenceTbtt,
+ Time BeaconInterval
+ )
+{
+ BeaconInfoMap::iterator myBeacon = m_myBeaconInfo.find(portAddress);
+ NS_ASSERT(myBeacon != m_myBeaconInfo.end());
+ myBeacon->second.referenceTbtt = ReferenceTbtt;
+ myBeacon->second.beaconInterval = BeaconInterval;
+
+}
+
+void
+WifiPeerManager::SetReceivedBeaconTimers(
+ Mac48Address portAddress,
+ Mac48Address peerAddress,
+ Time lastBeacon,
+ Time beaconInterval,
+ WifiBeaconTimingElement beaconTiming
+ )
+{
+ PeerDescriptorsMap::iterator port = m_peerDescriptors.find(portAddress);
+ NS_ASSERT(port!=m_peerDescriptors.end());
+ for(std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin(); i!= port->second.end(); i++)
+ {
+ if((*i)->GetPeerAddress() == peerAddress)
+ {
+ (*i)->SetBeaconTimingElement(beaconTiming);
+ (*i)->SetBeaconInformation(lastBeacon, beaconInterval);
+ return;
+ }
+ }
+ Ptr<WifiPeerLinkDescriptor> new_descriptor =
+ AddDescriptor(portAddress, peerAddress, Simulator::Now(), beaconInterval);
+ new_descriptor->SetBeaconTimingElement(beaconTiming);
+}
+
+ bool
+WifiPeerManager::AttachPorts(std::vector<Ptr<WifiNetDevice> > ports)
+{
+ NS_ASSERT(ports.size()!=0);
+ for(std::vector<Ptr<WifiNetDevice> >::iterator i = ports.begin(); i != ports.end(); i++)
+ {
+ MeshWifiMac * meshWifiMac = dynamic_cast<MeshWifiMac *> (PeekPointer ((*i)->GetMac()));
+ if(meshWifiMac == NULL)
+ return false;
+ meshWifiMac->SetPeerLinkManager(this);
+ //Add a mac pointer:
+ m_macPointers[meshWifiMac->GetAddress()] = meshWifiMac;
+ //Add descriptor array:
+ std::vector<Ptr<WifiPeerLinkDescriptor> > descriptors;
+ m_peerDescriptors[meshWifiMac->GetAddress()] = descriptors;
+ //Add beacon timers:
+ struct BeaconInfo myBeacon;
+ m_myBeaconInfo[meshWifiMac->GetAddress()] = myBeacon;
+ }
+ return true;
+}
+ void
+WifiPeerManager::AskIfOpenNeeded(Mac48Address portAddress, Mac48Address peerAddress)
+{
+ PeerDescriptorsMap::iterator port = m_peerDescriptors.find(portAddress);
+ NS_ASSERT(port!=m_peerDescriptors.end());
+ for(std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin(); i!= port->second.end(); i++)
+ if((*i)->GetPeerAddress() == peerAddress)
+ {
+ if(ShouldSendOpen(portAddress, peerAddress))
+ (*i)->MLMEActivePeerLinkOpen();
+ break;
+ }
+}
+
+void
+WifiPeerManager::SetOpenReceived(
+ Mac48Address portAddress,
+ Mac48Address peerAddress,
+ PeerLinkManagementElement peerMan,
+ MeshConfigurationElement conf
+ )
+{
+ dot11sReasonCode reasonCode;
+ if(!ShouldAcceptOpen(portAddress, peerAddress,reasonCode))
+ return;
+ PeerDescriptorsMap::iterator port = m_peerDescriptors.find(portAddress);
+ NS_ASSERT(port!=m_peerDescriptors.end());
+ for(std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin(); i!= port->second.end(); i++)
+ if((*i)->GetPeerAddress() == peerAddress)
+ {
+ (*i)->PeerLinkOpenAccept(peerMan.GetLocalLinkId(), conf);
+ return;
+ }
+ BeaconInfoMap::iterator myBeacon = m_myBeaconInfo.find(portAddress);
+ NS_ASSERT(myBeacon!=m_myBeaconInfo.end());
+ Ptr<WifiPeerLinkDescriptor>new_descriptor = AddDescriptor(
+ portAddress,
+ peerAddress,
+ Simulator::Now(),
+ myBeacon->second.beaconInterval
+ );
+ new_descriptor->PeerLinkOpenAccept(peerMan.GetLocalLinkId(), conf);
+}
+void
+WifiPeerManager::SetConfirmReceived(
+ Mac48Address portAddress,
+ Mac48Address peerAddress,
+ uint16_t peerAid,
+ PeerLinkManagementElement peerMan,
+ MeshConfigurationElement meshConfig
+ )
+{
+ PeerDescriptorsMap::iterator port = m_peerDescriptors.find(portAddress);
+ NS_ASSERT(port!= m_peerDescriptors.end());
+ for(std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin(); i!= port->second.end(); i++)
+ if((*i)->GetPeerAddress() == peerAddress)
+ (*i)->PeerLinkConfirmAccept(peerMan.GetLocalLinkId(), peerMan.GetPeerLinkId(), peerAid, meshConfig);
+}
+
+void
+WifiPeerManager::SetCloseReceived(
+ Mac48Address portAddress,
+ Mac48Address peerAddress,
+ PeerLinkManagementElement peerMan
+ )
+{
+ PeerDescriptorsMap::iterator port = m_peerDescriptors.find(portAddress);
+ NS_ASSERT(port!= m_peerDescriptors.end());
+ for(std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin(); i!= port->second.end(); i++)
+ if((*i)->GetPeerAddress() == peerAddress)
+ {
+ (*i)->PeerLinkClose(peerMan.GetLocalLinkId(), peerMan.GetPeerLinkId(), peerMan.GetReasonCode());
+ return;
+ }
+}
+
+void
+WifiPeerManager::ConfigurationMismatch(
+ Mac48Address portAddress,
+ Mac48Address peerAddress
+ )
+{
+ PeerDescriptorsMap::iterator port = m_peerDescriptors.find(portAddress);
+ NS_ASSERT(port!= m_peerDescriptors.end());
+ for(std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin(); i!= port->second.end(); i++)
+ if((*i)->GetPeerAddress() == peerAddress)
+ {
+ (*i)->MLMECancelPeerLink(MESH_CONFIGURATION_POLICY_VIOLATION);
+ return;
+ }
+
+}
+
+ WifiBeaconTimingElement
+WifiPeerManager::GetWifiBeaconTimingElementForMyBeacon(Mac48Address portAddress)
+{
+ PeerDescriptorsMap::iterator port = m_peerDescriptors.find(portAddress);
+ NS_ASSERT(port!= m_peerDescriptors.end());
+ WifiBeaconTimingElement return_val;
+ for(std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin(); i!= port->second.end(); i++)
+ {
+ //Just go through all neighbor entries and add it to timing element:
+ return_val.AddNeighboursTimingElementUnit(
+ (*i)->GetLocalAid(),
+ (*i)->GetLastBeacon(),
+ (*i)->GetBeaconInterval()
+ );
+ }
+ return return_val;
+
+}
+ WifiBeaconTimingElement
+WifiPeerManager::GetWifiBeaconTimingElementForAddress(
+ Mac48Address portAddress,
+ Mac48Address addr)
+{
+ PeerDescriptorsMap::iterator port = m_peerDescriptors.find(portAddress);
+ NS_ASSERT(port!= m_peerDescriptors.end());
+ WifiBeaconTimingElement return_val;
+ for(std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin(); i!= port->second.end(); i++)
+ if((*i)->GetPeerAddress() == addr)
+ return_val = (*i)->GetBeaconTimingElement();
+ return return_val;
+
+
+}
+Ptr<WifiPeerLinkDescriptor>
+WifiPeerManager::AddDescriptor(
+ Mac48Address portAddress,
+ Mac48Address peerAddress,
+ Time lastBeacon,
+ Time beaconInterval)
+{
+ Ptr<WifiPeerLinkDescriptor> new_descriptor = Create<WifiPeerLinkDescriptor>();
+ if(m_assocId ==0xff)
+ m_assocId = 0;
+ if(m_localLinkId == 0xff)
+ m_localLinkId = 0;
+ new_descriptor->SetLocalAid(m_assocId++);
+ new_descriptor->SetLocalLinkId(m_localLinkId++);
+ new_descriptor->SetPeerAddress(peerAddress);
+ new_descriptor->SetBeaconInformation(lastBeacon, beaconInterval);
+ //DEBUG ONLY:
+ new_descriptor->SetLocalAddress(portAddress);
+ //check if port address is wrong
+ MeshMacMap::iterator pos = m_macPointers.find(portAddress);
+ NS_ASSERT(pos!= m_macPointers.end());
+ //check if descriptors array exist
+ PeerDescriptorsMap::iterator port = m_peerDescriptors.find(portAddress);
+ NS_ASSERT(port !=m_peerDescriptors.end());
+ new_descriptor->SetMac(pos->second);
+ new_descriptor->SetMaxBeaconLoss(m_maxBeaconLoss);
+ new_descriptor->SetLinkStatusCallback(MakeCallback(&WifiPeerManager::PeerLinkStatus, this));
+ NS_ASSERT(port != m_peerDescriptors.end());
+ m_peerDescriptors[portAddress].push_back(new_descriptor);
+ return new_descriptor;
+}
+
+ void
+WifiPeerManager::PeerCleanup()
+{
+ for(
+ PeerDescriptorsMap::iterator j = m_peerDescriptors.begin();
+ j!= m_peerDescriptors.end();
+ j++)
+ {
+ std::vector<unsigned int> to_erase;
+ for(unsigned int i = 0; i< j->second.size(); i++)
+ if(j->second[i]->LinkIsIdle())
+ {
+ j->second[i]->ClearTimingElement();
+ j->second[i] = 0;
+ to_erase.push_back(i);
+ }
+ if(to_erase.size() == 0)
+ return;
+ for(unsigned int i = to_erase.size()-1 ; i >= 0; i--)
+ j->second.erase(j->second.begin() + to_erase[i]);
+ to_erase.clear();
+ }
+ m_cleanupEvent = Simulator::Schedule (m_peerLinkCleanupPeriod, &WifiPeerManager::PeerCleanup, this);
+}
+
+ std::vector<Mac48Address>
+WifiPeerManager::GetNeighbourAddressList(Mac48Address portAddress, Mac48Address peerAddress)
+{
+ PeerDescriptorsMap::iterator port = m_peerDescriptors.find(portAddress);
+ NS_ASSERT(port!= m_peerDescriptors.end());
+ std::vector<Mac48Address> return_value;
+ for(std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin(); i!= port->second.end(); i++)
+ return_value.push_back((*i)->GetPeerAddress());
+ return return_value;
+}
+
+ bool
+WifiPeerManager::IsActiveLink(Mac48Address portAddress, Mac48Address peerAddress)
+{
+ PeerDescriptorsMap::iterator port = m_peerDescriptors.find(portAddress);
+ NS_ASSERT(port!= m_peerDescriptors.end());
+ for(std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin(); i!= port->second.end(); i++)
+ if((*i)->GetPeerAddress() == peerAddress)
+ return ((*i)->LinkIsEstab());
+ return false;
+}
+
+ bool
+WifiPeerManager::ShouldSendOpen(Mac48Address portAddress, Mac48Address peerAddress)
+{
+ if(m_numberOfActivePeers > m_maxNumberOfPeerLinks)
+ return false;
+ return true;
+}
+
+ bool
+WifiPeerManager::ShouldAcceptOpen(Mac48Address portAddress, Mac48Address peerAddress,dot11sReasonCode & reasonCode)
+{
+ if(m_numberOfActivePeers > m_maxNumberOfPeerLinks)
+ {
+ reasonCode = MESH_MAX_PEERS;
+ return false;
+ }
+ return true;
+}
+
+ Time
+WifiPeerManager::GetNextBeaconShift(
+ Mac48Address portAddress,
+ Time myNextTBTT
+ )
+{
+ //REMINDER:: in timing element 1) last beacon reception time is measured in units of 256 microseconds
+ // 2) beacon interval is mesured in units of 1024 microseconds
+ // 3) hereafter TU = 1024 microseconds
+ //Im my MAC everything is stored in MicroSeconds
+
+ uint32_t myNextTBTTInTimeUnits = 0;
+ uint32_t futureBeaconInTimeUnits = 0;
+ //Going through all my timing elements and detecting future beacon collisions
+ PeerDescriptorsMap::iterator port = m_peerDescriptors.find(portAddress);
+ NS_ASSERT(port!= m_peerDescriptors.end());
+ BeaconInfoMap::iterator myBeacon = m_myBeaconInfo.find(portAddress);
+ NS_ASSERT(myBeacon!=m_myBeaconInfo.end());
+ for(std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin(); i!= port->second.end(); i++)
+ {
+ NeighboursTimingUnitsList neighbours;
+ neighbours = (*i)->GetBeaconTimingElement().GetNeighboursTimingElementsList();
+ //first let's form the list of all kown TBTTs
+ for(NeighboursTimingUnitsList::const_iterator j = neighbours.begin(); j!= neighbours.end(); j++)
+ {
+ uint16_t beaconIntervalTimeUnits;
+ beaconIntervalTimeUnits = (*j)->GetBeaconInterval();
+
+ //The last beacon time in timing elememt in Time Units
+ uint32_t lastBeaconInTimeUnits;
+ lastBeaconInTimeUnits = (*j)->GetLastBeacon()/4;
+
+ //The time of my next beacon sending in Time Units
+ myNextTBTTInTimeUnits = myNextTBTT.GetMicroSeconds()/1024;
+
+ //My beacon interval in Time Units
+ uint32_t myBeaconIntervalInTimeUnits;
+ myBeaconIntervalInTimeUnits = myBeacon->second.beaconInterval.GetMicroSeconds()/1024;
+
+ //The time the beacon of other station will be sent
+ //we need the time just after my next TBTT (or equal to my TBTT)
+ futureBeaconInTimeUnits = lastBeaconInTimeUnits + beaconIntervalTimeUnits;
+
+ //We apply MBAC only if beacon Intervals are equal
+ if (beaconIntervalTimeUnits == myBeaconIntervalInTimeUnits)
+ {
+ //We know when the neighbor STA transmitted it's beacon
+ //Now we need to know when it's going to send it's beacon in the future
+ //So let's use the valuse of it's beacon interval
+ while (myNextTBTTInTimeUnits >= futureBeaconInTimeUnits)
+ futureBeaconInTimeUnits = futureBeaconInTimeUnits + beaconIntervalTimeUnits;
+ //If we found that my TBTT coincide with another STA's TBTT
+ //break all cylce and return time shift for my next TBTT
+ if (myNextTBTTInTimeUnits == futureBeaconInTimeUnits)
+ break;
+ }
+
+ }
+ if (myNextTBTTInTimeUnits == futureBeaconInTimeUnits)
+ break;
+ }
+
+ //TBTTs coincide, so let's calculate the shift
+ if (myNextTBTTInTimeUnits == futureBeaconInTimeUnits) {
+ NS_LOG_DEBUG("MBCA: Future beacon collision is detected, applying avoidance mechanism");
+ UniformVariable randomSign(-1, 1);
+ int coefficientSign = -1;
+ if (randomSign.GetValue() >= 0)
+ coefficientSign = 1;
+ UniformVariable randomShift(1, 15);
+ //So, the shift is a random integer variable uniformly distributed in [-15;-1] U [1;15]
+ int beaconShift = randomShift.GetInteger() * coefficientSign;
+ NS_LOG_DEBUG("Shift value = " << beaconShift << " beacon TUs");
+ //We need the result not in Time Units, but in microseconds
+ return MicroSeconds(beaconShift * 1024);
+ }
+ //No collision detecterf, hence no shift is needed
+ else
+ return MicroSeconds(0);
+}
+
+void
+WifiPeerManager::PeerLinkStatus(Mac48Address portAddress, Mac48Address peerAddress, bool status)
+{
+ MeshMacMap::iterator pos = m_macPointers.find(portAddress);
+ NS_ASSERT(pos!= m_macPointers.end());
+ pos->second->PeerLinkStatus(peerAddress, status);
+}
+} //namespace NS3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/mesh-wifi-peer-manager.h Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,329 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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
+ *
+ * Authors: Kirill Andreev <andreev@iitp.ru>
+ * Aleksey Kovalenko <kovalenko@iitp.ru>
+ * Ivan Pustogarov <chinsa1@rambler.ru>
+ * Evgeny Khorov <horov@frtk.ru>
+ */
+
+
+#ifndef WIFI_PEER_MAN_H
+#define WIFI_PEER_MAN_H
+
+#include "ns3/event-id.h"
+#include "ns3/ptr.h"
+#include "ns3/nstime.h"
+#include "ns3/mac48-address.h"
+#include "ns3/uinteger.h"
+#include "ns3/wifi-net-device.h"
+#include "dot11s-peer-management-element.h"
+#include "mesh-wifi-beacon-timing-element.h"
+#include "mesh-wifi-mac.h"
+#include <list>
+
+namespace ns3
+{
+ class MeshWifiMac;
+ class WifiPeerLinkDescriptor : public RefCountBase
+ {
+ public:
+ WifiPeerLinkDescriptor();
+ /**
+ * Beacon loss processing:
+ */
+ void SetBeaconInformation(Time lastBeacon, Time BeaconInterval);
+ void SetMaxBeaconLoss(uint8_t maxBeaconLoss);
+ /**
+ * \brief Methods used to detecet peer link changes
+ * \param bool if true - opened new link, if
+ * false - link closed
+ */
+ void SetLinkStatusCallback(Callback<void, Mac48Address, Mac48Address, bool> cb);
+ /**
+ * Peer link geeters/setters
+ */
+ void SetPeerAddress(Mac48Address macaddr);
+ /**
+ * Debug purpose
+ */
+ void SetLocalAddress(Mac48Address macaddr);
+ void SetLocalLinkId(uint16_t id);
+ void SetPeerLinkId(uint16_t id);
+ void SetLocalAid(uint16_t aid);
+ void SetPeerAid(uint16_t aid);
+ void SetBeaconTimingElement(WifiBeaconTimingElement beaconTiming);
+ void SetPeerLinkDescriptorElement(
+ PeerLinkManagementElement peerLinkElement
+ );
+ Mac48Address GetPeerAddress()const;
+ /**
+ * Debug purpose
+ */
+ Mac48Address GetLocalAddress()const;
+ uint16_t GetLocalAid()const;
+ Time GetLastBeacon()const;
+ Time GetBeaconInterval()const;
+ WifiBeaconTimingElement
+ GetBeaconTimingElement()const;
+ PeerLinkManagementElement
+ GetPeerLinkDescriptorElement()const;
+ void ClearTimingElement();
+ /* MLME */
+ void MLMECancelPeerLink(dot11sReasonCode reason);
+ void MLMEPassivePeerLinkOpen();
+ void MLMEActivePeerLinkOpen();
+ void MLMEPeeringRequestReject();
+#if 0
+ void MLMEBindSecurityAssociation();
+#endif
+ void SetMac(Ptr<MeshWifiMac> mac);
+ void PeerLinkClose(uint16_t localLinkID,uint16_t peerLinkID, dot11sReasonCode reason);
+ void PeerLinkOpenAccept(uint16_t localLinkId, MeshConfigurationElement conf);
+ void PeerLinkOpenReject(uint16_t localLinkId, MeshConfigurationElement conf,dot11sReasonCode reason);
+ void PeerLinkConfirmAccept(
+ uint16_t localLinkId,
+ uint16_t peerLinkId,
+ uint16_t peerAid,
+ MeshConfigurationElement conf
+ );
+ void PeerLinkConfirmReject(
+ uint16_t localLinkId,
+ uint16_t peerLinkId,
+ MeshConfigurationElement conf,
+ dot11sReasonCode reason
+ );
+ bool LinkIsEstab() const;
+ bool LinkIsIdle() const;
+ private:
+ enum PeerState {
+ IDLE,
+ LISTEN,
+ OPN_SNT,
+ CNF_RCVD,
+ OPN_RCVD,
+ ESTAB,
+ HOLDING,
+ };
+ enum PeerEvent
+ {
+ CNCL, /** MLME-CancelPeerLink */
+ PASOPN, /** MLME-PassivePeerLinkOpen */
+ ACTOPN, /** MLME-ActivePeerLinkOpen */
+ //BNDSA, /** MLME-BindSecurityAssociation */
+ CLS_ACPT, /** PeerLinkClose_Accept */
+ //CLS_IGNR, /** PeerLinkClose_Ignore */
+ OPN_ACPT, /** PeerLinkOpen_Accept */
+ //OPN_IGNR, /** PeerLinkOpen_Ignore */
+ OPN_RJCT, /** PeerLinkOpen_Reject */
+ REQ_RJCT, /** PeerLinkOpenReject by internal reason */
+ CNF_ACPT, /** PeerLinkConfirm_Accept */
+ //CNF_IGNR, /** PeerLinkConfirm_Ignore */
+ CNF_RJCT, /** PeerLinkConfirm_Reject */
+ TOR1,
+ TOR2,
+ TOC,
+ TOH,
+ };
+ private:
+ void StateMachine(PeerEvent event,dot11sReasonCode = DOT11S_REASON_RESERVED);
+ /** Events handlers */
+ void ClearRetryTimer();
+ void ClearConfirmTimer();
+ void ClearHoldingTimer();
+ void SetHoldingTimer();
+ void SetRetryTimer();
+ void SetConfirmTimer();
+
+ void SendPeerLinkClose(dot11sReasonCode reasoncode );
+ void SendPeerLinkOpen();
+ void SendPeerLinkConfirm();
+ /** Private Event */
+ void HoldingTimeout();
+ void RetryTimeout();
+ void ConfirmTimeout();
+ private:
+ Mac48Address m_peerAddress;
+ Mac48Address m_localAddress;
+ uint16_t m_localLinkId;
+ uint16_t m_peerLinkId;
+ // Used for beacon timing:
+ // All values are stored in microseconds!
+ Time m_lastBeacon;
+ Time m_beaconInterval;
+ uint16_t m_assocId; //Assigned Assoc ID
+ uint16_t m_peerAssocId; //Assoc Id assigned to me by peer
+ //State of our peer Link:
+ PeerState m_state;
+
+ MeshConfigurationElement
+ m_configuration;
+ // State is a bitfield as defined as follows:
+ // This are states for a given
+ WifiBeaconTimingElement
+ m_beaconTiming;
+
+ EventId m_retryTimer;
+ EventId m_holdingTimer;
+ EventId m_confirmTimer;
+ uint16_t m_retryCounter;
+ /**
+ * Beacon loss timers:
+ */
+ EventId m_beaconLossTimer;
+ uint8_t m_maxBeaconLoss;
+ void BeaconLoss();
+ Ptr<MeshWifiMac> m_mac;
+ Callback<void, Mac48Address, Mac48Address, bool>
+ m_linkStatusCallback;
+ };
+
+ class WifiPeerManager : public Object
+ {
+ public:
+ WifiPeerManager();
+ WifiPeerManager(Ptr<MeshWifiMac> mac_pointer);
+ ~WifiPeerManager();
+ static TypeId GetTypeId (void);
+ //Returns a beacon timing element stored for remote station:
+ WifiBeaconTimingElement
+ GetWifiBeaconTimingElementForAddress(Mac48Address portAddress, Mac48Address addr);
+ //Returns a list of all addresses, which beacons can be decoded:
+ std::vector<Mac48Address>
+ GetNeighbourAddressList(Mac48Address portAddress, Mac48Address peerAddress);
+ bool AttachPorts(std::vector<Ptr<WifiNetDevice> >);
+ //void SetMac(Ptr<MeshWifiMac> mac);
+ Time GetNextBeaconShift(Mac48Address portAddress, Time myNextTBTT);
+
+ void SetSentBeaconTimers(
+ Mac48Address portAddress,
+ Time ReferenceTBTT,
+ Time BeaconInterval
+ );
+ void AskIfOpenNeeded(
+ Mac48Address portAddress,
+ Mac48Address peerAddress
+ );
+ void SetReceivedBeaconTimers(
+ Mac48Address portAddress,
+ Mac48Address peerAddress,
+ Time lastBeacon,
+ Time beaconInterval,
+ WifiBeaconTimingElement
+ beaconTiming
+ );
+ void SetOpenReceived(
+ Mac48Address portAddress,
+ Mac48Address peerAddress,
+ PeerLinkManagementElement
+ peerMan,
+ MeshConfigurationElement conf
+ );
+ void SetConfirmReceived(
+ Mac48Address portAddress,
+ Mac48Address peerAddress,
+ uint16_t peerAid,
+ PeerLinkManagementElement
+ peerMan,
+ MeshConfigurationElement meshConfig
+ );
+ void SetCloseReceived(
+ Mac48Address portAddress,
+ Mac48Address peerAddress,
+ PeerLinkManagementElement peerMan
+ );
+ //Using this function MAC
+ void ConfigurationMismatch(
+ Mac48Address portAddress,
+ Mac48Address peerAddress
+ );
+ //Returns a beacon timing element to added into my beacon:
+ WifiBeaconTimingElement
+ GetWifiBeaconTimingElementForMyBeacon(
+ Mac48Address portAddress
+ );
+ bool IsActiveLink(
+ Mac48Address portAddress,
+ Mac48Address peerAddress
+ );
+ private:
+ struct BeaconInfo
+ {
+ Time referenceTbtt; //When one of my station's beacons was put into a beacon queue;
+ Time beaconInterval; //Beacon interval of my station;
+ };
+ typedef std::map<Mac48Address, std::vector<Ptr<WifiPeerLinkDescriptor> >, std::less<Mac48Address> >
+ PeerDescriptorsMap;
+ typedef std::map<Mac48Address, Ptr<MeshWifiMac>,std::less<Mac48Address> > MeshMacMap;
+ typedef std::map<Mac48Address, struct BeaconInfo, std::less<Mac48Address> > BeaconInfoMap;
+
+ //Ptr<MeshWifiMac> m_mac;
+ //Maximum peers that may be opened:
+ uint8_t m_maxNumberOfPeerLinks;
+ /**
+ * Peer manager identify interface by address
+ * of MAC. So, for every interface we store
+ * list of peer descriptors.
+ */
+ PeerDescriptorsMap m_peerDescriptors;
+ /**
+ * List of MAC pointers - to iteract with each
+ * mac
+ */
+ MeshMacMap m_macPointers;
+ uint8_t m_numberOfActivePeers; //number of established peer links
+ uint16_t m_assocId; //last stored assoc ID
+ uint16_t m_localLinkId; //last stored local link ID
+ //This Variables used in beacon miss auto-cleanup:
+ //How many beacons may we lose before the link is
+ //considered to be broken:
+ uint8_t m_maxBeaconLoss;
+ //Periodically we scan the peer manager list of peers
+ //and check if the too many beacons were lost:
+ Time m_peerLinkCleanupPeriod;
+ EventId m_cleanupEvent;
+ Ptr<WifiPeerLinkDescriptor>
+ AddDescriptor(
+ Mac48Address portAddress,
+ Mac48Address peerAddress,
+ Time lastBeacon,
+ Time beaconInterval
+ );
+ void PeerCleanup();
+ //Mechanism of choosing PEERs:
+ bool ShouldSendOpen(Mac48Address portAddress, Mac48Address peerAddress);
+ bool ShouldAcceptOpen(
+ Mac48Address portAddress,
+ Mac48Address peerAddress,
+ dot11sReasonCode & reasonCode
+ );
+ //Needed for Beacon Collision Avoidance module:
+ BeaconInfoMap m_myBeaconInfo;
+ /**
+ * Peer link Open/Close callbacks: We need to
+ * inform MAC about this events.
+ * \brief Interaction with peer link
+ * descriptor - notify that peer link was
+ * opened or closed
+ * \param status true - peer link opened, peer
+ * link closed otherwise
+ */
+ void PeerLinkStatus(Mac48Address portAddress, Mac48Address peerAddress, bool status);
+ };
+
+} //namespace ns3
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/mesh-wifi-perr-information-element.cc Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,141 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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
+ *
+ * Authors: Yana Podkosova <yanapdk@rambler.ru>
+ * Kirill Andreev <andreev@iitp.ru>
+ */
+
+
+#include "mesh-wifi-perr-information-element.h"
+#include "ns3/address-utils.h"
+#define ELEMENT_ID (21)
+
+namespace ns3 {
+WifiPerrInformationElement::~WifiPerrInformationElement()
+{
+}
+
+TypeId
+WifiPerrInformationElement::GetTypeId()
+{
+ static TypeId tid = TypeId ("ns3::WifiPerrInformationElement")
+ .SetParent<Object> ();
+ return tid;
+}
+void
+WifiPerrInformationElement::Print(std::ostream &os) const
+{
+ // FILL
+}
+TypeId
+WifiPerrInformationElement::GetInstanceTypeId(void) const
+{
+ return GetTypeId();
+}
+WifiPerrInformationElement::WifiPerrInformationElement()
+{
+ m_numOfDest = 0;
+}
+uint8_t
+WifiPerrInformationElement::GetNumOfDest()
+{
+ return m_numOfDest;
+}
+void
+WifiPerrInformationElement::Serialize(Buffer::Iterator i)const
+{
+ i.WriteU8 (ELEMENT_ID);
+ i.WriteU8 (2+10*m_numOfDest);
+ i.WriteU8(0);
+ i.WriteU8 (m_numOfDest);
+ NS_ASSERT(m_numOfDest == m_addressUnits.size());
+ for(unsigned int j = 0; j < m_numOfDest; j++)
+ {
+ WriteTo(i,m_addressUnits[j].destination);
+ i.WriteHtonU32(m_addressUnits[j].seqnum);
+ }
+}
+uint32_t
+WifiPerrInformationElement::Deserialize(Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+ uint8_t ElementId;
+ ElementId = i.ReadU8();
+ NS_ASSERT (ElementId = ELEMENT_ID);
+ int length = i.ReadU8();
+ i.Next(1); //Mode flags is not used now
+ m_numOfDest = i.ReadU8();
+ NS_ASSERT((2+10*m_numOfDest) == length);
+ length = 0; //to avoid compiler warning in optimized builds
+ for(unsigned int j = 0; j < m_numOfDest; j++)
+ {
+ struct HwmpRtable::FailedDestination unit;
+ ReadFrom(i,unit.destination);
+ unit.seqnum = i.ReadNtohU32();
+ m_addressUnits.push_back(unit);
+ }
+ return i.GetDistanceFrom(start);
+}
+
+uint32_t
+WifiPerrInformationElement::GetSerializedSize() const
+{
+ uint32_t retval =
+ 1 //Element Id
+ +1 //Length
+ +1 //ModeFlags
+ +1 //NumOfDests
+ +6*m_numOfDest
+ +4*m_numOfDest;
+ return retval;
+}
+
+void
+WifiPerrInformationElement::AddAddressUnit(struct HwmpRtable::FailedDestination unit)
+{
+ for(unsigned int i = 0; i < m_addressUnits.size(); i ++)
+ if(m_addressUnits[i].destination == unit.destination)
+ return;
+ m_addressUnits.push_back(unit);
+ m_numOfDest++;
+}
+
+std::vector<struct HwmpRtable::FailedDestination>
+WifiPerrInformationElement::GetAddressUnitVector()
+{
+ return m_addressUnits;
+}
+void
+WifiPerrInformationElement::DeleteAddressUnit(Mac48Address address)
+{
+ for(std::vector<struct HwmpRtable::FailedDestination>::iterator i = m_addressUnits.begin(); i != m_addressUnits.end(); i ++)
+ if((*i).destination == address)
+ {
+ m_numOfDest --;
+ m_addressUnits.erase(i);
+ break;
+ }
+}
+
+void
+WifiPerrInformationElement::ResetPerr()
+{
+ m_numOfDest = 0;
+ m_addressUnits.clear();
+}
+}//namespace ns3
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/mesh-wifi-perr-information-element.h Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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
+ *
+ * Authors: Yana Podkosova <yanapdk@rambler.ru>
+ * Kirill Andreev <andreev@iitp.ru>
+ */
+
+
+#ifndef PERR_INFORMATION_ELEMENT_H
+#define PERR_INFORMATION_ELEMENT_H
+
+#include <stdint.h>
+#include "ns3/node.h"
+#include "ns3/buffer.h"
+#include "ns3/mac48-address.h"
+#include "ns3/hwmp-rtable.h"
+#include "ns3/header.h"
+
+namespace ns3
+{
+class WifiPerrInformationElement : public Header
+{
+ public:
+ WifiPerrInformationElement();
+ ~WifiPerrInformationElement();
+ static TypeId GetTypeId(void);
+ virtual TypeId GetInstanceTypeId(void) const;
+ virtual void Print(std::ostream &os) const;
+ virtual void Serialize(Buffer::Iterator i) const;
+ virtual uint32_t Deserialize(Buffer::Iterator start);
+ virtual uint32_t GetSerializedSize() const;
+#if 0
+ //RESERVED in D2.07
+ uint8_t GetModeFlags();
+ void SetModeFlags(uint8_t flags);
+#endif
+ uint8_t GetNumOfDest();
+
+ void AddAddressUnit(struct HwmpRtable::FailedDestination unit);
+ std::vector<struct HwmpRtable::FailedDestination>
+ GetAddressUnitVector();
+ void DeleteAddressUnit(Mac48Address address);
+ void ResetPerr();
+ private:
+ uint8_t m_numOfDest;
+ std::vector<struct HwmpRtable::FailedDestination>
+ m_addressUnits;
+};
+
+}
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/mesh-wifi-prep-information-element.cc Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,219 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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
+ *
+ * Authors: Yana Podkosova <yanapdk@rambler.ru>
+ * Kirill Andreev <andreev@iitp.ru>
+ */
+
+
+#include "mesh-wifi-prep-information-element.h"
+#include "ns3/address-utils.h"
+#include "ns3/assert.h"
+#define ELEMENT_ID (30)
+namespace ns3{
+/********************************
+ * WifiPrepInformationElement
+ *******************************/
+WifiPrepInformationElement::~WifiPrepInformationElement()
+{
+}
+
+TypeId
+WifiPrepInformationElement::GetTypeId()
+{
+ static TypeId tid = TypeId ("ns3::WifiPrepInformationElement")
+ .SetParent<Object> ();
+ return tid;
+}
+void
+WifiPrepInformationElement::Print(std::ostream &os) const
+{
+ //TODO:fill this method
+}
+TypeId
+WifiPrepInformationElement::GetInstanceTypeId(void) const
+{
+ return GetTypeId();
+}
+WifiPrepInformationElement::WifiPrepInformationElement()
+{
+ m_flags = 0;
+ m_hopcount = 0;
+ m_ttl = 0;
+ m_destSeqNumber = 0;
+ m_lifetime = 0;
+ m_destinationAddress = Mac48Address::GetBroadcast();
+ m_metric = 0;
+ m_originatorSeqNumber = 0;
+}
+void
+WifiPrepInformationElement::SetFlags(uint8_t flags)
+{
+ m_flags = flags;
+}
+void
+WifiPrepInformationElement::SetHopcount(uint8_t hopcount)
+{
+ m_hopcount = hopcount;
+}
+void
+WifiPrepInformationElement::SetTTL(uint8_t ttl)
+{
+ m_ttl = ttl;
+}
+void
+WifiPrepInformationElement::SetDestinationSeqNumber(uint32_t dest_seq_number)
+{
+ m_destSeqNumber = dest_seq_number;
+}
+void
+WifiPrepInformationElement::SetDestinationAddress(Mac48Address dest_address)
+{
+ m_destinationAddress = dest_address;
+}
+void
+WifiPrepInformationElement::SetMetric(uint32_t metric)
+{
+ m_metric = metric;
+}
+void
+WifiPrepInformationElement::SetOriginatorAddress(Mac48Address originator_address)
+{
+ m_originatorAddress = originator_address;
+}
+void
+WifiPrepInformationElement::SetOriginatorSeqNumber(uint32_t originator_seq_number)
+{
+ m_originatorSeqNumber = originator_seq_number;
+}
+void
+WifiPrepInformationElement::SetLifetime(uint32_t lifetime)
+{
+ m_lifetime = lifetime;
+}
+uint8_t
+WifiPrepInformationElement::GetFlags() const
+{
+ return m_flags;
+}
+uint8_t
+WifiPrepInformationElement::GetHopcount() const
+{
+ return m_hopcount;
+}
+uint32_t
+WifiPrepInformationElement::GetTTL() const
+{
+ return m_ttl;
+}
+uint32_t
+WifiPrepInformationElement::GetDestinationSeqNumber() const
+{
+ return m_destSeqNumber;
+}
+Mac48Address
+WifiPrepInformationElement::GetDestinationAddress() const
+{
+ return m_destinationAddress;
+}
+uint32_t
+WifiPrepInformationElement::GetMetric() const
+{
+ return m_metric;
+}
+Mac48Address
+WifiPrepInformationElement::GetOriginatorAddress() const
+{
+ return m_originatorAddress;
+}
+uint32_t
+WifiPrepInformationElement::GetOriginatorSeqNumber() const
+{
+ return m_originatorSeqNumber;
+}
+uint32_t
+WifiPrepInformationElement::GetLifetime() const
+{
+ return m_lifetime;
+}
+void
+WifiPrepInformationElement::DecrementTtl()
+{
+ m_ttl --;
+}
+
+void
+WifiPrepInformationElement::IncrementMetric(uint32_t metric)
+{
+ m_metric +=metric;
+}
+
+
+void
+WifiPrepInformationElement::Serialize(Buffer::Iterator i) const
+{
+ i.WriteU8 (ELEMENT_ID);
+ i.WriteU8 (32);//length = 32
+ i.WriteU8 (m_flags);
+ i.WriteU8 (m_hopcount);
+ i.WriteU8 (m_ttl);
+ WriteTo(i, m_destinationAddress);
+ i.WriteHtonU32 (m_destSeqNumber);
+ i.WriteHtonU32 (m_lifetime);
+ i.WriteHtonU32 (m_metric);
+ WriteTo(i, m_originatorAddress);
+ i.WriteHtonU32 (m_originatorSeqNumber);
+}
+uint32_t
+WifiPrepInformationElement::Deserialize(Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+ uint8_t ElementId;
+ ElementId = i.ReadU8();
+ NS_ASSERT (ElementId == ELEMENT_ID);
+ i.Next(1); // length is constatnt
+ m_flags = i.ReadU8();
+ m_hopcount = i.ReadU8();
+ m_ttl = i.ReadU8();
+ ReadFrom(i,m_destinationAddress);
+ m_destSeqNumber = i.ReadNtohU32();
+ m_lifetime = i.ReadNtohU32();
+ m_metric = i.ReadNtohU32();
+ ReadFrom(i,m_originatorAddress);
+ m_originatorSeqNumber = i.ReadNtohU32();
+ return i.GetDistanceFrom(start);
+}
+uint32_t
+WifiPrepInformationElement::GetSerializedSize() const
+{
+ uint32_t retval =
+ 1 //Element ID
+ +1 //Length
+ +1 //Flags
+ +1 //Hopcount
+ +1 //TTL
+ +6 //Dest address
+ +4 //Dest seqno
+ +4 //Lifetime
+ +4 //metric
+ +6 //Originator address
+ +4 //Originator seqno
+ +1; //destination count
+ return retval;
+
+};
+} //namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/mesh-wifi-prep-information-element.h Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,81 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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
+ *
+ * Authors: Yana Podkosova <yanapdk@rambler.ru>
+ * Kirill Andreev <andreev@iitp.ru>
+ */
+
+
+#ifndef WIFI_PREP_INFORMATION_ELEMENT_H
+#define WIFI_PREP_INFORMATION_ELEMENT_H
+
+
+#include <stdint.h>
+#include "ns3/node.h"
+#include "ns3/buffer.h"
+#include "ns3/mac48-address.h"
+#include "ns3/header.h"
+namespace ns3
+{
+class WifiPrepInformationElement : public Header
+{
+ public:
+ WifiPrepInformationElement();
+ ~WifiPrepInformationElement();
+ static TypeId GetTypeId(void);
+ virtual TypeId GetInstanceTypeId(void) const;
+ virtual void Print(std::ostream &os) const;
+ void SetFlags(uint8_t flags);
+ void SetHopcount(uint8_t hopcount);
+ void SetTTL(uint8_t ttl);
+ void SetDestinationAddress(Mac48Address dest_address);
+ void SetDestinationSeqNumber(uint32_t dest_seq_number);
+ void SetLifetime(uint32_t lifetime);
+ void SetMetric(uint32_t metric);
+ void SetOriginatorAddress(Mac48Address originator_address);
+ void SetOriginatorSeqNumber(uint32_t originator_seg_number);
+ virtual void Serialize(Buffer::Iterator i) const;
+ virtual uint32_t Deserialize(Buffer::Iterator i);
+ virtual uint32_t GetSerializedSize() const;
+
+ uint8_t GetFlags() const;
+ uint8_t GetHopcount() const;
+ uint32_t GetTTL() const;
+ Mac48Address GetDestinationAddress() const;
+ uint32_t GetDestinationSeqNumber() const;
+ uint32_t GetLifetime() const;
+ uint32_t GetMetric() const;
+ Mac48Address GetOriginatorAddress() const;
+ uint32_t GetOriginatorSeqNumber()const ;
+
+ void DecrementTtl();
+ void IncrementMetric(uint32_t metric);
+ private:
+
+ uint8_t m_flags;
+ uint8_t m_hopcount;
+ uint8_t m_ttl;
+ Mac48Address m_destinationAddress;
+ uint32_t m_destSeqNumber;
+ uint32_t m_lifetime;
+ uint32_t m_metric;
+ Mac48Address m_originatorAddress;
+ uint32_t m_originatorSeqNumber;
+};
+}//namespace ns3
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/mesh-wifi-preq-information-element.cc Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,393 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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
+ *
+ * Authors: Yana Podkosova <yanapdk@rambler.ru>
+ * Kirill Andreev <andreev@iitp.ru>
+ */
+
+
+#include "mesh-wifi-preq-information-element.h"
+#include "ns3/address-utils.h"
+#include "ns3/assert.h"
+#define ELEMENT_ID (22)
+namespace ns3{
+/*************************
+ * DestinationAddressUnit
+ ************************/
+DestinationAddressUnit::DestinationAddressUnit()
+{
+ m_do = false;
+ m_rf = false;
+ m_destSeqNumber = 0;
+ uint8_t mac_buffer[6];
+ for (int j = 0; j < 6; j++)
+ {
+ mac_buffer[j] = 0;
+ }
+ m_destinationAddress.CopyFrom(mac_buffer);
+}
+void
+DestinationAddressUnit::SetFlags(bool doFlag, bool rfFlag)
+{
+ m_do = doFlag;
+ m_rf = rfFlag;
+}
+
+void
+DestinationAddressUnit::SetDestSeqNumber(uint32_t dest_seq_number)
+{
+ m_destSeqNumber = dest_seq_number;
+}
+void
+DestinationAddressUnit::SetDestinationAddress(Mac48Address dest_address)
+{
+ m_destinationAddress = dest_address;
+}
+bool
+DestinationAddressUnit::IsDo()
+{
+ return m_do;
+}
+
+bool
+DestinationAddressUnit::IsRf()
+{
+ return m_rf;
+}
+
+uint32_t
+DestinationAddressUnit::GetDestSeqNumber() const
+{
+ return m_destSeqNumber;
+}
+Mac48Address
+DestinationAddressUnit::GetDestinationAddress() const
+{
+ return m_destinationAddress;
+}
+/********************************
+ * WifiPreqInformationElement
+ *******************************/
+WifiPreqInformationElement::~WifiPreqInformationElement()
+{
+}
+
+TypeId
+WifiPreqInformationElement::GetTypeId()
+{
+ static TypeId tid = TypeId ("ns3::WifiPreqInformationElement")
+ .SetParent<Object> ();
+ return tid;
+}
+void
+WifiPreqInformationElement::Print(std::ostream &os) const
+{
+ //TODO:fill this method
+}
+
+TypeId
+WifiPreqInformationElement::GetInstanceTypeId(void) const
+{
+ return GetTypeId();
+}
+
+WifiPreqInformationElement::WifiPreqInformationElement()
+{
+ m_flags = 0;
+ m_hopCount = 0;
+ m_ttl = 0;
+ m_preqId = 0;
+ m_lifetime = 0;
+ m_originatorAddress = Mac48Address::GetBroadcast();
+ m_originatorSeqNumber = 0;
+ m_metric = 0;
+ m_destCount = 0;
+ m_maxSize = DEF_MAX_SIZE;
+}
+void
+WifiPreqInformationElement::SetUnicastPreq()
+{
+ m_flags |= 1<<1;
+}
+
+void
+WifiPreqInformationElement::SetNeedNotPrep()
+{
+ m_flags |= 1<<2;
+}
+//void
+//WifiPreqInformationElement::SetFlags(uint8_t flags)
+//{
+// m_flags = flags;
+//}
+void
+WifiPreqInformationElement::SetHopcount(uint8_t hopcount)
+{
+ m_hopCount = hopcount;
+}
+void
+WifiPreqInformationElement::SetTTL(uint8_t ttl)
+{
+ m_ttl = ttl;
+}
+void
+WifiPreqInformationElement::SetPreqID(uint32_t preq_id)
+{
+ m_preqId = preq_id;
+}
+void
+WifiPreqInformationElement::SetMetric(uint32_t metric)
+{
+ m_metric = metric;
+}
+void
+WifiPreqInformationElement::SetOriginatorAddress(Mac48Address originator_address)
+{
+ m_originatorAddress = originator_address;
+}
+void
+WifiPreqInformationElement::SetOriginatorSeqNumber(uint32_t originator_seq_number)
+{
+ m_originatorSeqNumber = originator_seq_number;
+}
+void
+WifiPreqInformationElement::SetLifetime(uint32_t lifetime)
+{
+ m_lifetime = lifetime;
+}
+void
+WifiPreqInformationElement::SetDestCount(uint8_t dest_count)
+{
+ m_destCount = dest_count;
+}
+
+//uint8_t
+//WifiPreqInformationElement::GetFlags() const
+//{
+// return m_flags;
+//}
+bool
+WifiPreqInformationElement::IsUnicastPreq() const
+{
+ return (m_flags & (1<<1));
+}
+
+bool
+WifiPreqInformationElement::IsNeedNotPrep() const
+{
+ return (m_flags & (1<<2));
+}
+
+uint8_t
+WifiPreqInformationElement::GetHopCount() const
+{
+ return m_hopCount;
+}
+uint8_t
+WifiPreqInformationElement::GetTtl() const
+{
+ return m_ttl;
+}
+uint32_t
+WifiPreqInformationElement::GetPreqID() const
+{
+ return m_preqId;
+}
+uint32_t
+WifiPreqInformationElement::GetMetric() const
+{
+ return m_metric;
+}
+Mac48Address
+WifiPreqInformationElement::GetOriginatorAddress() const
+{
+ return m_originatorAddress;
+}
+uint32_t
+WifiPreqInformationElement::GetOriginatorSeqNumber() const
+{
+ return m_originatorSeqNumber;
+}
+uint32_t
+WifiPreqInformationElement::GetLifetime() const
+{
+ return m_lifetime;
+}
+
+uint8_t
+WifiPreqInformationElement::GetDestCount() const
+{
+ return m_destCount;
+}
+
+void
+WifiPreqInformationElement::DecrementTtl()
+{
+ m_ttl --;
+ m_hopCount ++;
+}
+
+void
+WifiPreqInformationElement::IncrementMetric(uint32_t metric)
+{
+ m_metric +=metric;
+}
+
+void
+WifiPreqInformationElement::Serialize(Buffer::Iterator i) const
+{
+ i.WriteU8 (ELEMENT_ID);
+ //TODO:Check maxsize
+ uint8_t length = m_destCount*11+28;
+ if(m_destCount> m_maxSize)
+ length -=(m_destCount-m_maxSize)*11;
+ i.WriteU8(length);
+ i.WriteU8 (m_flags);
+ i.WriteU8 (m_hopCount);
+ i.WriteU8 (m_ttl);
+ i.WriteHtonU32 (m_preqId);
+ WriteTo(i, m_originatorAddress);
+ i.WriteHtonU32 (m_originatorSeqNumber);
+ i.WriteHtonU32 (m_lifetime);
+ i.WriteHtonU32 (m_metric);
+ i.WriteU8 (m_destCount);
+ int written = 0;
+ for (std::vector<Ptr<DestinationAddressUnit> >::const_iterator j = m_destinations.begin(); j!= m_destinations.end(); j++)
+ {
+ uint8_t flags = 0;
+ if((*j)->IsDo())
+ flags +=128;
+ if((*j)->IsRf())
+ flags +=64;
+ i.WriteU8(flags);
+ WriteTo(i,(*j)->GetDestinationAddress());
+ i.WriteHtonU32 ((*j)->GetDestSeqNumber());
+ written++;
+ if (written > m_maxSize)
+ break;
+ }
+}
+
+uint32_t
+WifiPreqInformationElement::Deserialize(Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+ uint8_t ElementId;
+ ElementId = i.ReadU8();
+ NS_ASSERT (ElementId == ELEMENT_ID);
+ uint8_t length;
+ length = i.ReadU8();
+ m_flags = i.ReadU8();
+ m_hopCount = i.ReadU8();
+ m_ttl = i.ReadU8();
+ m_preqId = i.ReadNtohU32();
+ ReadFrom(i,m_originatorAddress);
+ m_originatorSeqNumber = i.ReadNtohU32();
+ m_lifetime = i.ReadNtohU32();
+ m_metric = i.ReadNtohU32();
+ m_destCount = i.ReadU8();
+ for (int j = 0; j < m_destCount; j++ )
+ {
+ Ptr<DestinationAddressUnit> new_element = Create<DestinationAddressUnit>();
+ bool doFlag = false;
+ bool rfFlag = false;
+ uint8_t flags = i.ReadU8();
+ if(flags >= 128)
+ {
+ doFlag = true;
+ flags -=128;
+ }
+ if(flags >=64)
+ rfFlag = true;
+ new_element->SetFlags(doFlag, rfFlag);
+ Mac48Address addr;
+ ReadFrom(i,addr);
+ new_element->SetDestinationAddress(addr);
+ new_element->SetDestSeqNumber(i.ReadNtohU32());
+ m_destinations.push_back(new_element);
+ NS_ASSERT(28+j*11 < length);
+ }
+ return i.GetDistanceFrom(start);
+}
+uint32_t
+WifiPreqInformationElement::GetSerializedSize() const
+{
+ uint32_t retval =
+ 1 //Element ID
+ +1 //Length
+ +1 //Flags
+ +1 //Hopcount
+ +1 //TTL
+ +4 //PREQ ID
+ +6 //Source address (originator)
+ +4 //Originator seqno
+ +4 //Lifetime
+ +4 //metric
+ +1; //destination count
+ if(m_destCount > m_maxSize)
+ retval+=(m_maxSize*11);
+ else
+ retval +=(m_destCount*11);
+ return retval;
+}
+std::vector<Ptr<DestinationAddressUnit> >
+WifiPreqInformationElement::GetDestinationList()
+{
+ return m_destinations;
+}
+void
+WifiPreqInformationElement::AddDestinationAddressElement(
+ bool doFlag, bool rfFlag,
+ Mac48Address dest_address,
+ uint32_t dest_seq_number
+ )
+{
+ for(std::vector<Ptr<DestinationAddressUnit> >::iterator i = m_destinations.begin(); i!=m_destinations.end(); i++ )
+ if((*i)->GetDestinationAddress() == dest_address)
+ return;
+ Ptr<DestinationAddressUnit>new_element = Create<DestinationAddressUnit>();
+ new_element->SetFlags(doFlag, rfFlag);
+ new_element->SetDestinationAddress(dest_address);
+ new_element->SetDestSeqNumber(dest_seq_number);
+ m_destinations.push_back(new_element);
+ m_destCount++;
+}
+
+void
+WifiPreqInformationElement::DelDestinationAddressElement(Mac48Address dest_address)
+{
+ for(std::vector<Ptr<DestinationAddressUnit> >::iterator i = m_destinations.begin(); i!=m_destinations.end(); i++ )
+ if((*i)->GetDestinationAddress() == dest_address)
+ {
+ m_destinations.erase(i);
+ m_destCount--;
+ break;
+ }
+}
+
+void
+WifiPreqInformationElement::ClearDestinationAddressElement()
+{
+ int i;
+ for(std::vector<Ptr<DestinationAddressUnit> >::iterator j = m_destinations.begin(); j!= m_destinations.end(); j++)
+ (*j) = 0;
+ for(i = 0; i < m_destCount; i ++)
+ m_destinations.pop_back();
+ m_destinations.clear();
+};
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/mesh-wifi-preq-information-element.h Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,124 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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
+ *
+ * Authors: Yana Podkosova <yanapdk@rambler.ru>
+ * Kirill Andreev <andreev@iitp.ru>
+ */
+
+
+#ifndef WIFI_PREQ_INFORMATION_ELEMENT_H
+#define WIFI_PREQ_INFORMATION_ELEMENT_H
+
+#include <stdint.h>
+#include "ns3/node.h"
+#include "ns3/buffer.h"
+#include "ns3/mac48-address.h"
+#include "ns3/header.h"
+#include <vector>
+namespace ns3
+{
+class DestinationAddressUnit : public RefCountBase
+{
+ public:
+ DestinationAddressUnit();
+ void SetFlags(bool doFlag, bool rfflag);
+ //void SetPerDestFlags(uint8_t per_dest_flags);
+ void SetDestinationAddress(Mac48Address dest_address);
+ void SetDestSeqNumber(uint32_t dest_seq_number);
+ bool IsDo();
+ bool IsRf();
+ Mac48Address GetDestinationAddress() const;
+ uint32_t GetDestSeqNumber() const;
+
+ private:
+ bool m_do;
+ bool m_rf;
+ Mac48Address m_destinationAddress;
+ uint32_t m_destSeqNumber;
+};
+
+class WifiPreqInformationElement : public Header
+{
+ public:
+ WifiPreqInformationElement();
+ ~WifiPreqInformationElement (void);
+ static TypeId GetTypeId (void);
+ virtual TypeId GetInstanceTypeId(void) const;
+ virtual void Print(std::ostream &os) const;
+ void AddDestinationAddressElement(
+ bool doFlag,
+ bool rfFlag,
+ Mac48Address dest_address,
+ uint32_t dest_seq_number
+ );
+ void DelDestinationAddressElement(Mac48Address dest_address);
+ void ClearDestinationAddressElement();
+ std::vector<Ptr<DestinationAddressUnit> > GetDestinationList ();
+ //void SetFlags(uint8_t flags);
+ void SetUnicastPreq();
+ /*
+ * \brief In proactive case: need we send PREP
+ */
+ void SetNeedNotPrep();
+ void SetHopcount(uint8_t hopcount);
+ void SetTTL(uint8_t ttl);
+ void SetPreqID(uint32_t id);
+ void SetOriginatorAddress(Mac48Address originator_address);
+ void SetOriginatorSeqNumber(uint32_t originator_seq_number);
+ void SetLifetime(uint32_t lifetime);
+ void SetMetric(uint32_t metric);
+ void SetDestCount(uint8_t dest_count);
+
+ virtual void Serialize(Buffer::Iterator i) const;
+ virtual uint32_t Deserialize(Buffer::Iterator i);
+ virtual uint32_t GetSerializedSize() const;
+
+ //uint8_t GetFlags() const ;
+ bool IsUnicastPreq() const;
+ bool IsNeedNotPrep() const;
+ uint8_t GetHopCount() const;
+ uint8_t GetTtl()const ;
+ uint32_t GetPreqID() const;
+ Mac48Address GetOriginatorAddress() const;
+ uint32_t GetOriginatorSeqNumber() const;
+ uint32_t GetLifetime() const;
+ uint32_t GetMetric() const;
+ uint8_t GetDestCount() const;
+ void DecrementTtl();
+ void IncrementMetric(uint32_t metric);
+
+ private:
+ std::vector<Ptr<DestinationAddressUnit> >
+ m_destinations;
+ //how many destinations we support
+ uint8_t m_maxSize;
+ //Fields:
+ uint8_t m_flags;
+ uint8_t m_hopCount;
+ uint8_t m_ttl;
+ uint32_t m_preqId;
+ Mac48Address m_originatorAddress;
+ uint32_t m_originatorSeqNumber;
+ uint32_t m_lifetime;
+ uint32_t m_metric;
+ uint8_t m_destCount;
+#define DEF_MAX_SIZE 32
+};
+
+} //namespace ns3
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/mesh-wifi-rann-information-element.cc Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,164 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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
+ *
+ * Authors: Yana Podkosova <yanapdk@rambler.ru>
+ * Kirill Andreev <andreev@iitp.ru>
+ */
+
+
+#include "mesh-wifi-rann-information-element.h"
+#include "ns3/assert.h"
+#include "ns3/address-utils.h"
+#define ELEMENT_ID (20)
+
+namespace ns3{
+
+WifiRannInformationElement::~WifiRannInformationElement()
+{
+}
+TypeId
+WifiRannInformationElement::GetTypeId()
+{
+ static TypeId tid = TypeId ("ns3::WifiRannInformationElement").SetParent<Object> ();
+ return tid;
+}
+TypeId
+WifiRannInformationElement::GetInstanceTypeId(void) const
+{
+ return GetTypeId();
+}
+void
+WifiRannInformationElement::Print(std::ostream &os)const
+{
+ // FILL
+}
+WifiRannInformationElement::WifiRannInformationElement()
+{ m_flags = 0;
+ m_hopcount = 0;
+ m_ttl = 0;
+ m_destSeqNumber = 0;
+ m_metric = 0;
+ m_originatorAddress = Mac48Address::GetBroadcast();
+ m_destSeqNumber = 0;
+
+}
+void
+WifiRannInformationElement::SetFlags(uint8_t flags)
+{
+ m_flags = flags;
+}
+void
+WifiRannInformationElement::SetHopcount(uint8_t hopcount)
+{
+ m_hopcount = hopcount;
+}
+void
+WifiRannInformationElement::SetTTL(uint8_t ttl)
+{
+ m_ttl = ttl;
+}
+void
+WifiRannInformationElement::SetDestSeqNumber(uint32_t dest_seq_number)
+{
+ m_destSeqNumber = dest_seq_number;
+}
+void
+WifiRannInformationElement::SetMetric(uint32_t metric)
+{
+ m_metric = metric;
+}
+void
+WifiRannInformationElement::SetOriginatorAddress(Mac48Address originator_address)
+{
+ m_originatorAddress = originator_address;
+}
+
+uint8_t
+WifiRannInformationElement::GetFlags()
+{
+ return m_flags;
+}
+uint8_t
+WifiRannInformationElement::GetHopcount()
+{
+ return m_hopcount;
+}
+uint8_t
+WifiRannInformationElement::GetTTL()
+{
+ return m_ttl;
+}
+uint32_t
+WifiRannInformationElement::GetDestSeqNumber()
+{
+ return m_destSeqNumber;
+}
+uint32_t
+WifiRannInformationElement::GetMetric()
+{
+ return m_metric;
+}
+Mac48Address
+WifiRannInformationElement::GetOriginatorAddress()
+{
+ return m_originatorAddress;
+}
+void
+WifiRannInformationElement::Serialize(Buffer::Iterator i) const
+{
+ i.WriteU8 (ELEMENT_ID);
+ i.WriteU8 (21);//length = 21
+ i.WriteU8 (m_flags);
+ i.WriteU8 (m_hopcount);
+ i.WriteU8 (m_ttl);
+ WriteTo(i, m_originatorAddress);
+ i.WriteHtonU32 (m_destSeqNumber);
+ i.WriteHtonU32 (m_metric);
+}
+uint32_t
+WifiRannInformationElement::Deserialize(Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+ uint8_t ElementId;
+ ElementId = i.ReadU8();
+ NS_ASSERT (ElementId == ELEMENT_ID);
+ i.Next(1);// length is constant
+ m_flags = i.ReadU8();
+ m_hopcount = i.ReadU8();
+ m_ttl = i.ReadU8();
+ ReadFrom(i, m_originatorAddress);
+ m_destSeqNumber = i.ReadNtohU32();
+ m_metric = i.ReadNtohU32();
+ return i.GetDistanceFrom(start);
+}
+uint32_t
+WifiRannInformationElement::GetSerializedSize() const
+{
+ uint32_t retval =
+ 1//ElementId
+ +1//Length
+ +1//Flags
+ +1//Hopcount
+ +1//TTL
+ +6//OriginatorAddress
+ +4//DestSeqNumber
+ +4;//Metric
+ return retval;
+};
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/mesh-wifi-rann-information-element.h Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,72 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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
+ *
+ * Authors: Yana Podkosova <yanapdk@rambler.ru>
+ * Kirill Andreev <andreev@iitp.ru>
+ */
+
+
+#ifndef RANN_INFORMATION_ELEMENT_H
+#define RANN_INFORMATION_ELEMENT_H
+
+
+#include <stdint.h>
+#include "ns3/buffer.h"
+#include "ns3/mac48-address.h"
+#include "ns3/node.h"
+#include "ns3/header.h"
+
+namespace ns3
+{
+class WifiRannInformationElement
+{
+ public:
+ WifiRannInformationElement();
+ virtual ~WifiRannInformationElement();
+ static TypeId GetTypeId(void);
+ virtual TypeId GetInstanceTypeId(void) const;
+ virtual void Print(std::ostream &os) const;
+ void SetFlags(uint8_t flags);
+ void SetHopcount(uint8_t hopcount);
+ void SetTTL(uint8_t ttl);
+ void SetOriginatorAddress(Mac48Address originator_address);
+ void SetDestSeqNumber(uint32_t dest_seq_number);
+ void SetMetric(uint32_t metric);
+ virtual void Serialize(Buffer::Iterator i) const;
+ virtual uint32_t Deserialize(Buffer::Iterator start);
+ virtual uint32_t GetSerializedSize() const;
+ uint8_t GetFlags();
+ uint8_t GetHopcount();
+ uint8_t GetTTL();
+ Mac48Address GetOriginatorAddress();
+ uint32_t GetDestSeqNumber();
+ uint32_t GetMetric();
+
+ void DecrementTtl();
+ void IncrementMetric(uint32_t metric);
+
+ private:
+ uint8_t m_flags;
+ uint8_t m_hopcount;
+ uint8_t m_ttl;
+ Mac48Address m_originatorAddress;
+ uint32_t m_destSeqNumber;
+ uint32_t m_metric;
+};
+
+}
+#endif
--- a/src/devices/wifi/mgt-headers.cc Wed Feb 25 12:27:00 2009 -0500
+++ b/src/devices/wifi/mgt-headers.cc Sat Feb 28 14:21:05 2009 +0300
@@ -20,6 +20,8 @@
#include "mgt-headers.h"
#include "ns3/simulator.h"
#include "ns3/assert.h"
+#include "ns3/log.h"
+NS_LOG_COMPONENT_DEFINE("MgtHeaders");
namespace ns3 {
@@ -109,6 +111,11 @@
MgtProbeResponseHeader::~MgtProbeResponseHeader ()
{}
+uint64_t
+MgtProbeResponseHeader::GetTimestamp()
+{
+ return m_timestamp;
+}
Ssid
MgtProbeResponseHeader::GetSsid (void) const
{
@@ -198,7 +205,7 @@
MgtProbeResponseHeader::Deserialize (Buffer::Iterator start)
{
Buffer::Iterator i = start;
- i.Next (8); // timestamp
+ m_timestamp = i.ReadNtohU64();
m_beaconInterval = i.ReadNtohU16 ();
m_beaconInterval *= 1024;
i = m_capability.Deserialize (i);
@@ -207,6 +214,71 @@
//i.Next (3); // ds parameter set
return i.GetDistanceFrom (start);
}
+/***********************************************************
+ * Mesh Beacon
+ ***********************************************************/
+void
+MgtMeshBeaconHeader::SetMeshConfigurationElement(MeshConfigurationElement mesh_config)
+{
+ m_meshConfig = mesh_config;
+}
+
+void
+MgtMeshBeaconHeader::SetWifiBeaconTimingElement(WifiBeaconTimingElement wifi_timing)
+{
+ m_meshTiming = wifi_timing;
+}
+
+MeshConfigurationElement
+MgtMeshBeaconHeader::GetMeshConfigurationElement()
+{
+ return m_meshConfig;
+}
+
+WifiBeaconTimingElement
+MgtMeshBeaconHeader::GetWifiBeaconTimingElement()
+{
+ return m_meshTiming;
+}
+
+uint32_t
+MgtMeshBeaconHeader::GetSerializedSize (void) const
+{
+ uint32_t size = (
+ MgtBeaconHeader::GetSerializedSize()
+ + m_meshConfig.GetSerializedSize()
+ + m_meshTiming.GetSerializedSize()
+ + 9 //MSCIE
+ );
+ return size;
+}
+
+void
+MgtMeshBeaconHeader::Serialize (Buffer::Iterator start) const
+{
+ //First we pack Beacon:
+ NS_LOG_DEBUG("Serialization beacon");
+ Buffer::Iterator i = start;
+ MgtBeaconHeader::Serialize(i);
+ i.Next(MgtBeaconHeader::GetSerializedSize());
+ i = m_meshConfig.Serialize(i);
+ i = m_meshTiming.Serialize(i);
+ i.Next(9); //MSCIE
+}
+
+uint32_t
+MgtMeshBeaconHeader::Deserialize (Buffer::Iterator start)
+{
+ NS_LOG_DEBUG("Deserialization beacon");
+ Buffer::Iterator i = start;
+ MgtBeaconHeader::Deserialize(start);
+ i.Next(MgtBeaconHeader::GetSerializedSize());
+ i = m_meshConfig.Deserialize(i);
+ i = m_meshTiming.Deserialize(i);
+ i.Next(9); //MSCIE
+ return i.GetDistanceFrom (start);
+}
+
/***********************************************************
* Assoc Request
--- a/src/devices/wifi/mgt-headers.h Wed Feb 25 12:27:00 2009 -0500
+++ b/src/devices/wifi/mgt-headers.h Sat Feb 28 14:21:05 2009 +0300
@@ -21,11 +21,14 @@
#define MGT_HEADERS_H
#include <stdint.h>
+#include <vector>
#include "ns3/header.h"
#include "status-code.h"
#include "capability-information.h"
#include "supported-rates.h"
+#include "mesh-configuration-element.h"
+#include "mesh-wifi-beacon-timing-element.h"
#include "ssid.h"
namespace ns3 {
@@ -117,6 +120,8 @@
void SetBeaconIntervalUs (uint64_t us);
void SetSupportedRates (SupportedRates rates);
+ uint64_t GetTimestamp();
+
static TypeId GetTypeId (void);
virtual TypeId GetInstanceTypeId (void) const;
virtual void Print (std::ostream &os) const;
@@ -125,6 +130,7 @@
virtual uint32_t Deserialize (Buffer::Iterator start);
private:
+ uint64_t m_timestamp;
Ssid m_ssid;
uint64_t m_beaconInterval;
SupportedRates m_rates;
@@ -132,6 +138,22 @@
};
class MgtBeaconHeader : public MgtProbeResponseHeader {};
+class MgtMeshBeaconHeader : public MgtBeaconHeader
+{
+ public:
+ void SetMeshConfigurationElement(MeshConfigurationElement mesh_config);
+ void SetWifiBeaconTimingElement(WifiBeaconTimingElement wifi_timing);
+ MeshConfigurationElement GetMeshConfigurationElement();
+ WifiBeaconTimingElement GetWifiBeaconTimingElement();
+ virtual uint32_t GetSerializedSize (void) const;
+ virtual void Serialize (Buffer::Iterator start) const;
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+
+ private:
+ MeshConfigurationElement m_meshConfig;
+ WifiBeaconTimingElement m_meshTiming;
+
+};
} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/tx-statistics.cc Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,186 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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 <andreev@iitp.ru>
+ */
+
+
+#include "ns3/tx-statistics.h"
+#include "ns3/assert.h"
+#include "ns3/log.h"
+
+NS_LOG_COMPONENT_DEFINE ("WifiTxStatistics");
+
+namespace ns3 {
+
+TypeId
+WifiTxStatistics::GetTypeId(void)
+{
+ static TypeId tid = TypeId("ns3::WifiTxStatistics")
+ .SetParent<Object> ()
+ .AddConstructor<WifiTxStatistics> ();
+ return tid;
+}
+WifiTxStatistics::WifiTxStatistics():
+ m_numOfGroups(10),
+ m_maxLength(2500)
+{
+}
+WifiTxStatistics::~WifiTxStatistics()
+{
+}
+void
+WifiTxStatistics::SetLengthDivisionParams(uint16_t maxLength, uint8_t numOfGroups)
+{
+
+}
+void
+WifiTxStatistics::NotifyDataSent(uint16_t length, uint32_t dataRate)
+{
+ m_currentSize = length;
+ m_currentRate = dataRate;
+}
+
+WifiTxStatistics::RATE_STAT::iterator
+WifiTxStatistics::FillCurrentStatPosition(uint16_t length, uint32_t dataRate)
+{
+ uint16_t group = (length/(m_maxLength/m_numOfGroups)+1)* (m_maxLength/m_numOfGroups);
+#if 0
+ for(RATE_LENGTH_STAT::iterator i = m_stats.begin(); i != m_stats.end(); i ++)
+ if(i->first == )
+#endif
+ RATE_LENGTH_STAT::iterator lengthPos = m_stats.find(group);
+ if(lengthPos == m_stats.end())
+ {
+ RATE_STAT newStat;
+ m_stats[group] = newStat;
+ }
+ lengthPos = m_stats.find(group);
+ NS_ASSERT(lengthPos != m_stats.end());
+ RATE_STAT::iterator ratePos = lengthPos->second.find(dataRate);
+ if(ratePos == lengthPos->second.end())
+ {
+ SIMPLE_STAT newStat;
+ newStat.packetsFailed =0;
+ newStat.packetsRetried = 0;
+ newStat.packetsAcked = 0;
+ newStat.rtsFailed = 0;
+ newStat.rtsRetried = 0;
+ newStat.rtsAcked = 0;
+ newStat.bytesFailed = 0;
+ newStat.bytesRetried = 0;
+ newStat.bytesAcked = 0;
+ lengthPos->second[dataRate] = newStat;
+ }
+ ratePos = lengthPos->second.find(dataRate);
+ NS_ASSERT(ratePos != lengthPos->second.end());
+ return ratePos;
+}
+
+void
+WifiTxStatistics::NotifyDataFailed()
+{
+ RATE_STAT::iterator ratePos = FillCurrentStatPosition(m_currentSize, m_currentRate);
+ ratePos->second.packetsFailed++;
+ ratePos->second.bytesFailed += m_currentSize;
+
+}
+
+void
+WifiTxStatistics::NotifyGotAck(uint32_t retryCounter)
+{
+ RATE_STAT::iterator ratePos = FillCurrentStatPosition(m_currentSize, m_currentRate);
+ ratePos->second.packetsAcked++;
+ ratePos->second.packetsRetried += retryCounter;
+ ratePos->second.bytesAcked+= m_currentSize;
+ ratePos->second.bytesRetried += (m_currentSize*retryCounter);
+}
+
+void
+WifiTxStatistics::NotifyRtsSend(uint32_t rtsRate, uint32_t dataLength)
+{
+ m_currentSize = dataLength;
+ m_currentRate = rtsRate;
+}
+
+void
+WifiTxStatistics::NotifyRtsFailed()
+{
+ RATE_STAT::iterator ratePos = FillCurrentStatPosition(m_currentSize, m_currentRate);
+ ratePos->second.rtsFailed++;
+ ratePos->second.bytesFailed += m_currentSize;
+}
+
+void
+WifiTxStatistics::NotifyRtsSuccess(uint32_t retryCounter)
+{
+ RATE_STAT::iterator ratePos = FillCurrentStatPosition(m_currentSize, m_currentRate);
+ ratePos->second.rtsAcked++;
+ ratePos->second.rtsRetried += retryCounter;
+ ratePos->second.bytesAcked += m_currentSize;
+ ratePos->second.bytesRetried += (m_currentSize*retryCounter);
+}
+
+void
+WifiTxStatistics::ResetStatistics()
+{
+ for(RATE_LENGTH_STAT::iterator lengthPos = m_stats.begin(); lengthPos != m_stats.end(); lengthPos++)
+ lengthPos->second.clear();
+}
+#if 0
+WifiTxStatistics::SIMPLE_STAT
+WifiTxStatistics::GetTxStatCommon()
+{
+}
+
+WifiTxStatistics::RATE_STAT
+WifiTxStatistics::GetTxStatRate()
+{
+}
+
+WifiTxStatistics::LENGTH_STAT
+WifiTxStatistics::GetTxStatLength()
+{
+}
+#endif
+WifiTxStatistics::TX_STATISTICS
+WifiTxStatistics::GetTxStatRateLength()
+{
+ TX_STATISTICS retval;
+ retval.statistics = m_stats;
+ retval.lengthInterval = m_maxLength / m_numOfGroups;
+ retval.maxLength = m_maxLength;
+ return retval;
+}
+#if 0
+void
+WifiTxStatistics::Print()
+{
+ for(RATE_LENGTH_STAT::iterator lengthPos = m_stats.begin(); lengthPos != m_stats.end(); lengthPos++)
+ {
+ NS_LOG_UNCOND("\tGROUP = " <<lengthPos->first);
+ for(RATE_STAT::iterator ratePos = lengthPos->second.begin(); ratePos != lengthPos->second.end(); ratePos ++)
+ {
+ NS_LOG_UNCOND("Rate is "<<ratePos->first
+ <<": SUCCESS = "<<ratePos->second.packetsAcked
+ <<", RRETRY = " <<ratePos->second.packetsRetried
+ <<", FAILURE = "<<ratePos->second.packetsFailed);
+ }
+ }
+}
+#endif
+} //namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/tx-statistics.h Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,104 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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 <andreev@iitp.ru>
+ */
+
+
+#ifndef TX_STAT_H
+#define TX_STAT_H
+
+#include <map>
+#include <utility>
+#include "ns3/mac48-address.h"
+#include "ns3/packet.h"
+#include "ns3/object.h"
+#include "ns3/traced-value.h"
+#include "wifi-mode.h"
+
+namespace ns3 {
+ class WifiTxStatistics : public Object
+ {
+ public:
+ static TypeId GetTypeId(void);
+ WifiTxStatistics();
+ ~WifiTxStatistics();
+
+ struct TxStat
+ {
+ /**
+ * Packet counters:
+ */
+ uint32_t packetsFailed;
+ uint32_t packetsRetried;
+ uint32_t packetsAcked;
+ /**
+ * RTS counters:
+ */
+ uint32_t rtsFailed;
+ uint32_t rtsRetried;
+ uint32_t rtsAcked;
+ /**
+ * Byte counters:
+ */
+ uint64_t bytesFailed;
+ uint64_t bytesRetried;
+ uint64_t bytesAcked;
+ };
+ typedef struct TxStat SIMPLE_STAT;
+ typedef std::map<uint32_t, SIMPLE_STAT> RATE_STAT;
+#if 0
+ typedef std::map<uint16_t, SIMPLE_STAT> LENGTH_STAT;
+#endif
+ typedef std::map<uint16_t, RATE_STAT> RATE_LENGTH_STAT;
+
+ void SetLengthDivisionParams(uint16_t maxLength, uint8_t numOfGroups);
+
+ void NotifyDataSent(uint16_t length, uint32_t dataRate);
+ void NotifyDataFailed();
+ void NotifyGotAck(uint32_t retryCounter);
+
+ void NotifyRtsSend(uint32_t rtsRate, uint32_t dataLength);
+ void NotifyRtsRetried();
+ void NotifyRtsFailed();
+ void NotifyRtsSuccess(uint32_t retryCounter);
+
+ void ResetStatistics();
+#if 0
+ SIMPLE_STAT GetTxStatCommon();
+ RATE_STAT GetTxStatRate();
+ LENGTH_STAT GetTxStatLength();
+#endif
+ typedef struct {
+ RATE_LENGTH_STAT statistics;
+ uint16_t lengthInterval;
+ uint16_t maxLength;
+ } TX_STATISTICS;
+ TX_STATISTICS GetTxStatRateLength();
+ private:
+ RATE_STAT::iterator FillCurrentStatPosition(uint16_t length, uint32_t dataRate);
+ //DEBUG PURPOSE
+ //void Print();
+ RATE_LENGTH_STAT m_stats;
+ bool m_isTx;
+ uint8_t m_numOfGroups;
+ uint16_t m_maxLength;
+ uint16_t m_currentSize;
+ uint32_t m_currentRate;
+ };
+} //namespace ns3
+#endif
--- a/src/devices/wifi/wifi-mac-header.cc Wed Feb 25 12:27:00 2009 -0500
+++ b/src/devices/wifi/wifi-mac-header.cc Sat Feb 28 14:21:05 2009 +0300
@@ -125,6 +125,13 @@
m_ctrlType = TYPE_DATA;
m_ctrlSubtype = 0;
}
+void
+WifiMacHeader::SetMultihopAction (void)
+{
+ m_ctrlType = TYPE_MGT;
+ m_ctrlSubtype = 15;
+}
+
void
WifiMacHeader::SetType (enum WifiMacType_e type)
{
@@ -188,6 +195,9 @@
case WIFI_MAC_MGT_DEAUTHENTICATION:
m_ctrlType = TYPE_MGT;
m_ctrlSubtype = 12;
+ case WIFI_MAC_MGT_MULTIHOP_ACTION:
+ m_ctrlType = TYPE_MGT;
+ m_ctrlSubtype = 15;
break;
case WIFI_MAC_DATA:
@@ -360,6 +370,9 @@
case 12:
return WIFI_MAC_MGT_DEAUTHENTICATION;
break;
+ case 15:
+ return WIFI_MAC_MGT_MULTIHOP_ACTION;
+ break;
}
break;
@@ -553,6 +566,11 @@
{
return (GetType () == WIFI_MAC_MGT_DEAUTHENTICATION)?true:false;
}
+bool
+WifiMacHeader::IsMultihopAction (void) const
+{
+ return (GetType () == WIFI_MAC_MGT_MULTIHOP_ACTION)?true:false;
+}
uint16_t
@@ -861,6 +879,7 @@
case WIFI_MAC_QOSDATA_NULL:
case WIFI_MAC_QOSDATA_NULL_CFPOLL:
case WIFI_MAC_QOSDATA_NULL_CFACK_CFPOLL:
+ case WIFI_MAC_MGT_MULTIHOP_ACTION:
break;
}
}
@@ -961,4 +980,338 @@
return i.GetDistanceFrom (start);
}
+/***********************************************************
+ * Here Mesh Mac Header functionality is defined.
+ ***********************************************************/
+TypeId
+WifiMeshHeader::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::WifiMeshHeader")
+ .SetParent<Header> ()
+ .AddConstructor<WifiMeshHeader> ()
+ ;
+ return tid;
+}
+
+WifiMeshHeader::WifiMeshHeader()
+{
+ m_meshFlags = 0;
+}
+
+WifiMeshHeader::~WifiMeshHeader()
+{
+}
+
+TypeId
+WifiMeshHeader::GetInstanceTypeId (void) const
+{
+ return GetTypeId ();
+}
+
+void
+WifiMeshHeader::SetAddr5 (Mac48Address address)
+{
+ m_addr5 = address;
+}
+
+void
+WifiMeshHeader::SetAddr6 (Mac48Address address)
+{
+ m_addr6 = address;
+}
+
+void
+WifiMeshHeader::SetAddr7 (Mac48Address address)
+{
+ m_addr7 = address;
+}
+
+Mac48Address
+WifiMeshHeader::GetAddr5 ()
+{
+ return m_addr5;
+}
+
+Mac48Address
+WifiMeshHeader::GetAddr6 ()
+{
+ return m_addr6;
+}
+
+Mac48Address
+WifiMeshHeader::GetAddr7 ()
+{
+ return m_addr7;
+}
+
+void
+WifiMeshHeader::SetMeshSeqno (uint32_t seqno)
+{
+ m_meshSeqno = seqno;
+}
+
+uint32_t
+WifiMeshHeader::GetMeshSeqno ()
+{
+ return m_meshSeqno;
+}
+
+void
+WifiMeshHeader::SetMeshTtl (uint8_t TTL)
+{
+ m_meshTtl = TTL;
+}
+
+uint8_t
+WifiMeshHeader::GetMeshTtl ()
+{
+ return m_meshTtl;
+}
+
+void
+WifiMeshHeader::SetAddressExt (uint8_t num_of_addresses)
+{
+ if (num_of_addresses > 3)
+ return;
+ m_meshFlags = MESH_AE_MASK| (num_of_addresses << MESH_AE_SHIFT);
+}
+
+uint8_t
+WifiMeshHeader::GetAddressExt ()
+{
+ return ((MESH_AE_MASK & m_meshFlags) >> MESH_AE_SHIFT);
+}
+
+
+uint32_t
+WifiMeshHeader::GetSerializedSize (void) const
+{
+ return 6 + ((MESH_AE_MASK & m_meshFlags) >> MESH_AE_SHIFT)*6;
+}
+
+void
+WifiMeshHeader::Serialize (Buffer::Iterator start) const
+{
+ Buffer::Iterator i = start;
+ i.WriteU8(m_meshFlags);
+ i.WriteU8(m_meshTtl);
+ i.WriteU32(m_meshSeqno);
+ uint8_t addresses_to_add = (m_meshFlags & MESH_AE_MASK) >> MESH_AE_SHIFT;
+ //Writing Address extensions:
+ if(addresses_to_add > 0)
+ WriteTo (i, m_addr5);
+ if(addresses_to_add > 1)
+ WriteTo (i, m_addr6);
+ if(addresses_to_add > 2)
+ WriteTo (i, m_addr7);
+}
+
+uint32_t
+WifiMeshHeader::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+ uint8_t addresses_to_read = 0;
+ m_meshFlags = i.ReadU8();
+ m_meshTtl = i.ReadU8();
+ m_meshSeqno = i.ReadU32();
+ addresses_to_read = (m_meshFlags & MESH_AE_MASK) >> MESH_AE_SHIFT;
+ if(addresses_to_read > 0)
+ ReadFrom (i, m_addr5);
+ if(addresses_to_read > 1)
+ ReadFrom (i, m_addr6);
+ if(addresses_to_read > 2)
+ ReadFrom (i, m_addr7);
+ return i.GetDistanceFrom(start);
+}
+void
+WifiMeshHeader::Print (std::ostream &os) const
+{
+ os << "flags" << m_meshFlags
+ << "ttl" << m_meshTtl
+ << "seqno" << m_meshSeqno;
+}
+/**********************************************************
+ * MultihopActionFrame
+ **********************************************************/
+WifiMeshMultihopActionHeader::WifiMeshMultihopActionHeader ()
+{
+}
+
+WifiMeshMultihopActionHeader::~WifiMeshMultihopActionHeader ()
+{
+}
+
+void
+WifiMeshMultihopActionHeader::SetAction(
+ enum WifiMeshMultihopActionHeader::CategoryValue type,
+ WifiMeshMultihopActionHeader::ACTION_VALUE action)
+{
+ switch(type)
+ {
+ case MESH_PEER_LINK_MGT:
+ m_category = 4;
+ switch (action.peerLink)
+ {
+ case PEER_LINK_OPEN:
+ m_actionValue = 0;
+ break;
+ case PEER_LINK_CONFIRM:
+ m_actionValue = 1;
+ break;
+ case PEER_LINK_CLOSE:
+ m_actionValue = 2;
+ break;
+ };
+ break;
+ case MESH_LINK_METRIC:
+ m_category = 5;
+ break;
+ case MESH_PATH_SELECTION:
+ m_category = 6;
+ switch(action.pathSelection)
+ {
+ case PATH_REQUEST:
+ m_actionValue = 0;
+ break;
+ case PATH_REPLY:
+ m_actionValue = 1;
+ break;
+ case PATH_ERROR:
+ m_actionValue = 2;
+ break;
+ case ROOT_ANNOUNCEMENT:
+ m_actionValue = 3;
+ break;
+ };
+ break;
+ case MESH_INTERWORK_ACTION:
+ m_category = 7;
+ break;
+ case MESH_RESOURCE_COORDINATION:
+ m_category = 8;
+ break;
+ };
+}
+
+enum WifiMeshMultihopActionHeader::CategoryValue
+WifiMeshMultihopActionHeader::GetCategory()
+{
+ switch(m_category)
+ {
+ case 4:
+ return MESH_PEER_LINK_MGT;
+ case 5:
+ return MESH_LINK_METRIC;
+ case 6:
+ return MESH_PATH_SELECTION;
+ case 7:
+ return MESH_INTERWORK_ACTION;
+ case 8:
+ return MESH_RESOURCE_COORDINATION;
+ default:
+ NS_ASSERT(false);
+ return MESH_PEER_LINK_MGT;
+ }
+}
+
+WifiMeshMultihopActionHeader::ACTION_VALUE
+WifiMeshMultihopActionHeader::GetAction()
+{
+ ACTION_VALUE retval;
+ switch(m_category)
+ {
+ case 4:
+ //MESH_PEER_LINK_MGT;
+ switch(m_actionValue)
+ {
+ case 0:
+ retval.peerLink = PEER_LINK_OPEN;
+ return retval;
+ case 1:
+ retval.peerLink = PEER_LINK_CONFIRM;
+ return retval;
+ case 2:
+ retval.peerLink = PEER_LINK_CLOSE;
+ return retval;
+ default:
+ NS_ASSERT(false);
+ return retval;
+
+ }
+ case 5:
+ //MESH_LINK_METRIC;
+ case 6:
+ //MESH_PATH_SELECTION;
+ switch(m_actionValue)
+ {
+ case 0:
+ retval.pathSelection = PATH_REQUEST;
+ return retval;
+ case 1:
+ retval.pathSelection = PATH_REPLY;
+ return retval;
+ case 2:
+ retval.pathSelection = PATH_ERROR;
+ return retval;
+ case 3:
+ retval.pathSelection = ROOT_ANNOUNCEMENT;
+ return retval;
+ default:
+ NS_ASSERT(false);
+ return retval;
+ }
+
+ case 7:
+ //MESH_INTERWORK_ACTION;
+ case 8:
+ //MESH_RESOURCE_COORDINATION;
+ default:
+ NS_ASSERT(false);
+ return retval;
+ }
+}
+
+TypeId
+WifiMeshMultihopActionHeader::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::WifiMeshMultihopActionHeader")
+ .SetParent<Header> ()
+ .AddConstructor<WifiMeshMultihopActionHeader> ()
+ ;
+ return tid;
+}
+
+TypeId
+WifiMeshMultihopActionHeader::GetInstanceTypeId (void) const
+{
+ return GetTypeId();
+}
+
+void
+WifiMeshMultihopActionHeader::Print (std::ostream &os) const
+{
+}
+
+uint32_t
+WifiMeshMultihopActionHeader::GetSerializedSize (void) const
+{
+ return 2;
+}
+
+void
+WifiMeshMultihopActionHeader::Serialize (Buffer::Iterator start) const
+{
+ start.WriteU8(m_category);
+ start.WriteU8(m_actionValue);
+}
+
+uint32_t
+WifiMeshMultihopActionHeader::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+ m_category = i.ReadU8();
+ m_actionValue = i.ReadU8();
+ return i.GetDistanceFrom(start);
+}
+
} // namespace ns3
--- a/src/devices/wifi/wifi-mac-header.h Wed Feb 25 12:27:00 2009 -0500
+++ b/src/devices/wifi/wifi-mac-header.h Sat Feb 28 14:21:05 2009 +0300
@@ -44,6 +44,8 @@
WIFI_MAC_MGT_PROBE_RESPONSE,
WIFI_MAC_MGT_AUTHENTICATION,
WIFI_MAC_MGT_DEAUTHENTICATION,
+//Mesh management frames:
+ WIFI_MAC_MGT_MULTIHOP_ACTION,
WIFI_MAC_DATA,
WIFI_MAC_DATA_CFACK,
@@ -83,6 +85,7 @@
void SetProbeResp (void);
void SetBeacon (void);
void SetTypeData (void);
+ void SetMultihopAction();
void SetDsFrom (void);
void SetDsNotFrom (void);
void SetDsTo (void);
@@ -129,6 +132,7 @@
bool IsDisassociation (void) const;
bool IsAuthentication (void) const;
bool IsDeauthentication (void) const;
+ bool IsMultihopAction(void) const;
uint16_t GetRawDuration (void) const;
Time GetDuration (void) const;
uint16_t GetSequenceControl (void) const;
@@ -176,7 +180,120 @@
uint8_t m_qosAckPolicy;
uint16_t m_qosStuff;
};
+class WifiMeshHeader : public Header //7.1.3.5b
+{
+ public:
+ WifiMeshHeader ();
+ ~WifiMeshHeader ();
+ static TypeId GetTypeId (void);
+ virtual TypeId GetInstanceTypeId (void) const;
+ virtual void Print (std::ostream &os) const;
+ void SetAddr5 (Mac48Address address);
+ void SetAddr6 (Mac48Address address);
+ void SetAddr7 (Mac48Address address);
+ Mac48Address GetAddr5 ();
+ Mac48Address GetAddr6 ();
+ Mac48Address GetAddr7 ();
+
+ void SetMeshSeqno (uint32_t seqno);
+ uint32_t GetMeshSeqno ();
+
+ void SetMeshTtl (uint8_t TTL);
+ uint8_t GetMeshTtl ();
+
+#define MESH_AE_MASK 0xc0
+#define MESH_AE_SHIFT 6
+ void SetAddressExt (uint8_t num_of_addresses);
+ uint8_t GetAddressExt ();
+
+ virtual uint32_t GetSerializedSize (void) const;
+ virtual void Serialize (Buffer::Iterator start) const;
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+ private:
+ uint8_t m_meshFlags;
+ uint8_t m_meshTtl;
+ uint32_t m_meshSeqno;
+ Mac48Address m_addr5;
+ Mac48Address m_addr6;
+ Mac48Address m_addr7;
+};
+class WifiMeshMultihopActionHeader : public Header //7.2.3.14
+{
+ //Multichop action frame consists of Mesh header, Action, and
+ //the last information. Mesh header is present within all data
+ //frames and multihop action frames, so Mesh header is a
+ //separate structure. Each MultihopAction frames (frames like
+ //PREQ, PREP and other) start form Category field and Action
+ //value field, so the Multihop Action Frame should containt
+ //three fields: Category, Action Value;
+ public:
+ WifiMeshMultihopActionHeader ();
+ ~WifiMeshMultihopActionHeader ();
+ enum CategoryValue //table 7-24 staring from 4
+ {
+ MESH_PEER_LINK_MGT =4,
+ MESH_LINK_METRIC,
+ MESH_PATH_SELECTION,
+ MESH_INTERWORK_ACTION,
+ MESH_RESOURCE_COORDINATION,
+ };
+ enum PeerLinkMgtActionValue
+ {
+ PEER_LINK_OPEN = 0,
+ PEER_LINK_CONFIRM,
+ PEER_LINK_CLOSE,
+ };
+ enum LinkMetricActionValue
+ {
+ LINK_METRIC_REQUEST = 0,
+ LINK_METRIC_REPORT,
+ };
+ enum PathSelectionActionValue
+ {
+ PATH_REQUEST = 0,
+ PATH_REPLY,
+ PATH_ERROR,
+ ROOT_ANNOUNCEMENT,
+ };
+ enum InterworkActionValue
+ {
+ PORTAL_ANNOUNCEMENT = 0,
+ };
+ enum ResourceCoordinationActionValue
+ {
+ CONGESTION_CONTROL_NOTIFICATION = 0,
+ MDA_SETUP_REQUEST,
+ MDA_SETUP_REPLY,
+ MDAOP_ADVERTISMENT_REQUEST,
+ MDAOP_ADVERTISMENTS,
+ MDAOP_SET_TEARDOWN,
+ BEACON_TIMING_REQUEST,
+ BEACON_TIMING_RESPONSE,
+ TBTT_ADJASTMENT_REQUEST,
+ MESH_CHANNEL_SWITCH_ANNOUNCEMENT,
+ };
+ typedef union
+ {
+ enum PeerLinkMgtActionValue peerLink;
+ enum LinkMetricActionValue linkMetrtic;
+ enum PathSelectionActionValue pathSelection;
+ enum InterworkActionValue interwork;
+ enum ResourceCoordinationActionValue resourceCoordination;
+ } ACTION_VALUE;
+ void SetAction(enum CategoryValue type,ACTION_VALUE action);
+ enum CategoryValue GetCategory();
+ ACTION_VALUE GetAction();
+ static TypeId GetTypeId (void);
+ virtual TypeId GetInstanceTypeId (void) const;
+ virtual void Print (std::ostream &os) const;
+ virtual uint32_t GetSerializedSize (void) const;
+ virtual void Serialize (Buffer::Iterator start) const;
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+ private:
+ uint8_t m_category;
+ uint8_t m_actionValue;
+};
} // namespace ns3
--- a/src/devices/wifi/wifi-remote-station-manager.cc Wed Feb 25 12:27:00 2009 -0500
+++ b/src/devices/wifi/wifi-remote-station-manager.cc Sat Feb 28 14:21:05 2009 +0300
@@ -422,7 +422,9 @@
: m_state (BRAND_NEW),
m_ssrc (0),
m_slrc (0)
-{}
+{
+ m_txStat = CreateObject<WifiTxStatistics> ();
+}
WifiRemoteStation::~WifiRemoteStation ()
{}
@@ -543,7 +545,7 @@
WifiMode
WifiRemoteStation::GetAckMode (WifiMode dataMode)
{
- return GetControlAnswerMode (dataMode);
+ return dataMode;
}
uint32_t
@@ -572,12 +574,14 @@
{
if (GetManager ()->IsLowLatency ())
{
+ m_txStat->NotifyDataSent(fullPacketSize, DoGetDataMode (fullPacketSize).GetDataRate());
return DoGetDataMode (fullPacketSize);
}
TxModeTag tag;
bool found;
found = packet->FindFirstMatchingTag (tag);
NS_ASSERT (found);
+ m_txStat->NotifyDataSent(fullPacketSize, tag.GetDataMode ().GetDataRate());
return tag.GetDataMode ();
}
WifiMode
@@ -585,12 +589,14 @@
{
if (GetManager ()->IsLowLatency ())
{
+ m_txStat->NotifyDataSent(packet->GetSize() +36, DoGetRtsMode().GetDataRate());
return DoGetRtsMode ();
}
TxModeTag tag;
bool found;
found = packet->FindFirstMatchingTag (tag);
NS_ASSERT (found);
+ m_txStat->NotifyDataSent(packet->GetSize() +36, tag.GetRtsMode ().GetDataRate());
return tag.GetRtsMode ();
}
@@ -693,6 +699,7 @@
void
WifiRemoteStation::ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
{
+ m_txStat->NotifyRtsSuccess(m_ssrc);
m_ssrc = 0;
DoReportRtsOk (ctsSnr, ctsMode, rtsSnr);
}
@@ -700,6 +707,7 @@
void
WifiRemoteStation::ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
{
+ m_txStat->NotifyGotAck(m_slrc);
m_slrc = 0;
DoReportDataOk (ackSnr, ackMode, dataSnr);
}
@@ -708,6 +716,7 @@
WifiRemoteStation::ReportFinalRtsFailed (void)
{
m_ssrc = 0;
+ m_txStat->NotifyRtsFailed();
DoReportFinalRtsFailed ();
}
@@ -715,6 +724,7 @@
WifiRemoteStation::ReportFinalDataFailed (void)
{
m_slrc = 0;
+ m_txStat->NotifyDataFailed();
DoReportFinalDataFailed ();
}
@@ -723,5 +733,16 @@
{
DoReportRxOk (rxSnr, txMode);
}
+WifiTxStatistics::TX_STATISTICS
+WifiRemoteStation::GetTxStat()
+{
+ return m_txStat->GetTxStatRateLength();
+}
+void
+WifiRemoteStation::ResetTxStat()
+{
+ m_txStat->ResetStatistics();
+}
+
} // namespace ns3
--- a/src/devices/wifi/wifi-remote-station-manager.h Wed Feb 25 12:27:00 2009 -0500
+++ b/src/devices/wifi/wifi-remote-station-manager.h Sat Feb 28 14:21:05 2009 +0300
@@ -26,6 +26,7 @@
#include "ns3/packet.h"
#include "ns3/object.h"
#include "ns3/traced-value.h"
+#include "ns3/tx-statistics.h"
#include "wifi-mode.h"
namespace ns3 {
@@ -257,6 +258,8 @@
* handshake.
*/
WifiMode GetAckMode (WifiMode dataMode);
+ WifiTxStatistics::TX_STATISTICS GetTxStat();
+ void ResetTxStat();
private:
typedef std::vector<WifiMode> SupportedModes;
@@ -286,6 +289,7 @@
SupportedModes m_modes;
TracedValue<uint32_t> m_ssrc;
TracedValue<uint32_t> m_slrc;
+ Ptr<WifiTxStatistics> m_txStat;
};
} // namespace ns3
--- a/src/devices/wifi/wscript Wed Feb 25 12:27:00 2009 -0500
+++ b/src/devices/wifi/wscript Sat Feb 28 14:21:05 2009 +0300
@@ -3,6 +3,7 @@
def build(bld):
obj = bld.create_ns3_module('wifi', ['node'])
obj.source = [
+ 'tx-statistics.cc',
'propagation-delay-model.cc',
'propagation-loss-model.cc',
'jakes-propagation-loss-model.cc',
@@ -35,6 +36,16 @@
'adhoc-wifi-mac.cc',
'nqap-wifi-mac.cc',
'nqsta-wifi-mac.cc',
+ 'mesh-wifi-mac.cc',
+ 'mesh-configuration-element.cc',
+ 'mesh-wifi-beacon-timing-element.cc',
+ 'dot11s-peer-management-element.cc',
+ 'mesh-mgt-headers.cc',
+ 'mesh-wifi-peer-manager.cc',
+ 'mesh-wifi-rann-information-element.cc',
+ 'mesh-wifi-preq-information-element.cc',
+ 'mesh-wifi-perr-information-element.cc',
+ 'mesh-wifi-prep-information-element.cc',
'wifi-net-device.cc',
'arf-wifi-manager.cc',
'aarf-wifi-manager.cc',
@@ -44,10 +55,12 @@
'rraa-wifi-manager.cc',
'constant-rate-wifi-manager.cc',
'wifi-test.cc',
+ 'dot11s-parameters.cc',
]
headers = bld.new_task_gen('ns3header')
headers.module = 'wifi'
headers.source = [
+ 'tx-statistics.h',
'propagation-delay-model.h',
'propagation-loss-model.h',
'jakes-propagation-loss-model.h',
@@ -73,10 +86,25 @@
'adhoc-wifi-mac.h',
'nqsta-wifi-mac.h',
'nqap-wifi-mac.h',
+ 'mesh-wifi-mac.h',
'wifi-phy.h',
'supported-rates.h',
+ 'mgt-headers.h',
+ 'status-code.h',
+ 'capability-information.h',
+ 'mesh-configuration-element.h',
+ 'mesh-wifi-beacon-timing-element.h',
+ 'dot11s-peer-management-element.h',
+ 'mesh-mgt-headers.h',
+ 'mesh-wifi-peer-manager.h',
+ 'mesh-wifi-rann-information-element.h',
+ 'mesh-wifi-preq-information-element.h',
+ 'mesh-wifi-perr-information-element.h',
+ 'mesh-wifi-prep-information-element.h',
'error-rate-model.h',
'yans-error-rate-model.h',
+ 'dot11s-codes.h',
+ 'dot11s-parameters.h',
]
obj = bld.create_ns3_program('wifi-phy-test',
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/hwmp-helper.cc Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,21 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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 <andreev@iitp.ru>
+ */
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/hwmp-helper.h Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,21 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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 <andreev@iitp.ru>
+ */
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/mesh-wifi-helper.cc Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,220 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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
+ *
+ * Authors: Kirill Andreev <andreev@iitp.ru>
+ * Evgeny Khorov <horov@frtk.ru>
+ */
+
+
+#include "mesh-wifi-helper.h"
+#include "ns3/wifi-net-device.h"
+#include "ns3/wifi-mac.h"
+#include "ns3/wifi-phy.h"
+#include "ns3/wifi-remote-station-manager.h"
+#include "ns3/wifi-channel.h"
+#include "ns3/yans-wifi-channel.h"
+#include "ns3/propagation-delay-model.h"
+#include "ns3/propagation-loss-model.h"
+#include "ns3/mobility-model.h"
+#include "ns3/log.h"
+#include "ns3/pcap-writer.h"
+#include "ns3/config.h"
+#include "ns3/simulator.h"
+#include "ns3/hwmp.h"
+
+NS_LOG_COMPONENT_DEFINE ("MeshWifiHelper");
+namespace ns3
+{
+
+MeshWifiHelper::MeshWifiHelper ()
+{
+ //m_deviceFactory.SetTypeId ("ns3::L2RoutingNetDevice");
+}
+
+MeshWifiHelper::~MeshWifiHelper ()
+{
+}
+
+void
+MeshWifiHelper::SetRemoteStationManager (std::string type,
+ std::string n0, const AttributeValue &v0,
+ std::string n1, const AttributeValue &v1,
+ std::string n2, const AttributeValue &v2,
+ std::string n3, const AttributeValue &v3,
+ std::string n4, const AttributeValue &v4,
+ std::string n5, const AttributeValue &v5,
+ std::string n6, const AttributeValue &v6,
+ std::string n7, const AttributeValue &v7)
+{
+ m_stationManager = ObjectFactory ();
+ m_stationManager.SetTypeId (type);
+ m_stationManager.Set (n0, v0);
+ m_stationManager.Set (n1, v1);
+ m_stationManager.Set (n2, v2);
+ m_stationManager.Set (n3, v3);
+ m_stationManager.Set (n4, v4);
+ m_stationManager.Set (n5, v5);
+ m_stationManager.Set (n6, v6);
+ m_stationManager.Set (n7, v7);
+}
+
+void
+MeshWifiHelper::SetMac (std::string type,
+ std::string n0, const AttributeValue &v0,
+ std::string n1, const AttributeValue &v1,
+ std::string n2, const AttributeValue &v2,
+ std::string n3, const AttributeValue &v3,
+ std::string n4, const AttributeValue &v4,
+ std::string n5, const AttributeValue &v5,
+ std::string n6, const AttributeValue &v6,
+ std::string n7, const AttributeValue &v7)
+{
+ m_meshMac = ObjectFactory ();
+ m_meshMac.SetTypeId (type);
+ m_meshMac.Set (n0, v0);
+ m_meshMac.Set (n1, v1);
+ m_meshMac.Set (n2, v2);
+ m_meshMac.Set (n3, v3);
+ m_meshMac.Set (n4, v4);
+ m_meshMac.Set (n5, v5);
+ m_meshMac.Set (n6, v6);
+ m_meshMac.Set (n7, v7);
+}
+
+void
+MeshWifiHelper::SetL2RoutingProtocol(std::string type,
+ std::string n0, const AttributeValue &v0,
+ std::string n1, const AttributeValue &v1,
+ std::string n2, const AttributeValue &v2,
+ std::string n3, const AttributeValue &v3,
+ std::string n4, const AttributeValue &v4,
+ std::string n5, const AttributeValue &v5,
+ std::string n6, const AttributeValue &v6,
+ std::string n7, const AttributeValue &v7,
+ std::string n8, const AttributeValue &v8,
+ std::string n9, const AttributeValue &v9)
+{
+ m_routingProtocol = ObjectFactory ();
+ m_routingProtocol.SetTypeId (type);
+ m_routingProtocol.Set (n0, v0);
+ m_routingProtocol.Set (n1, v1);
+ m_routingProtocol.Set (n2, v2);
+ m_routingProtocol.Set (n3, v3);
+ m_routingProtocol.Set (n4, v4);
+ m_routingProtocol.Set (n5, v5);
+ m_routingProtocol.Set (n6, v6);
+ m_routingProtocol.Set (n7, v7);
+}
+
+void
+MeshWifiHelper::SetL2RoutingNetDevice(std::string type,
+ std::string n0, const AttributeValue &v0,
+ std::string n1, const AttributeValue &v1,
+ std::string n2, const AttributeValue &v2,
+ std::string n3, const AttributeValue &v3,
+ std::string n4, const AttributeValue &v4,
+ std::string n5, const AttributeValue &v5,
+ std::string n6, const AttributeValue &v6,
+ std::string n7, const AttributeValue &v7,
+ std::string n8, const AttributeValue &v8,
+ std::string n9, const AttributeValue &v9)
+{
+ m_deviceFactory = ObjectFactory ();
+ m_deviceFactory.SetTypeId (type);
+ m_deviceFactory.Set (n0, v0);
+ m_deviceFactory.Set (n1, v1);
+ m_deviceFactory.Set (n2, v2);
+ m_deviceFactory.Set (n3, v3);
+ m_deviceFactory.Set (n4, v4);
+ m_deviceFactory.Set (n5, v5);
+ m_deviceFactory.Set (n6, v6);
+ m_deviceFactory.Set (n7, v7);
+}
+
+void
+MeshWifiHelper::SetPeerLinkManager (std::string type,
+ std::string n0, const AttributeValue &v0,
+ std::string n1, const AttributeValue &v1,
+ std::string n2, const AttributeValue &v2,
+ std::string n3, const AttributeValue &v3,
+ std::string n4, const AttributeValue &v4,
+ std::string n5, const AttributeValue &v5,
+ std::string n6, const AttributeValue &v6,
+ std::string n7, const AttributeValue &v7,
+ std::string n8, const AttributeValue &v8,
+ std::string n9, const AttributeValue &v9)
+{
+ m_peerManager = ObjectFactory ();
+ m_peerManager.SetTypeId (type);
+ m_peerManager.Set (n0, v0);
+ m_peerManager.Set (n1, v1);
+ m_peerManager.Set (n2, v2);
+ m_peerManager.Set (n3, v3);
+ m_peerManager.Set (n4, v4);
+ m_peerManager.Set (n5, v5);
+ m_peerManager.Set (n6, v6);
+ m_peerManager.Set (n7, v7);
+ m_peerManager.Set (n8, v8);
+ m_peerManager.Set (n9, v9);
+}
+
+NetDeviceContainer
+MeshWifiHelper::Install (const WifiPhyHelper &phyHelper, NodeContainer c, uint8_t numOfPorts) const
+{
+ NetDeviceContainer devices;
+ for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
+ {
+ Ptr<Node> node = *i;
+ Ptr<L2RoutingNetDevice> virtualDevice = m_deviceFactory.Create<L2RoutingNetDevice> ();
+ Ptr<WifiPeerManager>pPeer = m_peerManager.Create<WifiPeerManager > ();
+ devices.Add (virtualDevice);
+ std::vector<Ptr<WifiNetDevice> > nodeDevices;
+ for (uint8_t k=0; k<numOfPorts; k++)
+ {
+ Ptr<WifiNetDevice> device = CreateObject<WifiNetDevice> ();
+ Ptr<MeshWifiMac> mac = m_meshMac.Create<MeshWifiMac> ();
+ Ptr<WifiRemoteStationManager> manager = m_stationManager.Create<WifiRemoteStationManager> ();
+ Ptr<WifiPhy> phy = phyHelper.Create (node, device);
+ mac->SetAddress (Mac48Address::Allocate ());
+ device->SetMac (mac);
+ device->SetPhy (phy);
+ device->SetRemoteStationManager (manager);
+ //mac ->SetPeerLinkManager (pPeer);
+ //create L2RoutingNetDevice and add WifiNetDevice to it
+ node->AddDevice(device);
+ nodeDevices.push_back(device);
+ }
+ node -> AddDevice(virtualDevice);
+ for (std::vector<Ptr<WifiNetDevice> > ::iterator iter=nodeDevices.begin();iter!=nodeDevices.end(); ++iter)
+ virtualDevice->AddPort(*iter);
+ // nodeDevice.pop_back()
+ pPeer->AttachPorts(nodeDevices);
+ Ptr<L2RoutingProtocol> routingProtocol = m_routingProtocol.Create <L2RoutingProtocol>();
+ virtualDevice->AttachProtocol(routingProtocol);
+ //hwmp->SetRoot(device->GetIfIndex(), Seconds(5));
+ nodeDevices.clear();
+ }
+ return devices;
+}
+
+NetDeviceContainer
+MeshWifiHelper::Install (const WifiPhyHelper &phy, Ptr<Node> node, uint8_t numOfPorts) const
+{
+ return Install (phy, NodeContainer (node), numOfPorts);
+}
+
+} //namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/mesh-wifi-helper.h Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,124 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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
+ *
+ * Authors: Kirill Andreev <andreev@iitp.ru>
+ * Evgeny Khorov <horov@frtk.ru>
+ */
+
+
+#ifndef _MESHWIFIHELPER_H
+#define _MESHWIFIHELPER_H
+
+#include "ns3/wifi-net-device.h"
+#include "ns3/l2-routing-net-device.h"
+#include "ns3/mesh-wifi-mac.h"
+#include "ns3/wifi-channel.h"
+#include "ns3/mesh-wifi-peer-manager.h"
+#include "wifi-helper.h"
+
+namespace ns3
+{
+ class WifiChannel;
+
+ class MeshWifiHelper
+ {
+ public:
+ MeshWifiHelper ();
+ virtual ~MeshWifiHelper ();
+
+ /**
+ * \param type the type of peer manager to use.
+ * \param n0 the name of the attribute to set in the peer manager.
+ * \param v0 the value of the attribute to set in the peer manager.
+ * etc.
+ *
+ */
+ void SetRemoteStationManager (std::string type,
+ std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
+ std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
+ std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
+ std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
+ std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
+ std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
+ std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
+ std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
+
+ /**
+ * \param type the type of ns3::WifiMac to create.
+ * \param n0 the name of the attribute to set
+ * \param v0 the value of the attribute to set
+ *
+ * All the attributes specified in this method should exist
+ * in the requested mac.
+ */
+ void SetMac (std::string type,
+ std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
+ std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
+ std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
+ std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
+ std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
+ std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
+ std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
+ std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
+
+ void SetPeerLinkManager (std::string type,
+ std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
+ std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
+ std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
+ std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
+ std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
+ std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
+ std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
+ std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue (),
+ std::string n8 = "", const AttributeValue &v8 = EmptyAttributeValue (),
+ std::string n9 = "", const AttributeValue &v9 = EmptyAttributeValue ());
+ void SetL2RoutingProtocol(std::string type,
+ std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
+ std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
+ std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
+ std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
+ std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
+ std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
+ std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
+ std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue (),
+ std::string n8 = "", const AttributeValue &v8 = EmptyAttributeValue (),
+ std::string n9 = "", const AttributeValue &v9 = EmptyAttributeValue ());
+
+ void SetL2RoutingNetDevice(std::string type,
+ std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
+ std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
+ std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
+ std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
+ std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
+ std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
+ std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
+ std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue (),
+ std::string n8 = "", const AttributeValue &v8 = EmptyAttributeValue (),
+ std::string n9 = "", const AttributeValue &v9 = EmptyAttributeValue ());
+ NetDeviceContainer Install (const WifiPhyHelper &phyHelper, NodeContainer c, uint8_t numOfPorts) const;
+ NetDeviceContainer Install (const WifiPhyHelper &phy, Ptr<Node> node, uint8_t numOfPorts) const;
+ private:
+ ObjectFactory m_stationManager;
+ ObjectFactory m_meshMac;
+ ObjectFactory m_peerManager;
+ //L2routing:
+ ObjectFactory m_deviceFactory;
+ ObjectFactory m_routingProtocol;
+ };
+}//namespace ns3
+#endif /* _MESHWIFIHELPER_H */
+
--- a/src/helper/wscript Wed Feb 25 12:27:00 2009 -0500
+++ b/src/helper/wscript Sat Feb 28 14:21:05 2009 +0300
@@ -23,6 +23,8 @@
'bridge-helper.cc',
'yans-wifi-helper.cc',
'v4ping-helper.cc',
+ 'mesh-wifi-helper.cc',
+ 'hwmp-helper.cc',
]
headers = bld.new_task_gen('ns3header')
@@ -48,6 +50,8 @@
'bridge-helper.h',
'yans-wifi-helper.h',
'v4ping-helper.h',
+ 'mesh-wifi-helper.h',
+ 'hwmp-helper.h',
]
env = bld.env_of_name('default')
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/l2-routing-protocol.cc Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,43 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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 <andreev@iitp.ru>
+ */
+
+
+#include "ns3/object.h"
+#include "ns3/log.h"
+#include "l2-routing-protocol.h"
+
+NS_LOG_COMPONENT_DEFINE ("L2RoutingProtocol");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (L2RoutingProtocol);
+
+TypeId
+L2RoutingProtocol::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::L2RoutingProtocol")
+ .SetParent<Object> ();
+ return tid;
+}
+
+L2RoutingProtocol::~L2RoutingProtocol ()
+{}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/l2-routing-protocol.h Sat Feb 28 14:21:05 2009 +0300
@@ -0,0 +1,166 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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 <andreev@iitp.ru>
+ */
+
+
+#ifndef L2_ROUTING_PROTOCOL_H
+#define L2_ROUTING_PROTOCOL_H
+
+#include <list>
+#include <vector>
+#include <ostream>
+#include "ns3/nstime.h"
+#include "ns3/mac48-address.h"
+#include "ns3/net-device.h"
+#include "ns3/ptr.h"
+
+namespace ns3 {
+
+class Packet;
+/**
+ * \ingroup node
+ * \defgroup L2RoutingProtocol L2routingProtocol
+ */
+/**
+ * \ingroup L2RoutingProtocol
+ *
+ * \brief Base class for Layer 2 routing protocols
+ *
+ * \details Yhis class is an internal part of L2RoutingNetDevice class
+ * and this class implements interface between L2RoutingNetDevice and
+ * any protocol of MAC layer. This interface is similar to ipv4
+ * routiong protocol base class.
+ */
+class L2RoutingProtocol : public Object
+{
+ public:
+ static TypeId GetTypeId();
+ virtual ~L2RoutingProtocol();
+ /**
+ * \brief Callback to be invoked when route discovery
+ * procedure is completed
+ * \param bool flag indicating whether a route was
+ * actually found and all needed information is added
+ * to the packet succesfully
+ * \param Ptr<Packet> is packet, for which the route
+ * was resolved
+ * \attention All needed information for MAC layer
+ * must be stored in proper tags (like in case of
+ * HWMP, when WifiMacHeader needs address of next
+ * hop), or must be added as a packet header(if MAC
+ * does not need any additional information). So, the
+ * packet is returned back to L2RoutingNetDevice looks
+ * like a pure packet with ethernet header (i.e data
+ * +src +dst + protocol). All information needed to
+ * L2RoutingNetDevice is outgoing port ID.
+ * \param Mac48Address Source address of the packet
+ * \param Mac48Address Destiation address of the
+ * packet
+ * \param uint16_t Ethernet 'Protocol' field - stored
+ * in protocol, needed to form a proper MAC-layer
+ * header.
+ * \param uint32_t Output port
+ */
+typedef Callback<
+ void,
+ bool,
+ Ptr<Packet>,
+ Mac48Address,
+ Mac48Address,
+ uint16_t,
+ uint32_t
+ >
+ RouteReplyCallback;
+ /**
+ * \brief All packets must go through RequestRoute
+ * \returns Can the route be discovered or not
+ * \param sourceIface The incoming interface of the
+ * packet
+ * \param source Source address of the packet
+ * \param destination Destination address of the
+ * packet
+ * \param packet The packet to be resolved (needed the
+ * whole packet, because we can add tags or headers).
+ * \param protocolType The protocol ID (must be stored
+ * for route discovery time to form a proper MAC-layer
+ * header).
+ * \param routeReply Callback to be invoked after route
+ * discovery procedure.
+ */
+ virtual bool RequestRoute(
+ uint32_t sourceIface,
+ const Mac48Address source,
+ const Mac48Address destination,
+ Ptr<Packet> packet,
+ uint16_t protocolType,
+ RouteReplyCallback routeReply
+ ) = 0;
+ /**
+ * \brief Attaches ports to the L2RoutingProtocols,
+ * \returns False if there are not proper devices (like
+ * HWMP, which requires only WifiNetDevice and works
+ * only above MeshWifiMac).
+ * \param ports The array of ports.
+ */
+ virtual bool AttachPorts(std::vector<Ptr<NetDevice> > ports) = 0;
+ /**
+ * \brief L2Routing protocol must know the
+ * L2RoutingNetDevice ID to determine packets as 'came
+ * from upper layer' and 'received from network' (for
+ * example, to manage TTL).
+ * \param interface The interface ID of
+ * L2RoutingNetDevice
+ */
+ virtual void SetIfIndex(uint32_t interface) = 0;
+ protected:
+ struct QueuedPacket {
+ Ptr<Packet> pkt;
+ Mac48Address dst;
+ Mac48Address src;
+ uint16_t protocol;
+ uint32_t inPort;
+ RouteReplyCallback reply;
+ };
+ /**
+ * \brief Set Max queue size per destinztion
+ * \details Routing Queue is implemented inside the
+ * routing protocol and keeps one queue per
+ * destination (to make it easier to find resolved and
+ * timed out packets).
+ * \param maxPacketsPerDestination Packets per
+ * destination that can be stored inside protocol.
+ */
+ virtual void SetMaxQueueSize(int maxPacketsPerDestination) = 0;
+ /**
+ * \brief Queue packet with 'Ethernet header'
+ * \returns false if the queue is full.
+ */
+ virtual bool QueuePacket(struct QueuedPacket packet) = 0;
+ /**
+ * \brief Deques packet with 'Ethernet header'
+ * \returns Ptr<packet> (NULL if queue is empty), src,
+ * dst, protocol ID, incoming port ID, and reply
+ * callback
+ * \param destination The destination address, which
+ * identifyes queue.
+ */
+ virtual struct QueuedPacket DequeuePacket(Mac48Address destination) = 0;
+};
+}//namespace ns3
+#endif
--- a/src/node/wscript Wed Feb 25 12:27:00 2009 -0500
+++ b/src/node/wscript Sat Feb 28 14:21:05 2009 +0300
@@ -38,6 +38,7 @@
'ipv6-address.cc',
'ipv6-header.cc',
'ipv4-raw-socket-factory.cc',
+ 'l2-routing-protocol.cc',
]
headers = bld.new_task_gen('ns3header')
@@ -77,4 +78,5 @@
'ipv6-address.h',
'ipv6-header.h',
'ipv4-raw-socket-factory.h',
+ 'l2-routing-protocol.h',
]
--- a/src/wscript Wed Feb 25 12:27:00 2009 -0500
+++ b/src/wscript Sat Feb 28 14:21:05 2009 +0300
@@ -34,6 +34,8 @@
'helper',
'contrib/stats',
'applications/v4ping',
+ 'devices/l2-routing/l2-routing-main',
+ 'devices/l2-routing/l2-routing-hwmp',
)
def set_options(opt):