From dec333d06370a9230652d1c0a5bc53acd10b339a Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Tue, 9 Oct 2007 12:30:51 +0200 Subject: [PATCH] add MacRxMiddle to build --- src/devices/wifi/mac-rx-middle.cc | 303 ++++++++++++++++++++++++++++++ src/devices/wifi/mac-rx-middle.h | 66 +++++++ src/devices/wifi/wscript | 1 + 3 files changed, 370 insertions(+) create mode 100644 src/devices/wifi/mac-rx-middle.cc create mode 100644 src/devices/wifi/mac-rx-middle.h diff --git a/src/devices/wifi/mac-rx-middle.cc b/src/devices/wifi/mac-rx-middle.cc new file mode 100644 index 000000000..4a384ef30 --- /dev/null +++ b/src/devices/wifi/mac-rx-middle.cc @@ -0,0 +1,303 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2005 INRIA + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Mathieu Lacage + */ + +#include "mac-rx-middle.h" +#include "ns3/packet.h" +#include "wifi-mac-header.h" + +#include +#include + +#define noRX_MIDDLE_TRACE 1 + +#ifdef RX_MIDDLE_TRACE +#include +# define TRACE(x) \ + std::cout <<"RX MIDDLE "< Fragments; + typedef std::list::const_iterator FragmentsCI; + + bool m_defragmenting; + uint16_t m_lastSequenceControl; + Fragments m_fragments; +public: + OriginatorRxStatus () { + /* this is a magic value necessary. */ + m_lastSequenceControl = 0xffff; + m_defragmenting = false; + } + ~OriginatorRxStatus () { + for (FragmentsCI i = m_fragments.begin (); i != m_fragments.end (); i++) + { + // XXX ? + } + m_fragments.erase (m_fragments.begin (), m_fragments.end ()); + } + bool IsDeFragmenting (void) { + return m_defragmenting; + } + void AccumulateFirstFragment (Packet const packet) { + assert (!m_defragmenting); + m_defragmenting = true; + m_fragments.push_back (packet); + } + Packet AccumulateLastFragment (Packet const packet) { + assert (m_defragmenting); + m_fragments.push_back (packet); + m_defragmenting = false; + Packet full; + for (FragmentsCI i = m_fragments.begin (); i != m_fragments.end (); i++) + { + full.AddAtEnd (*i); + } + m_fragments.erase (m_fragments.begin (), m_fragments.end ()); + return full; + } + void AccumulateFragment (Packet const packet) { + assert (m_defragmenting); + m_fragments.push_back (packet); + } + bool IsNextFragment (uint16_t sequenceControl) { + if ((sequenceControl >> 4) == (m_lastSequenceControl >> 4) && + (sequenceControl & 0x0f) == ((m_lastSequenceControl & 0x0f)+1)) + { + return true; + } + else + { + return false; + } + } + uint16_t GetLastSequenceControl (void) + { + return m_lastSequenceControl; + } + void SetSequenceControl (uint16_t sequenceControl) + { + m_lastSequenceControl = sequenceControl; + } + +}; + + +MacRxMiddle::MacRxMiddle () +{} + +MacRxMiddle::~MacRxMiddle () +{ + for (OriginatorsI i = m_originatorStatus.begin (); + i != m_originatorStatus.end (); i++) + { + delete (*i).second; + } + m_originatorStatus.erase (m_originatorStatus.begin (), + m_originatorStatus.end ()); + for (QosOriginatorsI i = m_qosOriginatorStatus.begin (); + i != m_qosOriginatorStatus.end (); i++) + { + delete (*i).second; + } + m_qosOriginatorStatus.erase (m_qosOriginatorStatus.begin (), + m_qosOriginatorStatus.end ()); +} + +void +MacRxMiddle::SetForwardCallback (ForwardUpCallback callback) +{ + m_callback = callback; +} + +bool +MacRxMiddle::SequenceControlSmaller (int seqca, int seqcb) +{ + int seqa = seqca >> 4; + int seqb = seqcb >> 4; + int delta = seqb - seqa; + TRACE ("seqb="<IsNextFragment (hdr->GetSequenceControl ())) + { + TRACE ("accumulate last fragment seq="<GetSequenceNumber ()<< + ", frag="<GetFragmentNumber ()<< + ", size="<GetSize ()); + packet = originator->AccumulateLastFragment (packet); + originator->SetSequenceControl (hdr->GetSequenceControl ()); + *complete = true; + return packet; + } + else + { + TRACE ("non-ordered fragment"); + *complete = false; + return Packet (); + } + } + } + else + { + if (hdr->IsMoreFragments ()) + { + TRACE ("accumulate first fragment seq="<GetSequenceNumber ()<< + ", frag="<GetFragmentNumber ()<< + ", size="<AccumulateFirstFragment (packet); + originator->SetSequenceControl (hdr->GetSequenceControl ()); + *complete = false; + return Packet (); + } + else + { + *complete = true; + return packet; + } + } +} + +void +MacRxMiddle::Receive (Packet packet, WifiMacHeader const *hdr) +{ + OriginatorRxStatus *originator = Lookup (hdr); + if (hdr->IsData ()) + { + assert (SequenceControlSmaller (originator->GetLastSequenceControl (), + hdr->GetSequenceControl ())); + // filter duplicates. + if (IsDuplicate (hdr, originator)) + { + TRACE ("duplicate from="<GetAddr2 ()<< + ", seq="<GetSequenceNumber ()<< + ", frag="<GetFragmentNumber ()); + return; + } + bool complete; + Packet agregate = HandleFragments (packet, hdr, originator, &complete); + if (!complete) + { + return; + } + TRACE ("forwarding data from="<GetAddr2 ()<< + ", seq="<GetSequenceNumber ()<< + ", frag="<GetFragmentNumber ()); + originator->SetSequenceControl (hdr->GetSequenceControl ()); + m_callback (agregate, hdr); + } + else + { + TRACE ("forwarding "<GetTypeString ()<< + ", seq="<GetSequenceNumber ()<< + ", frag="<GetFragmentNumber ()); + originator->SetSequenceControl (hdr->GetSequenceControl ()); + m_callback (packet, hdr); + } +} + +} // namespace ns3 diff --git a/src/devices/wifi/mac-rx-middle.h b/src/devices/wifi/mac-rx-middle.h new file mode 100644 index 000000000..031e3c004 --- /dev/null +++ b/src/devices/wifi/mac-rx-middle.h @@ -0,0 +1,66 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2005 INRIA + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Mathieu Lacage + */ + +#ifndef MAC_RX_MIDDLE_H +#define MAC_RX_MIDDLE_H + +#include +#include +#include "ns3/callback.h" +#include "ns3/mac48-address.h" +#include "ns3/packet.h" + +namespace ns3 { + +class WifiMacHeader; +class OriginatorRxStatus; + +class MacRxMiddle +{ +public: + typedef Callback ForwardUpCallback; + + MacRxMiddle (); + ~MacRxMiddle (); + + void SetForwardCallback (ForwardUpCallback callback); + + void Receive (Packet packet, WifiMacHeader const *hdr); +private: + OriginatorRxStatus *Lookup (WifiMacHeader const*hdr); + bool IsDuplicate (WifiMacHeader const *hdr, OriginatorRxStatus *originator) const; + Packet HandleFragments (Packet packet, WifiMacHeader const*hdr, + OriginatorRxStatus *originator, bool *complete); + bool SequenceControlSmaller (int seqa, int seqb); + + typedef std::map > Originators; + typedef std::map , OriginatorRxStatus *, std::less > > QosOriginators; + typedef std::map >::iterator OriginatorsI; + typedef std::map , OriginatorRxStatus *, std::less > >::iterator QosOriginatorsI; + Originators m_originatorStatus; + QosOriginators m_qosOriginatorStatus; + ForwardUpCallback m_callback; +}; + +} // namespace ns3 + + +#endif /* MAC_RX_MIDDLE_H */ diff --git a/src/devices/wifi/wscript b/src/devices/wifi/wscript index de2e7e3a1..f0af5f073 100644 --- a/src/devices/wifi/wscript +++ b/src/devices/wifi/wscript @@ -20,6 +20,7 @@ def build(bld): 'dcf.cc', 'wifi-mac-queue.cc', 'mac-tx-middle.cc', + 'mac-rx-middle.cc', ] headers = bld.create_obj('ns3header') headers.source = [