A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
flame-protocol.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2009 IITP RAS
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Kirill Andreev <andreev@iitp.ru>
7 */
8
9#include "flame-protocol.h"
10
11#include "flame-header.h"
12#include "flame-protocol-mac.h"
13#include "flame-rtable.h"
14
15#include "ns3/llc-snap-header.h"
16#include "ns3/log.h"
17#include "ns3/mesh-point-device.h"
18#include "ns3/mesh-wifi-interface-mac.h"
19#include "ns3/packet.h"
20#include "ns3/simulator.h"
21#include "ns3/wifi-net-device.h"
22
23namespace ns3
24{
25
26NS_LOG_COMPONENT_DEFINE("FlameProtocol");
27
28namespace flame
29{
30
31//-----------------------------------------------------------------------------
32// FlameTag
33//-----------------------------------------------------------------------------
35NS_OBJECT_ENSURE_REGISTERED(FlameProtocol);
36
37TypeId
39{
40 static TypeId tid = TypeId("ns3::flame::FlameTag")
41 .SetParent<Tag>()
42 .SetGroupName("Mesh")
43 .AddConstructor<FlameTag>();
44 return tid;
45}
46
49{
50 return GetTypeId();
51}
52
55{
56 return 12;
57}
58
59void
61{
62 uint8_t buf[6];
63 receiver.CopyTo(buf);
64 for (int j = 0; j < 6; j++)
65 {
66 i.WriteU8(buf[j]);
67 }
69 for (int j = 0; j < 6; j++)
70 {
71 i.WriteU8(buf[j]);
72 }
73}
74
75void
77{
78 uint8_t buf[6];
79 for (int j = 0; j < 6; j++)
80 {
81 buf[j] = i.ReadU8();
82 }
83 receiver.CopyFrom(buf);
84 for (int j = 0; j < 6; j++)
85 {
86 buf[j] = i.ReadU8();
87 }
89}
90
91void
92FlameTag::Print(std::ostream& os) const
93{
94 os << "receiver = " << receiver << ", transmitter = " << transmitter;
95}
96
97//-----------------------------------------------------------------------------
98// FlameProtocol
99//-----------------------------------------------------------------------------
100TypeId
102{
103 static TypeId tid = TypeId("ns3::flame::FlameProtocol")
105 .SetGroupName("Mesh")
106 .AddConstructor<FlameProtocol>()
107 .AddAttribute("BroadcastInterval",
108 "How often we must send broadcast packets",
109 TimeValue(Seconds(5)),
112 .AddAttribute("MaxCost",
113 "Cost threshold after which packet will be dropped",
114 UintegerValue(32),
117 return tid;
118}
119
121 : m_address(Mac48Address()),
122 m_broadcastInterval(Seconds(5)),
123 m_lastBroadcast(Seconds(0)),
124 m_maxCost(32),
125 m_myLastSeqno(1),
126 m_rtable(CreateObject<FlameRtable>())
127{
128}
129
133
134void
136{
137 m_interfaces.clear();
138 m_rtable = nullptr;
139 m_mp = nullptr;
140}
141
142bool
144 const Mac48Address source,
145 const Mac48Address destination,
146 Ptr<const Packet> const_packet,
147 uint16_t protocolType,
148 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);
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;
180 {
182 }
183 else
184 {
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!
205 source,
206 flameHdr,
207 tag.transmitter,
208 sourceIface));
210 flameHdr.AddCost(1);
211 m_stats.txBytes += packet->GetSize();
212 packet->AddHeader(flameHdr);
213 packet->AddPacketTag(tag);
214 routeReply(true,
215 packet,
216 source,
217 destination,
221 return true;
222 }
223 else
224 {
225 // We check sequence only when forward unicast, because broadcast-checks were done
226 // inside remove routing stuff.
227 if (HandleDataFrame(flameHdr.GetSeqno(),
228 source,
229 flameHdr,
230 tag.transmitter,
231 sourceIface))
232 {
233 return false;
234 }
235 FlameRtable::LookupResult result = m_rtable->Lookup(destination);
237 {
239 {
240 NS_LOG_DEBUG("unicast packet dropped, because no route! I am "
241 << GetAddress() << ", RA = " << tag.receiver
242 << ", TA = " << tag.transmitter);
244 return false;
245 }
246 tag.receiver = result.retransmitter;
247 }
248 else
249 {
251 }
253 {
255 }
256 else
257 {
259 }
260 m_stats.txBytes += packet->GetSize();
261 flameHdr.AddCost(1);
262 packet->AddHeader(flameHdr);
263 packet->AddPacketTag(tag);
264 routeReply(true, packet, source, destination, FLAME_PROTOCOL, result.ifIndex);
265 return true;
266 }
267 return true;
268 }
269 return false;
270}
271
272bool
274 const Mac48Address source,
275 const Mac48Address destination,
276 Ptr<Packet> packet,
277 uint16_t& protocolType)
278{
279 // Filter seqno:
280 if (source == GetAddress())
281 {
282 NS_LOG_DEBUG("Dropped my own frame!");
283 return false;
284 }
285 FlameTag tag;
286 if (!packet->RemovePacketTag(tag))
287 {
288 NS_FATAL_ERROR("FLAME tag must exist when packet is coming to protocol");
289 }
290 FlameHeader flameHdr;
291 packet->RemoveHeader(flameHdr);
292 if (HandleDataFrame(flameHdr.GetSeqno(), source, flameHdr, tag.transmitter, fromIface))
293 {
294 return false;
295 }
296 // Start PATH_UPDATE procedure if destination is our own address and last broadcast was sent
297 // more than broadcast interval ago or was not sent at all
298 if ((destination == GetAddress()) &&
300 (m_lastBroadcast == Seconds(0))))
301 {
302 Ptr<Packet> packet = Create<Packet>();
303 m_mp->Send(packet, Mac48Address::GetBroadcast(), 0);
305 }
306 NS_ASSERT(protocolType == FLAME_PROTOCOL);
307 protocolType = flameHdr.GetProtocol();
308 return true;
309}
310
311bool
313{
314 m_mp = mp;
315 std::vector<Ptr<NetDevice>> interfaces = mp->GetInterfaces();
316 for (auto i = interfaces.begin(); i != interfaces.end(); i++)
317 {
318 // Checking for compatible net device
319 Ptr<WifiNetDevice> wifiNetDev = (*i)->GetObject<WifiNetDevice>();
320 if (!wifiNetDev)
321 {
322 return false;
323 }
324 Ptr<MeshWifiInterfaceMac> mac = wifiNetDev->GetMac()->GetObject<MeshWifiInterfaceMac>();
325 if (!mac)
326 {
327 return false;
328 }
329 // Installing plugins:
331 m_interfaces[wifiNetDev->GetIfIndex()] = flameMac;
332 mac->SetBeaconGeneration(false);
333 mac->InstallPlugin(flameMac);
334 }
335 mp->SetRoutingProtocol(this);
336 // Mesh point aggregates all installed protocols
337 mp->AggregateObject(this);
338 m_address = Mac48Address::ConvertFrom(mp->GetAddress()); //* address;
339 return true;
340}
341
344{
345 return m_address;
346}
347
348bool
350 Mac48Address source,
351 const FlameHeader flameHdr,
352 Mac48Address receiver,
353 uint32_t fromInterface)
354{
355 if (source == GetAddress())
356 {
358 return true;
359 }
360 FlameRtable::LookupResult result = m_rtable->Lookup(source);
361 if ((result.retransmitter != Mac48Address::GetBroadcast()) &&
362 ((int16_t)(result.seqnum - seqno) >= 0))
363 {
364 return true;
365 }
366 if (flameHdr.GetCost() > m_maxCost)
367 {
369 return true;
370 }
371 m_rtable->AddPath(source, receiver, fromInterface, flameHdr.GetCost(), flameHdr.GetSeqno());
372 return false;
373}
374
375// Statistics:
377 : txUnicast(0),
378 txBroadcast(0),
379 txBytes(0),
380 droppedTtl(0),
381 totalDropped(0)
382{
383}
384
385void
386FlameProtocol::Statistics::Print(std::ostream& os) const
387{
388 os << "<Statistics "
389 "txUnicast=\""
390 << txUnicast
391 << "\" "
392 "txBroadcast=\""
393 << txBroadcast
394 << "\" "
395 "txBytes=\""
396 << txBytes
397 << "\" "
398 "droppedTtl=\""
399 << droppedTtl
400 << "\" "
401 "totalDropped=\""
402 << totalDropped << "\"/>" << std::endl;
403}
404
405void
406FlameProtocol::Report(std::ostream& os) const
407{
408 os << "<Flame "
409 "address=\""
410 << m_address << "\"" << std::endl
411 << "broadcastInterval=\"" << m_broadcastInterval.GetSeconds() << "\"" << std::endl
412 << "maxCost=\"" << (uint16_t)m_maxCost << "\">" << std::endl;
413 m_stats.Print(os);
414 for (auto plugin = m_interfaces.begin(); plugin != m_interfaces.end(); plugin++)
415 {
416 plugin->second->Report(os);
417 }
418 os << "</Flame>" << std::endl;
419}
420
421void
423{
425 for (auto plugin = m_interfaces.begin(); plugin != m_interfaces.end(); plugin++)
426 {
427 plugin->second->ResetStats();
428 }
429}
430
431} // namespace flame
432} // namespace ns3
Callback template class.
Definition callback.h:422
an EUI-48 address
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.
Smart pointer class similar to boost::intrusive_ptr.
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
read and write tag data
Definition tag-buffer.h:41
TAG_BUFFER_INLINE void WriteU8(uint8_t v)
Definition tag-buffer.h:161
TAG_BUFFER_INLINE uint8_t ReadU8()
Definition tag-buffer.h:185
tag a set of bytes in a packet
Definition tag.h:28
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition nstime.h:392
a unique identifier for an interface.
Definition type-id.h:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
Hold an unsigned integer type.
Definition uinteger.h:34
Hold together all Wifi-related objects.
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.
static const uint32_t INTERFACE_ANY
Means all interfaces.
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:55
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeUintegerChecker()
Definition uinteger.h:85
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition nstime.h:1396
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition uinteger.h:35
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition nstime.h:1416
uint16_t txBroadcast
transmit broadcast
void Print(std::ostream &os) const
Print function.
Route lookup result, return type of LookupXXX methods.
Mac48Address retransmitter
retransmitter