00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "LMacLayer.h"
00013
00014
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
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
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
00125
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
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
00161
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
00180
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)
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
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
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
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
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
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
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
00385
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
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
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
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
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
00595 handleSelfMsg(msg);
00596 }
00597
00598
00602 void LMacLayer::handleLowerControl(cMessage *msg)
00603 {
00604 if(msg->getKind() == MacToPhyInterface::TX_OVER)
00605 {
00606
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
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
00648
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
00683
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
00690 delete cInfo;
00691
00692
00693 pkt->setSrcAddr(myMacAddr);
00694
00695
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
00707 simtime_t duration = macPkt->getBitLength() / bitrate;
00708
00709 Signal* s = createSignal(simTime(), duration, txPower, bitrate);
00710
00711 MacToPhyControlInfo* ctrl = new MacToPhyControlInfo(s);
00712 macPkt->setControlInfo(ctrl);
00713 }
00714