A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
mac-rx-middle.cc
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 
37 {
38 private:
39  typedef std::list<Ptr<const Packet> > Fragments;
40  typedef std::list<Ptr<const Packet> >::const_iterator FragmentsCI;
41 
42  bool m_defragmenting;
43  uint16_t m_lastSequenceControl;
44  Fragments m_fragments;
45 public:
47  {
48  /* this is a magic value necessary. */
49  m_lastSequenceControl = 0xffff;
50  m_defragmenting = false;
51  }
53  {
54  m_fragments.clear ();
55  }
56  bool IsDeFragmenting (void)
57  {
58  return m_defragmenting;
59  }
60  void AccumulateFirstFragment (Ptr<const Packet> packet)
61  {
62  NS_ASSERT (!m_defragmenting);
63  m_defragmenting = true;
64  m_fragments.push_back (packet);
65  }
66  Ptr<Packet> AccumulateLastFragment (Ptr<const Packet> packet)
67  {
68  NS_ASSERT (m_defragmenting);
69  m_fragments.push_back (packet);
70  m_defragmenting = false;
71  Ptr<Packet> full = Create<Packet> ();
72  for (FragmentsCI i = m_fragments.begin (); i != m_fragments.end (); i++)
73  {
74  full->AddAtEnd (*i);
75  }
76  m_fragments.erase (m_fragments.begin (), m_fragments.end ());
77  return full;
78  }
79  void AccumulateFragment (Ptr<const Packet> packet)
80  {
81  NS_ASSERT (m_defragmenting);
82  m_fragments.push_back (packet);
83  }
84  bool IsNextFragment (uint16_t sequenceControl)
85  {
86  if ((sequenceControl >> 4) == (m_lastSequenceControl >> 4)
87  && (sequenceControl & 0x0f) == ((m_lastSequenceControl & 0x0f) + 1))
88  {
89  return true;
90  }
91  else
92  {
93  return false;
94  }
95  }
96  uint16_t GetLastSequenceControl (void)
97  {
98  return m_lastSequenceControl;
99  }
100  void SetSequenceControl (uint16_t sequenceControl)
101  {
102  m_lastSequenceControl = sequenceControl;
103  }
104 
105 };
106 
107 
108 MacRxMiddle::MacRxMiddle ()
109 {
111 }
112 
113 MacRxMiddle::~MacRxMiddle ()
114 {
116  for (OriginatorsI i = m_originatorStatus.begin ();
117  i != m_originatorStatus.end (); i++)
118  {
119  delete (*i).second;
120  }
121  m_originatorStatus.erase (m_originatorStatus.begin (),
122  m_originatorStatus.end ());
123  for (QosOriginatorsI i = m_qosOriginatorStatus.begin ();
124  i != m_qosOriginatorStatus.end (); i++)
125  {
126  delete (*i).second;
127  }
128  m_qosOriginatorStatus.erase (m_qosOriginatorStatus.begin (),
129  m_qosOriginatorStatus.end ());
130 }
131 
132 void
133 MacRxMiddle::SetForwardCallback (ForwardUpCallback callback)
134 {
136  m_callback = callback;
137 }
138 
139 OriginatorRxStatus *
140 MacRxMiddle::Lookup (const WifiMacHeader *hdr)
141 {
142  NS_LOG_FUNCTION (hdr);
143  OriginatorRxStatus *originator;
144  Mac48Address source = hdr->GetAddr2 ();
145  if (hdr->IsQosData ()
146  && !hdr->GetAddr2 ().IsGroup ())
147  {
148  /* only for qos data non-broadcast frames */
149  originator = m_qosOriginatorStatus[std::make_pair (source, hdr->GetQosTid ())];
150  if (originator == 0)
151  {
152  originator = new OriginatorRxStatus ();
153  m_qosOriginatorStatus[std::make_pair (source, hdr->GetQosTid ())] = originator;
154  }
155  }
156  else
157  {
158  /* - management frames
159  * - qos data broadcast frames
160  * - nqos data frames
161  * see section 7.1.3.4.1
162  */
163  originator = m_originatorStatus[source];
164  if (originator == 0)
165  {
166  originator = new OriginatorRxStatus ();
167  m_originatorStatus[source] = originator;
168  }
169  }
170  return originator;
171 }
172 
173 bool
174 MacRxMiddle::IsDuplicate (const WifiMacHeader* hdr,
175  OriginatorRxStatus *originator) const
176 {
177  NS_LOG_FUNCTION (hdr << originator);
178  if (hdr->IsRetry ()
179  && originator->GetLastSequenceControl () == hdr->GetSequenceControl ())
180  {
181  return true;
182  }
183  return false;
184 }
185 
186 Ptr<Packet>
187 MacRxMiddle::HandleFragments (Ptr<Packet> packet, const WifiMacHeader *hdr,
188  OriginatorRxStatus *originator)
189 {
190  NS_LOG_FUNCTION (packet << hdr << originator);
191  if (originator->IsDeFragmenting ())
192  {
193  if (hdr->IsMoreFragments ())
194  {
195  if (originator->IsNextFragment (hdr->GetSequenceControl ()))
196  {
197  NS_LOG_DEBUG ("accumulate fragment seq=" << hdr->GetSequenceNumber () <<
198  ", frag=" << hdr->GetFragmentNumber () <<
199  ", size=" << packet->GetSize ());
200  originator->AccumulateFragment (packet);
201  originator->SetSequenceControl (hdr->GetSequenceControl ());
202  }
203  else
204  {
205  NS_LOG_DEBUG ("non-ordered fragment");
206  }
207  return 0;
208  }
209  else
210  {
211  if (originator->IsNextFragment (hdr->GetSequenceControl ()))
212  {
213  NS_LOG_DEBUG ("accumulate last fragment seq=" << hdr->GetSequenceNumber () <<
214  ", frag=" << hdr->GetFragmentNumber () <<
215  ", size=" << hdr->GetSize ());
216  Ptr<Packet> p = originator->AccumulateLastFragment (packet);
217  originator->SetSequenceControl (hdr->GetSequenceControl ());
218  return p;
219  }
220  else
221  {
222  NS_LOG_DEBUG ("non-ordered fragment");
223  return 0;
224  }
225  }
226  }
227  else
228  {
229  if (hdr->IsMoreFragments ())
230  {
231  NS_LOG_DEBUG ("accumulate first fragment seq=" << hdr->GetSequenceNumber () <<
232  ", frag=" << hdr->GetFragmentNumber () <<
233  ", size=" << packet->GetSize ());
234  originator->AccumulateFirstFragment (packet);
235  originator->SetSequenceControl (hdr->GetSequenceControl ());
236  return 0;
237  }
238  else
239  {
240  return packet;
241  }
242  }
243 }
244 
245 void
247 {
248  NS_LOG_FUNCTION (packet << hdr);
249  NS_ASSERT (hdr->IsData () || hdr->IsMgt ());
250  OriginatorRxStatus *originator = Lookup (hdr);
260  if (!(SequenceNumber16 (originator->GetLastSequenceControl ()) < SequenceNumber16 (hdr->GetSequenceControl ())))
261  {
262  NS_LOG_DEBUG ("Sequence numbers have looped back. last recorded=" << originator->GetLastSequenceControl () <<
263  " currently seen=" << hdr->GetSequenceControl ());
264  }
265  // filter duplicates.
266  if (IsDuplicate (hdr, originator))
267  {
268  NS_LOG_DEBUG ("duplicate from=" << hdr->GetAddr2 () <<
269  ", seq=" << hdr->GetSequenceNumber () <<
270  ", frag=" << hdr->GetFragmentNumber ());
271  return;
272  }
273  Ptr<Packet> agregate = HandleFragments (packet, hdr, originator);
274  if (agregate == 0)
275  {
276  return;
277  }
278  NS_LOG_DEBUG ("forwarding data from=" << hdr->GetAddr2 () <<
279  ", seq=" << hdr->GetSequenceNumber () <<
280  ", frag=" << hdr->GetFragmentNumber ());
281  if (!hdr->GetAddr1 ().IsGroup ())
282  {
283  originator->SetSequenceControl (hdr->GetSequenceControl ());
284  }
285  m_callback (agregate, hdr);
286 }
287 
288 } // namespace ns3
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
#define NS_ASSERT(condition)
Definition: assert.h:64
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
#define NS_LOG_FUNCTION_NOARGS()
Definition: log.h:275
void Receive(Ptr< Packet > packet, const WifiMacHeader *hdr)
void AddAtEnd(Ptr< const Packet > packet)
Definition: packet.cc:334
Generic "sequence number" class.
bool IsGroup(void) const
#define NS_LOG_DEBUG(msg)
Definition: log.h:255