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 * 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
34namespace ns3
35{
36
37NS_LOG_COMPONENT_DEFINE("FlameProtocol");
38
39namespace flame
40{
41
42//-----------------------------------------------------------------------------
43// FlameTag
44//-----------------------------------------------------------------------------
46NS_OBJECT_ENSURE_REGISTERED(FlameProtocol);
47
48TypeId
50{
51 static TypeId tid = TypeId("ns3::flame::FlameTag")
52 .SetParent<Tag>()
53 .SetGroupName("Mesh")
54 .AddConstructor<FlameTag>();
55 return tid;
56}
57
60{
61 return GetTypeId();
62}
63
66{
67 return 12;
68}
69
70void
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 }
80 for (int j = 0; j < 6; j++)
81 {
82 i.WriteU8(buf[j]);
83 }
84}
85
86void
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 }
100}
101
102void
103FlameTag::Print(std::ostream& os) const
104{
105 os << "receiver = " << receiver << ", transmitter = " << transmitter;
106}
107
108//-----------------------------------------------------------------------------
109// FlameProtocol
110//-----------------------------------------------------------------------------
111TypeId
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)),
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
145void
147{
148 m_interfaces.clear();
149 m_rtable = nullptr;
150 m_mp = nullptr;
151}
152
153bool
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 {
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 {
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
283bool
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
322bool
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 }
335 Ptr<MeshWifiInterfaceMac> mac = wifiNetDev->GetMac()->GetObject<MeshWifiInterfaceMac>();
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
359bool
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
396void
397FlameProtocol::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
416void
417FlameProtocol::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
432void
434{
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.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
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
AttributeValue implementation for Time.
Definition: nstime.h:1413
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
Hold an unsigned integer type.
Definition: uinteger.h:45
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.
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
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition: nstime.h:1434
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1414
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
#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:630
#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
Every class exported by the ns3 library is enclosed in the ns3 namespace.
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