From 1b0678bc19c231c701cab970dc7fecfed50bb778 Mon Sep 17 00:00:00 2001 From: Mirko Banchi Date: Wed, 3 Feb 2010 20:34:48 +0100 Subject: [PATCH] add action frames needed by block ack --- src/devices/wifi/mgt-headers.cc | 467 ++++++++++++++++++++++++++++++++ src/devices/wifi/mgt-headers.h | 123 +++++++++ 2 files changed, 590 insertions(+) diff --git a/src/devices/wifi/mgt-headers.cc b/src/devices/wifi/mgt-headers.cc index dfcb2d0cc..cbf531dba 100644 --- a/src/devices/wifi/mgt-headers.cc +++ b/src/devices/wifi/mgt-headers.cc @@ -1,6 +1,7 @@ /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ /* * Copyright (c) 2006 INRIA + * 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 @@ -16,6 +17,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Author: Mathieu Lacage + * Author: Mirko Banchi */ #include "mgt-headers.h" #include "ns3/simulator.h" @@ -405,6 +407,11 @@ WifiActionHeader::SetAction (WifiActionHeader::CategoryValue type, switch (type) { + case BLOCK_ACK: + { + m_actionValue = action.blockAck; + break; + } case MESH_PEERING_MGT: { m_actionValue = action.peerLink; @@ -427,6 +434,8 @@ WifiActionHeader::GetCategory () { switch (m_category) { + case BLOCK_ACK: + return BLOCK_ACK; case MESH_PEERING_MGT: return MESH_PEERING_MGT; case MESH_LINK_METRIC: @@ -451,6 +460,19 @@ WifiActionHeader::GetAction () retval.peerLink = PEER_LINK_OPEN; // Needs to be initialized to something to quiet valgrind in default cases switch (m_category) { + case BLOCK_ACK: + switch (m_actionValue) + { + case BLOCK_ACK_ADDBA_REQUEST: + retval.blockAck = BLOCK_ACK_ADDBA_REQUEST; + return retval; + case BLOCK_ACK_ADDBA_RESPONSE: + retval.blockAck = BLOCK_ACK_ADDBA_RESPONSE; + return retval; + case BLOCK_ACK_DELBA: + retval.blockAck = BLOCK_ACK_DELBA; + return retval; + } case MESH_PEERING_MGT: switch (m_actionValue) { @@ -528,4 +550,449 @@ WifiActionHeader::Deserialize (Buffer::Iterator start) return i.GetDistanceFrom (start); } +/*************************************************** +* ADDBARequest +****************************************************/ + +NS_OBJECT_ENSURE_REGISTERED (MgtAddBaRequestHeader); + +MgtAddBaRequestHeader::MgtAddBaRequestHeader () + : m_dialogToken (1), + m_amsduSupport (1), + m_bufferSize (0) +{} + +TypeId +MgtAddBaRequestHeader::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::MgtAddBaRequestHeader") + .SetParent
() + .AddConstructor (); + ; + return tid; +} + +TypeId +MgtAddBaRequestHeader::GetInstanceTypeId (void) const +{ + return GetTypeId (); +} + +void +MgtAddBaRequestHeader::Print (std::ostream &os) const +{} + +uint32_t +MgtAddBaRequestHeader::GetSerializedSize (void) const +{ + uint32_t size = 0; + size += 1; //Dialog token + size += 2; //Block ack parameter set + size += 2; //Block ack timeout value + size += 2; //Starting sequence control + return size; +} + +void +MgtAddBaRequestHeader::Serialize (Buffer::Iterator start) const +{ + Buffer::Iterator i = start; + i.WriteU8 (m_dialogToken); + i.WriteHtolsbU16 (GetParameterSet ()); + i.WriteHtolsbU16 (m_timeoutValue); + i.WriteHtolsbU16 (GetStartingSequenceControl ()); +} + +uint32_t +MgtAddBaRequestHeader::Deserialize (Buffer::Iterator start) +{ + Buffer::Iterator i = start; + m_dialogToken = i.ReadU8 (); + SetParameterSet (i.ReadLsbtohU16 ()); + m_timeoutValue = i.ReadLsbtohU16 (); + SetStartingSequenceControl (i.ReadLsbtohU16 ()); + return i.GetDistanceFrom (start); +} + +void +MgtAddBaRequestHeader::SetDelayedBlockAck () +{ + m_policy = 0; +} + +void +MgtAddBaRequestHeader::SetImmediateBlockAck () +{ + m_policy = 1; +} + +void +MgtAddBaRequestHeader::SetTid (uint8_t tid) +{ + NS_ASSERT (tid < 16); + m_tid = tid; +} + +void +MgtAddBaRequestHeader::SetTimeout (uint16_t timeout) +{ + m_timeoutValue = timeout; +} + +void +MgtAddBaRequestHeader::SetBufferSize (uint16_t size) +{ + m_bufferSize = size; +} + +void +MgtAddBaRequestHeader::SetStartingSequence (uint16_t seq) +{ + m_startingSeq = seq; +} + +void +MgtAddBaRequestHeader::SetAmsduSupport (bool supported) +{ + m_amsduSupport = supported; +} + +uint8_t +MgtAddBaRequestHeader::GetTid (void) const +{ + return m_tid; +} + +bool +MgtAddBaRequestHeader::IsImmediateBlockAck (void) const +{ + return (m_policy == 1)?true:false; +} + +uint16_t +MgtAddBaRequestHeader::GetTimeout (void) const +{ + return m_timeoutValue; +} + +uint16_t +MgtAddBaRequestHeader::GetBufferSize (void) const +{ + return m_bufferSize; +} + +bool +MgtAddBaRequestHeader::IsAmsduSupported (void) const +{ + return (m_amsduSupport == 1)?true:false; +} + +uint16_t +MgtAddBaRequestHeader::GetStartingSequence (void) const +{ + return m_startingSeq; +} + +uint16_t +MgtAddBaRequestHeader::GetStartingSequenceControl (void) const +{ + return (m_startingSeq << 4) & 0xfff0; +} + +void +MgtAddBaRequestHeader::SetStartingSequenceControl (uint16_t seqControl) +{ + m_startingSeq = (seqControl >> 4) & 0x0fff; +} + +uint16_t +MgtAddBaRequestHeader::GetParameterSet (void) const +{ + uint16_t res = 0; + res |= m_amsduSupport; + res |= m_policy << 1; + res |= m_tid << 2; + res |= m_bufferSize << 6; + return res; +} + +void +MgtAddBaRequestHeader::SetParameterSet (uint16_t params) +{ + m_amsduSupport = (params) & 0x01; + m_policy = (params >> 1) & 0x01; + m_tid = (params >> 2) & 0x0f; + m_bufferSize = (params >> 6) & 0x03ff; +} + +/*************************************************** +* ADDBAResponse +****************************************************/ + +NS_OBJECT_ENSURE_REGISTERED (MgtAddBaResponseHeader); + +MgtAddBaResponseHeader::MgtAddBaResponseHeader () + : m_dialogToken (1), + m_amsduSupport (1), + m_bufferSize (0) +{} + +TypeId +MgtAddBaResponseHeader::GetTypeId () +{ + static TypeId tid = TypeId ("ns3::MgtAddBaResponseHeader") + .SetParent
() + .AddConstructor () + ; + return tid; +} + +TypeId +MgtAddBaResponseHeader::GetInstanceTypeId (void) const +{ + return GetTypeId (); +} + +void +MgtAddBaResponseHeader::Print (std::ostream &os) const +{ + os <<"status code="<> 1) & 0x01; + m_tid = (params >> 2) & 0x0f; + m_bufferSize = (params >> 6) & 0x03ff; +} + +/*************************************************** +* DelBa +****************************************************/ + +NS_OBJECT_ENSURE_REGISTERED (MgtDelBaHeader); + +MgtDelBaHeader::MgtDelBaHeader () + : m_reasonCode (1) +{} + +TypeId +MgtDelBaHeader::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::MgtDelBaHeader") + .SetParent
() + .AddConstructor () + ; + return tid; +} + +TypeId +MgtDelBaHeader::GetInstanceTypeId (void) const +{ + return GetTypeId (); +} + +void +MgtDelBaHeader::Print (std::ostream &os) const +{} + +uint32_t +MgtDelBaHeader::GetSerializedSize (void) const +{ + uint32_t size = 0; + size += 2; //DelBa parameter set + size += 2; //Reason code + return size; +} + +void +MgtDelBaHeader::Serialize (Buffer::Iterator start) const +{ + Buffer::Iterator i = start; + i.WriteHtolsbU16 (GetParameterSet ()); + i.WriteHtolsbU16 (m_reasonCode); +} + +uint32_t +MgtDelBaHeader::Deserialize (Buffer::Iterator start) +{ + Buffer::Iterator i = start; + SetParameterSet (i.ReadLsbtohU16 ()); + m_reasonCode = i.ReadLsbtohU16 (); + return i.GetDistanceFrom (start); +} + +bool +MgtDelBaHeader::IsByOriginator (void) const +{ + return (m_initiator == 1)?true:false; +} + +uint8_t +MgtDelBaHeader::GetTid (void) const +{ + NS_ASSERT (m_tid < 16); + uint8_t tid = static_cast (m_tid); + return tid; +} + +void +MgtDelBaHeader::SetByOriginator (void) +{ + m_initiator = 1; +} + +void +MgtDelBaHeader::SetByRecipient (void) +{ + m_initiator = 0; +} + +void +MgtDelBaHeader::SetTid (uint8_t tid) +{ + NS_ASSERT (tid < 16); + m_tid = static_cast (tid); +} + +uint16_t +MgtDelBaHeader::GetParameterSet (void) const +{ + uint16_t res = 0; + res |= m_initiator << 11; + res |= m_tid << 12; + return res; +} + +void +MgtDelBaHeader::SetParameterSet (uint16_t params) +{ + m_initiator = (params >> 11) & 0x01; + m_tid = (params >> 12) & 0x0f; +} + } // namespace ns3 diff --git a/src/devices/wifi/mgt-headers.h b/src/devices/wifi/mgt-headers.h index 6a04c8ffb..6d8a9cd4b 100644 --- a/src/devices/wifi/mgt-headers.h +++ b/src/devices/wifi/mgt-headers.h @@ -1,6 +1,7 @@ /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ /* * Copyright (c) 2006 INRIA + * 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 @@ -16,6 +17,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Author: Mathieu Lacage + * Author: Mirko Banchi */ #ifndef MGT_HEADERS_H #define MGT_HEADERS_H @@ -134,6 +136,10 @@ private: class MgtBeaconHeader : public MgtProbeResponseHeader {}; +/**************************** +* Action frames +*****************************/ + /** * \brief See IEEE 802.11 chapter 7.3.1.11 * @@ -148,6 +154,7 @@ public: /* Compatible with open80211s implementation */ enum CategoryValue //table 7-24 staring from 4 { + BLOCK_ACK = 3, MESH_PEERING_MGT = 30, MESH_LINK_METRIC = 31, MESH_PATH_SELECTION = 32, @@ -189,6 +196,12 @@ public: TBTT_ADJUSTMENT_REQUEST, MESH_CHANNEL_SWITCH_ANNOUNCEMENT, }; + enum BlockAckActionValue + { + BLOCK_ACK_ADDBA_REQUEST = 0, + BLOCK_ACK_ADDBA_RESPONSE = 1, + BLOCK_ACK_DELBA = 2 + }; typedef union { enum PeerLinkMgtActionValue peerLink; @@ -196,6 +209,7 @@ public: enum PathSelectionActionValue pathSelection; enum InterworkActionValue interwork; enum ResourceCoordinationActionValue resourceCoordination; + enum BlockAckActionValue blockAck; } ActionValue; void SetAction (enum CategoryValue type,ActionValue action); @@ -212,6 +226,115 @@ private: uint8_t m_actionValue; }; +class MgtAddBaRequestHeader : public Header { +public: + + MgtAddBaRequestHeader (); + + static TypeId GetTypeId (void); + virtual TypeId GetInstanceTypeId (void) const; + virtual void Print (std::ostream &os) const; + virtual uint32_t GetSerializedSize (void) const; + virtual void Serialize (Buffer::Iterator start) const; + virtual uint32_t Deserialize (Buffer::Iterator start); + + void SetDelayedBlockAck (); + void SetImmediateBlockAck (); + void SetTid (uint8_t tid); + void SetTimeout (uint16_t timeout); + void SetBufferSize (uint16_t size); + void SetStartingSequence (uint16_t seq); + void SetAmsduSupport (bool supported); + + uint16_t GetStartingSequence (void) const; + uint8_t GetTid (void) const; + bool IsImmediateBlockAck (void) const; + uint16_t GetTimeout (void) const; + uint16_t GetBufferSize (void) const; + bool IsAmsduSupported (void) const; + +private: + uint16_t GetParameterSet (void) const; + void SetParameterSet (uint16_t params); + uint16_t GetStartingSequenceControl (void) const; + void SetStartingSequenceControl (uint16_t seqControl); + + uint8_t m_dialogToken; /* Not used for now */ + uint8_t m_amsduSupport; + uint8_t m_policy; + uint8_t m_tid; + uint16_t m_bufferSize; + uint16_t m_timeoutValue; + uint16_t m_startingSeq; +}; + +class MgtAddBaResponseHeader : public Header { +public: + + MgtAddBaResponseHeader (); + + static TypeId GetTypeId (void); + virtual TypeId GetInstanceTypeId (void) const; + virtual void Print (std::ostream &os) const; + virtual uint32_t GetSerializedSize (void) const; + virtual void Serialize (Buffer::Iterator start) const; + virtual uint32_t Deserialize (Buffer::Iterator start); + + void SetDelayedBlockAck (); + void SetImmediateBlockAck (); + void SetTid (uint8_t tid); + void SetTimeout (uint16_t timeout); + void SetBufferSize (uint16_t size); + void SetStatusCode (StatusCode code); + void SetAmsduSupport (bool supported); + + StatusCode GetStatusCode (void) const; + uint8_t GetTid (void) const; + bool IsImmediateBlockAck (void) const; + uint16_t GetTimeout (void) const; + uint16_t GetBufferSize (void) const; + bool IsAmsduSupported (void) const; + +private: + uint16_t GetParameterSet (void) const; + void SetParameterSet (uint16_t params); + + uint8_t m_dialogToken; /* Not used for now */ + StatusCode m_code; + uint8_t m_amsduSupport; + uint8_t m_policy; + uint8_t m_tid; + uint16_t m_bufferSize; + uint16_t m_timeoutValue; +}; + +class MgtDelBaHeader : public Header { +public: + MgtDelBaHeader (); + + static TypeId GetTypeId (void); + virtual TypeId GetInstanceTypeId (void) const; + virtual void Print (std::ostream &os) const; + virtual uint32_t GetSerializedSize (void) const; + virtual void Serialize (Buffer::Iterator start) const; + virtual uint32_t Deserialize (Buffer::Iterator start); + + bool IsByOriginator (void) const; + uint8_t GetTid (void) const; + void SetTid (uint8_t); + void SetByOriginator (void); + void SetByRecipient (void); + +private: + uint16_t GetParameterSet (void) const; + void SetParameterSet (uint16_t params); + + uint16_t m_initiator; + uint16_t m_tid; + /* Not used for now. + Always set to 1: "Unspecified reason" */ + uint16_t m_reasonCode; +}; } // namespace ns3