add action frames needed by block ack

This commit is contained in:
Mirko Banchi
2010-02-03 20:34:48 +01:00
parent 7169072c51
commit 1b0678bc19
2 changed files with 590 additions and 0 deletions

View File

@@ -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 @@ 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<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

View File

@@ -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 @@ 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