Merge 802.11s code.
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/examples/mesh.cc Sat Feb 28 14:21:05 2009 +0300
1.3 @@ -0,0 +1,108 @@
1.4 +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
1.5 +/*
1.6 + * Copyright (c) 2008,2009 IITP RAS
1.7 + *
1.8 + * This program is free software; you can redistribute it and/or modify
1.9 + * it under the terms of the GNU General Public License version 2 as
1.10 + * published by the Free Software Foundation;
1.11 + *
1.12 + * This program is distributed in the hope that it will be useful,
1.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.15 + * GNU General Public License for more details.
1.16 + *
1.17 + * You should have received a copy of the GNU General Public License
1.18 + * along with this program; if not, write to the Free Software
1.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1.20 + *
1.21 + * Authors: Kirill Andreev <andreev@iitp.ru>
1.22 + * Evgeny Khorov <horov@frtk.ru>
1.23 + */
1.24 +
1.25 +
1.26 +#include "ns3/core-module.h"
1.27 +#include "ns3/simulator-module.h"
1.28 +#include "ns3/node-module.h"
1.29 +#include "ns3/helper-module.h"
1.30 +#include "ns3/global-routing-module.h"
1.31 +#include "ns3/wifi-module.h"
1.32 +#include "ns3/mobility-module.h"
1.33 +
1.34 +using namespace ns3;
1.35 +
1.36 +NS_LOG_COMPONENT_DEFINE ("TestMeshScript");
1.37 +
1.38 +int
1.39 +main(int argc, char *argv[])
1.40 +{
1.41 + // Creating square topology with nNodes x nNodes grid:
1.42 + int xSize = 5;
1.43 + int ySize = 5;
1.44 + double step = 100.0; //Grid with one-hop edge
1.45 + double randomStart = 0.1; //One beacon interval
1.46 + NodeContainer nodes;
1.47 + CommandLine cmd;
1.48 + MobilityHelper mobility;
1.49 + MeshWifiHelper wifi;
1.50 + NetDeviceContainer meshDevices;
1.51 + // Defining a size of our network:
1.52 + cmd.AddValue("x-size", "Number of nodes in a row grid", xSize);
1.53 + cmd.AddValue("y-size", "Number of rows in a grid", ySize);
1.54 + cmd.AddValue("step", "Size of edge in our grid", step);
1.55 + cmd.AddValue("start", "Random start parameter", randomStart);
1.56 + cmd.Parse (argc, argv);
1.57 + NS_LOG_DEBUG("Grid:"<<xSize<<"*"<<ySize);
1.58 + // Creating nodes:
1.59 + nodes.Create (ySize*xSize);
1.60 +
1.61 + // Setting channel:
1.62 + YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
1.63 + YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
1.64 + wifiPhy.SetChannel (wifiChannel.Create ());
1.65 + // Setting Wifi:
1.66 + //wifi.SetPhy("ns3::WifiPhy");
1.67 + wifi.SetRemoteStationManager("ns3::AarfWifiManager");
1.68 + Ssid ssid = Ssid("MyMeSH");
1.69 + wifi.SetMac ("ns3::MeshWifiMac",
1.70 + "Ssid", SsidValue (ssid),
1.71 + "RandomStart", TimeValue (Seconds (randomStart))
1.72 + );
1.73 + wifi.SetPeerLinkManager ("ns3::WifiPeerManager");
1.74 + wifi.SetL2RoutingProtocol ("ns3::Hwmp");
1.75 + wifi.SetL2RoutingNetDevice ("ns3::L2RoutingNetDevice");
1.76 + meshDevices = wifi.Install (wifiPhy,nodes,1);
1.77 + // Installing Mobility.
1.78 + mobility.SetPositionAllocator
1.79 + ("ns3::GridPositionAllocator",
1.80 + "MinX", DoubleValue (0.0),
1.81 + "MinY", DoubleValue (0.0),
1.82 + "DeltaX", DoubleValue (step),
1.83 + "DeltaY", DoubleValue (step),
1.84 + "GridWidth", UintegerValue (xSize),
1.85 + "LayoutType", StringValue("RowFirst"));
1.86 + mobility.SetMobilityModel ("ns3::StaticMobilityModel");
1.87 + mobility.Install (nodes);
1.88 +
1.89 + // Setting Internet Stack:
1.90 + InternetStackHelper stack;
1.91 + stack.Install(nodes);
1.92 + Ipv4AddressHelper address;
1.93 + address.SetBase ("10.1.1.0", "255.255.255.0");
1.94 + Ipv4InterfaceContainer interfaces = address.Assign (meshDevices);
1.95 + UdpEchoServerHelper echoServer (9);
1.96 + ApplicationContainer serverApps = echoServer.Install (nodes.Get (0));
1.97 + serverApps.Start (Seconds (1.0));
1.98 + serverApps.Stop (Seconds (10.0));
1.99 + UdpEchoClientHelper echoClient (interfaces.GetAddress (0), 9);
1.100 + echoClient.SetAttribute ("MaxPackets", UintegerValue (1000));
1.101 + echoClient.SetAttribute ("Interval", TimeValue (Seconds (0.001)));
1.102 + echoClient.SetAttribute ("PacketSize", UintegerValue (1024));
1.103 + ApplicationContainer clientApps = echoClient.Install (nodes.Get (1));
1.104 + clientApps.Start (Seconds (2.0));
1.105 + clientApps.Stop (Seconds (10.0));
1.106 + //end
1.107 + Simulator::Stop (Seconds (10.0));
1.108 + Simulator::Run();
1.109 + Simulator::Destroy();
1.110 + return 0;
1.111 +}
2.1 --- a/examples/wscript Wed Feb 25 12:27:00 2009 -0500
2.2 +++ b/examples/wscript Sat Feb 28 14:21:05 2009 +0300
2.3 @@ -120,6 +120,10 @@
2.4 ['core', 'simulator', 'mobility', 'wifi'])
2.5 obj.source = 'wifi-ap.cc'
2.6
2.7 + obj = bld.create_ns3_program('mesh',
2.8 + ['core', 'simulator', 'mobility', 'wifi'])
2.9 + obj.source = 'mesh.cc'
2.10 +
2.11 bld.add_subdirs('stats')
2.12
2.13 obj = bld.create_ns3_program('wifi-wired-bridging',
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/src/devices/l2-routing/l2-routing-hwmp/hwmp-rtable.cc Sat Feb 28 14:21:05 2009 +0300
3.3 @@ -0,0 +1,282 @@
3.4 +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
3.5 +/*
3.6 + * Copyright (c) 2008,2009 IITP RAS
3.7 + *
3.8 + * This program is free software; you can redistribute it and/or modify
3.9 + * it under the terms of the GNU General Public License version 2 as
3.10 + * published by the Free Software Foundation;
3.11 + *
3.12 + * This program is distributed in the hope that it will be useful,
3.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3.15 + * GNU General Public License for more details.
3.16 + *
3.17 + * You should have received a copy of the GNU General Public License
3.18 + * along with this program; if not, write to the Free Software
3.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3.20 + *
3.21 + * Author: Kirill Andreev <andreev@iitp.ru>
3.22 + */
3.23 +
3.24 +
3.25 +#include "ns3/object.h"
3.26 +#include "ns3/assert.h"
3.27 +#include "ns3/simulator.h"
3.28 +#include "ns3/ptr.h"
3.29 +#include "ns3/log.h"
3.30 +#include "ns3/node.h"
3.31 +#include "hwmp-rtable.h"
3.32 +
3.33 +NS_LOG_COMPONENT_DEFINE ("HwmpRtable");
3.34 +
3.35 +namespace ns3 {
3.36 +
3.37 +NS_OBJECT_ENSURE_REGISTERED (HwmpRtable);
3.38 +
3.39 +TypeId
3.40 +HwmpRtable::GetTypeId(void)
3.41 +{
3.42 + static TypeId tid = TypeId ("ns3::HwmpRtable")
3.43 + .SetParent<Object> ()
3.44 + .AddConstructor<HwmpRtable> ();
3.45 + return tid;
3.46 +
3.47 +}
3.48 +
3.49 +HwmpRtable::HwmpRtable()
3.50 +{
3.51 +}
3.52 +
3.53 +HwmpRtable::~HwmpRtable()
3.54 +{
3.55 + DoDispose();
3.56 +}
3.57 +
3.58 +void
3.59 +HwmpRtable::DoDispose()
3.60 +{
3.61 + NS_LOG_UNCOND("RTABLE DISPOSE STARTED");
3.62 + m_routes.clear();
3.63 + m_roots.clear();
3.64 +}
3.65 +
3.66 +void
3.67 +HwmpRtable::AddReactivePath(
3.68 + Mac48Address destination,
3.69 + Mac48Address retransmitter,
3.70 + uint32_t port,
3.71 + uint32_t metric,
3.72 + Time lifetime,
3.73 + uint32_t seqnum
3.74 + )
3.75 +{
3.76 + std::map<Mac48Address, struct ReactiveRoute, addrcmp>::iterator i = m_routes.find(destination);
3.77 + if(i == m_routes.end())
3.78 + {
3.79 + struct ReactiveRoute newroute;
3.80 + m_routes[destination] = newroute;
3.81 + }
3.82 + else
3.83 + {
3.84 + /**
3.85 + * if outport differs from stored, routing info is
3.86 + * actual and metric is worse - we ignore this
3.87 + * information
3.88 + */
3.89 + if(
3.90 + (i->second.port != port) &&
3.91 + (i->second.metric < metric) &&
3.92 + /**
3.93 + * The routing info is actual or it
3.94 + * was received from peer
3.95 + */
3.96 + ((i->second.whenExpire > Simulator::Now())||(i->second.whenExpire == Seconds(0)))
3.97 + )
3.98 + return;
3.99 + }
3.100 + i = m_routes.find(destination);
3.101 + NS_ASSERT(i != m_routes.end());
3.102 + i->second.retransmitter = retransmitter;
3.103 + i->second.port = port;
3.104 + i->second.metric = metric;
3.105 + if(lifetime != Seconds(0))
3.106 + i->second.whenExpire = MilliSeconds(Simulator::Now().GetMilliSeconds() + lifetime.GetMilliSeconds());
3.107 + else
3.108 + /**
3.109 + * Information about peer does not have lifetime
3.110 + */
3.111 + i->second.whenExpire = Seconds(0);
3.112 + i->second.seqnum = seqnum;
3.113 +}
3.114 +
3.115 +void
3.116 +HwmpRtable::AddProactivePath(
3.117 + uint32_t metric,
3.118 + Mac48Address root,
3.119 + Mac48Address retransmitter,
3.120 + uint32_t port,
3.121 + Time lifetime,
3.122 + uint32_t seqnum
3.123 + )
3.124 +{
3.125 + struct ProactiveRoute newroute;
3.126 + m_roots[port] = newroute;
3.127 + std::map<uint32_t,struct ProactiveRoute>::iterator i = m_roots.find(port);
3.128 + NS_ASSERT(i != m_roots.end());
3.129 + i->second.root = root;
3.130 + i->second.retransmitter = retransmitter;
3.131 + i->second.metric = metric;
3.132 + i->second.whenExpire = MilliSeconds(Simulator::Now().GetMilliSeconds() + lifetime.GetMilliSeconds());
3.133 + i->second.seqnum = seqnum;
3.134 +
3.135 +}
3.136 +
3.137 +void
3.138 +HwmpRtable::AddPrecursor(Mac48Address destination, uint32_t port, Mac48Address precursor)
3.139 +{
3.140 + bool should_add = true;
3.141 + std::map<Mac48Address, struct ReactiveRoute, addrcmp>::iterator i = m_routes.find(destination);
3.142 + if((i != m_routes.end()) && (i->second.port == port))
3.143 + {
3.144 + for(unsigned int j = 0 ; j < i->second.precursors.size(); j ++)
3.145 + if(i->second.precursors[j] == precursor)
3.146 + {
3.147 + should_add = false;
3.148 + break;
3.149 + }
3.150 + if(should_add)
3.151 + i->second.precursors.push_back(precursor);
3.152 + }
3.153 + std::map<uint32_t,struct ProactiveRoute>::iterator k = m_roots.find(port);
3.154 + if(k!= m_roots.end())
3.155 + {
3.156 + for(unsigned int j = 0 ; j < k->second.precursors.size(); j ++)
3.157 + if(k->second.precursors[j] == precursor)
3.158 + return;
3.159 + k->second.precursors.push_back(precursor);
3.160 + return;
3.161 + }
3.162 +}
3.163 +
3.164 +void
3.165 +HwmpRtable::DeleteProactivePath(uint32_t port)
3.166 +{
3.167 + std::map<uint32_t,struct ProactiveRoute>::iterator j = m_roots.find(port);
3.168 + if(j != m_roots.end())
3.169 + m_roots.erase(j);
3.170 +
3.171 +}
3.172 +void
3.173 +HwmpRtable::DeleteProactivePath(Mac48Address root, uint32_t port)
3.174 +{
3.175 + std::map<uint32_t,struct ProactiveRoute>::iterator j = m_roots.find(port);
3.176 + if((j != m_roots.end())&&(j->second.root == root))
3.177 + m_roots.erase(j);
3.178 +
3.179 +}
3.180 +
3.181 +void
3.182 +HwmpRtable::DeleteReactivePath(Mac48Address destination, uint32_t port)
3.183 +{
3.184 + std::map<Mac48Address, struct ReactiveRoute, addrcmp>::iterator i = m_routes.find(destination);
3.185 + if(i != m_routes.end())
3.186 + if(i->second.port == port)
3.187 + m_routes.erase(i);
3.188 +}
3.189 +
3.190 +struct HwmpRtable::LookupResult
3.191 +HwmpRtable::LookupReactive(Mac48Address destination)
3.192 +{
3.193 + struct LookupResult result;
3.194 + result.retransmitter = Mac48Address::GetBroadcast();
3.195 + result.metric = MAX_METRIC;
3.196 + result.ifIndex = PORT_ANY;
3.197 +
3.198 + std::map<Mac48Address, struct ReactiveRoute, addrcmp>::iterator i = m_routes.find(destination);
3.199 + if(i == m_routes.end())
3.200 + return result;
3.201 + result.ifIndex = i->second.port;
3.202 + //Seconds(0) means that this is routing
3.203 + if(i->second.whenExpire < Simulator::Now())
3.204 + if(i->second.retransmitter != destination)
3.205 + return result;
3.206 + result.retransmitter = i->second.retransmitter;
3.207 + result.metric = i->second.metric;
3.208 + result.seqnum = i->second.seqnum;
3.209 + return result;
3.210 +}
3.211 +
3.212 +struct HwmpRtable::LookupResult
3.213 +HwmpRtable::LookupProactive(uint32_t port)
3.214 +{
3.215 + struct LookupResult result;
3.216 + result.retransmitter = Mac48Address::GetBroadcast();
3.217 + result.metric = MAX_METRIC;
3.218 + result.ifIndex = PORT_ANY;
3.219 + std::map<uint32_t, struct ProactiveRoute, addrcmp>::iterator i = m_roots.find(port);
3.220 + if(i == m_roots.end())
3.221 + return result;
3.222 + result.ifIndex = i->first;
3.223 + if(i->second.whenExpire < Simulator::Now())
3.224 + return result;
3.225 + result.retransmitter = i->second.retransmitter;
3.226 + result.metric = i->second.metric;
3.227 + result.seqnum = i->second.seqnum;
3.228 + return result;
3.229 +}
3.230 +
3.231 +std::vector<struct HwmpRtable::FailedDestination>
3.232 +HwmpRtable::GetUnreachableDestinations(Mac48Address peerAddress, uint32_t port)
3.233 +{
3.234 + std::vector<struct FailedDestination> retval;
3.235 + for(std::map<Mac48Address, struct ReactiveRoute, addrcmp>::iterator i = m_routes.begin(); i!= m_routes.end(); i++)
3.236 + if((i->second.retransmitter == peerAddress)&&(i->second.port == port))
3.237 + {
3.238 + struct FailedDestination dst;
3.239 + dst.destination = i->first;
3.240 + i->second.seqnum ++;
3.241 + dst.seqnum = i->second.seqnum;
3.242 + retval.push_back(dst);
3.243 + }
3.244 + /**
3.245 + * Lookup a path to root
3.246 + */
3.247 + std::map<uint32_t, struct ProactiveRoute, addrcmp>::iterator i = m_roots.find(port);
3.248 + if((i != m_roots.end())&&(i->second.retransmitter == peerAddress))
3.249 + {
3.250 + struct FailedDestination dst;
3.251 + dst.destination = i->second.root;
3.252 + dst.seqnum = i->second.seqnum;
3.253 + retval.push_back(dst);
3.254 + }
3.255 + return retval;
3.256 +}
3.257 +uint32_t
3.258 +HwmpRtable::RequestSeqnum(Mac48Address destination)
3.259 +{
3.260 + std::map<Mac48Address, struct ReactiveRoute, addrcmp>::iterator i = m_routes.find(destination);
3.261 + if(i == m_routes.end())
3.262 + return 0;
3.263 + return i->second.seqnum;
3.264 +}
3.265 +
3.266 +std::vector<Mac48Address>
3.267 +HwmpRtable::GetPrecursors(Mac48Address destination, uint32_t port)
3.268 +{
3.269 + std::vector<Mac48Address> retval;
3.270 + std::map<uint32_t, struct ProactiveRoute, addrcmp>::iterator root = m_roots.find(port);
3.271 + if((root != m_roots.end()) &&(root->second.root == destination))
3.272 + {
3.273 + for(unsigned int i = 0; i < root->second.precursors.size(); i ++)
3.274 + retval.push_back(root->second.precursors[i]);
3.275 + }
3.276 + std::map<Mac48Address, struct ReactiveRoute, addrcmp>::iterator route = m_routes.find(destination);
3.277 + if( (route != m_routes.end()) && (route->second.port == port) )
3.278 + {
3.279 + for(unsigned int i = 0; i < route->second.precursors.size(); i ++)
3.280 + retval.push_back(route->second.precursors[i]);
3.281 + }
3.282 + return retval;
3.283 +}
3.284 +
3.285 +}//namespace ns3
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/src/devices/l2-routing/l2-routing-hwmp/hwmp-rtable.h Sat Feb 28 14:21:05 2009 +0300
4.3 @@ -0,0 +1,125 @@
4.4 +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
4.5 +/*
4.6 + * Copyright (c) 2008,2009 IITP RAS
4.7 + *
4.8 + * This program is free software; you can redistribute it and/or modify
4.9 + * it under the terms of the GNU General Public License version 2 as
4.10 + * published by the Free Software Foundation;
4.11 + *
4.12 + * This program is distributed in the hope that it will be useful,
4.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4.15 + * GNU General Public License for more details.
4.16 + *
4.17 + * You should have received a copy of the GNU General Public License
4.18 + * along with this program; if not, write to the Free Software
4.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4.20 + *
4.21 + * Author: Kirill Andreev <andreev@iitp.ru>
4.22 + */
4.23 +
4.24 +
4.25 +#ifndef HWMP_RTABLE_H
4.26 +#define HWMP_RTABLE_H
4.27 +
4.28 +#include <list>
4.29 +#include <map>
4.30 +#include "ns3/nstime.h"
4.31 +#include "ns3/mac48-address.h"
4.32 +#include "ns3/net-device.h"
4.33 +#include "ns3/event-id.h"
4.34 +#include "ns3/packet.h"
4.35 +namespace ns3 {
4.36 +
4.37 +
4.38 + class HwmpRtable : public Object
4.39 + {
4.40 + public:
4.41 + static TypeId GetTypeId (void);
4.42 + HwmpRtable();
4.43 + ~HwmpRtable();
4.44 + void DoDispose();
4.45 + void AddReactivePath(
4.46 + Mac48Address destination,
4.47 + Mac48Address retransmitter,
4.48 + uint32_t port,
4.49 + uint32_t metric,
4.50 + Time lifetime,
4.51 + uint32_t seqnum
4.52 + );
4.53 + void AddProactivePath(
4.54 + uint32_t metric,
4.55 + Mac48Address root,
4.56 + Mac48Address retransmitter,
4.57 + uint32_t port,
4.58 + Time lifetime,
4.59 + uint32_t seqnum
4.60 + );
4.61 + void AddPrecursor(Mac48Address destination, uint32_t port, Mac48Address precursor);
4.62 + void DeleteProactivePath(uint32_t port);
4.63 + void DeleteProactivePath(Mac48Address root, uint32_t port);
4.64 + void DeleteReactivePath(Mac48Address destination, uint32_t port);
4.65 + struct LookupResult
4.66 + {
4.67 + Mac48Address retransmitter;
4.68 + uint32_t ifIndex;
4.69 + uint32_t metric;
4.70 + uint32_t seqnum;
4.71 + };
4.72 + struct LookupResult
4.73 + LookupReactive(Mac48Address destination);
4.74 + struct LookupResult
4.75 + LookupProactive(uint32_t port);
4.76 + //path error routines:
4.77 + struct FailedDestination
4.78 + {
4.79 + Mac48Address destination;
4.80 + uint32_t seqnum;
4.81 + };
4.82 + std::vector<struct FailedDestination>
4.83 + GetUnreachableDestinations(Mac48Address peerAddress, uint32_t port);
4.84 + uint32_t
4.85 + RequestSeqnum(Mac48Address dst);
4.86 + std::vector<Mac48Address>
4.87 + GetPrecursors(Mac48Address destination, uint32_t port);
4.88 + const static uint32_t PORT_ANY = 0xffffffff;
4.89 + const static uint32_t MAX_METRIC = 0xffffffff;
4.90 + private:
4.91 + struct ReactiveRoute
4.92 + {
4.93 + Mac48Address retransmitter;
4.94 + uint32_t port;
4.95 + uint32_t metric;
4.96 + Time whenExpire;
4.97 + uint32_t seqnum;
4.98 + std::vector<Mac48Address> precursors;
4.99 + };
4.100 + struct ProactiveRoute
4.101 + {
4.102 + Mac48Address root;
4.103 + Mac48Address retransmitter;
4.104 + uint32_t metric;
4.105 + Time whenExpire;
4.106 + uint32_t seqnum;
4.107 + std::vector<Mac48Address> precursors;
4.108 + };
4.109 + struct addrcmp
4.110 + {
4.111 + bool operator()(const Mac48Address addr1, const Mac48Address addr2) const
4.112 + {
4.113 + uint8_t s1[6], s2[6];
4.114 + addr1.CopyTo(s1);
4.115 + addr2.CopyTo(s2);
4.116 + for(int i = 0; i < 6; i ++)
4.117 + if(s1[i] > s2[i])
4.118 + return true;
4.119 + return false;
4.120 + }
4.121 + };
4.122 + std::map<Mac48Address, struct ReactiveRoute, addrcmp>
4.123 + m_routes;
4.124 + std::map<uint32_t, struct ProactiveRoute>
4.125 + m_roots;
4.126 + };
4.127 +} //namespace ns3
4.128 +#endif
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/src/devices/l2-routing/l2-routing-hwmp/hwmp-state.cc Sat Feb 28 14:21:05 2009 +0300
5.3 @@ -0,0 +1,539 @@
5.4 +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
5.5 +/*
5.6 + * Copyright (c) 2008,2009 IITP RAS
5.7 + *
5.8 + * This program is free software; you can redistribute it and/or modify
5.9 + * it under the terms of the GNU General Public License version 2 as
5.10 + * published by the Free Software Foundation;
5.11 + *
5.12 + * This program is distributed in the hope that it will be useful,
5.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
5.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5.15 + * GNU General Public License for more details.
5.16 + *
5.17 + * You should have received a copy of the GNU General Public License
5.18 + * along with this program; if not, write to the Free Software
5.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
5.20 + *
5.21 + * Author: Kirill Andreev <andreev@iitp.ru>
5.22 + */
5.23 +
5.24 +
5.25 +#include "hwmp-state.h"
5.26 +#include "ns3/simulator.h"
5.27 +#include "ns3/nstime.h"
5.28 +#include "ns3/log.h"
5.29 +namespace ns3 {
5.30 +
5.31 +
5.32 +NS_LOG_COMPONENT_DEFINE ("HwmpState");
5.33 +TypeId
5.34 +HwmpState::GetTypeId (void)
5.35 +{
5.36 + static TypeId tid = TypeId ("ns3::HwmpState")
5.37 + .SetParent<Object> ()
5.38 + .AddConstructor<HwmpState> ()
5.39 + ;
5.40 + return tid;
5.41 +}
5.42 +
5.43 +HwmpState::HwmpState()
5.44 +{
5.45 + m_myPreq = m_preqQueue.end();
5.46 + m_preqId = 1;
5.47 + m_myDsn = 1;
5.48 + m_maxTtl = 10;
5.49 + m_disabled = false;
5.50 +}
5.51 +void
5.52 +HwmpState::SetRequestRouteCallback(
5.53 + Callback<struct HwmpRtable::LookupResult, const Mac48Address&> cb)
5.54 +{
5.55 + m_requestRouteCallback = cb;
5.56 +}
5.57 +
5.58 +void
5.59 +HwmpState::SetRequestRootPathCallback(
5.60 + Callback<struct HwmpRtable::LookupResult, uint32_t> cb)
5.61 +{
5.62 + m_requestRootPathCallback = cb;
5.63 +}
5.64 +
5.65 +//Setting MAC
5.66 +void
5.67 +HwmpState::SetMac(Ptr<MeshWifiMac> mac)
5.68 +{
5.69 + mac->SetPeerStatusCallback(MakeCallback(&HwmpState::PeerStatus, this));
5.70 + mac->SetPreqReceivedCallback(MakeCallback(&HwmpState::ReceivePreq, this));
5.71 + mac->SetPrepReceivedCallback(MakeCallback(&HwmpState::ReceivePrep, this));
5.72 + mac->SetPerrReceivedCallback(MakeCallback(&HwmpState::ReceivePerr, this));
5.73 + m_address = mac->GetAddress();
5.74 + m_preqCallback = MakeCallback(&MeshWifiMac::SendPreq, mac);
5.75 + m_prepCallback = MakeCallback(&MeshWifiMac::SendPrep, mac);
5.76 + m_perrCallback = MakeCallback(&MeshWifiMac::SendPerr, mac);
5.77 +}
5.78 +HwmpState::~HwmpState()
5.79 +{
5.80 + m_preqQueue.clear();
5.81 +}
5.82 +//Interaction with HWMP:
5.83 +void
5.84 +HwmpState::SetRoutingInfoCallback(
5.85 + Callback<void, INFO> cb
5.86 + )
5.87 +{
5.88 + m_routingInfoCallback = cb;
5.89 +}
5.90 +
5.91 +void
5.92 +HwmpState::SetRetransmittersOfPerrCallback(
5.93 + Callback<std::vector<Mac48Address>, std::vector<struct HwmpRtable::FailedDestination>, uint32_t> cb)
5.94 +{
5.95 + m_retransmittersOfPerrCallback = cb;
5.96 +}
5.97 +
5.98 +void
5.99 +HwmpState::RequestDestination(Mac48Address dst)
5.100 +{
5.101 + if(m_preqQueue.end() == m_myPreq)
5.102 + {
5.103 + WifiPreqInformationElement preq;
5.104 + //fill PREQ:
5.105 + preq.SetHopcount(0);
5.106 + preq.SetTTL(m_maxTtl);
5.107 + preq.SetPreqID(m_preqId++);
5.108 + if(m_preqId == MAX_PREQ_ID)
5.109 + m_preqId = 0;
5.110 + preq.SetLifetime(TIME_TO_TU(dot11sParameters::dot11MeshHWMPactivePathTimeout));
5.111 + preq.SetOriginatorSeqNumber(m_myDsn++);
5.112 + if(m_myDsn == MAX_DSN)
5.113 + m_myDsn = 0;
5.114 + preq.SetOriginatorAddress(m_address);
5.115 + preq.AddDestinationAddressElement(false, false, dst, 0); //DO = 0, RF = 0
5.116 + if(m_preqTimer.IsRunning())
5.117 + {
5.118 + NS_LOG_DEBUG("No my preq");
5.119 + m_preqQueue.push_back(preq);
5.120 + //set iterator position to my preq:
5.121 + m_myPreq = m_preqQueue.end() -1;
5.122 + }
5.123 + else
5.124 + {
5.125 + NS_LOG_DEBUG("Send PREQ now, "<<preq.GetPreqID()<<" destinations, now is "<<Simulator::Now());
5.126 + m_preqCallback(preq);
5.127 + NS_ASSERT(!m_preqTimer.IsRunning());
5.128 + m_preqTimer = Simulator::Schedule(dot11sParameters::dot11MeshHWMPpreqMinInterval, &HwmpState::SendOnePreq, this);
5.129 + }
5.130 + }
5.131 + else
5.132 + {
5.133 + NS_ASSERT(m_myPreq->GetOriginatorAddress() == m_address);
5.134 + NS_LOG_DEBUG("add a destination "<<dst);
5.135 + m_myPreq->AddDestinationAddressElement(false, false, dst, 0); //DO = 0, RF = 0
5.136 + }
5.137 +}
5.138 +void
5.139 +HwmpState::SendPathError(std::vector<struct HwmpRtable::FailedDestination> destinations)
5.140 +{
5.141 + std::vector<Mac48Address> receivers = m_retransmittersOfPerrCallback(destinations, m_ifIndex);
5.142 + NS_LOG_DEBUG("SendPathError started");
5.143 + if(receivers.size()== 0)
5.144 + return;
5.145 + NS_LOG_DEBUG(m_address<<" Should Send PERR to");
5.146 + for(unsigned int i = 0; i < receivers.size(); i ++)
5.147 + {
5.148 + AddPerrReceiver(receivers[i]);
5.149 + NS_LOG_DEBUG(receivers[i]);
5.150 + }
5.151 + NS_LOG_DEBUG("To tel about failure with");
5.152 + for(unsigned int i = 0; i < destinations.size(); i ++)
5.153 + {
5.154 + m_myPerr.AddAddressUnit(destinations[i]);
5.155 + NS_LOG_DEBUG(destinations[i].destination);
5.156 + }
5.157 + if(!m_perrTimer.IsRunning())
5.158 + {
5.159 + m_perrCallback(m_myPerr,m_myPerrReceivers);
5.160 + m_myPerr.ResetPerr();
5.161 + m_perrTimer = Simulator::Schedule(dot11sParameters::dot11MeshHWMPperrMinInterval,&HwmpState::SendOnePerr,this);
5.162 + }
5.163 +}
5.164 +//needed to fill routing information structure
5.165 +void
5.166 +HwmpState::SetAssociatedIfaceId(uint32_t interface)
5.167 +{
5.168 + m_ifIndex = interface;
5.169 +}
5.170 +
5.171 +uint32_t
5.172 +HwmpState::GetAssociatedIfaceId()
5.173 +{
5.174 + return m_ifIndex;
5.175 +}
5.176 +
5.177 +//Interaction with MAC:
5.178 +void
5.179 +HwmpState::ReceivePreq(WifiPreqInformationElement& preq, const Mac48Address& from, const uint32_t& metric)
5.180 +{
5.181 + if(m_disabled)
5.182 + return;
5.183 + if(preq.GetOriginatorAddress() == m_address)
5.184 + return;
5.185 + preq.DecrementTtl();
5.186 + preq.IncrementMetric(metric);
5.187 + if(preq.GetTtl() == 0)
5.188 + return;
5.189 + //acceptance cretirea:
5.190 + std::map<Mac48Address, uint32_t, addrcmp>::iterator i = m_dsnDatabase.find(preq.GetOriginatorAddress());
5.191 + if(i == m_dsnDatabase.end())
5.192 + {
5.193 + m_dsnDatabase[preq.GetOriginatorAddress()] = preq.GetOriginatorSeqNumber();
5.194 + m_preqMetricDatabase[preq.GetOriginatorAddress()] = preq.GetMetric();
5.195 + }
5.196 + else
5.197 + {
5.198 + if(i->second > preq.GetOriginatorSeqNumber())
5.199 + return;
5.200 + if(i->second == preq.GetOriginatorSeqNumber())
5.201 + {
5.202 + //find metric
5.203 + std::map<Mac48Address, uint32_t, addrcmp>::iterator j =
5.204 + m_preqMetricDatabase.find(preq.GetOriginatorAddress());
5.205 + NS_ASSERT(j != m_dsnDatabase.end());
5.206 + if(j->second <= preq.GetMetric())
5.207 + return;
5.208 + }
5.209 + m_dsnDatabase[preq.GetOriginatorAddress()] = preq.GetOriginatorSeqNumber();
5.210 + m_preqMetricDatabase[preq.GetOriginatorAddress()] = preq.GetMetric();
5.211 + }
5.212 + NS_LOG_DEBUG(
5.213 + "PREQ from "<< preq.GetOriginatorAddress()
5.214 + <<", at "<< m_address
5.215 + <<", TTL ="<< (int)preq.GetTtl()
5.216 + <<", metric = "<< preq.GetMetric()
5.217 + <<", hopcount = "<< (int)preq.GetHopCount()
5.218 + <<", preqId = "<< preq.GetPreqID()
5.219 + <<", transmitter is "<<from);
5.220 + //fill routingTable
5.221 + INFO newInfo;
5.222 + newInfo.me = m_address;
5.223 + newInfo.destination = preq.GetOriginatorAddress();
5.224 + newInfo.nextHop = from;
5.225 + newInfo.metric = preq.GetMetric();
5.226 + newInfo.lifetime = TU_TO_TIME(preq.GetLifetime());
5.227 + newInfo.outPort = m_ifIndex;
5.228 + newInfo.dsn = preq.GetOriginatorSeqNumber();
5.229 + newInfo.type = INFO_PREQ;
5.230 + //check if can answer:
5.231 + std::vector<Ptr<DestinationAddressUnit> > destinations = preq.GetDestinationList ();
5.232 + for(std::vector<Ptr<DestinationAddressUnit> >::iterator i = destinations.begin(); i!= destinations.end(); i++)
5.233 + {
5.234 + if((*i)->GetDestinationAddress() == Mac48Address::GetBroadcast())
5.235 + {
5.236 + //only proactive PREQ contains destination
5.237 + //address as broadcast! Proactive preq MUST
5.238 + //have destination count equal to 1 and
5.239 + //per destination flags DO and RF
5.240 + NS_ASSERT(preq.GetDestCount() == 1);
5.241 + NS_ASSERT(((*i)->IsDo()) && ((*i)->IsRf()));
5.242 + NS_LOG_DEBUG("PROACTIVE PREQ RECEIVED");
5.243 + newInfo.type = INFO_PROACTIVE;
5.244 + m_routingInfoCallback(newInfo);
5.245 + if(!preq.IsNeedNotPrep())
5.246 + {
5.247 + SendPrep(
5.248 + preq.GetOriginatorAddress(),
5.249 + m_address,
5.250 + from,
5.251 + preq.GetMetric(),
5.252 + preq.GetOriginatorSeqNumber(),
5.253 + m_myDsn ++,
5.254 + preq.GetLifetime()
5.255 + );
5.256 + if(m_myDsn == MAX_DSN)
5.257 + m_myDsn = 0;
5.258 + }
5.259 + break;
5.260 + }
5.261 + if((*i)->GetDestinationAddress()==m_address)
5.262 + {
5.263 + preq.DelDestinationAddressElement((*i)->GetDestinationAddress());
5.264 + SendPrep(
5.265 + preq.GetOriginatorAddress(),
5.266 + m_address,
5.267 + from,
5.268 + 0,
5.269 + preq.GetOriginatorSeqNumber(),
5.270 + m_myDsn++,
5.271 + preq.GetLifetime()
5.272 + );
5.273 + if(m_myDsn == MAX_DSN)
5.274 + m_myDsn = 0;
5.275 + continue;
5.276 + }
5.277 + //check if can answer:
5.278 + struct HwmpRtable::LookupResult result = m_requestRouteCallback((*i)->GetDestinationAddress());
5.279 + if((!((*i)->IsDo())) && (result.retransmitter!=Mac48Address::GetBroadcast()))
5.280 + {
5.281 + //have a valid information and acn answer
5.282 + if((*i)->IsRf())
5.283 + (*i)->SetFlags(true, false); //DO = 1, RF = 0 (as it was)
5.284 + else
5.285 + {
5.286 + //send a PREP and delete destination
5.287 + preq.DelDestinationAddressElement((*i)->GetDestinationAddress());
5.288 + SendPrep(
5.289 + preq.GetOriginatorAddress(),
5.290 + (*i)->GetDestinationAddress(),
5.291 + result.retransmitter,
5.292 + result.metric,
5.293 + preq.GetOriginatorSeqNumber(),
5.294 + result.seqnum,
5.295 + preq.GetLifetime()
5.296 + );
5.297 + continue;
5.298 + }
5.299 + }
5.300 + }
5.301 + m_routingInfoCallback(newInfo);
5.302 + //chack if must retransmit:
5.303 + if(preq.GetDestCount() == 0)
5.304 + return;
5.305 + if(m_preqTimer.IsRunning())
5.306 + {
5.307 + m_preqQueue.push_back(preq);
5.308 + }
5.309 + else
5.310 + {
5.311 + m_preqCallback(preq);
5.312 + NS_ASSERT(!m_preqTimer.IsRunning());
5.313 + m_preqTimer = Simulator::Schedule(dot11sParameters::dot11MeshHWMPpreqMinInterval, &HwmpState::SendOnePreq, this);
5.314 + }
5.315 +}
5.316 +
5.317 +void
5.318 +HwmpState::ReceivePrep(WifiPrepInformationElement& prep, const Mac48Address& from, const uint32_t& metric)
5.319 +{
5.320 + if(m_disabled)
5.321 + return;
5.322 + prep.DecrementTtl();
5.323 + prep.IncrementMetric(metric);
5.324 + //acceptance cretirea:
5.325 + std::map<Mac48Address, uint32_t, addrcmp>::iterator i = m_dsnDatabase.find(prep.GetDestinationAddress());
5.326 + if(i == m_dsnDatabase.end())
5.327 + {
5.328 + m_dsnDatabase[prep.GetDestinationAddress()] = prep.GetDestinationSeqNumber();
5.329 + }
5.330 + else
5.331 + if(i->second > prep.GetDestinationSeqNumber())
5.332 + return;
5.333 + //update routing info
5.334 + struct HwmpRtable::LookupResult result = m_requestRouteCallback(prep.GetDestinationAddress());
5.335 + if(result.retransmitter == Mac48Address::GetBroadcast())
5.336 + //try to look for default route
5.337 + result = m_requestRootPathCallback(m_ifIndex);
5.338 + if((result.retransmitter == Mac48Address::GetBroadcast())&&(m_address != prep.GetDestinationAddress()))
5.339 + return;
5.340 + INFO newInfo;
5.341 + newInfo.me = m_address;
5.342 + newInfo.destination = prep.GetOriginatorAddress();
5.343 + newInfo.source = prep.GetDestinationAddress();
5.344 + newInfo.nextHop = from;
5.345 + newInfo.metric = prep.GetMetric();
5.346 + newInfo.lifetime = TU_TO_TIME(prep.GetLifetime());
5.347 + newInfo.outPort = m_ifIndex;
5.348 + newInfo.dsn = prep.GetOriginatorSeqNumber();
5.349 + newInfo.prevHop = result.retransmitter;
5.350 + newInfo.type = INFO_PREP;
5.351 + NS_LOG_DEBUG("Path to "<<newInfo.source<<", i am "<<m_address<<", precursor is "<<from);
5.352 + NS_LOG_DEBUG("Path to "<<newInfo.destination<<", i am "<<m_address<<", precursor is "<<result.retransmitter);
5.353 + m_routingInfoCallback(newInfo);
5.354 + if(prep.GetDestinationAddress() == m_address)
5.355 + {
5.356 + NS_LOG_DEBUG("Destination resolved"<<newInfo.destination);
5.357 + return;
5.358 + }
5.359 + m_prepCallback(prep, result.retransmitter);
5.360 +}
5.361 +
5.362 +void
5.363 +HwmpState::ReceivePerr(WifiPerrInformationElement& perr, const Mac48Address& from)
5.364 +{
5.365 + if(m_disabled)
5.366 + return;
5.367 + NS_LOG_DEBUG(m_address<<" RECEIVED PERR from "<<from);
5.368 + /**
5.369 + * Check forwarding conditions:
5.370 + */
5.371 + std::vector<HwmpRtable::FailedDestination> destinations = perr.GetAddressUnitVector();
5.372 + for(unsigned int i = 0; i < destinations.size(); i ++)
5.373 + {
5.374 + /**
5.375 + * Lookup for a valid routing information
5.376 + */
5.377 + struct HwmpRtable::LookupResult result = m_requestRouteCallback(destinations[i].destination);
5.378 + if(
5.379 + (result.retransmitter != from)
5.380 + ||(result.seqnum >= destinations[i].seqnum)
5.381 + )
5.382 +
5.383 + perr.DeleteAddressUnit(destinations[i].destination);
5.384 + }
5.385 + NS_LOG_DEBUG("Retransmit "<<(int)perr.GetNumOfDest());
5.386 + if(perr.GetNumOfDest() == 0)
5.387 + return;
5.388 + destinations = perr.GetAddressUnitVector();
5.389 + SendPathError(destinations);
5.390 +}
5.391 +
5.392 +void
5.393 +HwmpState::PeerStatus(const Mac48Address peerAddress, const bool status, const uint32_t metric)
5.394 +{
5.395 + INFO newInfo;
5.396 + newInfo.me = m_address;
5.397 + newInfo.destination = peerAddress;
5.398 + newInfo.nextHop = peerAddress;
5.399 + newInfo.metric = metric;
5.400 + newInfo.outPort = m_ifIndex;
5.401 + newInfo.dsn = 0;
5.402 + if(status)
5.403 + newInfo.type = INFO_NEW_PEER;
5.404 + else
5.405 + newInfo.type = INFO_FAILED_PEER;
5.406 + m_routingInfoCallback(newInfo);
5.407 +}
5.408 +
5.409 +bool
5.410 +HwmpState::SetRoot()
5.411 +{
5.412 +#if 0
5.413 + //TODO:: delete this lines!!!!!!!
5.414 + if(m_address != Mac48Address("00:00:00:00:00:10"))
5.415 + return false;
5.416 + //TODO
5.417 +#endif
5.418 + Simulator::Schedule(dot11sParameters::dot11MeshHWMPactiveRootTimeout, &HwmpState::SendProactivePreq, this);
5.419 + return true;
5.420 +}
5.421 +
5.422 +void
5.423 +HwmpState::SendProactivePreq()
5.424 +{
5.425 + NS_LOG_DEBUG("Sending proactive PREQ");
5.426 + WifiPreqInformationElement preq;
5.427 + //By default: must answer
5.428 + preq.SetHopcount(0);
5.429 + preq.SetTTL(m_maxTtl);
5.430 + preq.SetPreqID(m_preqId++);
5.431 + if(m_preqId == MAX_PREQ_ID)
5.432 + m_preqId = 0;
5.433 + preq.SetLifetime(TIME_TO_TU(dot11sParameters::dot11MeshHWMPpathToRootInterval));
5.434 + preq.SetOriginatorSeqNumber(m_myDsn++);
5.435 + if(m_myDsn == MAX_DSN)
5.436 + m_myDsn = 0;
5.437 + preq.SetOriginatorAddress(m_address);
5.438 + preq.AddDestinationAddressElement(
5.439 + true,
5.440 + true,
5.441 + Mac48Address::GetBroadcast()
5.442 + ,0);
5.443 + if(m_preqTimer.IsRunning())
5.444 + m_preqQueue.push_back(preq);
5.445 + else
5.446 + {
5.447 + NS_LOG_DEBUG("Send now "<<preq.GetPreqID());
5.448 + m_preqCallback(preq);
5.449 + NS_ASSERT(!m_preqTimer.IsRunning());
5.450 + m_preqTimer = Simulator::Schedule(dot11sParameters::dot11MeshHWMPpreqMinInterval, &HwmpState::SendOnePreq, this);
5.451 + }
5.452 + Simulator::Schedule(dot11sParameters::dot11MeshHWMPactiveRootTimeout, &HwmpState::SendProactivePreq, this);
5.453 +}
5.454 +
5.455 +void
5.456 +HwmpState::AddPerrReceiver(Mac48Address receiver)
5.457 +{
5.458 + /**
5.459 + * add new vector of addresses to m_perrReceiversand check
5.460 + * duplicates
5.461 + */
5.462 + for(unsigned int j = 0; j < m_myPerrReceivers.size(); j++)
5.463 + if(m_myPerrReceivers[j] == receiver)
5.464 + return;
5.465 + m_myPerrReceivers.push_back(receiver);
5.466 +}
5.467 +
5.468 +void
5.469 +HwmpState::UnSetRoot()
5.470 +{
5.471 +}
5.472 +
5.473 +void
5.474 +HwmpState::Disable()
5.475 +{
5.476 + m_disabled = true;
5.477 +}
5.478 +
5.479 +void
5.480 +HwmpState::Enable()
5.481 +{
5.482 + m_disabled = false;
5.483 +}
5.484 +
5.485 +Mac48Address
5.486 +HwmpState::GetAddress()
5.487 +{
5.488 + return m_address;
5.489 +}
5.490 +
5.491 +void
5.492 +HwmpState::SendOnePreq()
5.493 +{
5.494 + if(m_preqQueue.size() == 0)
5.495 + return;
5.496 + if(m_myPreq == m_preqQueue.begin())
5.497 + m_myPreq == m_preqQueue.end();
5.498 + WifiPreqInformationElement preq = m_preqQueue[0];
5.499 + NS_LOG_DEBUG(
5.500 + "Sending PREQ from "<<preq.GetOriginatorAddress() <<
5.501 + " destinations are "<<(int)preq.GetDestCount()<<
5.502 + ", at "<<Simulator::Now()<<
5.503 + ", store in queue "<<m_preqQueue.size()<<
5.504 + " preqs"<<", I am "<<m_address);
5.505 + m_preqCallback(preq);
5.506 + //erase first!
5.507 + m_preqQueue.erase(m_preqQueue.begin());
5.508 + //reschedule sending PREQ
5.509 + NS_ASSERT(!m_preqTimer.IsRunning());
5.510 + m_preqTimer = Simulator::Schedule(dot11sParameters::dot11MeshHWMPpreqMinInterval, &HwmpState::SendOnePreq, this);
5.511 +}
5.512 +
5.513 +void
5.514 +HwmpState::SendPrep(Mac48Address dst,
5.515 + Mac48Address src,
5.516 + Mac48Address retransmitter,
5.517 + uint32_t initMetric,
5.518 + uint32_t dsn,
5.519 + uint32_t originatorDsn,
5.520 + uint32_t lifetime)
5.521 +{
5.522 + WifiPrepInformationElement prep;
5.523 + prep.SetHopcount(0);
5.524 + prep.SetTTL(m_maxTtl);
5.525 + prep.SetDestinationAddress(dst);
5.526 + prep.SetDestinationSeqNumber(dsn);
5.527 + prep.SetLifetime(lifetime);
5.528 + prep.SetMetric(0);
5.529 + prep.SetOriginatorAddress(src);
5.530 + prep.SetOriginatorSeqNumber(originatorDsn);
5.531 + m_prepCallback(prep, retransmitter);
5.532 +}
5.533 +
5.534 +void
5.535 +HwmpState::SendOnePerr()
5.536 +{
5.537 + if(m_myPerr.GetNumOfDest() == 0)
5.538 + return;
5.539 + m_perrCallback(m_myPerr, m_myPerrReceivers);
5.540 + m_myPerr.ResetPerr();
5.541 +}
5.542 +}//namespace ns3
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/src/devices/l2-routing/l2-routing-hwmp/hwmp-state.h Sat Feb 28 14:21:05 2009 +0300
6.3 @@ -0,0 +1,206 @@
6.4 +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
6.5 +/*
6.6 + * Copyright (c) 2008,2009 IITP RAS
6.7 + *
6.8 + * This program is free software; you can redistribute it and/or modify
6.9 + * it under the terms of the GNU General Public License version 2 as
6.10 + * published by the Free Software Foundation;
6.11 + *
6.12 + * This program is distributed in the hope that it will be useful,
6.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6.15 + * GNU General Public License for more details.
6.16 + *
6.17 + * You should have received a copy of the GNU General Public License
6.18 + * along with this program; if not, write to the Free Software
6.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
6.20 + *
6.21 + * Author: Kirill Andreev <andreev@iitp.ru>
6.22 + */
6.23 +
6.24 +
6.25 +#ifndef HWMP_STATE_H
6.26 +#define HWMP_STATE_H
6.27 +#include <map>
6.28 +#include "ns3/event-id.h"
6.29 +#include "ns3/ptr.h"
6.30 +#include "ns3/hwmp-rtable.h"
6.31 +#include "ns3/packet.h"
6.32 +#include "ns3/wifi-net-device.h"
6.33 +#include "ns3/mesh-wifi-mac.h"
6.34 +#include "ns3/mesh-wifi-preq-information-element.h"
6.35 +#include "ns3/mesh-wifi-prep-information-element.h"
6.36 +#include "ns3/mesh-wifi-perr-information-element.h"
6.37 +#include "ns3/dot11s-parameters.h"
6.38 +namespace ns3 {
6.39 + /**
6.40 + * \brief Handles HWMP state machine at each real interface
6.41 + * \details Implements the following:
6.42 + * 1. Keep it's own DSN,
6.43 + * 2. Keep PREQ and PREP timers adn send this frames in
6.44 + * accordance with HWMP-limitations
6.45 + * 3. Deliver routing information to Hwmp main class
6.46 + * 4. Notify about broken peers
6.47 + */
6.48 + class HwmpState : public Object {
6.49 + public:
6.50 + static TypeId GetTypeId();
6.51 + HwmpState();
6.52 + ~HwmpState();
6.53 +
6.54 + /**
6.55 + * \brief Interface with HWMP - Hwmp can only
6.56 + * request address and collect routing
6.57 + * information
6.58 + */
6.59 + void SetRequestRouteCallback(
6.60 + Callback<struct HwmpRtable::LookupResult, const Mac48Address&> cb);
6.61 + void SetRequestRootPathCallback(
6.62 + Callback<struct HwmpRtable::LookupResult, uint32_t> cb);
6.63 +
6.64 + enum InfoType {
6.65 + INFO_PREQ,
6.66 + INFO_PREP,
6.67 + INFO_PERR,
6.68 + INFO_PROACTIVE,
6.69 + INFO_NEW_PEER,
6.70 + INFO_FAILED_PEER
6.71 + };
6.72 + typedef struct RoutingInfo{
6.73 + Mac48Address me;
6.74 + Mac48Address destination;
6.75 + Mac48Address source;
6.76 + Mac48Address nextHop;
6.77 + Mac48Address prevHop;
6.78 + uint32_t outPort;
6.79 + uint32_t metric;
6.80 + std::vector<Mac48Address>
6.81 + failedDestinations;
6.82 + uint32_t dsn;
6.83 + Time lifetime;
6.84 + enum InfoType type;
6.85 + } INFO;
6.86 + void SetRoutingInfoCallback(
6.87 + Callback<void, INFO> cb
6.88 + );
6.89 + void SetRetransmittersOfPerrCallback(
6.90 + Callback<std::vector<Mac48Address>, std::vector<struct HwmpRtable::FailedDestination>, uint32_t> cb);
6.91 + void RequestDestination(Mac48Address dest);
6.92 + void SendPathError(std::vector<struct HwmpRtable::FailedDestination> destinations);
6.93 + void SetAssociatedIfaceId(uint32_t interface);
6.94 + uint32_t
6.95 + GetAssociatedIfaceId();
6.96 + //Mac interaction:
6.97 + void SetMac(Ptr<MeshWifiMac> mac);
6.98 + void SetSendPreqCallback(
6.99 + Callback<void, const WifiPreqInformationElement&> cb);
6.100 + void SetSendPrepCallback(
6.101 + Callback<void, const WifiPrepInformationElement&> cb);
6.102 + void SetSendPerrCallback(
6.103 + Callback<void, const WifiPerrInformationElement&, std::vector<Mac48Address> > cb);
6.104 + void ReceivePreq(WifiPreqInformationElement&, const Mac48Address& from, const uint32_t& metric);
6.105 + void ReceivePrep(WifiPrepInformationElement&, const Mac48Address& from, const uint32_t& metric);
6.106 + void ReceivePerr(WifiPerrInformationElement&, const Mac48Address& from);
6.107 + void PeerStatus(
6.108 + const Mac48Address peerAddress,
6.109 + const bool status,
6.110 + const uint32_t metric
6.111 + );
6.112 + //Proactive mode routines:
6.113 + bool SetRoot();
6.114 + void UnSetRoot();
6.115 + //external handling:
6.116 + void Disable();
6.117 + void Enable();
6.118 + //DEBUG purpose:
6.119 + Mac48Address GetAddress();
6.120 + private:
6.121 + static const uint32_t MAX_PREQ_ID = 0xffffffff;
6.122 + static const uint32_t MAX_DSN = 0xffffffff;
6.123 + //information about associated port:
6.124 + Mac48Address m_address;
6.125 + //index when HWMP state is attached
6.126 + uint32_t m_ifIndex;
6.127 + //timers for PREQ and PREP:
6.128 + EventId m_preqTimer;
6.129 + void SendOnePreq();
6.130 + std::vector<WifiPreqInformationElement>
6.131 + m_preqQueue;
6.132 + //true means that we can add a destination to
6.133 + //existing PREQ element
6.134 + //False means that we must send
6.135 + EventId m_prepTimer;
6.136 + void SendPrep(
6.137 + Mac48Address dst, //dst is PREQ's originator address
6.138 + Mac48Address src, //src is PREQ's destination address
6.139 + Mac48Address retransmitter,
6.140 + uint32_t initMetric,
6.141 + uint32_t dsn,/* taken form PREQ*/
6.142 + uint32_t originatorDsn, //taken from rtable or as m_myDsn ++;
6.143 + uint32_t lifetime //taken from PREQ
6.144 + );
6.145 + std::vector<WifiPreqInformationElement>::iterator
6.146 + m_myPreq;
6.147 + //HWMP interaction callbacks:
6.148 + Callback<void, INFO>
6.149 + m_routingInfoCallback;
6.150 + Callback<std::vector<Mac48Address>, std::vector<struct HwmpRtable::FailedDestination>, uint32_t>
6.151 + m_retransmittersOfPerrCallback;
6.152 + Callback<struct HwmpRtable::LookupResult, const Mac48Address&>
6.153 + m_requestRouteCallback;
6.154 + Callback<struct HwmpRtable::LookupResult, uint32_t>
6.155 + m_requestRootPathCallback;
6.156 + //Mac interaction callbacks:
6.157 + Callback<void, const WifiPreqInformationElement&>
6.158 + m_preqCallback;
6.159 + Callback<void, const WifiPrepInformationElement&, const Mac48Address&>
6.160 + m_prepCallback;
6.161 + Callback<void, const WifiPerrInformationElement&, std::vector<Mac48Address> >
6.162 + m_perrCallback;
6.163 + //HwmpCounters:
6.164 + uint32_t m_preqId;
6.165 + uint32_t m_myDsn;
6.166 + //Seqno and metric database
6.167 + struct addrcmp
6.168 + {
6.169 + bool operator()(const Mac48Address addr1, Mac48Address addr2) const
6.170 + {
6.171 + uint8_t s1[6], s2[6];
6.172 + addr1.CopyTo(s1);
6.173 + addr2.CopyTo(s2);
6.174 + for(int i = 0; i < 6; i ++)
6.175 + if(s1[i] > s2[i])
6.176 + return true;
6.177 + return false;
6.178 + }
6.179 + };
6.180 + std::map<Mac48Address, uint32_t, addrcmp>
6.181 + m_dsnDatabase;
6.182 + std::map<Mac48Address, uint32_t, addrcmp>
6.183 + m_preqMetricDatabase;
6.184 + //Disable/enable functionality
6.185 + bool m_disabled;
6.186 + //Proactive PREQ mechanism:
6.187 + EventId m_proactivePreqTimer;
6.188 + void SendProactivePreq();
6.189 + /**
6.190 + * \brief Two PERRs may not be sent closer to
6.191 + * each other than
6.192 + * dot11MeshHWMPperrMinInterval, so, each HWMP
6.193 + * state collects all unreachable destinations
6.194 + * and once in dot11MeshHWMPperrMinInterval
6.195 + * should send PERR, and PERR element should
6.196 + * be cleared
6.197 + */
6.198 + WifiPerrInformationElement
6.199 + m_myPerr;
6.200 + std::vector<Mac48Address>
6.201 + m_myPerrReceivers;
6.202 + void AddPerrReceiver(Mac48Address receiver);
6.203 + EventId m_perrTimer;
6.204 + void SendOnePerr();
6.205 + //Configurable parameters:
6.206 + uint8_t m_maxTtl;
6.207 + };
6.208 +} //namespace ns3
6.209 +#endif
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/src/devices/l2-routing/l2-routing-hwmp/hwmp.cc Sat Feb 28 14:21:05 2009 +0300
7.3 @@ -0,0 +1,699 @@
7.4 +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
7.5 +/*
7.6 + * Copyright (c) 2008,2009 IITP RAS
7.7 + *
7.8 + * This program is free software; you can redistribute it and/or modify
7.9 + * it under the terms of the GNU General Public License version 2 as
7.10 + * published by the Free Software Foundation;
7.11 + *
7.12 + * This program is distributed in the hope that it will be useful,
7.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7.15 + * GNU General Public License for more details.
7.16 + *
7.17 + * You should have received a copy of the GNU General Public License
7.18 + * along with this program; if not, write to the Free Software
7.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
7.20 + *
7.21 + * Authors: Kirill Andreev <andreev@iitp.ru>
7.22 + * Aleksey Kovalenko <kovalenko@iitp.ru>
7.23 + */
7.24 +
7.25 +
7.26 +#include "ns3/hwmp.h"
7.27 +#include "ns3/log.h"
7.28 +#include "ns3/simulator.h"
7.29 +
7.30 +NS_LOG_COMPONENT_DEFINE ("Hwmp");
7.31 +namespace ns3 {
7.32 +
7.33 +NS_OBJECT_ENSURE_REGISTERED (Hwmp);
7.34 +NS_OBJECT_ENSURE_REGISTERED (HwmpTag);
7.35 +//Class HwmpTag:
7.36 +HwmpTag::HwmpTag()
7.37 +{
7.38 +}
7.39 +
7.40 +HwmpTag::~HwmpTag()
7.41 +{
7.42 +}
7.43 +
7.44 +void
7.45 +HwmpTag::SetAddress(Mac48Address retransmitter)
7.46 +{
7.47 + m_address = retransmitter;
7.48 +}
7.49 +
7.50 +Mac48Address
7.51 +HwmpTag::GetAddress()
7.52 +{
7.53 + return m_address;
7.54 +}
7.55 +
7.56 +void
7.57 +HwmpTag::SetTtl(uint8_t ttl)
7.58 +{
7.59 + m_ttl = ttl;
7.60 +}
7.61 +
7.62 +uint8_t
7.63 +HwmpTag::GetTtl()
7.64 +{
7.65 + return m_ttl;
7.66 +}
7.67 +
7.68 +void
7.69 +HwmpTag::SetMetric(uint32_t metric)
7.70 +{
7.71 + m_metric = metric;
7.72 +}
7.73 +
7.74 +uint32_t
7.75 +HwmpTag::GetMetric()
7.76 +{
7.77 + return m_metric;
7.78 +}
7.79 +
7.80 +void
7.81 +HwmpTag::SetSeqno(uint32_t seqno)
7.82 +{
7.83 + m_seqno = seqno;
7.84 +}
7.85 +
7.86 +uint32_t
7.87 +HwmpTag::GetSeqno()
7.88 +{
7.89 + return m_seqno;
7.90 +}
7.91 +
7.92 +TypeId
7.93 +HwmpTag::GetTypeId (void)
7.94 +{
7.95 + static TypeId tid = TypeId ("ns3::HwmpTag")
7.96 + .SetParent<Tag> ()
7.97 + .AddConstructor<HwmpTag> ()
7.98 + ;
7.99 + return tid;
7.100 +}
7.101 +
7.102 +TypeId
7.103 +HwmpTag::GetInstanceTypeId(void) const
7.104 +{
7.105 + return GetTypeId();
7.106 +}
7.107 +
7.108 +uint32_t
7.109 +HwmpTag::GetSerializedSize(void) const
7.110 +{
7.111 +
7.112 + return 6 //address
7.113 + +1 //ttl
7.114 + +4; //metric
7.115 +}
7.116 +
7.117 +void
7.118 +HwmpTag::Serialize(TagBuffer i) const
7.119 +{
7.120 + uint8_t address[6];
7.121 + int j;
7.122 + m_address.CopyTo(address);
7.123 + i.WriteU8(m_ttl);
7.124 + i.WriteU32(m_metric);
7.125 + for(j = 0;j < 6;j ++)
7.126 + i.WriteU8(address[j]);
7.127 +}
7.128 +
7.129 +void
7.130 +HwmpTag::Deserialize (TagBuffer i)
7.131 +{
7.132 + uint8_t address[6];
7.133 + int j;
7.134 + m_ttl = i.ReadU8();
7.135 + m_metric = i.ReadU32();
7.136 + for(j = 0;j < 6;j ++)
7.137 + address[j] = i.ReadU8();
7.138 + m_address.CopyFrom(address);
7.139 +}
7.140 +
7.141 +void
7.142 +HwmpTag::Print (std::ostream &os) const
7.143 +{
7.144 + os << "address=" << m_address;
7.145 + os << "ttl=" << m_ttl;
7.146 + os << "metrc=" << m_metric;
7.147 +}
7.148 +void
7.149 +HwmpTag::DecrementTtl()
7.150 +{
7.151 + m_ttl --;
7.152 +}
7.153 +//Class HWMP:
7.154 +TypeId
7.155 +Hwmp::GetTypeId (void)
7.156 +{
7.157 + static TypeId tid = TypeId ("ns3::Hwmp")
7.158 + .SetParent<L2RoutingProtocol> ()
7.159 + .AddConstructor<Hwmp>();
7.160 + return tid;
7.161 +}
7.162 +Hwmp::Hwmp()
7.163 +{
7.164 + m_maxTtl = 32;
7.165 + m_broadcastPerr = false;
7.166 + m_rtable = CreateObject<HwmpRtable> ();
7.167 +}
7.168 +
7.169 +Hwmp::~Hwmp()
7.170 +{
7.171 +}
7.172 +
7.173 +void
7.174 +Hwmp::DoDispose()
7.175 +{
7.176 + for(std::map<Mac48Address, EventId, addrcmp>::iterator i = m_timeoutDatabase.begin(); i != m_timeoutDatabase.end(); i ++)
7.177 + i->second.Cancel();
7.178 + m_timeoutDatabase.clear();
7.179 + m_seqnoDatabase.clear();
7.180 + m_rtable = 0;
7.181 +
7.182 + /**
7.183 + * clear routing queue:
7.184 + */
7.185 + for(
7.186 + std::map<Mac48Address, std::queue<struct QueuedPacket> >::iterator i = m_rqueue.begin();
7.187 + i != m_rqueue.end();
7.188 + i++
7.189 + )
7.190 + {
7.191 + while(1)
7.192 + {
7.193 + if(i->second.empty())
7.194 + break;
7.195 + i->second.pop();
7.196 + }
7.197 + }
7.198 + m_rqueue.clear();
7.199 + /**
7.200 + * clear HWMP states
7.201 + */
7.202 + for(unsigned int i = 0; i < m_hwmpStates.size(); i ++)
7.203 + m_hwmpStates[i] = 0;
7.204 + m_hwmpStates.clear();
7.205 +}
7.206 +
7.207 +bool
7.208 +Hwmp::RequestRoute(
7.209 + uint32_t sourceIface,
7.210 + const Mac48Address source,
7.211 + const Mac48Address destination,
7.212 + Ptr<Packet> packet,
7.213 + uint16_t protocolType, //ethrnet 'Protocol' field
7.214 + L2RoutingProtocol::RouteReplyCallback routeReply
7.215 + )
7.216 +{
7.217 + struct HwmpRtable::LookupResult result;
7.218 + HwmpTag tag;
7.219 + if(sourceIface == m_interface)
7.220 + {
7.221 + if(destination == Mac48Address::GetBroadcast())
7.222 + {
7.223 + //set seqno!
7.224 + tag.SetSeqno(m_seqno++);
7.225 + if(m_seqno == MAX_SEQNO)
7.226 + m_seqno = 0;
7.227 + }
7.228 + tag.SetTtl(m_maxTtl);
7.229 + }
7.230 + else
7.231 + {
7.232 + NS_ASSERT(packet->FindFirstMatchingTag(tag));
7.233 + //check seqno!
7.234 + if(destination == Mac48Address::GetBroadcast())
7.235 + {
7.236 + std::map<Mac48Address, uint32_t, addrcmp>::iterator i = m_seqnoDatabase.find(source);
7.237 + if(i == m_seqnoDatabase.end())
7.238 + m_seqnoDatabase[source] = tag.GetSeqno();
7.239 + else
7.240 + {
7.241 + if(i->second >= tag.GetSeqno())
7.242 + return false;
7.243 + m_seqnoDatabase[source] = tag.GetSeqno();
7.244 + }
7.245 + }
7.246 + }
7.247 + tag.SetAddress(Mac48Address::GetBroadcast());
7.248 + if(tag.GetTtl() == 0)
7.249 + return false;
7.250 + tag.DecrementTtl();
7.251 + if(destination == Mac48Address::GetBroadcast())
7.252 + {
7.253 + //add RA tag RA = broadcast
7.254 + packet->RemoveAllTags();
7.255 + packet->AddTag(tag);
7.256 + routeReply(
7.257 + true,
7.258 + packet,
7.259 + source,
7.260 + destination,
7.261 + protocolType,
7.262 + HwmpRtable::PORT_ANY
7.263 + );
7.264 + return true;
7.265 + }
7.266 + result = m_rtable->LookupReactive(destination);
7.267 + if (result.retransmitter == Mac48Address::GetBroadcast())
7.268 + {
7.269 + //no actual route exists, queue packet and start route
7.270 + //discover procedure
7.271 + if(sourceIface != m_interface)
7.272 + {
7.273 + //Start path error procedure:
7.274 + NS_LOG_DEBUG("Must Send PERR");
7.275 + std::vector<struct HwmpRtable::FailedDestination> destinations;
7.276 + struct HwmpRtable::FailedDestination dst;
7.277 + dst.seqnum = m_rtable->RequestSeqnum(destination);
7.278 + dst.destination = destination;
7.279 + destinations.push_back(dst);
7.280 + StartPathErrorProcedure(destinations, result.ifIndex);
7.281 + }
7.282 + struct L2RoutingProtocol::QueuedPacket pkt;
7.283 + packet->RemoveAllTags();
7.284 + packet->AddTag(tag);
7.285 + pkt.pkt = packet;
7.286 + pkt.dst = destination;
7.287 + pkt.src = source;
7.288 + pkt.protocol = protocolType;
7.289 + pkt.reply = routeReply;
7.290 + pkt.inPort = sourceIface;
7.291 + QueuePacket(pkt);
7.292 + for(unsigned int i = 0; i< m_requestCallback.size(); i++)
7.293 + {
7.294 + if((m_modes[i] == REACTIVE) || (m_modes[i] == ROOT))
7.295 + {
7.296 + if(ShouldSendPreq(destination))
7.297 + m_requestCallback[i](destination);
7.298 + }
7.299 + else
7.300 + {
7.301 + NS_ASSERT(false);
7.302 + //PROACTIVE mode
7.303 + //lookup a default route
7.304 + result = m_rtable->LookupProactive(m_hwmpStates[i]->GetAssociatedIfaceId());
7.305 + if(result.retransmitter == Mac48Address::GetBroadcast())
7.306 + {
7.307 + m_rtable->DeleteProactivePath(m_hwmpStates[i]->GetAssociatedIfaceId());
7.308 + m_modes[i] = REACTIVE;
7.309 + if(ShouldSendPreq(destination))
7.310 + m_requestCallback[i](destination);
7.311 + continue;
7.312 + }
7.313 + tag.SetAddress(result.retransmitter);
7.314 + packet->RemoveAllTags();
7.315 + packet->AddTag(tag);
7.316 + routeReply(
7.317 + true,
7.318 + packet,
7.319 + source,
7.320 + destination,
7.321 + protocolType,
7.322 + result.ifIndex
7.323 + );
7.324 + }
7.325 + }
7.326 + for(unsigned int i = 0; i< m_requestCallback.size(); i++)
7.327 + {
7.328 + m_requestCallback[i](Mac48Address("00:00:00:00:00:19"));
7.329 +
7.330 + }
7.331 + }
7.332 + else
7.333 + {
7.334 + tag.SetAddress(result.retransmitter);
7.335 + packet->RemoveAllTags();
7.336 + packet->AddTag(tag);
7.337 + routeReply(
7.338 + true,
7.339 + packet,
7.340 + source,
7.341 + destination,
7.342 + protocolType,
7.343 + result.ifIndex
7.344 + );
7.345 + }
7.346 + return true;
7.347 +}
7.348 +bool
7.349 +Hwmp::AttachPorts(std::vector<Ptr<NetDevice> > ports)
7.350 +{
7.351 + for(std::vector<Ptr<NetDevice> >::iterator i = ports.begin(); i != ports.end(); i++)
7.352 + {
7.353 + //Checking netdevice:
7.354 + const WifiNetDevice * wifiNetDev = dynamic_cast<const WifiNetDevice *> (PeekPointer (*i));
7.355 + if(wifiNetDev == NULL)
7.356 + return false;
7.357 + MeshWifiMac * meshWifiMac = dynamic_cast<MeshWifiMac *> (PeekPointer (wifiNetDev->GetMac()));
7.358 + if(meshWifiMac == NULL)
7.359 + return false;
7.360 + //Adding HWMP-state
7.361 + Ptr<HwmpState> hwmpState = CreateObject<HwmpState> ();
7.362 + hwmpState->SetRoutingInfoCallback(MakeCallback(&Hwmp::ObtainRoutingInformation, this));
7.363 + hwmpState->SetMac(meshWifiMac);
7.364 + hwmpState->SetRequestRouteCallback(MakeCallback(&Hwmp::RequestRouteForAddress, this));
7.365 + hwmpState->SetRequestRootPathCallback(MakeCallback(&Hwmp::RequestRootPathForPort, this));
7.366 + hwmpState->SetAssociatedIfaceId(wifiNetDev->GetIfIndex());
7.367 + hwmpState->SetRetransmittersOfPerrCallback(MakeCallback(&Hwmp::GetRetransmittersForFailedDestinations,this));
7.368 + m_hwmpStates.push_back(hwmpState);
7.369 + m_requestCallback.push_back(MakeCallback(&HwmpState::RequestDestination, hwmpState));
7.370 + m_pathErrorCallback.push_back(MakeCallback(&HwmpState::SendPathError, hwmpState));
7.371 + //Default mode is reactive, default state is enabled
7.372 + enum DeviceState state = ENABLED;
7.373 + enum DeviceMode mode = REACTIVE;
7.374 + m_states.push_back(state);
7.375 + m_modes.push_back(mode);
7.376 + }
7.377 + return true;
7.378 +}
7.379 +
7.380 +void
7.381 +Hwmp::SetIfIndex(uint32_t interface)
7.382 +{
7.383 + m_interface = interface;
7.384 +}
7.385 +
7.386 +void
7.387 +Hwmp::DisablePort(uint32_t port)
7.388 +{
7.389 + int position = 0;
7.390 + for(std::vector<Ptr<HwmpState> >::iterator i = m_hwmpStates.begin(); i!= m_hwmpStates.end(); i++)
7.391 + {
7.392 + if((*i)->GetAssociatedIfaceId() == port)
7.393 + {
7.394 + m_states[position] = DISABLED;
7.395 + m_hwmpStates[position]->Disable();
7.396 + return;
7.397 + }
7.398 + position ++;
7.399 + }
7.400 +}
7.401 +
7.402 +void
7.403 +Hwmp::EnablePort(uint32_t port)
7.404 +{
7.405 + int position = 0;
7.406 + for(std::vector<Ptr<HwmpState> >::iterator i = m_hwmpStates.begin(); i!= m_hwmpStates.end(); i++)
7.407 + {
7.408 + if((*i)->GetAssociatedIfaceId() == port)
7.409 + {
7.410 + m_states[position] = ENABLED;
7.411 + m_hwmpStates[position]->Enable();
7.412 + return;
7.413 + }
7.414 + position ++;
7.415 + }
7.416 +}
7.417 +
7.418 +void
7.419 +Hwmp::SetRoot(uint32_t port)
7.420 +{
7.421 + int position = 0;
7.422 + for(std::vector<Ptr<HwmpState> >::iterator i = m_hwmpStates.begin(); i!= m_hwmpStates.end(); i++)
7.423 + {
7.424 + if(((*i)->GetAssociatedIfaceId() == port)||(port == HwmpRtable::PORT_ANY))
7.425 + {
7.426 + if(m_hwmpStates[position]->SetRoot())
7.427 + {
7.428 + m_modes[position] = ROOT;
7.429 + NS_LOG_DEBUG("I am proactive");
7.430 + }
7.431 + }
7.432 + position ++;
7.433 + }
7.434 +}
7.435 +void
7.436 +Hwmp::SetProactive(uint32_t port)
7.437 +{
7.438 + int position = 0;
7.439 + for(std::vector<Ptr<HwmpState> >::iterator i = m_hwmpStates.begin(); i!= m_hwmpStates.end(); i++)
7.440 + {
7.441 + if((*i)->GetAssociatedIfaceId() == port)
7.442 + {
7.443 + m_modes[position] = PROACTIVE;
7.444 + return;
7.445 + }
7.446 + position ++;
7.447 + }
7.448 +}
7.449 +bool
7.450 +Hwmp::IsRoot(uint32_t port)
7.451 +{
7.452 + int position = 0;
7.453 + for(std::vector<Ptr<HwmpState> >::iterator i = m_hwmpStates.begin(); i!= m_hwmpStates.end(); i++)
7.454 + {
7.455 + if((*i)->GetAssociatedIfaceId() == port)
7.456 + if(m_modes[position] == ROOT)
7.457 + return true;
7.458 + position ++;
7.459 + }
7.460 + return false;
7.461 +}
7.462 +void
7.463 +Hwmp::UnSetRoot(uint32_t port)
7.464 +{
7.465 + int position = 0;
7.466 + for(std::vector<Ptr<HwmpState> >::iterator i = m_hwmpStates.begin(); i!= m_hwmpStates.end(); i++)
7.467 + {
7.468 + if(((*i)->GetAssociatedIfaceId() == port)||(port == HwmpRtable::PORT_ANY))
7.469 + {
7.470 + m_modes[position] = REACTIVE;
7.471 + m_hwmpStates[position]->UnSetRoot();
7.472 + }
7.473 + position ++;
7.474 + }
7.475 +}
7.476 +
7.477 +void
7.478 +Hwmp::ObtainRoutingInformation(
7.479 + HwmpState::INFO info
7.480 + )
7.481 +{
7.482 + switch(info.type)
7.483 + {
7.484 + case HwmpState::INFO_PREP:
7.485 + if(info.me != info.source)
7.486 + {
7.487 + m_rtable->AddPrecursor(info.source, info.outPort, info.nextHop);
7.488 + m_rtable->AddPrecursor(info.destination, info.outPort, info.prevHop);
7.489 + NS_LOG_DEBUG("path to "<<info.source<<" precursor is "<<info.nextHop);
7.490 + NS_LOG_DEBUG("path to "<<info.destination<<" precursor is "<<info.prevHop);
7.491 + }
7.492 + case HwmpState::INFO_PREQ:
7.493 + m_rtable->AddReactivePath(
7.494 + info.destination,
7.495 + info.nextHop,
7.496 + info.outPort,
7.497 + info.metric,
7.498 + info.lifetime,
7.499 + info.dsn);
7.500 + SendAllPossiblePackets(info.destination);
7.501 + break;
7.502 + case HwmpState::INFO_PERR:
7.503 + //delete first subentry
7.504 + case HwmpState::INFO_PROACTIVE:
7.505 + //add information to the root MP.
7.506 + m_rtable->AddProactivePath(
7.507 + info.metric,
7.508 + info.destination,
7.509 + info.nextHop,
7.510 + info.outPort,
7.511 + info.lifetime,
7.512 + info.dsn);
7.513 + //Set mode as PROACTIVE:
7.514 + SetProactive(info.outPort);
7.515 + break;
7.516 + case HwmpState::INFO_NEW_PEER:
7.517 +#if 0
7.518 + m_rtable->AddReactivePath(
7.519 + info.destination,
7.520 + info.nextHop,
7.521 + info.outPort,
7.522 + info.metric,
7.523 + Seconds(0),
7.524 + 0);
7.525 +#endif
7.526 + break;
7.527 + case HwmpState::INFO_FAILED_PEER:
7.528 + /**
7.529 + * Conditions for generating PERR
7.530 + */
7.531 + {
7.532 + NS_LOG_DEBUG("Failed peer"<<info.destination);
7.533 + std::vector<struct HwmpRtable::FailedDestination> failedDestinations =
7.534 + m_rtable->GetUnreachableDestinations(info.destination, info.outPort);
7.535 + /**
7.536 + * Entry about peer does not contain seqnum
7.537 + */
7.538 + struct HwmpRtable::FailedDestination peer;
7.539 + peer.destination = info.destination;
7.540 + peer.seqnum = 0;
7.541 + failedDestinations.push_back(peer);
7.542 + StartPathErrorProcedure(failedDestinations, info.outPort);
7.543 + }
7.544 + break;
7.545 + default:
7.546 + return;
7.547 + }
7.548 +}
7.549 +
7.550 +struct HwmpRtable::LookupResult
7.551 +Hwmp::RequestRouteForAddress(const Mac48Address& dst)
7.552 +{
7.553 + return m_rtable->LookupReactive(dst);
7.554 +}
7.555 +
7.556 +struct HwmpRtable::LookupResult
7.557 +Hwmp::RequestRootPathForPort(uint32_t port)
7.558 +{
7.559 + return m_rtable->LookupProactive(port);
7.560 +}
7.561 +
7.562 +void
7.563 +Hwmp::StartPathErrorProcedure(std::vector<struct HwmpRtable::FailedDestination> destinations, uint32_t port)
7.564 +{
7.565 + NS_LOG_DEBUG("START PERR");
7.566 + for(unsigned int i = 0; i < m_hwmpStates.size(); i++)
7.567 + if(m_hwmpStates[i]->GetAssociatedIfaceId() == port)
7.568 + m_pathErrorCallback[i](destinations);
7.569 +}
7.570 +std::vector<Mac48Address>
7.571 +Hwmp::GetRetransmittersForFailedDestinations(std::vector<struct HwmpRtable::FailedDestination> failedDest, uint32_t port)
7.572 +{
7.573 + std::vector<Mac48Address> retransmitters;
7.574 + if(m_broadcastPerr)
7.575 + retransmitters.push_back(Mac48Address::GetBroadcast());
7.576 + else
7.577 + for(unsigned int i = 0; i< failedDest.size(); i ++)
7.578 + {
7.579 + std::vector<Mac48Address> precursors =
7.580 + m_rtable->GetPrecursors(failedDest[i].destination, port);
7.581 + for(unsigned int j = 0; j < precursors.size(); j++)
7.582 + {
7.583 + for(unsigned int k = 0; k < retransmitters.size(); k ++)
7.584 + if(retransmitters[k] == precursors[j])
7.585 + break;
7.586 + retransmitters.push_back(precursors[j]);
7.587 + }
7.588 + }
7.589 + for(unsigned int i = 0; i < failedDest.size(); i ++)
7.590 + {
7.591 + m_rtable->DeleteReactivePath(failedDest[i].destination, port);
7.592 + m_rtable->DeleteProactivePath(failedDest[i].destination, port);
7.593 + }
7.594 + return retransmitters;
7.595 +}
7.596 +void
7.597 +Hwmp::SetMaxQueueSize(int maxPacketsPerDestination)
7.598 +{
7.599 + m_maxQueueSize = maxPacketsPerDestination;
7.600 +}
7.601 +
7.602 +bool
7.603 +Hwmp::QueuePacket(struct L2RoutingProtocol::QueuedPacket packet)
7.604 +{
7.605 + if((int)m_rqueue[packet.dst].size() > m_maxQueueSize)
7.606 + return false;
7.607 + m_rqueue[packet.dst].push(packet);
7.608 + return true;
7.609 +}
7.610 +
7.611 +struct L2RoutingProtocol::QueuedPacket
7.612 +Hwmp::DequeuePacket(Mac48Address dst)
7.613 +{
7.614 + struct L2RoutingProtocol::QueuedPacket retval;
7.615 + retval.pkt = NULL;
7.616 + //Ptr<Packet> in this structure is NULL when queue is empty
7.617 + std::map<Mac48Address, std::queue<struct QueuedPacket>, addrcmp>:: iterator i = m_rqueue.find(dst);
7.618 + if(i == m_rqueue.end())
7.619 + return retval;
7.620 + if((int)m_rqueue[dst].size() == 0)
7.621 + return retval;
7.622 + if((int)i->second.size() == 0)
7.623 + {
7.624 + m_rqueue.erase(i);
7.625 + return retval;
7.626 + }
7.627 + retval = m_rqueue[dst].front();
7.628 + m_rqueue[dst].pop();
7.629 + return retval;
7.630 +}
7.631 +
7.632 +void
7.633 +Hwmp::SendAllPossiblePackets(Mac48Address dst)
7.634 +{
7.635 + struct HwmpRtable::LookupResult result = m_rtable->LookupReactive(dst);
7.636 + struct L2RoutingProtocol::QueuedPacket packet;
7.637 + while(1)
7.638 +
7.639 + {
7.640 + packet = DequeuePacket(dst);
7.641 + if(packet.pkt == NULL)
7.642 + return;
7.643 + //set RA tag for retransmitter:
7.644 + HwmpTag tag;
7.645 + NS_ASSERT(packet.pkt->FindFirstMatchingTag(tag));
7.646 + tag.SetAddress(result.retransmitter);
7.647 + NS_ASSERT(result.retransmitter!=Mac48Address::GetBroadcast());
7.648 + packet.pkt->RemoveAllTags();
7.649 + packet.pkt->AddTag(tag);
7.650 + packet.reply(true, packet.pkt, packet.src, packet.dst, packet.protocol, result.ifIndex);
7.651 + }
7.652 +}
7.653 +
7.654 +bool
7.655 +Hwmp::ShouldSendPreq(Mac48Address dst)
7.656 +{
7.657 + std::map<Mac48Address, EventId, addrcmp>::iterator i = m_timeoutDatabase.find(dst);
7.658 + if(i == m_timeoutDatabase.end())
7.659 + {
7.660 + m_timeoutDatabase[dst] = Simulator::Schedule(
7.661 + MilliSeconds(2*(dot11sParameters::dot11MeshHWMPnetDiameterTraversalTime.GetMilliSeconds())),
7.662 + &Hwmp::RetryPathDiscovery, this, dst, 0);
7.663 + return true;
7.664 + }
7.665 + return false;
7.666 +}
7.667 +void
7.668 +Hwmp::RetryPathDiscovery(Mac48Address dst, uint8_t numOfRetry)
7.669 +{
7.670 + struct HwmpRtable::LookupResult result = m_rtable->LookupReactive(dst);
7.671 + if(result.retransmitter != Mac48Address::GetBroadcast())
7.672 + {
7.673 + std::map<Mac48Address, EventId, addrcmp>::iterator i = m_timeoutDatabase.find(dst);
7.674 + NS_ASSERT(i!= m_timeoutDatabase.end());
7.675 + m_timeoutDatabase.erase(i);
7.676 + return;
7.677 + }
7.678 + numOfRetry++;
7.679 + if(numOfRetry > dot11sParameters::dot11MeshHWMPmaxPREQretries)
7.680 + {
7.681 + struct L2RoutingProtocol::QueuedPacket packet;
7.682 + //purge queue and delete entry from retryDatabase
7.683 + while(1)
7.684 + {
7.685 + packet = DequeuePacket(dst);
7.686 + if(packet.pkt == NULL)
7.687 + break;
7.688 + packet.reply(false, packet.pkt, packet.src, packet.dst, packet.protocol, HwmpRtable::MAX_METRIC);
7.689 + }
7.690 + std::map<Mac48Address, EventId, addrcmp>::iterator i = m_timeoutDatabase.find(dst);
7.691 + NS_ASSERT(i!= m_timeoutDatabase.end());
7.692 + m_timeoutDatabase.erase(i);
7.693 + return;
7.694 + }
7.695 + for(unsigned int i = 0; i< m_requestCallback.size(); i++)
7.696 + if((m_modes[i] == REACTIVE) || (m_modes[i] == ROOT))
7.697 + m_requestCallback[i](dst);
7.698 + m_timeoutDatabase[dst] = Simulator::Schedule(
7.699 + MilliSeconds(2*(dot11sParameters::dot11MeshHWMPnetDiameterTraversalTime.GetMilliSeconds())),
7.700 + &Hwmp::RetryPathDiscovery, this, dst, numOfRetry);
7.701 +}
7.702 +} //namespace ns3
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/src/devices/l2-routing/l2-routing-hwmp/hwmp.h Sat Feb 28 14:21:05 2009 +0300
8.3 @@ -0,0 +1,303 @@
8.4 +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
8.5 +/*
8.6 + * Copyright (c) 2008,2009 IITP RAS
8.7 + *
8.8 + * This program is free software; you can redistribute it and/or modify
8.9 + * it under the terms of the GNU General Public License version 2 as
8.10 + * published by the Free Software Foundation;
8.11 + *
8.12 + * This program is distributed in the hope that it will be useful,
8.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8.15 + * GNU General Public License for more details.
8.16 + *
8.17 + * You should have received a copy of the GNU General Public License
8.18 + * along with this program; if not, write to the Free Software
8.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
8.20 + *
8.21 + * Authors: Kirill Andreev <andreev@iitp.ru>
8.22 + * Aleksey Kovalenko <kovalenko@iitp.ru>
8.23 + */
8.24 +
8.25 +
8.26 +#ifndef HWMP_H
8.27 +#define HWMP_H
8.28 +#include <map>
8.29 +#include <queue>
8.30 +#include "ns3/tag.h"
8.31 +#include "ns3/object.h"
8.32 +#include "ns3/mac48-address.h"
8.33 +#include "ns3/l2-routing-protocol.h"
8.34 +#include "ns3/packet.h"
8.35 +#include "ns3/ptr.h"
8.36 +#include "hwmp-state.h"
8.37 +namespace ns3 {
8.38 + class HwmpState;
8.39 + /**
8.40 + * \brief Hwmp tag implements interaction between HWMP
8.41 + * protocol and MeshWifiMac
8.42 + * \details Hwmp tag keeps the following:
8.43 + * 1. When packet is passed from Hwmp to 11sMAC:
8.44 + * - retransmitter address,
8.45 + * - TTL value,
8.46 + * 2. When packet is passed to Hwmp from 11sMAC:
8.47 + * - lasthop address,
8.48 + * - TTL value,
8.49 + * - metric value (metric of link is recalculated
8.50 + * at each packet, but routing table stores metric
8.51 + * obtained during path discovery procedure)
8.52 + */
8.53 + class HwmpTag : public Tag
8.54 + {
8.55 + public:
8.56 + HwmpTag();
8.57 + ~HwmpTag();
8.58 + void SetAddress(Mac48Address retransmitter);
8.59 + Mac48Address GetAddress();
8.60 + void SetTtl(uint8_t ttl);
8.61 + uint8_t GetTtl();
8.62 + void SetMetric(uint32_t metric);
8.63 + uint32_t GetMetric();
8.64 + void SetSeqno(uint32_t seqno);
8.65 + uint32_t GetSeqno();
8.66 + void DecrementTtl();
8.67 +
8.68 + static TypeId GetTypeId (void);
8.69 + virtual TypeId GetInstanceTypeId (void) const;
8.70 + virtual uint32_t GetSerializedSize (void) const;
8.71 + virtual void Serialize (TagBuffer i) const;
8.72 + virtual void Deserialize (TagBuffer i);
8.73 + virtual void Print (std::ostream &os) const;
8.74 + private:
8.75 + Mac48Address m_address;
8.76 + uint8_t m_ttl;
8.77 + uint32_t m_metric;
8.78 + uint32_t m_seqno;
8.79 + };
8.80 + class Hwmp : public L2RoutingProtocol
8.81 + {
8.82 + public:
8.83 + static TypeId GetTypeId();
8.84 + Hwmp();
8.85 + ~Hwmp();
8.86 + void DoDispose();
8.87 + //intheritedfrom L2RoutingProtocol
8.88 + /**
8.89 + * \brief L2Routing protocol base class metod
8.90 + *
8.91 + * \details Route resolving procedure consits
8.92 + * of the following steps:
8.93 + * 1. Find reactive route and send a packet.
8.94 + * 2. Find all ports which are operate in
8.95 + * 'Proactive' mode and find a proper default
8.96 + * routes. and send packet to all proactive
8.97 + * 'ports'.
8.98 + * 3. If there are ports which are operate in
8.99 + * reactive mode - queue packet and start
8.100 + * route reactive path discovery
8.101 + *
8.102 + * \bug Now packet is sent to the 'best root'
8.103 + * rather than to the best root at each port
8.104 + */
8.105 + bool RequestRoute(
8.106 + uint32_t sourceIface,
8.107 + const Mac48Address source,
8.108 + const Mac48Address destination,
8.109 + Ptr<Packet> packet,
8.110 + uint16_t protocolType,
8.111 + L2RoutingProtocol::RouteReplyCallback
8.112 + routeReply
8.113 + );
8.114 + bool AttachPorts(std::vector<Ptr<NetDevice> >);
8.115 + void SetIfIndex(uint32_t interface);
8.116 + /**
8.117 + * \brief Disables port by index.
8.118 + * \details Needed for external modules like
8.119 + * clusterization.
8.120 + */
8.121 + void DisablePort(uint32_t port);
8.122 + /**
8.123 + * \brief enables port
8.124 + */
8.125 + void EnablePort(uint32_t port);
8.126 + /**
8.127 + * \brief Setting proative mode.
8.128 + * \details To enable proactive mode you must
8.129 + * set a root node. Choosing the route is made
8.130 + * in accordance with the following:
8.131 + * 1. Find 'reactive' route. If route is
8.132 + * found - send a packet using this
8.133 + * information
8.134 + * 2. If there is no reactive route -
8.135 + * find proactive or 'default' route.
8.136 + * \attention Comparsion between proactive and
8.137 + * reactive routes is incorrect, because we
8.138 + * have metric to root MP in te first case and
8.139 + * metric to the destination in the second
8.140 + * case.
8.141 + * \param port is the port where proactive
8.142 + * mode should be activated
8.143 + */
8.144 + void SetRoot(uint32_t port);
8.145 + /**
8.146 + * \brief Disable root functionality at a
8.147 + * given port
8.148 + */
8.149 + void UnSetRoot(uint32_t port);
8.150 + /**
8.151 + * \brief HwmpState retrns to Hwmp class all
8.152 + * routing information obtained from all HWMP
8.153 + * action frames
8.154 + */
8.155 + void ObtainRoutingInformation(
8.156 + HwmpState::INFO info
8.157 + );
8.158 + /**
8.159 + * \brief Hwmp state noyifyes that neighbour
8.160 + * is dissapeared. Hwmp state knows about peer
8.161 + * failure from MAC
8.162 + */
8.163 + void PeerFailure(Mac48Address peerAddress);
8.164 + void SetMaxTtl(uint8_t ttl);
8.165 + uint8_t
8.166 + GetMaxTtl();
8.167 + private:
8.168 + static const uint32_t MAX_SEQNO = 0xffffffff;
8.169 + //candidate queue is implemented inside the
8.170 + //protocol:
8.171 + void SetMaxQueueSize(int maxPacketsPerDestination);
8.172 + int m_maxQueueSize;
8.173 + bool QueuePacket(struct L2RoutingProtocol::QueuedPacket packet);
8.174 + struct L2RoutingProtocol::QueuedPacket
8.175 + DequeuePacket(Mac48Address dst);
8.176 + void SendAllPossiblePackets(Mac48Address dst);
8.177 + struct addrcmp
8.178 + {
8.179 + bool operator()(const Mac48Address addr1, Mac48Address addr2) const
8.180 + {
8.181 + uint8_t s1[6], s2[6];
8.182 + addr1.CopyTo(s1);
8.183 + addr2.CopyTo(s2);
8.184 + for(int i = 0; i < 6; i ++)
8.185 + if(s1[i] > s2[i])
8.186 + return true;
8.187 + return false;
8.188 + }
8.189 + };
8.190 + std::map<Mac48Address, std::queue<struct QueuedPacket> >
8.191 + m_rqueue;
8.192 + //devices and HWMP states:
8.193 + enum DeviceState {
8.194 + ENABLED,
8.195 + DISABLED
8.196 + };
8.197 + enum DeviceMode {
8.198 + REACTIVE,
8.199 + PROACTIVE,
8.200 + ROOT
8.201 + };
8.202 + std::vector<enum DeviceState>
8.203 + m_states;
8.204 + std::vector<enum DeviceMode>
8.205 + m_modes;
8.206 + std::vector<Ptr<HwmpState> >
8.207 + m_hwmpStates;
8.208 + //Routing table:
8.209 + Ptr<HwmpRtable>
8.210 + m_rtable;
8.211 + //Proactive routines:
8.212 + /**
8.213 + * \brief Set port state as proactive.
8.214 + * \details mode is supposed to be proactive
8.215 + * when proatcive PREQ with a valid
8.216 + * information was received.
8.217 + */
8.218 + void SetProactive(uint32_t port);
8.219 + /**
8.220 + * \brief Checks if the port is root, if true
8.221 + * - no default routes must be used at this
8.222 + * port
8.223 + */
8.224 + bool IsRoot(uint32_t port);
8.225 + /**
8.226 + * \brief Interaction with HwmpState class -
8.227 + * request for starting routing discover
8.228 + * procedure (reactive route discovery!)
8.229 + * \param Mac48Address is destination to be
8.230 + * resolved
8.231 + */
8.232 + std::vector< Callback<void, Mac48Address> >
8.233 + m_requestCallback;
8.234 + /**
8.235 + * \brief Callback that shall be executed when
8.236 + * need to send Path error
8.237 + * \param std::vector<Mac48Address> is the
8.238 + * list of unreachable destinations
8.239 + * \param std::vector<Mac48Address> is
8.240 + * receivers of PERR
8.241 + */
8.242 + std::vector<Callback<void,std::vector<struct HwmpRtable::FailedDestination> > >
8.243 + m_pathErrorCallback;
8.244 + void StartPathErrorProcedure(
8.245 + std::vector<struct HwmpRtable::FailedDestination> destinations,
8.246 + uint32_t port);
8.247 + /**
8.248 + * \brief HwmpState need to know where to
8.249 + * retransmit PERR, only HWMP knows how to
8.250 + * retransmit it (broadcast/unicast) and only
8.251 + * HWMP has accessto routing table
8.252 + */
8.253 + std::vector<Mac48Address>
8.254 + GetRetransmittersForFailedDestinations(
8.255 + std::vector<struct HwmpRtable::FailedDestination> failedDest,
8.256 + uint32_t port);
8.257 + /**
8.258 + * \brief Needed by HwmpState to find routes in case
8.259 + * of intermediate reply and choosing the
8.260 + * better route
8.261 + *
8.262 + */
8.263 + struct HwmpRtable::LookupResult
8.264 + RequestRouteForAddress(const Mac48Address& destination);
8.265 + struct HwmpRtable::LookupResult
8.266 + RequestRootPathForPort(uint32_t port);
8.267 +
8.268 + /**
8.269 + * \brief interface which is the HWMP attached to
8.270 + * (Virtual netdevice)
8.271 + */
8.272 + uint32_t m_interface;
8.273 + /**
8.274 + * \attention mesh seqno is processed at HWMP
8.275 + */
8.276 + uint32_t m_seqno;
8.277 + std::map<Mac48Address, uint32_t, addrcmp>
8.278 + m_seqnoDatabase;
8.279 + //Timers:
8.280 + /**
8.281 + * /brief checks when last preq was initiated, returns
8.282 + * false when retry has not expired
8.283 + */
8.284 + bool ShouldSendPreq(Mac48Address dst);
8.285 + /**
8.286 + * \brief Generates PREQ retry when route is
8.287 + * still unresolved after first PREQ
8.288 + * If number of retries greater than
8.289 + * dot11sParameters::dot11MeshHWMPmaxPREQretries,
8.290 + * we return all packets to upper layers
8.291 + */
8.292 + void RetryPathDiscovery(Mac48Address dst, uint8_t numOfRetry);
8.293 + /**
8.294 + * Keeps PREQ retry timers for every
8.295 + * destination
8.296 + */
8.297 + std::map<Mac48Address, EventId, addrcmp>
8.298 + m_timeoutDatabase;
8.299 + /**
8.300 + * Configurable parameters:
8.301 + */
8.302 + uint8_t m_maxTtl;
8.303 + bool m_broadcastPerr;
8.304 + };
8.305 +} //namespace ns3
8.306 +#endif
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/src/devices/l2-routing/l2-routing-hwmp/waf Sat Feb 28 14:21:05 2009 +0300
9.3 @@ -0,0 +1,1 @@
9.4 +exec "`dirname "$0"`"/../../../../waf "$@"
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/src/devices/l2-routing/l2-routing-hwmp/wscript Sat Feb 28 14:21:05 2009 +0300
10.3 @@ -0,0 +1,16 @@
10.4 +## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
10.5 +
10.6 +def build(bld):
10.7 + obj = bld.create_ns3_module('l2-routing-hwmp', ['node', 'l2-routing-main'])
10.8 + obj.source = [
10.9 + 'hwmp-rtable.cc',
10.10 + 'hwmp-state.cc',
10.11 + 'hwmp.cc',
10.12 + ]
10.13 + headers = bld.new_task_gen('ns3header')
10.14 + headers.module = 'l2-routing-hwmp'
10.15 + headers.source = [
10.16 + 'hwmp-rtable.h',
10.17 + 'hwmp-state.h',
10.18 + 'hwmp.h',
10.19 + ]
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/src/devices/l2-routing/l2-routing-main/l2-routing-net-device.cc Sat Feb 28 14:21:05 2009 +0300
11.3 @@ -0,0 +1,355 @@
11.4 +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
11.5 +/*
11.6 + * Copyright (c) 2008,2009 IITP RAS
11.7 + *
11.8 + * This program is free software; you can redistribute it and/or modify
11.9 + * it under the terms of the GNU General Public License version 2 as
11.10 + * published by the Free Software Foundation;
11.11 + *
11.12 + * This program is distributed in the hope that it will be useful,
11.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11.15 + * GNU General Public License for more details.
11.16 + *
11.17 + * You should have received a copy of the GNU General Public License
11.18 + * along with this program; if not, write to the Free Software
11.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
11.20 + *
11.21 + * Author: Kirill Andreev <andreev@iitp.ru>
11.22 + */
11.23 +
11.24 +
11.25 +#include "ns3/node.h"
11.26 +#include "ns3/channel.h"
11.27 +#include "ns3/packet.h"
11.28 +#include "ns3/log.h"
11.29 +#include "ns3/boolean.h"
11.30 +#include "ns3/simulator.h"
11.31 +#include "ns3/l2-routing-net-device.h"
11.32 +
11.33 +NS_LOG_COMPONENT_DEFINE ("L2RoutingNetDevice");
11.34 +
11.35 +namespace ns3 {
11.36 +
11.37 +NS_OBJECT_ENSURE_REGISTERED (L2RoutingNetDevice);
11.38 +
11.39 +
11.40 +TypeId
11.41 +L2RoutingNetDevice::GetTypeId (void)
11.42 +{
11.43 + static TypeId tid = TypeId ("ns3::L2RoutingNetDevice")
11.44 + .SetParent<NetDevice> ()
11.45 + .AddConstructor<L2RoutingNetDevice> ()
11.46 + ;
11.47 + return tid;
11.48 +}
11.49 +
11.50 +
11.51 +L2RoutingNetDevice::L2RoutingNetDevice ()
11.52 +{
11.53 + NS_LOG_FUNCTION_NOARGS ();
11.54 + m_channel = CreateObject<BridgeChannel> ();
11.55 +}
11.56 +
11.57 +L2RoutingNetDevice::~L2RoutingNetDevice()
11.58 +{
11.59 + NS_LOG_FUNCTION_NOARGS ();
11.60 +}
11.61 +
11.62 + void
11.63 +L2RoutingNetDevice::DoDispose ()
11.64 +{
11.65 + NS_LOG_FUNCTION_NOARGS ();
11.66 + for (std::vector< Ptr<NetDevice> >::iterator iter = m_ports.begin (); iter != m_ports.end (); iter++)
11.67 + *iter = 0;
11.68 + m_ports.clear ();
11.69 + m_node = 0;
11.70 + NetDevice::DoDispose ();
11.71 +
11.72 +}
11.73 +
11.74 + void
11.75 +L2RoutingNetDevice::ReceiveFromDevice (Ptr<NetDevice> incomingPort, Ptr<const Packet> packet, uint16_t protocol,
11.76 + Address const &src, Address const &dst, PacketType packetType)
11.77 +{
11.78 + NS_LOG_FUNCTION_NOARGS ();
11.79 + NS_LOG_DEBUG ("UID is " << packet->GetUid ());
11.80 + const Mac48Address src48 = Mac48Address::ConvertFrom (src);
11.81 + const Mac48Address dst48 = Mac48Address::ConvertFrom (dst);
11.82 + if (!m_promiscRxCallback.IsNull ())
11.83 + m_promiscRxCallback (this, packet, protocol, src, dst, packetType);
11.84 + switch (packetType)
11.85 + {
11.86 + case PACKET_HOST:
11.87 + if (dst48 == m_address)
11.88 + m_rxCallback (this, packet, protocol, src);
11.89 + break;
11.90 + case PACKET_BROADCAST:
11.91 + case PACKET_MULTICAST:
11.92 + m_rxCallback (this, packet, protocol, src);
11.93 + case PACKET_OTHERHOST:
11.94 + Forward (incomingPort, packet->Copy(), protocol, src48, dst48);
11.95 + break;
11.96 + }
11.97 +
11.98 +}
11.99 +
11.100 +void
11.101 +L2RoutingNetDevice::Forward (Ptr<NetDevice> inport, Ptr<Packet> packet,
11.102 + uint16_t protocol, const Mac48Address src, const Mac48Address dst)
11.103 +{
11.104 + //pass through routing protocol
11.105 + m_requestRoute(inport->GetIfIndex(), src, dst, packet, protocol, m_myResponse);
11.106 +}
11.107 +
11.108 +uint32_t
11.109 +L2RoutingNetDevice::GetNPorts (void) const
11.110 +{
11.111 + NS_LOG_FUNCTION_NOARGS ();
11.112 + return m_ports.size ();
11.113 +}
11.114 +
11.115 +Ptr<NetDevice>
11.116 +L2RoutingNetDevice::GetPort (uint32_t n) const
11.117 +{
11.118 + NS_ASSERT(m_ports.size () > n);
11.119 + return m_ports[n];
11.120 +}
11.121 +
11.122 +void
11.123 +L2RoutingNetDevice::AddPort (Ptr<NetDevice> routingPort)
11.124 +{
11.125 + NS_LOG_FUNCTION_NOARGS ();
11.126 + NS_ASSERT (routingPort != this);
11.127 + if (!Mac48Address::IsMatchingType (routingPort->GetAddress ()))
11.128 + NS_FATAL_ERROR ("Device does not support eui 48 addresses: cannot be added to bridge.");
11.129 + if (!routingPort->SupportsSendFrom ())
11.130 + NS_FATAL_ERROR ("Device does not support SendFrom: cannot be added to bridge.");
11.131 + m_address = Mac48Address::ConvertFrom (routingPort->GetAddress ());
11.132 + NS_LOG_DEBUG ("RegisterProtocolHandler for " << routingPort->GetName ());
11.133 + m_node->RegisterProtocolHandler (MakeCallback (&L2RoutingNetDevice::ReceiveFromDevice, this),
11.134 + 0, routingPort, true);
11.135 + m_ports.push_back (routingPort);
11.136 + m_channel->AddChannel (routingPort->GetChannel ());
11.137 +}
11.138 +
11.139 + void
11.140 +L2RoutingNetDevice::SetName(const std::string name)
11.141 +{
11.142 + NS_LOG_FUNCTION_NOARGS ();
11.143 + m_name = name;
11.144 +}
11.145 +
11.146 +std::string
11.147 +L2RoutingNetDevice::GetName(void) const
11.148 +{
11.149 + NS_LOG_FUNCTION_NOARGS ();
11.150 + return m_name;
11.151 +}
11.152 +
11.153 + void
11.154 +L2RoutingNetDevice::SetIfIndex(const uint32_t index)
11.155 +{
11.156 + NS_LOG_FUNCTION_NOARGS ();
11.157 + m_ifIndex = index;
11.158 +}
11.159 +
11.160 +uint32_t
11.161 +L2RoutingNetDevice::GetIfIndex(void) const
11.162 +{
11.163 + NS_LOG_FUNCTION_NOARGS ();
11.164 + return m_ifIndex;
11.165 +}
11.166 +
11.167 +Ptr<Channel>
11.168 +L2RoutingNetDevice::GetChannel (void) const
11.169 +{
11.170 + NS_LOG_FUNCTION_NOARGS ();
11.171 + return m_channel;
11.172 +}
11.173 +
11.174 +Address
11.175 +L2RoutingNetDevice::GetAddress (void) const
11.176 +{
11.177 + NS_LOG_FUNCTION_NOARGS ();
11.178 + return m_address;
11.179 +}
11.180 +
11.181 + bool
11.182 +L2RoutingNetDevice::SetMtu (const uint16_t mtu)
11.183 +{
11.184 + NS_LOG_FUNCTION_NOARGS ();
11.185 + m_mtu = mtu;
11.186 + return true;
11.187 +}
11.188 +
11.189 +uint16_t
11.190 +L2RoutingNetDevice::GetMtu (void) const
11.191 +{
11.192 + NS_LOG_FUNCTION_NOARGS ();
11.193 + return 1500;
11.194 +}
11.195 +
11.196 +
11.197 +bool
11.198 +L2RoutingNetDevice::IsLinkUp (void) const
11.199 +{
11.200 + NS_LOG_FUNCTION_NOARGS ();
11.201 + return true;
11.202 +}
11.203 +
11.204 +
11.205 + void
11.206 +L2RoutingNetDevice::SetLinkChangeCallback (Callback<void> callback)
11.207 +{}
11.208 +
11.209 +bool
11.210 +L2RoutingNetDevice::IsBroadcast (void) const
11.211 +{
11.212 + NS_LOG_FUNCTION_NOARGS ();
11.213 + return true;
11.214 +}
11.215 +
11.216 +
11.217 +Address
11.218 +L2RoutingNetDevice::GetBroadcast (void) const
11.219 +{
11.220 + NS_LOG_FUNCTION_NOARGS ();
11.221 + return Mac48Address ("ff:ff:ff:ff:ff:ff");
11.222 +}
11.223 +
11.224 +bool
11.225 +L2RoutingNetDevice::IsMulticast (void) const
11.226 +{
11.227 + NS_LOG_FUNCTION_NOARGS ();
11.228 + return true;
11.229 +}
11.230 +
11.231 +Address
11.232 +L2RoutingNetDevice::GetMulticast (Ipv4Address multicastGroup) const
11.233 +{
11.234 + NS_LOG_FUNCTION (this << multicastGroup);
11.235 + Mac48Address multicast = Mac48Address::GetMulticast (multicastGroup);
11.236 + return multicast;
11.237 +}
11.238 +
11.239 +
11.240 +bool
11.241 +L2RoutingNetDevice::IsPointToPoint (void) const
11.242 +{
11.243 + NS_LOG_FUNCTION_NOARGS ();
11.244 + return false;
11.245 +}
11.246 +
11.247 +bool
11.248 +L2RoutingNetDevice::IsBridge (void) const
11.249 +{
11.250 + NS_LOG_FUNCTION_NOARGS ();
11.251 + return false;
11.252 +}
11.253 +
11.254 +
11.255 +bool
11.256 +L2RoutingNetDevice::Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
11.257 +{
11.258 +
11.259 + const Mac48Address dst48 = Mac48Address::ConvertFrom (dest);
11.260 + return m_requestRoute(m_ifIndex, m_address, dst48, packet, protocolNumber, m_myResponse);
11.261 +}
11.262 +
11.263 +bool
11.264 +L2RoutingNetDevice::SendFrom (Ptr<Packet> packet, const Address& src, const Address& dest, uint16_t protocolNumber)
11.265 +{
11.266 + const Mac48Address src48 = Mac48Address::ConvertFrom (src);
11.267 + const Mac48Address dst48 = Mac48Address::ConvertFrom (dest);
11.268 + return m_requestRoute(m_ifIndex, src48, dst48, packet, protocolNumber, m_myResponse);
11.269 +}
11.270 +
11.271 +
11.272 +Ptr<Node>
11.273 +L2RoutingNetDevice::GetNode (void) const
11.274 +{
11.275 + NS_LOG_FUNCTION_NOARGS ();
11.276 + return m_node;
11.277 +}
11.278 +
11.279 +
11.280 + void
11.281 +L2RoutingNetDevice::SetNode (Ptr<Node> node)
11.282 +{
11.283 + NS_LOG_FUNCTION_NOARGS ();
11.284 + m_node = node;
11.285 +}
11.286 +
11.287 +
11.288 +bool
11.289 +L2RoutingNetDevice::NeedsArp (void) const
11.290 +{
11.291 + NS_LOG_FUNCTION_NOARGS ();
11.292 + return true;
11.293 +}
11.294 +
11.295 +
11.296 + void
11.297 +L2RoutingNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb)
11.298 +{
11.299 + NS_LOG_FUNCTION_NOARGS ();
11.300 + m_rxCallback = cb;
11.301 +}
11.302 +
11.303 + void
11.304 +L2RoutingNetDevice::SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb)
11.305 +{
11.306 + NS_LOG_FUNCTION_NOARGS ();
11.307 + m_promiscRxCallback = cb;
11.308 +}
11.309 +
11.310 +bool
11.311 +L2RoutingNetDevice::SupportsSendFrom () const
11.312 +{
11.313 + NS_LOG_FUNCTION_NOARGS ();
11.314 + return true;
11.315 +}
11.316 +
11.317 +Address
11.318 +L2RoutingNetDevice::GetMulticast (Ipv6Address addr) const
11.319 +{
11.320 + NS_LOG_FUNCTION (this << addr);
11.321 + return Mac48Address::GetMulticast (addr);
11.322 +}
11.323 +//L2RouitingSpecific methods:
11.324 +
11.325 +bool
11.326 +L2RoutingNetDevice::AttachProtocol(Ptr<L2RoutingProtocol> protocol)
11.327 +{
11.328 + m_requestRoute = MakeCallback(&L2RoutingProtocol::RequestRoute, protocol);
11.329 + m_myResponse = MakeCallback(&L2RoutingNetDevice::ProtocolResponse, this);
11.330 + protocol->SetIfIndex(m_ifIndex);
11.331 + return protocol->AttachPorts(m_ports);
11.332 +}
11.333 +
11.334 +void
11.335 +L2RoutingNetDevice::ProtocolResponse(
11.336 + bool success,
11.337 + Ptr<Packet> packet,
11.338 + Mac48Address src,
11.339 + Mac48Address dst,
11.340 + uint16_t protocol,
11.341 + uint32_t outPort
11.342 + )
11.343 +{
11.344 + if(!success)
11.345 + {
11.346 + NS_LOG_UNCOND("Resolve failed");
11.347 + //TODO: SendError callback
11.348 + return;
11.349 + }
11.350 + //just do sendFrom!
11.351 + if(outPort!=0xffffffff)
11.352 + GetPort(outPort)->SendFrom(packet, src, dst, protocol);
11.353 + else
11.354 + for(std::vector<Ptr<NetDevice> >::iterator i = m_ports.begin(); i!= m_ports.end(); i++)
11.355 + (*i) -> SendFrom(packet, src, dst, protocol);
11.356 +}
11.357 +
11.358 +} // namespace ns3
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/src/devices/l2-routing/l2-routing-main/l2-routing-net-device.h Sat Feb 28 14:21:05 2009 +0300
12.3 @@ -0,0 +1,167 @@
12.4 +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
12.5 +/*
12.6 + * Copyright (c) 2008,2009 IITP RAS
12.7 + *
12.8 + * This program is free software; you can redistribute it and/or modify
12.9 + * it under the terms of the GNU General Public License version 2 as
12.10 + * published by the Free Software Foundation;
12.11 + *
12.12 + * This program is distributed in the hope that it will be useful,
12.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12.15 + * GNU General Public License for more details.
12.16 + *
12.17 + * You should have received a copy of the GNU General Public License
12.18 + * along with this program; if not, write to the Free Software
12.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
12.20 + *
12.21 + * Author: Kirill Andreev <andreev@iitp.ru>
12.22 + */
12.23 +
12.24 +
12.25 +#ifndef L2ROUTING_NET_DEVICE_H
12.26 +#define L2ROUTING_NET_DEVICE_H
12.27 +
12.28 +#include "ns3/net-device.h"
12.29 +#include "ns3/mac48-address.h"
12.30 +#include "ns3/nstime.h"
12.31 +#include "ns3/bridge-net-device.h"
12.32 +#include "ns3/bridge-channel.h"
12.33 +#include "ns3/l2-routing-protocol.h"
12.34 +
12.35 +namespace ns3 {
12.36 + class Node;
12.37 + /**
12.38 + * \ingroup devices
12.39 + * \defgroup L2RoutingNetDevice L2routingNetDevice
12.40 + */
12.41 + /**
12.42 + * \ingroup L2RoutingNetDevice
12.43 + * \brief a virtual net device that may forward packets
12.44 + * between real network devices using routing protocols of
12.45 + * MAC-layer
12.46 + * \details This is a virtual netdevice, which aggreagates
12.47 + * real netdevices and uses interface of L2RoutingProtocol to
12.48 + * forward packets
12.49 + * \attention The idea of L2RoutingNetDevice is similar to
12.50 + * BridgeNetDevice, but the packets, which going through
12.51 + * L2RoutingNetDevice may be changed (because routing protocol
12.52 + * may require its own headers or tags).
12.53 + */
12.54 + class L2RoutingNetDevice : public NetDevice
12.55 + {
12.56 + public:
12.57 + static TypeId GetTypeId (void);
12.58 + L2RoutingNetDevice ();
12.59 + virtual ~L2RoutingNetDevice ();
12.60 + /**
12.61 + * \brief Attaches a 'port' to a virtual
12.62 + * L2RoutingNetDevice, and this port is handled
12.63 + * by L2RoutingProtocol.
12.64 + * \attention Like in a bridge,
12.65 + * L2RoutingNetDevice's ports must not have IP
12.66 + * addresses, and only L2RoutingNetDevice
12.67 + * itself may have an IP address.
12.68 + *
12.69 + * \attention L2RoutingNetDevice may be a port
12.70 + * of BridgeNetDevice.
12.71 + */
12.72 + void AddPort (Ptr<NetDevice> port);
12.73 + /**
12.74 + * \returns number of ports attached to
12.75 + * L2RoutingNetDevice
12.76 + */
12.77 + uint32_t GetNPorts (void) const;
12.78 + /**
12.79 + * \returns a pointer to netdevice
12.80 + * \param n is device ID to be returned
12.81 + */
12.82 + Ptr<NetDevice> GetPort (uint32_t n) const;
12.83 + //inherited from netdevice:
12.84 + virtual void SetName(const std::string name);
12.85 + virtual std::string GetName(void) const;
12.86 + virtual void SetIfIndex(const uint32_t index);
12.87 + virtual uint32_t GetIfIndex(void) const;
12.88 + virtual Ptr<Channel> GetChannel (void) const;
12.89 + virtual Address GetAddress (void) const;
12.90 + virtual bool SetMtu (const uint16_t mtu);
12.91 + virtual uint16_t GetMtu (void) const;
12.92 + virtual bool IsLinkUp (void) const;
12.93 + virtual void SetLinkChangeCallback (Callback<void> callback);
12.94 + virtual bool IsBroadcast (void) const;
12.95 + virtual Address GetBroadcast (void) const;
12.96 + virtual bool IsMulticast (void) const;
12.97 + virtual Address GetMulticast (Ipv4Address multicastGroup) const;
12.98 + virtual bool IsPointToPoint (void) const;
12.99 + virtual bool IsBridge (void) const;
12.100 + virtual bool Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber);
12.101 + virtual bool SendFrom (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber);
12.102 + virtual Ptr<Node> GetNode (void) const;
12.103 + virtual void SetNode (Ptr<Node> node);
12.104 + virtual bool NeedsArp (void) const;
12.105 + virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
12.106 + virtual void SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb);
12.107 + virtual bool SupportsSendFrom () const;
12.108 + virtual Address GetMulticast (Ipv6Address addr) const;
12.109 + virtual void DoDispose (void);
12.110 + /**
12.111 + * \brief Attaches protocol to a given virtual
12.112 + * device
12.113 + * \returns true if success
12.114 + */
12.115 + virtual bool AttachProtocol(Ptr<L2RoutingProtocol> protocol);
12.116 + protected:
12.117 + /**
12.118 + * \brief This is similar to BridgeNetDevice
12.119 + * method
12.120 + */
12.121 + void ReceiveFromDevice (Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol,
12.122 + Address const &source, Address const &destination, PacketType packetType);
12.123 + /**
12.124 + * \brief This is similar to BridgeNetDevice
12.125 + * method
12.126 + */
12.127 + void Forward (Ptr<NetDevice> incomingPort, Ptr<Packet> packet,
12.128 + uint16_t protocol, const Mac48Address src, const Mac48Address dst);
12.129 + /**
12.130 + * \brief This is a function, which should be
12.131 + * passed to L2RoutingProtocol as response
12.132 + * callback (see L2RoutingProtocol).
12.133 + */
12.134 + virtual void ProtocolResponse(
12.135 + bool success,
12.136 + Ptr<Packet>,
12.137 + Mac48Address src,
12.138 + Mac48Address dst,
12.139 + uint16_t protocol,
12.140 + uint32_t outPort
12.141 + );
12.142 + private:
12.143 + NetDevice::ReceiveCallback
12.144 + m_rxCallback;
12.145 + NetDevice::PromiscReceiveCallback
12.146 + m_promiscRxCallback;
12.147 + Mac48Address m_address;
12.148 + Ptr<Node> m_node;
12.149 + std::string m_name;
12.150 + std::vector< Ptr<NetDevice> >
12.151 + m_ports;
12.152 + uint32_t m_ifIndex;
12.153 + uint16_t m_mtu;
12.154 + Ptr<BridgeChannel>
12.155 + m_channel;
12.156 + Callback<
12.157 + bool,
12.158 + uint32_t,
12.159 + Mac48Address,
12.160 + Mac48Address,
12.161 + Ptr<Packet>,
12.162 + uint16_t,
12.163 + L2RoutingProtocol::RouteReplyCallback>
12.164 + m_requestRoute;
12.165 + //What we give to L2Routing
12.166 + L2RoutingProtocol::RouteReplyCallback
12.167 + m_myResponse;
12.168 + };
12.169 +} //namespace ns3
12.170 +#endif
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/src/devices/l2-routing/l2-routing-main/waf Sat Feb 28 14:21:05 2009 +0300
13.3 @@ -0,0 +1,1 @@
13.4 +exec "`dirname "$0"`"/../../../../waf "$@"
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
14.2 +++ b/src/devices/l2-routing/l2-routing-main/wscript Sat Feb 28 14:21:05 2009 +0300
14.3 @@ -0,0 +1,12 @@
14.4 +## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
14.5 +
14.6 +def build(bld):
14.7 + obj = bld.create_ns3_module('l2-routing-main', ['node', 'bridge'])
14.8 + obj.source = [
14.9 + 'l2-routing-net-device.cc',
14.10 + ]
14.11 + headers = bld.new_task_gen('ns3header')
14.12 + headers.module = 'l2-routing-main'
14.13 + headers.source = [
14.14 + 'l2-routing-net-device.h',
14.15 + ]
15.1 --- a/src/devices/wifi/dca-txop.h Wed Feb 25 12:27:00 2009 -0500
15.2 +++ b/src/devices/wifi/dca-txop.h Sat Feb 28 14:21:05 2009 +0300
15.3 @@ -161,6 +161,7 @@
15.4 bool m_accessOngoing;
15.5 Ptr<const Packet> m_currentPacket;
15.6 WifiMacHeader m_currentHdr;
15.7 + uint8_t m_currentRetry;
15.8 uint8_t m_fragmentNumber;
15.9 };
15.10
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
16.2 +++ b/src/devices/wifi/dot11s-codes.h Sat Feb 28 14:21:05 2009 +0300
16.3 @@ -0,0 +1,89 @@
16.4 +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
16.5 +/*
16.6 + * Copyright (c) 2008,2009 IITP RAS
16.7 + *
16.8 + * This program is free software; you can redistribute it and/or modify
16.9 + * it under the terms of the GNU General Public License version 2 as
16.10 + * published by the Free Software Foundation;
16.11 + *
16.12 + * This program is distributed in the hope that it will be useful,
16.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
16.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16.15 + * GNU General Public License for more details.
16.16 + *
16.17 + * You should have received a copy of the GNU General Public License
16.18 + * along with this program; if not, write to the Free Software
16.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16.20 + *
16.21 + * Authors: Aleksey Kovalenko <kovalenko@iitp.ru>
16.22 + * Kirill Andreev <andreev@iitp.ru>
16.23 + */
16.24 +
16.25 +
16.26 +#ifndef DOT11S_CODES_H
16.27 +#define DOT11S_CODES_H
16.28 +
16.29 +namespace ns3 {
16.30 +
16.31 +enum dot11sElementID {
16.32 + MESH_CONFIGURATION = 18,
16.33 + MESH_ID,
16.34 + LINK_METRIC_REPORT,
16.35 + CONGESTION_NOTIFICATION,
16.36 + PEER_LINK_MANAGEMENT,
16.37 + MESH_CHANNEL_SWITCH_ANNOUNCEMENT,
16.38 + MESH_TIM,
16.39 + AWAKE_WINDOW,
16.40 + SYNCHRONIZATION_PROTOCOL,
16.41 + BEACON_TIMING,
16.42 + MDAOP_SETUP_REQUEST,
16.43 + MDAOP_SETUP_REPLY,
16.44 + MDAOP_ADVERTISEMENT,
16.45 + MDAOP_SET_TEARDOWN,
16.46 + CONNECTIVITY_REPORT,
16.47 + PORTAL_ANNOUNCEMENT,
16.48 + ROOT_ANNOUCEMENT,
16.49 + PATH_REQUEST,
16.50 + PATH_REPLY,
16.51 + PATH_ERROR,
16.52 + PROXY_UPDATE,
16.53 + PROXY_UPDATE_CONFIRMATION,
16.54 + MSCIE,
16.55 + MSAIE,
16.56 +};
16.57 +
16.58 +enum dot11sReasonCode {
16.59 + PEER_LINK_CANCELLED,
16.60 + MESH_MAX_PEERS,
16.61 + MESH_CAPABILITY_POLICY_VIOLATION,
16.62 + MESH_CLOSE_RCVD,
16.63 + MESH_MAX_RETRIES,
16.64 + MESH_CONFIRM_TIMEOUT,
16.65 + MESH_SECURITY_ROLE_NEGOTIATION_DIFFERS,
16.66 + MESH_SECURITY_AUTHENTICATION_IMPOSSIBLE,
16.67 + MESH_SECURITY_FAILED_VERIFICATION,
16.68 + MESH_INVALID_GTK,
16.69 + MESH_MISMATCH_GTK,
16.70 + MESH_INCONSISTENT_PARAMETERS,
16.71 + MESH_CONFIGURATION_POLICY_VIOLATION,
16.72 + DOT11S_REASON_RESERVED,
16.73 +};
16.74 +
16.75 +enum dot11sStatusCode {
16.76 + PEAR_LINK_ESTABLISHED,
16.77 + PEAR_LINK_CLOSED,
16.78 + NO_LISTED_KEY_HOLDER,
16.79 + MESH_KEY_HANDSHAKE_MALFORMED,
16.80 + PEAR_LINK_MAX_RETRIES,
16.81 + PEAR_LINK_NO_PMK,
16.82 + PEAR_LINK_ALT_PMK,
16.83 + PEAR_LINK_NO_AKM,
16.84 + PEAR_LINK_ALT_AKM,
16.85 + PEAR_LINK_NO_KDF,
16.86 + PEAR_LINK_SA_ESTABLISHED,
16.87 + AUTHENTICATION_REJECTED_CLOGGING,
16.88 + DOT11S_STATUS_RESERVED,
16.89 +};
16.90 +
16.91 +}
16.92 +#endif
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
17.2 +++ b/src/devices/wifi/dot11s-parameters.cc Sat Feb 28 14:21:05 2009 +0300
17.3 @@ -0,0 +1,43 @@
17.4 +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
17.5 +/*
17.6 + * Copyright (c) 2008,2009 IITP RAS
17.7 + *
17.8 + * This program is free software; you can redistribute it and/or modify
17.9 + * it under the terms of the GNU General Public License version 2 as
17.10 + * published by the Free Software Foundation;
17.11 + *
17.12 + * This program is distributed in the hope that it will be useful,
17.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
17.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17.15 + * GNU General Public License for more details.
17.16 + *
17.17 + * You should have received a copy of the GNU General Public License
17.18 + * along with this program; if not, write to the Free Software
17.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17.20 + *
17.21 + * Authors: Aleksey Kovalenko <kovalenko@iitp.ru>
17.22 + * Kirill Andreev <andreev@iitp.ru>
17.23 + */
17.24 +
17.25 +
17.26 +#include "ns3/dot11s-parameters.h"
17.27 +
17.28 +namespace ns3
17.29 +{
17.30 +
17.31 +uint8_t dot11sParameters::dot11MeshMaxRetries = 4;
17.32 +Time dot11sParameters::dot11MeshRetryTimeout = TU_TO_TIME(40);
17.33 +Time dot11sParameters::dot11MeshHoldingTimeout = TU_TO_TIME(40);
17.34 +Time dot11sParameters::dot11MeshConfirmTimeout = TU_TO_TIME(40);
17.35 +
17.36 +
17.37 +uint8_t dot11sParameters::dot11MeshHWMPmaxPREQretries = 3;
17.38 +Time dot11sParameters::dot11MeshHWMPnetDiameterTraversalTime = TU_TO_TIME(10);
17.39 +Time dot11sParameters::dot11MeshHWMPpreqMinInterval = TU_TO_TIME(100);
17.40 +Time dot11sParameters::dot11MeshHWMPperrMinInterval = TU_TO_TIME(100);
17.41 +Time dot11sParameters::dot11MeshHWMPactiveRootTimeout = TU_TO_TIME(5000);
17.42 +Time dot11sParameters::dot11MeshHWMPactivePathTimeout = TU_TO_TIME(5000);
17.43 +Time dot11sParameters::dot11MeshHWMPpathToRootInterval = TU_TO_TIME(5000);
17.44 +Time dot11sParameters::dot11MeshHWMPrannInterval = TU_TO_TIME(1000);
17.45 +
17.46 +}
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
18.2 +++ b/src/devices/wifi/dot11s-parameters.h Sat Feb 28 14:21:05 2009 +0300
18.3 @@ -0,0 +1,53 @@
18.4 +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
18.5 +/*
18.6 + * Copyright (c) 2008,2009 IITP RAS
18.7 + *
18.8 + * This program is free software; you can redistribute it and/or modify
18.9 + * it under the terms of the GNU General Public License version 2 as
18.10 + * published by the Free Software Foundation;
18.11 + *
18.12 + * This program is distributed in the hope that it will be useful,
18.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
18.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18.15 + * GNU General Public License for more details.
18.16 + *
18.17 + * You should have received a copy of the GNU General Public License
18.18 + * along with this program; if not, write to the Free Software
18.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18.20 + *
18.21 + * Authors: Aleksey Kovalenko <kovalenko@iitp.ru>
18.22 + * Kirill Andreev <andreev@iitp.ru>
18.23 + */
18.24 +
18.25 +
18.26 +#ifndef DOT11S_PARAMETERS_H
18.27 +#define DOT11S_PARAMETERS_H
18.28 +#include "ns3/uinteger.h"
18.29 +#include "ns3/nstime.h"
18.30 +
18.31 +namespace ns3
18.32 +{
18.33 +
18.34 +#define TU_TO_TIME(x) MicroSeconds(x*1024)
18.35 +#define TIME_TO_TU(x) x.GetMicroSeconds()/1024
18.36 +
18.37 +struct dot11sParameters
18.38 +{
18.39 + /** Peer Link */
18.40 + static uint8_t dot11MeshMaxRetries;
18.41 + static Time dot11MeshRetryTimeout;
18.42 + static Time dot11MeshHoldingTimeout;
18.43 + static Time dot11MeshConfirmTimeout;
18.44 + /** HWMP */
18.45 + static uint8_t dot11MeshHWMPmaxPREQretries;
18.46 + static Time dot11MeshHWMPnetDiameterTraversalTime;
18.47 + static Time dot11MeshHWMPpreqMinInterval;
18.48 + static Time dot11MeshHWMPperrMinInterval;
18.49 + static Time dot11MeshHWMPactiveRootTimeout;
18.50 + static Time dot11MeshHWMPactivePathTimeout;
18.51 + static Time dot11MeshHWMPpathToRootInterval;
18.52 + static Time dot11MeshHWMPrannInterval;
18.53 +};
18.54 +
18.55 +};
18.56 +#endif
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
19.2 +++ b/src/devices/wifi/dot11s-peer-management-element.cc Sat Feb 28 14:21:05 2009 +0300
19.3 @@ -0,0 +1,134 @@
19.4 +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
19.5 +/*
19.6 + * Copyright (c) 2008,2009 IITP RAS
19.7 + *
19.8 + * This program is free software; you can redistribute it and/or modify
19.9 + * it under the terms of the GNU General Public License version 2 as
19.10 + * published by the Free Software Foundation;
19.11 + *
19.12 + * This program is distributed in the hope that it will be useful,
19.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
19.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19.15 + * GNU General Public License for more details.
19.16 + *
19.17 + * You should have received a copy of the GNU General Public License
19.18 + * along with this program; if not, write to the Free Software
19.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19.20 + *
19.21 + * Authors: Kirill Andreev <andreev@iitp.ru>
19.22 + * Aleksey Kovalenko <kovalenko@iitp.ru>
19.23 + */
19.24 +
19.25 +
19.26 +#include "dot11s-peer-management-element.h"
19.27 +#include "ns3/assert.h"
19.28 +
19.29 +
19.30 +//NS_LOG_COMPONENT_DEFINE ("MeshPeerLinkManagementelement");
19.31 +
19.32 +namespace ns3 {
19.33 +
19.34 +PeerLinkManagementElement::PeerLinkManagementElement ():
19.35 + m_length(0),
19.36 + m_subtype(PEER_OPEN),
19.37 + m_localLinkId(0),
19.38 + m_peerLinkId(0),
19.39 + m_reasonCode(DOT11S_REASON_RESERVED)
19.40 +{}
19.41 +
19.42 +
19.43 +void
19.44 +PeerLinkManagementElement::SetPeerOpen(uint16_t localLinkId)
19.45 +{
19.46 + m_length = 3;
19.47 + m_subtype=PEER_OPEN;
19.48 + m_localLinkId = localLinkId;
19.49 +}
19.50 +void
19.51 +PeerLinkManagementElement::SetPeerClose(uint16_t localLinkId, uint16_t peerLinkId, dot11sReasonCode reasonCode)
19.52 +{
19.53 + m_length = 7;
19.54 + m_subtype=PEER_CLOSE;
19.55 + m_localLinkId = localLinkId;
19.56 + m_peerLinkId = peerLinkId;
19.57 + m_reasonCode = reasonCode;
19.58 +}
19.59 +
19.60 +void
19.61 +PeerLinkManagementElement::SetPeerConfirm(uint16_t localLinkId, uint16_t peerLinkId)
19.62 +{
19.63 + m_length = 5;
19.64 + m_subtype=PEER_CONFIRM;
19.65 + m_localLinkId = localLinkId;
19.66 + m_peerLinkId = peerLinkId;
19.67 +}
19.68 +
19.69 +dot11sReasonCode
19.70 +PeerLinkManagementElement::GetReasonCode() const
19.71 +{
19.72 + return m_reasonCode;
19.73 +}
19.74 +
19.75 +uint16_t
19.76 +PeerLinkManagementElement::GetLocalLinkId() const
19.77 +{
19.78 + return m_localLinkId;
19.79 +}
19.80 +
19.81 +uint16_t
19.82 +PeerLinkManagementElement::GetPeerLinkId() const
19.83 +{
19.84 + return m_peerLinkId;
19.85 +}
19.86 +
19.87 +uint32_t
19.88 +PeerLinkManagementElement::GetSerializedSize (void) const
19.89 +{
19.90 + return m_length+2;
19.91 +}
19.92 +
19.93 +bool
19.94 +PeerLinkManagementElement::SubtypeIsOpen() const
19.95 +{
19.96 + return (m_subtype == PEER_OPEN);
19.97 +}
19.98 +bool
19.99 +PeerLinkManagementElement::SubtypeIsClose() const
19.100 +{
19.101 + return (m_subtype == PEER_CLOSE);
19.102 +}
19.103 +bool
19.104 +PeerLinkManagementElement::SubtypeIsConfirm() const
19.105 +{
19.106 + return (m_subtype == PEER_CONFIRM);
19.107 +}
19.108 +
19.109 +Buffer::Iterator
19.110 +PeerLinkManagementElement::Serialize (Buffer::Iterator i) const
19.111 +{
19.112 + i.WriteU8(PEER_LINK_MANAGEMENT);
19.113 + i.WriteU8(m_length);
19.114 + i.WriteU8(m_subtype);
19.115 + i.WriteHtonU16(m_localLinkId);
19.116 + if(m_length > 3)
19.117 + i.WriteHtonU16(m_peerLinkId);
19.118 + if(m_length > 5)
19.119 + i.WriteHtonU16(m_reasonCode);
19.120 + return i;
19.121 +}
19.122 +Buffer::Iterator
19.123 +PeerLinkManagementElement::Deserialize (Buffer::Iterator i)
19.124 +{
19.125 + dot11sElementID ElementId;
19.126 + ElementId = (dot11sElementID)i.ReadU8();
19.127 + NS_ASSERT(ElementId == PEER_LINK_MANAGEMENT);
19.128 + m_length = i.ReadU8();
19.129 + m_subtype = i.ReadU8();
19.130 + m_localLinkId = i.ReadNtohU16();
19.131 + if(m_length > 3)
19.132 + m_peerLinkId = i.ReadNtohU16();
19.133 + if(m_length > 5)
19.134 + m_reasonCode = (dot11sReasonCode)i.ReadNtohU16();
19.135 + return i;
19.136 +}
19.137 +} //namespace NS3
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
20.2 +++ b/src/devices/wifi/dot11s-peer-management-element.h Sat Feb 28 14:21:05 2009 +0300
20.3 @@ -0,0 +1,66 @@
20.4 +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
20.5 +/*
20.6 + * Copyright (c) 2008,2009 IITP RAS
20.7 + *
20.8 + * This program is free software; you can redistribute it and/or modify
20.9 + * it under the terms of the GNU General Public License version 2 as
20.10 + * published by the Free Software Foundation;
20.11 + *
20.12 + * This program is distributed in the hope that it will be useful,
20.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
20.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20.15 + * GNU General Public License for more details.
20.16 + *
20.17 + * You should have received a copy of the GNU General Public License
20.18 + * along with this program; if not, write to the Free Software
20.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20.20 + *
20.21 + * Authors: Kirill Andreev <andreev@iitp.ru>
20.22 + * Aleksey Kovalenko <kovalenko@iitp.ru>
20.23 + */
20.24 +
20.25 +
20.26 +#ifndef MESH_PEER_MAN_ELEMENT
20.27 +#define MESH_PEER_MAN_ELEMENT
20.28 +
20.29 +#include <stdint.h>
20.30 +#include "ns3/buffer.h"
20.31 +#include "dot11s-codes.h"
20.32 +
20.33 +namespace ns3
20.34 +{
20.35 +class PeerLinkManagementElement
20.36 +{
20.37 + public:
20.38 + enum Subtype {
20.39 + PEER_OPEN = 0,
20.40 + PEER_CLOSE = 1,
20.41 + PEER_CONFIRM = 2,
20.42 + };
20.43 + public:
20.44 + PeerLinkManagementElement ();
20.45 +
20.46 + void SetPeerOpen(uint16_t localLinkId);
20.47 + void SetPeerClose(uint16_t localLinkID, uint16_t peerLinkId, dot11sReasonCode reasonCode);
20.48 + void SetPeerConfirm(uint16_t localLinkID, uint16_t peerLinkId);
20.49 +
20.50 + dot11sReasonCode GetReasonCode() const;
20.51 + uint16_t GetLocalLinkId() const;
20.52 + uint16_t GetPeerLinkId() const;
20.53 + bool SubtypeIsOpen() const;
20.54 + bool SubtypeIsClose() const;
20.55 + bool SubtypeIsConfirm() const ;
20.56 +
20.57 + uint32_t GetSerializedSize (void) const;
20.58 + Buffer::Iterator Serialize (Buffer::Iterator i) const;
20.59 + Buffer::Iterator Deserialize (Buffer::Iterator i);
20.60 + private:
20.61 + uint8_t m_length;
20.62 + uint8_t m_subtype;
20.63 + uint16_t m_localLinkId; //always is present
20.64 + uint16_t m_peerLinkId; //only in confirm and may be present in close frame
20.65 + dot11sReasonCode m_reasonCode; //only in close frame
20.66 +};
20.67 +} //namespace NS3
20.68 +#endif
20.69 +
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
21.2 +++ b/src/devices/wifi/mesh-configuration-element.cc Sat Feb 28 14:21:05 2009 +0300
21.3 @@ -0,0 +1,178 @@
21.4 +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
21.5 +/*
21.6 + * Copyright (c) 2008,2009 IITP RAS
21.7 + *
21.8 + * This program is free software; you can redistribute it and/or modify
21.9 + * it under the terms of the GNU General Public License version 2 as
21.10 + * published by the Free Software Foundation;
21.11 + *
21.12 + * This program is distributed in the hope that it will be useful,
21.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
21.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21.15 + * GNU General Public License for more details.
21.16 + *
21.17 + * You should have received a copy of the GNU General Public License
21.18 + * along with this program; if not, write to the Free Software
21.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21.20 + *
21.21 + * Authors: Kirill Andreev <andreev@iitp.ru>
21.22 + * Aleksey Kovalenko <kovalenko@iitp.ru>
21.23 + */
21.24 +
21.25 +
21.26 +#include "mesh-configuration-element.h"
21.27 +#include "ns3/assert.h"
21.28 +#include "dot11s-codes.h"
21.29 +
21.30 +//NS_LOG_COMPONENT_DEFINE ("MeshConfigurationElement");
21.31 +
21.32 +namespace ns3 {
21.33 +
21.34 +dot11sMeshCapability::dot11sMeshCapability():
21.35 + acceptPeerLinks(true),
21.36 + MDAEnabled(false),
21.37 + forwarding(true),
21.38 + beaconTimingReport(false),
21.39 + TBTTAdjustment(false),
21.40 + powerSaveLevel(false)
21.41 +{}
21.42 +
21.43 +uint32_t dot11sMeshCapability::GetSerializedSize (void) const
21.44 +{
21.45 + return 2;
21.46 +}
21.47 +
21.48 +Buffer::Iterator dot11sMeshCapability::Serialize (Buffer::Iterator i) const
21.49 +{
21.50 + uint16_t result = 0;
21.51 + if(acceptPeerLinks)
21.52 + result |= 1 << 0;
21.53 + if(MDAEnabled)
21.54 + result |= 1 << 1;
21.55 + if(forwarding)
21.56 + result |= 1 << 2;
21.57 + if(beaconTimingReport)
21.58 + result |= 1 << 3;
21.59 + if(TBTTAdjustment)
21.60 + result |= 1 << 4;
21.61 + if(powerSaveLevel)
21.62 + result |= 1 << 5;
21.63 + i.WriteHtonU16(result);
21.64 + return i;
21.65 +}
21.66 +
21.67 +Buffer::Iterator dot11sMeshCapability::Deserialize (Buffer::Iterator i)
21.68 +{
21.69 + uint16_t cap = i.ReadNtohU16();
21.70 + acceptPeerLinks = Is(cap,0);
21.71 + MDAEnabled = Is(cap,1);
21.72 + forwarding = Is(cap,2);
21.73 + beaconTimingReport = Is(cap,3);
21.74 + TBTTAdjustment = Is(cap,4);
21.75 + powerSaveLevel = Is(cap,5);
21.76 + return i;
21.77 +}
21.78 +
21.79 +bool dot11sMeshCapability::Is(uint16_t cap, uint8_t n) const
21.80 +{
21.81 + uint16_t mask = 1<<n;
21.82 + return (cap & mask) == mask;
21.83 +}
21.84 +
21.85 +MeshConfigurationElement::MeshConfigurationElement ():
21.86 + m_APSId(PROTOCOL_HWMP),
21.87 + m_APSMId(METRIC_AIRTIME),
21.88 + m_CCMId(CONGESTION_DEFAULT),
21.89 + m_CP(CHANNEL_PRECEDENCE_OFF)
21.90 +{}
21.91 +
21.92 +uint32_t
21.93 +MeshConfigurationElement::GetSerializedSize (void) const
21.94 +{
21.95 + return 1 // ID
21.96 + + 1 // Length
21.97 + + 1 // Version
21.98 + + 4 // APSPId
21.99 + + 4 // APSMId
21.100 + + 4 // CCMId
21.101 + + 4 // CP
21.102 + + m_meshCap.GetSerializedSize()
21.103 + ;
21.104 +}
21.105 +
21.106 +Buffer::Iterator
21.107 +MeshConfigurationElement::Serialize (Buffer::Iterator i) const
21.108 +{
21.109 +
21.110 + i.WriteU8 (MESH_CONFIGURATION);
21.111 + i.WriteU8 (GetSerializedSize()); // Length
21.112 + i.WriteU8 (1); //Version
21.113 + // Active Path Selection Protocol ID:
21.114 + i.WriteHtonU32(m_APSId);
21.115 + // Active Path Metric ID:
21.116 + i.WriteHtonU32(m_APSMId);
21.117 + // Congestion Control Mode ID:
21.118 + i.WriteU32(m_CCMId);
21.119 + // Channel Precedence:
21.120 + i.WriteU32(m_CP);
21.121 + i = m_meshCap.Serialize(i);
21.122 + return i;
21.123 +}
21.124 +
21.125 +Buffer::Iterator
21.126 +MeshConfigurationElement::Deserialize (Buffer::Iterator i)
21.127 +{
21.128 +
21.129 + uint8_t elementId;
21.130 + uint8_t size;
21.131 + uint8_t version;
21.132 + elementId = i.ReadU8 ();
21.133 +
21.134 + NS_ASSERT (elementId == MESH_CONFIGURATION);
21.135 +
21.136 + size = i.ReadU8 ();
21.137 + version = i.ReadU8();
21.138 + // Active Path Selection Protocol ID:
21.139 + m_APSId = (dot11sPathSelectionProtocol)i.ReadNtohU32();
21.140 + // Active Path Metric ID:
21.141 + m_APSMId = (dot11sPathSelectionMetric)i.ReadNtohU32();
21.142 + // Congestion Control Mode ID:
21.143 + m_CCMId = (dot11sCongestionControlMode)i.ReadU32();
21.144 + // Channel Precedence:
21.145 + m_CP = (dot11sChannelPrecedence)i.ReadU32();
21.146 + i = m_meshCap.Deserialize(i);
21.147 + return i;
21.148 +
21.149 +
21.150 +}
21.151 +
21.152 +void
21.153 +MeshConfigurationElement::SetRouting(dot11sPathSelectionProtocol routingId)
21.154 +{
21.155 + m_APSId = routingId ;
21.156 +}
21.157 +
21.158 +void
21.159 +MeshConfigurationElement::SetMetric(dot11sPathSelectionMetric metricId)
21.160 +{
21.161 + m_APSMId = metricId;
21.162 +}
21.163 +
21.164 +bool
21.165 +MeshConfigurationElement::IsHWMP(void)
21.166 +{
21.167 + return (m_APSId == PROTOCOL_HWMP);
21.168 +}
21.169 +
21.170 +bool
21.171 +MeshConfigurationElement::IsAirtime(void)
21.172 +{
21.173 + return (m_APSMId == METRIC_AIRTIME);
21.174 +}
21.175 +
21.176 +dot11sMeshCapability const& MeshConfigurationElement::MeshCapability()
21.177 +{
21.178 + return m_meshCap;
21.179 +}
21.180 +
21.181 +} //namespace NS3
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
22.2 +++ b/src/devices/wifi/mesh-configuration-element.h Sat Feb 28 14:21:05 2009 +0300
22.3 @@ -0,0 +1,101 @@
22.4 +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
22.5 +/*
22.6 + * Copyright (c) 2008,2009 IITP RAS
22.7 + *
22.8 + * This program is free software; you can redistribute it and/or modify
22.9 + * it under the terms of the GNU General Public License version 2 as
22.10 + * published by the Free Software Foundation;
22.11 + *
22.12 + * This program is distributed in the hope that it will be useful,
22.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
22.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22.15 + * GNU General Public License for more details.
22.16 + *
22.17 + * You should have received a copy of the GNU General Public License
22.18 + * along with this program; if not, write to the Free Software
22.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22.20 + *
22.21 + * Authors: Kirill Andreev <andreev@iitp.ru>
22.22 + * Aleksey Kovalenko <kovalenko@iitp.ru>
22.23 + */
22.24 +
22.25 +
22.26 +#ifndef MESH_CONFIGURATION_H
22.27 +#define MESH_CONFIGURATION_H
22.28 +
22.29 +#include <stdint.h>
22.30 +#include "ns3/buffer.h"
22.31 +
22.32 +namespace ns3
22.33 +{
22.34 +
22.35 +enum dot11sPathSelectionProtocol
22.36 +{
22.37 + PROTOCOL_HWMP = 0x000fac00,
22.38 + PROTOCOL_NULL = 0x000facff,
22.39 +};
22.40 +
22.41 +enum dot11sPathSelectionMetric
22.42 +{
22.43 + METRIC_AIRTIME = 0x000fac00,
22.44 + METRIC_NULL = 0x000facff,
22.45 +};
22.46 +
22.47 +enum dot11sCongestionControlMode
22.48 +{
22.49 + CONGESTION_DEFAULT = 0x000fac00,
22.50 + CONGESTION_NULL = 0x000facff,
22.51 +};
22.52 +
22.53 +enum dot11sChannelPrecedence
22.54 +{
22.55 + CHANNEL_PRECEDENCE_OFF = 0x000fac00,
22.56 +};
22.57 +
22.58 +
22.59 +class dot11sMeshCapability
22.60 +{
22.61 + public:
22.62 + dot11sMeshCapability();
22.63 + uint32_t GetSerializedSize (void) const;
22.64 + Buffer::Iterator Serialize (Buffer::Iterator i) const;
22.65 + Buffer::Iterator Deserialize (Buffer::Iterator i);
22.66 + bool acceptPeerLinks;
22.67 + bool MDAEnabled;
22.68 + bool forwarding;
22.69 + bool beaconTimingReport;
22.70 + bool TBTTAdjustment;
22.71 + bool powerSaveLevel;
22.72 + private:
22.73 + bool Is(uint16_t cap,uint8_t n) const;
22.74 +};
22.75 +
22.76 +class MeshConfigurationElement
22.77 +{
22.78 + public:
22.79 + MeshConfigurationElement();
22.80 + void SetRouting(dot11sPathSelectionProtocol routingId);
22.81 + void SetMetric(dot11sPathSelectionMetric metricId);
22.82 + bool IsHWMP(void);
22.83 + bool IsAirtime(void);
22.84 +
22.85 + dot11sMeshCapability const& MeshCapability();
22.86 +
22.87 + uint32_t GetSerializedSize (void) const;
22.88 + Buffer::Iterator Serialize (Buffer::Iterator i) const;
22.89 + Buffer::Iterator Deserialize (Buffer::Iterator i);
22.90 + // TODO: Release and fill other fields in configuration
22.91 + // element
22.92 + private:
22.93 + /** Active Path Selection Protocol ID */
22.94 + dot11sPathSelectionProtocol m_APSId;
22.95 + /** Active Path Metric ID */
22.96 + dot11sPathSelectionMetric m_APSMId;
22.97 + /** Congestion Control Mode ID */
22.98 + dot11sCongestionControlMode m_CCMId;
22.99 + /* Channel Precedence */
22.100 + dot11sChannelPrecedence m_CP;
22.101 + dot11sMeshCapability m_meshCap;
22.102 +};
22.103 +} //name space NS3
22.104 +#endif
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
23.2 +++ b/src/devices/wifi/mesh-mgt-headers.cc Sat Feb 28 14:21:05 2009 +0300
23.3 @@ -0,0 +1,226 @@
23.4 +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
23.5 +/*
23.6 + * Copyright (c) 2008,2009 IITP RAS
23.7 + *
23.8 + * This program is free software; you can redistribute it and/or modify
23.9 + * it under the terms of the GNU General Public License version 2 as
23.10 + * published by the Free Software Foundation;
23.11 + *
23.12 + * This program is distributed in the hope that it will be useful,
23.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
23.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23.15 + * GNU General Public License for more details.
23.16 + *
23.17 + * You should have received a copy of the GNU General Public License
23.18 + * along with this program; if not, write to the Free Software
23.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23.20 + *
23.21 + * Authors: Kirill Andreev <andreev@iitp.ru>
23.22 + * Yana Podkosova <yanapdk@rambler.ru>
23.23 + * Aleksey Kovalenko <kovalenko@iitp.ru>
23.24 + */
23.25 +
23.26 +
23.27 +#include "mesh-mgt-headers.h"
23.28 +#include "ns3/address-utils.h"
23.29 +#include "ns3/simulator.h"
23.30 +#include "ns3/assert.h"
23.31 +
23.32 +namespace ns3
23.33 +{
23.34 +/***********************************************************
23.35 +* PeerLinkOpen frame:
23.36 +************************************************************/
23.37 +NS_OBJECT_ENSURE_REGISTERED (MeshMgtPeerLinkManFrame);
23.38 +
23.39 +MeshMgtPeerLinkManFrame::MeshMgtPeerLinkManFrame()
23.40 +{
23.41 +}
23.42 +
23.43 +void
23.44 +MeshMgtPeerLinkManFrame::SetAid(uint16_t aid)
23.45 +{
23.46 + Aid = aid;
23.47 +}
23.48 +
23.49 +void
23.50 +MeshMgtPeerLinkManFrame::SetSupportedRates(SupportedRates rates)
23.51 +{
23.52 + Rates = rates;
23.53 +}
23.54 +
23.55 +void
23.56 +MeshMgtPeerLinkManFrame::SetQosField(uint16_t qos)
23.57 +{
23.58 + QoS= qos;
23.59 +}
23.60 +
23.61 +void
23.62 +MeshMgtPeerLinkManFrame::SetMeshId(Ssid Id)
23.63 +{
23.64 + MeshId = Id;
23.65 +}
23.66 +
23.67 +void
23.68 +MeshMgtPeerLinkManFrame::SetMeshConfigurationElement(MeshConfigurationElement MeshConf)
23.69 +{
23.70 + MeshConfig = MeshConf;
23.71 +}
23.72 +
23.73 +void
23.74 +MeshMgtPeerLinkManFrame::SetPeerLinkManagementElement(PeerLinkManagementElement MeshPeerElement)
23.75 +{
23.76 + PeerLinkMan = MeshPeerElement;
23.77 +}
23.78 +
23.79 +uint16_t
23.80 +MeshMgtPeerLinkManFrame::GetAid()
23.81 +{
23.82 + return Aid;
23.83 +}
23.84 +
23.85 +SupportedRates
23.86 +MeshMgtPeerLinkManFrame::GetSupportedRates()
23.87 +{
23.88 + return Rates;
23.89 +}
23.90 +
23.91 +uint16_t
23.92 +MeshMgtPeerLinkManFrame::GetQosField()
23.93 +{
23.94 + return QoS;
23.95 +}
23.96 +
23.97 +Ssid
23.98 +MeshMgtPeerLinkManFrame::GetMeshId()
23.99 +{
23.100 + return MeshId;
23.101 +}
23.102 +
23.103 +MeshConfigurationElement
23.104 +MeshMgtPeerLinkManFrame::GetMeshConfigurationElement()
23.105 +{
23.106 + return MeshConfig;
23.107 +}
23.108 +
23.109 +PeerLinkManagementElement
23.110 +MeshMgtPeerLinkManFrame::GetPeerLinkManagementElement()
23.111 +{
23.112 + return PeerLinkMan;
23.113 +}
23.114 +
23.115 +TypeId
23.116 +MeshMgtPeerLinkManFrame::GetTypeId(void)
23.117 +{
23.118 + static TypeId tid =
23.119 + TypeId ("ns3::MeshMgtPeerLinkManFrame")
23.120 + .SetParent<Header> ()
23.121 + .AddConstructor<MeshMgtPeerLinkManFrame> ()
23.122 + ;
23.123 + return tid;
23.124 +}
23.125 +
23.126 +TypeId
23.127 +MeshMgtPeerLinkManFrame::GetInstanceTypeId(void) const
23.128 +{
23.129 + return GetTypeId();
23.130 +}
23.131 +
23.132 +void
23.133 +MeshMgtPeerLinkManFrame::Print(std::ostream &os) const
23.134 +{
23.135 + //TODO:fill this method
23.136 +}
23.137 +
23.138 +uint32_t
23.139 +MeshMgtPeerLinkManFrame::GetSerializedSize(void) const
23.140 +{
23.141 + uint32_t size = 1; //Subtype
23.142 + if(MESH_MGT_HEADER_PEER_CONFIRM == Subtype)
23.143 + size +=2; //AID of remote peer
23.144 + if(MESH_MGT_HEADER_PEER_CLOSE != Subtype)
23.145 + {
23.146 + size += Rates.GetSerializedSize ();
23.147 + size +=2;
23.148 + size += MeshId.GetSerializedSize ();
23.149 + size += MeshConfig.GetSerializedSize ();
23.150 + }
23.151 + size += PeerLinkMan.GetSerializedSize ();
23.152 + return size;
23.153 +}
23.154 +
23.155 +void
23.156 +MeshMgtPeerLinkManFrame::Serialize(Buffer::Iterator start) const
23.157 +{
23.158 + Buffer::Iterator i = start;
23.159 + i.WriteU8(Subtype); //Like a Category in Standart
23.160 + if(MESH_MGT_HEADER_PEER_CONFIRM == Subtype)
23.161 +
23.162 + i.WriteHtonU16(Aid);
23.163 + if(MESH_MGT_HEADER_PEER_CLOSE != Subtype)
23.164 + {
23.165 + i = Rates.Serialize(i);
23.166 + //now QoS capabilities
23.167 + i.WriteHtonU16(QoS);
23.168 + i = MeshId.Serialize (i);
23.169 + i = MeshConfig.Serialize (i);
23.170 + }
23.171 + i = PeerLinkMan.Serialize (i);
23.172 +}
23.173 +
23.174 +uint32_t
23.175 +MeshMgtPeerLinkManFrame::Deserialize(Buffer::Iterator start)
23.176 +{
23.177 + Buffer::Iterator i = start;
23.178 + Subtype = i.ReadU8();
23.179 + if(MESH_MGT_HEADER_PEER_CONFIRM == Subtype)
23.180 + Aid = i.ReadNtohU16();
23.181 + if(MESH_MGT_HEADER_PEER_CLOSE != Subtype)
23.182 + {
23.183 + i = Rates.Deserialize(i);
23.184 + QoS = i.ReadNtohU16();
23.185 + i = MeshId.Deserialize (i);
23.186 + i = MeshConfig.Deserialize (i);
23.187 + }
23.188 + i = PeerLinkMan.Deserialize (i);
23.189 + return i.GetDistanceFrom (start);
23.190 +}
23.191 +void
23.192 +MeshMgtPeerLinkManFrame::SetOpen()
23.193 +{
23.194 + Subtype = MESH_MGT_HEADER_PEER_OPEN;
23.195 +}
23.196 +
23.197 +void
23.198 +MeshMgtPeerLinkManFrame::SetConfirm()
23.199 +{
23.200 + Subtype = MESH_MGT_HEADER_PEER_CONFIRM;
23.201 +}
23.202 +
23.203 +void
23.204 +MeshMgtPeerLinkManFrame::SetClose()
23.205 +{
23.206 + Subtype = MESH_MGT_HEADER_PEER_CLOSE;
23.207 +}
23.208 +
23.209 +bool
23.210 +MeshMgtPeerLinkManFrame::IsOpen()
23.211 +{
23.212 + return (Subtype==MESH_MGT_HEADER_PEER_OPEN);
23.213 +}
23.214 +
23.215 +bool
23.216 +MeshMgtPeerLinkManFrame::IsConfirm()
23.217 +{
23.218 + return (Subtype==MESH_MGT_HEADER_PEER_CONFIRM);
23.219 +}
23.220 +
23.221 +bool
23.222 +MeshMgtPeerLinkManFrame::IsClose()
23.223 +{
23.224 + return (Subtype==MESH_MGT_HEADER_PEER_CLOSE);
23.225 +}
23.226 +
23.227 +} //namespace NS3
23.228 +
23.229 +
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
24.2 +++ b/src/devices/wifi/mesh-mgt-headers.h Sat Feb 28 14:21:05 2009 +0300
24.3 @@ -0,0 +1,95 @@
24.4 +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
24.5 +/*
24.6 + * Copyright (c) 2008,2009 IITP RAS
24.7 + *
24.8 + * This program is free software; you can redistribute it and/or modify
24.9 + * it under the terms of the GNU General Public License version 2 as
24.10 + * published by the Free Software Foundation;
24.11 + *
24.12 + * This program is distributed in the hope that it will be useful,
24.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
24.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24.15 + * GNU General Public License for more details.
24.16 + *
24.17 + * You should have received a copy of the GNU General Public License
24.18 + * along with this program; if not, write to the Free Software
24.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24.20 + *
24.21 + * Authors: Kirill Andreev <andreev@iitp.ru>
24.22 + * Yana Podkosova <yanapdk@rambler.ru>
24.23 + * Aleksey Kovalenko <kovalenko@iitp.ru>
24.24 + */
24.25 +
24.26 +
24.27 +#ifndef MESH_MGT_HEADERS_H
24.28 +#define MESH_MGT_HEADERS_H
24.29 +
24.30 +#include <stdint.h>
24.31 +
24.32 +#include "ns3/header.h"
24.33 +#include "status-code.h"
24.34 +#include "dot11s-peer-management-element.h"
24.35 +#include "supported-rates.h"
24.36 +#include "mesh-configuration-element.h"
24.37 +#include "mesh-wifi-preq-information-element.h"
24.38 +#include "mesh-wifi-prep-information-element.h"
24.39 +#include "mesh-wifi-perr-information-element.h"
24.40 +#include "mesh-wifi-rann-information-element.h"
24.41 +#include "ssid.h"
24.42 +
24.43 +namespace ns3 {
24.44 +
24.45 +class MeshMgtPeerLinkManFrame : public Header
24.46 +{
24.47 + public:
24.48 + MeshMgtPeerLinkManFrame ();
24.49 + void SetAid(uint16_t aid);
24.50 + void SetSupportedRates(SupportedRates rates);
24.51 + void SetQosField(uint16_t qos);
24.52 + void SetMeshId(Ssid Id);
24.53 + void SetMeshConfigurationElement(MeshConfigurationElement MeshConf);
24.54 + void SetPeerLinkManagementElement(PeerLinkManagementElement MeshPeerElement);
24.55 +
24.56 + uint16_t GetAid();
24.57 + SupportedRates GetSupportedRates();
24.58 + uint16_t GetQosField();
24.59 + Ssid GetMeshId();
24.60 + MeshConfigurationElement GetMeshConfigurationElement();
24.61 + PeerLinkManagementElement GetPeerLinkManagementElement();
24.62 +
24.63 + static TypeId GetTypeId(void);
24.64 + virtual TypeId GetInstanceTypeId(void) const;
24.65 + virtual void Print(std::ostream &os) const;
24.66 + virtual uint32_t GetSerializedSize(void) const;
24.67 + virtual void Serialize(Buffer::Iterator start) const;
24.68 + virtual uint32_t Deserialize(Buffer::Iterator start);
24.69 + //Subtype defining methods:
24.70 + void SetOpen();
24.71 + void SetConfirm();
24.72 + void SetClose();
24.73 +
24.74 + bool IsOpen();
24.75 + bool IsConfirm();
24.76 + bool IsClose();
24.77 +
24.78 + private:
24.79 + uint8_t Subtype;
24.80 + static const uint8_t MESH_MGT_HEADER_PEER_OPEN = 1;
24.81 + static const uint8_t MESH_MGT_HEADER_PEER_CONFIRM = 2;
24.82 + static const uint8_t MESH_MGT_HEADER_PEER_CLOSE = 3;
24.83 + // Standart is also requires a ReasonCode to be within
24.84 + // PeerLinkClose frame format, but it is present within
24.85 + // PeerLinkManagementElement, so we did not duplicate
24.86 + // it.
24.87 + uint16_t Aid; //only in Confirm
24.88 + SupportedRates Rates; //only in Open and Confirm
24.89 + uint16_t QoS; //only in Open and Confirm
24.90 + Ssid MeshId; //only in Open and Confirm
24.91 + MeshConfigurationElement MeshConfig; //only in Open and Confirm
24.92 + PeerLinkManagementElement PeerLinkMan; //in all types of frames
24.93 +};
24.94 +
24.95 +}//namespace NS3
24.96 +#endif
24.97 +
24.98 +
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
25.2 +++ b/src/devices/wifi/mesh-wifi-beacon-timing-element.cc Sat Feb 28 14:21:05 2009 +0300
25.3 @@ -0,0 +1,195 @@
25.4 +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
25.5 +/*
25.6 + * Copyright (c) 2008,2009 IITP RAS
25.7 + *
25.8 + * This program is free software; you can redistribute it and/or modify
25.9 + * it under the terms of the GNU General Public License version 2 as
25.10 + * published by the Free Software Foundation;
25.11 + *
25.12 + * This program is distributed in the hope that it will be useful,
25.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
25.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25.15 + * GNU General Public License for more details.
25.16 + *
25.17 + * You should have received a copy of the GNU General Public License
25.18 + * along with this program; if not, write to the Free Software
25.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25.20 + *
25.21 + * Author: Kirill Andreev <andreev@iitp.ru>
25.22 + */
25.23 +
25.24 +
25.25 +#include "mesh-wifi-beacon-timing-element.h"
25.26 +#define ELEMENT_ID (19)
25.27 +namespace ns3 {
25.28 +/*******************************************
25.29 + * WifiBeaconTimingElementUnit
25.30 + *******************************************/
25.31 +WifiBeaconTimingElementUnit::WifiBeaconTimingElementUnit()
25.32 +{
25.33 + AID = 0;
25.34 + LastBeacon = 0;
25.35 + BeaconInterval = 0;
25.36 +}
25.37 +
25.38 +void
25.39 +WifiBeaconTimingElementUnit::SetAID(uint8_t aid)
25.40 +{
25.41 + AID = aid;
25.42 +}
25.43 +
25.44 +void
25.45 +WifiBeaconTimingElementUnit::SetLastBeacon(uint16_t last_beacon)
25.46 +{
25.47 + LastBeacon = last_beacon;
25.48 +}
25.49 +
25.50 +void