![]() |
User Manual, Developers Guide and API Documentation |
![]() |
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 }
1.5.5