User Manual, Developers Guide and API Documentation

Component.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  * 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 }

Generated on Sun May 27 03:31:48 2012 for openWNS by  doxygen 1.5.5