User Manual, Developers Guide and API Documentation

Wire.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002  * This file is part of openWNS (open Wireless Network Simulator)
00003  * _____________________________________________________________________________
00004  *
00005  * Copyright (C) 2004-2009
00006  * Chair of Communication Networks (ComNets)
00007  * Kopernikusstr. 5, D-52074 Aachen, Germany
00008  * phone: ++49-241-80-27910,
00009  * fax: ++49-241-80-22242
00010  * email: info@openwns.org
00011  * www: http://www.openwns.org
00012  * _____________________________________________________________________________
00013  *
00014  * openWNS is free software; you can redistribute it and/or modify it under the
00015  * terms of the GNU Lesser General Public License version 2 as published by the
00016  * Free Software Foundation;
00017  *
00018  * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY
00019  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
00020  * A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00021  * details.
00022  *
00023  * You should have received a copy of the GNU Lesser General Public License
00024  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00025  *
00026  ******************************************************************************/
00027 
00028 #include <COPPER/Wire.hpp>
00029 #include <COPPER/Transceiver.hpp>
00030 #include <COPPER/Receiver.hpp>
00031 #include <COPPER/Transmission.hpp>
00032 #include <COPPER/Transmitter.hpp>
00033 
00034 #include <WNS/service/phy/copper/Handler.hpp>
00035 #include <WNS/service/dll/Address.hpp>
00036 
00037 #include <WNS/Exception.hpp>
00038 #include <WNS/rng/RNGen.hpp>
00039 
00040 using namespace copper;
00041 
00042 Wire::Wire(const wns::pyconfig::View& config) :
00043     name(config.get<std::string>("name")),
00044     roundRobin(),
00045     receivers(),
00046     transmissionEndEvents(),
00047     transmissions(),
00048     addressMapping(),
00049     logger(config.get<wns::pyconfig::View>("logger"))
00050 {
00051     MESSAGE_BEGIN(NORMAL, logger, m, "Created wire: ");
00052     m << this->name;
00053     MESSAGE_END();
00054 }
00055 
00056 void
00057 Wire::sendData(const UnicastTransmissionPtr& ut, simTimeType duration)
00058 {
00059     assure(
00060         this->addressMapping.find(ut->target) != this->addressMapping.end(),
00061         "Target receiver not at this wire");
00062 
00063     simTimeType arrivalTime = sendDataGeneric(ut, duration);
00064 
00065     MESSAGE_SINGLE(
00066                NORMAL, this->logger,
00067                "Sending to MAC address: " << ut->target
00068                << ". Arrival time: " << arrivalTime);
00069 
00070 }
00071 
00072 void
00073 Wire::sendData(const BroadcastTransmissionPtr& bt, simTimeType duration)
00074 {
00075     simTimeType arrivalTime = sendDataGeneric(bt, duration);
00076 
00077     MESSAGE_SINGLE(
00078         NORMAL, this->logger,
00079         "Sending to: BROADCAST. Arrival time: " << arrivalTime);
00080 }
00081 
00082 simTimeType
00083 Wire::blockedSince() const
00084 {
00085     if (this->isFree())
00086     {
00087         // return a number < 0 (doesn't matter)
00088         return -1.0;
00089     }
00090     else
00091     {
00092         // the wire is blocked, return the time for which the wire
00093         // has been blocked
00094         return wns::simulator::getEventScheduler()->getTime() - this->timeWireBlocked;
00095     }
00096 }
00097 
00098 
00099 bool
00100 Wire::isFree() const
00101 {
00102     return this->transmissions.empty();
00103 }
00104 
00105 void
00106 Wire::addReceiver(
00107     ReceiverInterface* r,
00108     const wns::service::dll::UnicastAddress& macAddress)
00109 {
00110     assure(r, "wo must be non-NULL");
00111     MESSAGE_SINGLE(
00112         NORMAL, this->logger,
00113         "adding receiver with MAC address" << macAddress);
00114 
00115     this->roundRobin.add(r);
00116     this->receivers.push_back(r);
00117     if (this->addressMapping.find(macAddress) != this->addressMapping.end())
00118     {
00119         wns::Exception e;
00120         e << "Receiver with this MAC address ("
00121           << macAddress
00122           <<") is already registered";
00123         throw e;
00124     }
00125     else
00126     {
00127         this->addressMapping[macAddress] = r;
00128     }
00129 }
00130 
00131 void
00132 Wire::stopTransmission(const wns::osi::PDUPtr& pdu)
00133 {
00134     assure(
00135         this->transmissions.find(pdu) != this->transmissions.end(),
00136         "Transmission not active");
00137 
00138     TransmissionEndEventContainer::iterator itr =
00139         this->transmissionEndEvents.find(pdu);
00140 
00141     // delete event from EventScheduler
00142     wns::simulator::getEventScheduler()->cancelEvent(itr->second);
00143     // manually execute the event to stop transmission
00144     this->transmissionEndEvents.erase(itr);
00145 
00146     this->transmissions.erase(pdu);
00147 
00148     if (this->isFree())
00149     {
00150         this->signalCopperFreeAgainToReceivers();
00151     }
00152 
00153 }
00154 
00155 void
00156 Wire::removeTransmissionEndEvent(const TransmissionPtr& transmission)
00157 {
00158     assure(
00159         this->transmissions.find(transmission->pdu) != this->transmissions.end(),
00160         "No such transmission active");
00161 
00162     this->transmissionEndEvents.erase(transmission->pdu);
00163     this->transmissions.erase(transmission->pdu);
00164 }
00165 
00166 void
00167 Wire::stopTransmission(const UnicastTransmissionPtr& ut)
00168 {
00169     assure(ut, "must be non-NULL");
00170 
00171     Address2ReceiverContainer::iterator itr =
00172         this->addressMapping.find(ut->target);
00173 
00174     assure(itr != this->addressMapping.end(), "Target receiver not at this wire");
00175 
00176     this->removeTransmissionEndEvent(ut);
00177 
00178     // inform sender, that the data has been sent
00179     ut->sender->onDataSent(ut->pdu);
00180 
00181     // inform the receiver, that there is data available
00182     itr->second->onData(ut);
00183 
00184     MESSAGE_SINGLE(NORMAL, this->logger, "UnicastTransmission finished");
00185 
00186     if (this->isFree())
00187     {
00188         this->signalCopperFreeAgainToReceivers();
00189     }
00190 }
00191 
00192 void
00193 Wire::stopTransmission(const BroadcastTransmissionPtr& bt)
00194 {
00195     assure(bt, "must be non-NULL");
00196 
00197     this->removeTransmissionEndEvent(bt);
00198 
00199     // inform sender, that the data has been sent
00200     bt->sender->onDataSent(bt->pdu);
00201 
00202     // inform the receivers, that there is data available
00203     for (
00204         std::list<ReceiverInterface*>::iterator itr = this->receivers.begin();
00205         itr != this->receivers.end();
00206         ++itr)
00207     {
00208         (*itr)->onData(bt);
00209     }
00210 
00211     MESSAGE_SINGLE(NORMAL, this->logger, "BroadcastTransmission finished");
00212 
00213     if(this->isFree())
00214     {
00215         this->signalCopperFreeAgainToReceivers();
00216     }
00217 }
00218 
00219 void
00220 Wire::checkForCollision(const TransmissionPtr& t)
00221 {
00222     if(!this->isFree())
00223     {
00224         for(
00225             Transmissions::iterator itr = this->transmissions.begin();
00226             itr != this->transmissions.end();
00227             ++itr)
00228         {
00229             itr->second->collision = true;
00230         }
00231         t->collision = true;
00232         MESSAGE_SINGLE(NORMAL, logger, "Collision occured!!");
00233 
00234         for(
00235             std::list<ReceiverInterface*>::iterator itr = this->receivers.begin();
00236             itr != this->receivers.end();
00237             ++itr)
00238         {
00239             (*itr)->onCollision();
00240         }
00241     }
00242 
00243 }
00244 
00245 
00246 void
00247 Wire::signalCopperFreeAgainToReceivers()
00248 {
00249     MESSAGE_SINGLE(NORMAL, this->logger, "Wire is free again");
00250 
00251     this->roundRobin.startRound();
00252     MESSAGE_SINGLE(NORMAL, this->logger, "Starting round robin wakeup");
00253 
00254     while(this->roundRobin.hasNext() && this->isFree())
00255     {
00256         this->roundRobin.next()->onCopperFree();
00257     }
00258 
00259     this->roundRobin.endRound();
00260     MESSAGE_SINGLE(NORMAL, this->logger, "Round robin stopped");
00261 }
00262 
00263 

Generated on Sat May 26 03:32:16 2012 for openWNS by  doxygen 1.5.5