A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
flame-protocol.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2009 IITP RAS
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Kirill Andreev <andreev@iitp.ru>
19  */
20 
21 #include "flame-protocol.h"
22 #include "flame-protocol-mac.h"
23 #include "flame-header.h"
24 #include "flame-rtable.h"
25 #include "ns3/llc-snap-header.h"
26 #include "ns3/log.h"
27 #include "ns3/simulator.h"
28 #include "ns3/packet.h"
29 #include "ns3/mesh-point-device.h"
30 #include "ns3/wifi-net-device.h"
31 #include "ns3/mesh-point-device.h"
32 #include "ns3/mesh-wifi-interface-mac.h"
33 
34 NS_LOG_COMPONENT_DEFINE ("FlameProtocol");
35 
36 namespace ns3 {
37 namespace flame {
38 //-----------------------------------------------------------------------------
39 // FlameTag
40 //-----------------------------------------------------------------------------
42  ;
43 NS_OBJECT_ENSURE_REGISTERED (FlameProtocol)
44  ;
45 
46 TypeId
48 {
49  static TypeId tid = TypeId ("ns3::flame::FlameTag").SetParent<Tag> ().AddConstructor<FlameTag> ();
50  return tid;
51 }
52 
53 TypeId
55 {
56  return GetTypeId ();
57 }
58 
59 uint32_t
61 {
62  return 12;
63 }
64 
65 void
67 {
68  uint8_t buf[6];
69  receiver.CopyTo (buf);
70  for (int j = 0; j < 6; j++)
71  {
72  i.WriteU8 (buf[j]);
73  }
74  transmitter.CopyTo (buf);
75  for (int j = 0; j < 6; j++)
76  {
77  i.WriteU8 (buf[j]);
78  }
79 
80 }
81 
82 void
84 {
85  uint8_t buf[6];
86  for (int j = 0; j < 6; j++)
87  {
88  buf[j] = i.ReadU8 ();
89  }
90  receiver.CopyFrom (buf);
91  for (int j = 0; j < 6; j++)
92  {
93  buf[j] = i.ReadU8 ();
94  }
95  transmitter.CopyFrom (buf);
96 
97 }
98 
99 void
100 FlameTag::Print (std::ostream &os) const
101 {
102  os << "receiver = " << receiver << ", transmitter = " << transmitter;
103 }
104 
105 //-----------------------------------------------------------------------------
106 // FlameProtocol
107 //-----------------------------------------------------------------------------
108 TypeId
110 {
111  static TypeId tid = TypeId ("ns3::flame::FlameProtocol")
113  .AddConstructor<FlameProtocol> ()
114  .AddAttribute ( "BroadcastInterval",
115  "How often we must send broadcast packets",
116  TimeValue (Seconds (5)),
117  MakeTimeAccessor (
119  MakeTimeChecker ()
120  )
121  .AddAttribute ( "MaxCost",
122  "Cost threshold after which packet will be dropped",
123  UintegerValue (32),
124  MakeUintegerAccessor (
126  MakeUintegerChecker<uint8_t> (3)
127  )
128  ;
129  return tid;
130 }
132  m_address (Mac48Address ()), m_broadcastInterval (Seconds (5)), m_lastBroadcast (Seconds (0)),
133  m_maxCost (32), m_myLastSeqno (1), m_rtable (CreateObject<FlameRtable> ())
134 {
135 }
137 {
138 }
139 void
141 {
142  m_interfaces.clear ();
143  m_rtable = 0;
144  m_mp = 0;
145 }
146 bool
147 FlameProtocol::RequestRoute (uint32_t sourceIface, const Mac48Address source, const Mac48Address destination,
148  Ptr<const Packet> const_packet, uint16_t protocolType, RouteReplyCallback routeReply)
149 {
150  Ptr<Packet> packet = const_packet->Copy ();
151  if (sourceIface == m_mp->GetIfIndex ())
152  {
153  //Packet from upper layer!
154  FlameTag tag;
155  if (packet->PeekPacketTag (tag))
156  {
157  NS_FATAL_ERROR ("FLAME tag is not supposed to be received from upper layers");
158  }
159  FlameRtable::LookupResult result = m_rtable->Lookup (destination);
160  if (result.retransmitter == Mac48Address::GetBroadcast ())
161  {
163  }
165  {
169  }
170  FlameHeader flameHdr;
171  flameHdr.AddCost (0);
172  flameHdr.SetSeqno (m_myLastSeqno++);
173  flameHdr.SetProtocol (protocolType);
174  flameHdr.SetOrigDst (destination);
175  flameHdr.SetOrigSrc (source);
176  m_stats.txBytes += packet->GetSize ();
177  packet->AddHeader (flameHdr);
178  tag.receiver = result.retransmitter;
179  if (result.retransmitter == Mac48Address::GetBroadcast ())
180  {
182  }
183  else
184  {
185  m_stats.txUnicast++;
186  }
187  NS_LOG_DEBUG ("Source: send packet with RA = " << tag.receiver);
188  packet->AddPacketTag (tag);
189  routeReply (true, packet, source, destination, FLAME_PROTOCOL, result.ifIndex);
190  }
191  else
192  {
193  FlameHeader flameHdr;
194  packet->RemoveHeader (flameHdr);
195  FlameTag tag;
196 
197  if (!packet->RemovePacketTag (tag))
198  {
199  NS_FATAL_ERROR ("FLAME tag must exist here");
200  }
201  if (destination == Mac48Address::GetBroadcast ())
202  {
203  //Broadcast always is forwarded as broadcast!
204  NS_ASSERT (HandleDataFrame (flameHdr.GetSeqno (), source, flameHdr, tag.transmitter, sourceIface));
206  flameHdr.AddCost (1);
207  m_stats.txBytes += packet->GetSize ();
208  packet->AddHeader (flameHdr);
209  packet->AddPacketTag (tag);
210  routeReply (true, packet, source, destination, FLAME_PROTOCOL, FlameRtable::INTERFACE_ANY);
212  return true;
213  }
214  else
215  {
216  // We check sequence only when forward unicast, because broadcast-checks were done
217  // inside remove routing stuff.
218  if (HandleDataFrame (flameHdr.GetSeqno (), source, flameHdr, tag.transmitter, sourceIface))
219  {
220  return false;
221  }
222  FlameRtable::LookupResult result = m_rtable->Lookup (destination);
223  if (tag.receiver != Mac48Address::GetBroadcast ())
224  {
225  if (result.retransmitter == Mac48Address::GetBroadcast ())
226  {
227  NS_LOG_DEBUG ("unicast packet dropped, because no route! I am " << GetAddress ()
228  << ", RA = " << tag.receiver << ", TA = " << tag.transmitter);
230  return false;
231  }
232  tag.receiver = result.retransmitter;
233  }
234  else
235  {
237  }
238  if (result.retransmitter == Mac48Address::GetBroadcast ())
239  {
241  }
242  else
243  {
244  m_stats.txUnicast++;
245  }
246  m_stats.txBytes += packet->GetSize ();
247  flameHdr.AddCost (1);
248  packet->AddHeader (flameHdr);
249  packet->AddPacketTag (tag);
250  routeReply (true, packet, source, destination, FLAME_PROTOCOL, result.ifIndex);
251  return true;
252  }
253  return true;
254  }
255  return false;
256 }
257 bool
258 FlameProtocol::RemoveRoutingStuff (uint32_t fromIface, const Mac48Address source,
259  const Mac48Address destination, Ptr<Packet> packet, uint16_t& protocolType)
260 {
261  //Filter seqno:
262  if (source == GetAddress ())
263  {
264  NS_LOG_DEBUG ("Dropped my own frame!");
265  return false;
266  }
267  FlameTag tag;
268  if (!packet->RemovePacketTag (tag))
269  {
270  NS_FATAL_ERROR ("FLAME tag must exist when packet is coming to protocol");
271  }
272  FlameHeader flameHdr;
273  packet->RemoveHeader (flameHdr);
274  if (HandleDataFrame (flameHdr.GetSeqno (), source, flameHdr, tag.transmitter, fromIface))
275  {
276  return false;
277  }
278  // Start PATH_UPDATE procedure if destination is our own address and last broadcast was sent more
279  // than broadcast interval ago or was not sent at all
280  if ((destination == GetAddress ()) && ((m_lastBroadcast + m_broadcastInterval < Simulator::Now ())
281  || (m_lastBroadcast == Seconds (0))))
282  {
283  Ptr<Packet> packet = Create<Packet> ();
284  m_mp->Send (packet, Mac48Address::GetBroadcast (), 0);
286  }
287  NS_ASSERT (protocolType == FLAME_PROTOCOL);
288  protocolType = flameHdr.GetProtocol ();
289  return true;
290 }
291 bool
293 {
294  m_mp = mp;
295  std::vector<Ptr<NetDevice> > interfaces = mp->GetInterfaces ();
296  for (std::vector<Ptr<NetDevice> >::const_iterator i = interfaces.begin (); i != interfaces.end (); i++)
297  {
298  // Checking for compatible net device
299  Ptr<WifiNetDevice> wifiNetDev = (*i)->GetObject<WifiNetDevice> ();
300  if (wifiNetDev == 0)
301  {
302  return false;
303  }
304  Ptr<MeshWifiInterfaceMac> mac = wifiNetDev->GetMac ()->GetObject<MeshWifiInterfaceMac> ();
305  if (mac == 0)
306  {
307  return false;
308  }
309  // Installing plugins:
310  Ptr<FlameProtocolMac> flameMac = Create<FlameProtocolMac> (this);
311  m_interfaces[wifiNetDev->GetIfIndex ()] = flameMac;
312  mac->SetBeaconGeneration (false);
313  mac->InstallPlugin (flameMac);
314  }
315  mp->SetRoutingProtocol (this);
316  // Mesh point aggregates all installed protocols
317  mp->AggregateObject (this);
318  m_address = Mac48Address::ConvertFrom (mp->GetAddress ()); //* address;
319  return true;
320 }
323 {
324  return m_address;
325 }
326 bool
327 FlameProtocol::HandleDataFrame (uint16_t seqno, Mac48Address source, const FlameHeader flameHdr,
328  Mac48Address receiver, uint32_t fromInterface)
329 {
330  if (source == GetAddress ())
331  {
333  return true;
334  }
335  FlameRtable::LookupResult result = m_rtable->Lookup (source);
336  if ((result.retransmitter != Mac48Address::GetBroadcast ()) && ((int16_t)(result.seqnum - seqno) >= 0))
337  {
338  return true;
339  }
340  if (flameHdr.GetCost () > m_maxCost)
341  {
343  return true;
344  }
345  m_rtable->AddPath (source, receiver, fromInterface, flameHdr.GetCost (), flameHdr.GetSeqno ());
346  return false;
347 }
348 //Statistics:
350  txUnicast (0), txBroadcast (0), txBytes (0), droppedTtl (0), totalDropped (0)
351 {
352 }
353 void
354 FlameProtocol::Statistics::Print (std::ostream & os) const
355 {
356  os << "<Statistics "
357  "txUnicast=\"" << txUnicast << "\" "
358  "txBroadcast=\"" << txBroadcast << "\" "
359  "txBytes=\"" << txBytes << "\" "
360  "droppedTtl=\"" << droppedTtl << "\" "
361  "totalDropped=\"" << totalDropped << "\"/>" << std::endl;
362 }
363 void
364 FlameProtocol::Report (std::ostream & os) const
365 {
366  os << "<Flame "
367  "address=\"" << m_address << "\"" << std::endl <<
368  "broadcastInterval=\"" << m_broadcastInterval.GetSeconds () << "\"" << std::endl <<
369  "maxCost=\"" << (uint16_t) m_maxCost << "\">" << std::endl;
370  m_stats.Print (os);
371  for (FlamePluginMap::const_iterator plugin = m_interfaces.begin (); plugin != m_interfaces.end (); plugin++)
372  {
373  plugin->second->Report (os);
374  }
375  os << "</Flame>" << std::endl;
376 }
377 void
379 {
380  m_stats = Statistics ();
381  for (FlamePluginMap::const_iterator plugin = m_interfaces.begin (); plugin != m_interfaces.end (); plugin++)
382  {
383  plugin->second->ResetStats ();
384  }
385 }
386 
387 } // namespace flame
388 } // namespace ns3
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:268
Routing table for FLAME.
Definition: flame-rtable.h:36
Callback template class.
Definition: callback.h:920
void SetSeqno(uint16_t seqno)
void Print(std::ostream &os) const
uint32_t GetSerializedSize() const
void SetOrigDst(Mac48Address dst)
bool RemoveRoutingStuff(uint32_t fromIface, const Mac48Address source, const Mac48Address destination, Ptr< Packet > packet, uint16_t &protocolType)
Cleanup flame headers!
void Print(std::ostream &os) const
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:841
#define NS_ASSERT(condition)
Definition: assert.h:64
NS_OBJECT_ENSURE_REGISTERED(NullMessageSimulatorImpl)
uint32_t GetSize(void) const
Definition: packet.h:650
TAG_BUFFER_INLINE uint8_t ReadU8(void)
Definition: tag-buffer.h:179
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
uint8_t m_maxCost
Max Cost value (or TTL, because cost is actually hopcount)
void SetProtocol(uint16_t protocol)
Ptr< T > CreateObject(void)
Definition: object.h:420
bool HandleDataFrame(uint16_t seqno, Mac48Address source, const FlameHeader flameHdr, Mac48Address receiver, uint32_t fromIface)
Handles a packet: adds a routing information and drops packets by TTL or Seqno.
double GetSeconds(void) const
Definition: nstime.h:274
void CopyTo(uint8_t buffer[6]) const
bool PeekPacketTag(Tag &tag) const
Search a matching tag and call Tag::Deserialize if it is found.
Definition: packet.cc:863
Ptr< FlameRtable > m_rtable
Routing table:
uint8_t GetCost() const
Definition: flame-header.cc:98
Ptr< MeshPointDevice > m_mp
Host mesh point.
void Serialize(TagBuffer i) const
hold objects of type ns3::Time
Definition: nstime.h:961
Hold an unsigned integer type.
Definition: uinteger.h:46
tuple interfaces
Definition: first.py:40
Hold together all Wifi-related objects.
static Mac48Address GetBroadcast(void)
uint16_t GetSeqno() const
void AddCost(uint8_t cost)
Definition: flame-header.cc:93
static Mac48Address ConvertFrom(const Address &address)
NS_LOG_COMPONENT_DEFINE("FlameProtocol")
Ptr< Packet > Copy(void) const
Definition: packet.cc:122
tag a set of bytes in a packet
Definition: tag.h:36
Route lookup result, return type of LookupXXX methods.
Definition: flame-rtable.h:45
bool Install(Ptr< MeshPointDevice >)
Install FLAME on given mesh point.
void SetOrigSrc(Mac48Address OrigSrc)
bool RequestRoute(uint32_t sourceIface, const Mac48Address source, const Mac48Address destination, Ptr< const Packet > packet, uint16_t protocolType, RouteReplyCallback routeReply)
Route request, inherited from MeshL2RoutingProtocol.
void Deserialize(TagBuffer i)
an EUI-48 address
Definition: mac48-address.h:41
TAG_BUFFER_INLINE void WriteU8(uint8_t v)
Definition: tag-buffer.h:156
void CopyFrom(const uint8_t buffer[6])
static Time Now(void)
Return the "current simulation time".
Definition: simulator.cc:180
Interface for L2 mesh routing protocol and mesh point communication.
void DoDispose()
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
read and write tag data
Definition: tag-buffer.h:51
static const uint32_t INTERFACE_ANY
Means all interfaces.
Definition: flame-rtable.h:40
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:848
#define NS_LOG_DEBUG(msg)
Definition: log.h:289
void Report(std::ostream &) const
Statistics.
TypeId GetInstanceTypeId() const
Mac48Address receiver
Receiver of the packet:
static TypeId GetTypeId()
uint16_t m_myLastSeqno
Sequence number:
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:452
static const uint16_t FLAME_PROTOCOL
LLC protocol number reserved by flame.
a unique identifier for an interface.
Definition: type-id.h:49
TypeId SetParent(TypeId tid)
Definition: type-id.cc:611
Basic MAC of mesh point Wi-Fi interface.
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:253
Transmitter and receiver addresses.
Mac48Address transmitter
transmitter for incoming: