Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1294)

Unified Diff: src/devices/mesh/flame/flame-protocol.cc

Issue 88094: 802.11s mesh stack model (Closed)
Patch Set: Review finished by Mathieu, ready to merge Created 14 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/devices/mesh/flame/flame-protocol.h ('k') | src/devices/mesh/flame/flame-protocol-mac.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/devices/mesh/flame/flame-protocol.cc
===================================================================
new file mode 100644
--- /dev/null
+++ b/src/devices/mesh/flame/flame-protocol.cc
@@ -0,0 +1,377 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 IITP RAS
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Kirill Andreev <andreev@iitp.ru>
+ */
+
+#include "flame-protocol.h"
+#include "flame-protocol-mac.h"
+#include "flame-header.h"
+#include "flame-rtable.h"
+#include "ns3/llc-snap-header.h"
+#include "ns3/log.h"
+#include "ns3/simulator.h"
+#include "ns3/packet.h"
+#include "ns3/mesh-point-device.h"
+#include "ns3/wifi-net-device.h"
+#include "ns3/mesh-point-device.h"
+#include "ns3/mesh-wifi-interface-mac.h"
+#include "ns3/random-variable.h"
+
+NS_LOG_COMPONENT_DEFINE ("FlameProtocol");
+
+namespace ns3 {
+namespace flame {
+//-----------------------------------------------------------------------------
+// FlameTag
+//-----------------------------------------------------------------------------
+NS_OBJECT_ENSURE_REGISTERED (FlameTag);
+
+TypeId
+FlameTag::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::flame::FlameTag") .SetParent<Tag> () .AddConstructor<FlameTag> ();
+ return tid;
+}
+
+TypeId
+FlameTag::GetInstanceTypeId () const
+{
+ return GetTypeId ();
+}
+
+uint32_t
+FlameTag::GetSerializedSize () const
+{
+ return 12;
+}
+
+void
+FlameTag::Serialize (TagBuffer i) const
+{
+ uint8_t buf[6];
+ receiver.CopyTo (buf);
+ for (int j = 0; j < 6; j++)
+ {
+ i.WriteU8 (buf[j]);
+ }
+ transmitter.CopyTo (buf);
+ for (int j = 0; j < 6; j++)
+ {
+ i.WriteU8 (buf[j]);
+ }
+
+}
+
+void
+FlameTag::Deserialize (TagBuffer i)
+{
+ uint8_t buf[6];
+ for (int j = 0; j < 6; j++)
+ {
+ buf[j] = i.ReadU8 ();
+ }
+ receiver.CopyFrom (buf);
+ for (int j = 0; j < 6; j++)
+ {
+ buf[j] = i.ReadU8 ();
+ }
+ transmitter.CopyFrom (buf);
+
+}
+
+void
+FlameTag::Print (std::ostream &os) const
+{
+ os << "receiver = " << receiver << ", transmitter = " << transmitter;
+}
+
+//-----------------------------------------------------------------------------
+// FlameProtocol
+//-----------------------------------------------------------------------------
+TypeId
+FlameProtocol::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::flame::FlameProtocol")
+ .SetParent<MeshL2RoutingProtocol> ()
+ .AddConstructor<FlameProtocol> ()
+ .AddAttribute ( "BroadcastInterval",
+ "How often we must send broadcast packets",
+ TimeValue (Seconds (5)),
+ MakeTimeAccessor (
+ &FlameProtocol::m_broadcastInterval),
+ MakeTimeChecker ()
+ )
+ .AddAttribute ( "MaxCost",
+ "Cost threshold after which packet will be dropeed",
+ UintegerValue (32),
+ MakeUintegerAccessor (
+ &FlameProtocol::m_maxCost),
+ MakeUintegerChecker<uint8_t> (3)
+ )
+ ;
+ return tid;
+}
+FlameProtocol::FlameProtocol () :
+ m_address (Mac48Address ()), m_broadcastInterval (Seconds (5)), m_lastBroadcast (Simulator::Now ()),
+ m_maxCost (32), m_myLastSeqno (1), m_rtable (CreateObject<FlameRtable> ())
+{
+}
+FlameProtocol::~FlameProtocol ()
+{
+}
+void
+FlameProtocol::DoDispose ()
+{
+}
+bool
+FlameProtocol::RequestRoute (uint32_t sourceIface, const Mac48Address source, const Mac48Address destination,
+ Ptr<const Packet> const_packet, uint16_t protocolType, RouteReplyCallback routeReply)
+{
+ Ptr<Packet> packet = const_packet->Copy ();
+ if (sourceIface == m_mp->GetIfIndex ())
+ {
+ //Packet from upper layer!
+ FlameTag tag;
+ if (packet->PeekPacketTag (tag))
+ {
+ NS_FATAL_ERROR ("FLAME tag is not supposed to be received from upper layers");
+ }
+ FlameRtable::LookupResult result = m_rtable->Lookup (destination);
+ if (result.retransmitter == Mac48Address::GetBroadcast ())
+ {
+ m_lastBroadcast = Simulator::Now ();
+ }
+ if (m_lastBroadcast + m_broadcastInterval < Simulator::Now ())
+ {
+ result.retransmitter = Mac48Address::GetBroadcast ();
+ result.ifIndex = FlameRtable::INTERFACE_ANY;
+ m_lastBroadcast = Simulator::Now ();
+ }
+ FlameHeader flameHdr;
+ flameHdr.AddCost (0);
+ flameHdr.SetSeqno (m_myLastSeqno++);
+ flameHdr.SetProtocol (protocolType);
+ flameHdr.SetOrigDst (destination);
+ flameHdr.SetOrigSrc (source);
+ m_stats.txBytes += packet->GetSize ();
+ packet->AddHeader (flameHdr);
+ tag.receiver = result.retransmitter;
+ if (result.retransmitter == Mac48Address::GetBroadcast ())
+ {
+ m_stats.txBroadcast++;
+ }
+ else
+ {
+ m_stats.txUnicast++;
+ }
+ NS_LOG_DEBUG ("Source: send packet with RA = " << tag.receiver);
+ packet->AddPacketTag (tag);
+ routeReply (true, packet, source, destination, FLAME_PROTOCOL, result.ifIndex);
+ }
+ else
+ {
+ FlameHeader flameHdr;
+ packet->RemoveHeader (flameHdr);
+ FlameTag tag;
+
+ if (!packet->RemovePacketTag (tag))
+ {
+ NS_FATAL_ERROR ("FLAME tag must exist here");
+ }
+ if (destination == Mac48Address::GetBroadcast ())
+ {
+ //Broadcast always is forwarded as broadcast!
+ NS_ASSERT (HandleDataFrame (flameHdr.GetSeqno (), source, flameHdr, tag.transmitter, sourceIface));
+ FlameTag tag (Mac48Address::GetBroadcast ());
+ flameHdr.AddCost (1);
+ m_stats.txBytes += packet->GetSize ();
+ packet->AddHeader (flameHdr);
+ packet->AddPacketTag (tag);
+ routeReply (true, packet, source, destination, FLAME_PROTOCOL, FlameRtable::INTERFACE_ANY);
+ m_stats.txBroadcast++;
+ return true;
+ }
+ else
+ {
+ // We check sequence only when forward unicast, because broadcast-checks were done
+ // inside remove routing stuff.
+ if (HandleDataFrame (flameHdr.GetSeqno (), source, flameHdr, tag.transmitter, sourceIface))
+ {
+ return false;
+ }
+ FlameRtable::LookupResult result = m_rtable->Lookup (destination);
+ if (tag.receiver != Mac48Address::GetBroadcast ())
+ {
+ if (result.retransmitter == Mac48Address::GetBroadcast ())
+ {
+ NS_LOG_DEBUG ("unicast packet dropped, because no route! I am " << GetAddress ()
+ << ", RA = " << tag.receiver << ", TA = " << tag.transmitter);
+ m_stats.totalDropped++;
+ return false;
+ }
+ }
+ tag.receiver = result.retransmitter;
+ if (result.retransmitter == Mac48Address::GetBroadcast ())
+ {
+ m_stats.txBroadcast++;
+ }
+ else
+ {
+ m_stats.txUnicast++;
+ }
+ m_stats.txBytes += packet->GetSize ();
+ flameHdr.AddCost (1);
+ packet->AddHeader (flameHdr);
+ packet->AddPacketTag (tag);
+ routeReply (true, packet, source, destination, FLAME_PROTOCOL, result.ifIndex);
+ return true;
+ }
+ return true;
+ }
+ return false;
+}
+bool
+FlameProtocol::RemoveRoutingStuff (uint32_t fromIface, const Mac48Address source,
+ const Mac48Address destination, Ptr<Packet> packet, uint16_t& protocolType)
+{
+ //Filter seqno:
+ if (source == GetAddress ())
+ {
+ NS_LOG_DEBUG ("Dropped my own frame!");
+ return false;
+ }
+ FlameTag tag;
+ if (!packet->RemovePacketTag (tag))
+ {
+ NS_FATAL_ERROR ("FLAME tag must exist when packet is coming to protocol");
+ }
+ FlameHeader flameHdr;
+ packet->RemoveHeader (flameHdr);
+ if ((destination == GetAddress ()) && (m_lastBroadcast + m_broadcastInterval < Simulator::Now ()))
+ {
+ Ptr<Packet> packet = Create<Packet> ();
+ m_mp->Send(packet, Mac48Address::GetBroadcast (), 0);
+ m_lastBroadcast = Simulator::Now ();
+ }
+ NS_ASSERT (protocolType == FLAME_PROTOCOL);
+ protocolType = flameHdr.GetProtocol ();
+ if ((HandleDataFrame (flameHdr.GetSeqno (), source, flameHdr, tag.transmitter, fromIface))
+ || packet->GetSize () == 0)
+ {
+ return false;
+ }
+ return true;
+}
+bool
+FlameProtocol::Install (Ptr<MeshPointDevice> mp)
+{
+ m_mp = mp;
+ std::vector<Ptr<NetDevice> > interfaces = mp->GetInterfaces ();
+ for (std::vector<Ptr<NetDevice> >::const_iterator i = interfaces.begin (); i != interfaces.end (); i++)
+ {
+ // Checking for compatible net device
+ Ptr<WifiNetDevice> wifiNetDev = (*i)->GetObject<WifiNetDevice> ();
+ if (wifiNetDev == 0)
+ {
+ return false;
+ }
+ Ptr<MeshWifiInterfaceMac> mac = wifiNetDev->GetMac ()->GetObject<MeshWifiInterfaceMac> ();
+ if (mac == 0)
+ {
+ return false;
+ }
+ // Installing plugins:
+ Ptr<FlameProtocolMac> flameMac = Create<FlameProtocolMac> (wifiNetDev->GetIfIndex (), this);
+ m_interfaces[wifiNetDev->GetIfIndex ()] = flameMac;
+ mac->SetBeaconGeneration (false);
+ mac->InstallPlugin (flameMac);
+ }
+ mp->SetRoutingProtocol (this);
+ // Mesh point aggregates all installed protocols
+ mp->AggregateObject (this);
+ m_address = Mac48Address::ConvertFrom (mp->GetAddress ());//* address;
+ return true;
+}
+Mac48Address
+FlameProtocol::GetAddress ()
+{
+ return m_address;
+}
+bool
+FlameProtocol::HandleDataFrame (uint16_t seqno, Mac48Address source, const FlameHeader flameHdr,
+ Mac48Address receiver, uint32_t fromInterface)
+{
+ if (source == GetAddress ())
+ {
+ m_stats.totalDropped++;
+ return true;
+ }
+ FlameRtable::LookupResult result = m_rtable->Lookup (source);
+ if ((result.retransmitter != Mac48Address::GetBroadcast ()) && ((int16_t)(result.seqnum - seqno) >= 0))
+ {
+ return true;
+ }
+ if (flameHdr.GetCost () > m_maxCost)
+ {
+ m_stats.droppedTtl++;
+ return true;
+ }
+ m_rtable->AddPath (source, receiver, fromInterface, flameHdr.GetCost (), flameHdr.GetSeqno ());
+ return false;
+}
+//Statistics:
+FlameProtocol::Statistics::Statistics () :
+ txUnicast (0), txBroadcast (0), txBytes (0), droppedTtl (0), totalDropped (0)
+{
+}
+void
+FlameProtocol::Statistics::Print (std::ostream & os) const
+{
+ os << "<Statistics "
+ "txUnicast=\"" << txUnicast << "\" "
+ "txBroadcast=\"" << txBroadcast << "\" "
+ "txBytes=\"" << txBytes << "\" "
+ "droppedTtl=\"" << droppedTtl << "\" "
+ "totalDropped=\"" << totalDropped << "\"/>" << std::endl;
+}
+void
+FlameProtocol::Report (std::ostream & os) const
+{
+ os << "<Flame "
+ "address=\"" << m_address << "\"" << std::endl <<
+ "broadcastInterval=\"" << m_broadcastInterval.GetSeconds () << "\"" << std::endl <<
+ "maxCost=\"" << (uint16_t) m_maxCost << "\">" << std::endl;
+ m_stats.Print (os);
+ for (FlamePluginMap::const_iterator plugin = m_interfaces.begin (); plugin != m_interfaces.end (); plugin++)
+ {
+ plugin->second->Report (os);
+ }
+ os << "</Flame>" << std::endl;
+}
+void
+FlameProtocol::ResetStats ()
+{
+ m_stats = Statistics ();
+ for (FlamePluginMap::const_iterator plugin = m_interfaces.begin (); plugin != m_interfaces.end (); plugin++)
+ {
+ plugin->second->ResetStats ();
+ }
+}
+
+} //namespace flame
+} //namespace ns3
« no previous file with comments | « src/devices/mesh/flame/flame-protocol.h ('k') | src/devices/mesh/flame/flame-protocol-mac.h » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b