![]() |
User Manual, Developers Guide and API Documentation |
![]() |
00001 /****************************************************************************** 00002 * WiMeMac * 00003 * This file is part of openWNS (open Wireless Network Simulator) 00004 * _____________________________________________________________________________ 00005 * 00006 * Copyright (C) 2004-2011 00007 * Chair of Communication Networks (ComNets) 00008 * Kopernikusstr. 5, D-52074 Aachen, Germany 00009 * phone: ++49-241-80-27910, 00010 * fax: ++49-241-80-22242 00011 * email: info@openwns.org 00012 * www: http://www.openwns.org 00013 * _____________________________________________________________________________ 00014 * 00015 * openWNS is free software; you can redistribute it and/or modify it under the 00016 * terms of the GNU Lesser General Public License version 2 as published by the 00017 * Free Software Foundation; 00018 * 00019 * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY 00020 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 00021 * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 00022 * details. 00023 * 00024 * You should have received a copy of the GNU Lesser General Public License 00025 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00026 * 00027 ******************************************************************************/ 00028 00029 #include <WIMEMAC/lowerMAC/Manager.hpp> 00030 #include <WIMEMAC/convergence/ChannelState.hpp> 00031 #include <WIMEMAC/Component.hpp> 00032 #include <WNS/service/dll/StationTypes.hpp> 00033 #include <WNS/ldk/FlowGate.hpp> 00034 00035 00036 00037 using namespace wimemac::lowerMAC; 00038 00039 STATIC_FACTORY_REGISTER_WITH_CREATOR( 00040 wimemac::lowerMAC::Manager, 00041 wns::ldk::FunctionalUnit, 00042 "wimemac.lowerMAC.Manager", 00043 wns::ldk::FUNConfigCreator); 00044 00045 Manager::Manager(wns::ldk::fun::FUN* fun, const wns::pyconfig::View& config) : 00046 wns::ldk::fu::Plain<Manager, ManagerCommand>(fun), 00047 config_(config), 00048 logger_(config_.get("logger")), 00049 expectedACKDuration(config.get<wns::simulator::Time>("myConfig.expectedACKDuration")), 00050 sifsDuration(config.get<wns::simulator::Time>("myConfig.sifsDuration")), 00051 myMACAddress_(config.get<wns::service::dll::UnicastAddress>("myMACAddress")), 00052 ucName_(config_.get<std::string>("upperConvergenceCommandName")), 00053 protocolCalculatorName(config_.get<std::string>("protocolCalculatorName")), 00054 mcsProbe(new wns::probe::bus::ContextCollector(wns::probe::bus::ContextProviderCollection(&fun->getLayer()->getContextProviderCollection()),"wimemac.manager.mcs")), 00055 reservationBlocks(config.get<int>("myConfig.reservationBlocks")), 00056 useRandomPattern(config_.get<bool>("myConfig.useRandomPattern") ), 00057 useRateAdaptation(config_.get<bool>("myConfig.useRateAdaptation")), 00058 useDRPchannelAccess(config_.get<bool>("myConfig.useDRPchannelAccess")), 00059 usePCAchannelAccess(config_.get<bool>("myConfig.usePCAchannelAccess")), 00060 msduLifetimeLimit(config_.get<wns::simulator::Time>("myConfig.msduLifetimeLimit")) 00061 00062 00063 { 00064 MESSAGE_SINGLE(NORMAL, logger_, "created"); 00065 friends.phyUser = NULL; 00066 friends.upperConvergence = NULL; 00067 friends.drpScheduler = NULL; 00068 00069 } 00070 00071 Manager::~Manager() 00072 { 00073 00074 } 00075 00076 void 00077 Manager::onFUNCreated() 00078 { 00079 // set services in my PhyUser to communicate with lower layer 00080 friends.phyUser = getFUN()->findFriend<wimemac::convergence::PhyUser*>(config_.get<std::string>("phyUserName")); 00081 00082 friends.phyUser->setDataTransmissionService( 00083 this->getFUN()->getLayer<wimemac::Component*>() 00084 ->getService<wns::service::phy::ofdma::DataTransmission*>( config_.get<std::string>("phyDataTransmission") ) ); 00085 friends.phyUser->setNotificationService( 00086 this->getFUN()->getLayer<wimemac::Component*>() 00087 ->getService<wns::service::phy::ofdma::Notification*>( config_.get<std::string>("phyNotification") ) ); 00088 00089 friends.drpScheduler = getFUN()->findFriend<wimemac::drp::DRPScheduler*>(config_.get<std::string>("drpSchedulerName")); 00090 00091 friends.errorModelling = getFUN()->findFriend<wimemac::convergence::ErrorModelling*>(config_.get<std::string>("errorModellingName")); 00092 00093 protocolCalculator = getFUN()->getLayer<dll::Layer2*>()->getManagementService<wimemac::management::ProtocolCalculator>(protocolCalculatorName); 00094 00095 // set service in ChannelState to observe the CarrierSense 00096 wimemac::convergence::ChannelState* cs = getFUN()->findFriend<wimemac::convergence::ChannelState*>(config_.get<std::string>("channelStateName")); 00097 assure(cs, "Could not get ChannelState from my FUN"); 00098 00099 cs->setCarrierSensingService( 00100 this->getFUN()->getLayer<dll::Layer2*>() 00101 ->getService<wns::service::phy::ofdma::Notification*>(config_.get<std::string>("phyCarrierSense")) ); 00102 00103 // find upper convergence 00104 friends.upperConvergence = getFUN()->findFriend<dll::UpperConvergence*>(ucName_); 00105 00106 } 00107 00108 00109 void 00110 Manager::processIncoming(const wns::ldk::CompoundPtr& /*compound*/) 00111 { 00112 00113 } 00114 00115 void 00116 Manager::processOutgoing(const wns::ldk::CompoundPtr& compound) 00117 { 00118 assure(getFUN()->getCommandReader(ucName_) 00119 ->readCommand<dll::UpperCommand>(compound->getCommandPool()) 00120 ->peer.sourceMACAddress == myMACAddress_, 00121 "Try to tx compound with source address " << 00122 getFUN()->getCommandReader(ucName_) 00123 ->readCommand<dll::UpperCommand>(compound->getCommandPool()) 00124 ->peer.sourceMACAddress << 00125 " from transceiver with MAC address " << myMACAddress_ ); 00126 00127 // The command has to be activated to be considered in the createReply chain 00128 ManagerCommand* mc = activateCommand(compound->getCommandPool()); 00129 mc->peer.CompoundType = DATA; 00130 mc->peer.hasPayload = true; 00131 mc->peer.frameExchangeDuration = this->sifsDuration + this->expectedACKDuration; 00132 00133 // Sets the phymode according to the configuration of the drpscheduler 00134 wns::service::dll::UnicastAddress rx = getFUN()->getCommandReader(ucName_) 00135 ->readCommand<dll::UpperCommand>(compound->getCommandPool()) 00136 ->peer.targetMACAddress; 00137 int masNumber_ = getMASNumber(wns::simulator::getEventScheduler()->getTime()); 00138 mc->peer.phyMode = friends.drpScheduler->getPhyMode(rx, masNumber_); 00139 mc->peer.psduDuration = protocolCalculator->getDuration()->MSDU_PSDU(compound->getLengthInBits(), mc->peer.phyMode); 00140 00141 mcsProbe->put(mc->peer.phyMode.getDataRate() ); 00142 00143 if(this->msduLifetimeLimit > 0) 00144 { 00145 mc->local.expirationTime = wns::simulator::getEventScheduler()->getTime() + this->msduLifetimeLimit; 00146 MESSAGE_SINGLE(NORMAL, logger_, "Outgoing command will expire at " << mc->local.expirationTime); 00147 } 00148 else 00149 { 00150 mc->local.expirationTime = 0.0; 00151 MESSAGE_SINGLE(NORMAL, logger_, "Outgoing command, no expiration time"); 00152 } 00153 } 00154 00155 bool 00156 Manager::doIsAccepting(const wns::ldk::CompoundPtr& compound) const 00157 { 00158 wns::ldk::CompoundPtr compound2send = compound->copy(); 00159 00160 // The command has to be activated to be considered in the createReply chain 00161 ManagerCommand* mc = activateCommand(compound2send->getCommandPool()); 00162 mc->peer.CompoundType = DATA; 00163 mc->peer.hasPayload = true; 00164 mc->peer.frameExchangeDuration = this->sifsDuration + this->expectedACKDuration; 00165 00166 // Sets the phymode according to the configuration of the drpscheduler 00167 wns::service::dll::UnicastAddress rx = getFUN()->getCommandReader(ucName_) 00168 ->readCommand<dll::UpperCommand>(compound2send->getCommandPool()) 00169 ->peer.targetMACAddress; 00170 //int masNumber_ = this->getMASNumber(wns::simulator::getEventScheduler()->getTime()); 00171 //mc->peer.phyMode = friends.drpScheduler->getPhyMode(rx, masNumber_); 00172 mc->peer.phyMode = friends.drpScheduler->getPhyMode(rx, -1); 00173 00174 //return getConnector()->hasAcceptor(compound2send); 00175 return (wns::ldk::Processor<Manager>::doIsAccepting(compound2send)); 00176 } 00177 00178 bool 00179 Manager::lifetimeExpired(const wns::ldk::CommandPool* commandPool) const 00180 { 00181 wns::simulator::Time exp = getCommand(commandPool)->local.expirationTime; 00182 if(exp == 0) 00183 { 00184 return false; 00185 } 00186 else 00187 { 00188 return(wns::simulator::getEventScheduler()->getTime() > exp); 00189 } 00190 } 00191 00192 wns::simulator::Time 00193 Manager::getExpirationTime(const wns::ldk::CommandPool* commandPool) const 00194 { 00195 return(getCommand(commandPool)->local.expirationTime); 00196 } 00197 00198 wimemac::convergence::PhyUser* 00199 Manager::getPhyUser() 00200 { 00201 if(friends.phyUser) 00202 { 00203 return(friends.phyUser); 00204 } 00205 else 00206 { 00207 return(getFUN()->findFriend<wimemac::convergence::PhyUser*>(config_.get<std::string>("phyUserName"))); 00208 } 00209 } 00210 00211 wimemac::management::ProtocolCalculator* 00212 Manager::getProtocolCalculator() 00213 { 00214 return (protocolCalculator); 00215 } 00216 00217 dll::Layer2::StationType 00218 Manager::getStationType() const 00219 { 00220 // simply relayed to Layer2 00221 return(this->getFUN()->getLayer<dll::Layer2*>()->getStationType()); 00222 } 00223 00224 wns::service::dll::UnicastAddress 00225 Manager::getMACAddress() const 00226 { 00227 return(this->myMACAddress_); 00228 } 00229 00230 wns::ldk::CommandPool* 00231 Manager::createReply(const wns::ldk::CommandPool* original) const 00232 { 00233 wns::ldk::CommandPool* reply = this->getFUN()->getProxy()->createReply(original, this); 00234 00235 dll::UpperCommand* ucReply = getFUN()->getProxy()->getCommand<dll::UpperCommand>(reply, ucName_); 00236 dll::UpperCommand* ucOriginal = getFUN()->getCommandReader(ucName_)->readCommand<dll::UpperCommand>(original); 00237 00238 // this cannot be set to this->myAddress_, because it is not defined which 00239 // Manager-entity will be asked for createReply 00240 ucReply->peer.sourceMACAddress = ucOriginal->peer.targetMACAddress; 00241 00242 ManagerCommand* mc = activateCommand(reply); 00243 // Sets the phymode to the same as the original compounds phymode 00244 wimemac::lowerMAC::ManagerCommand* mcOriginal = this->getCommand(original); 00245 mc->peer.phyMode = mcOriginal->getPhyMode(); 00246 00247 mc->peer.CompoundType = mcOriginal->getCompoundType(); 00248 00249 if(this->msduLifetimeLimit > 0) 00250 { 00251 mc->local.expirationTime = wns::simulator::getEventScheduler()->getTime() + this->msduLifetimeLimit; 00252 } 00253 else 00254 { 00255 mc->local.expirationTime = 0; 00256 } 00257 00258 00259 MESSAGE_SINGLE(NORMAL, logger_, "create reply done, set sourceMACAddress to " << ucReply->peer.sourceMACAddress); 00260 00261 return(reply); 00262 } 00263 00264 wns::ldk::CommandPool* 00265 Manager::createReply(const wns::ldk::CommandPool* original, wimemac::CompoundType compoundType) const 00266 { 00267 wns::ldk::CommandPool* reply = this->getFUN()->getProxy()->createReply(original, this); 00268 00269 dll::UpperCommand* ucReply = getFUN()->getProxy()->getCommand<dll::UpperCommand>(reply, ucName_); 00270 dll::UpperCommand* ucOriginal = getFUN()->getCommandReader(ucName_)->readCommand<dll::UpperCommand>(original); 00271 00272 // this cannot be set to this->myAddress_, because it is not defined which 00273 // Manager-entity will be asked for createReply 00274 ucReply->peer.sourceMACAddress = ucOriginal->peer.targetMACAddress; 00275 00276 ManagerCommand* mc = activateCommand(reply); 00277 mc->peer.CompoundType = compoundType; 00278 if (compoundType == ACK) 00279 { 00280 mc->peer.hasPayload = false; 00281 } 00282 // Sets the phymode to the same as the original compounds phymode 00283 wimemac::lowerMAC::ManagerCommand* mcOriginal = this->getCommand(original); 00284 mc->peer.phyMode = mcOriginal->getPhyMode(); 00285 00286 if(this->msduLifetimeLimit > 0) 00287 { 00288 mc->local.expirationTime = wns::simulator::getEventScheduler()->getTime() + this->msduLifetimeLimit; 00289 } 00290 else 00291 { 00292 mc->local.expirationTime = 0; 00293 } 00294 00295 00296 MESSAGE_SINGLE(NORMAL, logger_, "create reply done, set sourceMACAddress to " << ucReply->peer.sourceMACAddress); 00297 00298 return(reply); 00299 } 00300 00301 wns::service::dll::UnicastAddress 00302 Manager::getTransmitterAddress(const wns::ldk::CommandPool* commandPool) const 00303 { 00304 return (getFUN()->getCommandReader(ucName_)->readCommand<dll::UpperCommand>(commandPool)->peer.sourceMACAddress); 00305 } 00306 00307 wns::service::dll::UnicastAddress 00308 Manager::getReceiverAddress(const wns::ldk::CommandPool* commandPool) const 00309 { 00310 return (getFUN()->getCommandReader(ucName_)->readCommand<dll::UpperCommand>(commandPool)->peer.targetMACAddress); 00311 } 00312 00313 bool 00314 Manager::isForMe(const wns::ldk::CommandPool* commandPool) const 00315 { 00316 if(getFUN()->getCommandReader(ucName_)->commandIsActivated(commandPool)) 00317 { 00318 return(getFUN()->getCommandReader(ucName_)->readCommand<dll::UpperCommand>(commandPool)->peer.targetMACAddress == this->myMACAddress_); 00319 } 00320 else 00321 { 00322 // broadcast -> is for me 00323 return true; 00324 } 00325 } 00326 00327 wimemac::CompoundType 00328 Manager::getCompoundType(const wns::ldk::CommandPool* commandPool) const 00329 { 00330 return(getCommand(commandPool)->peer.CompoundType); 00331 } 00332 00333 std::string 00334 Manager::getPreambleMode(const wns::ldk::CommandPool* commandPool) const 00335 { 00336 return(getCommand(commandPool)->peer.phyMode.getPreambleMode()); 00337 } 00338 00339 bool 00340 Manager::hasPayload(const wns::ldk::CommandPool* commandPool) const 00341 { 00342 return (getCommand(commandPool)->peer.hasPayload); 00343 } 00344 00345 00346 void 00347 Manager::setHasPayload(const wns::ldk::CommandPool* commandPool, bool setPayloadTo) 00348 { 00349 getCommand(commandPool)->peer.hasPayload = setPayloadTo; 00350 } 00351 00352 00353 bool 00354 Manager::isPreamble(const wns::ldk::CommandPool* commandPool) const 00355 { 00356 return (getCommand(commandPool)->peer.CompoundType == ACK_PREAMBLE || getCommand(commandPool)->peer.CompoundType == BEACON_PREAMBLE || getCommand(commandPool)->peer.CompoundType == DATA_PREAMBLE); 00357 } 00358 00359 bool 00360 Manager::isBeacon(const wns::ldk::CommandPool* commandPool) const 00361 { 00362 return friends.drpScheduler->isBeacon(commandPool); 00363 } 00364 00365 wns::ldk::CompoundPtr 00366 Manager::createCompound(const wns::service::dll::UnicastAddress transmitterAddress, 00367 const wns::service::dll::UnicastAddress receiverAddress, 00368 const CompoundType compoundType, 00369 const bool hasPayload, 00370 //const FrameType frameType, 00371 const wns::simulator::Time frameExchangeDuration, 00372 const bool requiresDirectReply) 00373 { 00374 wns::ldk::CompoundPtr compound(new wns::ldk::Compound(getFUN()->getProxy()->createCommandPool())); 00375 ManagerCommand* mc = activateCommand(compound->getCommandPool()); 00376 dll::UpperCommand* uc = friends.upperConvergence->activateCommand(compound->getCommandPool()); 00377 00378 uc->peer.sourceMACAddress = transmitterAddress; 00379 uc->peer.targetMACAddress = receiverAddress; 00380 mc->peer.CompoundType = compoundType; 00381 mc->peer.hasPayload = hasPayload; 00382 mc->peer.frameExchangeDuration = frameExchangeDuration; 00383 mc->peer.psduDuration = 0.0; 00384 mc->peer.requiresDirectReply = requiresDirectReply; 00385 00386 // phymode is set by the compounds creating instance 00387 00388 return(compound); 00389 } 00390 00391 void 00392 Manager::setCompoundType(const wns::ldk::CommandPool* commandPool, const CompoundType type) 00393 { 00394 getCommand(commandPool)->peer.CompoundType = type; 00395 } 00396 00397 wimemac::convergence::PhyMode 00398 Manager::getPhyMode(const wns::ldk::CommandPool* commandPool) const 00399 { 00400 return(getCommand(commandPool)->getPhyMode()); 00401 } 00402 00403 void 00404 Manager::setPhyMode(const wns::ldk::CommandPool* commandPool, const wimemac::convergence::PhyMode phyMode) 00405 { 00406 getCommand(commandPool)->peer.phyMode = phyMode; 00407 } 00408 00409 wimemac::convergence::PhyMode 00410 Manager::getDefaultPhyMode() const 00411 { 00412 return(friends.phyUser->getPhyModeProvider()->getDefaultPhyMode()); 00413 } 00414 00415 wns::Power 00416 Manager::getRxPower(const wns::ldk::CommandPool* commandPool) 00417 { 00418 return friends.phyUser->getRxPower(commandPool); 00419 } 00420 00421 wns::Power 00422 Manager::getInterference(const wns::ldk::CommandPool* commandPool) 00423 { 00424 return friends.phyUser->getInterference(commandPool); 00425 } 00426 00427 wimemac::convergence::MCS 00428 Manager::getMaxPosMCS(wns::Ratio sinr_, Bit maxCompoundSize_, double per_) 00429 { 00430 return (friends.errorModelling->getMaxPosMCS(sinr_, maxCompoundSize_, per_)); 00431 } 00432 00433 00434 double 00435 Manager::getErrorRateForCommandFrames(wns::Ratio sinr_, Bit maxCompoundSize_) 00436 { 00437 return (friends.errorModelling->getErrorRateForCommandFrames(sinr_,maxCompoundSize_)); 00438 } 00439 00440 int 00441 Manager::getMASNumber(wns::simulator::Time time_) 00442 { 00443 // +10E-6 offset to avoid rounding errors 00444 // The shortest possible TxDuration is 18E-6s. Thus even with the offset the time is definitely within the TxTime 00445 wns::simulator::Time timeInSF_ = time_ - BPStartTime + 10E-6; 00446 double masNumberdouble_ = timeInSF_ / 256E-6; 00447 int masNumber_ = masNumberdouble_; 00448 00449 return masNumber_; 00450 } 00451 00452 double 00453 Manager::getDesiredPER() 00454 { 00455 return (friends.drpScheduler->getDesiredPER()); 00456 } 00457 00458 double 00459 Manager::getPatternPEROffset() 00460 { 00461 return (friends.drpScheduler->getPatternPEROffset()); 00462 } 00463 00464 wns::simulator::Time 00465 Manager::getFrameExchangeDuration(const wns::ldk::CommandPool* commandPool) const 00466 { 00467 return(getCommand(commandPool)->peer.frameExchangeDuration); 00468 } 00469 00470 void 00471 Manager::setFrameExchangeDuration(const wns::ldk::CommandPool* commandPool, const wns::simulator::Time duration) 00472 { 00473 getCommand(commandPool)->peer.frameExchangeDuration = duration; 00474 } 00475 00476 wns::simulator::Time 00477 Manager::getpsduDuration(const wns::ldk::CommandPool* commandPool) const 00478 { 00479 return(getCommand(commandPool)->peer.psduDuration); 00480 } 00481 00482 void 00483 Manager::setpsduDuration(const wns::ldk::CommandPool* commandPool, const wns::simulator::Time duration) 00484 { 00485 getCommand(commandPool)->peer.psduDuration = duration; 00486 } 00487 00488 bool 00489 Manager::getRequiresDirectReply(const wns::ldk::CommandPool* commandPool) const 00490 { 00491 return(getCommand(commandPool)->peer.requiresDirectReply); 00492 } 00493 00494 void 00495 Manager::setRequiresDirectReply(const wns::ldk::CommandPool* commandPool, bool requiresDirectReply) 00496 { 00497 getCommand(commandPool)->peer.requiresDirectReply = requiresDirectReply; 00498 } 00499 00500 // For BeaconBuilder Services 00502 void 00503 Manager::prepareDRPConnection(wns::service::dll::UnicastAddress rx, int CompoundspSF, int BitspSF, int MaxCompoundSize) 00504 { 00505 friends.drpScheduler->getBeaconBuilder()->prepareDRPConnection(rx, CompoundspSF, BitspSF, MaxCompoundSize); 00506 } 00507 00508 void 00509 Manager::updateDRPConnection(wns::service::dll::UnicastAddress rx, int CompoundspSF, int BitspSF, int MaxCompoundSize) 00510 { 00511 friends.drpScheduler->getBeaconBuilder()->updateDRPConnection(rx, CompoundspSF, BitspSF, MaxCompoundSize); 00512 } 00513 00514 void 00515 Manager::BuildDTPmap() 00516 { 00517 friends.drpScheduler->getBeaconBuilder()->BuildDTPmap(); 00518 } 00519 00520 void 00521 Manager::SetBPDuration(wns::simulator::Time duration) 00522 { 00523 friends.drpScheduler->getBeaconBuilder()->SetBPDuration(duration); 00524 } 00525 00526 // For DRPScheduler Services 00527 bool 00528 Manager::startPCAtransmission() 00529 { 00530 return(friends.drpScheduler->startPCAtransmission()); 00531 } 00532 00533 void 00534 Manager::stopPCAtransmission() 00535 { 00536 friends.drpScheduler->stopPCAtransmission(); 00537 } 00538 00539 void 00540 Manager::txOPCloseIn(wns::simulator::Time duration) 00541 { 00542 friends.drpScheduler->txOPCloseIn(duration); 00543 } 00544 00545 int 00546 Manager::getNumOfRetransmissions(const wns::ldk::CompoundPtr& compound) 00547 { 00548 return(friends.drpScheduler->getNumOfRetransmissions(compound)); 00549 } 00550 00551 wns::service::dll::UnicastAddress 00552 Manager::getCurrentTransmissionTarget() 00553 { 00554 return(friends.drpScheduler->getCurrentTransmissionTarget()); 00555 } 00556 00557 bool 00558 Manager::UpdateMapWithPeerAvailabilityMap(wns::service::dll::UnicastAddress rx , Vector& DRPMap) 00559 { 00560 return(friends.drpScheduler->UpdateMapWithPeerAvailabilityMap(rx, DRPMap)); 00561 } 00562 00563 bool 00564 Manager::adjustMCSdown(wns::service::dll::UnicastAddress rx) 00565 { 00566 return(friends.drpScheduler->adjustMCSdown(rx)); 00567 } 00568 00569 void 00570 Manager::UpdateDRPMap(Vector DRPMap) 00571 { 00572 friends.drpScheduler->UpdateDRPMap(DRPMap); 00573 } 00574 00575 void 00576 Manager::onBPStart(wns::simulator::Time BPduration) 00577 { 00578 friends.drpScheduler->onBPStart(BPduration); 00579 } 00580 00581 void 00582 Manager::Acknowledgment(wns::service::dll::UnicastAddress tx) 00583 { 00584 friends.drpScheduler->Acknowledgment(tx); 00585 }
1.5.5