A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
mac-rx-middle.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2005 INRIA
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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 
21 #include "mac-rx-middle.h"
22 #include "wifi-mac-header.h"
23 
24 #include "ns3/assert.h"
25 #include "ns3/log.h"
26 #include "ns3/packet.h"
27 #include "ns3/simulator.h"
28 #include "ns3/sequence-number.h"
29 #include <list>
30 
31 NS_LOG_COMPONENT_DEFINE ("MacRxMiddle");
32 
33 namespace ns3 {
34 
35 
41 {
42 private:
46  typedef std::list<Ptr<const Packet> > Fragments;
50  typedef std::list<Ptr<const Packet> >::const_iterator FragmentsCI;
51 
55 public:
57  {
58  /* this is a magic value necessary. */
59  m_lastSequenceControl = 0xffff;
60  m_defragmenting = false;
61  }
63  {
64  m_fragments.clear ();
65  }
72  bool IsDeFragmenting (void)
73  {
74  return m_defragmenting;
75  }
83  {
85  m_defragmenting = true;
86  m_fragments.push_back (packet);
87  }
98  {
100  m_fragments.push_back (packet);
101  m_defragmenting = false;
102  Ptr<Packet> full = Create<Packet> ();
103  for (FragmentsCI i = m_fragments.begin (); i != m_fragments.end (); i++)
104  {
105  full->AddAtEnd (*i);
106  }
107  m_fragments.erase (m_fragments.begin (), m_fragments.end ());
108  return full;
109  }
117  {
119  m_fragments.push_back (packet);
120  }
129  bool IsNextFragment (uint16_t sequenceControl)
130  {
131  if ((sequenceControl >> 4) == (m_lastSequenceControl >> 4)
132  && (sequenceControl & 0x0f) == ((m_lastSequenceControl & 0x0f) + 1))
133  {
134  return true;
135  }
136  else
137  {
138  return false;
139  }
140  }
146  uint16_t GetLastSequenceControl (void)
147  {
148  return m_lastSequenceControl;
149  }
155  void SetSequenceControl (uint16_t sequenceControl)
156  {
157  m_lastSequenceControl = sequenceControl;
158  }
159 
160 };
161 
162 
164 {
166 }
167 
169 {
171  for (OriginatorsI i = m_originatorStatus.begin ();
172  i != m_originatorStatus.end (); i++)
173  {
174  delete (*i).second;
175  }
176  m_originatorStatus.erase (m_originatorStatus.begin (),
177  m_originatorStatus.end ());
178  for (QosOriginatorsI i = m_qosOriginatorStatus.begin ();
179  i != m_qosOriginatorStatus.end (); i++)
180  {
181  delete (*i).second;
182  }
184  m_qosOriginatorStatus.end ());
185 }
186 
187 void
189 {
191  m_callback = callback;
192 }
193 
196 {
197  NS_LOG_FUNCTION (hdr);
198  OriginatorRxStatus *originator;
199  Mac48Address source = hdr->GetAddr2 ();
200  if (hdr->IsQosData ()
201  && !hdr->GetAddr2 ().IsGroup ())
202  {
203  /* only for qos data non-broadcast frames */
204  originator = m_qosOriginatorStatus[std::make_pair (source, hdr->GetQosTid ())];
205  if (originator == 0)
206  {
207  originator = new OriginatorRxStatus ();
208  m_qosOriginatorStatus[std::make_pair (source, hdr->GetQosTid ())] = originator;
209  }
210  }
211  else
212  {
213  /* - management frames
214  * - qos data broadcast frames
215  * - nqos data frames
216  * see section 7.1.3.4.1
217  */
218  originator = m_originatorStatus[source];
219  if (originator == 0)
220  {
221  originator = new OriginatorRxStatus ();
222  m_originatorStatus[source] = originator;
223  }
224  }
225  return originator;
226 }
227 
228 bool
230  OriginatorRxStatus *originator) const
231 {
232  NS_LOG_FUNCTION (hdr << originator);
233  if (hdr->IsRetry ()
234  && originator->GetLastSequenceControl () == hdr->GetSequenceControl ())
235  {
236  return true;
237  }
238  return false;
239 }
240 
243  OriginatorRxStatus *originator)
244 {
245  NS_LOG_FUNCTION (packet << hdr << originator);
246  if (originator->IsDeFragmenting ())
247  {
248  if (hdr->IsMoreFragments ())
249  {
250  if (originator->IsNextFragment (hdr->GetSequenceControl ()))
251  {
252  NS_LOG_DEBUG ("accumulate fragment seq=" << hdr->GetSequenceNumber () <<
253  ", frag=" << hdr->GetFragmentNumber () <<
254  ", size=" << packet->GetSize ());
255  originator->AccumulateFragment (packet);
256  originator->SetSequenceControl (hdr->GetSequenceControl ());
257  }
258  else
259  {
260  NS_LOG_DEBUG ("non-ordered fragment");
261  }
262  return 0;
263  }
264  else
265  {
266  if (originator->IsNextFragment (hdr->GetSequenceControl ()))
267  {
268  NS_LOG_DEBUG ("accumulate last fragment seq=" << hdr->GetSequenceNumber () <<
269  ", frag=" << hdr->GetFragmentNumber () <<
270  ", size=" << hdr->GetSize ());
271  Ptr<Packet> p = originator->AccumulateLastFragment (packet);
272  originator->SetSequenceControl (hdr->GetSequenceControl ());
273  return p;
274  }
275  else
276  {
277  NS_LOG_DEBUG ("non-ordered fragment");
278  return 0;
279  }
280  }
281  }
282  else
283  {
284  if (hdr->IsMoreFragments ())
285  {
286  NS_LOG_DEBUG ("accumulate first fragment seq=" << hdr->GetSequenceNumber () <<
287  ", frag=" << hdr->GetFragmentNumber () <<
288  ", size=" << packet->GetSize ());
289  originator->AccumulateFirstFragment (packet);
290  originator->SetSequenceControl (hdr->GetSequenceControl ());
291  return 0;
292  }
293  else
294  {
295  return packet;
296  }
297  }
298 }
299 
300 void
302 {
303  NS_LOG_FUNCTION (packet << hdr);
304  NS_ASSERT (hdr->IsData () || hdr->IsMgt ());
305  OriginatorRxStatus *originator = Lookup (hdr);
315  if (!(SequenceNumber16 (originator->GetLastSequenceControl ()) < SequenceNumber16 (hdr->GetSequenceControl ())))
316  {
317  NS_LOG_DEBUG ("Sequence numbers have looped back. last recorded=" << originator->GetLastSequenceControl () <<
318  " currently seen=" << hdr->GetSequenceControl ());
319  }
320  // filter duplicates.
321  if (IsDuplicate (hdr, originator))
322  {
323  NS_LOG_DEBUG ("duplicate from=" << hdr->GetAddr2 () <<
324  ", seq=" << hdr->GetSequenceNumber () <<
325  ", frag=" << hdr->GetFragmentNumber ());
326  return;
327  }
328  Ptr<Packet> agregate = HandleFragments (packet, hdr, originator);
329  if (agregate == 0)
330  {
331  return;
332  }
333  NS_LOG_DEBUG ("forwarding data from=" << hdr->GetAddr2 () <<
334  ", seq=" << hdr->GetSequenceNumber () <<
335  ", frag=" << hdr->GetFragmentNumber ());
336  if (!hdr->GetAddr1 ().IsGroup ())
337  {
338  originator->SetSequenceControl (hdr->GetSequenceControl ());
339  }
340  m_callback (agregate, hdr);
341 }
342 
343 } // namespace ns3
uint16_t GetLastSequenceControl(void)
Return the last sequence control we received.
uint32_t GetSize(void) const
Return the size of the WifiMacHeader in octets.
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:345
uint16_t GetFragmentNumber(void) const
Return the fragment number of the header.
void AccumulateFirstFragment(Ptr< const Packet > packet)
We have received a first fragmented packet.
void SetForwardCallback(ForwardUpCallback callback)
Set a callback to forward the packet up.
#define NS_ASSERT(condition)
Definition: assert.h:64
uint32_t GetSize(void) const
Definition: packet.h:650
std::map< std::pair< Mac48Address, uint8_t >, OriginatorRxStatus *, std::less< std::pair< Mac48Address, uint8_t > > >::iterator QosOriginatorsI
typedef for an interator for QosOriginators
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Definition: log.h:309
void Receive(Ptr< Packet > packet, const WifiMacHeader *hdr)
Ptr< Packet > HandleFragments(Ptr< Packet > packet, const WifiMacHeader *hdr, OriginatorRxStatus *originator)
Check if the received packet is a fragment and handle it appropriately.
bool IsMoreFragments(void) const
Return if the More Fragment bit is set.
std::map< Mac48Address, OriginatorRxStatus *, std::less< Mac48Address > >::iterator OriginatorsI
typedef for an interator for Originators
void AccumulateFragment(Ptr< const Packet > packet)
We received a fragmented packet (not first and not last).
uint8_t GetQosTid(void) const
Return the Traffic ID of a QoS header.
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
Definition: packet.cc:317
OriginatorRxStatus * Lookup(const WifiMacHeader *hdr)
Look up for OriginatorRxStatus associated with the sender address (by looking at ADDR2 field in the h...
uint16_t GetSequenceControl(void) const
Return the raw Sequence Control field.
Originators m_originatorStatus
bool IsNextFragment(uint16_t sequenceControl)
Check if the sequence control (i.e.
bool IsDuplicate(const WifiMacHeader *hdr, OriginatorRxStatus *originator) const
Check if we have already received the packet from the sender before (by looking at the sequence contr...
bool IsMgt(void) const
Return true if the Type is Management.
Generic "sequence number" class.
bool IsGroup(void) const
Ptr< Packet > AccumulateLastFragment(Ptr< const Packet > packet)
We have received a last fragment of the fragmented packets (indicated by the no more fragment field)...
void SetSequenceControl(uint16_t sequenceControl)
Set the last sequence control we received.
an EUI-48 address
Definition: mac48-address.h:41
bool IsDeFragmenting(void)
Check if we are de-fragmenting packets.
std::list< Ptr< const Packet > > Fragments
typedef for a list of fragments (i.e.
bool IsData(void) const
Return true if the Type is DATA.
bool IsQosData(void) const
Return true if the Type is DATA and Subtype is one of the possible values for QoS DATA...
ForwardUpCallback m_callback
#define NS_LOG_DEBUG(msg)
Definition: log.h:289
std::list< Ptr< const Packet > >::const_iterator FragmentsCI
typedef for a const iterator for Fragments
Mac48Address GetAddr1(void) const
Return the address in the Address 1 field.
A class to keep track of the packet originator status.
NS_LOG_COMPONENT_DEFINE("MacRxMiddle")
QosOriginators m_qosOriginatorStatus
bool IsRetry(void) const
Return if the Retry bit is set.
Implements the IEEE 802.11 MAC header.
Mac48Address GetAddr2(void) const
Return the address in the Address 2 field.
uint16_t GetSequenceNumber(void) const
Return the sequence number of the header.