00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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
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
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
00150
00151
00152 }
00153 }
00154
00160 void BMacLayer::handleUpperMsg(cMessage *msg)
00161 {
00162 bool pktAdded = addToQueue(msg);
00163 if (!pktAdded)
00164 return;
00165
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
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
00202 attachSignal(ack);
00203 sendDown(ack);
00204 nbTxAcks++;
00205
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
00253
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
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
00277
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
00290
00291
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
00304
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
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
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
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
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
00396 delete macQueue.front();
00397 macQueue.pop_front();
00398
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
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
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
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
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
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
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
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
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
00537
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
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
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
00592 else if(msg->getKind() == MacToPhyInterface::RADIO_SWITCHING_OVER) {
00593
00594
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
00604
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
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
00645
00646
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
00665 simtime_t duration = macPkt->getBitLength() / bitrate;
00666
00667 Signal* s = createSignal(simTime(), duration, txPower, bitrate);
00668
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
00684 if (color == GREEN)
00685 dispStr.setTagArg("b", 3, "green");
00686
00687 if (color == BLUE)
00688 dispStr.setTagArg("b", 3, "blue");
00689
00690 if (color == RED)
00691 dispStr.setTagArg("b", 3, "red");
00692
00693 if (color == BLACK)
00694 dispStr.setTagArg("b", 3, "black");
00695
00696 if (color == YELLOW)
00697 dispStr.setTagArg("b", 3, "yellow");
00698
00699 }
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736