Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(89)

Unified Diff: src/devices/wifi/ctrl-headers.cc

Issue 144050: Full Compressed Block Ack support
Patch Set: possible final patch Created 14 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/devices/wifi/ctrl-headers.cc
===================================================================
new file mode 100644
--- /dev/null
+++ b/src/devices/wifi/ctrl-headers.cc
@@ -0,0 +1,681 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 MIRKO BANCHI
+ *
+ * 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: Mirko Banchi <mk.banchi@gmail.com>
+ */
+#include "ns3/fatal-error.h"
+
+#include "ctrl-headers.h"
+
+namespace ns3 {
+
+/***********************************
+ * Block ack request
+ ***********************************/
+
+NS_OBJECT_ENSURE_REGISTERED (CtrlBAckRequestHeader);
+
+CtrlBAckRequestHeader::CtrlBAckRequestHeader ()
+ : m_barAckPolicy (false),
+ m_multiTid (false),
+ m_compressed (false)
+{}
+
+CtrlBAckRequestHeader::~CtrlBAckRequestHeader ()
+{}
+
+TypeId
+CtrlBAckRequestHeader::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::CtrlBAckRequestHeader")
+ .SetParent<Header> ()
+ .AddConstructor<CtrlBAckRequestHeader> ()
+ ;
+ return tid;
+}
+
+TypeId
+CtrlBAckRequestHeader::GetInstanceTypeId (void) const
+{
+ return GetTypeId ();
+}
+
+void
+CtrlBAckRequestHeader::Print (std::ostream &os) const
+{
+ os << "TID_INFO=" << m_tidInfo << ", StartingSeq=" << std::hex << m_startingSeq;
+}
+
+uint32_t
+CtrlBAckRequestHeader::GetSerializedSize () const
+{
+ uint32_t size = 0;
+ size += 2; //Bar control
+ if (!m_multiTid)
+ {
+ size += 2; //Starting sequence control
+ }
+ else
+ {
+ if (m_compressed)
+ {
+ size += (2 + 2) * (m_tidInfo + 1); //Multi-tid block ack
+ }
+ else
+ {
+ NS_FATAL_ERROR ("Reserved configuration.");
+ }
+ }
+ return size;
+}
+
+void
+CtrlBAckRequestHeader::Serialize (Buffer::Iterator start) const
+{
+ Buffer::Iterator i = start;
+ i.WriteHtolsbU16 (GetBarControl ());
+ if (!m_multiTid)
+ {
+ i.WriteHtolsbU16 (GetStartingSequenceControl ());
+ }
+ else
+ {
+ if (m_compressed)
+ {
+ NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
+ }
+ else
+ {
+ NS_FATAL_ERROR ("Reserved configuration.");
+ }
+ }
+}
+
+uint32_t
+CtrlBAckRequestHeader::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+ SetBarControl (i.ReadLsbtohU16 ());
+ if (!m_multiTid)
+ {
+ SetStartingSequenceControl (i.ReadLsbtohU16 ());
+ }
+ else
+ {
+ if (m_compressed)
+ {
+ NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
+ }
+ else
+ {
+ NS_FATAL_ERROR ("Reserved configuration.");
+ }
+ }
+ return i.GetDistanceFrom (start);
+}
+
+uint16_t
+CtrlBAckRequestHeader::GetBarControl (void) const
+{
+ uint16_t res = 0;
+ if (m_barAckPolicy)
+ {
+ res |= 0x1;
+ }
+ if (m_multiTid)
+ {
+ res |= (0x1<<1);
+ }
+ if (m_compressed)
+ {
+ res |= (0x1<<2);
+ }
+ res |= (m_tidInfo << 12) & (0xf<<12);
+ return res;
+}
+
+void
+CtrlBAckRequestHeader::SetBarControl (uint16_t bar)
+{
+ m_barAckPolicy = ((bar & 0x01) == 1)?true:false;
+ m_multiTid = (((bar >> 1) & 0x01) == 1)?true:false;
+ m_compressed = (((bar >> 2) & 0x01) == 1)?true:false;
+ m_tidInfo = (bar >> 12) & 0x0f;
+}
+
+uint16_t
+CtrlBAckRequestHeader::GetStartingSequenceControl (void) const
+{
+ return (m_startingSeq << 4) & 0xfff0;
+}
+
+void
+CtrlBAckRequestHeader::SetStartingSequenceControl (uint16_t seqControl)
+{
+ m_startingSeq = (seqControl >> 4) & 0x0fff;
+}
+
+void
+CtrlBAckRequestHeader::SetHtImmediateAck (bool immediateAck)
+{
+ m_barAckPolicy = immediateAck;
+}
+
+void
+CtrlBAckRequestHeader::SetType (enum BlockAckType type)
+{
+ switch (type) {
+ case BASIC_BLOCK_ACK:
+ m_multiTid = false;
+ m_compressed = false;
+ break;
+ case COMPRESSED_BLOCK_ACK:
+ m_multiTid = false;
+ m_compressed = true;
+ break;
+ case MULTI_TID_BLOCK_ACK:
+ m_multiTid = true;
+ m_compressed = true;
+ break;
+ default:
+ NS_FATAL_ERROR ("Invalid variant type");
+ break;
+ }
+}
+
+void
+CtrlBAckRequestHeader::SetTidInfo (uint8_t tid)
+{
+ m_tidInfo = static_cast<uint16_t> (tid);
+}
+
+void
+CtrlBAckRequestHeader::SetStartingSequence (uint16_t seq)
+{
+ m_startingSeq = seq;
+}
+
+bool
+CtrlBAckRequestHeader::MustSendHtImmediateAck (void) const
+{
+ return m_barAckPolicy;
+}
+
+uint8_t
+CtrlBAckRequestHeader::GetTidInfo (void) const
+{
+ uint8_t tid = static_cast<uint8_t> (m_tidInfo);
+ return tid;
+}
+
+uint16_t
+CtrlBAckRequestHeader::GetStartingSequence (void) const
+{
+ return m_startingSeq;
+}
+
+bool
+CtrlBAckRequestHeader::IsBasic (void) const
+{
+ return (!m_multiTid && !m_compressed)?true:false;
+}
+
+bool
+CtrlBAckRequestHeader::IsCompressed (void) const
+{
+ return (!m_multiTid && m_compressed)?true:false;
+}
+
+bool
+CtrlBAckRequestHeader::IsMultiTid (void) const
+{
+ return (m_multiTid && m_compressed)?true:false;
+}
+
+/***********************************
+ * Block ack response
+ ***********************************/
+
+NS_OBJECT_ENSURE_REGISTERED (CtrlBAckResponseHeader);
+
+CtrlBAckResponseHeader::CtrlBAckResponseHeader ()
+ : m_baAckPolicy (false),
+ m_multiTid (false),
+ m_compressed (false)
+{
+ memset (&bitmap, 0, sizeof (bitmap));
+}
+
+CtrlBAckResponseHeader::~CtrlBAckResponseHeader ()
+{}
+
+TypeId
+CtrlBAckResponseHeader::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::CtrlBAckResponseHeader")
+ .SetParent<Header> ()
+ .AddConstructor<CtrlBAckResponseHeader> ()
+ ;
+ return tid;
+}
+
+TypeId
+CtrlBAckResponseHeader::GetInstanceTypeId (void) const
+{
+ return GetTypeId ();
+}
+
+void
+CtrlBAckResponseHeader::Print (std::ostream &os) const
+{
+ os << "TID_INFO=" << m_tidInfo << ", StartingSeq=" << std::hex << m_startingSeq;
+}
+
+uint32_t
+CtrlBAckResponseHeader::GetSerializedSize (void) const
+{
+ uint32_t size = 0;
+ size += 2; //Bar control
+ if (!m_multiTid)
+ {
+ if (!m_compressed)
+ {
+ size += (2 + 128); //Basic block ack
+ }
+ else
+ {
+ size += (2 + 8); //Compressed block ack
+ }
+ }
+ else
+ {
+ if (m_compressed)
+ {
+ size += (2 + 2 + 8) * (m_tidInfo + 1); //Multi-tid block ack
+ }
+ else
+ {
+ NS_FATAL_ERROR ("Reserved configuration.");
+ }
+ }
+ return size;
+}
+
+void
+CtrlBAckResponseHeader::Serialize (Buffer::Iterator start) const
+{
+ Buffer::Iterator i = start;
+ i.WriteHtolsbU16 (GetBaControl ());
+ if (!m_multiTid)
+ {
+ i.WriteHtolsbU16 (GetStartingSequenceControl ());
+ i = SerializeBitmap (i);
+ }
+ else
+ {
+ if (m_compressed)
+ {
+ NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
+ }
+ else
+ {
+ NS_FATAL_ERROR ("Reserved configuration.");
+ }
+ }
+}
+
+uint32_t
+CtrlBAckResponseHeader::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+ SetBaControl (i.ReadLsbtohU16 ());
+ if (!m_multiTid)
+ {
+ SetStartingSequenceControl (i.ReadLsbtohU16 ());
+ i = DeserializeBitmap (i);
+ }
+ else
+ {
+ if (m_compressed)
+ {
+ NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
+ }
+ else
+ {
+ NS_FATAL_ERROR ("Reserved configuration.");
+ }
+ }
+ return i.GetDistanceFrom (start);
+}
+
+void
+CtrlBAckResponseHeader::SetHtImmediateAck (bool immediateAck)
+{
+ m_baAckPolicy = immediateAck;
+}
+
+void
+CtrlBAckResponseHeader::SetType (enum BlockAckType type)
+{
+ switch (type) {
+ case BASIC_BLOCK_ACK:
+ m_multiTid = false;
+ m_compressed = false;
+ break;
+ case COMPRESSED_BLOCK_ACK:
+ m_multiTid = false;
+ m_compressed = true;
+ break;
+ case MULTI_TID_BLOCK_ACK:
+ m_multiTid = true;
+ m_compressed = true;
+ break;
+ default:
+ NS_FATAL_ERROR ("Invalid variant type");
+ break;
+ }
+}
+
+void
+CtrlBAckResponseHeader::SetTidInfo (uint8_t tid)
+{
+ m_tidInfo = static_cast<uint16_t> (tid);
+}
+
+void
+CtrlBAckResponseHeader::SetStartingSequence (uint16_t seq)
+{
+ m_startingSeq = seq;
+}
+
+bool
+CtrlBAckResponseHeader::MustSendHtImmediateAck (void) const
+{
+ return (m_baAckPolicy)?true:false;
+}
+
+uint8_t
+CtrlBAckResponseHeader::GetTidInfo (void) const
+{
+ uint8_t tid = static_cast<uint8_t> (m_tidInfo);
+ return tid;
+}
+
+uint16_t
+CtrlBAckResponseHeader::GetStartingSequence (void) const
+{
+ return m_startingSeq;
+}
+
+bool
+CtrlBAckResponseHeader::IsBasic (void) const
+{
+ return (!m_multiTid && !m_compressed)?true:false;
+}
+
+bool
+CtrlBAckResponseHeader::IsCompressed (void) const
+{
+ return (!m_multiTid && m_compressed)?true:false;
+}
+
+bool
+CtrlBAckResponseHeader::IsMultiTid (void) const
+{
+ return (m_multiTid && m_compressed)?true:false;
+}
+
+uint16_t
+CtrlBAckResponseHeader::GetBaControl (void) const
+{
+ uint16_t res = 0;
+ if (m_baAckPolicy)
+ {
+ res |= 0x1;
+ }
+ if (m_multiTid)
+ {
+ res |= (0x1<<1);
+ }
+ if (m_compressed)
+ {
+ res |= (0x1<<2);
+ }
+ res |= (m_tidInfo << 12) & (0xf<<12);
+ return res;
+}
+
+void
+CtrlBAckResponseHeader::SetBaControl (uint16_t ba)
+{
+ m_baAckPolicy = ((ba & 0x01) == 1)?true:false;
+ m_multiTid = (((ba >> 1) & 0x01) == 1)?true:false;
+ m_compressed = (((ba >> 2) & 0x01) == 1)?true:false;
+ m_tidInfo = (ba >> 12) & 0x0f;
+}
+
+uint16_t
+CtrlBAckResponseHeader::GetStartingSequenceControl (void) const
+{
+ return (m_startingSeq << 4) & 0xfff0;
+}
+
+void
+CtrlBAckResponseHeader::SetStartingSequenceControl (uint16_t seqControl)
+{
+ m_startingSeq = (seqControl >> 4) & 0x0fff;
+}
+
+Buffer::Iterator
+CtrlBAckResponseHeader::SerializeBitmap (Buffer::Iterator start) const
+{
+ Buffer::Iterator i = start;
+ if (!m_multiTid)
+ {
+ if (!m_compressed)
+ {
+ for (uint32_t j = 0; j < 64; j++)
+ {
+ i.WriteHtolsbU16 (bitmap.m_bitmap[j]);
+ }
+ }
+ else
+ {
+ i.WriteHtolsbU64 (bitmap.m_compressedBitmap);
+ }
+ }
+ else
+ {
+ if (m_compressed)
+ {
+ NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
+ }
+ else
+ {
+ NS_FATAL_ERROR ("Reserved configuration.");
+ }
+ }
+ return i;
+}
+
+Buffer::Iterator
+CtrlBAckResponseHeader::DeserializeBitmap (Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+ if (!m_multiTid)
+ {
+ if (!m_compressed)
+ {
+ for (uint32_t j = 0; j < 64; j++)
+ {
+ bitmap.m_bitmap[j] = i.ReadLsbtohU16 ();
+ }
+ }
+ else
+ {
+ bitmap.m_compressedBitmap = i.ReadLsbtohU64 ();
+ }
+ }
+ else
+ {
+ if (m_compressed)
+ {
+ NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
+ }
+ else
+ {
+ NS_FATAL_ERROR ("Reserved configuration.");
+ }
+ }
+ return i;
+}
+
+void
+CtrlBAckResponseHeader::SetReceivedPacket (uint16_t seq)
+{
+ if (!m_multiTid)
+ {
+ if (!m_compressed)
+ {
+ /* To set correctly basic block ack bitmap we need fragment number too.
+ So if it's not specified, we consider packet not fragmented. */
+ bitmap.m_bitmap[IndexInBitmap (seq)] |= 0x0001;
+ }
+ else
+ {
+ bitmap.m_compressedBitmap |= (0x0000000000000001 << IndexInBitmap (seq));
+ }
+ }
+ else
+ {
+ if (m_compressed)
+ {
+ NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
+ }
+ else
+ {
+ NS_FATAL_ERROR ("Reserved configuration.");
+ }
+ }
+}
+
+void
+CtrlBAckResponseHeader::SetReceivedFragment (uint16_t seq, uint8_t frag)
+{
+ NS_ASSERT (frag < 16);
+ if (!m_multiTid)
+ {
+ if (!m_compressed)
+ {
+ bitmap.m_bitmap[IndexInBitmap (seq)] |= (0x0001<<frag);
+ }
+ else
+ {
+ /* We can ignore this...compressed block ack doesn't support
+ acknowledgement of single fragments */
+ }
+ }
+ else
+ {
+ if (m_compressed)
+ {
+ NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
+ }
+ else
+ {
+ NS_FATAL_ERROR ("Reserved configuration.");
+ }
+ }
+}
+
+bool
+CtrlBAckResponseHeader::IsPacketReceived (uint16_t seq) const
+{
+ if (!m_multiTid)
+ {
+ if (!m_compressed)
+ {
+ /*It's impossible to say if an entire packet was correctly received. */
+ return false;
+ }
+ else
+ {
+ uint64_t mask = 0x0000000000000001;
+ return (((bitmap.m_compressedBitmap >> IndexInBitmap (seq)) & mask) == 1)?true:false;
+ }
+ }
+ else
+ {
+ if (m_compressed)
+ {
+ NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
+ }
+ else
+ {
+ NS_FATAL_ERROR ("Reserved configuration.");
+ }
+ }
+ return false;
+}
+
+bool
+CtrlBAckResponseHeader::IsFragmentReceived (uint16_t seq, uint8_t frag) const
+{
+ NS_ASSERT (frag < 16);
+ if (!m_multiTid)
+ {
+ if (!m_compressed)
+ {
+ return ((bitmap.m_bitmap[IndexInBitmap (seq)] & (0x0001<<frag)) != 0x0000)?true:false;
+ }
+ else
+ {
+ /* Although this could make no sense, if packet with sequence number
+ equal to <i>seq</i> was correctly received, also all of its fragments
+ were correctly received. */
+ uint64_t mask = 0x0000000000000001;
+ return (((bitmap.m_compressedBitmap >> IndexInBitmap (seq)) & mask) == 1)?true:false;
+ }
+ }
+ else
+ {
+ if (m_compressed)
+ {
+ NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
+ }
+ else
+ {
+ NS_FATAL_ERROR ("Reserved configuration.");
+ }
+ }
+ return false;
+}
+
+uint8_t
+CtrlBAckResponseHeader::IndexInBitmap (uint16_t seq) const
+{
+ if (seq >= m_startingSeq)
+ {
+ return (seq - m_startingSeq);
+ }
+ else
+ {
+ return (4096 - m_startingSeq + seq);
+ }
+}
+
+} //namespace ns3

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b