User Manual, Developers Guide and API Documentation

MeshForwarding.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002  * WiFiMac                                                                    *
00003  * This file is part of openWNS (open Wireless Network Simulator)
00004  * _____________________________________________________________________________
00005  *
00006  * Copyright (C) 2004-2007
00007  * Chair of Communication Networks (ComNets)
00008  * Kopernikusstr. 16, 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 <WIFIMAC/pathselection/MeshForwarding.hpp>
00030 
00031 #include <WNS/service/dll/StationTypes.hpp>
00032 #include <WNS/ldk/CommandPool.hpp>
00033 #include <WNS/Exception.hpp>
00034 
00035 using namespace wifimac::pathselection;
00036 
00037 STATIC_FACTORY_REGISTER_WITH_CREATOR(
00038     wifimac::pathselection::MeshForwarding,
00039     wns::ldk::FunctionalUnit,
00040     "wifimac.pathselection.MeshForwarding",
00041     wns::ldk::FUNConfigCreator);
00042 
00043 MeshForwarding::MeshForwarding(wns::ldk::fun::FUN* fun, const wns::pyconfig::View& config_) :
00044     wns::ldk::fu::Plain<MeshForwarding, ForwardingCommand>(fun),
00045     config(config_),
00046     logger(config.get("logger")),
00047     ucName(config.get<std::string>("upperConvergenceName")),
00048     dot11MeshTTL(config.get<int>("dot11MeshTTL"))
00049 {
00050     MESSAGE_SINGLE(NORMAL, this->logger, "created");
00051 }
00052 
00053 MeshForwarding::~MeshForwarding()
00054 {
00055 
00056 }
00057 
00058 void
00059 MeshForwarding::onFUNCreated()
00060 {
00061 
00062     if(getFUN()->getLayer<wifimac::Layer2*>()->getStationType() == wns::service::dll::StationTypes::UT())
00063     {
00064         throw wns::Exception("MeshForwarding is only allowed for StationType != UT");
00065     }
00066 
00067     std::string psName = config.get<std::string>("pathSelectionServiceName");
00068     layer2 = getFUN()->getLayer<wifimac::Layer2*>();
00069     ps = layer2->getManagementService<wifimac::pathselection::IPathSelection>(psName);
00070     assure(ps, "Could not get VirtualPathSelection Service");
00071 }
00072 
00073 bool
00074 MeshForwarding::doIsAccepting(const wns::ldk::CompoundPtr& _compound) const
00075 {
00076     // First make a copy of the compound and use this, as we manipulate the
00077     // target address
00078     wns::ldk::CompoundPtr compound = _compound->copy();
00079 
00080     dll::UpperCommand* uc = getFUN()->getProxy()->getCommand<dll::UpperCommand>(compound->getCommandPool(), ucName);
00081 
00082     if (layer2->getControlService<dll::services::control::Association>("ASSOCIATION")
00083         ->hasAssociated(uc->peer.targetMACAddress))
00084     {
00085         uc->peer.sourceMACAddress = ps->getProxyFor(uc->peer.targetMACAddress);
00086     }
00087     else
00088     {
00089         wns::service::dll::UnicastAddress mpDst = uc->peer.targetMACAddress;
00090         if (!mpDst.isValid())
00091         {
00092             mpDst = ps->getPortalFor(uc->peer.sourceMACAddress);
00093         }
00094         uc->peer.targetMACAddress = ps->getNextHop(uc->peer.sourceMACAddress, mpDst);
00095         if(layer2->isTransceiverMAC(uc->peer.targetMACAddress))
00096         {
00097             uc->peer.sourceMACAddress = uc->peer.targetMACAddress;
00098             uc->peer.targetMACAddress = ps->getNextHop(uc->peer.sourceMACAddress, mpDst);
00099         }
00100     }
00101 
00102     // Forward the manipulated compound
00103     return getConnector()->hasAcceptor(compound);
00104 }
00105 
00106 void
00107 MeshForwarding::doWakeup()
00108 {
00109     // simply forward the wakeup call
00110     getReceptor()->wakeup();
00111 }
00112 
00113 void
00114 MeshForwarding::doOnData(const wns::ldk::CompoundPtr& _compound)
00115 {
00116     // Received compound from one of my transceivers
00117 
00118     // First: copy the compound
00119     wns::ldk::CompoundPtr compound = _compound->copy();
00120 
00121     ForwardingCommand* fc = getCommand(compound);
00122     dll::UpperCommand* uc = getFUN()->getProxy()->getCommand<dll::UpperCommand>(compound->getCommandPool(), ucName);
00123 
00124     ++fc->magic.hopCount;
00125     fc->magic.path.push_back(uc->peer.targetMACAddress);
00126     if(uc->peer.targetMACAddress != layer2->getDLLAddress())
00127     {
00128         fc->magic.path.push_back(layer2->getDLLAddress());
00129     }
00130 
00131 #ifndef WNS_NO_LOGGING
00132     printForwardingInformation(fc, uc);
00133 #endif
00134 
00135     assure(layer2->isTransceiverMAC(uc->peer.targetMACAddress),
00136            "Recieved compound with targetMACAddress " << uc->peer.targetMACAddress << " which is not a transceiver of me");
00137 
00138     if (layer2->getStationType() == wns::service::dll::StationTypes::AP())
00139     {
00140         this->doOnDataAP(compound, fc, uc);
00141         return;
00142     }
00143     if (layer2->getStationType() == wns::service::dll::StationTypes::FRS())
00144     {
00145         this->doOnDataFRS(compound, fc, uc);
00146         return;
00147     }
00148 
00149     throw wns::Exception("doOnData not implemented for this station type");
00150 }
00151 
00152 void MeshForwarding::doOnDataAP(const wns::ldk::CompoundPtr& compound, ForwardingCommand*& fc, dll::UpperCommand*& uc)
00153 {
00154     assure(layer2->getStationType() == wns::service::dll::StationTypes::AP(), "Forwarding only valid for AP!");
00155     assure(fc->peer.toDS, "received frame NOT to DS");
00156 
00157     // special handling if one of the hops on the selected path goes over the
00158     // wired backbone, i.e. the RANG
00159     if((fc->peer.fromDS) &&
00160        (fc->peer.finalDestination != layer2->getDLLAddress()) &&
00161        (ps->isPortal(ps->getNextHop(layer2->getDLLAddress(), fc->peer.finalDestination))))
00162     {
00163         // the initial increase of the hc was incorrect
00164         --fc->magic.hopCount;
00165         // give it to the RANG
00166         MESSAGE_SINGLE(NORMAL, this->logger, "frame destination is another portal, give it to the RANG");
00167         // the RANG assumes the finalDestination in the UC command
00168         uc->peer.targetMACAddress = fc->peer.finalDestination;
00169         getDeliverer()->getAcceptor(compound)->onData(compound);
00170         return;
00171     }
00172 
00173     if(this->doOnDataFRS(compound, fc, uc))
00174     {
00175         //  Frame is either on its next wireless hop or dropped
00176         return;
00177     }
00178     else
00179     {
00180         assure(fc->peer.addressExtension == true, "delivered to root MP (AP), but peer.addressExtension is false");
00181 
00182         // frames which end up here are send by the meshSource without real
00183         // knowledge where to send them, i.e. using the tree-routing approach:
00184         // Send everything to the root, it should know where to put it
00185 
00186         if(ps->isMeshPoint(fc->peer.finalDestination))
00187         {
00188             // The finalDestination is known to be a MP -> convert into
00189             // 4-address and deliver
00190 
00191             // make a partial copy, i.e. only including the commands from
00192             // 'upper' FUs, including the payload
00193             dll::UpperCommand* copyUC;
00194             ForwardingCommand* copyFC;
00195             wns::ldk::CompoundPtr partialCompoundCopy = createForwardingCopy(compound, fc, copyFC, copyUC);
00196 
00197             sendFrameToMP(partialCompoundCopy, copyFC, copyUC,
00198                           fc->peer.originalSource,
00199                           fc->peer.finalDestination);
00200         } // end destination is MP
00201         else
00202         {
00203             // The finalDestination is non-MP, hopefully we know the proxy
00204 
00205             dll::UpperCommand* copyUC;
00206             ForwardingCommand* copyFC;
00207             wns::ldk::CompoundPtr partialCompoundCopy = createForwardingCopy(compound, fc, copyFC, copyUC);
00208 
00209             if(!sendFrameToOtherBSS(partialCompoundCopy, copyFC, copyUC,
00210                                     fc->peer.originalSource,
00211                                     layer2->getDLLAddress(),
00212                                     fc->peer.finalDestination))
00213 
00214             {
00215                 // Could not deliver the frame, give it to the RANG
00216                 MESSAGE_SINGLE(NORMAL, this->logger, "frame destination unknown, give to RANG");
00217                 uc->peer.targetMACAddress = fc->peer.finalDestination;
00218                 getDeliverer()->getAcceptor(compound)->onData(compound);
00219             } // end destination is unknown
00220         } // end destination is NOT MP
00221     } // end delivery by root MP
00222 } // end doOnDataAP
00223 
00224 
00225 bool MeshForwarding::doOnDataFRS(const wns::ldk::CompoundPtr& compound, ForwardingCommand*& fc, dll::UpperCommand*& uc)
00226 {
00227     assure(fc->peer.toDS, "received frame NOT to DS");
00228 
00229     if(!fc->peer.fromDS)
00230     {
00231         // The compound should be received from an associated STA
00232         assure(layer2->isTransceiverMAC(ps->getProxyFor(uc->peer.sourceMACAddress)),
00233                "Recieved compound from " << uc->peer.sourceMACAddress << " with fromDS=false, but source is not proxied by me");
00234 
00235         assure(this->layer2->
00236                getControlService<dll::services::control::Association>("ASSOCIATION")->hasAssociated(uc->peer.sourceMACAddress),
00237                "Received compound from " << uc->peer.sourceMACAddress << " with fromDS=false, but source is not associated to any of my transceivers");
00238 
00239         assure(!ps->isMeshPoint(uc->peer.sourceMACAddress),
00240                "Recieved compound from " << uc->peer.sourceMACAddress << " with fromDS=false, but source is registered as MP");
00241 
00242         MESSAGE_SINGLE(NORMAL, this->logger, "received frame from proxied client "
00243                        << uc->peer.sourceMACAddress << " to " << fc->peer.finalDestination);
00244 
00245         if(!fc->peer.finalDestination.isValid())
00246         {
00247             // The STA does not know the MAC-Address of its portal; hence it
00248             // sends it to -1
00249             fc->peer.finalDestination = ps->getPortalFor(uc->peer.sourceMACAddress);
00250             if(fc->peer.finalDestination == layer2->getDLLAddress())
00251             {
00252                 // I am the portal -> no FRS service required
00253                 MESSAGE_SINGLE(NORMAL, this->logger, "STA is associated directly to the portal -> delivery to RANG");
00254                 uc->peer.targetMACAddress = fc->peer.finalDestination;
00255                 getDeliverer()->getAcceptor(compound)->onData(compound);
00256                 return true;
00257             }
00258             if(!fc->peer.finalDestination.isValid())
00259             {
00260                 MESSAGE_SINGLE(NORMAL, this->logger, "proxy has no portal -> no delivery ");
00261                 return false;
00262             }
00263             MESSAGE_SINGLE(NORMAL, this->logger, "changing finalDestination to portal " << fc->peer.finalDestination);
00264         }
00265 
00266         dll::UpperCommand* copyUC;
00267         ForwardingCommand* copyFC;
00268         wns::ldk::CompoundPtr partialCompoundCopy = createForwardingCopy(compound, fc, copyFC, copyUC);
00269 
00270         if (layer2->getControlService<dll::services::control::Association>("ASSOCIATION")->hasAssociated(fc->peer.finalDestination))
00271         {
00272             // AP forwarding from the DS
00273             sendFrameToOwnBSS(partialCompoundCopy, copyFC, copyUC, uc->peer.sourceMACAddress, fc->peer.finalDestination);
00274             return true;
00275         }
00276         else
00277         {
00278             MESSAGE_SINGLE(NORMAL, this->logger, "doOnDataFRS: Destination " << fc->peer.finalDestination << " is not directly associated -> try forwarding");
00279 
00280             if(ps->isMeshPoint(fc->peer.finalDestination))
00281             {
00282                 MESSAGE_SINGLE(NORMAL, this->logger, "doOnDataFRS: Destination " << fc->peer.finalDestination << " is known MP -> forward");
00283                 sendFrameToMP(partialCompoundCopy, copyFC, copyUC, uc->peer.sourceMACAddress, fc->peer.finalDestination);
00284                 return true;
00285             }
00286             else
00287             {
00288                 sendFrameToOtherBSS(partialCompoundCopy, copyFC, copyUC,
00289                                     uc->peer.sourceMACAddress,                                          // src
00290                                     layer2->getDLLAddress(),  // MeshSrc
00291                                     fc->peer.finalDestination);                                         // finalDst
00292                 return true;
00293             }
00294         }
00295     }
00296 
00297     // Compound is fromDS
00298 
00299     wns::service::dll::UnicastAddress finalMeshDst;
00300     if(fc->peer.addressExtension)
00301     {
00302         finalMeshDst = fc->peer.meshDestination;
00303     }
00304     else
00305     {
00306         finalMeshDst = fc->peer.finalDestination;
00307         assure((layer2->isTransceiverMAC(finalMeshDst) == false) ||
00308                (finalMeshDst == layer2->getDLLAddress()),
00309                "Final Destination is Transceiver MAC " << finalMeshDst);
00310     }
00311 
00312     if((finalMeshDst == layer2->getDLLAddress()) ||
00313        (layer2->isTransceiverMAC(finalMeshDst)))
00314     {
00315         // I am the final mesh destination, so it goes
00316         //  a) to me directly
00317         //  b) to one of my clients
00318         //  c) to one of my transceivers and there to the client
00319         //  [d) to somewhere else, if I am a portal]
00320         MESSAGE_BEGIN(NORMAL, this->logger, m, "doOnData received frame from ");
00321         m << uc->peer.sourceMACAddress;
00322         m << " which has reached its final mesh destination towards ";
00323         m << fc->peer.finalDestination;
00324         MESSAGE_END();
00325 
00326         if(!fc->peer.addressExtension)
00327         {
00328             MESSAGE_SINGLE(NORMAL, this->logger, "Final destination reached, delivering to upper layer");
00329             getDeliverer()->getAcceptor(compound)->onData(compound);
00330             return true;
00331         } // end finalDestination is me
00332         if((layer2->getDLLAddress() == ps->getProxyFor(fc->peer.finalDestination)) ||
00333            (layer2->isTransceiverMAC(ps->getProxyFor(fc->peer.finalDestination))))
00334         {
00335             MESSAGE_SINGLE(NORMAL, this->logger, "finalDestination is proxied by me, delivering");
00336 
00337             dll::UpperCommand* copyUC;
00338             ForwardingCommand* copyFC;
00339             wns::ldk::CompoundPtr partialCompoundCopy = createForwardingCopy(compound, fc, copyFC, copyUC);
00340 
00341             sendFrameToOwnBSS(partialCompoundCopy, copyFC, copyUC, fc->peer.originalSource, fc->peer.finalDestination);
00342             return true;
00343         } // end finalDestination is proxied by me
00344 
00345         MESSAGE_SINGLE(NORMAL, this->logger, "finalDestination is not proxied by me -> unknown");
00346         return false;
00347     } // end meshDestination is me
00348     else
00349     {
00350         // I am not the meshDestination -> forward inside the mesh to
00351         // meshDestination if known
00352         MESSAGE_BEGIN(NORMAL, this->logger, m, "doOnData received frame from ");
00353         m << uc->peer.sourceMACAddress;
00354         m << " to be forwarded to mesh destination ";
00355         m << finalMeshDst;
00356         MESSAGE_END();
00357 
00358         --fc->peer.TTL;
00359         if(fc->peer.TTL == 0)
00360         {
00361             MESSAGE_SINGLE(NORMAL, this->logger, "TTL has reached zero, dropping frame");
00362             return true;
00363         } // end fc->TTL == 0
00364 
00365         dll::UpperCommand* copyUC;
00366         ForwardingCommand* copyFC;
00367         wns::ldk::CompoundPtr partialCompoundCopy = createForwardingCopy(compound, fc, copyFC, copyUC);
00368 
00369         copyFC->peer = fc->peer;
00370         copyUC->peer.sourceMACAddress = layer2->getDLLAddress();
00371         copyUC->peer.targetMACAddress = ps->getNextHop(copyUC->peer.sourceMACAddress, finalMeshDst);
00372         if(layer2->isTransceiverMAC(copyUC->peer.targetMACAddress))
00373         {
00374             // the next hop is simply to the own transceiver -> do one more hop
00375             MESSAGE_BEGIN(NORMAL, this->logger, m, "doOnDataFRS:");
00376             m << "next hop is own transceiver " << copyUC->peer.targetMACAddress;
00377             m << " -> one more hop to " << ps->getNextHop(copyUC->peer.targetMACAddress, finalMeshDst);
00378             MESSAGE_END();
00379 
00380             copyUC->peer.sourceMACAddress = copyUC->peer.targetMACAddress;
00381             copyUC->peer.targetMACAddress = ps->getNextHop(copyUC->peer.sourceMACAddress, finalMeshDst);
00382             copyFC->magic.path.push_back(copyUC->peer.sourceMACAddress);
00383         }
00384 
00385         if(!copyUC->peer.targetMACAddress.isValid())
00386         {
00387             MESSAGE_BEGIN(NORMAL, this->logger, m, "Path to meshDestination ");
00388             m << finalMeshDst;
00389             m << " is unknown -> drop frame";
00390             MESSAGE_END();
00391             return true;
00392         } // end no path found, drop
00393         else
00394         {
00395             MESSAGE_BEGIN(NORMAL, this->logger, m, "NextHop to meshDestination ");
00396             m << finalMeshDst;
00397             m << " is ";
00398             m << copyUC->peer.sourceMACAddress;
00399             m << " -> " << copyUC->peer.targetMACAddress;
00400             MESSAGE_END();
00401             getConnector()->getAcceptor(partialCompoundCopy)->sendData(partialCompoundCopy);
00402             return true;
00403         } // end path found, delivering
00404     } // end meshDestination is not me
00405 
00406 } // end doOnDataFRS
00407 
00408 void
00409 MeshForwarding::doSendData(const wns::ldk::CompoundPtr& compound)
00410 {
00411     // Received fresh packet from upper layer -> activate command
00412     ForwardingCommand* fc = activateCommand(compound->getCommandPool());
00413     fc->magic.path.push_back(layer2->getDLLAddress());
00414     // Get the upperCommand, which contains the final source and destination
00415     dll::UpperCommand* uc = getFUN()->getProxy()->getCommand<dll::UpperCommand>(compound->getCommandPool(), ucName);
00416 
00417     // this frame comes from the upperConvergence
00418     assure(uc->peer.sourceMACAddress.isValid(), "uc->peer.sourceMACAddress is not a valid MAC address");
00419 
00420     // locally generated traffic, destination not known
00421     if (not uc->peer.targetMACAddress.isValid())
00422     {
00423         uc->peer.targetMACAddress = ps->getPortalFor(uc->peer.sourceMACAddress);
00424     }
00425 
00426     fc->magic.isUplink = false;
00427 
00428     if (layer2->getControlService<dll::services::control::Association>("ASSOCIATION")
00429         ->hasAssociated(uc->peer.targetMACAddress))
00430     {
00431         MESSAGE_SINGLE(NORMAL, this->logger, "Destination " << uc->peer.targetMACAddress << " is directly associated -> deliver");
00432         sendFrameToOwnBSS(compound, fc, uc, uc->peer.sourceMACAddress, uc->peer.targetMACAddress);
00433         return;
00434     }
00435     else
00436     {
00437         if(ps->isMeshPoint(uc->peer.targetMACAddress))
00438         {
00439             assure(layer2->isTransceiverMAC(uc->peer.targetMACAddress) == false,
00440                    "Final destination is own transceiver MAC");
00441 
00442             MESSAGE_SINGLE(NORMAL, this->logger, "doSendDataAP: Destination " << uc->peer.targetMACAddress << " is known MP -> forward");
00443 
00444             assure((layer2->getStationType() != wns::service::dll::StationTypes::AP()) or
00445                    (ps->isPortal(ps->getNextHop(layer2->getDLLAddress(), uc->peer.targetMACAddress)) == false),
00446                    "AP cannot forward to an other portal --> RANG has used outdated configuration!");
00447 
00448             sendFrameToMP(compound, fc, uc, layer2->getDLLAddress(), uc->peer.targetMACAddress);
00449         } // end isMeshPoint
00450         else
00451         {
00452             sendFrameToOtherBSS(compound, fc, uc,
00453                                 layer2->getDLLAddress(),       // src
00454                                 layer2->getDLLAddress(),       // MeshSrc
00455                                 uc->peer.targetMACAddress);                                              // finalDst
00456             return;
00457         }
00458     } // end hasAssociated
00459 }
00460 
00461 void MeshForwarding::sendFrameToOwnBSS(const wns::ldk::CompoundPtr& compound,
00462                                        ForwardingCommand*& fc,
00463                                        dll::UpperCommand*& uc,
00464                                        wns::service::dll::UnicastAddress src,
00465                                        wns::service::dll::UnicastAddress dst)
00466 {
00467     assure(layer2->getControlService<dll::services::control::Association>("ASSOCIATION")->hasAssociated(dst),
00468            dst << " is not associated to me");
00469     assure(ps->getProxyFor(dst).isValid(), "Proxy for dst " << dst << " is unknown");
00470     assure(layer2->isTransceiverMAC(ps->getProxyFor(dst)),
00471            "Proxy " << ps->getProxyFor(dst) << " for dst " << dst << " is not a transceiver MAC");
00472 
00473     fc->peer.toDS = false;
00474     fc->peer.fromDS = true;
00475     fc->peer.originalSource = src;
00476     uc->peer.sourceMACAddress = ps->getProxyFor(dst);
00477     uc->peer.targetMACAddress = dst;
00478 
00479     getConnector()->getAcceptor(compound)->sendData(compound);
00480 }
00481 
00482 bool MeshForwarding::sendFrameToMP(const wns::ldk::CompoundPtr& compound,
00483                                    ForwardingCommand*& fc,
00484                                    dll::UpperCommand*& uc,
00485                                    wns::service::dll::UnicastAddress src,
00486                                    wns::service::dll::UnicastAddress mpDst)
00487 {
00488     assure(ps->isMeshPoint(mpDst), mpDst << " is not a known MP");
00489 
00490     fc->peer.TTL = dot11MeshTTL;
00491     fc->peer.toDS = true;
00492     fc->peer.fromDS = true;
00493     fc->peer.addressExtension = false;
00494     fc->peer.originalSource = src;
00495     fc->peer.finalDestination = mpDst;
00496     uc->peer.sourceMACAddress = layer2->getDLLAddress();
00497     uc->peer.targetMACAddress = ps->getNextHop(uc->peer.sourceMACAddress, mpDst);
00498 
00499     if(layer2->isTransceiverMAC(uc->peer.targetMACAddress))
00500     {
00501         // the next hop is simply to the own transceiver -> do one more hop
00502         MESSAGE_BEGIN(NORMAL, this->logger, m, "sendFrameToMP:");
00503         m << "next hop is own transceiver " << uc->peer.targetMACAddress;
00504         m << " -> one more hop to MP " << ps->getNextHop(uc->peer.targetMACAddress, mpDst);
00505         MESSAGE_END();
00506 
00507         uc->peer.sourceMACAddress = uc->peer.targetMACAddress;
00508         uc->peer.targetMACAddress = ps->getNextHop(uc->peer.sourceMACAddress, mpDst);
00509 
00510         fc->magic.path.push_back(uc->peer.sourceMACAddress);
00511     }
00512     if(!uc->peer.targetMACAddress.isValid())
00513     {
00514         MESSAGE_SINGLE(NORMAL, this->logger, "sendFrameToMP: finalDestination address " << mpDst << "unknown -> drop");
00515         return false;
00516     }
00517 
00518     MESSAGE_SINGLE(NORMAL, this->logger, "sendFrameToMP: Forward to " << uc->peer.targetMACAddress);
00519     
00520     getConnector()->getAcceptor(compound)->sendData(compound);
00521     return true;
00522 }
00523 
00524 bool MeshForwarding::sendFrameToOtherBSS(const wns::ldk::CompoundPtr& compound,
00525                                          ForwardingCommand*& fc,
00526                                          dll::UpperCommand*& uc,
00527                                          wns::service::dll::UnicastAddress src,
00528                                          wns::service::dll::UnicastAddress meshSrc,
00529                                          wns::service::dll::UnicastAddress dst)
00530 {
00531     fc->peer.TTL = dot11MeshTTL;
00532     fc->peer.toDS = true;
00533     fc->peer.fromDS = true;
00534     fc->peer.addressExtension = true;
00535     fc->peer.originalSource = src;
00536     fc->peer.meshSource = meshSrc;
00537     fc->peer.meshDestination = ps->getProxyFor(dst);
00538 
00539     if(!fc->peer.meshDestination.isValid())
00540     {
00541         MESSAGE_SINGLE(NORMAL, this->logger, "sendFrameToOtherBSS: proxy for " << dst << "unknown -> drop");
00542         return false;
00543     }
00544 
00545     fc->peer.finalDestination = dst;
00546 
00547     uc->peer.sourceMACAddress = layer2->getDLLAddress();
00548     uc->peer.targetMACAddress = ps->getNextHop(uc->peer.sourceMACAddress, dst);
00549 
00550     if(layer2->isTransceiverMAC(uc->peer.targetMACAddress))
00551     {
00552         // the next hop is simply to the own transceiver -> do one more hop
00553         MESSAGE_BEGIN(NORMAL, this->logger, m, "sendFrameToOtherBSS:");
00554         m << "next hop is own transceiver " << uc->peer.targetMACAddress;
00555         m << " -> one more hop to MP " << ps->getNextHop(uc->peer.targetMACAddress, dst);
00556         MESSAGE_END();
00557 
00558         uc->peer.sourceMACAddress = uc->peer.targetMACAddress;
00559         uc->peer.targetMACAddress = ps->getNextHop(uc->peer.sourceMACAddress, dst);
00560 
00561         fc->magic.path.push_back(uc->peer.sourceMACAddress);
00562     }
00563     if(!uc->peer.targetMACAddress.isValid())
00564     {
00565         MESSAGE_SINGLE(NORMAL, this->logger, "sendFrameToMP: finalDestination address " << dst << "unknown -> drop");
00566         return false;
00567     }
00568 
00569     MESSAGE_SINGLE(NORMAL, this->logger, "daSendDataAP: Forward to " << uc->peer.targetMACAddress);
00570     getConnector()->getAcceptor(compound)->sendData(compound);
00571     return true;
00572 }
00573 
00574 wns::ldk::CompoundPtr
00575 MeshForwarding::createForwardingCopy(const wns::ldk::CompoundPtr& compound,
00576                                      ForwardingCommand* originalFC,
00577                                      ForwardingCommand*& copyFC,
00578                                      dll::UpperCommand*& copyUC)
00579 {
00580     wns::ldk::CommandPool* copyCommandPool = getFUN()->getProxy()->createCommandPool();
00581     getFUN()->getProxy()->partialCopy(this, copyCommandPool, compound->getCommandPool());
00582     wns::ldk::CompoundPtr partialCompoundCopy(new wns::ldk::Compound(copyCommandPool, compound->getData()));
00583 
00584     copyUC = getFUN()->getProxy()->getCommand<dll::UpperCommand>(partialCompoundCopy->getCommandPool(), ucName);
00585     copyFC = activateCommand(partialCompoundCopy->getCommandPool());
00586     copyFC->magic = originalFC->magic;
00587 
00588     return(partialCompoundCopy);
00589 }
00590 
00591 void
00592 MeshForwarding::printForwardingInformation(ForwardingCommand* fc, dll::UpperCommand* uc) const
00593 {
00594     MESSAGE_BEGIN(NORMAL, this->logger, m, "Compound with fromDS " << fc->peer.fromDS << " toDS " << fc->peer.toDS << ":");
00595     if(fc->peer.fromDS == true)
00596     {
00597         m << " " << fc->peer.originalSource << " ->";
00598     }
00599     if(fc->peer.addressExtension == true)
00600     {
00601         m << " " << fc->peer.meshSource << " ->";
00602     }
00603     m << " " << uc->peer.sourceMACAddress << " -> " << uc->peer.targetMACAddress << " -> ";
00604     if(fc->peer.addressExtension == true)
00605     {
00606         m << " " << fc->peer.meshDestination << " ->";
00607     }
00608     if(fc->peer.toDS == true)
00609     {
00610         m << fc->peer.finalDestination;
00611     }
00612     m << "; hc: " << fc->magic.hopCount;
00613 
00614     m << "\nFull path:";
00615     for (unsigned int hop = 0; hop < fc->magic.path.size(); hop++)
00616     {
00617         m << " " << fc->magic.path[hop];
00618     }
00619 
00620     if(((fc->peer.fromDS == true) &&
00621         (fc->peer.originalSource == layer2->getDLLAddress()))
00622        ||
00623        ((fc->peer.addressExtension == true) &&
00624         (fc->peer.meshSource == layer2->getDLLAddress())))
00625     {
00626         // We have a loop in the path, which may occur e.g. due to
00627         // pathselection-table changes during the transmission process.
00628         m << "\nThere is a loop in the path!";
00629     }
00630 
00631     MESSAGE_END();
00632 }

Generated on Fri May 25 03:32:14 2012 for openWNS by  doxygen 1.5.5