![]() |
User Manual, Developers Guide and API Documentation |
![]() |
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
1.5.5