add MacRxMiddle to build
This commit is contained in:
303
src/devices/wifi/mac-rx-middle.cc
Normal file
303
src/devices/wifi/mac-rx-middle.cc
Normal file
@@ -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 <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
|
||||
#include "mac-rx-middle.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "wifi-mac-header.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <list>
|
||||
|
||||
#define noRX_MIDDLE_TRACE 1
|
||||
|
||||
#ifdef RX_MIDDLE_TRACE
|
||||
#include <iostream>
|
||||
# define TRACE(x) \
|
||||
std::cout <<"RX MIDDLE "<<x<<std::endl;
|
||||
#else /* RX_MIDDLE_TRACE */
|
||||
# define TRACE(x)
|
||||
#endif /* RX_MIDDLE_TRACE */
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
|
||||
class OriginatorRxStatus {
|
||||
private:
|
||||
typedef std::list<Packet> Fragments;
|
||||
typedef std::list<Packet>::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="<<seqb<<", seqa="<<seqa<<", delta="<<delta);
|
||||
if (delta <= 0 && delta < -2048)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (delta >= 0 && delta < 2048)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
OriginatorRxStatus *
|
||||
MacRxMiddle::Lookup (WifiMacHeader const *hdr)
|
||||
{
|
||||
OriginatorRxStatus *originator;
|
||||
Mac48Address source = hdr->GetAddr2 ();
|
||||
if (hdr->IsQosData () &&
|
||||
!hdr->GetAddr2 ().IsBroadcast ())
|
||||
{
|
||||
/* only for qos data non-broadcast frames */
|
||||
originator = m_qosOriginatorStatus[std::make_pair(source, hdr->GetQosTid ())];
|
||||
if (originator == 0)
|
||||
{
|
||||
originator = new OriginatorRxStatus ();
|
||||
m_qosOriginatorStatus[std::make_pair(source, hdr->GetQosTid ())] = originator;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* - management frames
|
||||
* - qos data broadcast frames
|
||||
* - nqos data frames
|
||||
* see section 7.1.3.4.1
|
||||
*/
|
||||
originator = m_originatorStatus[source];
|
||||
if (originator == 0)
|
||||
{
|
||||
originator = new OriginatorRxStatus ();
|
||||
m_originatorStatus[source] = originator;
|
||||
}
|
||||
}
|
||||
return originator;
|
||||
}
|
||||
|
||||
bool
|
||||
MacRxMiddle::IsDuplicate (WifiMacHeader const*hdr,
|
||||
OriginatorRxStatus *originator) const
|
||||
{
|
||||
if (originator->GetLastSequenceControl () == hdr->GetSequenceControl ())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Packet
|
||||
MacRxMiddle::HandleFragments (Packet packet, WifiMacHeader const*hdr,
|
||||
OriginatorRxStatus *originator, bool *complete)
|
||||
{
|
||||
if (originator->IsDeFragmenting ())
|
||||
{
|
||||
if (hdr->IsMoreFragments ())
|
||||
{
|
||||
if (originator->IsNextFragment (hdr->GetSequenceControl ()))
|
||||
{
|
||||
TRACE ("accumulate fragment seq="<<hdr->GetSequenceNumber ()<<
|
||||
", frag="<<hdr->GetFragmentNumber ()<<
|
||||
", size="<<packet.GetSize ());
|
||||
originator->AccumulateFragment (packet);
|
||||
originator->SetSequenceControl (hdr->GetSequenceControl ());
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE ("non-ordered fragment");
|
||||
}
|
||||
*complete = false;
|
||||
return Packet ();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (originator->IsNextFragment (hdr->GetSequenceControl ()))
|
||||
{
|
||||
TRACE ("accumulate last fragment seq="<<hdr->GetSequenceNumber ()<<
|
||||
", frag="<<hdr->GetFragmentNumber ()<<
|
||||
", size="<<hdr->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="<<hdr->GetSequenceNumber ()<<
|
||||
", frag="<<hdr->GetFragmentNumber ()<<
|
||||
", size="<<packet.GetSize ());
|
||||
originator->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="<<hdr->GetAddr2 ()<<
|
||||
", seq="<<hdr->GetSequenceNumber ()<<
|
||||
", frag="<<hdr->GetFragmentNumber ());
|
||||
return;
|
||||
}
|
||||
bool complete;
|
||||
Packet agregate = HandleFragments (packet, hdr, originator, &complete);
|
||||
if (!complete)
|
||||
{
|
||||
return;
|
||||
}
|
||||
TRACE ("forwarding data from="<<hdr->GetAddr2 ()<<
|
||||
", seq="<<hdr->GetSequenceNumber ()<<
|
||||
", frag="<<hdr->GetFragmentNumber ());
|
||||
originator->SetSequenceControl (hdr->GetSequenceControl ());
|
||||
m_callback (agregate, hdr);
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE ("forwarding "<<hdr->GetTypeString ()<<
|
||||
", seq="<<hdr->GetSequenceNumber ()<<
|
||||
", frag="<<hdr->GetFragmentNumber ());
|
||||
originator->SetSequenceControl (hdr->GetSequenceControl ());
|
||||
m_callback (packet, hdr);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
66
src/devices/wifi/mac-rx-middle.h
Normal file
66
src/devices/wifi/mac-rx-middle.h
Normal file
@@ -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 <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
|
||||
#ifndef MAC_RX_MIDDLE_H
|
||||
#define MAC_RX_MIDDLE_H
|
||||
|
||||
#include <map>
|
||||
#include <utility>
|
||||
#include "ns3/callback.h"
|
||||
#include "ns3/mac48-address.h"
|
||||
#include "ns3/packet.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class WifiMacHeader;
|
||||
class OriginatorRxStatus;
|
||||
|
||||
class MacRxMiddle
|
||||
{
|
||||
public:
|
||||
typedef Callback<void, Packet , WifiMacHeader const *> 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 <Mac48Address, OriginatorRxStatus *, std::less<Mac48Address> > Originators;
|
||||
typedef std::map <std::pair<Mac48Address, uint8_t>, OriginatorRxStatus *, std::less<std::pair<Mac48Address,uint8_t> > > QosOriginators;
|
||||
typedef std::map <Mac48Address, OriginatorRxStatus *, std::less<Mac48Address> >::iterator OriginatorsI;
|
||||
typedef std::map <std::pair<Mac48Address, uint8_t>, OriginatorRxStatus *, std::less<std::pair<Mac48Address,uint8_t> > >::iterator QosOriginatorsI;
|
||||
Originators m_originatorStatus;
|
||||
QosOriginators m_qosOriginatorStatus;
|
||||
ForwardUpCallback m_callback;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
|
||||
#endif /* MAC_RX_MIDDLE_H */
|
||||
@@ -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 = [
|
||||
|
||||
Reference in New Issue
Block a user