LMacLayer.cc

00001 /*
00002  *  LMACLayer.cc
00003  *
00004  *
00005  *  Created by Anna Foerster on 10/10/08.
00006  *  Copyright 2008 Universita della Svizzera Italiana. All rights reserved.
00007  *
00008  *  Converted to OMNeT++ 4 by Rudolf Hornig
00009  *  Converted to MiXiM by Kapourniotis Theodoros
00010  */
00011 
00012 #include "LMacLayer.h"
00013 
00014 //#include "NicControlType.h"
00015 #include "FWMath.h"
00016 
00017 
00018 
00019 Define_Module( LMacLayer )
00020 
00021 #define myId (getParentModule()->getParentModule()->getId()-4)
00022 
00023 
00024 const int LMacLayer::LMAC_NO_RECEIVER = -2;
00029 void LMacLayer::initialize(int stage)
00030 {
00031     BaseMacLayer::initialize(stage);
00032 
00033     if (stage == 0) {
00034 
00035         queueLength = par("queueLength");
00036         slotDuration = par("slotDuration");
00037         bitrate = par("bitrate");
00038     headerLength = par("headerLength");
00039     coreEV << "headerLength is: " << headerLength << endl;
00040         numSlots = par("numSlots");
00041     // the first N slots are reserved for mobile nodes to be able to function normally
00042     reservedMobileSlots = par("reservedMobileSlots");
00043     txPower = par("txPower");
00044 
00045         droppedPacket.setReason(DroppedPacket::NONE);
00046         nicId = getParentModule()->getId();
00047         debugEV << "My Mac address is" << myMacAddr << " and my Id is " << myId << endl;
00048 
00049 
00050         macState = INIT;
00051 
00052     slotChange = new cOutVector("slotChange");
00053 
00054     // how long does it take to send/receive a control packet
00055     controlDuration = ((double)headerLength + (double)numSlots + 16) / (double)bitrate;
00056     coreEV << "Control packets take : " << controlDuration << " seconds to transmit\n";
00057     }
00058 
00059     else if(stage == 1) {
00060         int channel;
00061         channel = hasPar("defaultChannel") ? par("defaultChannel") : 0;
00062 
00063         debugEV << "queueLength = " << queueLength
00064            << " slotDuration = " << slotDuration
00065        << " controlDuration = " << controlDuration
00066        << " numSlots = " << numSlots
00067            << " bitrate = " << bitrate << endl;
00068 
00069     timeout = new cMessage("timeout");
00070     timeout->setKind(LMAC_TIMEOUT);
00071 
00072     sendData = new cMessage("sendData");
00073     sendData->setKind(LMAC_SEND_DATA);
00074 
00075     wakeup = new cMessage("wakeup");
00076     wakeup->setKind(LMAC_WAKEUP);
00077 
00078     initChecker = new cMessage("setup phase");
00079     initChecker->setKind(LMAC_SETUP_PHASE_END);
00080 
00081     checkChannel = new cMessage("checkchannel");
00082     checkChannel->setKind(LMAC_CHECK_CHANNEL);
00083 
00084     start_lmac = new cMessage("start_lmac");
00085     start_lmac->setKind(LMAC_START_LMAC);
00086 
00087     send_control = new cMessage("send_control");
00088     send_control->setKind(LMAC_SEND_CONTROL);
00089 
00090     scheduleAt(0.0, start_lmac);
00091 
00092 
00093     }
00094 }
00095 
00096 LMacLayer::~LMacLayer() {
00097   delete slotChange;
00098   cancelAndDelete(timeout);
00099   cancelAndDelete(wakeup);
00100   cancelAndDelete(checkChannel);
00101   cancelAndDelete(sendData);
00102   cancelAndDelete(initChecker);
00103   cancelAndDelete(start_lmac);
00104   cancelAndDelete(send_control);
00105 
00106   MacQueue::iterator it;
00107     for(it = macQueue.begin(); it != macQueue.end(); ++it) {
00108         delete (*it);
00109     }
00110     macQueue.clear();
00111 }
00112 
00113 void LMacLayer::finish() {
00114 }
00115 
00120 void LMacLayer::handleUpperMsg(cMessage *msg)
00121 {
00122     LMacPkt *mac = static_cast<LMacPkt *>(encapsMsg(msg));
00123 
00124     // message has to be queued if another message is waiting to be send
00125     // or if we are already trying to send another message
00126 
00127     if (macQueue.size() <= queueLength) {
00128         macQueue.push_back(mac);
00129   debugEV << "packet put in queue\n  queue size: " << macQueue.size() << " macState: " << macState
00130       << "; mySlot is " << mySlot << "; current slot is " << currSlot << endl;;
00131 
00132     }
00133     else {
00134         // queue is full, message has to be deleted
00135         debugEV << "New packet arrived, but queue is FULL, so new packet is deleted\n";
00136         mac->setName("MAC ERROR");
00137         mac->setKind(PACKET_DROPPED);
00138         sendControlUp(mac);
00139         droppedPacket.setReason(DroppedPacket::QUEUE);
00140         utility->publishBBItem(catDroppedPacket, &droppedPacket, nicId);
00141     debugEV <<  "ERROR: Queue is full, forced to delete.\n";
00142     }
00143 }
00144 
00153 void LMacLayer::handleSelfMsg(cMessage *msg)
00154 {
00155   switch (macState)
00156   {
00157   case INIT:
00158     if (msg->getKind() == LMAC_START_LMAC)
00159     {
00160       // the first 5 full slots we will be waking up every controlDuration to setup the network first
00161       // normal packets will be queued, but will be send only after the setup phase
00162       scheduleAt(slotDuration*5*numSlots, initChecker);
00163       coreEV << "Startup time =" << slotDuration*5*numSlots << endl;
00164 
00165       debugEV << "Scheduling the first wakeup at : " << slotDuration << endl;
00166 
00167       scheduleAt(slotDuration, wakeup);
00168 
00169       for (int i = 0; i < numSlots; i++)
00170       {
00171         occSlotsDirect[i] = -1;
00172         occSlotsAway[i] = -1;
00173       }
00174 
00175       if (myId >= reservedMobileSlots)
00176         mySlot = ((int) getParentModule()->getParentModule()->getId() )% (numSlots - reservedMobileSlots);
00177       else
00178         mySlot = myId;
00179       //occSlotsDirect[mySlot] = myMacAddr;
00180       //occSlotsAway[mySlot] = myMacAddr;
00181       currSlot = 0;
00182 
00183       debugEV << "ID: " << getParentModule()->getParentModule()->getId() << ". Picked random slot: " << mySlot << endl;
00184 
00185       macState=SLEEP;
00186       debugEV << "Old state: INIT, New state: SLEEP" << endl;
00187       SETUP_PHASE = true;
00188     }
00189     else {
00190       EV << "Unknown packet" << msg->getKind() <<  "in state" << macState << endl;
00191       delete msg;
00192     }
00193     break;
00194 
00195   case SLEEP:
00196     if(msg->getKind() == LMAC_WAKEUP)
00197     {
00198       currSlot++;
00199       currSlot %= numSlots;
00200       debugEV << "New slot starting - No. " << currSlot << ", my slot is " << mySlot << endl;
00201 
00202       if (mySlot == currSlot)
00203       {
00204         debugEV << "Waking up in my slot. Switch to RECV first to check the channel.\n";
00205         phy->setRadioState(Radio::RX);
00206         macState = CCA;
00207         debugEV << "Old state: SLEEP, New state: CCA" << endl;
00208 
00209         double small_delay = controlDuration*dblrand();
00210         scheduleAt(simTime()+small_delay, checkChannel);
00211         debugEV << "Checking for channel for " << small_delay << " time.\n";
00212       }
00213       else
00214       {
00215         debugEV << "Waking up in a foreign slot. Ready to receive control packet.\n";
00216         phy->setRadioState(Radio::RX);
00217         macState = WAIT_CONTROL;
00218         debugEV << "Old state: SLEEP, New state: WAIT_CONTROL" << endl;
00219         if (!SETUP_PHASE) //in setup phase do not sleep
00220           scheduleAt(simTime()+2.f*controlDuration, timeout);
00221       }
00222       if (SETUP_PHASE)
00223       {
00224         scheduleAt(simTime()+2.f*controlDuration, wakeup);
00225         debugEV << "setup phase slot duration:" << 2.f*controlDuration << "while controlduration is" << controlDuration << endl;
00226       }
00227       else
00228         scheduleAt(simTime()+slotDuration, wakeup);
00229     }
00230     else if(msg->getKind() == LMAC_SETUP_PHASE_END)
00231     {
00232       debugEV << "Setup phase end. Start normal work at the next slot.\n";
00233       if (wakeup->isScheduled())
00234         cancelEvent(wakeup);
00235 
00236       scheduleAt(simTime()+slotDuration, wakeup);
00237 
00238       SETUP_PHASE = false;
00239     }
00240     else
00241     {
00242       EV << "Unknown packet" << msg->getKind() <<  "in state" << macState << endl;
00243       delete msg;
00244     }
00245     break;
00246 
00247   case CCA:
00248     if(msg->getKind() == LMAC_CHECK_CHANNEL)
00249     {
00250       // if the channel is clear, get ready for sending the control packet
00251       coreEV << "Channel is free, so let's prepare for sending.\n";
00252 
00253       phy->setRadioState(Radio::TX);
00254       macState = SEND_CONTROL;
00255       debugEV << "Old state: CCA, New state: SEND_CONTROL" << endl;
00256 
00257     }
00258     else if(msg->getKind() == LMAC_CONTROL)
00259     {
00260       LMacPkt *mac = static_cast<LMacPkt *>(msg);
00261       int dest = mac->getDestAddr();
00262       debugEV << " I have received a control packet from src " << mac->getSrcAddr() << " and dest " << dest << ".\n";
00263       bool collision = false;
00264       // if we are listening to the channel and receive anything, there is a collision in the slot.
00265       if (checkChannel->isScheduled())
00266       {
00267         cancelEvent(checkChannel);
00268         collision = true;
00269       }
00270 
00271       for (int s = 0; s < numSlots; s++)
00272         {
00273           occSlotsAway[s] = mac->getOccupiedSlots(s);
00274           debugEV << "Occupied slot " << s << ": " << occSlotsAway[s] << endl;
00275           debugEV << "Occupied direct slot " << s << ": " << occSlotsDirect[s] << endl;
00276         }
00277 
00278       if (mac->getMySlot() >-1)
00279       {
00280         // check first whether this address didn't have another occupied slot and free it again
00281         for (int i=0; i < numSlots; i++)
00282         {
00283           if (occSlotsDirect[i] == mac->getSrcAddr())
00284             occSlotsDirect[i] = -1;
00285           if (occSlotsAway[i] == mac->getSrcAddr())
00286             occSlotsAway[i] = -1;
00287         }
00288         occSlotsAway[mac->getMySlot()] = mac->getSrcAddr();
00289         occSlotsDirect[mac->getMySlot()] = mac->getSrcAddr();
00290       }
00291         collision = collision || (mac->getMySlot() == mySlot);
00292       if (((mySlot > -1) && (mac->getOccupiedSlots(mySlot) > -1) && (mac->getOccupiedSlots(mySlot) != myMacAddr)) || collision)
00293       {
00294         debugEV << "My slot is taken by " << mac->getOccupiedSlots(mySlot) << ". I need to change it.\n";
00295         findNewSlot();
00296         debugEV << "My new slot is " << mySlot << endl;
00297       }
00298       if (mySlot < 0)
00299       {
00300         debugEV << "I don;t have a slot - try to find one.\n";
00301         findNewSlot();
00302       }
00303 
00304       if(dest == myMacAddr || dest == L2BROADCAST)
00305       {
00306         debugEV << "I need to stay awake.\n";
00307         if (timeout->isScheduled())
00308           cancelEvent(timeout);
00309         macState=WAIT_DATA;
00310         debugEV << "Old state: CCA, New state: WAIT_DATA" << endl;
00311       }
00312       else
00313       {
00314         debugEV << "Incoming data packet not for me. Going back to sleep.\n";
00315         macState = SLEEP;
00316         debugEV << "Old state: CCA, New state: SLEEP" << endl;
00317         phy->setRadioState(Radio::SLEEP);
00318         if (timeout->isScheduled())
00319           cancelEvent(timeout);
00320       }
00321       delete mac;
00322     }
00323     //probably it never happens
00324     else if(msg->getKind() == LMAC_DATA)
00325     {
00326       LMacPkt *mac = static_cast<LMacPkt *>(msg);
00327       int dest = mac->getDestAddr();
00328       bool collision = false;
00329       // if we are listening to the channel and receive anything, there is a collision in the slot.
00330       if (checkChannel->isScheduled())
00331       {
00332         cancelEvent(checkChannel);
00333         collision = true;
00334       }
00335       debugEV << " I have received a data packet.\n";
00336       if(dest == myMacAddr || dest == L2BROADCAST)
00337       {
00338         debugEV << "sending pkt to upper...\n";
00339         sendUp(decapsMsg(mac));
00340       }
00341       else {
00342         debugEV << "packet not for me, deleting...\n";
00343         delete mac;
00344       }
00345       // in any case, go back to sleep
00346       macState = SLEEP;
00347       debugEV << "Old state: CCA, New state: SLEEP" << endl;
00348       phy->setRadioState(Radio::SLEEP);
00349     }
00350     else if(msg->getKind() == LMAC_SETUP_PHASE_END)
00351     {
00352       debugEV << "Setup phase end. Start normal work at the next slot.\n";
00353       if (wakeup->isScheduled())
00354         cancelEvent(wakeup);
00355 
00356       scheduleAt(simTime()+slotDuration, wakeup);
00357 
00358       SETUP_PHASE = false;
00359     }
00360     else
00361     {
00362       EV << "Unknown packet" << msg->getKind() <<  "in state" << macState << endl;
00363       delete msg;
00364     }
00365     break;
00366 
00367   case WAIT_CONTROL:
00368     if(msg->getKind() == LMAC_TIMEOUT)
00369     {
00370       debugEV << "Control timeout. Go back to sleep.\n";
00371       macState = SLEEP;
00372       debugEV << "Old state: WAIT_CONTROL, New state: SLEEP" << endl;
00373       phy->setRadioState(Radio::SLEEP);
00374     }
00375     else if(msg->getKind() == LMAC_CONTROL)
00376     {
00377 
00378       LMacPkt *mac = static_cast<LMacPkt *>(msg);
00379       int dest = mac->getDestAddr();
00380       debugEV << " I have received a control packet from src " << mac->getSrcAddr() << " and dest " << dest << ".\n";
00381 
00382       bool collision = false;
00383 
00384       // check first the slot assignment
00385       // copy the current slot assignment
00386 
00387       for (int s = 0; s < numSlots; s++)
00388       {
00389         occSlotsAway[s] = mac->getOccupiedSlots(s);
00390         debugEV << "Occupied slot " << s << ": " << occSlotsAway[s] << endl;
00391         debugEV << "Occupied direct slot " << s << ": " << occSlotsDirect[s] << endl;
00392       }
00393 
00394       if (mac->getMySlot() >-1)
00395       {
00396         // check first whether this address didn't have another occupied slot and free it again
00397         for (int i=0; i < numSlots; i++)
00398         {
00399           if (occSlotsDirect[i] == mac->getSrcAddr())
00400             occSlotsDirect[i] = -1;
00401           if (occSlotsAway[i] == mac->getSrcAddr())
00402             occSlotsAway[i] = -1;
00403         }
00404         occSlotsAway[mac->getMySlot()] = mac->getSrcAddr();
00405         occSlotsDirect[mac->getMySlot()] = mac->getSrcAddr();
00406       }
00407 
00408       collision = collision || (mac->getMySlot() == mySlot);
00409       if (((mySlot > -1) && (mac->getOccupiedSlots(mySlot) > -1) && (mac->getOccupiedSlots(mySlot) != myMacAddr)) || collision)
00410       {
00411         debugEV << "My slot is taken by " << mac->getOccupiedSlots(mySlot) << ". I need to change it.\n";
00412         findNewSlot();
00413         debugEV << "My new slot is " << mySlot << endl;
00414       }
00415       if (mySlot < 0)
00416       {
00417         debugEV << "I don;t have a slot - try to find one.\n";
00418         findNewSlot();
00419       }
00420 
00421       if(dest == myMacAddr || dest == L2BROADCAST)
00422       {
00423         debugEV << "I need to stay awake.\n";
00424         macState=WAIT_DATA;
00425         debugEV << "Old state: WAIT_CONTROL, New state: WAIT_DATA" << endl;
00426         if (timeout->isScheduled())
00427           cancelEvent(timeout);
00428       }
00429       else
00430       {
00431         debugEV << "Incoming data packet not for me. Going back to sleep.\n";
00432         macState = SLEEP;
00433         debugEV << "Old state: WAIT_CONTROL, New state: SLEEP" << endl;
00434         phy->setRadioState(Radio::SLEEP);
00435         if (timeout->isScheduled())
00436           cancelEvent(timeout);
00437       }
00438       delete mac;
00439     }
00440     else if ((msg->getKind() == LMAC_WAKEUP))
00441     {
00442       if (SETUP_PHASE == true)
00443         debugEV << "End of setup-phase slot" << endl;
00444       else
00445         debugEV << "Very unlikely transition";
00446 
00447       macState = SLEEP;
00448       debugEV << "Old state: WAIT_DATA, New state: SLEEP" << endl;
00449       scheduleAt(simTime(), wakeup);
00450 
00451     }
00452     else if (msg->getKind() == LMAC_SETUP_PHASE_END)
00453     {
00454       debugEV << "Setup phase end. Start normal work at the next slot.\n";
00455       if (wakeup->isScheduled())
00456         cancelEvent(wakeup);
00457 
00458       scheduleAt(simTime()+slotDuration, wakeup);
00459 
00460       SETUP_PHASE = false;
00461     }
00462     else
00463     {
00464       EV << "Unknown packet" << msg->getKind() <<  "in state" << macState << endl;
00465       delete msg;
00466     }
00467 
00468     break;
00469 
00470   case SEND_CONTROL:
00471 
00472     if(msg->getKind() == LMAC_SEND_CONTROL)
00473     {
00474       // send first a control message, so that non-receiving nodes can switch off.
00475       coreEV << "Sending a control packet.\n";
00476       LMacPkt* control = new LMacPkt();
00477       control->setKind(LMAC_CONTROL);
00478       if ((macQueue.size() > 0) && !SETUP_PHASE)
00479         control->setDestAddr((macQueue.front())->getDestAddr());
00480       else
00481         control->setDestAddr(LMAC_NO_RECEIVER);
00482 
00483       control->setSrcAddr(myMacAddr);
00484       control->setMySlot(mySlot);
00485       control->setBitLength(headerLength + numSlots);
00486       control->setOccupiedSlotsArraySize(numSlots);
00487       for (int i = 0; i < numSlots; i++)
00488         control->setOccupiedSlots(i, occSlotsDirect[i]);
00489 
00490       attachSignal(control);
00491       sendDown(control);
00492       if ((macQueue.size() > 0) && (!SETUP_PHASE))
00493         scheduleAt(simTime()+controlDuration, sendData);
00494     }
00495     else if(msg->getKind() == LMAC_SEND_DATA)
00496     {
00497       // we should be in our own slot and the control packet should be already sent. receiving neighbors should wait for the data now.
00498       if (currSlot != mySlot)
00499       {
00500         debugEV << "ERROR: Send data message received, but we are not in our slot!!! Repair.\n";
00501         phy->setRadioState(Radio::SLEEP);
00502         if (timeout->isScheduled())
00503           cancelEvent(timeout);
00504         return;
00505       }
00506       LMacPkt* data = macQueue.front()->dup();
00507       data->setKind(LMAC_DATA);
00508       data->setMySlot(mySlot);
00509       data->setOccupiedSlotsArraySize(numSlots);
00510       for (int i = 0; i < numSlots; i++)
00511         data->setOccupiedSlots(i, occSlotsDirect[i]);
00512 
00513       attachSignal(data);
00514       coreEV << "Sending down data packet\n";
00515       sendDown(data);
00516       delete macQueue.front();
00517       macQueue.pop_front();
00518       macState = SEND_DATA;
00519       debugEV << "Old state: SEND_CONTROL, New state: SEND_DATA" << endl;
00520     }
00521     else if(msg->getKind() == LMAC_SETUP_PHASE_END)
00522     {
00523       debugEV << "Setup phase end. Start normal work at the next slot.\n";
00524       if (wakeup->isScheduled())
00525         cancelEvent(wakeup);
00526 
00527       scheduleAt(simTime()+slotDuration, wakeup);
00528 
00529       SETUP_PHASE = false;
00530     }
00531     else
00532     {
00533       EV << "Unknown packet" << msg->getKind() <<  "in state" << macState << endl;
00534       delete msg;
00535     }
00536     break;
00537 
00538   case SEND_DATA:
00539     if(msg->getKind() == LMAC_WAKEUP)
00540     {
00541       error("I am still sending a message, while a new slot is starting!\n");
00542     }
00543     else
00544     {
00545       EV << "Unknown packet" << msg->getKind() <<  "in state" << macState << endl;
00546       delete msg;
00547     }
00548     break;
00549 
00550   case WAIT_DATA:
00551     if(msg->getKind() == LMAC_DATA)
00552     {
00553       LMacPkt *mac = static_cast<LMacPkt *>(msg);
00554       int dest = mac->getDestAddr();
00555       debugEV << " I have received a data packet.\n";
00556       if(dest == myMacAddr || dest == L2BROADCAST)
00557       {
00558         debugEV << "sending pkt to upper...\n";
00559         sendUp(decapsMsg(mac));
00560       }
00561       else {
00562         debugEV << "packet not for me, deleting...\n";
00563         delete mac;
00564       }
00565       // in any case, go back to sleep
00566       macState = SLEEP;
00567       debugEV << "Old state: WAIT_DATA, New state: SLEEP" << endl;
00568       phy->setRadioState(Radio::SLEEP);
00569       if (timeout->isScheduled())
00570         cancelEvent(timeout);
00571     }
00572     else if(msg->getKind() == LMAC_WAKEUP)
00573     {
00574       macState = SLEEP;
00575       debugEV << "Unlikely transition. Old state: WAIT_DATA, New state: SLEEP" << endl;
00576       scheduleAt(simTime(), wakeup);
00577     }
00578     else
00579     {
00580       EV << "Unknown packet" << msg->getKind() <<  "in state" << macState << endl;
00581       delete msg;
00582     }
00583     break;
00584   default:
00585     opp_error("Unknown mac state: %d", macState);
00586   }
00587 }
00588 
00592 void LMacLayer::handleLowerMsg(cMessage *msg)
00593 {
00594   // simply pass the massage as self message, to be processed by the FSM.
00595   handleSelfMsg(msg);
00596 }
00597 
00598 
00602 void LMacLayer::handleLowerControl(cMessage *msg)
00603 {
00604   if(msg->getKind() == MacToPhyInterface::TX_OVER)
00605   {
00606     // if data is scheduled for transfer, don;t do anything.
00607     if (sendData->isScheduled())
00608     {
00609       debugEV << " transmission of control packet over. data transfer will start soon." << endl;
00610       delete msg;
00611       return;
00612     }
00613     else
00614     {
00615       debugEV << " transmission over. nothing else is scheduled, get back to sleep." << endl;
00616       macState = SLEEP;
00617       debugEV << "Old state: ?, New state: SLEEP" << endl;
00618       phy->setRadioState(Radio::SLEEP);
00619       if (timeout->isScheduled())
00620         cancelEvent(timeout);
00621     }
00622     }
00623 
00624   else if(msg->getKind() == MacToPhyInterface::RADIO_SWITCHING_OVER)
00625   {
00626       // we just switched to TX after CCA, so simply send the first sendPremable self message
00627       if ((macState == SEND_CONTROL) && (phy->getRadioState() == Radio::TX))
00628       {
00629         scheduleAt(simTime(), send_control);
00630       }
00631 
00632   }
00633 
00634     else {
00635         EV << "control message with wrong kind -- deleting\n";
00636     }
00637     delete msg;
00638 
00639 }
00640 
00641 
00645 void LMacLayer::findNewSlot()
00646 {
00647   // pick a random slot at the beginning and schedule the next wakeup
00648   // free the old one first
00649   int counter = 0;
00650 
00651   mySlot = intrand((numSlots - reservedMobileSlots));
00652   while ((occSlotsAway[mySlot] != -1) && (counter < (numSlots - reservedMobileSlots)))
00653   {
00654     counter++;
00655     mySlot--;
00656     if (mySlot < 0)
00657       mySlot = (numSlots - reservedMobileSlots)-1;
00658   }
00659   if (occSlotsAway[mySlot] != -1)
00660   {
00661     EV << "ERROR: I cannot find a free slot. Cannot send data.\n";
00662     mySlot = -1;
00663   }
00664   else
00665   {
00666     EV << "ERROR: My new slot is : " << mySlot << endl;
00667   }
00668   EV << "ERROR: I needed to find new slot\n";
00669   slotChange->recordWithTimestamp(simTime(), getParentModule()->getParentModule()->getId()-4);
00670 }
00671 
00676 MacPkt *LMacLayer::encapsMsg(cMessage * msg)
00677 {
00678 
00679     LMacPkt *pkt = new LMacPkt(msg->getName(), msg->getKind());
00680     pkt->setBitLength(headerLength);
00681 
00682     // copy dest address from the Control Info attached to the network
00683     // mesage by the network layer
00684     NetwToMacControlInfo* cInfo = static_cast<NetwToMacControlInfo*>(msg->removeControlInfo());
00685 
00686     debugEV <<"CInfo removed, mac addr="<< cInfo->getNextHopMac()<<endl;
00687     pkt->setDestAddr(cInfo->getNextHopMac());
00688 
00689     //delete the control info
00690     delete cInfo;
00691 
00692     //set the src address to own mac address (nic module getId())
00693     pkt->setSrcAddr(myMacAddr);
00694 
00695     //encapsulate the network packet
00696     pkt->encapsulate(check_and_cast<cPacket *>(msg));
00697     debugEV <<"pkt encapsulated\n";
00698 
00699     return pkt;
00700 
00701 }
00702 
00703 
00704 void LMacLayer::attachSignal(MacPkt *macPkt)
00705 {
00706   //calc signal duration
00707   simtime_t duration = macPkt->getBitLength() / bitrate;
00708   //create signal
00709   Signal* s = createSignal(simTime(), duration, txPower, bitrate);
00710   //create and initialize control info
00711   MacToPhyControlInfo* ctrl = new MacToPhyControlInfo(s);
00712   macPkt->setControlInfo(ctrl);
00713 }
00714