![]() |
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 #include <WIMAC/Classifier.hpp> 00027 00028 #include <WNS/service/dll/Address.hpp> 00029 #include <WNS/service/dll/StationTypes.hpp> 00030 #include <WNS/ldk/fun/FUN.hpp> 00031 00032 #include <WIMAC/Component.hpp> 00033 #include <WIMAC/ConnectionRule.hpp> 00034 #include <WIMAC/services/ConnectionManager.hpp> 00035 #include <WIMAC/StationManager.hpp> 00036 #include <WIMAC/UpperConvergence.hpp> 00037 #include <WIMAC/Utilities.hpp> 00038 00039 STATIC_FACTORY_REGISTER_WITH_CREATOR( 00040 wimac::ConnectionClassifier, 00041 wns::ldk::FunctionalUnit, 00042 "wimac.ConnectionClassifier", 00043 wns::ldk::FUNConfigCreator); 00044 00045 STATIC_FACTORY_REGISTER_WITH_CREATOR( 00046 wimac::ClassifierMock, 00047 wns::ldk::FunctionalUnit, 00048 "wimac.ClassifierMock", 00049 wns::ldk::FUNConfigCreator); 00050 00051 00052 using namespace wimac; 00053 00054 ConnectionClassifier::ConnectionClassifier( wns::ldk::fun::FUN* fun, 00055 const wns::pyconfig::View& /* config*/ ) : 00056 wns::ldk::CommandTypeSpecifier< wns::ldk::ClassifierCommand >(fun) 00057 {} 00058 00059 void ConnectionClassifier::doOnData(const wns::ldk::CompoundPtr& compound) 00060 { 00061 if( classifyIncoming(compound) == -1 ) //Invalid Compound, throw away 00062 return; 00063 00064 getDeliverer()->getAcceptor(compound)->onData(compound); 00065 } 00066 00067 00068 00069 void ConnectionClassifier::doSendData(const wns::ldk::CompoundPtr& compound) 00070 { 00071 //Activate command and allocate classify id 00072 assure( !( getFUN()->getProxy() 00073 ->commandIsActivated( compound->getCommandPool(), this ) ), 00074 " wimac::ConnectionClassifier::processOutgoing: ConnectionClassifier shouldn't get activated command! \n"); 00075 00076 wns::ldk::ClassifierCommand* command = NULL; 00077 command = activateCommand( compound->getCommandPool() ); 00078 command->peer.id = classifyOutgoing( compound); 00079 00080 getConnector()->getAcceptor(compound)->sendData(compound); 00081 } 00082 00083 00084 00085 void ConnectionClassifier::onFUNCreated() 00086 { 00087 friends_.upperConvergence = getFUN()->findFriend<UpperConvergence*>("wimax.upperConvergence"); 00088 friends_.connectionManager = 00089 getFUN()->getLayer()->getManagementService<service::ConnectionManager> 00090 ("connectionManager"); 00091 00092 assureType( getFUN()->getLayer(), wimac::Component* ); 00093 friends_.component = dynamic_cast<wimac::Component*>( getFUN()->getLayer() ); 00094 } 00095 00096 00097 00098 wns::ldk::CommandPool* 00099 ConnectionClassifier::createReply(const wns::ldk::CommandPool* original) const 00100 { 00101 wns::ldk::CommandPool* newCommand = getFUN()->getProxy()->createReply(original, this); 00102 wns::ldk::ClassifierCommand* newClassifierCommand = activateCommand( newCommand ); 00103 wns::ldk::ClassifierCommand* classifierCommand = getCommand( original ); 00104 newClassifierCommand->peer.id = classifierCommand->peer.id; 00105 return newCommand; 00106 } 00107 00108 00109 00110 wns::ldk::ClassificationID 00111 ConnectionClassifier::classifyIncoming( const wns::ldk::CompoundPtr& compound ) 00112 { 00113 wns::ldk::ClassifierCommand* command; 00114 command = getCommand( compound->getCommandPool() ) ; 00115 00116 UpperCommand* ucCommand = 00117 friends_.upperConvergence->getCommand(compound->getCommandPool()); 00118 00119 00120 LOG_INFO( getFUN()->getLayer()->getName(), ": classify incomming compound. CID: ", 00121 command->peer.id, " to destMACAdr: ", ucCommand->peer.targetMACAddress ); 00122 00123 ConnectionIdentifier::Ptr ci 00124 ( friends_.connectionManager->getConnectionWithID(command->peer.id) ); 00125 00126 if( !ci ) 00127 { 00128 std::stringstream error; 00129 error << "No ConnectionIdentifier registered with ID " << command->peer.id; 00130 throw wns::Exception( error.str() ); 00131 } 00132 00133 ConnectionIdentifier::StationID sourceID = -1; 00134 if( ci->subscriberStation_ == dynamic_cast<Component*>(getFUN()->getLayer())->getID() ) 00135 sourceID = ci->baseStation_; 00136 if( ci->baseStation_ == dynamic_cast<Component*>(getFUN()->getLayer())->getID() ) 00137 sourceID = ci->remoteStation_; 00138 00139 return command->peer.id; 00140 } 00141 00142 00143 00144 wns::ldk::ClassificationID 00145 ConnectionClassifier::classifyOutgoing( const wns::ldk::CompoundPtr& compound ) 00146 { 00147 UpperCommand* ucCommand = 00148 friends_.upperConvergence->getCommand(compound->getCommandPool()); 00149 00150 ConnectionIdentifiers cis = 00151 friends_.connectionManager->getOutgoingDataConnections( 00152 ucCommand->peer.targetMACAddress.getInteger(), 00153 ucCommand->local.qosClass); 00154 00155 if ( cis.empty() ) 00156 { 00157 if(friends_.component->getStationType() == wns::service::dll::StationTypes::UT() || 00158 friends_.component->getStationType() == wns::service::dll::StationTypes::RUT() ) 00159 { 00160 cis = friends_.connectionManager 00161 ->getAllDataConnections(ConnectionIdentifier::Uplink, ucCommand->local.qosClass); 00162 } 00163 00164 assure( !cis.empty(), 00165 "ConnectionClassifier::processOutgoing: No connections found for destination"); 00166 } 00167 00168 assure( cis.size() == 1, "ConnectionClassifier::classifyOutgoing: Only on ConnectionIdentifier to target MacAdress is at the moment allowed. \n"); 00169 00170 LOG_INFO( getFUN()->getName(), ": classify outgoing Compound. destMACAdr: ", 00171 ucCommand->peer.targetMACAddress, " to CID: ", 00172 ( *cis.begin() )->cid_ ); 00173 00174 return (*cis.begin())->cid_; 00175 } 00176 00177 00178 bool 00179 ConnectionClassifier::doIsAccepting(const wns::ldk::CompoundPtr& compound) const 00180 { 00181 00182 UpperCommand* ucCommand = friends_.upperConvergence->getCommand(compound->getCommandPool()); 00183 00184 // try to get ConnectionIdentifier for this compound 00185 ConnectionIdentifiers cis = 00186 friends_.connectionManager->getOutgoingDataConnections( 00187 ucCommand->peer.targetMACAddress.getInteger() , 00188 ucCommand->local.qosClass); 00189 00190 if( cis.empty() ) 00191 { 00192 if(friends_.component->getStationType() == wns::service::dll::StationTypes::UT() || 00193 friends_.component->getStationType() == wns::service::dll::StationTypes::RUT() ) 00194 { 00195 cis = friends_.connectionManager 00196 ->getAllDataConnections(ConnectionIdentifier::Uplink, 00197 ucCommand->local.qosClass ); 00198 } 00199 } 00200 00201 // return true if CI for this compound exist and lower FU isAccepting 00202 if ( !cis.empty() 00203 && getConnector()->hasAcceptor(compound) ) 00204 { 00205 return true; 00206 } 00207 return false; 00208 } 00209
1.5.5