00001
00002 #ifndef MAC_PROTOCOL_H
00003 #define MAC_PROTOCOL_H
00004
00005 #include <boost/shared_ptr.hpp>
00006
00007 #include "timer.hpp"
00008 #include "simulation_end_listener.hpp"
00009
00010 class LinkLayer;
00011 typedef boost::shared_ptr<LinkLayer> LinkLayerPtr;
00012
00017 class MacProtocol : public SimulationEndListener {
00018 friend class SendToLinkLayerEvent;
00019 public:
00021 typedef boost::shared_ptr<MacProtocol> MacProtocolPtr;
00023 typedef boost::shared_ptr<SimulationEndListener>
00024 SimulationEndListenerPtr;
00025
00027 virtual ~MacProtocol();
00028
00035 virtual MacProtocolPtr thisMacProtocol() = 0;
00036
00043 virtual SimulationEndListenerPtr thisSimulationEndListener() = 0;
00044
00052 bool startSendTimer(
00053 CommunicationLayer::Directions direction, PacketPtr packet,
00054 const SimTime& delay);
00055
00065 virtual bool recvFromLinkLayer(
00066 CommunicationLayer::Directions direction, PacketPtr packet,
00067 t_uint sendingLayerIdx);
00068
00076 virtual bool handleRecvdMacPacket(PacketPtr packet,
00077 t_uint sendingLayerIdx) = 0;
00078
00086 virtual bool handleRecvdUpperLayerPacket(PacketPtr packet,
00087 t_uint sendingLayerIdx) = 0;
00088
00096 virtual void handleChannelBusy(PacketPtr packet) = 0;
00097
00105 virtual void handlePacketSent(PacketPtr packet) = 0;
00106
00113 void setLinkLayer(LinkLayerPtr linkLayer);
00114
00119 inline NodePtr getNode() const
00120 {
00121 return m_node;
00122 }
00123
00124 protected:
00125
00128 MacProtocol(NodePtr node);
00129
00137 bool sendToLinkLayer(
00138 CommunicationLayer::Directions direction, PacketPtr packet);
00139
00143 void blockUpperQueues();
00144
00148 void unblockUpperQueues();
00149
00154 bool getQueueIsBlocked() const;
00155
00157 TimerPtr m_sendTimer;
00158
00164 boost::weak_ptr<LinkLayer> m_linkLayer;
00165
00166 private:
00167
00169 NodePtr m_node;
00170
00171 };
00172 typedef boost::shared_ptr<MacProtocol> MacProtocolPtr;
00173
00175
00177
00182 class SlottedMac : public MacProtocol {
00183 friend class SlottedMacSlotEvent;
00184 public:
00186 typedef boost::shared_ptr<SlottedMac> SlottedMacPtr;
00187
00189 virtual ~SlottedMac() {};
00190
00191 protected:
00192
00194 static const double m_DEFAULT_SLOT_TIME;
00195
00197 TimerPtr m_slotTimer;
00198
00200 t_uint m_currentSlotNumber;
00201
00203 t_uint m_txSlotNumber;
00204
00208 t_uint m_numberOfSlots;
00209
00211 PacketPtr m_packetToTransmit;
00212
00214 SlottedMac(NodePtr node)
00215 : MacProtocol(node), m_currentSlotNumber(0),
00216 m_txSlotNumber(0), m_numberOfSlots(0)
00217 { }
00218
00222 virtual void beginSlotEvent() = 0;
00223
00228 inline void setSlotTime(const SimTime& slotTime)
00229 {
00230 m_slotTime = slotTime;
00231 }
00232
00237 inline SimTime getSlotTime() const
00238 {
00239 return m_slotTime;
00240 }
00241
00247 inline bool inContentionCycle() const
00248 {
00249 return (m_currentSlotNumber < m_numberOfSlots);
00250 }
00251
00256 inline void stopContentionCycle()
00257 {
00258 m_currentSlotNumber = 0;
00259 m_numberOfSlots = 0;
00260 }
00261
00262 private:
00263
00267 SimTime m_slotTime;
00268
00269 };
00270 typedef boost::shared_ptr<SlottedMac> SlottedMacPtr;
00271
00273
00275
00279 class SlottedMacSlotEvent : public Event {
00280 public:
00282 typedef boost::shared_ptr<SlottedMacSlotEvent> SlottedMacSlotEventPtr;
00283
00288 static inline SlottedMacSlotEventPtr create(
00289 SlottedMacPtr slottedMac)
00290 {
00291 SlottedMacSlotEventPtr p(new SlottedMacSlotEvent(slottedMac));
00292 return p;
00293 }
00294
00295 void execute()
00296 {
00297 m_slottedMac->beginSlotEvent();
00298 }
00299
00300 protected:
00301
00303 SlottedMacSlotEvent(SlottedMacPtr slottedMac)
00304 : Event()
00305 {
00306 m_slottedMac = slottedMac;
00307 }
00308 private:
00309 SlottedMacPtr m_slottedMac;
00310 };
00311 typedef boost::shared_ptr<SlottedMacSlotEvent> SlottedMacSlotEventPtr;
00312
00317 class SendToLinkLayerEvent : public Event {
00318 public:
00320 typedef boost::shared_ptr<SendToLinkLayerEvent>
00321 SendToLinkLayerEventPtr;
00322
00327 static inline SendToLinkLayerEventPtr create(
00328 MacProtocolPtr macProtocol,
00329 CommunicationLayer::Directions direction, PacketPtr packet)
00330 {
00331 SendToLinkLayerEventPtr p(new SendToLinkLayerEvent(
00332 macProtocol, direction, packet));
00333 return p;
00334 }
00335
00336 void execute()
00337 {
00338 m_macProtocol->sendToLinkLayer(m_direction, m_packet);
00339 }
00340
00341 protected:
00343 SendToLinkLayerEvent(MacProtocolPtr macProtocol,
00344 CommunicationLayer::Directions direction, PacketPtr packet)
00345 : Event(), m_macProtocol(macProtocol), m_direction(direction),
00346 m_packet(packet)
00347 {
00348
00349 }
00350 private:
00351 MacProtocolPtr m_macProtocol;
00352 CommunicationLayer::Directions m_direction;
00353 PacketPtr m_packet;
00354 };
00355 typedef boost::shared_ptr<SendToLinkLayerEvent> SendToLinkLayerEventPtr;
00356
00357 #endif // MAC_PROTOCOL_H