SimpleMacLayer.cc

00001 #include "SimpleMacLayer.h"
00002 #include "Mapping.h"
00003 
00004 Define_Module(SimpleMacLayer);
00005 
00006 //---omnetpp part----------------------
00007 
00008 //---intialisation---------------------
00009 void SimpleMacLayer::initialize(int stage) {
00010   BaseModule::initialize(stage);
00011 
00012   if(stage == 0) {
00013     myIndex = findHost()->getIndex();
00014 
00015     dimensions.addDimension(Dimension::time);
00016     dimensions.addDimension(Dimension::frequency);
00017 
00018     dataOut = findGate("lowerGateOut");
00019     dataIn = findGate("lowerGateIn");
00020 
00021     phy = FindModule<MacToPhyInterface*>::findSubModule(this->getParentModule());
00022 
00023   } else if(stage == 1) {
00024     if(myIndex == 0){ //host with index 0 start with sending packets
00025       log("Switching radio to TX...");
00026       nextReceiver = 1;
00027       phy->setRadioState(Radio::TX); //to be able to send packets it has to switch to TX mode
00028 
00029     }else{ //every other host start in receiving mode
00030       log("Switching radio to RX...");
00031       phy->setRadioState(Radio::RX);
00032     }
00033     //switching the radio can take some time,
00034     //we will get a "RADIO_SWITCHING_OVER" message as soon as the radio has switched.
00035   }
00036 }
00037 
00038 void SimpleMacLayer::handleMessage(cMessage* msg) {
00039 
00040   //what to do if the radio has switched
00041   if(msg->getKind() == MacToPhyInterface::RADIO_SWITCHING_OVER) {
00042     log("...switching radio done.");
00043 
00044     switch(phy->getRadioState()) {
00045     case Radio::TX:     //if we switched to TX mode we probably wanted to send
00046       broadCastPacket();  //an answer packet
00047       break;
00048     default:
00049       break;
00050     }
00051     delete msg;
00052 
00053   //forward MacPackets and TX_OVER to their own handling routine
00054   } else if (msg->getKind() == TEST_MACPKT) {
00055     handleMacPkt(static_cast<MacPkt*>(msg));
00056   } else if(msg->getKind() == MacToPhyInterface::TX_OVER) {
00057     handleTXOver();
00058     delete msg;
00059   }
00060 
00061 }
00062 
00063 void SimpleMacLayer::handleTXOver() {
00064   //the TX_Over message is sent by the phy to us to indicate that
00065   //the sending process is over. SO we will switch back to receiving
00066   //mode after that.
00067   log("Transmission over signal from PhyLayer received. Changing back to RX");
00068   phy->setRadioState(Radio::RX);
00069 }
00070 
00071 void SimpleMacLayer::handleMacPkt(MacPkt* pkt) {
00072 
00073   //if we got a Mac packet check if it was for us or not.
00074   if(pkt->getDestAddr() == myIndex){
00075     log("Received MacPkt for me - broadcasting answer (but first change to TX mode)");
00076     if(myIndex == 0)
00077       nextReceiver = 1;
00078     else
00079       nextReceiver = 0;
00080 
00081     //if the destination of the packet was us, send an answer packet->switch to sending mode
00082     phy->setRadioState(Radio::TX);
00083   }else
00084     log("Received MacPkt - but not for me.");
00085 
00086   delete pkt;
00087 
00088 }
00089 
00090 void SimpleMacLayer::log(std::string msg) {
00091   ev << "[Host " << myIndex << "] - MacLayer: " << msg << endl;
00092 }
00093 
00094 void SimpleMacLayer::broadCastPacket() {
00095   //create the answer packet of length 64kByte / 11kByte/sec
00096   MacPkt* pkt = createMacPkt(64.0 / 11000.0);
00097 
00098   log("Sending broadcast packet to phy layer.");
00099   //pass it to the phy layer
00100   sendDown(pkt);
00101 }
00102 
00103 void SimpleMacLayer::sendDown(MacPkt* pkt) {
00104   send(pkt, dataOut);
00105 }
00106 
00107 Mapping* SimpleMacLayer::createMapping(simtime_t time, simtime_t length, double freqFrom, double freqTo, double value){
00108   //create mapping for frequency and time
00109   Mapping* m = MappingUtils::createMapping(0.0, dimensions, Mapping::LINEAR);
00110 
00111   //set position Argument
00112   Argument pos(dimensions, time);
00113   pos.setArgValue(Dimension("frequency"), freqFrom);
00114   //set mapping at position
00115   m->setValue(pos, value);
00116 
00117   pos.setTime(time + length);
00118   //set mapping at position
00119   m->setValue(pos, value);
00120 
00121   pos.setArgValue(Dimension("frequency"), freqTo);
00122   //set mapping at position
00123   m->setValue(pos, value);
00124 
00125   pos.setTime(time);
00126   //set mapping at position
00127   m->setValue(pos, value);
00128 
00129 
00130 
00131   return m;
00132 }
00133 
00134 MacPkt* SimpleMacLayer::createMacPkt(simtime_t length) {
00135   //create signal with start at current simtime and passed length
00136   Signal* s = new Signal(simTime(), length);
00137 
00138   //create and set tx power mapping
00139   Mapping* txPower = createMapping(simTime(), length, 2.412e9, 2.472e9, 50.0);
00140   s->setTransmissionPower(txPower);
00141 
00142   //create and set bitrate mapping
00143   Mapping* bitrate = createMapping(simTime(), length, 2.412e9, 2.472e9, 54.0);
00144   s->setBitrate(bitrate);
00145 
00146   //create and initialize control info
00147   MacToPhyControlInfo* ctrl = new MacToPhyControlInfo(s);
00148   MacPkt* res = new MacPkt();
00149   res->setControlInfo(ctrl);
00150   res->setKind(TEST_MACPKT);
00151   res->setDestAddr(nextReceiver);
00152   return res;
00153 }