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-wifi-interface-mac.h"
32
33namespace ns3 {
34
35NS_LOG_COMPONENT_DEFINE ("FlameProtocol");
36
37namespace flame {
38
39//-----------------------------------------------------------------------------
40// FlameTag
41//-----------------------------------------------------------------------------
43NS_OBJECT_ENSURE_REGISTERED (FlameProtocol);
44
45TypeId
47{
48 static TypeId tid = TypeId ("ns3::flame::FlameTag")
49 .SetParent<Tag> ()
50 .SetGroupName ("Mesh")
51 .AddConstructor<FlameTag> ()
52 ;
53 return tid;
54}
55
58{
59 return GetTypeId ();
60}
61
64{
65 return 12;
66}
67
68void
70{
71 uint8_t buf[6];
72 receiver.CopyTo (buf);
73 for (int j = 0; j < 6; j++)
74 {
75 i.WriteU8 (buf[j]);
76 }
77 transmitter.CopyTo (buf);
78 for (int j = 0; j < 6; j++)
79 {
80 i.WriteU8 (buf[j]);
81 }
82
83}
84
85void
87{
88 uint8_t buf[6];
89 for (int j = 0; j < 6; j++)
90 {
91 buf[j] = i.ReadU8 ();
92 }
93 receiver.CopyFrom (buf);
94 for (int j = 0; j < 6; j++)
95 {
96 buf[j] = i.ReadU8 ();
97 }
99
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)),
124 )
125 .AddAttribute ( "MaxCost",
126 "Cost threshold after which packet will be dropped",
127 UintegerValue (32),
130 MakeUintegerChecker<uint8_t> (3)
131 )
132 ;
133 return tid;
134}
136 m_address (Mac48Address ()), m_broadcastInterval (Seconds (5)), m_lastBroadcast (Seconds (0)),
137 m_maxCost (32), m_myLastSeqno (1), m_rtable (CreateObject<FlameRtable> ())
138{
139}
141{
142}
143void
145{
146 m_interfaces.clear ();
147 m_rtable = 0;
148 m_mp = 0;
149}
150bool
151FlameProtocol::RequestRoute (uint32_t sourceIface, const Mac48Address source, const Mac48Address destination,
152 Ptr<const Packet> const_packet, uint16_t protocolType, RouteReplyCallback routeReply)
153{
154 Ptr<Packet> packet = const_packet->Copy ();
155 if (sourceIface == m_mp->GetIfIndex ())
156 {
157 //Packet from upper layer!
158 FlameTag tag;
159 if (packet->PeekPacketTag (tag))
160 {
161 NS_FATAL_ERROR ("FLAME tag is not supposed to be received from upper layers");
162 }
164 if (result.retransmitter == Mac48Address::GetBroadcast ())
165 {
167 }
169 {
170 result.retransmitter = Mac48Address::GetBroadcast ();
173 }
174 FlameHeader flameHdr;
175 flameHdr.AddCost (0);
176 flameHdr.SetSeqno (m_myLastSeqno++);
177 flameHdr.SetProtocol (protocolType);
178 flameHdr.SetOrigDst (destination);
179 flameHdr.SetOrigSrc (source);
180 m_stats.txBytes += packet->GetSize ();
181 packet->AddHeader (flameHdr);
182 tag.receiver = result.retransmitter;
183 if (result.retransmitter == Mac48Address::GetBroadcast ())
184 {
186 }
187 else
188 {
190 }
191 NS_LOG_DEBUG ("Source: send packet with RA = " << tag.receiver);
192 packet->AddPacketTag (tag);
193 routeReply (true, packet, source, destination, FLAME_PROTOCOL, result.ifIndex);
194 }
195 else
196 {
197 FlameHeader flameHdr;
198 packet->RemoveHeader (flameHdr);
199 FlameTag tag;
200
201 if (!packet->RemovePacketTag (tag))
202 {
203 NS_FATAL_ERROR ("FLAME tag must exist here");
204 }
205 if (destination == Mac48Address::GetBroadcast ())
206 {
207 //Broadcast always is forwarded as broadcast!
208 NS_ASSERT (HandleDataFrame (flameHdr.GetSeqno (), source, flameHdr, tag.transmitter, sourceIface));
210 flameHdr.AddCost (1);
211 m_stats.txBytes += packet->GetSize ();
212 packet->AddHeader (flameHdr);
213 packet->AddPacketTag (tag);
214 routeReply (true, packet, source, destination, FLAME_PROTOCOL, FlameRtable::INTERFACE_ANY);
216 return true;
217 }
218 else
219 {
220 // We check sequence only when forward unicast, because broadcast-checks were done
221 // inside remove routing stuff.
222 if (HandleDataFrame (flameHdr.GetSeqno (), source, flameHdr, tag.transmitter, sourceIface))
223 {
224 return false;
225 }
228 {
229 if (result.retransmitter == Mac48Address::GetBroadcast ())
230 {
231 NS_LOG_DEBUG ("unicast packet dropped, because no route! I am " << GetAddress ()
232 << ", RA = " << tag.receiver << ", TA = " << tag.transmitter);
234 return false;
235 }
236 tag.receiver = result.retransmitter;
237 }
238 else
239 {
241 }
242 if (result.retransmitter == Mac48Address::GetBroadcast ())
243 {
245 }
246 else
247 {
249 }
250 m_stats.txBytes += packet->GetSize ();
251 flameHdr.AddCost (1);
252 packet->AddHeader (flameHdr);
253 packet->AddPacketTag (tag);
254 routeReply (true, packet, source, destination, FLAME_PROTOCOL, result.ifIndex);
255 return true;
256 }
257 return true;
258 }
259 return false;
260}
261bool
263 const Mac48Address destination, Ptr<Packet> packet, uint16_t& protocolType)
264{
265 //Filter seqno:
266 if (source == GetAddress ())
267 {
268 NS_LOG_DEBUG ("Dropped my own frame!");
269 return false;
270 }
271 FlameTag tag;
272 if (!packet->RemovePacketTag (tag))
273 {
274 NS_FATAL_ERROR ("FLAME tag must exist when packet is coming to protocol");
275 }
276 FlameHeader flameHdr;
277 packet->RemoveHeader (flameHdr);
278 if (HandleDataFrame (flameHdr.GetSeqno (), source, flameHdr, tag.transmitter, fromIface))
279 {
280 return false;
281 }
282 // Start PATH_UPDATE procedure if destination is our own address and last broadcast was sent more
283 // than broadcast interval ago or was not sent at all
284 if ((destination == GetAddress ()) && ((m_lastBroadcast + m_broadcastInterval < Simulator::Now ())
285 || (m_lastBroadcast == Seconds (0))))
286 {
287 Ptr<Packet> packet = Create<Packet> ();
288 m_mp->Send (packet, Mac48Address::GetBroadcast (), 0);
290 }
291 NS_ASSERT (protocolType == FLAME_PROTOCOL);
292 protocolType = flameHdr.GetProtocol ();
293 return true;
294}
295bool
297{
298 m_mp = mp;
299 std::vector<Ptr<NetDevice> > interfaces = mp->GetInterfaces ();
300 for (std::vector<Ptr<NetDevice> >::const_iterator i = interfaces.begin (); i != interfaces.end (); i++)
301 {
302 // Checking for compatible net device
303 Ptr<WifiNetDevice> wifiNetDev = (*i)->GetObject<WifiNetDevice> ();
304 if (wifiNetDev == 0)
305 {
306 return false;
307 }
308 Ptr<MeshWifiInterfaceMac> mac = wifiNetDev->GetMac ()->GetObject<MeshWifiInterfaceMac> ();
309 if (mac == 0)
310 {
311 return false;
312 }
313 // Installing plugins:
314 Ptr<FlameProtocolMac> flameMac = Create<FlameProtocolMac> (this);
315 m_interfaces[wifiNetDev->GetIfIndex ()] = flameMac;
316 mac->SetBeaconGeneration (false);
317 mac->InstallPlugin (flameMac);
318 }
319 mp->SetRoutingProtocol (this);
320 // Mesh point aggregates all installed protocols
321 mp->AggregateObject (this);
322 m_address = Mac48Address::ConvertFrom (mp->GetAddress ()); //* address;
323 return true;
324}
327{
328 return m_address;
329}
330bool
331FlameProtocol::HandleDataFrame (uint16_t seqno, Mac48Address source, const FlameHeader flameHdr,
332 Mac48Address receiver, uint32_t fromInterface)
333{
334 if (source == GetAddress ())
335 {
337 return true;
338 }
340 if ((result.retransmitter != Mac48Address::GetBroadcast ()) && ((int16_t)(result.seqnum - seqno) >= 0))
341 {
342 return true;
343 }
344 if (flameHdr.GetCost () > m_maxCost)
345 {
347 return true;
348 }
349 m_rtable->AddPath (source, receiver, fromInterface, flameHdr.GetCost (), flameHdr.GetSeqno ());
350 return false;
351}
352//Statistics:
354 txUnicast (0), txBroadcast (0), txBytes (0), droppedTtl (0), totalDropped (0)
355{
356}
357void
358FlameProtocol::Statistics::Print (std::ostream & os) const
359{
360 os << "<Statistics "
361 "txUnicast=\"" << txUnicast << "\" "
362 "txBroadcast=\"" << txBroadcast << "\" "
363 "txBytes=\"" << txBytes << "\" "
364 "droppedTtl=\"" << droppedTtl << "\" "
365 "totalDropped=\"" << totalDropped << "\"/>" << std::endl;
366}
367void
368FlameProtocol::Report (std::ostream & os) const
369{
370 os << "<Flame "
371 "address=\"" << m_address << "\"" << std::endl <<
372 "broadcastInterval=\"" << m_broadcastInterval.GetSeconds () << "\"" << std::endl <<
373 "maxCost=\"" << (uint16_t) m_maxCost << "\">" << std::endl;
374 m_stats.Print (os);
375 for (FlamePluginMap::const_iterator plugin = m_interfaces.begin (); plugin != m_interfaces.end (); plugin++)
376 {
377 plugin->second->Report (os);
378 }
379 os << "</Flame>" << std::endl;
380}
381void
383{
384 m_stats = Statistics ();
385 for (FlamePluginMap::const_iterator plugin = m_interfaces.begin (); plugin != m_interfaces.end (); plugin++)
386 {
387 plugin->second->ResetStats ();
388 }
389}
390
391} // namespace flame
392} // namespace ns3
Callback template class.
Definition: callback.h:1279
an EUI-48 address
Definition: mac48-address.h:44
static Mac48Address GetBroadcast(void)
void CopyFrom(const uint8_t buffer[6])
static Mac48Address ConvertFrom(const Address &address)
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(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:963
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:280
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:956
bool PeekPacketTag(Tag &tag) const
Search a matching tag and call Tag::Deserialize if it is found.
Definition: packet.cc:978
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:856
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
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(void)
Definition: tag-buffer.h:195
tag a set of bytes in a packet
Definition: tag.h:37
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:379
AttributeValue implementation for Time.
Definition: nstime.h:1308
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
Hold an unsigned integer type.
Definition: uinteger.h:44
Hold together all Wifi-related objects.
Ptr< WifiMac > GetMac(void) const
uint32_t GetIfIndex(void) const override
uint8_t GetCost() const
Get cost value.
Definition: flame-header.cc:98
void SetOrigSrc(Mac48Address OrigSrc)
Set origin source function.
void AddCost(uint8_t cost)
Add cost value.
Definition: flame-header.cc:93
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.
Time m_broadcastInterval
Max Cost value (or TTL, because cost is actually hopcount)
void DoDispose()
Destructor implementation.
static TypeId GetTypeId()
Get the type ID.
static const uint16_t FLAME_PROTOCOL
LLC protocol number reserved by flame.
uint16_t m_myLastSeqno
Sequence number:
Ptr< FlameRtable > m_rtable
Routing table:
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.
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.
bool RemoveRoutingStuff(uint32_t fromIface, const Mac48Address source, const Mac48Address destination, Ptr< Packet > packet, uint16_t &protocolType)
Cleanup flame headers!
FlamePluginMap m_interfaces
interfaces
Routing table for FLAME.
Definition: flame-rtable.h:37
LookupResult Lookup(Mac48Address destination)
Lookup path to destination.
Definition: flame-rtable.cc:88
static const uint32_t INTERFACE_ANY
Means all interfaces.
Definition: flame-rtable.h:40
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
Transmitter and receiver addresses.
void Serialize(TagBuffer i) const
void Deserialize(TagBuffer i)
static TypeId GetTypeId()
Get the type ID.
Mac48Address receiver
Receiver of the packet:
TypeId GetInstanceTypeId() const
Get the most derived TypeId for this Object.
Mac48Address transmitter
transmitter for incoming:
void Print(std::ostream &os) const
uint32_t GetSerializedSize() const
#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
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1309
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:45
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition: object.h:576
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
interfaces
Definition: first.py:48
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:536
mac
Definition: third.py:96
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:46