• Tidak ada hasil yang ditemukan

BAB V. KESIMPULAN DAN SARAN

B. SARAN

Penelitian ini berfokus pada penerapan mekanisme Priority Based Channel Access. Mekanisme ini digunakan karena peningkatan performansi lebih tinggi jika dibandingkan dengan skema standar CSMA/CA

48

pada skenario lalu lintas kota Makassar pada Mac Layer dan untuk penyebaran paket masih menggunakan protokol AODV. Sehingga pada penelitian selanjutnya, disarankan untuk menggunakan protokol lain dalam hal penyebaran paket untuk membandingkan beberapa routing protokol

49

DAFTAR PUSTAKA

Akanksha Saini, H. K. (2010) ‘Effect Of Black Hole Attack On AODV Routing Protocol In MANET’, INTERNATIONAL JOURNAL OF COMPUTER SCIENCE AND TECHNOLOGY, 4333(March), pp. 57–60.

Ali, T. E. and Khalil, L. A. (2016) ‘Review and Performance Comparison of VANET Protocols: AODV, DSR, OLSR, DYMO, DSDV & ZRP’.

Benkirane, S. et al. (2016) ‘A new comparative study of ad hoc routing protocol AODV and DSR in VANET environment using simulation tools’, in International Conference on Intelligent Systems Design and Applications, ISDA, pp. 458–461. doi: 10.1109/ISDA.2015.7489158.

Bi, Y. et al. (2016) ‘A multi-hop broadcast protocol for emergency message dissemination in urban vehicular ad hoc networks’, IEEE Transactions on Intelligent Transportation Systems, 17(3), pp. 736–750. doi: 10.1109/TITS.2015.2481486.

Bitam, S. and Mellouk, A. (2014) Bio-inspired Routing Protocols for Vehicular Ad-Hoc Networks. John Wiley & Sons.

Dawood, H. S. and Wang, Y. (2013) ‘An efficient emergency message broadcasting scheme in vehicular Ad hoc networks’, International Journal of Distributed Sensor Networks, 2013. doi: 10.1155/2013/232916.

Giang, A. T. and Busson, A. (2012) ‘Modeling CSMA/CA in VANET’, Lecture Notes in Computer Science (including subseries Lecture Notes in Artificial Intelligence and Lecture Notes in Bioinformatics), 7314 LNCS, pp. 91–105. doi: 10.1007/978-3-642-30782-9_7.

IEEE Std 802.11e-2005 (Amendment to IEEE Std 802.11, 1999 Edition (Reaff 2003) (2005) IEEE Standard for Information technology--Local and metropolitan area networks--Specific requirements--Part 11: Wireless LAN Medium Access Control (MAC) and Physical Layer (PHY) Specifications - Amendment 8: Medium Access Control (MAC) Quality of Service, IEEE Std 802.11e-2005 (Amendment to IEEE Std 802.11, 1999 Edition (Reaff 2003). doi: 10.1109/IEEESTD.2005.97890.

Javed, M. A., Ngo, D. T. and Khan, J. Y. (2014) ‘A multi-hop broadcast protocol design for emergency warning notification in highway VANETs’, EURASIP Journal on Wireless …, pp. 1–15. doi: 10.1186/1687-1499-2014-179.

Kaisar, A. (2016) ‘ANALISIS KINERJA LALU LINTAS JALAN PADA JARINGAN JALAN ARTERI DI KOTA MAKASSAR BERBASIS SIG’. Khisty, C. J. (2006) Dasar-Dasar Rekayasa Transportasi.

50

Krajzewicz, D. et al. (2002) ‘SUMO (Simulation of Urban MObility); An open-source traffic simulation’, in ResearchGate, pp. 183–187.

Krajzewicz, D. et al. (2012) ‘Recent Development and Applications of SUMO - Simulation of Urban MObility Recent Development and Applications of SUMO – Simulation of Urban MObility’, (April 2015).

Kumar, V., Mishra, S. and Chand, N. (2013) ‘Applications of VANETs : Present & Future’, 2013(February), pp. 12–15. doi: 10.4236/cn.2013.51B004.

Lin, Y.-W., Chen, Y.-S. and Lee, S.-L. (2010) ‘Routing Protocols in Vehicular Ad Hoc Networks: A Survey and Future Perspectives’, ResearchGate, 26(3), pp. 913–932.

Lorincz, J., Ukić, N. and Begušić, D. (2007) ‘Throughput comparison of AODV-UU and DSR-UU protocol implementations in multi-hop static environments’, in Proceedings of the 9th International Conference on Telecommunications, ConTEL 2007, pp. 195–201. doi: 10.1109/CONTEL.2007.381872.

Man, L. A. N. and Society, C. (2007) IEEE Standard for Information technology — Telecommunications and information exchange between systems — Local and metropolitan area networks — Specific requirements. Rehman, S. et al. (2013) ‘Vehicular Ad-Hoc Networks ( VANETs ): An Overview and Challenges Vehicular Ad-Hoc Networks ( VANETs ) - An Overview and Challenges’, (March 2016). doi: 10.5923/j.jwnc.20130303.02. Sallam, G. and Mahmoud, A. (2015) ‘Performance Evaluation of OLSR and AODV in VANET Cloud Computing Using Fading Model With SUMO and NS3’, pp. 1–5.

Sanguesa, J. A. et al. (2016) ‘A Survey and Comparative Study of Broadcast Warning Message Dissemination Schemes for VANETs’, 2016.

Shah, A. F. M. S. and Mustari, N. (2017) ‘Modeling and performance analysis of the IEEE 802.11P Enhanced Distributed Channel Access function for vehicular network’, FTC 2016 - Proceedings of Future Technologies Conference, (December), pp. 173–178. doi: 10.1109/FTC.2016.7821607.

Stanica, R., Chaput, E. and Beylot, A. L. (2012) ‘Properties of the MAC layer in safety vehicular Ad Hoc networks’, IEEE Communications Magazine, 50(5), pp. 192–200. doi: 10.1109/MCOM.2012.6194402.

Suthaputchakun, C., Sun, Z. and Dianati, M. (2013) ‘Trinary Partition Black-Burst based Broadcast Protocol for Emergency Message Dissemination in’, pp. 2244–2249.

Tentang OpenStreetMap (OSM) | OpenStreetMap Indonesia (no date). Tomar, P., Chaurasia, B. K. and Tomar, G. S. (2010) ‘State of the Art of Data Dissemination in VANETs’, 2(6), pp. 957–962.

TraCI - Sumo (no date). Available at: http://sumo.dlr.de/wiki/TraCI (Accessed: 29 June 2017).

Transportation, I. and Committee, S. (2016) ‘Draft Guide for Wireless Access in Vehicular Environments ( WAVE ) Architecture’, (July).

Tripti, C., G, J. K. M. and Manoj, R. (2015) ‘Priority based Control Channel Access Scheme for Throughput Improvement in VANET’, (September), pp. 139–142.

Upadhyay, A. (2016) ‘Cluster Head Selection for CCB-MAC Protocol by Implementing High Priority Algorithm in VANET’, pp. 107–112.

Zhu, W. et al. (2016) ‘A collision avoidance mechanism for emergency message broadcast in urban VANET’, IEEE Vehicular Technology Conference, 2016–July, pp. 1–5. doi: 10.1109/VTCSpring.2016.7504057. Zhu, W. et al. (2016) ‘A Collision Avoidance Mechanism for Emergency Message Broadcast in Urban VANET’, in 2016 IEEE 83rd Vehicular Technology Conference (VTC Spring), pp. 1–5. doi: 10.1109/VTCSpring.2016.7504057.

LAMPIRAN Listing Program .INI FILE [General] cmdenv-express-mode = true cmdenv-autoflush = true cmdenv-status-frequency = 10000000s #tkenv-default-config = debug #tkenv-default-run = 1 tkenv-image-path = bitmaps ned-path = . network = Aodvuu num-rngs = 1 ########################################################## # Simulation parameters # ########################################################## debug-on-errors = true print-undisposed = false sim-time-limit = 60s **.wlan[*].bitrate= 1Mbps #output-scalar-file = ${resultdir}/${configname}/${repetition}.sca #output-vector-file = ${resultdir}/${configname}/${repetition}.vec **.scalar-recording = true **.vector-recording = true **.debug = false **.coreDebug = false *.playgroundSizeX = 1000m *.playgroundSizeY = 1000m *.playgroundSizeZ = 1000m ########################################################## # Annotation parameters # ########################################################## *.annotations.draw = false ########################################################## # Obstacle parameters # ########################################################## *.obstacles.debug = false ########################################################## # WorldUtility parameters # ########################################################## *.world.useTorus = false *.world.use2D = false ########################################################## # TraCIScenarioManager parameters # ########################################################## *.manager.updateInterval = 0.1s *.manager.host = "localhost" *.manager.port = 9999 *.manager.moduleType = "org.car2x.veins.nodes.Car" *.manager.moduleName = "node" *.manager.moduleDisplayString = "i=device/t1;is=vs" *.manager.autoShutdown = true *.manager.margin = 25

*.manager.launchConfig = xmldoc("makassar100/makassar.launchd.xml") ########################################################## # rsu SETTINGS # ########################################################## *.rsu[*].mobilityType = "LinearMobility" *.rsu[*].mobility.speed = 0mps *.rsu[0].mobility.x = 1000 *.rsu[0].mobility.y = 2000 *.rsu[0].mobility.z = 3 *.rsu1[*].mobilityType = "LinearMobility" *.rsu1[*].mobility.speed = 0mps *.rsu1[0].mobility.x = 4500 *.rsu1[0].mobility.y = 3000 *.rsu1[0].mobility.z = 3 *.rsu2[0].mobility.x = 4500 *.rsu2[0].mobility.y = 3000 *.rsu2[0].mobility.z = 3 #*.rsu[*].appType = "TraCIDemoRSU11p" #*.rsu[*].app.headerLength = 256 bit #*.rsu[*].app.sendBeacons = false #*.rsu[*].app.dataOnSch = false #*.rsu[*].app.sendData = false #*.rsu[*].app.beaconInterval = 1s #*.rsu[*].app.dataPriority = 2 #*.rsu[*].app.maxOffset = 0.005s ########################################################## # 11p specific parameters # # NIC-Settings # ########################################################## *.connectionManager.p_Max = 2mW *.connectionManager.sat = -85dBm *.connectionManager.carrier_Frequency = 2.4e9 Hz *.connectionManager.sendDirect = true *.**.nic.phy80211p.sensitivity = -85dBm *.**.nic.phy80211p.max_TXPower = 10mW *.**.nic.phy80211p.useThermalNoise = true *.**.nic.phy80211p.thermalNoise = -110dBm *.**.nic.phy80211p.decider = xmldoc("makassar100/config.xml") *.**.nic.phy80211p.analogueModels = xmldoc("makassar100/config.xml") *.**.nic.phy80211p.usePropagationDelay = true

**.mac.queueSize = ${queue = 2MiB}

**.mac.maxBytesPerTti = ${maxBytesPerTti = 3MiB} **.mac.macDelay.result-recording-modes = all **.mac.macThroughput.result-recording-modes = all # Schedulers

**.mac.schedulingDisciplineDl = ${scheduler = "MAXCI"} #MAXCI, DRR, PF **.mac.schedulingDisciplineUl = ${scheduler} ########################################################## # WaveAppLayer # ########################################################## *.node[*].applType = "TraCIDemo11p" *.node[*].appl.debug = false *.node[*].appl.headerLength = 256 bit

*.node[*].appl.sendBeacons = true *.node[*].appl.dataOnSch = true *.node[*].appl.sendData = true *.node[*].appl.data_time_interval = 1s *.node[*].appl.beaconPriority = 3 *.node[*].appl.dataPriority = 2 *.node[*].appl.maxOffset = 0.005s ########################################################## # Mobility # ########################################################## *.node[*].veinsmobilityType = "org.car2x.veins.modules.mobility.traci.TraCIMobility" *.node[*].mobilityType = "TraCIMobility" *.node[*].mobilityType.debug = true *.node[*].veinsmobilityType.debug = true *.node[*].veinsmobility.x = 0 *.node[*].veinsmobility.y = 0 *.node[*].veinsmobility.z = 1.895 *.node[*].speed=13 *.node[*0].veinsmobility.accidentCount = 1 *.node[*0].veinsmobility.accidentStart = 5s *.node[*0].veinsmobility.accidentDuration = 30s # UEs **.enableHandover = True # RUs **.deployer.numRus = 0 **.deployer.ruRange = 50 **.deployer.ruTxPower = "50,50,50;" **.deployer.ruStartingAngle = 0deg

**.deployer.antennaCws = "2;" # !!MACRO + RUS (numRus + 1) # AMC **.deployer.numRbDl = ${RB = 100} **.deployer.numRbUl = ${RB} **.deployer.rbyDl = 12 **.deployer.rbyUl = 12 **.deployer.rbxDl = 7 **.deployer.rbxUl = 7 **.deployer.rbPilotDl = 3 **.deployer.rbPilotUl = 0 **.deployer.signalDl = 1 **.deployer.signalUl = 1 **.deployer.numBands = 1 **.deployer.numPreferredBands = 1

############### AMC MODULE PARAMETERS ############### **.rbAllocationType = "localized" **.mac.amcMode = "AUTO" **.feedbackType = "ALLBANDS" **.feedbackGeneratorType = "IDEAL" **.maxHarqRtx = 3 **.pfAlpha = 0.95 **.pfTmsAwareDL = false **.numUe = ${numUEs=1000} ###################################################################### # routing Protocol ###################################################################### **.routingProtocol = "AODVUU" #**.manetrouting.manetmanager.routingProtocol = "AODVUU"

#**.routingProtocol = "vanetsim.inet.networklayer.manetrouting.AODVUU" **.manetrouting.manetmanager.routingProtocol = "AODVUU" **.manetrouting.interfaces = "prefix(wlan)" **.active_timeout = 3s **.hello_jittering = false **.optimized_hellos = false **.expanding_ring_search = false **.local_repair = true **.rreq_gratuitous = false **.rt_log_interval = 0 **.unidir_hack = 0 **.internet_gw_mode = 0 **.receive_n_hellos = 1 **.ratelimit = 1000 **.llfeedback = false# //1000 **.wait_on_reboot = 0 **.active_timeout = 1000ms # // time in ms **.internet_gw_address = "0.0.0.0" [Config AODVUU100] description = "AODVUU" *.connectionManager.alpha = 1.5 *.node[*].appl.sendBeacons = true *.node[*].appl.dataOnSch = true *.node[*].appl.sendData = true **.debug = false **.coreDebug = true *.annotations.draw = false *.node[*].appl.st=3 *.obstacles.stag =0 NED FILE import inet.networklayer.routing.aodv.AODVRouting; import inet.nodes.aodv.AODVRouter; import org.car2x.veins._nodes.RSU; import org.car2x.veins.nodes.Scenario; import inet.networklayer.autorouting.ipv4.IPv4NetworkConfigurator; import inet.networklayer.ipv4.RoutingTableRecorder; import inet.nodes.ethernet.Eth1G; import inet.nodes.inet.Router; import inet.nodes.inet.StandardHost; import lte.stack.phy.ChannelControl.LteChannelControl; import lte.corenetwork.binder.LteBinder; import lte.corenetwork.nodes.Ue; import lte.corenetwork.nodes.eNodeB; import lte.corenetwork.nodes.ExtCell; import lte.epc.PgwStandardSimplified; network Aodvuu extends Scenario {

submodules:

channelControl: LteChannelControl { @display("p=50,25;is=s");

} routingRecorder: RoutingTableRecorder { @display("p=50,75;is=s"); } configurator: IPv4NetworkConfigurator { @display("p=50,125"); config = xmldoc("demo.xml"); } binder: LteBinder { @display("p=50,175;is=s"); } server: StandardHost { @display("p=212,118;is=n;i=device/car"); } router: Router { @display("p=321,136;i=device/smallrouter"); } rsu[1]: RSU { @display("p=16,50;i=device/antennatower;is=vl"); } rsu1[1]: RSU { @display("p=176,174;i=device/antennatower;is=vl"); } connections:

server.pppg++ <--> Eth1G <--> router.pppg++; }

IEEE 80211p

#include "Mac1609_4.h" #include <iterator> #define DBG_MAC EV

//#define DBG_MAC std::cerr << "[" << simTime().raw() << "] " << myId << " " Define_Module(Mac1609_4);

void Mac1609_4::initialize(int stage) { BaseMacLayer::initialize(stage); if (stage == 0) {

phy11p = FindModule<Mac80211pToPhy11pInterface*>::findSubModule( getParentModule());

assert(phy11p);

//this is required to circumvent double precision issues with constants from CONST80211p.h

assert(simTime().getScaleExp() == -12); txPower = par("txPower").doubleValue();

bitrate = par("bitrate"); n_dbps = 0; setParametersForBitrate(bitrate); //mac-adresses myMacAddress = intuniform(0,0xFFFFFFFE); myId = getParentModule()->getParentModule()->getFullPath(); //create frequency mappings

frequency.insert(std::pair<int, double>(Channels::CRIT_SOL, 5.86e9)); frequency.insert(std::pair<int, double>(Channels::SCH1, 5.87e9)); frequency.insert(std::pair<int, double>(Channels::SCH2, 5.88e9)); frequency.insert(std::pair<int, double>(Channels::CCH, 5.89e9)); frequency.insert(std::pair<int, double>(Channels::SCH3, 5.90e9)); frequency.insert(std::pair<int, double>(Channels::SCH4, 5.91e9)); frequency.insert(std::pair<int, double>(Channels::HPPS, 5.92e9)); //create two edca systems

myEDCA[type_CCH] = new EDCA(type_CCH,par("queueSize").longValue()); myEDCA[type_CCH]->myId = myId; myEDCA[type_CCH]->myId.append(" CCH"); myEDCA[type_CCH]->createQueue(2,(((CWMIN_11P+1)/4)-1),(((CWMIN_11P +1)/2)-1),AC_VO); myEDCA[type_CCH]->createQueue(3,(((CWMIN_11P+1)/2)-1),CWMIN_11P,AC_VI); myEDCA[type_CCH]->createQueue(6,CWMIN_11P,CWMAX_11P,AC_BE); myEDCA[type_CCH]->createQueue(9,CWMIN_11P,CWMAX_11P,AC_BK); myEDCA[type_SCH] = new EDCA(type_SCH,par("queueSize").longValue()); myEDCA[type_SCH]->myId = myId; myEDCA[type_SCH]->myId.append(" SCH"); myEDCA[type_SCH]->createQueue(2,(((CWMIN_11P+1)/4)-1),(((CWMIN_11P +1)/2)-1),AC_VO); myEDCA[type_SCH]->createQueue(3,(((CWMIN_11P+1)/2)-1),CWMIN_11P,AC_VI); myEDCA[type_SCH]->createQueue(6,CWMIN_11P,CWMAX_11P,AC_BE); myEDCA[type_SCH]->createQueue(9,CWMIN_11P,CWMAX_11P,AC_BK); if (useSCH) {

//set the initial service channel

switch (par("serviceChannel").longValue()) { case 1: mySCH = Channels::SCH1; break; case 2: mySCH = Channels::SCH2; break; case 3: mySCH = Channels::SCH3; break; case 4: mySCH = Channels::SCH4; break;

default: opp_error("Service Channel must be between 1 and 4"); break; }

}

headerLength = par("headerLength");

nextMacEvent = new cMessage("next Mac Event"); if (useSCH) {

// introduce a little asynchronization between radios, but no more than .3 milliseconds

uint64_t currenTime = simTime().raw();

uint64_t switchingTime = SWITCHING_INTERVAL_11P.raw(); double timeToNextSwitch = (double)(switchingTime

- (currenTime % switchingTime)) / simTime().getScale(); if ((currenTime / switchingTime) % 2 == 0) { setActiveChannel(type_CCH); } else { setActiveChannel(type_SCH); }

// channel switching active

nextChannelSwitch = new cMessage("Channel Switch"); simtime_t offset = dblrand() * par("syncOffset").doubleValue();

scheduleAt(simTime() + offset + timeToNextSwitch, nextChannelSwitch); } else { // no channel switching nextChannelSwitch = 0; setActiveChannel(type_CCH); } //stats statsReceivedPackets = 0; statsReceivedBroadcasts = 0; packetDelete = 0; statsSentPackets = 0; statsTXRXLostPackets = 0; statsSNIRLostPackets = 0; statsDroppedPackets = 0; statsNumTooLittleTime = 0; statsNumInternalContention = 0; statsNumBackoff = 0; statsSlotsBackoff = 0; statsTotalBusyTime = 0; idleChannel = true; lastBusy = simTime(); channelIdle(true); } } void Mac1609_4::handleSelfMsg(cMessage* msg) { if (msg == nextChannelSwitch) { ASSERT(useSCH);

scheduleAt(simTime() + SWITCHING_INTERVAL_11P, nextChannelSwitch); switch (activeChannel) { case type_CCH: DBG_MAC << "CCH --> SCH" << std::endl; channelBusySelf(false); setActiveChannel(type_SCH); channelIdle(true); phy11p->changeListeningFrequency(frequency[mySCH]);

break; case type_SCH: DBG_MAC << "SCH --> CCH" << std::endl; channelBusySelf(false); setActiveChannel(type_CCH); channelIdle(true); phy11p->changeListeningFrequency(frequency[Channels::CCH]); break; }

//schedule next channel switch in 50ms }

else if (msg == nextMacEvent) {

//we actually came to the point where we can send a packet channelBusySelf(true);

WaveShortMessage* pktToSend = myEDCA[activeChannel]->initiateTransmit(lastIdle);

lastAC = mapPriority(pktToSend->getPriority());

DBG_MAC << "MacEvent received. Trying to send packet with priority" << lastAC << std::endl;

//send the packet

Mac80211Pkt* mac = new Mac80211Pkt(>getName(), pktToSend->getKind());

mac->setDestAddr(LAddress::L2BROADCAST); mac->setSrcAddr(myMacAddress);

mac->encapsulate(pktToSend->dup());

simtime_t sendingDuration = RADIODELAY_11P + getFrameDuration(mac->getBitLength());

DBG_MAC << "Sending duration will be" << sendingDuration << std::endl; if ((!useSCH) || (timeLeftInSlot() > sendingDuration)) {

if (useSCH) DBG_MAC << " Time in this slot left: " << timeLeftInSlot() << std::endl;

// give time for the radio to be in Tx state before transmitting phy->setRadioState(Radio::TX);

double freq = (activeChannel == type_CCH) ? frequency[Channels::CCH] : frequency[mySCH];

attachSignal(mac, simTime()+RADIODELAY_11P, freq);

MacToPhyControlInfo* phyInfo = dynamic_cast<MacToPhyControlInfo*>(mac->getControlInfo());

assert(phyInfo);

DBG_MAC << "Sending a Packet. Frequency " << freq << " Priority" << lastAC << std::endl;

sendDelayed(mac, RADIODELAY_11P, lowerLayerOut); statsSentPackets++;

}

else { //not enough time left now

DBG_MAC << "Too little Time left. This packet cannot be send in this slot." << std::endl;

//revoke TXOP

myEDCA[activeChannel]->revokeTxOPs(); statsNumTooLittleTime++;

delete mac; channelIdle();

//do nothing. contention will automatically start after channel switch } } } void Mac1609_4::handleUpperControl(cMessage* msg) { assert(false); } void Mac1609_4::handleUpperMsg(cMessage* msg) { WaveShortMessage* thisMsg;

if ((thisMsg = dynamic_cast<WaveShortMessage*>(msg)) == NULL) { error("WaveMac only accepts WaveShortMessages");

}

t_access_category ac = mapPriority(thisMsg->getPriority());

DBG_MAC << "Received a message from upper layer for channel " << thisMsg->getChannelNumber() << " Access Category (Priority): " << ac << std::endl;

t_channel chan;

//rewrite SCH channel to actual SCH the Mac1609_4 is set to if (thisMsg->getChannelNumber() == Channels::SCH1) { ASSERT(useSCH);

thisMsg->setChannelNumber(mySCH); chan = type_SCH;

}

//put this packet in its queue

if (thisMsg->getChannelNumber() == Channels::CCH) { chan = type_CCH;

}

int num = myEDCA[chan]->queuePacket(ac,thisMsg); //packet was dropped in Mac

if (num == -1) {

statsDroppedPackets++; return;

}

//if this packet is not at the front of a new queue we dont have to reevaluate times DBG_MAC << "sorted packet into queue of EDCA " << chan << " this packet is now at position: " << num << std::endl;

DBG_MAC << "this packet is for the currently active channel" << std::endl; }

else {

DBG_MAC << "this packet is NOT for the currently active channel" << std::endl; }

if (num == 1 && idleChannel == true && chan == activeChannel) {

simtime_t nextEvent = myEDCA[chan]->startContent(lastIdle,guardActive()); if (nextEvent != -1) {

if ((!useSCH) || (nextEvent <= nextChannelSwitch->getArrivalTime())) { if (nextMacEvent->isScheduled()) {

cancelEvent(nextMacEvent); }

scheduleAt(nextEvent,nextMacEvent);

DBG_MAC << "Updated nextMacEvent:" << nextMacEvent->getArrivalTime().raw() << std::endl;

} else {

DBG_MAC << "Too little time in this interval. Will not schedule nextMacEvent" << std::endl;

//it is possible that this queue has an txop. we have to revoke it myEDCA[activeChannel]->revokeTxOPs(); statsNumTooLittleTime++; } } else { cancelEvent(nextMacEvent); } }

if (num == 1 && idleChannel == false && myEDCA[chan]->myQueues[ac].currentBackoff == 0 && chan == activeChannel) { myEDCA[chan]->backoff(ac);

} }

void Mac1609_4::handleLowerControl(cMessage* msg) { if (msg->getKind() == MacToPhyInterface::TX_OVER) {

DBG_MAC << "Successfully transmitted a packet on " << lastAC << std::endl; phy->setRadioState(Radio::RX);

//message was sent

//update EDCA queue. go into post-transmit backoff and set cwCur to cwMin myEDCA[activeChannel]->postTransmit(lastAC);

//channel just turned idle.

//don't set the chan to idle. the PHY layer decides, not us. if (guardActive()) {

opp_error("We shouldnt have sent a packet in guard!"); }

}

channelBusy(); }

else if (msg->getKind() == Mac80211pToPhy11pInterface::CHANNEL_IDLE) { channelIdle();

}

else if (msg->getKind() == Decider80211p::BITERROR) { statsSNIRLostPackets++;

DBG_MAC << "A packet was not received due to biterrors" << std::endl; }

else if (msg->getKind() == Decider80211p::RECWHILESEND) { statsTXRXLostPackets++;

DBG_MAC << "A packet was not received because we were sending while receiving" << std::endl;

}

else if (msg->getKind() == MacToPhyInterface::RADIO_SWITCHING_OVER) { DBG_MAC << "Phylayer said radio switching is done" << std::endl;

}

else if (msg->getKind() == BaseDecider::PACKET_DROPPED) { phy->setRadioState(Radio::RX);

packetDelete++;

DBG_MAC << "Phylayer said packet was dropped" << std::endl; }

else {

DBG_MAC << "Invalid control message type (type=NOTHING) : name=" << msg->getName() << " modulesrc=" << msg->getSenderModule()->getFullPath() << "." << std::endl;

assert(false); }

delete msg; }

void Mac1609_4::setActiveChannel(t_channel state) { activeChannel = state;

assert(state == type_CCH || (useSCH && state == type_SCH)); }

void Mac1609_4::finish() { //clean up queues.

for (std::map<t_channel,EDCA*>::iterator iter = myEDCA.begin(); iter != myEDCA.end(); iter++) { statsNumInternalContention += iter->second->statsNumInternalContention; statsNumBackoff += iter->second->statsNumBackoff; statsSlotsBackoff += iter->second->statsSlotsBackoff; iter->second->cleanUp(); delete iter->second; } myEDCA.clear(); if (nextMacEvent->isScheduled()) { cancelAndDelete(nextMacEvent); } else { delete nextMacEvent; }

if (nextChannelSwitch && nextChannelSwitch->isScheduled()) cancelAndDelete(nextChannelSwitch);

}

void Mac1609_4::attachSignal(Mac80211Pkt* mac, simtime_t startTime, double frequency) {

simtime_t duration = getFrameDuration(mac->getBitLength());

Signal* s = createSignal(startTime, duration, txPower, bitrate, frequency); MacToPhyControlInfo* cinfo = new MacToPhyControlInfo(s);

mac->setControlInfo(cinfo); }

Signal* Mac1609_4::createSignal(simtime_t start, simtime_t length, double power, double bitrate, double frequency) {

simtime_t end = start + length;

//create signal with start at current simtime and passed length Signal* s = new Signal(start, length);

//create and set tx power mapping

ConstMapping* txPowerMapping = createSingleFrequencyMapping(start, end, frequency, 5.0e6, power);

s->setTransmissionPower(txPowerMapping);

Mapping* bitrateMapping = MappingUtils::createMapping(DimensionSet::timeDomain, Mapping::STEPS); Argument pos(start); bitrateMapping->setValue(pos, bitrate); pos.setTime(phyHeaderLength / bitrate); bitrateMapping->setValue(pos, bitrate); s->setBitrate(bitrateMapping); return s; }

/* checks if guard is active */

bool Mac1609_4::guardActive() const { if (!useSCH) return false;

if (simTime().dbl() - nextChannelSwitch->getSendingTime() <= GUARD_INTERVAL_11P)

return true; return false; }

/* returns the time until the guard is over */

simtime_t Mac1609_4::timeLeftTillGuardOver() const { ASSERT(useSCH);

simtime_t sTime = simTime();

if (sTime - nextChannelSwitch->getSendingTime() <= GUARD_INTERVAL_11P) { return GUARD_INTERVAL_11P

- (sTime - nextChannelSwitch->getSendingTime()); }

else return 0; }

/* returns the time left in this channel window */ simtime_t Mac1609_4::timeLeftInSlot() const { ASSERT(useSCH);

return nextChannelSwitch->getArrivalTime() - simTime(); }

/* Will change the Service Channel on which the mac layer is listening and sending */ void Mac1609_4::changeServiceChannel(int cN) {

ASSERT(useSCH);

if (cN != Channels::SCH1 && cN != Channels::SCH2 && cN != Channels::SCH3 && cN != Channels::SCH4) {

opp_error("This Service Channel doesnt exit: %d",cN); }

mySCH = cN;

if (activeChannel == type_SCH) {

//change to new chan immediately if we are in a SCH slot,

//otherwise it will switch to the new SCH upon next channel switch phy11p->changeListeningFrequency(frequency[mySCH]);

} }

void Mac1609_4::handleLowerMsg(cMessage* msg) {

Mac80211Pkt* macPkt = static_cast<Mac80211Pkt*>(msg); ASSERT(macPkt);

WaveShortMessage* wsm = dynamic_cast<WaveShortMessage*>(macPkt->decapsulate());

long dest = macPkt->getDestAddr();

DBG_MAC << "Received frame name= " << macPkt->getName() << ", myState=" << " src=" << macPkt->getSrcAddr() << " dst=" << macPkt->getDestAddr() << " myAddr=" << myMacAddress << std::endl;

//statsReceivedPackets++;

if (macPkt->getDestAddr() == myMacAddress) {

DBG_MAC << "Received a data packet addressed to me." << std::endl; statsReceivedPackets++;

sendUp(wsm); }

else if (dest == LAddress::L2BROADCAST) { statsReceivedBroadcasts++;

sendUp(wsm); }

else {

DBG_MAC << "Packet not for me, deleting..." << std::endl; delete wsm;

}

//packetDelete++; delete macPkt; }

int Mac1609_4::EDCA::queuePacket(t_access_category ac,WaveShortMessage* msg) { if (maxQueueSize && myQueues[ac].queue.size() >= maxQueueSize) {

delete msg; return -1; } myQueues[ac].queue.push(msg); return myQueues[ac].queue.size(); }

int Mac1609_4::EDCA::createQueue(int aifsn, int cwMin, int cwMax,t_access_category ac) {

if (myQueues.find(ac) != myQueues.end()) {

opp_error("You can only add one queue per Access Category per EDCA subsystem"); } EDCAQueue newQueue(aifsn,cwMin,cwMax,ac); myQueues[ac] = newQueue; return ++numQueues; }

Mac1609_4::t_access_category Mac1609_4::mapPriority(int prio) { //dummy mapping function

switch (prio) {

case 0: return AC_BK; case 1: return AC_BE; case 2: return AC_VI; case 3: return AC_VO;

default: opp_error("MacLayer received a packet with unknown priority"); break; }

return AC_VO; }

WaveShortMessage* Mac1609_4::EDCA::initiateTransmit(simtime_t lastIdle) { //iterate through the queues to return the packet we want to send

WaveShortMessage* pktToSend = NULL; simtime_t idleTime = simTime() - lastIdle;

DBG_MAC << "Initiating transmit at " << simTime() << ". I've been idle since " << idleTime << std::endl;

for (std::map<t_access_category, EDCAQueue>::iterator iter = myQueues.begin(); iter != myQueues.end(); iter++) {

if (iter->second.queue.size() != 0) {

if (idleTime >= >second.aifsn* SLOTLENGTH_11P + SIFS_11P && iter->second.txOP == true) {

DBG_MAC << "Queue " << iter->first << " is ready to send!" << std::endl; iter->second.txOP = false;

//this queue is ready to send if (pktToSend == NULL) {

pktToSend = iter->second.queue.front(); }

else {

//there was already another packet ready. we have to go increase cw and go into backoff. It's called internal contention and its wonderful

statsNumInternalContention++;

iter->second.cwCur = std::min(iter->second.cwMax,iter->second.cwCur*2); iter->second.currentBackoff = intuniform(0,iter->second.cwCur);

DBG_MAC << "Internal contention for queue " << >first << " : "<< iter->second.currentBackoff << ". Increase cwCur to " << iter->second.cwCur << std::endl; }

} } }

if (pktToSend == NULL) {

opp_error("No packet was ready"); }

return pktToSend; }

simtime_t Mac1609_4::EDCA::startContent(simtime_t idleSince,bool guardActive) { DBG_MAC << "Restarting contention." << std::endl;

simtime_t nextEvent = -1;

simtime_t idleTime = SimTime().setRaw(std::max((int64_t)0,(simTime() - idleSince).raw()));;

lastStart = idleSince;

DBG_MAC << "Channel is already idle for:" << idleTime << " since " << idleSince << std::endl;

//this returns the nearest possible event in this EDCA subsystem after a busy channel for (std::map<t_access_category, EDCAQueue>::iterator iter = myQueues.begin(); iter != myQueues.end(); iter++) {

if (iter->second.queue.size() != 0) {

/* 1609_4 says that when attempting to send (backoff == 0) when guard is active, a random backoff is invoked */

if (guardActive == true && iter->second.currentBackoff == 0) { //cw is not increased

iter->second.currentBackoff = intuniform(0,iter->second.cwCur); statsNumBackoff++;

simtime_t DIFS = iter->second.aifsn * SLOTLENGTH_11P + SIFS_11P; //the next possible time to send can be in the past if the channel was idle for a long time, meaning we COULD have sent earlier if we had a packet

simtime_t possibleNextEvent = DIFS + iter->second.currentBackoff * SLOTLENGTH_11P;

DBG_MAC << "Waiting Time for Queue " << iter->first << ":" <<

possibleNextEvent << "=" << iter->second.aifsn << " * " << SLOTLENGTH_11P << " + " << SIFS_11P << "+" << iter->second.currentBackoff << "*" << SLOTLENGTH_11P << "; Idle time: " << idleTime << std::endl;

if (idleTime > possibleNextEvent) {

DBG_MAC << "Could have already send if we had it earlier" << std::endl; //we could have already sent. round up to next boundary

simtime_t base = idleSince + DIFS;

possibleNextEvent = simTime() - simtime_t().setRaw((simTime() - base).raw() % SLOTLENGTH_11P.raw()) + SLOTLENGTH_11P;

} else {

//we are gonna send in the future

DBG_MAC << "Sending in the future" << std::endl; possibleNextEvent = idleSince + possibleNextEvent; }

nextEvent == -1? nextEvent = possibleNextEvent : nextEvent = std::min(nextEvent,possibleNextEvent);

Dokumen terkait