27 std::vector<SwapSessionSpec> out;
31 auto rvJitter = ns3::CreateObject<ns3::UniformRandomVariable>();
32 rvJitter->SetStream(
static_cast<int64_t
>(topo.
rounds.
seed));
41 for (
const auto& s : topo.
sessions) {
49 out.emplace_back(std::move(copy));
71 bool useIpv6, uint32_t ctrlPayloadBytes) {
72 NS_ASSERT_MSG(
m_nc !=
nullptr,
"EntanglementSwapHelper requires NetController");
77 std::unique_ptr<ISwapPolicy> localDefault;
80 localDefault = std::make_unique<AllAtOncePolicy>();
81 policy = localDefault.get();
87 NS_LOG_INFO(
"SwapHelper: installation done (" << planned.size() <<
" sessions).");
144 uint32_t ctrlPayloadBytes) {
147 auto getV4 = [&](
const std::string& name) -> ns3::Ipv4Address {
148 auto it = net.
nodes.find(name);
149 if (it == net.
nodes.end() || it->second.v4Addrs.empty())
150 return ns3::Ipv4Address(
"0.0.0.0");
151 return it->second.v4Addrs.front();
153 auto getV6 = [&](
const std::string& name) -> ns3::Ipv6Address {
154 auto it = net.
nodes.find(name);
155 if (it == net.
nodes.end() || it->second.v6Addrs.empty())
156 return ns3::Ipv6Address::GetAny();
157 return it->second.v6Addrs.front();
161 kv.second->SetPayloadBytes(ctrlPayloadBytes);
162 kv.second->SetUseIpv6(useIpv6);
165 for (
const auto& sess : planned) {
166 if (sess.path.size() < 2)
169 const uint16_t port = sess.ctrlPort ? sess.ctrlPort :
AllocatePort(sess.sessionId);
170 const auto& Aname = sess.path.front();
171 const auto& Bname = sess.path.back();
173 const auto addrA_v4 = getV4(Aname);
174 const auto addrB_v4 = getV4(Bname);
175 const auto addrA_v6 = getV6(Aname);
176 const auto addrB_v6 = getV6(Bname);
178 const uint32_t kRepeaters =
179 sess.path.size() >= 2 ?
static_cast<uint32_t
>(sess.path.size() - 2) : 0;
185 cfg.
sid = sess.sessionId;
187 cfg.applyCorrections =
false;
188 cfg.start = Seconds(sess.start_s);
189 cfg.proto = sess.protocol;
191 cfg.expectedMsgs = kRepeaters;
192 cfg.verifyFidelity =
true;
193 cfg.verifyThreshold = 0.99;
196 auto nextNode = ns3::DynamicCast<q2ns::QNode>(
m_name2node.at(sess.path[1]));
198 cfg.nextPeerId = nextNode->GetId();
200 appA->AddSession(cfg);
207 cfg.
sid = sess.sessionId;
209 cfg.applyCorrections =
true;
210 cfg.start = Seconds(sess.start_s);
211 cfg.proto = sess.protocol;
213 cfg.expectedMsgs = kRepeaters;
214 cfg.verifyFidelity =
true;
215 cfg.verifyThreshold = 0.99;
216 appB->AddSession(cfg);
220 for (
size_t i = 1; i + 1 < sess.path.size(); ++i) {
221 auto Rname = sess.path[i];
224 auto prevNode = ns3::DynamicCast<q2ns::QNode>(
m_name2node.at(sess.path[i - 1]));
225 auto nextNode = ns3::DynamicCast<q2ns::QNode>(
m_name2node.at(sess.path[i + 1]));
228 cfg.
sid = sess.sessionId;
230 cfg.applyCorrections =
false;
231 cfg.start = Seconds(sess.start_s);
232 cfg.proto = sess.protocol;
234 cfg.prevPeerId = prevNode->GetId();
235 cfg.nextPeerId = nextNode->GetId();
239 cfg.prevEndAddr6 = addrA_v6;
240 cfg.nextEndAddr6 = addrB_v6;
242 cfg.prevEndAddr = addrA_v4;
243 cfg.nextEndAddr = addrB_v4;
246 appR->AddSession(cfg);