BMacLayer.cc

00001 //
00002 // This program is free software: you can redistribute it and/or modify
00003 // it under the terms of the GNU Lesser General Public License as published by
00004 // the Free Software Foundation, either version 3 of the License, or
00005 // (at your option) any later version.
00006 // 
00007 // This program is distributed in the hope that it will be useful,
00008 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00009 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010 // GNU Lesser General Public License for more details.
00011 // 
00012 // You should have received a copy of the GNU Lesser General Public License
00013 // along with this program.  If not, see http://www.gnu.org/licenses/.
00014 // 
00015 
00016 #include "BMacLayer.h"
00017 #include "FWMath.h"
00018 #include "MacToPhyControlInfo.h"
00019 #include <BaseArp.h>
00020 #include <BaseConnectionManager.h>
00021 #include <SimpleAddress.h>
00022 #include <NetwToMacControlInfo.h>
00023 
00024 Define_Module( BMacLayer )
00025 
00026 
00029 void BMacLayer::initialize(int stage)
00030 {
00031   BaseMacLayer::initialize(stage);
00032 
00033     if (stage == 0) {
00034 
00035         queueLength = hasPar("queueLength") ? par("queueLength") : 10;
00036     animation = hasPar("animation") ? par("animation") : true;
00037         slotDuration = hasPar("slotDuration") ? par("slotDuration") : 1;
00038         bitrate = hasPar("bitrate") ? par("bitrate") : 15360;
00039     headerLength = hasPar("headerLength") ? par("headerLength") : 10;
00040     checkInterval = hasPar("checkInterval") ? par("checkInterval") : 0.1;
00041     txPower = hasPar("txPower") ? par("txPower") : 50;
00042     useMacAcks = hasPar("useMACAcks") ? par("useMACAcks") : false;
00043     maxTxAttempts = hasPar("maxTxAttempts") ? par("maxTxAttempts") : 2;
00044     debugEV << "headerLength: " << headerLength << ", bitrate: " << bitrate << endl;
00045 
00046     stats = par("stats");
00047     nbTxDataPackets = 0;
00048     nbTxPreambles = 0;
00049     nbRxDataPackets = 0;
00050     nbRxPreambles = 0;
00051     nbMissedAcks = 0;
00052     nbRecvdAcks=0;
00053     nbDroppedDataPackets=0;
00054     nbTxAcks=0;
00055 
00056     txAttempts = 0;
00057     lastDataPktDestAddr = L2BROADCAST;
00058     lastDataPktSrcAddr = L2BROADCAST;
00059 
00060     macState = INIT;
00061 
00062     // init the dropped packet info
00063     droppedPacket.setReason(DroppedPacket::NONE);
00064     nicId = getParentModule()->getId();
00065 
00066     catDroppedPacket = utility->getCategory(&droppedPacket);
00067     WATCH(macState);
00068     }
00069 
00070     else if(stage == 1) {
00071 
00072     wakeup = new cMessage("wakeup");
00073     wakeup->setKind(BMAC_WAKE_UP);
00074 
00075     data_timeout = new cMessage("data_timeout");
00076     data_timeout->setKind(BMAC_DATA_TIMEOUT);
00077     data_timeout->setSchedulingPriority(100);
00078 
00079     data_tx_over = new cMessage("data_tx_over");
00080     data_tx_over->setKind(BMAC_DATA_TX_OVER);
00081 
00082     stop_preambles = new cMessage("stop_preambles");
00083     stop_preambles->setKind(BMAC_STOP_PREAMBLES);
00084 
00085     send_preamble = new cMessage("send_preamble");
00086     send_preamble->setKind(BMAC_SEND_PREAMBLE);
00087 
00088     ack_tx_over = new cMessage("ack_tx_over");
00089     ack_tx_over->setKind(BMAC_ACK_TX_OVER);
00090 
00091     cca_timeout = new cMessage("cca_timeout");
00092     cca_timeout->setKind(BMAC_CCA_TIMEOUT);
00093     cca_timeout->setSchedulingPriority(100);
00094 
00095     send_ack = new cMessage("send_ack");
00096     send_ack->setKind(BMAC_SEND_ACK);
00097 
00098     start_bmac = new cMessage("start_bmac");
00099     start_bmac->setKind(BMAC_START_BMAC);
00100 
00101     ack_timeout = new cMessage("ack_timeout");
00102     ack_timeout->setKind(BMAC_ACK_TIMEOUT);
00103 
00104     resend_data = new cMessage("resend_data");
00105     resend_data->setKind(BMAC_RESEND_DATA);
00106     resend_data->setSchedulingPriority(100);
00107 
00108     scheduleAt(0.0, start_bmac);
00109     }
00110 }
00111 
00112 BMacLayer::~BMacLayer()
00113 {
00114   cancelAndDelete(wakeup);
00115   cancelAndDelete(data_timeout);
00116   cancelAndDelete(data_tx_over);
00117   cancelAndDelete(stop_preambles);
00118   cancelAndDelete(send_preamble);
00119   cancelAndDelete(ack_tx_over);
00120   cancelAndDelete(cca_timeout);
00121   cancelAndDelete(send_ack);
00122   cancelAndDelete(start_bmac);
00123   cancelAndDelete(ack_timeout);
00124   cancelAndDelete(resend_data);
00125 
00126   MacQueue::iterator it;
00127   for(it = macQueue.begin(); it != macQueue.end(); ++it)
00128   {
00129     delete (*it);
00130   }
00131   macQueue.clear();
00132 }
00133 
00134 void BMacLayer::finish()
00135 {
00136     BaseMacLayer::finish();
00137 
00138     // record stats
00139     if (stats)
00140     {
00141       recordScalar("nbTxDataPackets", nbTxDataPackets);
00142       recordScalar("nbTxPreambles", nbTxPreambles);
00143       recordScalar("nbRxDataPackets", nbRxDataPackets);
00144       recordScalar("nbRxPreambles", nbRxPreambles);
00145       recordScalar("nbMissedAcks", nbMissedAcks);
00146       recordScalar("nbRecvdAcks", nbRecvdAcks);
00147       recordScalar("nbTxAcks", nbTxAcks);
00148       recordScalar("nbDroppedDataPackets", nbDroppedDataPackets);
00149       //recordScalar("timeSleep", timeSleep);
00150       //recordScalar("timeRX", timeRX);
00151       //recordScalar("timeTX", timeTX);
00152     }
00153 }
00154 
00160 void BMacLayer::handleUpperMsg(cMessage *msg)
00161 {
00162   bool pktAdded = addToQueue(msg);
00163   if (!pktAdded)
00164     return;
00165   // force wakeup now
00166   if (wakeup->isScheduled() && (macState == SLEEP))
00167   {
00168     cancelEvent(wakeup);
00169     scheduleAt(simTime() + dblrand()*0.1f, wakeup);
00170   }
00171 }
00172 
00176 void BMacLayer::sendPreamble()
00177 {
00178   MacPkt* preamble = new MacPkt();
00179   preamble->setSrcAddr(myMacAddr);
00180   preamble->setDestAddr(L2BROADCAST);
00181   preamble->setKind(BMAC_PREAMBLE);
00182   preamble->setBitLength(headerLength);
00183 
00184   //attach signal and send down
00185   attachSignal(preamble);
00186   sendDown(preamble);
00187   nbTxPreambles++;
00188 }
00189 
00193 void BMacLayer::sendMacAck()
00194 {
00195   MacPkt* ack = new MacPkt();
00196   ack->setSrcAddr(myMacAddr);
00197   ack->setDestAddr(lastDataPktSrcAddr);
00198   ack->setKind(BMAC_ACK);
00199   ack->setBitLength(headerLength);
00200 
00201   //attach signal and send down
00202   attachSignal(ack);
00203   sendDown(ack);
00204   nbTxAcks++;
00205   //endSimulation();
00206 }
00207 
00208 
00209 
00223 void BMacLayer::handleSelfMsg(cMessage *msg)
00224 {
00225   switch (macState)
00226   {
00227   case INIT:
00228     if (msg->getKind() == BMAC_START_BMAC)
00229     {
00230       debugEV << "State INIT, message BMAC_START, new state SLEEP" << endl;
00231       changeDisplayColor(BLACK);
00232       phy->setRadioState(Radio::SLEEP);
00233       macState = SLEEP;
00234       scheduleAt(simTime()+dblrand()*slotDuration, wakeup);
00235       return;
00236     }
00237     break;
00238   case SLEEP:
00239     if (msg->getKind() == BMAC_WAKE_UP)
00240     {
00241       debugEV << "State SLEEP, message BMAC_WAKEUP, new state CCA" << endl;
00242       scheduleAt(simTime() + checkInterval, cca_timeout);
00243       phy->setRadioState(Radio::RX);
00244       changeDisplayColor(GREEN);
00245       macState = CCA;
00246       return;
00247     }
00248     break;
00249   case CCA:
00250     if (msg->getKind() == BMAC_CCA_TIMEOUT)
00251     {
00252       // channel is clear
00253       // something waiting in eth queue?
00254       if (macQueue.size() > 0)
00255       {
00256         debugEV << "State CCA, message CCA_TIMEOUT, new state"
00257               " SEND_PREAMBLE" << endl;
00258         phy->setRadioState(Radio::TX);
00259         changeDisplayColor(YELLOW);
00260         macState = SEND_PREAMBLE;
00261         scheduleAt(simTime() + slotDuration, stop_preambles);
00262         return;
00263       }
00264       // if not, go back to sleep and wake up after a full period
00265       else
00266       {
00267         debugEV << "State CCA, message CCA_TIMEOUT, new state SLEEP"
00268              << endl;
00269         scheduleAt(simTime() + slotDuration, wakeup);
00270         macState = SLEEP;
00271         phy->setRadioState(Radio::SLEEP);
00272         changeDisplayColor(BLACK);
00273         return;
00274       }
00275     }
00276     // during CCA, we received a preamble. Go to state WAIT_DATA and
00277     // schedule the timeout.
00278     if (msg->getKind() == BMAC_PREAMBLE)
00279     {
00280       nbRxPreambles++;
00281       debugEV << "State CCA, message BMAC_PREAMBLE received, new state"
00282             " WAIT_DATA" << endl;
00283       macState = WAIT_DATA;
00284       cancelEvent(cca_timeout);
00285       scheduleAt(simTime() + slotDuration + checkInterval, data_timeout);
00286       delete msg;
00287       return;
00288     }
00289     // this case is very, very, very improbable, but let's do it.
00290     // if in CCA and the node receives directly the data packet, switch to
00291     // state WAIT_DATA and re-send the message
00292     if (msg->getKind() == BMAC_DATA)
00293     {
00294       nbRxDataPackets++;
00295       debugEV << "State CCA, message BMAC_DATA, new state WAIT_DATA"
00296            << endl;
00297       macState = WAIT_DATA;
00298       cancelEvent(cca_timeout);
00299       scheduleAt(simTime() + slotDuration + checkInterval, data_timeout);
00300       scheduleAt(simTime(), msg);
00301       return;
00302     }
00303     //in case we get an ACK, we simply dicard it, because it means the end
00304     //of another communication
00305     if (msg->getKind() == BMAC_ACK)
00306     {
00307       debugEV << "State CCA, message BMAC_ACK, new state CCA" << endl;
00308       delete msg;
00309       return;
00310     }
00311     break;
00312 
00313   case SEND_PREAMBLE:
00314     if (msg->getKind() == BMAC_SEND_PREAMBLE)
00315     {
00316       debugEV << "State SEND_PREAMBLE, message BMAC_SEND_PREAMBLE, new"
00317             " state SEND_PREAMBLE" << endl;
00318       sendPreamble();
00319       scheduleAt(simTime() + 0.5f*checkInterval, send_preamble);
00320       macState = SEND_PREAMBLE;
00321       return;
00322     }
00323     // simply change the state to SEND_DATA
00324     if (msg->getKind() == BMAC_STOP_PREAMBLES)
00325     {
00326       debugEV << "State SEND_PREAMBLE, message BMAC_STOP_PREAMBLES, new"
00327             " state SEND_DATA" << endl;
00328       macState = SEND_DATA;
00329       txAttempts = 1;
00330       return;
00331     }
00332     break;
00333 
00334   case SEND_DATA:
00335     if ((msg->getKind() == BMAC_SEND_PREAMBLE)
00336       || (msg->getKind() == BMAC_RESEND_DATA))
00337     {
00338       debugEV << "State SEND_DATA, message BMAC_SEND_PREAMBLE or"
00339             " BMAC_RESEND_DATA, new state WAIT_TX_DATA_OVER" << endl;
00340       // send the data packet
00341       sendDataPacket();
00342       macState = WAIT_TX_DATA_OVER;
00343       return;
00344     }
00345     break;
00346 
00347   case WAIT_TX_DATA_OVER:
00348     if (msg->getKind() == BMAC_DATA_TX_OVER)
00349     {
00350       if ((useMacAcks) && (lastDataPktDestAddr != L2BROADCAST))
00351       {
00352         debugEV << "State WAIT_TX_DATA_OVER, message BMAC_DATA_TX_OVER,"
00353               " new state WAIT_ACK" << endl;
00354         macState = WAIT_ACK;
00355         phy->setRadioState(Radio::RX);
00356         changeDisplayColor(GREEN);
00357         scheduleAt(simTime()+checkInterval, ack_timeout);
00358       }
00359       else
00360       {
00361         debugEV << "State WAIT_TX_DATA_OVER, message BMAC_DATA_TX_OVER,"
00362               " new state  SLEEP" << endl;
00363         delete macQueue.front();
00364         macQueue.pop_front();
00365         // if something in the queue, wakeup soon.
00366         if (macQueue.size() > 0)
00367           scheduleAt(simTime() + dblrand()*checkInterval, wakeup);
00368         else
00369           scheduleAt(simTime() + slotDuration, wakeup);
00370         macState = SLEEP;
00371         phy->setRadioState(Radio::SLEEP);
00372         changeDisplayColor(BLACK);
00373       }
00374       return;
00375     }
00376     break;
00377   case WAIT_ACK:
00378     if (msg->getKind() == BMAC_ACK_TIMEOUT)
00379     {
00380       // No ACK received. try again or drop.
00381       if (txAttempts < maxTxAttempts)
00382       {
00383         debugEV << "State WAIT_ACK, message BMAC_ACK_TIMEOUT, new state"
00384               " SEND_DATA" << endl;
00385         txAttempts++;
00386         macState = SEND_PREAMBLE;
00387         scheduleAt(simTime() + slotDuration, stop_preambles);
00388         phy->setRadioState(Radio::TX);
00389         changeDisplayColor(YELLOW);
00390       }
00391       else
00392       {
00393         debugEV << "State WAIT_ACK, message BMAC_ACK_TIMEOUT, new state"
00394               " SLEEP" << endl;
00395         //drop the packet
00396         delete macQueue.front();
00397         macQueue.pop_front();
00398         // if something in the queue, wakeup soon.
00399         if (macQueue.size() > 0)
00400           scheduleAt(simTime() + dblrand()*checkInterval, wakeup);
00401         else
00402           scheduleAt(simTime() + slotDuration, wakeup);
00403         macState = SLEEP;
00404         phy->setRadioState(Radio::SLEEP);
00405         changeDisplayColor(BLACK);
00406         nbMissedAcks++;
00407       }
00408       return;
00409     }
00410     //ignore and other packets
00411     if ((msg->getKind() == BMAC_DATA) || (msg->getKind() == BMAC_PREAMBLE))
00412     {
00413       debugEV << "State WAIT_ACK, message BMAC_DATA or BMAC_PREMABLE, new"
00414             " state WAIT_ACK" << endl;
00415       delete msg;
00416       return;
00417     }
00418     if (msg->getKind() == BMAC_ACK)
00419     {
00420       debugEV << "State WAIT_ACK, message BMAC_ACK" << endl;
00421       MacPkt *mac = static_cast<MacPkt *>(msg);
00422       int src = mac->getSrcAddr();
00423       // the right ACK is received..
00424       debugEV << "We are waiting for ACK from : " << lastDataPktDestAddr
00425            << ", and ACK came from : " << src << endl;
00426       if (src == lastDataPktDestAddr)
00427       {
00428         debugEV << "New state SLEEP" << endl;
00429         nbRecvdAcks++;
00430         lastDataPktDestAddr = L2BROADCAST;
00431         cancelEvent(ack_timeout);
00432         delete macQueue.front();
00433         macQueue.pop_front();
00434         // if something in the queue, wakeup soon.
00435         if (macQueue.size() > 0)
00436           scheduleAt(simTime() + dblrand()*checkInterval, wakeup);
00437         else
00438           scheduleAt(simTime() + slotDuration, wakeup);
00439         macState = SLEEP;
00440         phy->setRadioState(Radio::SLEEP);
00441         changeDisplayColor(BLACK);
00442         lastDataPktDestAddr = L2BROADCAST;
00443       }
00444       delete msg;
00445       return;
00446     }
00447     break;
00448   case WAIT_DATA:
00449     if(msg->getKind() == BMAC_PREAMBLE)
00450     {
00451       //nothing happens
00452       debugEV << "State WAIT_DATA, message BMAC_PREAMBLE, new state"
00453             " WAIT_DATA" << endl;
00454       nbRxPreambles++;
00455       delete msg;
00456       return;
00457     }
00458     if(msg->getKind() == BMAC_ACK)
00459     {
00460       //nothing happens
00461       debugEV << "State WAIT_DATA, message BMAC_ACK, new state WAIT_DATA"
00462            << endl;
00463       delete msg;
00464       return;
00465     }
00466     if (msg->getKind() == BMAC_DATA)
00467     {
00468       nbRxDataPackets++;
00469       MacPkt *mac = static_cast<MacPkt *>(msg);
00470       int dest = mac->getDestAddr();
00471       int src = mac->getSrcAddr();
00472       if ((dest == myMacAddr) || (dest == L2BROADCAST)) {
00473         sendUp(decapsMsg(mac));
00474       } else {
00475         delete msg;
00476         msg = NULL;
00477         mac = NULL;
00478       }
00479 
00480       cancelEvent(data_timeout);
00481       if ((useMacAcks) && (dest == myMacAddr))
00482       {
00483         debugEV << "State WAIT_DATA, message BMAC_DATA, new state"
00484               " SEND_ACK" << endl;
00485         macState = SEND_ACK;
00486         lastDataPktSrcAddr = src;
00487         phy->setRadioState(Radio::TX);
00488         changeDisplayColor(YELLOW);
00489       }
00490       else
00491       {
00492         debugEV << "State WAIT_DATA, message BMAC_DATA, new state SLEEP"
00493              << endl;
00494         // if something in the queue, wakeup soon.
00495         if (macQueue.size() > 0)
00496           scheduleAt(simTime() + dblrand()*checkInterval, wakeup);
00497         else
00498           scheduleAt(simTime() + slotDuration, wakeup);
00499         macState = SLEEP;
00500         phy->setRadioState(Radio::SLEEP);
00501         changeDisplayColor(BLACK);
00502       }
00503       return;
00504     }
00505     if (msg->getKind() == BMAC_DATA_TIMEOUT)
00506     {
00507       debugEV << "State WAIT_DATA, message BMAC_DATA_TIMEOUT, new state"
00508             " SLEEP" << endl;
00509       // if something in the queue, wakeup soon.
00510       if (macQueue.size() > 0)
00511         scheduleAt(simTime() + dblrand()*checkInterval, wakeup);
00512       else
00513         scheduleAt(simTime() + slotDuration, wakeup);
00514       macState = SLEEP;
00515       phy->setRadioState(Radio::SLEEP);
00516       changeDisplayColor(BLACK);
00517       return;
00518     }
00519     break;
00520   case SEND_ACK:
00521     if (msg->getKind() == BMAC_SEND_ACK)
00522     {
00523       debugEV << "State SEND_ACK, message BMAC_SEND_ACK, new state"
00524             " WAIT_ACK_TX" << endl;
00525       // send now the ack packet
00526       sendMacAck();
00527       macState = WAIT_ACK_TX;
00528       return;
00529     }
00530     break;
00531   case WAIT_ACK_TX:
00532     if (msg->getKind() == BMAC_ACK_TX_OVER)
00533     {
00534       debugEV << "State WAIT_ACK_TX, message BMAC_ACK_TX_OVER, new state"
00535             " SLEEP" << endl;
00536       // ack sent, go to sleep now.
00537       // if something in the queue, wakeup soon.
00538       if (macQueue.size() > 0)
00539         scheduleAt(simTime() + dblrand()*checkInterval, wakeup);
00540       else
00541         scheduleAt(simTime() + slotDuration, wakeup);
00542       macState = SLEEP;
00543       phy->setRadioState(Radio::SLEEP);
00544       changeDisplayColor(BLACK);
00545       lastDataPktSrcAddr = L2BROADCAST;
00546       return;
00547     }
00548     break;
00549   }
00550   opp_error("Undefined event of type %d in state %d (Radio state %d)!",
00551         msg->getKind(), macState, phy->getRadioState());
00552 }
00553 
00554 
00558 void BMacLayer::handleLowerMsg(cMessage *msg)
00559 {
00560   // simply pass the massage as self message, to be processed by the FSM.
00561   handleSelfMsg(msg);
00562 }
00563 
00564 void BMacLayer::sendDataPacket()
00565 {
00566   nbTxDataPackets++;
00567   MacPkt *pkt = macQueue.front()->dup();
00568   attachSignal(pkt);
00569   lastDataPktDestAddr = pkt->getDestAddr();
00570   pkt->setKind(BMAC_DATA);
00571   sendDown(pkt);
00572 }
00573 
00578 void BMacLayer::handleLowerControl(cMessage *msg)
00579 {
00580   // Transmission of one packet is over
00581     if(msg->getKind() == MacToPhyInterface::TX_OVER) {
00582       if (macState == WAIT_TX_DATA_OVER)
00583       {
00584         scheduleAt(simTime(), data_tx_over);
00585       }
00586       if (macState == WAIT_ACK_TX)
00587       {
00588         scheduleAt(simTime(), ack_tx_over);
00589       }
00590     }
00591     // Radio switching (to RX or TX) ir over, ignore switching to SLEEP.
00592     else if(msg->getKind() == MacToPhyInterface::RADIO_SWITCHING_OVER) {
00593       // we just switched to TX after CCA, so simply send the first
00594       // sendPremable self message
00595       if ((macState == SEND_PREAMBLE) && (phy->getRadioState() == Radio::TX))
00596       {
00597         scheduleAt(simTime(), send_preamble);
00598       }
00599       if ((macState == SEND_ACK) && (phy->getRadioState() == Radio::TX))
00600       {
00601         scheduleAt(simTime(), send_ack);
00602       }
00603       // we were waiting for acks, but none came. we switched to TX and now
00604       // need to resend data
00605       if ((macState == SEND_DATA) && (phy->getRadioState() == Radio::TX))
00606       {
00607         scheduleAt(simTime(), resend_data);
00608       }
00609 
00610     }
00611     else {
00612         debugEV << "control message with wrong kind -- deleting\n";
00613     }
00614     delete msg;
00615 }
00616 
00617 
00618 
00619 
00624 bool BMacLayer::addToQueue(cMessage *msg)
00625 {
00626   if (macQueue.size() >= queueLength) {
00627     // queue is full, message has to be deleted
00628     debugEV << "New packet arrived, but queue is FULL, so new packet is"
00629           " deleted\n";
00630     msg->setName("MAC ERROR");
00631     msg->setKind(PACKET_DROPPED);
00632     sendControlUp(msg);
00633     droppedPacket.setReason(DroppedPacket::QUEUE);
00634     utility->publishBBItem(catDroppedPacket, &droppedPacket, nicId);
00635     nbDroppedDataPackets++;
00636 
00637     return false;
00638   }
00639 
00640   MacPkt *macPkt = new MacPkt(msg->getName());
00641   macPkt->setBitLength(headerLength);
00642   NetwToMacControlInfo* cInfo
00643       = static_cast<NetwToMacControlInfo*> (msg->removeControlInfo());
00644   //EV<<"CSMA received a message from upper layer, name is "
00645   //  << msg->getName() <<", CInfo removed, mac addr="
00646   //  << cInfo->getNextHopMac()<<endl;
00647   int dest = cInfo->getNextHopMac();
00648   macPkt->setDestAddr(dest);
00649   delete cInfo;
00650   macPkt->setSrcAddr(myMacAddr);
00651 
00652   assert(static_cast<cPacket*>(msg));
00653   macPkt->encapsulate(static_cast<cPacket*>(msg));
00654 
00655   macQueue.push_back(macPkt);
00656   debugEV << "Max queue length: " << queueLength << ", packet put in queue"
00657         "\n  queue size: " << macQueue.size() << " macState: "
00658         << macState << endl;
00659   return true;
00660 }
00661 
00662 void BMacLayer::attachSignal(MacPkt *macPkt)
00663 {
00664   //calc signal duration
00665   simtime_t duration = macPkt->getBitLength() / bitrate;
00666   //create signal
00667   Signal* s = createSignal(simTime(), duration, txPower, bitrate);
00668   //create and initialize control info
00669   MacToPhyControlInfo* ctrl = new MacToPhyControlInfo(s);
00670   macPkt->setControlInfo(ctrl);
00671 }
00672 
00677 void BMacLayer::changeDisplayColor(BMAC_COLORS color)
00678 {
00679   if (!animation)
00680     return;
00681   cDisplayString& dispStr
00682       = findHost()->getDisplayString();
00683   //b=40,40,rect,black,black,2"
00684   if (color == GREEN)
00685     dispStr.setTagArg("b", 3, "green");
00686     //dispStr.parse("b=40,40,rect,green,green,2");
00687   if (color == BLUE)
00688     dispStr.setTagArg("b", 3, "blue");
00689         //dispStr.parse("b=40,40,rect,blue,blue,2");
00690   if (color == RED)
00691     dispStr.setTagArg("b", 3, "red");
00692         //dispStr.parse("b=40,40,rect,red,red,2");
00693   if (color == BLACK)
00694     dispStr.setTagArg("b", 3, "black");
00695         //dispStr.parse("b=40,40,rect,black,black,2");
00696   if (color == YELLOW)
00697     dispStr.setTagArg("b", 3, "yellow");
00698         //dispStr.parse("b=40,40,rect,yellow,yellow,2");
00699 }
00700 
00701 /*void BMacLayer::changeMacState(States newState)
00702 {
00703   switch (macState)
00704   {
00705   case RX:
00706     timeRX += (simTime() - lastTime);
00707     break;
00708   case TX:
00709     timeTX += (simTime() - lastTime);
00710     break;
00711   case SLEEP:
00712     timeSleep += (simTime() - lastTime);
00713     break;
00714   case CCA:
00715     timeRX += (simTime() - lastTime);
00716   }
00717   lastTime = simTime();
00718 
00719   switch (newState)
00720   {
00721   case CCA:
00722     changeDisplayColor(GREEN);
00723     break;
00724   case TX:
00725     changeDisplayColor(BLUE);
00726     break;
00727   case SLEEP:
00728     changeDisplayColor(BLACK);
00729     break;
00730   case RX:
00731     changeDisplayColor(YELLOW);
00732     break;
00733   }
00734 
00735   macState = newState;
00736 }*/