371 //m_routingInfoCallback (newInfo); |
369 //m_routingInfoCallback (newInfo); |
372 //chack if must retransmit: |
370 //chack if must retransmit: |
373 if (preq.GetDestCount () == 0) |
371 if (preq.GetDestCount () == 0) |
374 return; |
372 return; |
375 //Forward PREQ to all interfaces: |
373 //Forward PREQ to all interfaces: |
376 NS_LOG_UNCOND("I am "<<m_address<<"retransmitting PREQ:"<<preq); |
374 NS_LOG_DEBUG("I am "<<m_address<<"retransmitting PREQ:"<<preq); |
377 for(HwmpPluginMap::iterator i = m_interfaces.begin (); i != m_interfaces.end (); i ++) |
375 for(HwmpPluginMap::iterator i = m_interfaces.begin (); i != m_interfaces.end (); i ++) |
378 i->second->SendPreq (preq); |
376 i->second->SendPreq (preq); |
379 } |
377 } |
380 void |
378 void |
381 HwmpProtocol::ReceivePrep (IePrep prep, Mac48Address from, uint32_t interface) |
379 HwmpProtocol::ReceivePrep (IePrep prep, Mac48Address from, uint32_t interface) |
382 { |
380 { |
383 prep.IncrementMetric (1); |
381 prep.IncrementMetric (1); |
384 //acceptance cretirea: |
382 //acceptance cretirea: |
385 NS_LOG_UNCOND("I am "<<m_address<<", received prep"); |
383 NS_LOG_DEBUG("I am "<<m_address<<", received prep"); |
386 std::map<Mac48Address, uint32_t>::iterator i = m_lastHwmpSeqno.find (prep.GetOriginatorAddress()); |
384 std::map<Mac48Address, uint32_t>::iterator i = m_lastHwmpSeqno.find (prep.GetOriginatorAddress()); |
387 if (i == m_lastHwmpSeqno.end ()) |
385 if (i == m_lastHwmpSeqno.end ()) |
388 { |
386 { |
389 m_lastHwmpSeqno[prep.GetOriginatorAddress ()] = prep.GetOriginatorSeqNumber(); |
387 m_lastHwmpSeqno[prep.GetOriginatorAddress ()] = prep.GetOriginatorSeqNumber(); |
390 } |
388 } |
406 HwmpRtable::LookupResult result = m_rtable->LookupReactive(prep.GetDestinationAddress()); |
404 HwmpRtable::LookupResult result = m_rtable->LookupReactive(prep.GetDestinationAddress()); |
407 if (result.retransmitter == Mac48Address::GetBroadcast ()) |
405 if (result.retransmitter == Mac48Address::GetBroadcast ()) |
408 //try to look for default route |
406 //try to look for default route |
409 result = m_rtable->LookupProactive (); |
407 result = m_rtable->LookupProactive (); |
410 if (result.retransmitter == Mac48Address::GetBroadcast ()) |
408 if (result.retransmitter == Mac48Address::GetBroadcast ()) |
411 { |
|
412 NS_LOG_UNCOND("I am "<<m_address<<", can not forward prep"); |
|
413 return; |
409 return; |
414 } |
|
415 m_rtable->AddPrecursor (prep.GetOriginatorAddress (), interface, result.retransmitter); |
410 m_rtable->AddPrecursor (prep.GetOriginatorAddress (), interface, result.retransmitter); |
416 //Forward PREP |
411 //Forward PREP |
417 HwmpPluginMap::iterator prep_sender = m_interfaces.find (result.ifIndex); |
412 HwmpPluginMap::iterator prep_sender = m_interfaces.find (result.ifIndex); |
418 NS_ASSERT(prep_sender != m_interfaces.end ()); |
413 NS_ASSERT(prep_sender != m_interfaces.end ()); |
419 prep_sender->second->SendPrep(prep, result.retransmitter); |
414 prep_sender->second->SendPrep(prep, result.retransmitter); |
421 } |
416 } |
422 void |
417 void |
423 HwmpProtocol::ReceivePerr (IePerr perr, Mac48Address from, uint32_t interface) |
418 HwmpProtocol::ReceivePerr (IePerr perr, Mac48Address from, uint32_t interface) |
424 { |
419 { |
425 //Acceptance cretirea: |
420 //Acceptance cretirea: |
426 NS_LOG_UNCOND("I am "<<m_address<<", received PERR from "<<from); |
421 NS_LOG_DEBUG("I am "<<m_address<<", received PERR from "<<from); |
427 std::vector<IePerr::FailedDestination> destinations = perr.GetAddressUnitVector (); |
422 std::vector<IePerr::FailedDestination> destinations = perr.GetAddressUnitVector (); |
428 HwmpRtable::LookupResult result; |
423 HwmpRtable::LookupResult result; |
429 for(unsigned int i = 0; i < destinations.size (); i ++) |
424 for(unsigned int i = 0; i < destinations.size (); i ++) |
430 { |
425 { |
431 result = m_rtable->LookupReactive (destinations[i].destination); |
426 result = m_rtable->LookupReactive (destinations[i].destination); |
432 NS_LOG_UNCOND("Destination = "<<destinations[i].destination<<", RA = "<<result.retransmitter); |
427 NS_LOG_DEBUG("Destination = "<<destinations[i].destination<<", RA = "<<result.retransmitter); |
433 if ( |
428 if ( |
434 (result.retransmitter != from) || |
429 (result.retransmitter != from) || |
435 (result.ifIndex != interface) || |
430 (result.ifIndex != interface) || |
436 (result.seqnum > destinations[i].seqnum) |
431 (result.seqnum > destinations[i].seqnum) |
437 ) |
432 ) |
454 uint32_t originatorDsn, |
450 uint32_t originatorDsn, |
455 uint32_t destinationSN, |
451 uint32_t destinationSN, |
456 uint32_t lifetime, |
452 uint32_t lifetime, |
457 uint32_t interface) |
453 uint32_t interface) |
458 { |
454 { |
459 NS_LOG_UNCOND("sending prep to "<<dst<<" through "<<retransmitter); |
|
460 IePrep prep; |
455 IePrep prep; |
461 prep.SetHopcount (0); |
456 prep.SetHopcount (0); |
462 prep.SetTtl (m_maxTtl); |
457 prep.SetTtl (m_maxTtl); |
463 prep.SetDestinationAddress (dst); |
458 prep.SetDestinationAddress (dst); |
464 prep.SetDestinationSeqNumber (destinationSN); |
459 prep.SetDestinationSeqNumber (destinationSN); |
492 mac->InstallPlugin (hwmpMac); |
487 mac->InstallPlugin (hwmpMac); |
493 } |
488 } |
494 mp->SetRoutingProtocol (this); |
489 mp->SetRoutingProtocol (this); |
495 // Mesh point aggregates all installed protocols |
490 // Mesh point aggregates all installed protocols |
496 mp->AggregateObject (this); |
491 mp->AggregateObject (this); |
497 //Address tmp_addr = mp->GetAddress (); |
|
498 //Mac48Address * address = dynamic_cast<Mac48Address *> (&tmp_addr); |
|
499 //if (address == NULL) |
|
500 // return false; |
|
501 m_address = Mac48Address::ConvertFrom (mp->GetAddress ());//* address; |
492 m_address = Mac48Address::ConvertFrom (mp->GetAddress ());//* address; |
502 return true; |
493 return true; |
503 } |
494 } |
504 void |
495 void |
505 HwmpProtocol::PeerLinkStatus(Mac48Address peerAddress, uint32_t interface, bool status) |
496 HwmpProtocol::PeerLinkStatus(Mac48Address peerAddress, uint32_t interface, bool status) |
506 { |
497 { |
507 if(status) |
498 if(status) |
508 { |
499 m_rtable->AddReactivePath(peerAddress, peerAddress, interface, 1, Seconds (0), 0); |
509 // m_rtable->AddReactivePath(peerAddress, peerAddress, interface, 1, Seconds (0), 0); |
|
510 } |
|
511 else |
500 else |
512 { |
501 { |
513 std::vector<IePerr::FailedDestination> destinations = m_rtable->GetUnreachableDestinations (peerAddress); |
502 std::vector<IePerr::FailedDestination> destinations = m_rtable->GetUnreachableDestinations (peerAddress); |
514 MakePathError (destinations); |
503 MakePathError (destinations); |
515 } |
504 } |
531 return true; |
520 return true; |
532 m_lastDataSeqno[source] = seqno; |
521 m_lastDataSeqno[source] = seqno; |
533 } |
522 } |
534 return false; |
523 return false; |
535 } |
524 } |
536 |
|
537 #if 0 |
|
538 void |
|
539 HwmpProtocol::ObtainRoutingInformation ( |
|
540 HwmpProtocolState::INFO info |
|
541 ) |
|
542 { |
|
543 switch (info.type) |
|
544 { |
|
545 case HwmpProtocolState::INFO_PREP: |
|
546 if (info.me != info.source) |
|
547 { |
|
548 m_rtable->AddPrecursor (info.source, info.outPort, info.nextHop); |
|
549 m_rtable->AddPrecursor (info.destination, info.outPort, info.prevHop); |
|
550 NS_LOG_DEBUG ("path to "<<info.source<<" precursor is "<<info.nextHop); |
|
551 NS_LOG_DEBUG ("path to "<<info.destination<<" precursor is "<<info.prevHop); |
|
552 } |
|
553 case HwmpProtocolState::INFO_PREQ: |
|
554 m_rtable->AddReactivePath ( |
|
555 info.destination, |
|
556 info.nextHop, |
|
557 info.outPort, |
|
558 info.metric, |
|
559 info.lifetime, |
|
560 info.dsn); |
|
561 SendAllPossiblePackets (info.destination); |
|
562 break; |
|
563 case HwmpProtocolState::INFO_PERR: |
|
564 //delete first subentry |
|
565 case HwmpProtocolState::INFO_PROACTIVE: |
|
566 //add information to the root MP. |
|
567 m_rtable->AddProactivePath ( |
|
568 info.metric, |
|
569 info.destination, |
|
570 info.nextHop, |
|
571 info.outPort, |
|
572 info.lifetime, |
|
573 info.dsn); |
|
574 //Set mode as PROACTIVE: |
|
575 SetProactive (info.outPort); |
|
576 break; |
|
577 case HwmpProtocolState::INFO_NEW_PEER: |
|
578 #if 0 |
|
579 m_rtable->AddReactivePath ( |
|
580 info.destination, |
|
581 info.nextHop, |
|
582 info.outPort, |
|
583 info.metric, |
|
584 Seconds (0), |
|
585 0); |
|
586 #endif |
|
587 break; |
|
588 case HwmpProtocolState::INFO_FAILED_PEER: |
|
589 /** |
|
590 * Conditions for generating PERR |
|
591 */ |
|
592 { |
|
593 NS_LOG_DEBUG ("Failed peer"<<info.destination); |
|
594 std::vector<HwmpRtable::FailedDestination> failedDestinations = |
|
595 m_rtable->GetUnreachableDestinations (info.destination, info.outPort); |
|
596 /** |
|
597 * Entry about peer does not contain seqnum |
|
598 */ |
|
599 HwmpRtable::FailedDestination peer; |
|
600 peer.destination = info.destination; |
|
601 peer.seqnum = 0; |
|
602 failedDestinations.push_back (peer); |
|
603 MakePathError (failedDestinations, info.outPort); |
|
604 } |
|
605 break; |
|
606 default: |
|
607 return; |
|
608 } |
|
609 } |
|
610 #endif |
|
611 void |
525 void |
612 HwmpProtocol::MakePathError (std::vector<IePerr::FailedDestination> destinations) |
526 HwmpProtocol::MakePathError (std::vector<IePerr::FailedDestination> destinations) |
613 { |
527 { |
614 NS_LOG_UNCOND ("START PERR, I am "<<m_address); |
|
615 //TODO: |
|
616 //make a perr IE and send |
|
617 //HwmpRtable increments a sequence number as written in 11B.9.7.2 |
528 //HwmpRtable increments a sequence number as written in 11B.9.7.2 |
618 NS_LOG_UNCOND("Number of unreachable destinations:"<<destinations.size ()); |
|
619 for(std::vector<IePerr::FailedDestination>::iterator i = destinations.begin (); i != destinations.end (); i ++) |
|
620 { |
|
621 HwmpRtable::LookupResult result = m_rtable->LookupReactiveExpired (i->destination); |
|
622 NS_LOG_UNCOND("Address::"<<i->destination<<", next hop is "<<result.retransmitter); |
|
623 } |
|
624 std::vector<std::pair<uint32_t, Mac48Address> > receivers = GetPerrReceivers (destinations); |
529 std::vector<std::pair<uint32_t, Mac48Address> > receivers = GetPerrReceivers (destinations); |
625 NS_LOG_UNCOND("Number of perr receivers:"<<receivers.size ()); |
|
626 if(receivers.size () == 0) |
530 if(receivers.size () == 0) |
627 return; |
531 return; |
628 for(std::vector<std::pair<uint32_t, Mac48Address> >::iterator i = receivers.begin (); i != receivers.end (); i ++) |
|
629 NS_LOG_UNCOND("Address:"<<i->second<<", interface:"<<i->first); |
|
630 //form a path error and send it to proper ports |
|
631 IePerr perr; |
532 IePerr perr; |
632 for(unsigned int i = 0; i < destinations.size (); i ++) |
533 for(unsigned int i = 0; i < destinations.size (); i ++) |
633 { |
534 { |
634 perr.AddAddressUnit(destinations[i]); |
535 perr.AddAddressUnit(destinations[i]); |
635 m_rtable->DeleteReactivePath(destinations[i].destination); |
536 m_rtable->DeleteReactivePath(destinations[i].destination); |
640 for(unsigned int j = 0; j < receivers.size(); j ++) |
541 for(unsigned int j = 0; j < receivers.size(); j ++) |
641 if(i->first == receivers[j].first) |
542 if(i->first == receivers[j].first) |
642 receivers_for_interface.push_back(receivers[j].second); |
543 receivers_for_interface.push_back(receivers[j].second); |
643 i->second->SendOnePerr (perr, receivers_for_interface); |
544 i->second->SendOnePerr (perr, receivers_for_interface); |
644 } |
545 } |
645 |
|
646 } |
546 } |
647 std::vector<std::pair<uint32_t, Mac48Address> > |
547 std::vector<std::pair<uint32_t, Mac48Address> > |
648 HwmpProtocol::GetPerrReceivers (std::vector<IePerr::FailedDestination> failedDest) |
548 HwmpProtocol::GetPerrReceivers (std::vector<IePerr::FailedDestination> failedDest) |
649 { |
549 { |
650 HwmpRtable::PrecursorList retval; |
550 HwmpRtable::PrecursorList retval; |
655 m_rtable->DeleteProactivePath(failedDest[i].destination); |
555 m_rtable->DeleteProactivePath(failedDest[i].destination); |
656 for (unsigned int j = 0; j < precursors.size (); j ++) |
556 for (unsigned int j = 0; j < precursors.size (); j ++) |
657 retval.push_back(precursors[j]); |
557 retval.push_back(precursors[j]); |
658 } |
558 } |
659 //Check if we have dublicates in retval and precursors: |
559 //Check if we have dublicates in retval and precursors: |
660 unsigned int size = retval.size(); |
560 for (unsigned int i = 0; i < retval.size(); i ++) |
661 for (unsigned int i = 0; i < size; i ++) |
561 for (unsigned int j = i; j < retval.size(); j ++) |
662 for (unsigned int j = i; j < size; j ++) |
|
663 if(retval[i].second == retval[j].second) |
562 if(retval[i].second == retval[j].second) |
664 { |
|
665 //erase and check size |
|
666 NS_LOG_UNCOND("deleting dublicate"); |
|
667 retval.erase(retval.begin() + j); |
563 retval.erase(retval.begin() + j); |
668 size --; |
|
669 } |
|
670 return retval; |
564 return retval; |
671 } |
565 } |
672 std::vector<Mac48Address> |
566 std::vector<Mac48Address> |
673 HwmpProtocol::GetPreqReceivers (uint32_t interface) |
567 HwmpProtocol::GetPreqReceivers (uint32_t interface) |
674 { |
568 { |
760 HwmpProtocol::ShouldSendPreq (Mac48Address dst) |
654 HwmpProtocol::ShouldSendPreq (Mac48Address dst) |
761 { |
655 { |
762 std::map<Mac48Address, EventId>::iterator i = m_preqTimeouts.find (dst); |
656 std::map<Mac48Address, EventId>::iterator i = m_preqTimeouts.find (dst); |
763 if (i == m_preqTimeouts.end ()) |
657 if (i == m_preqTimeouts.end ()) |
764 { |
658 { |
765 NS_LOG_UNCOND("Timeout is:" <<2*(m_dot11MeshHWMPnetDiameterTraversalTime.GetMilliSeconds())); |
|
766 m_preqTimeouts[dst] = Simulator::Schedule ( |
659 m_preqTimeouts[dst] = Simulator::Schedule ( |
767 MilliSeconds (2*(m_dot11MeshHWMPnetDiameterTraversalTime.GetMilliSeconds())), |
660 MilliSeconds (2*(m_dot11MeshHWMPnetDiameterTraversalTime.GetMilliSeconds())), |
768 &HwmpProtocol::RetryPathDiscovery, this, dst, 0); |
661 &HwmpProtocol::RetryPathDiscovery, this, dst, 0); |
769 return true; |
662 return true; |
770 } |
663 } |
799 NS_ASSERT (i != m_preqTimeouts.end()); |
692 NS_ASSERT (i != m_preqTimeouts.end()); |
800 m_preqTimeouts.erase (i); |
693 m_preqTimeouts.erase (i); |
801 return; |
694 return; |
802 } |
695 } |
803 for(HwmpPluginMap::iterator i = m_interfaces.begin (); i != m_interfaces.end (); i ++) |
696 for(HwmpPluginMap::iterator i = m_interfaces.begin (); i != m_interfaces.end (); i ++) |
804 { |
|
805 i->second->RequestDestination(dst); |
697 i->second->RequestDestination(dst); |
806 i->second->RequestDestination(Mac48Address("00:00:00:00:00:10")); |
|
807 i->second->RequestDestination(Mac48Address("00:00:00:00:00:24")); |
|
808 } |
|
809 m_preqTimeouts[dst] = Simulator::Schedule ( |
698 m_preqTimeouts[dst] = Simulator::Schedule ( |
810 MilliSeconds (2*(m_dot11MeshHWMPnetDiameterTraversalTime.GetMilliSeconds())), |
699 MilliSeconds (2*(m_dot11MeshHWMPnetDiameterTraversalTime.GetMilliSeconds())), |
811 &HwmpProtocol::RetryPathDiscovery, this, dst, numOfRetry); |
700 &HwmpProtocol::RetryPathDiscovery, this, dst, numOfRetry); |
812 } |
701 } |
813 //Proactive PREQ routines: |
702 //Proactive PREQ routines: |