src/wifi/model/wifi-mac-queue.h
author Sébastien Deronne <sebastien.deronne@gmail.com>
Thu, 16 Oct 2014 13:26:10 -0700
changeset 11033 2198f9c998cc
parent 10964 a13517b5ea47
child 11174 780a43e4980c
permissions -rw-r--r--
bug 1970: Missing NotifyAckTimeoutStartNow in MacLow::StartDataTxTimers

/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2005, 2009 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
 * 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>
 * Author: Mirko Banchi <mk.banchi@gmail.com>
 */
#ifndef WIFI_MAC_QUEUE_H
#define WIFI_MAC_QUEUE_H

#include <list>
#include <utility>
#include "ns3/packet.h"
#include "ns3/nstime.h"
#include "ns3/object.h"
#include "wifi-mac-header.h"

namespace ns3 {
class QosBlockedDestinations;

/**
 * \ingroup wifi
 *
 * This queue implements the timeout procedure described in
 * (Section 9.19.2.6 "Retransmit procedures" paragraph 6; IEEE 802.11-2012).
 *
 * When a packet is received by the MAC, to be sent to the PHY,
 * it is queued in the internal queue after being tagged by the
 * current time.
 *
 * When a packet is dequeued, the queue checks its timestamp
 * to verify whether or not it should be dropped. If
 * dot11EDCATableMSDULifetime has elapsed, it is dropped.
 * Otherwise, it is returned to the caller.
 */
class WifiMacQueue : public Object
{
public:
  static TypeId GetTypeId (void);
  WifiMacQueue ();
  ~WifiMacQueue ();

  /**
   * Set the maximum queue size.
   *
   * \param maxSize the maximum queue size
   */
  void SetMaxSize (uint32_t maxSize);
  /**
   * Set the maximum delay before the packet is discarded.
   *
   * \param delay the maximum delay
   */
  void SetMaxDelay (Time delay);
  /**
   * Return the maximum queue size.
   *
   * \return the maximum queue size
   */
  uint32_t GetMaxSize (void) const;
  /**
   * Return the maximum delay before the packet is discarded.
   *
   * \return the maximum delay
   */
  Time GetMaxDelay (void) const;

  /**
   * Enqueue the given packet and its corresponding WifiMacHeader at the <i>end</i> of the queue.
   *
   * \param packet the packet to be euqueued at the end
   * \param hdr the header of the given packet
   */
  void Enqueue (Ptr<const Packet> packet, const WifiMacHeader &hdr);
  /**
   * Enqueue the given packet and its corresponding WifiMacHeader at the <i>front</i> of the queue.
   *
   * \param packet the packet to be euqueued at the end
   * \param hdr the header of the given packet
   */
  void PushFront (Ptr<const Packet> packet, const WifiMacHeader &hdr);
  /**
   * Dequeue the packet in the front of the queue.
   *
   * \param hdr the WifiMacHeader of the packet
   * \return the packet
   */
  Ptr<const Packet> Dequeue (WifiMacHeader *hdr);
  /**
   * Peek the packet in the front of the queue. The packet is not removed.
   *
   * \param hdr the WifiMacHeader of the packet
   * \return the packet
   */
  Ptr<const Packet> Peek (WifiMacHeader *hdr);
  /**
   * Searchs and returns, if is present in this queue, first packet having
   * address indicated by <i>type</i> equals to <i>addr</i>, and tid
   * equals to <i>tid</i>. This method removes the packet from this queue.
   * Is typically used by ns3::EdcaTxopN in order to perform correct MSDU
   * aggregation (A-MSDU).
   *
   * \param hdr the header of the dequeued packet
   * \param tid the given TID
   * \param type the given address type
   * \param addr the given destination
   * \return packet
   */
  Ptr<const Packet> DequeueByTidAndAddress (WifiMacHeader *hdr,
                                            uint8_t tid,
                                            WifiMacHeader::AddressType type,
                                            Mac48Address addr);
  /**
   * Searchs and returns, if is present in this queue, first packet having
   * address indicated by <i>type</i> equals to <i>addr</i>, and tid
   * equals to <i>tid</i>. This method doesn't remove the packet from this queue.
   * Is typically used by ns3::EdcaTxopN in order to perform correct MSDU
   * aggregation (A-MSDU).
   *
   * \param hdr the header of the dequeued packet
   * \param tid the given TID
   * \param type the given address type
   * \param addr the given destination
   * \return packet
   */
  Ptr<const Packet> PeekByTidAndAddress (WifiMacHeader *hdr,
                                         uint8_t tid,
                                         WifiMacHeader::AddressType type,
                                         Mac48Address addr);
  /**
   * If exists, removes <i>packet</i> from queue and returns true. Otherwise it
   * takes no effects and return false. Deletion of the packet is
   * performed in linear time (O(n)).
   *
   * \param packet the packet to be removed
   * \return true if the packet was removed, false otherwise
   */
  bool Remove (Ptr<const Packet> packet);
  /**
   * Returns number of QoS packets having tid equals to <i>tid</i> and address
   * specified by <i>type</i> equals to <i>addr</i>.
   *
   * \param tid the given TID
   * \param type the given address type
   * \param addr the given destination
   * \return the number of QoS packets
   */
  uint32_t GetNPacketsByTidAndAddress (uint8_t tid,
                                       WifiMacHeader::AddressType type,
                                       Mac48Address addr);
  /**
   * Returns first available packet for transmission. A packet could be no available
   * if it's a QoS packet with a tid and an address1 fields equal to <i>tid</i> and <i>addr</i>
   * respectively that index a pending agreement in the BlockAckManager object.
   * So that packet must not be transmitted until reception of an ADDBA response frame from station
   * addressed by <i>addr</i>. This method removes the packet from queue.
   *
   * \param hdr the header of the dequeued packet
   * \param tStamp
   * \param blockedPackets
   * \return packet
   */
  Ptr<const Packet> DequeueFirstAvailable (WifiMacHeader *hdr,
                                           Time &tStamp,
                                           const QosBlockedDestinations *blockedPackets);
  /**
   * Returns first available packet for transmission. The packet isn't removed from queue.  
   *
   * \param hdr the header of the dequeued packet
   * \param tStamp
   * \param blockedPackets
   * \return packet
   */
  Ptr<const Packet> PeekFirstAvailable (WifiMacHeader *hdr,
                                        Time &tStamp,
                                        const QosBlockedDestinations *blockedPackets);
  /**
   * Flush the queue.
   */
  void Flush (void);

  /**
   * Return if the queue is empty.
   *
   * \return true if the queue is empty, false otherwise
   */
  bool IsEmpty (void);
  /**
   * Return the current queue size.
   *
   * \return the current queue size
   */
  uint32_t GetSize (void);
protected:
  /**
   * Clean up the queue by removing packets that exceeded the maximum delay.
   */
  virtual void Cleanup (void);

  /**
   * A struct that holds information about a packet for putting
   * in a packet queue.
   */
  struct Item
  {
    /**
     * Create a struct with the given parameters.
     *
     * \param packet
     * \param hdr
     * \param tstamp
     */
    Item (Ptr<const Packet> packet,
          const WifiMacHeader &hdr,
          Time tstamp);
    Ptr<const Packet> packet; //!< Actual packet
    WifiMacHeader hdr; //!< Wifi MAC header associated with the packet
    Time tstamp; //!< timestamp when the packet arrived at the queue
  };

  /**
   * typedef for packet (struct Item) queue.
   */
  typedef std::list<struct Item> PacketQueue;
  /**
   * typedef for packet (struct Item) queue reverse iterator.
   */
  typedef std::list<struct Item>::reverse_iterator PacketQueueRI;
  /**
   * typedef for packet (struct Item) queue iterator.
   */
  typedef std::list<struct Item>::iterator PacketQueueI;
  /**
   * Return the appropriate address for the given packet (given by PacketQueue iterator).
   *
   * \param type
   * \param it
   * \return the address
   */
  Mac48Address GetAddressForPacket (enum WifiMacHeader::AddressType type, PacketQueueI it);

  PacketQueue m_queue; //!< Packet (struct Item) queue
  uint32_t m_size; //!< Current queue size
  uint32_t m_maxSize; //!< Queue capacity
  Time m_maxDelay; //!< Time to live for packets in the queue
};

} // namespace ns3

#endif /* WIFI_MAC_QUEUE_H */