void LinkControlHelper::setErrorRate(Ptr<Node> node1, Ptr<Node> node2, double errorRate) { NS_LOG_FUNCTION(node1 << node2 << errorRate); NS_ASSERT(node1 != nullptr && node2 != nullptr); NS_ASSERT(errorRate <= 1.0); Ptr<ndn::L3Protocol> ndn1 = node1->GetObject<ndn::L3Protocol>(); Ptr<ndn::L3Protocol> ndn2 = node2->GetObject<ndn::L3Protocol>(); NS_ASSERT(ndn1 != nullptr && ndn2 != nullptr); // iterate over all faces to find the right one for (const auto& face : ndn1->getForwarder()->getFaceTable()) { auto transport = dynamic_cast<NetDeviceTransport*>(face.getTransport()); if (transport == nullptr) continue; Ptr<PointToPointNetDevice> nd1 = transport->GetNetDevice()->GetObject<PointToPointNetDevice>(); if (nd1 == nullptr) continue; Ptr<Channel> channel = nd1->GetChannel(); if (channel == nullptr) continue; Ptr<PointToPointChannel> ppChannel = DynamicCast<PointToPointChannel>(channel); Ptr<NetDevice> nd2 = ppChannel->GetDevice(0); if (nd2->GetNode() == node1) nd2 = ppChannel->GetDevice(1); if (nd2->GetNode() == node2) { ObjectFactory errorFactory("ns3::RateErrorModel"); errorFactory.Set("ErrorUnit", StringValue("ERROR_UNIT_PACKET")); errorFactory.Set("ErrorRate", DoubleValue(errorRate)); if (errorRate <= 0) { errorFactory.Set("IsEnabled", BooleanValue(false)); } nd1->SetAttribute("ReceiveErrorModel", PointerValue(errorFactory.Create<ErrorModel>())); nd2->SetAttribute("ReceiveErrorModel", PointerValue(errorFactory.Create<ErrorModel>())); return; } } NS_FATAL_ERROR("There is no link to fail between the requested nodes"); }
int main(int argc, char* argv[]) { // setting default parameters for PointToPoint links and channels Config::SetDefault("ns3::PointToPointNetDevice::DataRate", StringValue("1Mbps")); Config::SetDefault("ns3::PointToPointChannel::Delay", StringValue("10ms")); Config::SetDefault("ns3::DropTailQueue::MaxPackets", StringValue("20")); // Read optional command-line parameters (e.g., enable visualizer with ./waf --run=<> --visualize CommandLine cmd; cmd.Parse(argc, argv); ofstream file1("/tmp/topo1.txt"); file1 << "router\n\n" << "#node city y x mpi-partition\n" << "A1 NA 1 1 1\n" << "B1 NA 80 -40 1\n" << "C1 NA 80 40 1\n" << "A2 NA 1 1 1\n" << "B2 NA 80 -40 1\n" << "C2 NA 80 40 1\n\n" << "link\n\n" << "# from to capacity metric delay queue\n" << "A1 B1 10Mbps 100 1ms 100\n" << "A1 C1 10Mbps 50 1ms 100\n" << "B1 C1 10Mbps 1 1ms 100\n" << "A2 B2 10Mbps 50 1ms 100\n" << "A2 C2 10Mbps 100 1ms 100\n" << "B2 C2 10Mbps 1 1ms 100\n"; file1.close(); AnnotatedTopologyReader topologyReader(""); topologyReader.SetFileName("/tmp/topo1.txt"); topologyReader.Read(); // Install NDN stack on all nodes ndn::StackHelper ndnHelper; ndnHelper.InstallAll(); topologyReader.ApplyOspfMetric(); ndn::GlobalRoutingHelper ndnGlobalRoutingHelper; ndnGlobalRoutingHelper.InstallAll(); ndnGlobalRoutingHelper.AddOrigins("/test/prefix", Names::Find<Node>("C1")); ndnGlobalRoutingHelper.AddOrigins("/test/prefix", Names::Find<Node>("C2")); ndn::GlobalRoutingHelper::CalculateRoutes(); auto printFib = [](Ptr<Node> node) { auto ndn = node->GetObject<ndn::L3Protocol>(); for (const auto& entry : ndn->getForwarder()->getFib()) { cout << entry.getPrefix() << " ("; bool isFirst = true; for (auto& nextHop : entry.getNextHops()) { cout << *nextHop.getFace(); auto face = dynamic_pointer_cast<ndn::NetDeviceFace>(nextHop.getFace()); if (face == nullptr) continue; cout << " towards "; if (!isFirst) cout << ", "; cout << Names::FindName(face->GetNetDevice()->GetChannel()->GetDevice(1)->GetNode()); isFirst = false; } cout << ")" << endl; } }; cout << "FIB content on node A1" << endl; printFib(Names::Find<Node>("A1")); cout << "FIB content on node A2" << endl; printFib(Names::Find<Node>("A2")); Simulator::Stop(Seconds(20.0)); Simulator::Run(); Simulator::Destroy(); return 0; }