A Discrete-Event Network Simulator
API
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 namespace ns3 {
35 
36 NS_LOG_COMPONENT_DEFINE ("FlameProtocol");
37 
38 namespace flame {
39 
40 //-----------------------------------------------------------------------------
41 // FlameTag
42 //-----------------------------------------------------------------------------
44 NS_OBJECT_ENSURE_REGISTERED (FlameProtocol);
45 
46 TypeId
48 {
49  static TypeId tid = TypeId ("ns3::flame::FlameTag")
50  .SetParent<Tag> ()
51  .SetGroupName ("Mesh")
52  .AddConstructor<FlameTag> ()
53  ;
54  return tid;
55 }
56 
57 TypeId
59 {
60  return GetTypeId ();
61 }
62 
63 uint32_t
65 {
66  return 12;
67 }
68 
69 void
71 {
72  uint8_t buf[6];
73  receiver.CopyTo (buf);
74  for (int j = 0; j < 6; j++)
75  {
76  i.WriteU8 (buf[j]);
77  }
78  transmitter.CopyTo (buf);
79  for (int j = 0; j < 6; j++)
80  {
81  i.WriteU8 (buf[j]);
82  }
83 
84 }
85 
86 void
88 {
89  uint8_t buf[6];
90  for (int j = 0; j < 6; j++)
91  {
92  buf[j] = i.ReadU8 ();
93  }
94  receiver.CopyFrom (buf);
95  for (int j = 0; j < 6; j++)
96  {
97  buf[j] = i.ReadU8 ();
98  }
99  transmitter.CopyFrom (buf);
100 
101 }
102 
103 void
104 FlameTag::Print (std::ostream &os) const
105 {
106  os << "receiver = " << receiver << ", transmitter = " << transmitter;
107 }
108 
109 //-----------------------------------------------------------------------------
110 // FlameProtocol
111 //-----------------------------------------------------------------------------
112 TypeId
114 {
115  static TypeId tid = TypeId ("ns3::flame::FlameProtocol")
117  .SetGroupName ("Mesh")
118  .AddConstructor<FlameProtocol> ()
119  .AddAttribute ( "BroadcastInterval",
120  "How often we must send broadcast packets",
121  TimeValue (Seconds (5)),
124  MakeTimeChecker ()
125  )
126  .AddAttribute ( "MaxCost",
127  "Cost threshold after which packet will be dropped",
128  UintegerValue (32),
131  MakeUintegerChecker<uint8_t> (3)
132  )
133  ;
134  return tid;
135 }
137  m_address (Mac48Address ()), m_broadcastInterval (Seconds (5)), m_lastBroadcast (Seconds (0)),
138  m_maxCost (32), m_myLastSeqno (1), m_rtable (CreateObject<FlameRtable> ())
139 {
140 }
142 {
143 }
144 void
146 {
147  m_interfaces.clear ();
148  m_rtable = 0;
149  m_mp = 0;
150 }
151 bool
152 FlameProtocol::RequestRoute (uint32_t sourceIface, const Mac48Address source, const Mac48Address destination,
153  Ptr<const Packet> const_packet, uint16_t protocolType, RouteReplyCallback routeReply)
154 {
155  Ptr<Packet> packet = const_packet->Copy ();
156  if (sourceIface == m_mp->GetIfIndex ())
157  {
158  //Packet from upper layer!
159  FlameTag tag;
160  if (packet->PeekPacketTag (tag))
161  {
162  NS_FATAL_ERROR ("FLAME tag is not supposed to be received from upper layers");
163  }
164  FlameRtable::LookupResult result = m_rtable->Lookup (destination);
165  if (result.retransmitter == Mac48Address::GetBroadcast ())
166  {
168  }
170  {
174  }
175  FlameHeader flameHdr;
176  flameHdr.AddCost (0);
177  flameHdr.SetSeqno (m_myLastSeqno++);
178  flameHdr.SetProtocol (protocolType);
179  flameHdr.SetOrigDst (destination);
180  flameHdr.SetOrigSrc (source);
181  m_stats.txBytes += packet->GetSize ();
182  packet->AddHeader (flameHdr);
183  tag.receiver = result.retransmitter;
184  if (result.retransmitter == Mac48Address::GetBroadcast ())
185  {
187  }
188  else
189  {
190  m_stats.txUnicast++;
191  }
192  NS_LOG_DEBUG ("Source: send packet with RA = " << tag.receiver);
193  packet->AddPacketTag (tag);
194  routeReply (true, packet, source, destination, FLAME_PROTOCOL, result.ifIndex);
195  }
196  else
197  {
198  FlameHeader flameHdr;
199  packet->RemoveHeader (flameHdr);
200  FlameTag tag;
201 
202  if (!packet->RemovePacketTag (tag))
203  {
204  NS_FATAL_ERROR ("FLAME tag must exist here");
205  }
206  if (destination == Mac48Address::GetBroadcast ())
207  {
208  //Broadcast always is forwarded as broadcast!
209  NS_ASSERT (HandleDataFrame (flameHdr.GetSeqno (), source, flameHdr, tag.transmitter, sourceIface));
211  flameHdr.AddCost (1);
212  m_stats.txBytes += packet->GetSize ();
213  packet->AddHeader (flameHdr);
214  packet->AddPacketTag (tag);
215  routeReply (true, packet, source, destination, FLAME_PROTOCOL, FlameRtable::INTERFACE_ANY);
217  return true;
218  }
219  else
220  {
221  // We check sequence only when forward unicast, because broadcast-checks were done
222  // inside remove routing stuff.
223  if (HandleDataFrame (flameHdr.GetSeqno (), source, flameHdr, tag.transmitter, sourceIface))
224  {
225  return false;
226  }
227  FlameRtable::LookupResult result = m_rtable->Lookup (destination);
228  if (tag.receiver != Mac48Address::GetBroadcast ())
229  {
230  if (result.retransmitter == Mac48Address::GetBroadcast ())
231  {
232  NS_LOG_DEBUG ("unicast packet dropped, because no route! I am " << GetAddress ()
233  << ", RA = " << tag.receiver << ", TA = " << tag.transmitter);
235  return false;
236  }
237  tag.receiver = result.retransmitter;
238  }
239  else
240  {
242  }
243  if (result.retransmitter == Mac48Address::GetBroadcast ())
244  {
246  }
247  else
248  {
249  m_stats.txUnicast++;
250  }
251  m_stats.txBytes += packet->GetSize ();
252  flameHdr.AddCost (1);
253  packet->AddHeader (flameHdr);
254  packet->AddPacketTag (tag);
255  routeReply (true, packet, source, destination, FLAME_PROTOCOL, result.ifIndex);
256  return true;
257  }
258  return true;
259  }
260  return false;
261 }
262 bool
263 FlameProtocol::RemoveRoutingStuff (uint32_t fromIface, const Mac48Address source,
264  const Mac48Address destination, Ptr<Packet> packet, uint16_t& protocolType)
265 {
266  //Filter seqno:
267  if (source == GetAddress ())
268  {
269  NS_LOG_DEBUG ("Dropped my own frame!");
270  return false;
271  }
272  FlameTag tag;
273  if (!packet->RemovePacketTag (tag))
274  {
275  NS_FATAL_ERROR ("FLAME tag must exist when packet is coming to protocol");
276  }
277  FlameHeader flameHdr;
278  packet->RemoveHeader (flameHdr);
279  if (HandleDataFrame (flameHdr.GetSeqno (), source, flameHdr, tag.transmitter, fromIface))
280  {
281  return false;
282  }
283  // Start PATH_UPDATE procedure if destination is our own address and last broadcast was sent more
284  // than broadcast interval ago or was not sent at all
285  if ((destination == GetAddress ()) && ((m_lastBroadcast + m_broadcastInterval < Simulator::Now ())
286  || (m_lastBroadcast == Seconds (0))))
287  {
288  Ptr<Packet> packet = Create<Packet> ();
289  m_mp->Send (packet, Mac48Address::GetBroadcast (), 0);
291  }
292  NS_ASSERT (protocolType == FLAME_PROTOCOL);
293  protocolType = flameHdr.GetProtocol ();
294  return true;
295 }
296 bool
298 {
299  m_mp = mp;
300  std::vector<Ptr<NetDevice> > interfaces = mp->GetInterfaces ();
301  for (std::vector<Ptr<NetDevice> >::const_iterator i = interfaces.begin (); i != interfaces.end (); i++)
302  {
303  // Checking for compatible net device
304  Ptr<WifiNetDevice> wifiNetDev = (*i)->GetObject<WifiNetDevice> ();
305  if (wifiNetDev == 0)
306  {
307  return false;
308  }
309  Ptr<MeshWifiInterfaceMac> mac = wifiNetDev->GetMac ()->GetObject<MeshWifiInterfaceMac> ();
310  if (mac == 0)
311  {
312  return false;
313  }
314  // Installing plugins:
315  Ptr<FlameProtocolMac> flameMac = Create<FlameProtocolMac> (this);
316  m_interfaces[wifiNetDev->GetIfIndex ()] = flameMac;
317  mac->SetBeaconGeneration (false);
318  mac->InstallPlugin (flameMac);
319  }
320  mp->SetRoutingProtocol (this);
321  // Mesh point aggregates all installed protocols
322  mp->AggregateObject (this);
323  m_address = Mac48Address::ConvertFrom (mp->GetAddress ()); //* address;
324  return true;
325 }
328 {
329  return m_address;
330 }
331 bool
332 FlameProtocol::HandleDataFrame (uint16_t seqno, Mac48Address source, const FlameHeader flameHdr,
333  Mac48Address receiver, uint32_t fromInterface)
334 {
335  if (source == GetAddress ())
336  {
338  return true;
339  }
340  FlameRtable::LookupResult result = m_rtable->Lookup (source);
341  if ((result.retransmitter != Mac48Address::GetBroadcast ()) && ((int16_t)(result.seqnum - seqno) >= 0))
342  {
343  return true;
344  }
345  if (flameHdr.GetCost () > m_maxCost)
346  {
348  return true;
349  }
350  m_rtable->AddPath (source, receiver, fromInterface, flameHdr.GetCost (), flameHdr.GetSeqno ());
351  return false;
352 }
353 //Statistics:
355  txUnicast (0), txBroadcast (0), txBytes (0), droppedTtl (0), totalDropped (0)
356 {
357 }
358 void
359 FlameProtocol::Statistics::Print (std::ostream & os) const
360 {
361  os << "<Statistics "
362  "txUnicast=\"" << txUnicast << "\" "
363  "txBroadcast=\"" << txBroadcast << "\" "
364  "txBytes=\"" << txBytes << "\" "
365  "droppedTtl=\"" << droppedTtl << "\" "
366  "totalDropped=\"" << totalDropped << "\"/>" << std::endl;
367 }
368 void
369 FlameProtocol::Report (std::ostream & os) const
370 {
371  os << "<Flame "
372  "address=\"" << m_address << "\"" << std::endl <<
373  "broadcastInterval=\"" << m_broadcastInterval.GetSeconds () << "\"" << std::endl <<
374  "maxCost=\"" << (uint16_t) m_maxCost << "\">" << std::endl;
375  m_stats.Print (os);
376  for (FlamePluginMap::const_iterator plugin = m_interfaces.begin (); plugin != m_interfaces.end (); plugin++)
377  {
378  plugin->second->Report (os);
379  }
380  os << "</Flame>" << std::endl;
381 }
382 void
384 {
385  m_stats = Statistics ();
386  for (FlamePluginMap::const_iterator plugin = m_interfaces.begin (); plugin != m_interfaces.end (); plugin++)
387  {
388  plugin->second->ResetStats ();
389  }
390 }
391 
392 } // namespace flame
393 } // 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:1176
FLAME routing protocol.
void SetSeqno(uint16_t seqno)
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:44
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 AddPath(const Mac48Address destination, const Mac48Address retransmitter, const uint32_t interface, const uint8_t cost, const uint16_t seqnum)
Add path.
Definition: flame-rtable.cc:65
void Print(std::ostream &os) const
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:824
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:792
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
TAG_BUFFER_INLINE uint8_t ReadU8(void)
Definition: tag-buffer.h:195
uint8_t m_maxCost
Max Cost value (or TTL, because cost is actually hopcount)
void SetProtocol(uint16_t protocol)
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:446
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
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:341
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:846
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
AttributeValue implementation for Time.
Definition: nstime.h:957
Hold an unsigned integer type.
Definition: uinteger.h:44
tuple interfaces
Definition: first.py:41
Hold together all Wifi-related objects.
static Mac48Address GetBroadcast(void)
uint16_t GetSeqno() const
tuple mac
Definition: third.py:92
void AddCost(uint8_t cost)
Definition: flame-header.cc:93
static Mac48Address ConvertFrom(const Address &address)
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:122
tag a set of bytes in a packet
Definition: tag.h:36
Every class exported by the ns3 library is enclosed in the ns3 namespace.
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:43
TAG_BUFFER_INLINE void WriteU8(uint8_t v)
Definition: tag-buffer.h:172
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: nstime.h:958
void CopyFrom(const uint8_t buffer[6])
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:224
Interface for L2 mesh routing protocol and mesh point communication.
void DoDispose()
Destructor implementation.
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:831
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:236
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:895
void Report(std::ostream &) const
Statistics.
TypeId GetInstanceTypeId() const
Get the most derived TypeId for this Object.
Mac48Address receiver
Receiver of the packet:
Ptr< T > CreateObject(void)
Create an object by type, with varying number of constructor parameters.
Definition: object.h:531
static TypeId GetTypeId()
uint16_t m_myLastSeqno
Sequence number:
static const uint16_t FLAME_PROTOCOL
LLC protocol number reserved by flame.
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: uinteger.h:45
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:904
LookupResult Lookup(Mac48Address destination)
Lookup path to destination.
Definition: flame-rtable.cc:88
Basic MAC of mesh point Wi-Fi interface.
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:257
Transmitter and receiver addresses.
Mac48Address transmitter
transmitter for incoming: