A Discrete-Event Network Simulator
API
flame-protocol.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009 IITP RAS
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Kirill Andreev <andreev@iitp.ru>
18  */
19 
20 #include "flame-protocol.h"
21 
22 #include "flame-header.h"
23 #include "flame-protocol-mac.h"
24 #include "flame-rtable.h"
25 
26 #include "ns3/llc-snap-header.h"
27 #include "ns3/log.h"
28 #include "ns3/mesh-point-device.h"
29 #include "ns3/mesh-wifi-interface-mac.h"
30 #include "ns3/packet.h"
31 #include "ns3/simulator.h"
32 #include "ns3/wifi-net-device.h"
33 
34 namespace ns3
35 {
36 
37 NS_LOG_COMPONENT_DEFINE("FlameProtocol");
38 
39 namespace flame
40 {
41 
42 //-----------------------------------------------------------------------------
43 // FlameTag
44 //-----------------------------------------------------------------------------
46 NS_OBJECT_ENSURE_REGISTERED(FlameProtocol);
47 
48 TypeId
50 {
51  static TypeId tid = TypeId("ns3::flame::FlameTag")
52  .SetParent<Tag>()
53  .SetGroupName("Mesh")
54  .AddConstructor<FlameTag>();
55  return tid;
56 }
57 
58 TypeId
60 {
61  return GetTypeId();
62 }
63 
64 uint32_t
66 {
67  return 12;
68 }
69 
70 void
72 {
73  uint8_t buf[6];
74  receiver.CopyTo(buf);
75  for (int j = 0; j < 6; j++)
76  {
77  i.WriteU8(buf[j]);
78  }
79  transmitter.CopyTo(buf);
80  for (int j = 0; j < 6; j++)
81  {
82  i.WriteU8(buf[j]);
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 void
103 FlameTag::Print(std::ostream& os) const
104 {
105  os << "receiver = " << receiver << ", transmitter = " << transmitter;
106 }
107 
108 //-----------------------------------------------------------------------------
109 // FlameProtocol
110 //-----------------------------------------------------------------------------
111 TypeId
113 {
114  static TypeId tid = TypeId("ns3::flame::FlameProtocol")
116  .SetGroupName("Mesh")
117  .AddConstructor<FlameProtocol>()
118  .AddAttribute("BroadcastInterval",
119  "How often we must send broadcast packets",
120  TimeValue(Seconds(5)),
122  MakeTimeChecker())
123  .AddAttribute("MaxCost",
124  "Cost threshold after which packet will be dropped",
125  UintegerValue(32),
127  MakeUintegerChecker<uint8_t>(3));
128  return tid;
129 }
130 
132  : m_address(Mac48Address()),
133  m_broadcastInterval(Seconds(5)),
134  m_lastBroadcast(Seconds(0)),
135  m_maxCost(32),
136  m_myLastSeqno(1),
137  m_rtable(CreateObject<FlameRtable>())
138 {
139 }
140 
142 {
143 }
144 
145 void
147 {
148  m_interfaces.clear();
149  m_rtable = nullptr;
150  m_mp = nullptr;
151 }
152 
153 bool
154 FlameProtocol::RequestRoute(uint32_t sourceIface,
155  const Mac48Address source,
156  const Mac48Address destination,
157  Ptr<const Packet> const_packet,
158  uint16_t protocolType,
159  RouteReplyCallback routeReply)
160 {
161  Ptr<Packet> packet = const_packet->Copy();
162  if (sourceIface == m_mp->GetIfIndex())
163  {
164  // Packet from upper layer!
165  FlameTag tag;
166  if (packet->PeekPacketTag(tag))
167  {
168  NS_FATAL_ERROR("FLAME tag is not supposed to be received from upper layers");
169  }
170  FlameRtable::LookupResult result = m_rtable->Lookup(destination);
172  {
174  }
176  {
180  }
181  FlameHeader flameHdr;
182  flameHdr.AddCost(0);
183  flameHdr.SetSeqno(m_myLastSeqno++);
184  flameHdr.SetProtocol(protocolType);
185  flameHdr.SetOrigDst(destination);
186  flameHdr.SetOrigSrc(source);
187  m_stats.txBytes += packet->GetSize();
188  packet->AddHeader(flameHdr);
189  tag.receiver = result.retransmitter;
191  {
193  }
194  else
195  {
196  m_stats.txUnicast++;
197  }
198  NS_LOG_DEBUG("Source: send packet with RA = " << tag.receiver);
199  packet->AddPacketTag(tag);
200  routeReply(true, packet, source, destination, FLAME_PROTOCOL, result.ifIndex);
201  }
202  else
203  {
204  FlameHeader flameHdr;
205  packet->RemoveHeader(flameHdr);
206  FlameTag tag;
207 
208  if (!packet->RemovePacketTag(tag))
209  {
210  NS_FATAL_ERROR("FLAME tag must exist here");
211  }
212  if (destination == Mac48Address::GetBroadcast())
213  {
214  // Broadcast always is forwarded as broadcast!
216  source,
217  flameHdr,
218  tag.transmitter,
219  sourceIface));
221  flameHdr.AddCost(1);
222  m_stats.txBytes += packet->GetSize();
223  packet->AddHeader(flameHdr);
224  packet->AddPacketTag(tag);
225  routeReply(true,
226  packet,
227  source,
228  destination,
232  return true;
233  }
234  else
235  {
236  // We check sequence only when forward unicast, because broadcast-checks were done
237  // inside remove routing stuff.
238  if (HandleDataFrame(flameHdr.GetSeqno(),
239  source,
240  flameHdr,
241  tag.transmitter,
242  sourceIface))
243  {
244  return false;
245  }
246  FlameRtable::LookupResult result = m_rtable->Lookup(destination);
248  {
250  {
251  NS_LOG_DEBUG("unicast packet dropped, because no route! I am "
252  << GetAddress() << ", RA = " << tag.receiver
253  << ", TA = " << tag.transmitter);
255  return false;
256  }
257  tag.receiver = result.retransmitter;
258  }
259  else
260  {
262  }
264  {
266  }
267  else
268  {
269  m_stats.txUnicast++;
270  }
271  m_stats.txBytes += packet->GetSize();
272  flameHdr.AddCost(1);
273  packet->AddHeader(flameHdr);
274  packet->AddPacketTag(tag);
275  routeReply(true, packet, source, destination, FLAME_PROTOCOL, result.ifIndex);
276  return true;
277  }
278  return true;
279  }
280  return false;
281 }
282 
283 bool
285  const Mac48Address source,
286  const Mac48Address destination,
287  Ptr<Packet> packet,
288  uint16_t& protocolType)
289 {
290  // Filter seqno:
291  if (source == GetAddress())
292  {
293  NS_LOG_DEBUG("Dropped my own frame!");
294  return false;
295  }
296  FlameTag tag;
297  if (!packet->RemovePacketTag(tag))
298  {
299  NS_FATAL_ERROR("FLAME tag must exist when packet is coming to protocol");
300  }
301  FlameHeader flameHdr;
302  packet->RemoveHeader(flameHdr);
303  if (HandleDataFrame(flameHdr.GetSeqno(), source, flameHdr, tag.transmitter, fromIface))
304  {
305  return false;
306  }
307  // Start PATH_UPDATE procedure if destination is our own address and last broadcast was sent
308  // more than broadcast interval ago or was not sent at all
309  if ((destination == GetAddress()) &&
311  (m_lastBroadcast == Seconds(0))))
312  {
313  Ptr<Packet> packet = Create<Packet>();
314  m_mp->Send(packet, Mac48Address::GetBroadcast(), 0);
316  }
317  NS_ASSERT(protocolType == FLAME_PROTOCOL);
318  protocolType = flameHdr.GetProtocol();
319  return true;
320 }
321 
322 bool
324 {
325  m_mp = mp;
326  std::vector<Ptr<NetDevice>> interfaces = mp->GetInterfaces();
327  for (auto i = interfaces.begin(); i != interfaces.end(); i++)
328  {
329  // Checking for compatible net device
330  Ptr<WifiNetDevice> wifiNetDev = (*i)->GetObject<WifiNetDevice>();
331  if (!wifiNetDev)
332  {
333  return false;
334  }
336  if (!mac)
337  {
338  return false;
339  }
340  // Installing plugins:
341  Ptr<FlameProtocolMac> flameMac = Create<FlameProtocolMac>(this);
342  m_interfaces[wifiNetDev->GetIfIndex()] = flameMac;
343  mac->SetBeaconGeneration(false);
344  mac->InstallPlugin(flameMac);
345  }
346  mp->SetRoutingProtocol(this);
347  // Mesh point aggregates all installed protocols
348  mp->AggregateObject(this);
349  m_address = Mac48Address::ConvertFrom(mp->GetAddress()); //* address;
350  return true;
351 }
352 
355 {
356  return m_address;
357 }
358 
359 bool
361  Mac48Address source,
362  const FlameHeader flameHdr,
363  Mac48Address receiver,
364  uint32_t fromInterface)
365 {
366  if (source == GetAddress())
367  {
369  return true;
370  }
371  FlameRtable::LookupResult result = m_rtable->Lookup(source);
372  if ((result.retransmitter != Mac48Address::GetBroadcast()) &&
373  ((int16_t)(result.seqnum - seqno) >= 0))
374  {
375  return true;
376  }
377  if (flameHdr.GetCost() > m_maxCost)
378  {
380  return true;
381  }
382  m_rtable->AddPath(source, receiver, fromInterface, flameHdr.GetCost(), flameHdr.GetSeqno());
383  return false;
384 }
385 
386 // Statistics:
388  : txUnicast(0),
389  txBroadcast(0),
390  txBytes(0),
391  droppedTtl(0),
392  totalDropped(0)
393 {
394 }
395 
396 void
397 FlameProtocol::Statistics::Print(std::ostream& os) const
398 {
399  os << "<Statistics "
400  "txUnicast=\""
401  << txUnicast
402  << "\" "
403  "txBroadcast=\""
404  << txBroadcast
405  << "\" "
406  "txBytes=\""
407  << txBytes
408  << "\" "
409  "droppedTtl=\""
410  << droppedTtl
411  << "\" "
412  "totalDropped=\""
413  << totalDropped << "\"/>" << std::endl;
414 }
415 
416 void
417 FlameProtocol::Report(std::ostream& os) const
418 {
419  os << "<Flame "
420  "address=\""
421  << m_address << "\"" << std::endl
422  << "broadcastInterval=\"" << m_broadcastInterval.GetSeconds() << "\"" << std::endl
423  << "maxCost=\"" << (uint16_t)m_maxCost << "\">" << std::endl;
424  m_stats.Print(os);
425  for (auto plugin = m_interfaces.begin(); plugin != m_interfaces.end(); plugin++)
426  {
427  plugin->second->Report(os);
428  }
429  os << "</Flame>" << std::endl;
430 }
431 
432 void
434 {
435  m_stats = Statistics();
436  for (auto plugin = m_interfaces.begin(); plugin != m_interfaces.end(); plugin++)
437  {
438  plugin->second->ResetStats();
439  }
440 }
441 
442 } // namespace flame
443 } // namespace ns3
Callback template class.
Definition: callback.h:438
an EUI-48 address
Definition: mac48-address.h:46
void CopyFrom(const uint8_t buffer[6])
static Mac48Address ConvertFrom(const Address &address)
static Mac48Address GetBroadcast()
void CopyTo(uint8_t buffer[6]) const
Interface for L2 mesh routing protocol and mesh point communication.
Ptr< MeshPointDevice > m_mp
Host mesh point.
Basic MAC of mesh point Wi-Fi interface.
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:967
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:294
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:268
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:861
Ptr< Packet > Copy() const
performs a COW copy of the packet.
Definition: packet.cc:131
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:960
bool PeekPacketTag(Tag &tag) const
Search a matching tag and call Tag::Deserialize if it is found.
Definition: packet.cc:983
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
read and write tag data
Definition: tag-buffer.h:52
TAG_BUFFER_INLINE void WriteU8(uint8_t v)
Definition: tag-buffer.h:172
TAG_BUFFER_INLINE uint8_t ReadU8()
Definition: tag-buffer.h:196
tag a set of bytes in a packet
Definition: tag.h:39
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:403
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
Hold an unsigned integer type.
Definition: uinteger.h:45
Hold together all Wifi-related objects.
Ptr< WifiMac > GetMac() const
uint32_t GetIfIndex() const override
uint8_t GetCost() const
Get cost value.
void SetOrigSrc(Mac48Address OrigSrc)
Set origin source function.
void AddCost(uint8_t cost)
Add cost value.
uint16_t GetSeqno() const
Get sequence number value.
void SetOrigDst(Mac48Address dst)
Set origin destination address.
void SetProtocol(uint16_t protocol)
Set protocol value.
uint16_t GetProtocol() const
Get protocol value.
void SetSeqno(uint16_t seqno)
Set sequence number value.
FLAME routing protocol.
bool RemoveRoutingStuff(uint32_t fromIface, const Mac48Address source, const Mac48Address destination, Ptr< Packet > packet, uint16_t &protocolType) override
Cleanup flame headers!
Time m_broadcastInterval
Max Cost value (or TTL, because cost is actually hopcount)
void DoDispose() override
Destructor implementation.
static TypeId GetTypeId()
Get the type ID.
static const uint16_t FLAME_PROTOCOL
LLC protocol number reserved by flame.
bool RequestRoute(uint32_t sourceIface, const Mac48Address source, const Mac48Address destination, Ptr< const Packet > packet, uint16_t protocolType, RouteReplyCallback routeReply) override
Route request, inherited from MeshL2RoutingProtocol.
uint16_t m_myLastSeqno
Sequence number:
Ptr< FlameRtable > m_rtable
Routing table:
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.
Mac48Address GetAddress()
Get address of this instance.
uint8_t m_maxCost
Max Cost value (or TTL, because cost is actually hopcount)
bool Install(Ptr< MeshPointDevice > mp)
Install FLAME on given mesh point.
Time m_lastBroadcast
Max Cost value (or TTL, because cost is actually hopcount)
Statistics m_stats
statistics
Mac48Address m_address
address
void ResetStats()
Reset statistics function.
void Report(std::ostream &os) const
Statistics.
FlamePluginMap m_interfaces
interfaces
Routing table for FLAME.
Definition: flame-rtable.h:39
LookupResult Lookup(Mac48Address destination)
Lookup path to destination.
Definition: flame-rtable.cc:94
static const uint32_t INTERFACE_ANY
Means all interfaces.
Definition: flame-rtable.h:42
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:67
Transmitter and receiver addresses.
TypeId GetInstanceTypeId() const override
Get the most derived TypeId for this Object.
void Serialize(TagBuffer i) const override
void Print(std::ostream &os) const override
uint32_t GetSerializedSize() const override
static TypeId GetTypeId()
Get the type ID.
Mac48Address receiver
Receiver of the packet:
Mac48Address transmitter
transmitter for incoming:
void Deserialize(TagBuffer i) override
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition: object.h:579
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
interfaces
Definition: first.py:50
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1414
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:533
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
mac
Definition: third.py:92
uint16_t txBroadcast
transmit broadcast
uint16_t txUnicast
transmit unicast
void Print(std::ostream &os) const
Print function.
Route lookup result, return type of LookupXXX methods.
Definition: flame-rtable.h:48
uint16_t seqnum
sequence number
Definition: flame-rtable.h:52
Mac48Address retransmitter
retransmitter
Definition: flame-rtable.h:49