00001 #include "BasePhyLayer.h"
00002 #include "BaseWorldUtility.h"
00003
00004 #include "MacToPhyControlInfo.h"
00005 #include "PhyToMacControlInfo.h"
00006
00007
00008
00009
00010 Define_Module(BasePhyLayer);
00011
00012 short BasePhyLayer::airFramePriority = 10;
00013
00014
00015
00016 BasePhyLayer::BasePhyLayer():
00017 protocolId(GENERIC),
00018 thermalNoise(0),
00019 radio(0),
00020 decider(0),
00021 radioSwitchingOverTimer(0),
00022 txOverTimer(0),
00023 world(0)
00024 {}
00025
00026 template<class T> T BasePhyLayer::readPar(const char* parName, const T defaultValue){
00027 if(hasPar(parName))
00028 return par(parName);
00029 else
00030 return defaultValue;
00031 }
00032
00033
00034
00035
00036
00037 template int BasePhyLayer::readPar<int>(const char* parName, const int);
00038 template double BasePhyLayer::readPar<double>(const char* parName, const double);
00039 template simtime_t BasePhyLayer::readPar<simtime_t>(const char* parName, const simtime_t);
00040 template bool BasePhyLayer::readPar<bool>(const char* parName, const bool);
00041
00042 void BasePhyLayer::initialize(int stage) {
00043
00044 ChannelAccess::initialize(stage);
00045
00046 if (stage == 0) {
00047
00048 gate("radioIn")->setDeliverOnReceptionStart(true);
00049
00050
00051 upperGateIn = findGate("upperGateIn");
00052 upperGateOut = findGate("upperGateOut");
00053 upperControlOut = findGate("upperControlOut");
00054 upperControlIn = findGate("upperControlIn");
00055
00056
00057
00058 if(par("useThermalNoise").boolValue()) {
00059 double thermalNoiseVal = FWMath::dBm2mW(par("thermalNoise").doubleValue());
00060 thermalNoise = new ConstantSimpleConstMapping(DimensionSet::timeDomain,
00061 thermalNoiseVal);
00062 } else {
00063 thermalNoise = 0;
00064 }
00065 headerLength = par("headerLength").longValue();
00066 sensitivity = par("sensitivity").doubleValue();
00067 sensitivity = FWMath::dBm2mW(sensitivity);
00068 maxTXPower = par("maxTXPower").doubleValue();
00069
00070 recordStats = par("recordStats").boolValue();
00071
00072
00073 radio = initializeRadio();
00074
00075
00076 world = FindModule<BaseWorldUtility*>::findGlobalModule();
00077 if (world == NULL) {
00078 opp_error("Could not find BaseWorldUtility module");
00079 }
00080
00081 if(cc->hasPar("sat")
00082 && (sensitivity - FWMath::dBm2mW(cc->par("sat").doubleValue())) < -0.000001) {
00083 opp_error("Sensitivity can't be smaller than the "
00084 "signal attenuation threshold (sat) in ConnectionManager. "
00085 "Please adjust your omnetpp.ini file accordingly.");
00086 }
00087
00088
00089
00090
00091 initializeAnalogueModels(par("analogueModels").xmlValue());
00092
00093 initializeDecider(par("decider").xmlValue());
00094
00095
00096 radioSwitchingOverTimer = new cMessage("radio switching over", RADIO_SWITCHING_OVER);
00097 txOverTimer = new cMessage("transmission over", TX_OVER);
00098
00099 }
00100 }
00101
00102 Radio* BasePhyLayer::initializeRadio() {
00103 int initialRadioState = par("initialRadioState").longValue();
00104 double radioMinAtt = par("radioMinAtt").doubleValue();
00105 double radioMaxAtt = par("radioMaxAtt").doubleValue();
00106 int nbRadioChannels = readPar("nbRadioChannels", 1);
00107 int initialRadioChannel = readPar("initialRadioChannel", 0);
00108
00109 Radio* radio = Radio::createNewRadio(recordStats, initialRadioState,
00110 radioMinAtt, radioMaxAtt,
00111 initialRadioChannel, nbRadioChannels);
00112
00113
00114 simtime_t rxToTX = par("timeRXToTX").doubleValue();
00115 simtime_t sleepToTX = par("timeSleepToTX").doubleValue();
00116
00117
00118 radio->setSwitchTime(Radio::RX, Radio::TX, par("timeRXToTX").doubleValue());
00119
00120 radio->setSwitchTime(Radio::SLEEP, Radio::TX, par("timeSleepToTX").doubleValue());
00121
00122
00123
00124 simtime_t txToRX = par("timeTXToRX").doubleValue();
00125 simtime_t sleepToRX = par("timeSleepToRX").doubleValue();
00126
00127
00128 radio->setSwitchTime(Radio::TX, Radio::RX, par("timeTXToRX").doubleValue());
00129
00130 radio->setSwitchTime(Radio::SLEEP, Radio::RX, par("timeSleepToRX").doubleValue());
00131
00132
00133
00134 simtime_t txToSleep = par("timeTXToSleep").doubleValue();
00135 simtime_t rxToSleep = par("timeRXToSleep").doubleValue();
00136
00137
00138 radio->setSwitchTime(Radio::TX, Radio::SLEEP, par("timeTXToSleep").doubleValue());
00139
00140 radio->setSwitchTime(Radio::RX, Radio::SLEEP, par("timeRXToSleep").doubleValue());
00141
00142 return radio;
00143 }
00144
00145 void BasePhyLayer::getParametersFromXML(cXMLElement* xmlData, ParameterMap& outputMap) {
00146 cXMLElementList parameters = xmlData->getElementsByTagName("Parameter");
00147
00148 for(cXMLElementList::const_iterator it = parameters.begin();
00149 it != parameters.end(); it++) {
00150
00151 const char* name = (*it)->getAttribute("name");
00152 const char* type = (*it)->getAttribute("type");
00153 const char* value = (*it)->getAttribute("value");
00154 if(name == 0 || type == 0 || value == 0) {
00155 ev << "Invalid parameter, could not find name, type or value." << endl;
00156 continue;
00157 }
00158
00159 std::string sType = type;
00160 std::string sValue = value;
00161
00162 cMsgPar param(name);
00163
00164
00165 if (sType == "bool") {
00166 param.setBoolValue(sValue == "true" || sValue == "1");
00167
00168 } else if (sType == "double") {
00169 param.setDoubleValue(strtod(value, 0));
00170
00171 } else if (sType == "string") {
00172 param.setStringValue(value);
00173
00174 } else if (sType == "long") {
00175 param.setLongValue(strtol(value, 0, 0));
00176
00177 } else {
00178 ev << "Unknown parameter type: \"" << sType << "\"" << endl;
00179 continue;
00180 }
00181
00182
00183 outputMap[name] = param;
00184 }
00185 }
00186
00187 void BasePhyLayer::finish(){
00188
00189 decider->finish();
00190 }
00191
00192
00193
00194
00195 void BasePhyLayer::initializeDecider(cXMLElement* xmlConfig) {
00196
00197 decider = 0;
00198
00199 if(xmlConfig == 0) {
00200 opp_error("No decider configuration file specified.");
00201 return;
00202 }
00203
00204 cXMLElementList deciderList = xmlConfig->getElementsByTagName("Decider");
00205
00206 if(deciderList.empty()) {
00207 opp_error("No decider configuration found in configuration file.");
00208 return;
00209 }
00210
00211 if(deciderList.size() > 1) {
00212 opp_error("More than one decider configuration found in configuration file.");
00213 return;
00214 }
00215
00216 cXMLElement* deciderData = deciderList.front();
00217
00218 const char* name = deciderData->getAttribute("type");
00219
00220 if(name == 0) {
00221 opp_error("Could not read type of decider from configuration file.");
00222 return;
00223 }
00224
00225 ParameterMap params;
00226 getParametersFromXML(deciderData, params);
00227
00228 decider = getDeciderFromName(name, params);
00229
00230 if(decider == 0) {
00231 opp_error("Could not find a decider with the name \"%s\".", name);
00232 return;
00233 }
00234
00235 coreEV << "Decider \"" << name << "\" loaded." << endl;
00236 }
00237
00238 Decider* BasePhyLayer::getDeciderFromName(std::string name, ParameterMap& params)
00239 {
00240
00241 return 0;
00242 }
00243
00244
00245
00246
00247 void BasePhyLayer::initializeAnalogueModels(cXMLElement* xmlConfig) {
00248
00249
00250
00251
00252
00253
00254 std::string s("RadioStateAnalogueModel");
00255 ParameterMap p;
00256
00257 AnalogueModel* newAnalogueModel = getAnalogueModelFromName(s, p);
00258
00259 if(newAnalogueModel == 0)
00260 {
00261 opp_warning("Could not find an analogue model with the name \"%s\".", s.c_str());
00262 }
00263 else
00264 {
00265 analogueModels.push_back(newAnalogueModel);
00266 }
00267
00268
00269 if(xmlConfig == 0) {
00270 opp_warning("No analogue models configuration file specified.");
00271 return;
00272 }
00273
00274 cXMLElementList analogueModelList = xmlConfig->getElementsByTagName("AnalogueModel");
00275
00276 if(analogueModelList.empty()) {
00277 opp_warning("No analogue models configuration found in configuration file.");
00278 return;
00279 }
00280
00281
00282
00283 for(cXMLElementList::const_iterator it = analogueModelList.begin();
00284 it != analogueModelList.end(); it++) {
00285
00286
00287 cXMLElement* analogueModelData = *it;
00288
00289 const char* name = analogueModelData->getAttribute("type");
00290
00291 if(name == 0) {
00292 opp_warning("Could not read name of analogue model.");
00293 continue;
00294 }
00295
00296 ParameterMap params;
00297 getParametersFromXML(analogueModelData, params);
00298
00299 AnalogueModel* newAnalogueModel = getAnalogueModelFromName(name, params);
00300
00301 if(newAnalogueModel == 0) {
00302 opp_warning("Could not find an analogue model with the name \"%s\".", name);
00303 continue;
00304 }
00305
00306
00307 analogueModels.push_back(newAnalogueModel);
00308
00309 coreEV << "AnalogueModel \"" << name << "\" loaded." << endl;
00310
00311 }
00312
00313
00314 }
00315
00316 AnalogueModel* BasePhyLayer::getAnalogueModelFromName(std::string name, ParameterMap& params) {
00317
00318
00319
00320
00321 if (name == "RadioStateAnalogueModel")
00322 {
00323 return radio->getAnalogueModel();
00324 }
00325
00326 return 0;
00327 }
00328
00329
00330
00331
00332
00333 void BasePhyLayer::handleMessage(cMessage* msg) {
00334
00335
00336 if(msg->isSelfMessage()) {
00337 handleSelfMessage(msg);
00338
00339
00340 } else if(msg->getArrivalGateId() == upperGateIn) {
00341 handleUpperMessage(msg);
00342
00343
00344 } else if(msg->getArrivalGateId() == upperControlIn) {
00345 handleUpperControlMessage(msg);
00346
00347
00348 } else if(msg->getKind() == AIR_FRAME){
00349 handleAirFrame(msg);
00350
00351
00352 } else {
00353 ev << "Unknown message received." << endl;
00354 delete msg;
00355 }
00356 }
00357
00358 void BasePhyLayer::handleAirFrame(cMessage* msg) {
00359 AirFrame* frame = static_cast<AirFrame*>(msg);
00360
00361
00362
00363
00364 switch(frame->getState()) {
00365 case START_RECEIVE:
00366 handleAirFrameStartReceive(frame);
00367 break;
00368
00369 case RECEIVING: {
00370 handleAirFrameReceiving(frame);
00371 break;
00372 }
00373 case END_RECEIVE:
00374 handleAirFrameEndReceive(frame);
00375 break;
00376
00377 default:
00378 opp_error( "Unknown AirFrame state: %s", frame->getState());
00379 break;
00380 }
00381 }
00382
00383 void BasePhyLayer::handleAirFrameStartReceive(AirFrame* frame) {
00384 coreEV << "Received new AirFrame " << frame << " from channel." << endl;
00385
00386 if(channelInfo.isChannelEmpty()) {
00387 radio->setTrackingModeTo(true);
00388 }
00389
00390 channelInfo.addAirFrame(frame, simTime());
00391 assert(!channelInfo.isChannelEmpty());
00392
00393 if(usePropagationDelay) {
00394 Signal& s = frame->getSignal();
00395 simtime_t delay = simTime() - s.getSignalStart();
00396 s.setPropagationDelay(delay);
00397 }
00398 assert(frame->getSignal().getSignalStart() == simTime());
00399
00400 filterSignal(frame->getSignal());
00401
00402 if(decider and isKnownProtocolId(frame->getProtocolId())) {
00403 frame->setState(RECEIVING);
00404
00405
00406 handleAirFrameReceiving(frame);
00407
00408
00409 } else {
00410 Signal& signal = frame->getSignal();
00411
00412 simtime_t signalEndTime = signal.getSignalStart() + frame->getDuration();
00413 frame->setState(END_RECEIVE);
00414
00415 sendSelfMessage(frame, signalEndTime);
00416 }
00417 }
00418
00419 void BasePhyLayer::handleAirFrameReceiving(AirFrame* frame) {
00420
00421 Signal& signal = frame->getSignal();
00422 simtime_t nextHandleTime = decider->processSignal(frame);
00423
00424 assert(signal.getSignalLength() == frame->getDuration());
00425 simtime_t signalEndTime = signal.getSignalStart() + frame->getDuration();
00426
00427
00428 if(simTime() >= signalEndTime) {
00429 frame->setState(END_RECEIVE);
00430 handleAirFrameEndReceive(frame);
00431 return;
00432 }
00433
00434
00435 if(nextHandleTime < 0) {
00436 nextHandleTime = signalEndTime;
00437 frame->setState(END_RECEIVE);
00438
00439
00440 } else if(nextHandleTime < simTime() || nextHandleTime > signalEndTime) {
00441 opp_error("Invalid next handle time returned by Decider. Expected a value between current simulation time (%.2f) and end of signal (%.2f) but got %.2f",
00442 SIMTIME_DBL(simTime()), SIMTIME_DBL(signalEndTime), SIMTIME_DBL(nextHandleTime));
00443 }
00444
00445 coreEV << "Handed AirFrame with ID " << frame->getId() << " to Decider. Next handling in " << nextHandleTime - simTime() << "s." << endl;
00446
00447 sendSelfMessage(frame, nextHandleTime);
00448 }
00449
00450 void BasePhyLayer::handleAirFrameEndReceive(AirFrame* frame) {
00451 coreEV << "End of Airframe with ID " << frame->getId() << "." << endl;
00452
00453 simtime_t earliestInfoPoint = channelInfo.removeAirFrame(frame);
00454
00455
00456
00457
00458
00459
00460 if(channelInfo.isChannelEmpty()) {
00461 earliestInfoPoint = simTime();
00462 radio->setTrackingModeTo(false);
00463 }
00464
00465 radio->cleanAnalogueModelUntil(earliestInfoPoint);
00466 }
00467
00468 void BasePhyLayer::handleUpperMessage(cMessage* msg){
00469
00470
00471 if (radio->getCurrentState() != Radio::TX)
00472 {
00473 delete msg;
00474 msg = 0;
00475 opp_error("Error: message for sending received, but radio not in state TX");
00476 }
00477
00478
00479 if(txOverTimer->isScheduled())
00480 {
00481 delete msg;
00482 msg = 0;
00483 opp_error("Error: message for sending received, but radio already sending");
00484 }
00485
00486
00487 assert(dynamic_cast<cPacket*>(msg) != 0);
00488
00489 AirFrame* frame = encapsMsg(static_cast<cPacket*>(msg));
00490
00491
00492
00493 assert (!txOverTimer->isScheduled());
00494 sendSelfMessage(txOverTimer, simTime() + frame->getDuration());
00495
00496 sendMessageDown(frame);
00497 }
00498
00499 AirFrame *BasePhyLayer::encapsMsg(cPacket *macPkt)
00500 {
00501
00502
00503
00504
00505 cObject* ctrlInfo = macPkt->removeControlInfo();
00506 assert(ctrlInfo);
00507
00508
00509 AirFrame* frame = new AirFrame(macPkt->getName(), AIR_FRAME);
00510
00511 MacToPhyControlInfo* macToPhyCI = static_cast<MacToPhyControlInfo*>(ctrlInfo);
00512
00513
00514
00515
00516
00517 Signal* s = macToPhyCI->retrieveSignal();
00518
00519 assert(s);
00520
00521
00522 s->setMove(move);
00523
00524
00525 assert(s->getSignalLength() > 0);
00526 frame->setDuration(s->getSignalLength());
00527
00528 frame->setSignal(*s);
00529
00530
00531
00532
00533 frame->setSchedulingPriority(airFramePriority);
00534 frame->setProtocolId(myProtocolId());
00535 frame->setBitLength(headerLength);
00536 frame->setId(world->getUniqueAirFrameId());
00537 frame->setChannel(radio->getCurrentChannel());
00538
00539
00540
00541 delete s;
00542 s = 0;
00543
00544
00545
00546
00547 delete macToPhyCI;
00548 macToPhyCI = 0;
00549 ctrlInfo = 0;
00550
00551
00552
00553
00554
00555 frame->encapsulate(macPkt);
00556
00557
00558 macPkt = 0;
00559 coreEV <<"AirFrame encapsulated, length: " << frame->getBitLength() << "\n";
00560
00561 return frame;
00562 }
00563
00564 void BasePhyLayer::handleChannelSenseRequest(cMessage* msg) {
00565 ChannelSenseRequest* senseReq = static_cast<ChannelSenseRequest*>(msg);
00566
00567 simtime_t nextHandleTime = decider->handleChannelSenseRequest(senseReq);
00568
00569 if(nextHandleTime >= simTime()) {
00570 sendSelfMessage(msg, nextHandleTime);
00571
00572
00573 if(!channelInfo.isRecording()) {
00574 channelInfo.startRecording(simTime());
00575 }
00576 } else if(nextHandleTime >= 0.0){
00577 opp_error("Next handle time of ChannelSenseRequest returned by the Decider is smaller then current simulation time: %.2f",
00578 SIMTIME_DBL(nextHandleTime));
00579 }
00580
00581
00582
00583 }
00584
00585 void BasePhyLayer::handleUpperControlMessage(cMessage* msg){
00586
00587 switch(msg->getKind()) {
00588 case CHANNEL_SENSE_REQUEST:
00589 handleChannelSenseRequest(msg);
00590 break;
00591 default:
00592 ev << "Received unknown control message from upper layer!" << endl;
00593 break;
00594 }
00595 }
00596
00597 void BasePhyLayer::handleSelfMessage(cMessage* msg) {
00598
00599 switch(msg->getKind()) {
00600
00601 case TX_OVER:
00602 assert(msg == txOverTimer);
00603 sendControlMsg(new cMessage("Transmission over", TX_OVER));
00604 break;
00605
00606
00607 case RADIO_SWITCHING_OVER:
00608 assert(msg == radioSwitchingOverTimer);
00609 finishRadioSwitching();
00610 break;
00611
00612
00613 case AIR_FRAME:
00614 handleAirFrame(msg);
00615 break;
00616
00617
00618 case CHANNEL_SENSE_REQUEST:
00619 handleChannelSenseRequest(msg);
00620 break;
00621
00622 default:
00623 break;
00624 }
00625 }
00626
00627
00628
00629 void BasePhyLayer::sendControlMessageUp(cMessage* msg) {
00630 send(msg, upperControlOut);
00631 }
00632
00633 void BasePhyLayer::sendMacPktUp(cMessage* pkt) {
00634 send(pkt, upperGateOut);
00635 }
00636
00637 void BasePhyLayer::sendMessageDown(AirFrame* msg) {
00638
00639 sendToChannel(msg);
00640 }
00641
00642 void BasePhyLayer::sendSelfMessage(cMessage* msg, simtime_t time) {
00643
00644
00645
00646 scheduleAt(time, msg);
00647 }
00648
00649
00650 void BasePhyLayer::filterSignal(Signal& s) {
00651 for(AnalogueModelList::const_iterator it = analogueModels.begin();
00652 it != analogueModels.end(); it++) {
00653
00654 AnalogueModel* tmp = *it;
00655 tmp->filterSignal(s);
00656 }
00657 }
00658
00659
00660
00661 BasePhyLayer::~BasePhyLayer() {
00662
00663
00664
00665 AirFrameVector channel;
00666 channelInfo.getAirFrames(0, simTime(), channel);
00667
00668 for(AirFrameVector::iterator it = channel.begin();
00669 it != channel.end(); ++it)
00670 {
00671 cancelAndDelete(*it);
00672 }
00673
00674
00675 if(txOverTimer) {
00676 cancelAndDelete(txOverTimer);
00677 }
00678 if(radioSwitchingOverTimer) {
00679 cancelAndDelete(radioSwitchingOverTimer);
00680 }
00681
00682
00683 if(thermalNoise) {
00684 delete thermalNoise;
00685 }
00686
00687
00688 if(decider != 0) {
00689 delete decider;
00690 }
00691
00692
00693
00694
00695
00696 AnalogueModel* rsamPointer = radio->getAnalogueModel();
00697
00698
00699 for(AnalogueModelList::iterator it = analogueModels.begin();
00700 it != analogueModels.end(); it++) {
00701
00702 AnalogueModel* tmp = *it;
00703
00704
00705 if (tmp == rsamPointer)
00706 {
00707 rsamPointer = 0;
00708 continue;
00709 }
00710
00711 if(tmp != 0) {
00712 delete tmp;
00713 }
00714 }
00715
00716
00717
00718 if(radio != 0)
00719 {
00720 delete radio;
00721 }
00722 }
00723
00724
00725
00726 int BasePhyLayer::getRadioState() {
00727 Enter_Method_Silent();
00728 assert(radio);
00729 return radio->getCurrentState();
00730 }
00731
00732 void BasePhyLayer::finishRadioSwitching()
00733 {
00734 radio->endSwitch(simTime());
00735 sendControlMsg(new cMessage("Radio switching over", RADIO_SWITCHING_OVER));
00736 }
00737
00738 simtime_t BasePhyLayer::setRadioState(int rs) {
00739 Enter_Method_Silent();
00740 assert(radio);
00741
00742 if(txOverTimer && txOverTimer->isScheduled()) {
00743 opp_warning("Switched radio while sending an AirFrame. The effects this would have on the transmission are not simulated by the BasePhyLayer!");
00744 }
00745
00746 simtime_t switchTime = radio->switchTo(rs, simTime());
00747
00748
00749 if(switchTime < 0)
00750 return switchTime;
00751
00752
00753 if (switchTime == 0.0)
00754 {
00755
00756
00757 finishRadioSwitching();
00758 } else
00759 {
00760 sendSelfMessage(radioSwitchingOverTimer, simTime() + switchTime);
00761 }
00762
00763 return switchTime;
00764 }
00765
00766 ChannelState BasePhyLayer::getChannelState() {
00767 Enter_Method_Silent();
00768 assert(decider);
00769 return decider->getChannelState();
00770 }
00771
00772 int BasePhyLayer::getPhyHeaderLength() {
00773 Enter_Method_Silent();
00774 return par("headerLength").longValue();
00775 }
00776
00777 void BasePhyLayer::setCurrentRadioChannel(int newRadioChannel) {
00778 if(txOverTimer && txOverTimer->isScheduled()) {
00779 opp_warning("Switched channel while sending an AirFrame. The effects this would have on the transmission are not simulated by the BasePhyLayer!");
00780 }
00781
00782 radio->setCurrentChannel(newRadioChannel);
00783 decider->channelChanged(newRadioChannel);
00784 coreEV << "Switched radio to channel " << newRadioChannel << endl;
00785 }
00786
00787 int BasePhyLayer::getCurrentRadioChannel() {
00788 return radio->getCurrentChannel();
00789 }
00790
00791 int BasePhyLayer::getNbRadioChannels() {
00792 return par("nbRadioChannels");
00793 }
00794
00795
00796
00797 void BasePhyLayer::getChannelInfo(simtime_t from, simtime_t to, AirFrameVector& out) {
00798 channelInfo.getAirFrames(from, to, out);
00799 }
00800
00801 ConstMapping* BasePhyLayer::getThermalNoise(simtime_t from, simtime_t to) {
00802 if(thermalNoise)
00803 thermalNoise->initializeArguments(Argument(from));
00804
00805 return thermalNoise;
00806 }
00807
00808 void BasePhyLayer::sendControlMsg(cMessage* msg) {
00809 if(msg->getKind() == CHANNEL_SENSE_REQUEST) {
00810 if(channelInfo.isRecording()) {
00811 channelInfo.stopRecording();
00812 }
00813 }
00814 sendControlMessageUp(msg);
00815 }
00816
00817 void BasePhyLayer::sendUp(AirFrame* frame, DeciderResult* result) {
00818
00819 coreEV << "Decapsulating MacPacket from Airframe with ID " << frame->getId() << " and sending it up to MAC." << endl;
00820
00821 cMessage* packet = frame->decapsulate();
00822
00823 assert(packet);
00824
00825 PhyToMacControlInfo* ctrlInfo = new PhyToMacControlInfo(result);
00826
00827 packet->setControlInfo(ctrlInfo);
00828
00829 sendMacPktUp(packet);
00830 }
00831
00832 simtime_t BasePhyLayer::getSimTime() {
00833
00834 return simTime();
00835 }
00836
00837 void BasePhyLayer::cancelScheduledMessage(cMessage* msg) {
00838 if(msg->isScheduled()){
00839 cancelEvent(msg);
00840 } else {
00841 EV << "Warning: Decider wanted to cancel a scheduled message but message"
00842 << " wasn't actually scheduled. Message is: " << msg << endl;
00843 }
00844 }
00845
00846 void BasePhyLayer::rescheduleMessage(cMessage* msg, simtime_t t) {
00847 cancelScheduledMessage(msg);
00848 scheduleAt(t, msg);
00849 }
00850
00851 void BasePhyLayer::drawCurrent(double amount, int activity) {
00852 BatteryAccess::drawCurrent(amount, activity);
00853 }
00854
00855 BaseUtility* BasePhyLayer::getUtility() {
00856 return utility;
00857 }
00858
00859 BaseWorldUtility* BasePhyLayer::getWorldUtility() {
00860 return world;
00861 }
00862
00863 void BasePhyLayer::recordScalar(const char *name, double value, const char *unit) {
00864 ChannelAccess::recordScalar(name, value, unit);
00865 }