![]() |
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 * email: info@openwns.org 00009 * www: http://www.openwns.org 00010 * _____________________________________________________________________________ 00011 * 00012 * openWNS is free software; you can redistribute it and/or modify it under the 00013 * terms of the GNU Lesser General Public License version 2 as published by the 00014 * Free Software Foundation; 00015 * 00016 * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY 00017 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 00018 * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 00019 * details. 00020 * 00021 * You should have received a copy of the GNU Lesser General Public License 00022 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00023 * 00024 ******************************************************************************/ 00025 00026 00027 #include <WIMAC/Component.hpp> 00028 00029 #include <cstdlib> 00030 #include <sstream> 00031 00032 #include <boost/bind.hpp> 00033 00034 #include <WNS/rng/RNGen.hpp> 00035 #include <WNS/ldk/fcf/FrameBuilder.hpp> 00036 #include <WNS/ldk/buffer/Buffer.hpp> 00037 #include <WNS/ldk/fun/Main.hpp> 00038 #include <WNS/ldk/utils.hpp> 00039 #include <WNS/ldk/Group.hpp> 00040 #include <WNS/ldk/FlowSeparator.hpp> 00041 #include <WNS/service/phy/ofdma/Handler.hpp> 00042 #include <WNS/service/phy/ofdma/DataTransmission.hpp> 00043 #include <WNS/service/dll/StationTypes.hpp> 00044 00045 #include <WIMAC/ConnectionKey.hpp> 00046 #include <WIMAC/Logger.hpp> 00047 #include <WIMAC/PhyUser.hpp> 00048 #include <WIMAC/services/ConnectionManager.hpp> 00049 #include <WIMAC/StationManager.hpp> 00050 #include <WIMAC/UpperConvergence.hpp> 00051 #include <WIMAC/helper/ContextProvider.hpp> 00052 00053 00054 using namespace wimac; 00055 00056 STATIC_FACTORY_REGISTER_WITH_CREATOR(Component, 00057 wns::node::component::Interface, 00058 "wimac.Component", 00059 wns::node::component::ConfigCreator); 00060 00061 00062 Component::Component(wns::node::Interface* node, const wns::pyconfig::View& config) : 00063 wns::node::component::Component(node, config), 00064 stationType_(wns::service::dll::StationTypes::fromString(config.get<std::string>("stationType"))), 00065 id_(config.get<unsigned int>("stationID")), 00066 address_(config.get<wns::service::dll::UnicastAddress>("address")) 00067 { 00068 LOG_INFO( "Creating station ", node->getName(), " with station ID ", id_, 00069 " and station type ", wns::service::dll::StationTypes::toString(stationType_) ); 00070 00071 // build FUN 00072 fun_ = new wns::ldk::fun::Main(this); 00073 wns::ldk::configureFUN(fun_, config.get<wns::pyconfig::View>("fun")); 00074 00075 if(!getConfig().isNone("upperConvergenceName")) 00076 { 00077 std::string upperConvergenceName = getConfig().get<std::string>("upperConvergenceName"); 00078 UpperConvergence* upperConvergence = 00079 getFUN()->findFriend<UpperConvergence*>(upperConvergenceName); 00080 00081 // register UpperConvergence as the DLL DataTransmissionService 00082 addService(getConfig().get<std::string>("dataTransmission"), upperConvergence); 00083 addService(getConfig().get<std::string>("notification"), upperConvergence); 00084 addService(getConfig().get<std::string>("flowEstablishmentAndRelease"), upperConvergence); 00085 upperConvergence->setMACAddress(address_); 00086 } 00087 00088 // fire up control and management Services 00089 { // do control services 00090 for (int ii = 0; ii<config.len("controlServices"); ++ii){ 00091 wns::pyconfig::View controlServiceView = config.get("controlServices",ii); 00092 std::string serviceName = controlServiceView.get<std::string>("serviceName"); 00093 std::string creatorName = controlServiceView.get<std::string>("__plugin__"); 00094 wns::ldk::ControlServiceCreator* serviceCreator = wns::ldk::ControlServiceFactory::creator(creatorName); 00095 wns::ldk::ControlServiceInterface* service = serviceCreator->create(getCSR(), controlServiceView); 00096 addControlService(serviceName, service); 00097 LOG_INFO(" Registered Control Service: " , serviceName); 00098 } 00099 // do management services @todo pab: get rid of copy and paste patterns 00100 for (int ii = 0; ii<config.len("managementServices"); ++ii){ 00101 wns::pyconfig::View managementServiceView = config.get("managementServices",ii); 00102 std::string serviceName = managementServiceView.get<std::string>("serviceName"); 00103 std::string creatorName = managementServiceView.get<std::string>("__plugin__"); 00104 wns::ldk::ManagementServiceCreator* serviceCreator = wns::ldk::ManagementServiceFactory::creator(creatorName); 00105 wns::ldk::ManagementServiceInterface* service = serviceCreator->create(getMSR(), managementServiceView); 00106 addManagementService(serviceName, service); 00107 LOG_INFO(" Registered Management Service: ", serviceName); 00108 } 00109 } 00110 00111 getNode()->getContextProviderCollection(). 00112 addProvider(wns::probe::bus::contextprovider::Callback 00113 ("MAC.CellId", boost::bind(&wimac::Component::getCellID, this ) ) ); 00114 getNode()->getContextProviderCollection(). 00115 addProvider(wns::probe::bus::contextprovider::Callback 00116 ("MAC.Id", boost::bind(&wimac::Component::getID, this ) ) ); 00117 getNode()->getContextProviderCollection(). 00118 addProvider(wns::probe::bus::contextprovider::Callback 00119 ("MAC.Ring", boost::bind(&wimac::Component::getRing, this ) ) ); 00120 getNode()->getContextProviderCollection(). 00121 addProvider(wns::probe::bus::contextprovider::Callback 00122 ("MAC.StationType", boost::bind(&wimac::Component::getStationType, this ) ) ); 00123 getNode()->getContextProviderCollection().addProvider( 00124 wimac::helper::contextprovider::SourceAddress(fun_, 00125 config.get<std::string>("upperConvergenceName"))); 00126 getNode()->getContextProviderCollection().addProvider( 00127 wimac::helper::contextprovider::TargetAddress(fun_, 00128 config.get<std::string>("upperConvergenceName"))); 00129 getNode()->getContextProviderCollection().addProvider( 00130 wimac::helper::contextprovider::CallbackCommandContextProvider( 00131 fun_, 00132 config.get<std::string>("upperConvergenceName"), 00133 "MAC.CellId", 00134 &wimac::Component::getCellID)); 00135 getNode()->getContextProviderCollection().addProvider( 00136 wimac::helper::contextprovider::CallbackCommandContextProvider( 00137 fun_, 00138 config.get<std::string>("upperConvergenceName"), 00139 "MAC.Id", 00140 &wimac::Component::getID)); 00141 getNode()->getContextProviderCollection().addProvider( 00142 wimac::helper::contextprovider::CallbackCommandContextProvider( 00143 fun_, 00144 config.get<std::string>("upperConvergenceName"), 00145 "MAC.Ring", 00146 &wimac::Component::getRing)); 00147 getNode()->getContextProviderCollection().addProvider( 00148 wimac::helper::contextprovider::CallbackCommandContextProvider( 00149 fun_, 00150 config.get<std::string>("upperConvergenceName"), 00151 "MAC.StationType", 00152 &wimac::Component::getStationType)); 00153 00154 // global station registry 00155 TheStationManager::getInstance()->registerStation(id_, address_, this); 00156 00157 if(getStationType() == wns::service::dll::StationTypes::AP()) 00158 ring_ = config.get<unsigned int>("ring"); 00159 00160 } 00161 00162 void 00163 Component::doStartup() 00164 { 00165 } 00166 00167 unsigned int 00168 Component::getRing() const 00169 { 00170 if ( getStationType() == wns::service::dll::StationTypes::AP() ) 00171 { 00172 return ring_; 00173 } 00174 else 00175 { 00176 ConnectionIdentifier::Ptr ci; 00177 00178 ci = getManagementService<service::ConnectionManager> 00179 ("connectionManager")->getConnectionWithID(0); 00180 00181 if( ci ) 00182 { 00183 Component* associatedWith = dynamic_cast<wimac::Component*> 00184 ( TheStationManager::getInstance()->getStationByID(ci->baseStation_) ); 00185 assure(associatedWith, "Station is not associated with a WiMAC station"); 00186 00187 return associatedWith->getRing() + 1; 00188 } 00189 return 0; 00190 } 00191 } 00192 00193 unsigned int 00194 Component::getCellID() const 00195 { 00196 if ( getStationType() == wns::service::dll::StationTypes::AP() ) 00197 { 00198 return getID(); 00199 } else 00200 { 00201 ConnectionIdentifier::Ptr ci; 00202 00203 ci = getManagementService<service::ConnectionManager> 00204 ("connectionManager")->getConnectionWithID(0); 00205 00206 if( ci ) 00207 { 00208 Component* associatedWith = dynamic_cast<wimac::Component*> 00209 ( TheStationManager::getInstance()->getStationByID(ci->baseStation_) ); 00210 assure(associatedWith, "Station is not associated with a WiMAC station"); 00211 00212 return associatedWith->getCellID(); 00213 } 00214 return 0; 00215 } 00216 } 00217 00218 00219 void 00220 Component::onNodeCreated() 00221 { 00222 // get service names of the lower layer 00223 std::string transServiceName = getConfig().get<std::string>("phyDataTransmission"); 00224 std::string notifyServiceName = getConfig().get<std::string>("phyNotification"); 00225 00226 // set services in PhyUser to communicate with lower layer 00227 PhyUser* phyUser = getFUN()->findFriend<PhyUser*>("phyUser"); 00228 phyUser->setMACAddress( getMACAddress() ); 00229 00230 phyUser->setDataTransmissionService( 00231 getService<wns::service::phy::ofdma::DataTransmission*>( transServiceName ) ); 00232 phyUser->setNotificationService( 00233 getService<wns::service::phy::ofdma::Notification*>( notifyServiceName ) ); 00234 00235 getFUN()->onFUNCreated(); 00236 getMSR()->onMSRCreated(); 00237 getCSR()->onCSRCreated(); 00238 00239 // Start the Framebuilder and set it to pause state for synchronizing the 00240 // periodically event of all stations. 00241 wns::ldk::fcf::FrameBuilder* frameBuilder = 00242 getFUN()->findFriend<wns::ldk::fcf::FrameBuilder*>("frameBuilder"); 00243 frameBuilder->start(); 00244 } 00245 00246 void 00247 Component::onWorldCreated() 00248 { 00249 } 00250 00251 void 00252 Component::onShutdown() 00253 { 00254 } 00255 00256 int 00257 Component::getNumberOfQueuedPDUs(ConnectionIdentifiers cis) 00258 { 00259 int queuedPDUs = 0; 00260 for(ConnectionIdentifiers::const_iterator conn = cis.begin(); 00261 conn != cis.end(); 00262 ++conn) 00263 { 00264 assure((*conn)->direction_ != ConnectionIdentifier::Downlink, 00265 "Component::getNumberOfQueuedPDUs(...) works for uplink PDUs only"); 00266 wns::ldk::FlowSeparator* bufferSep = 00267 getFUN()->findFriend<wns::ldk::FlowSeparator*>("bufferSep"); 00268 wns::ldk::ConstKeyPtr key(new ConnectionKey((*conn)->cid_)); 00269 wns::ldk::Group* group = 00270 dynamic_cast<wns::ldk::Group*>(bufferSep->getInstance(key)); 00271 if(group) 00272 { 00273 wns::ldk::buffer::Buffer* buffer = 00274 group->getSubFUN()->findFriend<wns::ldk::buffer::Buffer*>("buffer"); 00275 assure(buffer, "Cannot find buffer in subFUN"); 00276 queuedPDUs += buffer->getSize(); 00277 } 00278 } 00279 if (getFUN()->knowsFunctionalUnit("upRelayInject")) 00280 { 00281 wns::ldk::buffer::Buffer* relayInject = 00282 getFUN()->findFriend<wns::ldk::buffer::Buffer*>("upRelayInject"); 00283 queuedPDUs += relayInject->getSize(); 00284 LOG_INFO("Added ", relayInject->getSize(), 00285 " PDUs to the number of total PDUs waiting for beeing transmitted"); 00286 } 00287 LOG_INFO( getName(), " with station ID ", id_, 00288 " and station type ", wns::service::dll::StationTypes::toString(stationType_), 00289 " has queued PDUS ", queuedPDUs ); 00290 return queuedPDUs; 00291 } 00292 00293 void 00294 Component::doVisit(wns::probe::bus::IContext& context) const 00295 { 00296 contextProviders_.fillContext(context); 00297 } 00298 00299 wns::ldk::fun::Main* 00300 Component::getFUN() 00301 { 00302 return fun_; 00303 } 00304 00305 std::string 00306 Component::getName() const 00307 { 00308 return getNode()->getName(); 00309 }
1.5.5