Merge 802.11s code.
authorAndrey Mazo <mazo@iitp.ru>
Sat Feb 28 14:21:05 2009 +0300 (11 months ago)
changeset 47934f6a6772628e
parent 4244 7c98934dcccd
child 4794 ddefc6dd6d9b
Merge 802.11s code.
examples/mesh.cc
examples/wscript
src/devices/l2-routing/l2-routing-hwmp/hwmp-rtable.cc
src/devices/l2-routing/l2-routing-hwmp/hwmp-rtable.h
src/devices/l2-routing/l2-routing-hwmp/hwmp-state.cc
src/devices/l2-routing/l2-routing-hwmp/hwmp-state.h
src/devices/l2-routing/l2-routing-hwmp/hwmp.cc
src/devices/l2-routing/l2-routing-hwmp/hwmp.h
src/devices/l2-routing/l2-routing-hwmp/waf
src/devices/l2-routing/l2-routing-hwmp/wscript
src/devices/l2-routing/l2-routing-main/l2-routing-net-device.cc
src/devices/l2-routing/l2-routing-main/l2-routing-net-device.h
src/devices/l2-routing/l2-routing-main/waf
src/devices/l2-routing/l2-routing-main/wscript
src/devices/wifi/dca-txop.h
src/devices/wifi/dot11s-codes.h
src/devices/wifi/dot11s-parameters.cc
src/devices/wifi/dot11s-parameters.h
src/devices/wifi/dot11s-peer-management-element.cc
src/devices/wifi/dot11s-peer-management-element.h
src/devices/wifi/mesh-configuration-element.cc
src/devices/wifi/mesh-configuration-element.h
src/devices/wifi/mesh-mgt-headers.cc
src/devices/wifi/mesh-mgt-headers.h
src/devices/wifi/mesh-wifi-beacon-timing-element.cc
src/devices/wifi/mesh-wifi-beacon-timing-element.h
src/devices/wifi/mesh-wifi-mac.cc
src/devices/wifi/mesh-wifi-mac.h
src/devices/wifi/mesh-wifi-peer-manager.cc
src/devices/wifi/mesh-wifi-peer-manager.h
src/devices/wifi/mesh-wifi-perr-information-element.cc
src/devices/wifi/mesh-wifi-perr-information-element.h
src/devices/wifi/mesh-wifi-prep-information-element.cc
src/devices/wifi/mesh-wifi-prep-information-element.h
src/devices/wifi/mesh-wifi-preq-information-element.cc
src/devices/wifi/mesh-wifi-preq-information-element.h
src/devices/wifi/mesh-wifi-rann-information-element.cc
src/devices/wifi/mesh-wifi-rann-information-element.h
src/devices/wifi/mgt-headers.cc
src/devices/wifi/mgt-headers.h
src/devices/wifi/tx-statistics.cc
src/devices/wifi/tx-statistics.h
src/devices/wifi/wifi-mac-header.cc
src/devices/wifi/wifi-mac-header.h
src/devices/wifi/wifi-remote-station-manager.cc
src/devices/wifi/wifi-remote-station-manager.h
src/devices/wifi/wscript
src/helper/hwmp-helper.cc
src/helper/hwmp-helper.h
src/helper/mesh-wifi-helper.cc
src/helper/mesh-wifi-helper.h
src/helper/wscript
src/node/l2-routing-protocol.cc
src/node/l2-routing-protocol.h
src/node/wscript
src/wscript
     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