add action frames needed by block ack
authorMirko Banchi <mk.banchi@gmail.com>
Wed, 03 Feb 2010 20:34:48 +0100
changeset 5949 66f939e7aaec
parent 5948 34bd93988e2b
child 5950 a09eebc83465
add action frames needed by block ack
src/devices/wifi/mgt-headers.cc
src/devices/wifi/mgt-headers.h
--- a/src/devices/wifi/mgt-headers.cc	Wed Feb 03 20:34:48 2010 +0100
+++ b/src/devices/wifi/mgt-headers.cc	Wed Feb 03 20:34:48 2010 +0100
@@ -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 <mathieu.lacage@sophia.inria.fr>
+ * Author: Mirko Banchi <mk.banchi@gmail.com>
  */
 #include "mgt-headers.h"
 #include "ns3/simulator.h"
@@ -405,6 +407,11 @@
 
   switch (type)
     {
+  case BLOCK_ACK:
+    {
+      m_actionValue = action.blockAck;
+      break;
+    }
   case MESH_PEERING_MGT:
     {
       m_actionValue = action.peerLink;
@@ -427,6 +434,8 @@
 {
   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 @@
   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 @@
   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<Header> ()
+    .AddConstructor<MgtAddBaRequestHeader> ();
+  ;
+  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<Header> ()
+    .AddConstructor<MgtAddBaResponseHeader> ()
+  ;
+  return tid;
+}
+
+TypeId
+MgtAddBaResponseHeader::GetInstanceTypeId (void) const
+{
+  return GetTypeId ();
+}
+
+void
+MgtAddBaResponseHeader::Print (std::ostream &os) const
+{
+  os <<"status code="<<m_code;
+}
+
+uint32_t
+MgtAddBaResponseHeader::GetSerializedSize (void) const
+{
+  uint32_t size = 0;
+  size += 1; //Dialog token
+  size += m_code.GetSerializedSize (); //Status code
+  size += 2; //Block ack parameter set
+  size += 2; //Block ack timeout value
+  return size;
+}
+
+void
+MgtAddBaResponseHeader::Serialize (Buffer::Iterator start) const
+{
+  Buffer::Iterator i = start;
+  i.WriteU8 (m_dialogToken);
+  i = m_code.Serialize (i);
+  i.WriteHtolsbU16 (GetParameterSet ());
+  i.WriteHtolsbU16 (m_timeoutValue);
+}
+
+uint32_t
+MgtAddBaResponseHeader::Deserialize (Buffer::Iterator start)
+{
+  Buffer::Iterator i = start;
+  m_dialogToken = i.ReadU8 ();
+  i = m_code.Deserialize (i);
+  SetParameterSet (i.ReadLsbtohU16 ());
+  m_timeoutValue = i.ReadLsbtohU16 ();
+  return i.GetDistanceFrom (start);
+}
+
+void
+MgtAddBaResponseHeader::SetDelayedBlockAck ()
+{
+  m_policy = 0;
+}
+
+void
+MgtAddBaResponseHeader::SetImmediateBlockAck ()
+{
+  m_policy = 1;
+}
+
+void
+MgtAddBaResponseHeader::SetTid (uint8_t tid)
+{
+  NS_ASSERT (tid < 16);
+  m_tid = tid;
+}
+
+void
+MgtAddBaResponseHeader::SetTimeout (uint16_t timeout)
+{
+  m_timeoutValue = timeout;
+}
+
+void
+MgtAddBaResponseHeader::SetBufferSize (uint16_t size)
+{
+  m_bufferSize = size;
+}
+
+void
+MgtAddBaResponseHeader::SetStatusCode (StatusCode code)
+{
+  m_code = code;
+}
+
+void
+MgtAddBaResponseHeader::SetAmsduSupport (bool supported)
+{
+  m_amsduSupport = supported;
+}
+
+StatusCode
+MgtAddBaResponseHeader::GetStatusCode (void) const
+{
+  return m_code;
+}
+
+uint8_t
+MgtAddBaResponseHeader::GetTid (void) const
+{
+  return m_tid;
+}
+
+bool
+MgtAddBaResponseHeader::IsImmediateBlockAck (void) const
+{
+  return (m_policy == 1)?true:false;
+}
+
+uint16_t
+MgtAddBaResponseHeader::GetTimeout (void) const
+{
+  return m_timeoutValue;
+}
+
+uint16_t
+MgtAddBaResponseHeader::GetBufferSize (void) const
+{
+  return m_bufferSize;
+}
+
+bool
+MgtAddBaResponseHeader::IsAmsduSupported (void) const
+{
+  return (m_amsduSupport == 1)?true:false; 
+}
+
+uint16_t
+MgtAddBaResponseHeader::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
+MgtAddBaResponseHeader::SetParameterSet (uint16_t params)
+{
+  m_amsduSupport = (params) & 0x01;
+  m_policy = (params >> 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<Header> ()
+    .AddConstructor<MgtDelBaHeader> ()
+  ;
+  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<uint8_t> (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<uint16_t> (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
--- a/src/devices/wifi/mgt-headers.h	Wed Feb 03 20:34:48 2010 +0100
+++ b/src/devices/wifi/mgt-headers.h	Wed Feb 03 20:34:48 2010 +0100
@@ -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 <mathieu.lacage@sophia.inria.fr>
+ * Author: Mirko Banchi <mk.banchi@gmail.com>
  */
 #ifndef MGT_HEADERS_H
 #define MGT_HEADERS_H
@@ -134,6 +136,10 @@
 
 class MgtBeaconHeader : public MgtProbeResponseHeader {};
 
+/****************************
+*     Action frames
+*****************************/
+
 /**
  * \brief See IEEE 802.11 chapter 7.3.1.11
  *
@@ -148,6 +154,7 @@
   /* 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 @@
     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 @@
     enum PathSelectionActionValue pathSelection;
     enum InterworkActionValue interwork;
     enum ResourceCoordinationActionValue resourceCoordination;
+    enum BlockAckActionValue blockAck;
   } ActionValue;
   void   SetAction (enum CategoryValue type,ActionValue action);
 
@@ -212,6 +226,115 @@
   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