📄 communication_layer.hpp
字号:
#ifndef COMMUNICATION_LAYER_H #define COMMUNICATION_LAYER_H #include <vector> #include <list> #include <iostream> using namespace std; #include <boost/shared_ptr.hpp> #include <boost/enable_shared_from_this.hpp> #include <boost/utility.hpp> #include "event.hpp" #include "utility.hpp" #include "sim_time.hpp" #include "simulation_end_listener.hpp" class Node; typedef boost::shared_ptr<Node> NodePtr; typedef boost::shared_ptr<Node const> ConstNodePtr; class NodeId; class Packet; typedef boost::shared_ptr<Packet> PacketPtr; class CommunicationLayer : public SimulationEndListener, boost::noncopyable, public boost::enable_shared_from_this<CommunicationLayer> { // Only node can call setNode() friend class Node; friend class LayerRecvEvent; public: typedef boost::shared_ptr<CommunicationLayer> CommunicationLayerPtr; typedef boost::shared_ptr<SimulationEndListener> SimulationEndListenerPtr; enum Directions { Directions_Lower, Directions_Upper }; enum Types { Types_Physical, Types_Link, Types_Network, Types_Transport, Types_Application }; virtual ~CommunicationLayer(); virtual SimulationEndListenerPtr thisSimulationEndListener() = 0; inline void insertLowerLayer(CommunicationLayerPtr layerToInsert); inline t_uint numberOfLayers(Directions direction) const; inline bool setDefaultLayer(Directions direction, t_uint newDefaultIdx); inline t_uint getDefaultLayer(Directions direction) const; inline void setLayerDelay(Directions direction, const SimTime& delay); inline SimTime getLayerDelay(Directions direction) const; bool sendToQueue(PacketPtr packet); bool sendToQueue(PacketPtr packet, t_uint lowerLayerIdx); inline void unblockQueue(); inline void blockQueue(); inline bool getQueueIsBlocked() const; inline void setMaxQueueLength(t_uint maxQueueLength); inline t_uint getMaxQueueLength() const; bool sendToLayer(Directions direction, PacketPtr packet); bool sendToLayer(Directions direction, PacketPtr packet, t_uint recvingLayerIdx); bool sendToAllLayers(Directions direction, PacketPtr packet); bool recvFromLayer(Directions direction, PacketPtr packet, CommunicationLayerPtr sendingLayer); virtual bool recvFromLayer(Directions direction, PacketPtr packet, t_uint sendingLayerIdx); virtual Types getLayerType() const = 0; NodeId getNodeId() const; protected: CommunicationLayer(NodePtr node); bool m_lowerLayerRecvEventPending; inline NodePtr getNode() const; inline bool queueIsFull() const; void blockUpperQueues(); void unblockUpperQueues(); void sendFromQueue(); inline void setLowerLayerRecvEventPending(bool isPending); void removeLayerData(PacketPtr packet) const; inline CommunicationLayerPtr getLayer(Directions direction, t_uint sendingLayerIdx); inline void insertLayer(Directions direction, CommunicationLayerPtr layerToInsert); private: static const t_uint m_DEFAULT_MAX_QUEUE_LENGTH; NodePtr m_node; SimTime m_lowerLayerDelay; SimTime m_upperLayerDelay; vector<CommunicationLayerPtr> m_lowerLayers; vector<CommunicationLayerPtr> m_upperLayers; t_uint m_defaultLowerLayerIdx; t_uint m_defaultUpperLayerIdx; t_uint m_maxQueueLength; list<pair<PacketPtr,t_uint> > m_packetQueue; bool m_queueIsBlocked; }; typedef boost::shared_ptr<CommunicationLayer> CommunicationLayerPtr; // Inline Functions inline NodePtr CommunicationLayer::getNode() const { return m_node; } inline void CommunicationLayer::insertLowerLayer( CommunicationLayerPtr layerToInsert) { assert(layerToInsert.get() != 0); assert(getNode() == layerToInsert->getNode()); insertLayer(CommunicationLayer::Directions_Lower, layerToInsert); layerToInsert->insertLayer(CommunicationLayer::Directions_Upper, shared_from_this()); } inline void CommunicationLayer::insertLayer( CommunicationLayer::Directions direction, CommunicationLayerPtr layerToInsert) { assert(layerToInsert.get() != 0); assert(getNode() == layerToInsert->getNode()); switch(direction) { case CommunicationLayer::Directions_Lower: m_lowerLayers.push_back(layerToInsert); break; case CommunicationLayer::Directions_Upper: m_upperLayers.push_back(layerToInsert); break; default: assert(false); } // If this is the first layer inserted, set it as the // default layer if(numberOfLayers(direction) == 1) setDefaultLayer(direction, 0); } inline void CommunicationLayer::blockQueue() { m_queueIsBlocked = true; } inline void CommunicationLayer::unblockQueue() { m_queueIsBlocked = false; sendFromQueue(); } inline void CommunicationLayer::setLowerLayerRecvEventPending( bool isPending) { bool previousValue = m_lowerLayerRecvEventPending; m_lowerLayerRecvEventPending = isPending; // If there was an event pending, but there no longer is, // then we need to try sending from the queue again. if(previousValue && !m_lowerLayerRecvEventPending) sendFromQueue(); } inline bool CommunicationLayer::getQueueIsBlocked() const { return m_queueIsBlocked; } inline bool CommunicationLayer::queueIsFull() const { assert(m_packetQueue.size() <= m_maxQueueLength); return (m_packetQueue.size() == m_maxQueueLength); } inline void CommunicationLayer::setMaxQueueLength(t_uint maxQueueLength) { assert(maxQueueLength > 0); m_maxQueueLength = maxQueueLength; } inline t_uint CommunicationLayer::getMaxQueueLength() const { return m_maxQueueLength; } inline CommunicationLayerPtr CommunicationLayer::getLayer( CommunicationLayer::Directions direction, t_uint sendingLayerIdx) { assert(sendingLayerIdx < numberOfLayers(direction)); vector<CommunicationLayerPtr>* layerVector = 0; switch(direction) { case Directions_Lower: layerVector = &m_lowerLayers; break; case Directions_Upper: layerVector = &m_upperLayers; break; default: assert(false); } assert(layerVector != 0); return (*layerVector)[sendingLayerIdx]; } inline t_uint CommunicationLayer::numberOfLayers( CommunicationLayer::Directions direction) const { switch(direction) { case CommunicationLayer::Directions_Lower: return m_lowerLayers.size(); break; case CommunicationLayer::Directions_Upper: return m_upperLayers.size(); break; default: assert(false); return 0; } } inline bool CommunicationLayer::setDefaultLayer( CommunicationLayer::Directions direction, t_uint newDefaultIdx) { bool setDefaultLayer = false; if(newDefaultIdx < numberOfLayers(direction)) { switch(direction) { case CommunicationLayer::Directions_Lower: m_defaultLowerLayerIdx = newDefaultIdx; break; case CommunicationLayer::Directions_Upper: m_defaultUpperLayerIdx = newDefaultIdx; break; default: assert(false); } setDefaultLayer = true; } return setDefaultLayer; } inline t_uint CommunicationLayer::getDefaultLayer( CommunicationLayer::Directions direction) const { switch(direction) { case CommunicationLayer::Directions_Lower: return m_defaultLowerLayerIdx; break; case CommunicationLayer::Directions_Upper: return m_defaultUpperLayerIdx; break; default: assert(false); return 0; } } inline void CommunicationLayer::setLayerDelay( CommunicationLayer::Directions direction, const SimTime& delay) { switch(direction) { case CommunicationLayer::Directions_Lower: m_lowerLayerDelay = delay; break; case CommunicationLayer::Directions_Upper: m_upperLayerDelay = delay; break; default: assert(false); } } inline SimTime CommunicationLayer::getLayerDelay( CommunicationLayer::Directions direction) const { switch(direction) { case CommunicationLayer::Directions_Lower: return m_lowerLayerDelay; break; case CommunicationLayer::Directions_Upper: return m_upperLayerDelay; break; default: assert(false); SimTime neverReturned; return neverReturned; } } // Overloaded Operators inline ostream& operator<< (ostream& s, const CommunicationLayer& communicationLayer) { return s<< "CommunicationLayer state (pointer=" << &communicationLayer << ", number of upper layers= " << communicationLayer.numberOfLayers( CommunicationLayer::Directions_Upper) << ", number of lower layers= " << communicationLayer.numberOfLayers( CommunicationLayer::Directions_Lower) << ", default upper layer= " << communicationLayer.getDefaultLayer( CommunicationLayer::Directions_Upper) << ", default lower layer= " << communicationLayer.getDefaultLayer( CommunicationLayer::Directions_Lower) << ", upper layer delay= " << communicationLayer.getLayerDelay( CommunicationLayer::Directions_Upper) << ", lower layer delay= " << communicationLayer.getLayerDelay( CommunicationLayer::Directions_Lower) << ")"; } inline ostream& operator<< (ostream& s, const CommunicationLayer::Types& communicationLayerType) { switch (communicationLayerType) { case CommunicationLayer::Types_Physical: s << "PHY"; break; case CommunicationLayer::Types_Link: s << "LINK"; break; case CommunicationLayer::Types_Network: s << "NET"; break; case CommunicationLayer::Types_Transport: s << "TRAN"; break; case CommunicationLayer::Types_Application: s << "APP"; break; } return s; } // Event Subclasses class LayerRecvEvent : public Event { public: typedef boost::shared_ptr<LayerRecvEvent> LayerRecvEventPtr; static inline LayerRecvEventPtr create( CommunicationLayer::Directions sendDirection, PacketPtr packet, CommunicationLayerPtr recvingLayer, CommunicationLayerPtr sendingLayer) { LayerRecvEventPtr p(new LayerRecvEvent(sendDirection, packet, recvingLayer, sendingLayer)); return p; } void execute() { // Give a default recvDirection for the compiler even // though the switch statement should be setup such // that it is guaranteed to set recvDirection. CommunicationLayer::Directions recvDirection = CommunicationLayer::Directions_Upper; // Just toggle the direction from the sending direction. switch(m_sendDirection) { case CommunicationLayer::Directions_Lower: recvDirection = CommunicationLayer::Directions_Upper; break; case CommunicationLayer::Directions_Upper: recvDirection = CommunicationLayer::Directions_Lower; break; default: assert(false); } assert(m_recvingLayer.get() != 0); m_recvingLayer->recvFromLayer(recvDirection, m_packet, m_sendingLayer); if(m_sendDirection == CommunicationLayer::Directions_Lower) { assert(m_sendingLayer.get() != 0); m_sendingLayer->setLowerLayerRecvEventPending(false); } } protected: LayerRecvEvent(CommunicationLayer::Directions sendDirection, PacketPtr packet, CommunicationLayerPtr recvingLayer, CommunicationLayerPtr sendingLayer) : Event() { m_sendDirection = sendDirection; m_packet = packet; m_recvingLayer = recvingLayer; m_sendingLayer = sendingLayer; } private: PacketPtr m_packet; CommunicationLayer::Directions m_sendDirection; CommunicationLayerPtr m_recvingLayer; CommunicationLayerPtr m_sendingLayer; }; typedef boost::shared_ptr<LayerRecvEvent> LayerRecvEventPtr; #endif // COMMUNICATION_LAYER_H
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -