PeerLink refactored (use peer-link.h)

This commit is contained in:
Pavel Boyko
2009-03-20 14:50:05 +03:00
parent 8d29fe0b56
commit d65bd66445
4 changed files with 821 additions and 0 deletions

View File

@@ -28,6 +28,7 @@
#include "ns3/nstime.h"
#include "ns3/dot11s-codes.h"
#include "ns3/wifi-information-element.h"
namespace ns3 {
/**
* \ingroup dot11s

View File

@@ -0,0 +1,569 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 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>
*/
#include "peer-link.h"
#include "ns3/log.h"
#include "ns3/uinteger.h"
NS_LOG_COMPONENT_DEFINE ("Dot11sPeerManagementProtocol");
namespace ns3 {
NS_OBJECT_ENSURE_REGISTERED(PeerLink);
TypeId
PeerLink::GetTypeId()
{
static TypeId tid = TypeId ("ns3::PeerLink")
.SetParent<Object> ()
.AddConstructor<PeerLink> ()
.AddAttribute ("RetryTimeout", "Retry timeout",
TimeValue (TimeValue (MicroSeconds (40 * 1024))),
MakeTimeAccessor (&PeerLink::m_retryTimeout),
MakeTimeChecker ()
)
.AddAttribute ("HoldingTimeout", "Holding timeout",
TimeValue (TimeValue (MicroSeconds (40 * 1024))),
MakeTimeAccessor (&PeerLink::m_holdingTimeout),
MakeTimeChecker ()
)
.AddAttribute ("ConfirmTimeout", "Confirm timeout",
TimeValue (TimeValue (MicroSeconds (40 * 1024))),
MakeTimeAccessor (&PeerLink::m_confirmTimeout),
MakeTimeChecker ()
)
.AddAttribute ("MaxRetries", "Maximum number of retries",
UintegerValue (4),
MakeUintegerAccessor (&PeerLink::m_maxRetries),
MakeUintegerChecker<uint16_t> ()
)
.AddAttribute ("MaxBeaconLoss", "Maximum number of lost beacons before link will be closed",
UintegerValue (3),
MakeUintegerAccessor (&PeerLink::m_maxBeaconLoss),
MakeUintegerChecker<uint16_t> ()
);
return tid;
}
//-----------------------------------------------------------------------------
// PeerLink public interface
//-----------------------------------------------------------------------------
PeerLink::PeerLink ():
m_localLinkId (0),
m_peerLinkId (0),
m_state (IDLE),
m_retryCounter (0)
{
}
void
PeerLink::SetPeerAddress (Mac48Address macaddr)
{
m_peerAddress = macaddr;
}
void
PeerLink::SetLocalAddress (Mac48Address macaddr)
{
m_localAddress = macaddr;
}
void
PeerLink::SetLocalLinkId (uint16_t id)
{
m_localLinkId = id;
}
void
PeerLink::SetLocalAid (uint16_t aid)
{
m_assocId = aid;
}
void
PeerLink::SetBeaconInformation (Time lastBeacon, Time beaconInterval)
{
m_lastBeacon = lastBeacon;
m_beaconInterval = beaconInterval;
m_beaconLossTimer.Cancel ();
Time delay = Seconds(beaconInterval.GetSeconds() * m_maxBeaconLoss);
NS_ASSERT (delay.GetMicroSeconds() != 0);
m_beaconLossTimer = Simulator::Schedule (delay, &PeerLink::BeaconLoss, this);
}
void
PeerLink::MLMESetSignalStatusCallback (PeerLink::SignalStatusCallback cb)
{
m_linkStatusCallback = cb;
}
void
PeerLink::BeaconLoss ()
{
StateMachine (CNCL);
}
void
PeerLink::SetBeaconTimingElement (IeDot11sBeaconTiming beaconTiming)
{
m_beaconTiming = beaconTiming;
}
Mac48Address
PeerLink::GetPeerAddress () const
{
return m_peerAddress;
}
Mac48Address
PeerLink::GetLocalAddress () const
{
return m_localAddress;
}
uint16_t
PeerLink::GetLocalAid () const
{
return m_assocId;
}
Time
PeerLink::GetLastBeacon () const
{
return m_lastBeacon;
}
Time
PeerLink::GetBeaconInterval () const
{
return m_beaconInterval;
}
IeDot11sBeaconTiming
PeerLink::GetBeaconTimingElement () const
{
return m_beaconTiming;
}
void
PeerLink::ClearTimingElement ()
{
m_beaconTiming.ClearTimingElement ();
}
void PeerLink::MLMECancelPeerLink (dot11sReasonCode reason)
{
StateMachine (CNCL,reason);
}
void PeerLink::MLMEPassivePeerLinkOpen ()
{
StateMachine (PASOPN);
}
void PeerLink::MLMEActivePeerLinkOpen ()
{
StateMachine (ACTOPN);
}
void PeerLink::MLMEPeeringRequestReject ()
{
StateMachine (REQ_RJCT, REASON11S_PEER_LINK_CANCELLED);
}
void PeerLink::Close (uint16_t localLinkId, uint16_t peerLinkId, dot11sReasonCode reason)
{
if (peerLinkId != 0 && m_localLinkId != peerLinkId)
return;
if (m_peerLinkId == 0)
m_peerLinkId = localLinkId;
else if (m_peerLinkId != localLinkId)
return;
StateMachine (CLS_ACPT, reason);
}
void PeerLink::OpenAccept (uint16_t localLinkId, IeDot11sConfiguration conf)
{
if (m_peerLinkId == 0)
m_peerLinkId = localLinkId;
m_configuration = conf;
StateMachine (OPN_ACPT);
}
void PeerLink::OpenReject (uint16_t localLinkId, IeDot11sConfiguration conf,dot11sReasonCode reason)
{
if ( m_peerLinkId == 0)
m_peerLinkId = localLinkId;
m_configuration = conf;
StateMachine (OPN_RJCT, reason);
}
void
PeerLink::ConfirmAccept (uint16_t localLinkId, uint16_t peerLinkId, uint16_t peerAid, IeDot11sConfiguration conf)
{
if ( m_localLinkId != peerLinkId)
return;
if ( m_peerLinkId == 0)
m_peerLinkId = localLinkId;
else if ( m_peerLinkId != localLinkId )
return;
m_configuration = conf;
m_peerAssocId = peerAid;
StateMachine (CNF_ACPT);
}
void
PeerLink::ConfirmReject (uint16_t localLinkId, uint16_t peerLinkId,
IeDot11sConfiguration conf,dot11sReasonCode reason)
{
if (m_localLinkId != peerLinkId)
return;
if (m_peerLinkId == 0)
m_peerLinkId = localLinkId;
else if (m_peerLinkId != localLinkId)
return;
m_configuration = conf;
StateMachine (CNF_RJCT, reason);
}
bool
PeerLink::LinkIsEstab () const
{
return (m_state == ESTAB);
}
bool
PeerLink::LinkIsIdle () const
{
return (m_state == IDLE);
}
//-----------------------------------------------------------------------------
// Private
//-----------------------------------------------------------------------------
void
PeerLink::StateMachine (PeerEvent event,dot11sReasonCode reasoncode)
{
switch (m_state)
{
case IDLE:
switch (event)
{
case PASOPN:
m_state = LISTEN;
break;
case ACTOPN:
m_state = OPN_SNT;
SendPeerLinkOpen ();
SetRetryTimer ();
break;
default:
{}
}
break;
case LISTEN:
switch (event)
{
case CNCL:
case CLS_ACPT:
m_state = IDLE;
// TODO Callback MLME-SignalPeerLinkStatus
break;
case REQ_RJCT:
SendPeerLinkClose (reasoncode);
break;
case ACTOPN:
m_state = OPN_SNT;
SendPeerLinkOpen ();
SetRetryTimer ();
break;
case OPN_ACPT:
m_state = OPN_RCVD;
SendPeerLinkConfirm ();
SendPeerLinkOpen ();
SetRetryTimer ();
break;
default:
{}
}
break;
case OPN_SNT:
switch (event)
{
case TOR1:
SendPeerLinkOpen ();
m_retryCounter++;
SetRetryTimer ();
break;
case CNF_ACPT:
m_state = CNF_RCVD;
ClearRetryTimer ();
SetConfirmTimer ();
break;
case OPN_ACPT:
m_state = OPN_RCVD;
SendPeerLinkConfirm ();
break;
case CLS_ACPT:
m_state = HOLDING;
ClearRetryTimer ();
SendPeerLinkClose (REASON11S_MESH_CLOSE_RCVD);
SetHoldingTimer ();
break;
case OPN_RJCT:
case CNF_RJCT:
m_state = HOLDING;
ClearRetryTimer ();
SendPeerLinkClose (reasoncode);
SetHoldingTimer ();
break;
case TOR2:
m_state = HOLDING;
ClearRetryTimer ();
SendPeerLinkClose (REASON11S_MESH_MAX_RETRIES);
SetHoldingTimer ();
break;
case CNCL:
m_state = HOLDING;
ClearRetryTimer ();
SendPeerLinkClose (REASON11S_PEER_LINK_CANCELLED);
SetHoldingTimer ();
break;
default:
{}
}
break;
case CNF_RCVD:
switch (event)
{
case CNF_ACPT:
break;
case OPN_ACPT:
m_state = ESTAB;
NS_LOG_DEBUG ("I am "<<m_localAddress<<", established link with "<<m_peerAddress<<", at "<<Simulator::Now());
ClearConfirmTimer ();
SendPeerLinkConfirm ();
m_linkStatusCallback (m_localAddress, m_peerAddress, true);
// TODO Callback MLME-SignalPeerLinkStatus
break;
case CLS_ACPT:
m_state = HOLDING;
ClearConfirmTimer ();
SendPeerLinkClose (REASON11S_MESH_CLOSE_RCVD);
SetHoldingTimer ();
break;
case CNF_RJCT:
case OPN_RJCT:
m_state = HOLDING;
ClearConfirmTimer ();
SendPeerLinkClose (reasoncode);
SetHoldingTimer ();
break;
case CNCL:
m_state = HOLDING;
ClearConfirmTimer ();
SendPeerLinkClose (REASON11S_PEER_LINK_CANCELLED);
SetHoldingTimer ();
break;
case TOC:
m_state = HOLDING;
SendPeerLinkClose (REASON11S_MESH_CONFIRM_TIMEOUT);
SetHoldingTimer ();
break;
default:
{}
}
break;
case OPN_RCVD:
switch (event)
{
case TOR1:
SendPeerLinkOpen ();
m_retryCounter++;
SetRetryTimer ();
break;
case CNF_ACPT:
NS_LOG_DEBUG ("I am "<<m_localAddress<<", established link with "<<m_peerAddress<<", at "<<Simulator::Now());
m_state = ESTAB;
ClearRetryTimer ();
m_linkStatusCallback (m_localAddress, m_peerAddress, true);
// TODO Callback MLME-SignalPeerLinkStatus
break;
case CLS_ACPT:
m_state = HOLDING;
ClearRetryTimer ();
SendPeerLinkClose (REASON11S_MESH_CLOSE_RCVD);
SetHoldingTimer ();
break;
case OPN_RJCT:
case CNF_RJCT:
m_state = HOLDING;
ClearRetryTimer ();
SendPeerLinkClose (reasoncode);
SetHoldingTimer ();
break;
case TOR2:
m_state = HOLDING;
ClearRetryTimer ();
SendPeerLinkClose (REASON11S_MESH_MAX_RETRIES);
SetHoldingTimer ();
break;
case CNCL:
m_state = HOLDING;
ClearRetryTimer ();
SendPeerLinkClose (REASON11S_PEER_LINK_CANCELLED);
SetHoldingTimer ();
break;
default:
{}
}
break;
case ESTAB:
switch (event)
{
case OPN_ACPT:
SendPeerLinkConfirm ();
break;
case CLS_ACPT:
NS_LOG_DEBUG ("I am "<<m_localAddress<<", CLOSED link with "<<m_peerAddress<<", at "<<Simulator::Now()<<" Close received");
m_state = HOLDING;
SendPeerLinkClose (REASON11S_MESH_CLOSE_RCVD);
SetHoldingTimer ();
m_linkStatusCallback (m_localAddress, m_peerAddress, false);
break;
case OPN_RJCT:
case CNF_RJCT:
NS_LOG_DEBUG ("I am "<<m_localAddress<<", CLOSED link with "<<m_peerAddress<<", at "<<Simulator::Now()<<" Rejected open or confirm");
m_state = HOLDING;
ClearRetryTimer ();
SendPeerLinkClose (reasoncode);
SetHoldingTimer ();
m_linkStatusCallback (m_localAddress, m_peerAddress, false);
break;
case CNCL:
NS_LOG_DEBUG ("I am "<<m_localAddress<<", CLOSED link with "<<m_peerAddress<<", at "<<Simulator::Now()<<" Link cancelled");
m_state = HOLDING;
SendPeerLinkClose (REASON11S_PEER_LINK_CANCELLED);
SetHoldingTimer ();
m_linkStatusCallback (m_localAddress, m_peerAddress, false);
break;
default:
{}
}
break;
case HOLDING:
switch (event)
{
case CLS_ACPT:
ClearHoldingTimer ();
case TOH:
m_state = IDLE;
// TODO Callback MLME-SignalPeerLinkStatus
break;
case OPN_ACPT:
case CNF_ACPT:
m_state = HOLDING;
// reason not spec in D2.0
SendPeerLinkClose (REASON11S_PEER_LINK_CANCELLED);
break;
case OPN_RJCT:
case CNF_RJCT:
m_state = HOLDING;
SendPeerLinkClose (reasoncode);
break;
default:
{}
}
break;
}
}
void PeerLink::ClearRetryTimer ()
{
m_retryTimer.Cancel ();
}
void PeerLink::ClearConfirmTimer ()
{
m_confirmTimer.Cancel ();
}
void PeerLink::ClearHoldingTimer ()
{
m_holdingTimer.Cancel ();
}
void PeerLink::SendPeerLinkClose (dot11sReasonCode reasoncode)
{
IeDot11sPeerManagement peerElement;
peerElement.SetPeerClose (m_localLinkId, m_peerLinkId, reasoncode);
//m_mac->SendPeerLinkClose (peerElement,m_peerAddress);
}
void PeerLink::SendPeerLinkOpen ()
{
IeDot11sPeerManagement peerElement;
peerElement.SetPeerOpen (m_localLinkId);
//NS_ASSERT (m_mac != NULL);
//m_mac->SendPeerLinkOpen (peerElement, m_peerAddress);
}
void PeerLink::SendPeerLinkConfirm ()
{
IeDot11sPeerManagement peerElement;
peerElement.SetPeerConfirm (m_localLinkId, m_peerLinkId);
//m_mac->SendPeerLinkConfirm (peerElement, m_peerAddress, m_assocId);
}
void PeerLink::SetHoldingTimer ()
{
m_holdingTimer = Simulator::Schedule (m_holdingTimeout, &PeerLink::HoldingTimeout, this);
}
void PeerLink::HoldingTimeout ()
{
StateMachine (TOH);
}
void PeerLink::SetRetryTimer ()
{
m_retryTimer = Simulator::Schedule (m_retryTimeout, &PeerLink::RetryTimeout, this);
}
void PeerLink::RetryTimeout ()
{
if ( m_retryCounter < m_maxRetries)
StateMachine (TOR1);
else
StateMachine (TOR2);
}
void PeerLink::SetConfirmTimer ()
{
m_confirmTimer = Simulator::Schedule (m_confirmTimeout, &PeerLink::ConfirmTimeout, this);
}
void PeerLink::ConfirmTimeout ()
{
StateMachine (TOC);
}
}

View File

@@ -0,0 +1,249 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 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>
*/
#ifndef PEERLLINK_H_
#define PEERLLINK_H_
#include "ns3/object.h"
#include "ns3/nstime.h"
#include "ns3/callback.h"
#include "ns3/mac48-address.h"
#include "ns3/simulator.h"
#include "ie-dot11s-beacon-timing.h"
#include "ie-dot11s-peer-management.h"
#include "ie-dot11s-configuration.h"
namespace ns3 {
/**
* \ingroup dot11s
*
* \brief Peer link model for 802.11s Peer Management protocol
*/
class PeerLink : public Object
{
public:
/// Support object system
static TypeId GetTypeId();
/// C-tor create empty link
PeerLink ();
/// Process beacon received from peer
void SetBeaconInformation (Time lastBeacon, Time BeaconInterval);
/**
* \brief Method used to detecet peer link changes
*
* \param bool if true - opened new link, if false - link closed
*/
void SetLinkStatusCallback (Callback<void, Mac48Address, Mac48Address, bool> cb);
/**
* \name Peer link geeters/setters
* \{
*/
void SetPeerAddress (Mac48Address macaddr);
void SetLocalAddress (Mac48Address macaddr);
void SetLocalLinkId (uint16_t id);
void SetPeerLinkId (uint16_t id);
void SetLocalAid (uint16_t aid);
void SetPeerAid (uint16_t aid);
void SetBeaconTimingElement (IeDot11sBeaconTiming beaconTiming);
void SetPeerLinkDescriptorElement (IeDot11sPeerManagement peerLinkElement);
Mac48Address GetPeerAddress () const;
Mac48Address GetLocalAddress () const;
uint16_t GetLocalAid () const;
Time GetLastBeacon () const;
Time GetBeaconInterval () const;
IeDot11sBeaconTiming GetBeaconTimingElement ()const;
IeDot11sPeerManagement GetPeerLinkDescriptorElement ()const;
void ClearTimingElement ();
//\}
/**
* \name MLME
* \{
*/
/// MLME-CancelPeerLink.request
void MLMECancelPeerLink (dot11sReasonCode reason);
/// MLME-PassivePeerLinkOpen.request
void MLMEPassivePeerLinkOpen ();
/// MLME-ActivePeerLinkOpen.request
void MLMEActivePeerLinkOpen ();
/// MLME-PeeringRequestReject
void MLMEPeeringRequestReject ();
/// Callback type for MLME-SignalPeerLinkStatus event
typedef Callback<void, Mac48Address, Mac48Address, bool> SignalStatusCallback;
/// Set callback
void MLMESetSignalStatusCallback (SignalStatusCallback);
//\}
/**
* \name Link response to received management frames
*
* \attention In all this methods {local/peer}LinkID correspond to _peer_ station, as written in
* received frame, e.g. I am peerLinkID and peer link is localLinkID .
*
* TODO is that clear?
*
* \{
*/
/// Close link
void Close (uint16_t localLinkID, uint16_t peerLinkID, dot11sReasonCode reason);
/// Accept open link
void OpenAccept (uint16_t localLinkId, IeDot11sConfiguration conf);
/// Reject open link
void OpenReject (uint16_t localLinkId, IeDot11sConfiguration conf, dot11sReasonCode reason);
/// Confirm accept
void ConfirmAccept (
uint16_t localLinkId,
uint16_t peerLinkId,
uint16_t peerAid,
IeDot11sConfiguration conf
);
/// Confirm reject
void ConfirmReject (
uint16_t localLinkId,
uint16_t peerLinkId,
IeDot11sConfiguration conf,
dot11sReasonCode reason
);
//\}
/// True if link is established
bool LinkIsEstab () const;
/// True if link is idle. Link can be deleted in this state
bool LinkIsIdle () const;
private:
/// Peer link states, see 802.11s draft 11B.3.3.1
enum PeerState {
IDLE,
LISTEN,
OPN_SNT,
CNF_RCVD,
OPN_RCVD,
ESTAB,
HOLDING,
};
/// Peer link events, see 802.11s draft 11B.3.3.2
enum PeerEvent
{
CNCL, ///< MLME-CancelPeerLink
PASOPN, ///< MLME-PassivePeerLinkOpen
ACTOPN, ///< MLME-ActivePeerLinkOpen
CLS_ACPT, ///< PeerLinkClose_Accept
OPN_ACPT, ///< PeerLinkOpen_Accept
OPN_RJCT, ///< PeerLinkOpen_Reject
REQ_RJCT, ///< PeerLinkOpenReject by internal reason
CNF_ACPT, ///< PeerLinkConfirm_Accept
CNF_RJCT, ///< PeerLinkConfirm_Reject
TOR1, ///< Timeout of retry timer
TOR2, ///< also timeout of retry timer
TOC, ///< Timeout of confirm timer
TOH, ///< Timeout of holding (gracefull closing) timer
};
private:
/// State transition
void StateMachine (PeerEvent event, dot11sReasonCode = REASON11S_RESERVED);
/**
* \name Event handlers
* \{
*/
void ClearRetryTimer ();
void ClearConfirmTimer ();
void ClearHoldingTimer ();
void SetHoldingTimer ();
void SetRetryTimer ();
void SetConfirmTimer ();
//\}
/**
* \name Work with management frames
* \{
*/
void SendPeerLinkClose (dot11sReasonCode reasoncode);
void SendPeerLinkOpen ();
void SendPeerLinkConfirm ();
//\}
/**
* \name Timeout handlers
* \{
*/
void HoldingTimeout ();
void RetryTimeout ();
void ConfirmTimeout ();
//\}
private:
/// Peer address
Mac48Address m_peerAddress;
/// My own address
Mac48Address m_localAddress;
/// My ID of this link
uint16_t m_localLinkId;
/// Peer ID of this link
uint16_t m_peerLinkId;
/// My association ID
uint16_t m_assocId;
/// Assoc Id assigned to me by peer
uint16_t m_peerAssocId;
/// When last beacon was sent (TODO or received?)
Time m_lastBeacon;
/// Current beacon interval on corresponding interface
Time m_beaconInterval;
/// Current state
PeerState m_state;
/// Mesh interface configuration
IeDot11sConfiguration m_configuration;
// State is a bitfield as defined as follows:
// This are states for a given
IeDot11sBeaconTiming m_beaconTiming;
/**
* \name Timers & counters used for internal state transitions
* \{
*/
Time m_retryTimeout;
EventId m_retryTimer;
Time m_holdingTimeout;
EventId m_holdingTimer;
Time m_confirmTimeout;
EventId m_confirmTimer;
uint16_t m_maxRetries;
uint16_t m_retryCounter;
EventId m_beaconLossTimer;
uint16_t m_maxBeaconLoss;
//\}
/// ?
void BeaconLoss ();
/// How to report my status change
SignalStatusCallback m_linkStatusCallback;
};
}
#endif /* PEERLLINK_H_ */

View File

@@ -13,6 +13,7 @@ def build(bld):
'peer-manager-plugin.cc',
'peer-manager-protocol.cc',
'dot11s-helper.cc',
'peer-link.cc',
]
headers = bld.new_task_gen('ns3header')
headers.module = '802.11s'
@@ -27,6 +28,7 @@ def build(bld):
'peer-manager-protocol.h',
'peer-manager-plugin.h',
'dot11s-helper.h',
'peer-link.h',
]
# obj = bld.create_ns3_program('wifi-phy-test',