INET Framework for OMNeT++/OMNEST
inet::LMac Class Reference

Implementation of L-MAC (Lightweight Medium Access Protocol for Wireless Sensor Networks [van Hoesel 04] ). More...

#include <LMac.h>

Inheritance diagram for inet::LMac:
inet::MacProtocolBase inet::IMacProtocol inet::queueing::IActivePacketSink inet::LayeredProtocolBase inet::OperationalBase inet::OperationalMixin< cSimpleModule > inet::ILifecycle

Public Member Functions

 LMac ()
 
virtual ~LMac ()
 Clean up messges. More...
 
virtual void initialize (int) override
 Initialization of the module and some variables. More...
 
virtual void handleLowerPacket (Packet *packet) override
 Handle messages from lower layer. More...
 
virtual void handleUpperPacket (Packet *packet) override
 Handle messages from upper layer. More...
 
virtual void handleSelfMessage (cMessage *) override
 Handle self messages such as timers. More...
 
virtual void receiveSignal (cComponent *source, simsignal_t signalID, intval_t value, cObject *details) override
 Handle control messages from lower layer. More...
 
virtual void encapsulate (Packet *)
 Encapsulate the NetwPkt into an MacPkt. More...
 
virtual void decapsulate (Packet *)
 
virtual queueing::IPassivePacketSourcegetProvider (cGate *gate) override
 Returns the passive packet source from where packets are pulled or nullptr if the connected module doesn't implement the interface. More...
 
virtual void handleCanPullPacketChanged (cGate *gate) override
 Notifies about a change in the possibility of pulling some packet from the passive packet source at the given gate. More...
 
virtual void handlePullPacketProcessed (Packet *packet, cGate *gate, bool successful) override
 Notifies about the completion of the packet processing for a packet that was pulled earlier independently whether the packet is passed or streamed. More...
 
- Public Member Functions inherited from inet::OperationalMixin< cSimpleModule >
virtual ~OperationalMixin ()
 }@ More...
 
- Public Member Functions inherited from inet::ILifecycle
virtual ~ILifecycle ()
 
- Public Member Functions inherited from inet::IMacProtocol
virtual ~IMacProtocol ()
 
- Public Member Functions inherited from inet::queueing::IActivePacketSink
virtual ~IActivePacketSink ()
 

Protected Types

enum  States {
  INIT, SLEEP, CCA, WAIT_CONTROL,
  WAIT_DATA, SEND_CONTROL, SEND_DATA
}
 MAC states. More...
 
- Protected Types inherited from inet::OperationalMixin< cSimpleModule >
enum  State
 

Protected Member Functions

virtual void configureNetworkInterface () override
 Generate new interface address. More...
 
virtual void handleCommand (cMessage *msg)
 
void findNewSlot ()
 find a new slot More...
 
void attachSignal (Packet *macPkt)
 Internal function to attach a signal to the packet. More...
 
- Protected Member Functions inherited from inet::MacProtocolBase
 MacProtocolBase ()
 
virtual ~MacProtocolBase ()
 
virtual void registerInterface ()
 
virtual MacAddress parseMacAddressParameter (const char *addrstr)
 
virtual void deleteCurrentTxFrame ()
 
virtual void dropCurrentTxFrame (PacketDropDetails &details)
 
virtual void handleMessageWhenDown (cMessage *msg) override
 
virtual void sendUp (cMessage *message)
 
virtual void sendDown (cMessage *message)
 
virtual bool isUpperMessage (cMessage *message) const override
 
virtual bool isLowerMessage (cMessage *message) const override
 
virtual bool isInitializeStage (int stage) const override
 
virtual bool isModuleStartStage (int stage) const override
 
virtual bool isModuleStopStage (int stage) const override
 
virtual void flushQueue (PacketDropDetails &details)
 should clear queue and emit signal "packetDropped" with entire packets More...
 
virtual void clearQueue ()
 should clear queue silently More...
 
virtual void receiveSignal (cComponent *source, simsignal_t signalID, cObject *obj, cObject *details) override
 
virtual void handleStartOperation (LifecycleOperation *operation) override
 
virtual void handleStopOperation (LifecycleOperation *operation) override
 
virtual void handleCrashOperation (LifecycleOperation *operation) override
 
queueing::IPacketQueuegetQueue (cGate *gate) const
 
virtual bool canDequeuePacket () const
 
virtual PacketdequeuePacket ()
 
- Protected Member Functions inherited from inet::LayeredProtocolBase
virtual void handleMessageWhenUp (cMessage *message) override
 
virtual void handleUpperMessage (cMessage *message)
 
virtual void handleLowerMessage (cMessage *message)
 
virtual void handleUpperCommand (cMessage *message)
 
virtual void handleLowerCommand (cMessage *message)
 
- Protected Member Functions inherited from inet::OperationalMixin< cSimpleModule >
virtual int numInitStages () const override
 
virtual void refreshDisplay () const override
 
virtual void handleMessage (cMessage *msg) override
 
virtual bool handleOperationStage (LifecycleOperation *operation, IDoneCallback *doneCallback) override
 Perform one stage of a lifecycle operation. More...
 
virtual State getInitialOperationalState () const
 Returns initial operational state: OPERATING or NOT_OPERATING. More...
 
virtual void handleActiveOperationTimeout (cMessage *message)
 
virtual bool isUp () const
 utility functions More...
 
virtual bool isDown () const
 
virtual void setOperationalState (State newState)
 
virtual void scheduleOperationTimeout (simtime_t timeout)
 
virtual void setupActiveOperation (LifecycleOperation *operation, IDoneCallback *doneCallback, State)
 
virtual void delayActiveOperationFinish (simtime_t timeout)
 
virtual void startActiveOperationExtraTime (simtime_t delay=SIMTIME_ZERO)
 
virtual void startActiveOperationExtraTimeOrFinish (simtime_t extraTime)
 
virtual void finishActiveOperation ()
 

Protected Attributes

bool SETUP_PHASE
 the setup phase is the beginning of the simulation, where only control packets at very small slot durations are exchanged. More...
 
cOutVector * slotChange
 indicate how often the node needs to change its slot because of collisions More...
 
States macState
 keep track of MAC state More...
 
double slotDuration
 Duration of a slot. More...
 
b headerLength
 Length of the header. More...
 
b ctrlFrameLength
 Length of the control frames. More...
 
double controlDuration
 Duration of teh control time in each slot. More...
 
int myId
 my ID More...
 
int mySlot
 my slot ID More...
 
int numSlots
 how many slots are there More...
 
int currSlot
 The current slot of the simulation. More...
 
MacAddress occSlotsDirect [64]
 Occupied slots from nodes, from which I hear directly. More...
 
MacAddress occSlotsAway [64]
 Occupied slots of two-hop neighbors. More...
 
int reservedMobileSlots
 The first couple of slots are reserved for nodes with special needs to avoid changing slots for them (mobile nodes) More...
 
ModuleRefByPar< physicallayer::IRadioradio
 The radio. More...
 
physicallayer::IRadio::TransmissionState transmissionState
 
cMessage * wakeup
 
cMessage * timeout
 
cMessage * sendData
 
cMessage * initChecker
 
cMessage * checkChannel
 
cMessage * start_lmac
 
cMessage * send_control
 
double bitrate
 the bit rate at which we transmit More...
 
- Protected Attributes inherited from inet::MacProtocolBase
int upperLayerInGateId = -1
 Gate ids. More...
 
int upperLayerOutGateId = -1
 
int lowerLayerInGateId = -1
 
int lowerLayerOutGateId = -1
 
opp_component_ptr< NetworkInterfacenetworkInterface
 
opp_component_ptr< cModule > hostModule
 
PacketcurrentTxFrame = nullptr
 Currently transmitted frame if any. More...
 
opp_component_ptr< queueing::IPacketQueuetxQueue
 Messages received from upper layer and to be transmitted later. More...
 
- Protected Attributes inherited from inet::OperationalMixin< cSimpleModule >
State operationalState
 
simtime_t lastChange
 
Operation activeOperation
 
cMessage * activeOperationTimeout
 
cMessage * activeOperationExtraTimer
 

Static Protected Attributes

static const MacAddress LMAC_NO_RECEIVER
 dummy receiver address to indicate no pending packets in the control packet More...
 
static const MacAddress LMAC_FREE_SLOT
 

Private Member Functions

 LMac (const LMac &)
 Copy constructor is not allowed. More...
 
LMacoperator= (const LMac &)
 Assignment operator is not allowed. More...
 

Detailed Description

Implementation of L-MAC (Lightweight Medium Access Protocol for Wireless Sensor Networks [van Hoesel 04] ).

Each node has its own unique timeslot. Nodes can use their timeslots to transfer data without having to contend for the medium or having to deal with energy wasting collisions or retransmissions.

During the first 5 full frames nodes will be waking up every controlDuration to setup the network first by assigning a different timeslot to each node. Normal packets will be queued, but will be send only after the setup phase.

During its timeslot a node wakes up, checks the channel for a short random period (CCA) to check for possible collision in the slot and, if the channel is free, sends a control packet. If there is a collision it tries to change its timeslot to an empty one. After the transmission of the control packet it checks its packet queue and if its non-empty it sends a data packet.

During a foreign timeslot a node wakes up, checks the channel for 2*controlDuration period for an incoming control packet and if there in nothing it goes back to sleep and conserves energy for the rest of the timeslot. If it receives a control packet addressed for itself it stays awake for the rest of the timeslot to receive the incoming data packet.

The finite state machine of the protocol is given in the below figure:

State chart for LMAC layer

A paper describing the protocol is:

L. van Hoesel and P. Havinga. A lightweight medium access protocol (LMAC) for wireless sensor networks. In Proceedings of the 3rd International Symposium on Information Processing in Sensor Networks (IPSN), pages 55-60, Berkeley, CA, February 2004. April.

Member Enumeration Documentation

◆ States

enum inet::LMac::States
protected

MAC states.

The MAC states help to keep track what the MAC is actually trying to do – this is esp. useful when radio switching takes some time. SLEEP – the node sleeps but accepts packets from the network layer RX – MAC accepts packets from PHY layer TX – MAC transmits a packet CCA – Clear Channel Assessment - MAC checks whether medium is busy

Enumerator
INIT 
SLEEP 
CCA 
WAIT_CONTROL 
WAIT_DATA 
SEND_CONTROL 
SEND_DATA 
142  {
144  };

Constructor & Destructor Documentation

◆ LMac() [1/2]

inet::LMac::LMac ( const LMac )
private

Copy constructor is not allowed.

◆ LMac() [2/2]

inet::LMac::LMac ( )
inline
75  : MacProtocolBase()
76  , SETUP_PHASE(true)
77  , slotChange()
78  , macState()
79  , slotDuration(0)
80  , headerLength(b(0))
81  , ctrlFrameLength(b(0))
82  , controlDuration(0)
83  , myId(0)
84  , mySlot(0)
85  , numSlots(0)
86  , currSlot()
89  , wakeup(nullptr)
90  , timeout(nullptr)
91  , sendData(nullptr)
92  , initChecker(nullptr)
93  , checkChannel(nullptr)
94  , start_lmac(nullptr)
95  , send_control(nullptr)
96  , bitrate(0)
97  {}

◆ ~LMac()

inet::LMac::~LMac ( )
virtual

Clean up messges.

87 {
88  delete slotChange;
89  cancelAndDelete(timeout);
90  cancelAndDelete(wakeup);
91  cancelAndDelete(checkChannel);
92  cancelAndDelete(sendData);
93  cancelAndDelete(initChecker);
94  cancelAndDelete(start_lmac);
95  cancelAndDelete(send_control);
96 }

Member Function Documentation

◆ attachSignal()

void inet::LMac::attachSignal ( Packet macPkt)
protected

Internal function to attach a signal to the packet.

643 {
644  // calc signal duration
645  simtime_t duration = macPkt->getBitLength() / bitrate;
646  // create and initialize control info with new signal
647  macPkt->setDuration(duration);
648 }

◆ configureNetworkInterface()

void inet::LMac::configureNetworkInterface ( )
overrideprotectedvirtual

Generate new interface address.

Implements inet::MacProtocolBase.

99 {
100  MacAddress address = parseMacAddressParameter(par("address"));
101 
102  // data rate
103  networkInterface->setDatarate(bitrate);
104 
105  // generate a link-layer address to be used as interface token for IPv6
106  networkInterface->setMacAddress(address);
107  networkInterface->setInterfaceToken(address.formInterfaceIdentifier());
108 
109  // capabilities
110  networkInterface->setMtu(par("mtu"));
111  networkInterface->setMulticast(false);
112  networkInterface->setBroadcast(true);
113 }

◆ decapsulate()

void inet::LMac::decapsulate ( Packet packet)
virtual
603 {
604  const auto& lmacHeader = packet->popAtFront<LMacDataFrameHeader>();
605  packet->addTagIfAbsent<MacAddressInd>()->setSrcAddress(lmacHeader->getSrcAddr());
606  packet->addTagIfAbsent<InterfaceInd>()->setInterfaceId(networkInterface->getInterfaceId());
607  auto payloadProtocol = ProtocolGroup::ethertype.getProtocol(lmacHeader->getNetworkProtocol());
608  packet->addTagIfAbsent<DispatchProtocolReq>()->setProtocol(payloadProtocol);
609  packet->addTagIfAbsent<PacketProtocolTag>()->setProtocol(payloadProtocol);
610  packet->setKind(0);
611  EV_DETAIL << " message decapsulated " << endl;
612 }

◆ encapsulate()

void inet::LMac::encapsulate ( Packet netwPkt)
virtual

Encapsulate the NetwPkt into an MacPkt.

Encapsulates the received network-layer packet into a MacPkt and set all needed header fields.

620 {
621  auto pkt = makeShared<LMacDataFrameHeader>();
622  pkt->setChunkLength(headerLength);
623 
624  // copy dest address from the Control Info attached to the network
625  // message by the network layer
626  auto dest = netwPkt->getTag<MacAddressReq>()->getDestAddress();
627  EV_DETAIL << "CInfo removed, mac addr=" << dest << endl;
628  pkt->setDestAddr(dest);
629  pkt->setNetworkProtocol(ProtocolGroup::ethertype.getProtocolNumber(netwPkt->getTag<PacketProtocolTag>()->getProtocol()));
630 
631  // delete the control info
632  delete netwPkt->removeControlInfo();
633 
634  // set the src address to own mac address (nic module getId())
635  pkt->setSrcAddr(networkInterface->getMacAddress());
636 
637  // encapsulate the network packet
638  netwPkt->insertAtFront(pkt);
639  EV_DETAIL << "pkt encapsulated\n";
640 }

◆ findNewSlot()

void inet::LMac::findNewSlot ( )
protected

find a new slot

Try to find a new slot after collision.

If not possible, set own slot to -1 (not able to send anything)

579 {
580  // pick a random slot at the beginning and schedule the next wakeup
581  // free the old one first
582  int counter = 0;
583 
584  mySlot = intrand((numSlots - reservedMobileSlots));
585  while ((occSlotsAway[mySlot] != LMAC_FREE_SLOT) && (counter < (numSlots - reservedMobileSlots))) {
586  counter++;
587  mySlot--;
588  if (mySlot < 0)
590  }
592  EV << "ERROR: I cannot find a free slot. Cannot send data.\n";
593  mySlot = -1;
594  }
595  else {
596  EV << "ERROR: My new slot is : " << mySlot << endl;
597  }
598  EV << "ERROR: I needed to find new slot\n";
599  slotChange->recordWithTimestamp(simTime(), FindModule<>::findHost(this)->getId() - 4);
600 }

◆ getProvider()

queueing::IPassivePacketSource * inet::LMac::getProvider ( cGate *  gate)
overridevirtual

Returns the passive packet source from where packets are pulled or nullptr if the connected module doesn't implement the interface.

The gate parameter must be a valid gate of this module.

Implements inet::queueing::IActivePacketSink.

651 {
652  return (gate->getId() == upperLayerInGateId) ? txQueue.get() : nullptr;
653 }

◆ handleCanPullPacketChanged()

void inet::LMac::handleCanPullPacketChanged ( cGate *  gate)
overridevirtual

Notifies about a change in the possibility of pulling some packet from the passive packet source at the given gate.

This method is called, for example, when a new packet is inserted into a queue. It allows the sink to pull a new packet from the queue.

The gate parameter must be a valid gate of this module.

Implements inet::queueing::IActivePacketSink.

656 {
657  Enter_Method("handleCanPullPacketChanged");
658  // packed arrived from upper layer
659 }

◆ handleCommand()

virtual void inet::LMac::handleCommand ( cMessage *  msg)
inlineprotectedvirtual
128 {}

◆ handleLowerPacket()

void inet::LMac::handleLowerPacket ( Packet packet)
overridevirtual

Handle messages from lower layer.

Handle LMAC control packets and data packets.

Recognize collisions, change own slot if necessary and remember who is using which slot.

Reimplemented from inet::LayeredProtocolBase.

526 {
527  if (packet->hasBitError()) {
528  EV << "Received " << packet << " contains bit errors or collision, dropping it\n";
529  PacketDropDetails details;
530  details.setReason(INCORRECTLY_RECEIVED);
531  emit(packetDroppedSignal, packet, &details);
532  delete packet;
533  return;
534  }
535  // simply pass the massage as self message, to be processed by the FSM.
536  const auto& hdr = packet->peekAtFront<LMacHeaderBase>();
537  packet->setKind(hdr->getType());
538  handleSelfMessage(packet);
539 }

◆ handlePullPacketProcessed()

void inet::LMac::handlePullPacketProcessed ( Packet packet,
cGate *  gate,
bool  successful 
)
overridevirtual

Notifies about the completion of the packet processing for a packet that was pulled earlier independently whether the packet is passed or streamed.

This method is called, for example, when a previously pulled packet is failed to be processed successfully. It allows the sink to retry the operation.

The gate parameter must be a valid gate of this module. The packet must not be nullptr.

Implements inet::queueing::IActivePacketSink.

662 {
663  Enter_Method("handlePullPacketProcessed");
664  throw cRuntimeError("Not supported callback");
665 }

◆ handleSelfMessage()

void inet::LMac::handleSelfMessage ( cMessage *  msg)
overridevirtual

Handle self messages such as timers.

Handle self messages: LMAC_SETUP_PHASE_END: end of setup phase.

Change slot duration to normal and start sending data packets. The slots of the nodes should be stable now. LMAC_SEND_DATA: send the data packet. LMAC_CHECK_CHANNEL: check the channel in own slot. If busy, change the slot. If not, send a control packet. LMAC_WAKEUP: wake up the node and either check the channel before sending a control packet or wait for control packets. LMAC_TIMEOUT: go back to sleep after nothing happened.

Reimplemented from inet::LayeredProtocolBase.

133 {
134  MacAddress address = networkInterface->getMacAddress();
135 
136  switch (macState) {
137  case INIT:
138  if (msg->getKind() == LMAC_START_LMAC) {
139  // the first 5 full slots we will be waking up every controlDuration to setup the network first
140  // normal packets will be queued, but will be send only after the setup phase
141  scheduleAfter(slotDuration * 5 * numSlots, initChecker);
142  EV << "Startup time =" << slotDuration * 5 * numSlots << endl;
143 
144  EV_DETAIL << "Scheduling the first wakeup at : " << slotDuration << endl;
145 
146  scheduleAfter(slotDuration, wakeup);
147 
148  for (int i = 0; i < numSlots; i++) {
151  }
152 
153  if (myId >= reservedMobileSlots)
154  mySlot = ((int)FindModule<>::findHost(this)->getId()) % (numSlots - reservedMobileSlots);
155  else
156  mySlot = myId;
157 // occSlotsDirect[mySlot] = address;
158 // occSlotsAway[mySlot] = address;
159  currSlot = 0;
160 
161  EV_DETAIL << "ID: " << FindModule<>::findHost(this)->getId() << ". Picked random slot: " << mySlot << endl;
162 
163  macState = SLEEP;
164  EV_DETAIL << "Old state: INIT, New state: SLEEP" << endl;
165  SETUP_PHASE = true;
166  }
167  else {
168  EV << "Unknown packet" << msg->getKind() << "in state" << macState << endl;
169  }
170  break;
171 
172  case SLEEP:
173  if (msg->getKind() == LMAC_WAKEUP) {
174  currSlot++;
175  currSlot %= numSlots;
176  EV_DETAIL << "New slot starting - No. " << currSlot << ", my slot is " << mySlot << endl;
177 
178  if (mySlot == currSlot) {
179  EV_DETAIL << "Waking up in my slot. Switch to RECV first to check the channel.\n";
180  macState = CCA;
181  radio->setRadioMode(IRadio::RADIO_MODE_RECEIVER);
182  EV_DETAIL << "Old state: SLEEP, New state: CCA" << endl;
183 
184  double small_delay = controlDuration * dblrand();
185  scheduleAfter(small_delay, checkChannel);
186  EV_DETAIL << "Checking for channel for " << small_delay << " time.\n";
187  }
188  else {
189  EV_DETAIL << "Waking up in a foreign slot. Ready to receive control packet.\n";
191  radio->setRadioMode(IRadio::RADIO_MODE_RECEIVER);
192  EV_DETAIL << "Old state: SLEEP, New state: WAIT_CONTROL" << endl;
193  if (!SETUP_PHASE) // in setup phase do not sleep
194  scheduleAfter(2.f * controlDuration, timeout);
195  }
196  if (SETUP_PHASE) {
197  scheduleAfter(2.f * controlDuration, wakeup);
198  EV_DETAIL << "setup phase slot duration:" << 2.f * controlDuration << "while controlduration is" << controlDuration << endl;
199  }
200  else
201  scheduleAfter(slotDuration, wakeup);
202  }
203  else if (msg->getKind() == LMAC_SETUP_PHASE_END) {
204  EV_DETAIL << "Setup phase end. Start normal work at the next slot.\n";
205  rescheduleAfter(slotDuration, wakeup);
206  SETUP_PHASE = false;
207  }
208  else {
209  EV << "Unknown packet" << msg->getKind() << "in state" << macState << endl;
210  }
211  break;
212 
213  case CCA:
214  if (msg->getKind() == LMAC_CHECK_CHANNEL) {
215  // if the channel is clear, get ready for sending the control packet
216  EV << "Channel is free, so let's prepare for sending.\n";
217 
219  radio->setRadioMode(IRadio::RADIO_MODE_TRANSMITTER);
220  EV_DETAIL << "Old state: CCA, New state: SEND_CONTROL" << endl;
221  }
222  else if (msg->getKind() == LMAC_CONTROL) {
223  auto packet = check_and_cast<Packet *>(msg);
224  const auto& lmacHeader = packet->peekAtFront<LMacControlFrame>();
225  const MacAddress& dest = lmacHeader->getDestAddr();
226  EV_DETAIL << " I have received a control packet from src " << lmacHeader->getSrcAddr() << " and dest " << dest << ".\n";
227  bool collision = false;
228  // if we are listening to the channel and receive anything, there is a collision in the slot.
229  if (checkChannel->isScheduled()) {
230  cancelEvent(checkChannel);
231  collision = true;
232  }
233 
234  for (int s = 0; s < numSlots; s++) {
235  occSlotsAway[s] = lmacHeader->getOccupiedSlots(s);
236  EV_DETAIL << "Occupied slot " << s << ": " << occSlotsAway[s] << endl;
237  EV_DETAIL << "Occupied direct slot " << s << ": " << occSlotsDirect[s] << endl;
238  }
239 
240  if (lmacHeader->getMySlot() > -1) {
241  // check first whether this address didn't have another occupied slot and free it again
242  for (int i = 0; i < numSlots; i++) {
243  if (occSlotsDirect[i] == lmacHeader->getSrcAddr())
245  if (occSlotsAway[i] == lmacHeader->getSrcAddr())
247  }
248  occSlotsAway[lmacHeader->getMySlot()] = lmacHeader->getSrcAddr();
249  occSlotsDirect[lmacHeader->getMySlot()] = lmacHeader->getSrcAddr();
250  }
251  collision = collision || (lmacHeader->getMySlot() == mySlot);
252  if (((mySlot > -1) && (lmacHeader->getOccupiedSlots(mySlot) > LMAC_FREE_SLOT) && (lmacHeader->getOccupiedSlots(mySlot) != address)) || collision) {
253  EV_DETAIL << "My slot is taken by " << lmacHeader->getOccupiedSlots(mySlot) << ". I need to change it.\n";
254  findNewSlot();
255  EV_DETAIL << "My new slot is " << mySlot << endl;
256  }
257  if (mySlot < 0) {
258  EV_DETAIL << "I don;t have a slot - try to find one.\n";
259  findNewSlot();
260  }
261 
262  if (dest == address || dest.isBroadcast()) {
263  EV_DETAIL << "I need to stay awake.\n";
264  if (timeout->isScheduled())
265  cancelEvent(timeout);
267  EV_DETAIL << "Old state: CCA, New state: WAIT_DATA" << endl;
268  }
269  else {
270  EV_DETAIL << "Incoming data packet not for me. Going back to sleep.\n";
271  macState = SLEEP;
272  EV_DETAIL << "Old state: CCA, New state: SLEEP" << endl;
273  radio->setRadioMode(IRadio::RADIO_MODE_SLEEP);
274  if (timeout->isScheduled())
275  cancelEvent(timeout);
276  }
277  delete packet;
278  }
279  // probably it never happens
280  else if (msg->getKind() == LMAC_DATA) {
281  auto packet = check_and_cast<Packet *>(msg);
282  const MacAddress& dest = packet->peekAtFront<LMacDataFrameHeader>()->getDestAddr();
283 // bool collision = false;
284  // if we are listening to the channel and receive anything, there is a collision in the slot.
285  if (checkChannel->isScheduled()) {
286  cancelEvent(checkChannel);
287 // collision = true;
288  }
289  EV_DETAIL << " I have received a data packet.\n";
290  if (dest == address || dest.isBroadcast()) {
291  EV_DETAIL << "sending pkt to upper...\n";
292  decapsulate(packet);
293  sendUp(packet);
294  }
295  else {
296  EV_DETAIL << "packet not for me, deleting...\n";
297  PacketDropDetails details;
298  details.setReason(NOT_ADDRESSED_TO_US);
299  emit(packetDroppedSignal, packet, &details);
300  delete packet;
301  }
302  // in any case, go back to sleep
303  macState = SLEEP;
304  EV_DETAIL << "Old state: CCA, New state: SLEEP" << endl;
305  radio->setRadioMode(IRadio::RADIO_MODE_SLEEP);
306  }
307  else if (msg->getKind() == LMAC_SETUP_PHASE_END) {
308  EV_DETAIL << "Setup phase end. Start normal work at the next slot.\n";
309  rescheduleAfter(slotDuration, wakeup);
310  SETUP_PHASE = false;
311  }
312  else {
313  EV << "Unknown packet" << msg->getKind() << "in state" << macState << endl;
314  }
315  break;
316 
317  case WAIT_CONTROL:
318  if (msg->getKind() == LMAC_TIMEOUT) {
319  EV_DETAIL << "Control timeout. Go back to sleep.\n";
320  macState = SLEEP;
321  EV_DETAIL << "Old state: WAIT_CONTROL, New state: SLEEP" << endl;
322  radio->setRadioMode(IRadio::RADIO_MODE_SLEEP);
323  }
324  else if (msg->getKind() == LMAC_CONTROL) {
325  auto packet = check_and_cast<Packet *>(msg);
326  const auto& lmacHeader = packet->peekAtFront<LMacControlFrame>();
327  const MacAddress& dest = lmacHeader->getDestAddr();
328  EV_DETAIL << " I have received a control packet from src " << lmacHeader->getSrcAddr() << " and dest " << dest << ".\n";
329 
330  bool collision = false;
331 
332  // check first the slot assignment
333  // copy the current slot assignment
334 
335  for (int s = 0; s < numSlots; s++) {
336  occSlotsAway[s] = lmacHeader->getOccupiedSlots(s);
337  EV_DETAIL << "Occupied slot " << s << ": " << occSlotsAway[s] << endl;
338  EV_DETAIL << "Occupied direct slot " << s << ": " << occSlotsDirect[s] << endl;
339  }
340 
341  if (lmacHeader->getMySlot() > -1) {
342  // check first whether this address didn't have another occupied slot and free it again
343  for (int i = 0; i < numSlots; i++) {
344  if (occSlotsDirect[i] == lmacHeader->getSrcAddr())
346  if (occSlotsAway[i] == lmacHeader->getSrcAddr())
348  }
349  occSlotsAway[lmacHeader->getMySlot()] = lmacHeader->getSrcAddr();
350  occSlotsDirect[lmacHeader->getMySlot()] = lmacHeader->getSrcAddr();
351  }
352 
353  collision = collision || (lmacHeader->getMySlot() == mySlot);
354  if (((mySlot > -1) && (lmacHeader->getOccupiedSlots(mySlot) > LMAC_FREE_SLOT) && (lmacHeader->getOccupiedSlots(mySlot) != address)) || collision) {
355  EV_DETAIL << "My slot is taken by " << lmacHeader->getOccupiedSlots(mySlot) << ". I need to change it.\n";
356  findNewSlot();
357  EV_DETAIL << "My new slot is " << mySlot << endl;
358  }
359  if (mySlot < 0) {
360  EV_DETAIL << "I don;t have a slot - try to find one.\n";
361  findNewSlot();
362  }
363 
364  if (dest == address || dest.isBroadcast()) {
365  EV_DETAIL << "I need to stay awake.\n";
367  EV_DETAIL << "Old state: WAIT_CONTROL, New state: WAIT_DATA" << endl;
368  if (timeout->isScheduled())
369  cancelEvent(timeout);
370  }
371  else {
372  EV_DETAIL << "Incoming data packet not for me. Going back to sleep.\n";
373  macState = SLEEP;
374  EV_DETAIL << "Old state: WAIT_CONTROL, New state: SLEEP" << endl;
375  radio->setRadioMode(IRadio::RADIO_MODE_SLEEP);
376  if (timeout->isScheduled())
377  cancelEvent(timeout);
378  }
379  delete packet;
380  }
381  else if ((msg->getKind() == LMAC_WAKEUP)) {
382  if (SETUP_PHASE == true)
383  EV_DETAIL << "End of setup-phase slot" << endl;
384  else
385  EV_DETAIL << "Very unlikely transition";
386 
387  macState = SLEEP;
388  EV_DETAIL << "Old state: WAIT_DATA, New state: SLEEP" << endl;
389  scheduleAfter(SIMTIME_ZERO, wakeup);
390  }
391  else if (msg->getKind() == LMAC_SETUP_PHASE_END) {
392  EV_DETAIL << "Setup phase end. Start normal work at the next slot.\n";
393  rescheduleAfter(slotDuration, wakeup);
394 
395  SETUP_PHASE = false;
396  }
397  else if (msg->getKind() == LMAC_DATA) {
398  // TODO review this delete, it's added to avoid a memory leak detected by Valgrind
399  delete msg;
400  }
401  else {
402  EV << "Unknown packet" << msg->getKind() << "in state" << macState << endl;
403  }
404 
405  break;
406 
407  case SEND_CONTROL:
408  if (msg->getKind() == LMAC_SEND_CONTROL) {
409  if (!SETUP_PHASE && currentTxFrame == nullptr && canDequeuePacket()) {
412  }
413  // send first a control message, so that non-receiving nodes can switch off.
414  EV << "Sending a control packet.\n";
415  auto control = makeShared<LMacControlFrame>();
416  if (currentTxFrame != nullptr && !SETUP_PHASE)
417  control->setDestAddr(currentTxFrame->peekAtFront<LMacHeaderBase>()->getDestAddr());
418  else
419  control->setDestAddr(LMAC_NO_RECEIVER);
420 
421  control->setSrcAddr(address);
422  control->setMySlot(mySlot);
423  control->setChunkLength(ctrlFrameLength + b(numSlots)); // FIXME check it: add only 1 bit / slot?
424  control->setOccupiedSlotsArraySize(numSlots);
425  for (int i = 0; i < numSlots; i++)
426  control->setOccupiedSlots(i, occSlotsDirect[i]);
427 
428  Packet *packet = new Packet("Control");
429  control->setType(LMAC_CONTROL);
430  packet->insertAtFront(control);
431  packet->addTag<PacketProtocolTag>()->setProtocol(&Protocol::lmac);
432  sendDown(packet);
433  if ((currentTxFrame != nullptr) && (!SETUP_PHASE))
434  scheduleAfter(controlDuration, sendData);
435  }
436  else if (msg->getKind() == LMAC_SEND_DATA) {
437  // we should be in our own slot and the control packet should be already sent. receiving neighbors should wait for the data now.
438  if (currSlot != mySlot) {
439  EV_DETAIL << "ERROR: Send data message received, but we are not in our slot!!! Repair.\n";
440  radio->setRadioMode(IRadio::RADIO_MODE_SLEEP);
441  if (timeout->isScheduled())
442  cancelEvent(timeout);
443  return;
444  }
445  Packet *data = new Packet("Data");
446  const auto& lmacHeader = currentTxFrame->removeAtFront<LMacDataFrameHeader>();
447  data->insertAtBack(currentTxFrame->peekData());
448  lmacHeader->setType(LMAC_DATA);
449  lmacHeader->setMySlot(mySlot);
450  lmacHeader->setOccupiedSlotsArraySize(numSlots);
451  for (int i = 0; i < numSlots; i++)
452  lmacHeader->setOccupiedSlots(i, occSlotsDirect[i]);
453 
454  data->insertAtFront(lmacHeader);
455  data->addTag<PacketProtocolTag>()->setProtocol(&Protocol::lmac);
456  EV << "Sending down data packet\n";
457  sendDown(data);
460  EV_DETAIL << "Old state: SEND_CONTROL, New state: SEND_DATA" << endl;
461  }
462  else if (msg->getKind() == LMAC_SETUP_PHASE_END) {
463  EV_DETAIL << "Setup phase end. Start normal work at the next slot.\n";
464  rescheduleAfter(slotDuration, wakeup);
465  SETUP_PHASE = false;
466  }
467  else {
468  EV << "Unknown packet" << msg->getKind() << "in state" << macState << endl;
469  }
470  break;
471 
472  case SEND_DATA:
473  if (msg->getKind() == LMAC_WAKEUP) {
474  throw cRuntimeError("I am still sending a message, while a new slot is starting!\n");
475  }
476  else {
477  EV << "Unknown packet" << msg->getKind() << "in state" << macState << endl;
478  }
479  break;
480 
481  case WAIT_DATA:
482  if (msg->getKind() == LMAC_DATA) {
483  auto packet = check_and_cast<Packet *>(msg);
484  const MacAddress& dest = packet->peekAtFront<LMacDataFrameHeader>()->getDestAddr();
485 
486  EV_DETAIL << " I have received a data packet.\n";
487  if (dest == address || dest.isBroadcast()) {
488  EV_DETAIL << "sending pkt to upper...\n";
489  decapsulate(packet);
490  sendUp(packet);
491  }
492  else {
493  EV_DETAIL << "packet not for me, deleting...\n";
494  PacketDropDetails details;
495  details.setReason(NOT_ADDRESSED_TO_US);
496  emit(packetDroppedSignal, packet, &details);
497  delete packet;
498  }
499  // in any case, go back to sleep
500  macState = SLEEP;
501  EV_DETAIL << "Old state: WAIT_DATA, New state: SLEEP" << endl;
502  radio->setRadioMode(IRadio::RADIO_MODE_SLEEP);
503  if (timeout->isScheduled())
504  cancelEvent(timeout);
505  }
506  else if (msg->getKind() == LMAC_WAKEUP) {
507  macState = SLEEP;
508  EV_DETAIL << "Unlikely transition. Old state: WAIT_DATA, New state: SLEEP" << endl;
509  scheduleAfter(SIMTIME_ZERO, wakeup);
510  }
511  else {
512  EV << "Unknown packet" << msg->getKind() << "in state" << macState << endl;
513  }
514  break;
515 
516  default:
517  throw cRuntimeError("Unknown mac state: %d", macState);
518  break;
519  }
520 }

◆ handleUpperPacket()

void inet::LMac::handleUpperPacket ( Packet packet)
overridevirtual

Handle messages from upper layer.

Check whether the queue is not full: if yes, print a warning and drop the packet.

Sending of messages is automatic.

Reimplemented from inet::LayeredProtocolBase.

120 {
121  throw cRuntimeError("Model error: this module should pull packet from upper queue, direct incoming packet not accepted");
122 }

◆ initialize()

void inet::LMac::initialize ( int  stage)
overridevirtual

Initialization of the module and some variables.

Reimplemented from inet::MacProtocolBase.

35 {
37  if (stage == INITSTAGE_LOCAL) {
38  slotDuration = par("slotDuration");
39  bitrate = par("bitrate");
40  headerLength = b(par("headerLength"));
41  EV << "headerLength is: " << headerLength << endl;
42  ctrlFrameLength = b(par("ctrlFrameLength"));
43  numSlots = par("numSlots");
44  // the first N slots are reserved for mobile nodes to be able to function normally
45  reservedMobileSlots = par("reservedMobileSlots");
46 
47  auto node = getContainingNode(this);
48  myId = node->isVector() ? node->getIndex() : getId() % numSlots;
49 
50  macState = INIT;
51 
52  slotChange = new cOutVector("slotChange");
53 
54  // how long does it take to send/receive a control packet
55  controlDuration = (double)(b(headerLength).get() + numSlots + 16) / (double)bitrate; // FIXME replace 16 to a constant
56  EV << "Control packets take : " << controlDuration << " seconds to transmit\n";
57 
59  }
60  else if (stage == INITSTAGE_LINK_LAYER) {
61  radio.reference(this, "radioModule", true);
62  cModule *radioModule = check_and_cast<cModule *>(radio.get());
63  radioModule->subscribe(IRadio::radioModeChangedSignal, this);
64  radioModule->subscribe(IRadio::transmissionStateChangedSignal, this);
65 
66  WATCH(macState);
67 
68  EV_DETAIL << " slotDuration = " << slotDuration
69  << " controlDuration = " << controlDuration
70  << " numSlots = " << numSlots
71  << " bitrate = " << bitrate << endl;
72 
73  timeout = new cMessage("timeout", LMAC_TIMEOUT);
74  sendData = new cMessage("sendData", LMAC_SEND_DATA);
75  wakeup = new cMessage("wakeup", LMAC_WAKEUP);
76  initChecker = new cMessage("setup phase", LMAC_SETUP_PHASE_END);
77  checkChannel = new cMessage("checkchannel", LMAC_CHECK_CHANNEL);
78  start_lmac = new cMessage("start_lmac", LMAC_START_LMAC);
79  send_control = new cMessage("send_control", LMAC_SEND_CONTROL);
80 
81  scheduleAfter(SIMTIME_ZERO, start_lmac);
82  EV_DETAIL << "My Mac address is" << networkInterface->getMacAddress() << " and my Id is " << myId << endl;
83  }
84 }

◆ operator=()

LMac& inet::LMac::operator= ( const LMac )
private

Assignment operator is not allowed.

◆ receiveSignal()

void inet::LMac::receiveSignal ( cComponent *  source,
simsignal_t  signalID,
intval_t  value,
cObject *  details 
)
overridevirtual

Handle control messages from lower layer.

Handle transmission over messages: send the data packet or don;t do anyhting.

545 {
546  Enter_Method("%s", cComponent::getSignalName(signalID));
547 
548  if (signalID == IRadio::transmissionStateChangedSignal) {
549  IRadio::TransmissionState newRadioTransmissionState = static_cast<IRadio::TransmissionState>(value);
551  // if data is scheduled for transfer, don;t do anything.
552  if (sendData->isScheduled()) {
553  EV_DETAIL << " transmission of control packet over. data transfer will start soon." << endl;
554  }
555  else {
556  EV_DETAIL << " transmission over. nothing else is scheduled, get back to sleep." << endl;
557  macState = SLEEP;
558  EV_DETAIL << "Old state: ?, New state: SLEEP" << endl;
559  radio->setRadioMode(IRadio::RADIO_MODE_SLEEP);
560  if (timeout->isScheduled())
561  cancelEvent(timeout);
562  }
563  }
564  transmissionState = newRadioTransmissionState;
565  }
566  else if (signalID == IRadio::radioModeChangedSignal) {
567  IRadio::RadioMode radioMode = (IRadio::RadioMode)value;
568  if (macState == SEND_CONTROL && radioMode == IRadio::RADIO_MODE_TRANSMITTER) {
569  // we just switched to TX after CCA, so simply send the first sendPremable self message
570  scheduleAfter(SIMTIME_ZERO, send_control);
571  }
572  }
573 }

Member Data Documentation

◆ bitrate

double inet::LMac::bitrate
protected

the bit rate at which we transmit

◆ checkChannel

cMessage* inet::LMac::checkChannel
protected

◆ controlDuration

double inet::LMac::controlDuration
protected

Duration of teh control time in each slot.

◆ ctrlFrameLength

b inet::LMac::ctrlFrameLength
protected

Length of the control frames.

◆ currSlot

int inet::LMac::currSlot
protected

The current slot of the simulation.

◆ headerLength

b inet::LMac::headerLength
protected

Length of the header.

◆ initChecker

cMessage* inet::LMac::initChecker
protected

◆ LMAC_FREE_SLOT

const MacAddress inet::LMac::LMAC_FREE_SLOT
staticprotected

◆ LMAC_NO_RECEIVER

const MacAddress inet::LMac::LMAC_NO_RECEIVER
staticprotected

dummy receiver address to indicate no pending packets in the control packet

◆ macState

States inet::LMac::macState
protected

keep track of MAC state

◆ myId

int inet::LMac::myId
protected

my ID

◆ mySlot

int inet::LMac::mySlot
protected

my slot ID

◆ numSlots

int inet::LMac::numSlots
protected

how many slots are there

◆ occSlotsAway

MacAddress inet::LMac::occSlotsAway[64]
protected

Occupied slots of two-hop neighbors.

◆ occSlotsDirect

MacAddress inet::LMac::occSlotsDirect[64]
protected

Occupied slots from nodes, from which I hear directly.

◆ radio

ModuleRefByPar<physicallayer::IRadio> inet::LMac::radio
protected

The radio.

◆ reservedMobileSlots

int inet::LMac::reservedMobileSlots
protected

The first couple of slots are reserved for nodes with special needs to avoid changing slots for them (mobile nodes)

◆ send_control

cMessage* inet::LMac::send_control
protected

◆ sendData

cMessage* inet::LMac::sendData
protected

◆ SETUP_PHASE

bool inet::LMac::SETUP_PHASE
protected

the setup phase is the beginning of the simulation, where only control packets at very small slot durations are exchanged.

◆ slotChange

cOutVector* inet::LMac::slotChange
protected

indicate how often the node needs to change its slot because of collisions

◆ slotDuration

double inet::LMac::slotDuration
protected

Duration of a slot.

◆ start_lmac

cMessage* inet::LMac::start_lmac
protected

◆ timeout

cMessage* inet::LMac::timeout
protected

◆ transmissionState

physicallayer::IRadio::TransmissionState inet::LMac::transmissionState
protected

◆ wakeup

cMessage* inet::LMac::wakeup
protected

The documentation for this class was generated from the following files:
inet::MacProtocolBase::networkInterface
opp_component_ptr< NetworkInterface > networkInterface
Definition: MacProtocolBase.h:30
inet::Packet::removeAtFront
const Ptr< Chunk > removeAtFront(b length=b(-1), int flags=0)
Removes the designated part from the beginning of the data part of the packet and returns it as a mut...
Definition: Packet.h:653
inet::LMac::occSlotsAway
MacAddress occSlotsAway[64]
Occupied slots of two-hop neighbors.
Definition: LMac.h:178
inet::LMAC_TIMEOUT
@ LMAC_TIMEOUT
Definition: LMacHeader_m.h:69
inet::LMac::SLEEP
@ SLEEP
Definition: LMac.h:143
inet::MacProtocolBase::sendUp
virtual void sendUp(cMessage *message)
Definition: MacProtocolBase.cc:59
inet::LMac::checkChannel
cMessage * checkChannel
Definition: LMac.h:190
inet::LMac::WAIT_CONTROL
@ WAIT_CONTROL
Definition: LMac.h:143
inet::LMAC_WAKEUP
@ LMAC_WAKEUP
Definition: LMacHeader_m.h:70
inet::LMac::sendData
cMessage * sendData
Definition: LMac.h:188
inet::LMAC_CONTROL
@ LMAC_CONTROL
Definition: LMacHeader_m.h:68
inet::LMac::INIT
@ INIT
Definition: LMac.h:143
inet::INCORRECTLY_RECEIVED
@ INCORRECTLY_RECEIVED
Definition: Simsignals_m.h:71
inet::LMac::bitrate
double bitrate
the bit rate at which we transmit
Definition: LMac.h:195
inet::Packet::peekAtFront
const Ptr< const Chunk > peekAtFront(b length=b(-1), int flags=0) const
Returns the designated part from the beginning of the data part of the packet as an immutable chunk i...
Definition: Packet.h:245
inet::getContainingNode
cModule * getContainingNode(const cModule *from)
Find the node containing the given module.
Definition: ModuleAccess.cc:40
inet::LMac::ctrlFrameLength
b ctrlFrameLength
Length of the control frames.
Definition: LMac.h:164
inet::physicallayer::IRadio::RADIO_MODE_SLEEP
@ RADIO_MODE_SLEEP
The radio is sleeping, frame reception or transmission is not possible, power consumption is minimal,...
Definition: IRadio.h:90
inet::LMac::LMAC_NO_RECEIVER
static const MacAddress LMAC_NO_RECEIVER
dummy receiver address to indicate no pending packets in the control packet
Definition: LMac.h:147
DispatchProtocolReq
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd DispatchProtocolReq L4PortInd Ipv4ControlInfo Ipv6ControlInfo down DispatchProtocolReq
Definition: IUdp-gates.txt:25
inet::Protocol::lmac
static const Protocol lmac
Definition: Protocol.h:98
inet::LMac::headerLength
b headerLength
Length of the header.
Definition: LMac.h:162
inet::LMac::slotChange
cOutVector * slotChange
indicate how often the node needs to change its slot because of collisions
Definition: LMac.h:154
inet::LMac::decapsulate
virtual void decapsulate(Packet *)
Definition: LMac.cc:602
inet::LMac::macState
States macState
keep track of MAC state
Definition: LMac.h:157
inet::physicallayer::IRadio::transmissionStateChangedSignal
static simsignal_t transmissionStateChangedSignal
This signal is emitted when the radio transmission state of the radio is changed.
Definition: IRadio.h:60
inet::LMac::slotDuration
double slotDuration
Duration of a slot.
Definition: LMac.h:160
inet::LMac::timeout
cMessage * timeout
Definition: LMac.h:187
inet::physicallayer::IRadio::RADIO_MODE_TRANSMITTER
@ RADIO_MODE_TRANSMITTER
The radio is prepared for frame transmission, frame reception is not possible, power consumption is l...
Definition: IRadio.h:104
inet::packetDroppedSignal
simsignal_t packetDroppedSignal
Definition: Simsignals.cc:85
PacketProtocolTag
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd DispatchProtocolReq L4PortInd Ipv4ControlInfo Ipv6ControlInfo down PacketProtocolTag
Definition: IUdp-gates.txt:25
inet::MacProtocolBase::MacProtocolBase
MacProtocolBase()
Definition: MacProtocolBase.cc:15
inet::LMac::WAIT_DATA
@ WAIT_DATA
Definition: LMac.h:143
inet::LMac::SEND_CONTROL
@ SEND_CONTROL
Definition: LMac.h:143
inet::LMAC_SEND_CONTROL
@ LMAC_SEND_CONTROL
Definition: LMacHeader_m.h:77
inet::units::values::s
value< double, units::s > s
Definition: Units.h:1235
inet::LMac::initChecker
cMessage * initChecker
Definition: LMac.h:189
inet::physicallayer::IRadio::RADIO_MODE_RECEIVER
@ RADIO_MODE_RECEIVER
The radio is prepared for frame reception, frame transmission is not possible, power consumption is l...
Definition: IRadio.h:97
inet::FindModule::findHost
static cModule * findHost(cModule *m)
Returns a pointer to the host module of the passed module.
Definition: FindModule.h:57
inet::LMac::currSlot
int currSlot
The current slot of the simulation.
Definition: LMac.h:174
inet::MacProtocolBase::currentTxFrame
Packet * currentTxFrame
Currently transmitted frame if any.
Definition: MacProtocolBase.h:35
inet::LMAC_START_LMAC
@ LMAC_START_LMAC
Definition: LMacHeader_m.h:76
inet::MacProtocolBase::sendDown
virtual void sendDown(cMessage *message)
Definition: MacProtocolBase.cc:66
inet::LMac::radio
ModuleRefByPar< physicallayer::IRadio > radio
The radio.
Definition: LMac.h:183
inet::MacProtocolBase::upperLayerInGateId
int upperLayerInGateId
Gate ids.
Definition: MacProtocolBase.h:24
inet::INITSTAGE_LOCAL
INET_API InitStage INITSTAGE_LOCAL
Initialization of local state that don't use or affect other modules includes:
inet::physicallayer::IRadio::TRANSMISSION_STATE_TRANSMITTING
@ TRANSMISSION_STATE_TRANSMITTING
The radio medium is busy, the radio is currently transmitting a signal.
Definition: IRadio.h:171
inet::LMAC_SETUP_PHASE_END
@ LMAC_SETUP_PHASE_END
Definition: LMacHeader_m.h:72
inet::LMac::SETUP_PHASE
bool SETUP_PHASE
the setup phase is the beginning of the simulation, where only control packets at very small slot dur...
Definition: LMac.h:151
inet::LMac::SEND_DATA
@ SEND_DATA
Definition: LMac.h:143
inet::units::values::b
value< int64_t, units::b > b
Definition: Units.h:1241
inet::Packet::peekData
const Ptr< const Chunk > peekData(int flags=0) const
Returns the whole data part (excluding front and back popped parts) in the current representation.
Definition: Packet.h:266
inet::LMac::transmissionState
physicallayer::IRadio::TransmissionState transmissionState
Definition: LMac.h:184
inet::LMAC_DATA
@ LMAC_DATA
Definition: LMacHeader_m.h:75
inet::MacProtocolBase::deleteCurrentTxFrame
virtual void deleteCurrentTxFrame()
Definition: MacProtocolBase.cc:93
inet::MacProtocolBase::initialize
virtual void initialize(int stage) override
Definition: MacProtocolBase.cc:37
inet::LMAC_CHECK_CHANNEL
@ LMAC_CHECK_CHANNEL
Definition: LMacHeader_m.h:73
inet::LMac::wakeup
cMessage * wakeup
Definition: LMac.h:186
inet::LMac::LMAC_FREE_SLOT
static const MacAddress LMAC_FREE_SLOT
Definition: LMac.h:148
inet::MacProtocolBase::getQueue
queueing::IPacketQueue * getQueue(cGate *gate) const
Definition: MacProtocolBase.cc:157
Enter_Method
#define Enter_Method(...)
Definition: SelfDoc.h:71
inet::physicallayer::IRadio::TransmissionState
TransmissionState
This enumeration specifies the transmission state of the radio.
Definition: IRadio.h:155
inet::LMac::encapsulate
virtual void encapsulate(Packet *)
Encapsulate the NetwPkt into an MacPkt.
Definition: LMac.cc:619
inet::MacProtocolBase::dequeuePacket
virtual Packet * dequeuePacket()
Definition: MacProtocolBase.cc:175
inet::physicallayer::IRadio::RadioMode
RadioMode
This enumeration specifies the requested operational mode of the radio.
Definition: IRadio.h:79
inet::LMac::CCA
@ CCA
Definition: LMac.h:143
inet::LMac::occSlotsDirect
MacAddress occSlotsDirect[64]
Occupied slots from nodes, from which I hear directly.
Definition: LMac.h:176
inet::MacProtocolBase::parseMacAddressParameter
virtual MacAddress parseMacAddressParameter(const char *addrstr)
Definition: MacProtocolBase.cc:24
inet::LMac::mySlot
int mySlot
my slot ID
Definition: LMac.h:170
inet::LMac::numSlots
int numSlots
how many slots are there
Definition: LMac.h:172
inet::ProtocolGroup::getProtocol
const Protocol * getProtocol(int protocolNumber) const
Definition: ProtocolGroup.cc:31
inet::MacProtocolBase::txQueue
opp_component_ptr< queueing::IPacketQueue > txQueue
Messages received from upper layer and to be transmitted later.
Definition: MacProtocolBase.h:38
inet::physicallayer::IRadio::TRANSMISSION_STATE_UNDEFINED
@ TRANSMISSION_STATE_UNDEFINED
The transmission state is undefined or meaningless.
Definition: IRadio.h:160
inet::LMAC_SEND_DATA
@ LMAC_SEND_DATA
Definition: LMacHeader_m.h:71
inet::LMac::reservedMobileSlots
int reservedMobileSlots
The first couple of slots are reserved for nodes with special needs to avoid changing slots for them ...
Definition: LMac.h:180
inet::physicallayer::IRadio::TRANSMISSION_STATE_IDLE
@ TRANSMISSION_STATE_IDLE
The radio is not transmitting a signal on the radio medium.
Definition: IRadio.h:166
inet::LMac::send_control
cMessage * send_control
Definition: LMac.h:192
inet::LMac::findNewSlot
void findNewSlot()
find a new slot
Definition: LMac.cc:578
inet::MacProtocolBase::canDequeuePacket
virtual bool canDequeuePacket() const
Definition: MacProtocolBase.cc:170
inet::NOT_ADDRESSED_TO_US
@ NOT_ADDRESSED_TO_US
Definition: Simsignals_m.h:76
inet::LMac::controlDuration
double controlDuration
Duration of teh control time in each slot.
Definition: LMac.h:166
inet::INITSTAGE_LINK_LAYER
INET_API InitStage INITSTAGE_LINK_LAYER
Initialization of link-layer protocols.
inet::ProtocolGroup::ethertype
static ProtocolGroup ethertype
Definition: ProtocolGroup.h:40
inet::physicallayer::IRadio::radioModeChangedSignal
static simsignal_t radioModeChangedSignal
This signal is emitted when the radio mode of the radio is changed.
Definition: IRadio.h:42
inet::LMac::myId
int myId
my ID
Definition: LMac.h:168
inet::LMac::handleSelfMessage
virtual void handleSelfMessage(cMessage *) override
Handle self messages such as timers.
Definition: LMac.cc:132
inet::LMac::start_lmac
cMessage * start_lmac
Definition: LMac.h:191