src/devices/mesh/hwmp.h
author Kirill Andreev <andreev@iitp.ru>
Wed, 25 Mar 2009 12:23:12 +0300
changeset 4876 d78f1b978dac
parent 4853 cb12c7003071
permissions -rw-r--r--
Rstructured file names: IeDot11s* no is Ie, because it is in namespace dot11s

/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2008,2009 IITP RAS
 *
 * 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
 *
 * Authors: Kirill Andreev <andreev@iitp.ru>
 *          Aleksey Kovalenko <kovalenko@iitp.ru>
 *          Pavel Boyko <boyko@iitp.ru>
 */


#ifndef HWMP_H
#define HWMP_H

#include <map>
#include <queue>
#include "ns3/tag.h"
#include "ns3/object.h"
#include "ns3/mac48-address.h"
#include "ns3/mesh-l2-routing-protocol.h"
#include "ns3/packet.h"
#include "ns3/hwmp-state.h"
namespace ns3 {
class HwmpState;
/**
 * \ingroup mesh
 *
 * \brief Hwmp tag implements interaction between HWMP
 * protocol and MeshWifiMac
 *
 * \details Hwmp tag keeps the following:
 * 1. When packet is passed from Hwmp to 11sMAC:
 *  - retransmitter address,
 *  - TTL value,
 * 2. When packet is passed to Hwmp from 11sMAC:
 *  - lasthop address,
 *  - TTL value,
 *  - metric value (metric of link is recalculated
 *  at each packet, but routing table stores metric
 *  obtained during path discovery procedure)
 */
class HwmpTag : public Tag
{
public:
  HwmpTag ();
  ~HwmpTag ();
  void  SetAddress (Mac48Address retransmitter);
  Mac48Address GetAddress ();
  void  SetTtl (uint8_t ttl);
  uint8_t GetTtl ();
  void  SetMetric (uint32_t metric);
  uint32_t GetMetric ();
  void  SetSeqno (uint32_t seqno);
  uint32_t GetSeqno ();
  void  DecrementTtl ();

  static  TypeId  GetTypeId ();
  virtual TypeId  GetInstanceTypeId () const;
  virtual uint32_t GetSerializedSize () const;
  virtual void  Serialize (TagBuffer i) const;
  virtual void  Deserialize (TagBuffer i);
  virtual void  Print (std::ostream &os) const;
private:
  Mac48Address m_address;
  uint8_t  m_ttl;
  uint32_t m_metric;
  uint32_t m_seqno;
};
/**
 * \ingroup mesh
 */
class Hwmp : public MeshL2RoutingProtocol
{
public:
  static TypeId GetTypeId ();
  Hwmp ();
  ~Hwmp ();
  void DoDispose ();
  //intheritedfrom L2RoutingProtocol
  /**
   * \brief L2Routing protocol base class metod
   *
   * \details Route resolving procedure consits
   * of the following steps:
   * 1. Find reactive route and send a packet.
   * 2. Find all ports which are operate in
   * 'Proactive' mode and find a proper default
   * routes. and send packet to all proactive
   * 'ports'.
   * 3. If there are ports which are operate in
   * reactive mode - queue packet and start
   * route reactive path discovery
   *
   * \bug Now packet is sent to the 'best root'
   * rather than to the best root at each port
   */
  bool RequestRoute (
    uint32_t  sourceIface,
    const Mac48Address source,
    const Mac48Address destination,
    Ptr<Packet>  packet,
    uint16_t  protocolType,
    MeshL2RoutingProtocol::RouteReplyCallback  routeReply
  );
  bool AttachPorts (std::vector<Ptr<NetDevice> >);
  /**
   * \brief Disables port by index.
   * \details Needed for external modules like
   * clusterization.
   */
  void DisablePort (uint32_t port);
  /**
   * \brief enables port
   */
  void EnablePort (uint32_t port);
  /**
   * \brief Setting proative mode.
   * \details To enable proactive mode you must
   * set a root node. Choosing the route is made
   * in accordance with the following:
   *  1. Find 'reactive' route. If route is
   *  found - send a packet using this
   *  information
   *  2. If there is no reactive route -
   *  find proactive or 'default' route.
   * \attention Comparsion between proactive and
   * reactive routes is incorrect, because we
   * have metric to root MP in te first case and
   * metric to the destination in the second
   * case.
   * \param port is the port where proactive
   * mode should be activated
   */
  void SetRoot (uint32_t port);
  /**
   * \brief Disable root functionality at a
   * given port
   */
  void UnSetRoot (uint32_t port);
  /**
   * \brief HwmpState retrns to Hwmp class all
   * routing information obtained from all HWMP
   * action frames
   */
  void ObtainRoutingInformation (
    HwmpState::INFO info
  );
  /**
   * \brief Hwmp state noyifyes that neighbour
   * is dissapeared. Hwmp state knows about peer
   * failure from MAC
   */
  void PeerFailure (Mac48Address peerAddress);
  void SetMaxTtl (uint8_t ttl);
  uint8_t  GetMaxTtl ();
private:
  static const uint32_t MAX_SEQNO = 0xffffffff;
  //candidate queue is implemented inside the
  //protocol:
  void  SetMaxQueueSize (int maxPacketsPerDestination);
  int  m_maxQueueSize;
  bool  QueuePacket (MeshL2RoutingProtocol::QueuedPacket packet);
  MeshL2RoutingProtocol::QueuedPacket  DequeuePacket (Mac48Address dst);
  void  SendAllPossiblePackets (Mac48Address dst);
  std::map<Mac48Address, std::queue<QueuedPacket> >  m_rqueue;
  //devices and HWMP states:
  enum DeviceState {
    ENABLED,
    DISABLED
  };
  enum DeviceMode {
    REACTIVE,
    PROACTIVE,
    ROOT
  };
  std::vector<enum DeviceState>  m_states;
  std::vector<enum DeviceMode>   m_modes;
  std::vector<Ptr<HwmpState> >   m_hwmpStates;
  //Routing table:
  Ptr<HwmpRtable>  m_rtable;
  //Proactive routines:
  /**
   * \brief Set port state as proactive.
   * \details mode is supposed to be proactive
   * when proatcive PREQ with a valid
   * information was received.
   */
  void  SetProactive (uint32_t port);
  /**
   * \brief Checks if the port is root, if true
   * - no default routes must be used at this
   * port
   */
  bool  IsRoot (uint32_t port);
  /**
   * \brief Interaction with HwmpState class -
   * request for starting routing discover
   * procedure (reactive route discovery!)
   * \param Mac48Address is destination to be
   * resolved
   */
  std::vector< Callback<void, Mac48Address> >  m_requestCallback;
  /**
   * \brief Callback that shall be executed when
   * need to send Path error
   * \param std::vector<Mac48Address> is the
   * list of unreachable destinations
   * \param std::vector<Mac48Address> is
   * receivers of PERR
   */
  std::vector<Callback<void,std::vector<HwmpRtable::FailedDestination> > >  m_pathErrorCallback;
  void StartPathErrorProcedure (
    std::vector<HwmpRtable::FailedDestination> destinations,
    uint32_t port);
  /**
   * \brief HwmpState need to know where to
   * retransmit PERR, only HWMP knows how to
   * retransmit it (broadcast/unicast) and only
   * HWMP has accessto routing table
   */
  std::vector<Mac48Address>  GetRetransmittersForFailedDestinations (
    std::vector<HwmpRtable::FailedDestination> failedDest,
    uint32_t port);
  /**
   * \brief Needed by HwmpState to find routes in case
   * of intermediate reply and choosing the
   * better route
   *
   */
  HwmpRtable::LookupResult  RequestRouteForAddress (const Mac48Address& destination);
  HwmpRtable::LookupResult  RequestRootPathForPort (uint32_t port);

  /**
   * \attention mesh seqno is processed at HWMP
   */
  uint32_t m_seqno;
  std::map<Mac48Address, uint32_t/**/>  m_seqnoDatabase;
  //Timers:
  /**
   * /brief checks when last preq was initiated, returns
   * false when retry has not expired
   */
  bool  ShouldSendPreq (Mac48Address dst);
  /**
   * \brief Generates PREQ retry when route is
   * still unresolved after first PREQ
   * If number of retries greater than
   * dot11sParameters::dot11MeshHWMPmaxPREQretries,
   * we return all packets to upper layers
   */
  void  RetryPathDiscovery (Mac48Address dst, uint8_t numOfRetry);
  /**
   * Keeps PREQ retry timers for every
   * destination
   */
  std::map<Mac48Address, EventId>  m_timeoutDatabase;
  /**
   * Configurable parameters:
   */
  uint8_t  m_maxTtl;
  bool     m_broadcastPerr;
};
} //namespace ns3
#endif