A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
qcen-control.cc
Go to the documentation of this file.
1/*
2 * Copyright(c) 2022 DOTFEESA www.tk.etf.unsa.ba
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 *
7 *
8 * Authors: Emir Dervisevic <emir.dervisevic@etf.unsa.ba>
9 * Miralem Mehic <miralem.mehic@ieee.org>
10 */
11
12#include <string>
13#include <queue>
14
15#include <cmath>
16#include <algorithm>
17#include <numeric>
18#include "ns3/packet.h"
19#include "ns3/simulator.h"
20#include "ns3/log.h"
21#include "ns3/boolean.h"
22#include "ns3/double.h"
23#include "ns3/uinteger.h"
24
25#include "qcen-control.h"
26//#include "ns3/qkd-control.h"
27//#include "ns3/qkd-control-container.h"
28//#include "ns3/qkd-location-register-entry.h"
29
30namespace ns3 {
31
32 NS_LOG_COMPONENT_DEFINE("QCenController");
33
34 TypeId
36 {
37 static TypeId tid = TypeId("ns3::QCenController")
40 ;
41 return tid;
42 }
43
48
50 {
51 NS_LOG_FUNCTION(this);
52
54 //Code adjusted from: https://www.srcmake.com/home/cpp-shortest-path-dijkstra
55 for(size_t i = 0; i < controllers.size(); i++)
56 {
57 // Create a vector to represent a row, and add it to the adjList.
58 std::vector<std::pair<uint32_t, uint32_t> > row;
59 m_adjList.push_back(row);
60 }
61
62 //Read inputs into sorted map entries where key is KMNodeId and value is QKDControl
63 for(auto el : controllers)
64 m_controllers.insert(std::make_pair(el->GetLocalKMNodeId(), el));
65 //Algorithm uses nodes from 0 to size. Our nodes have other numbers!
66 //We use this map to transit from position(0 to size) to actual node Id
67
69 NS_ASSERT(elNum != 0);
70 }
71
76
77 void
79 {
80 NS_LOG_FUNCTION(this);
81
83 //Code adjusted from: https://www.srcmake.com/home/cpp-shortest-path-dijkstra
84 for(size_t i = 0; i < controllers.size(); i++)
85 {
86 // Create a vector to represent a row, and add it to the adjList.
87 std::vector<std::pair<uint32_t, uint32_t> > row;
88 m_adjList.push_back(row);
89 }
90
91 //Read inputs into sorted map entries where key is KMNodeId and value is QKDControl
92 for(auto el : controllers)
93 m_controllers.insert(std::make_pair(el->GetLocalKMNodeId(), el));
94 //Algorithm uses nodes from 0 to size. Our nodes have other numbers!
95 //We use this map to transit from position(0 to size) to actual node Id
96
98 NS_ASSERT(elNum != 0);
99
100
101 //We use are automated procedure to fill adjList!
102 uint32_t row = 0;
103 for(auto const& el : m_controllers) //For each controller
104 {
105 NS_LOG_FUNCTION(this << "KMNodeId: " << el.first << "Row: " << row);
106 //Get connecting remote KM node IDs
107 std::vector<uint32_t> remoteKmNodeIds = el.second->GetRemoteKmNodeIds();
108 //Go through all remote KM node IDs and fill the graph
109 for(auto const& kmNodeId : remoteKmNodeIds)
110 {
111 NS_LOG_FUNCTION(this << "Connected to: " << kmNodeId << "Column: " << GetColumn(kmNodeId));
112 m_adjList[row].emplace_back(GetColumn(kmNodeId), 100u); //weight is set to 100 for all links, as they are down
113 }
114
115 ++row;
116 }
117
119 }
120
121 void
123 {
124 m_node = node;
125 }
126
129 {
130 uint32_t output = 0;
131 for(auto const& el : m_controllers)
132 {
133 if(el.first == nodeId)
134 break;
135 output++;
136 }
137
138 return output;
139 }
140
143 {
144 auto it = std::next(std::begin(m_controllers), position);
145 if(it == m_controllers.end())
146 NS_LOG_ERROR(this);
147
148 return it->first;
149 }
150
151 void
153 {
154 NS_LOG_FUNCTION(this << source << destination);
156 uint32_t rc2 {GetColumn(destination)};
157 for(auto it = m_adjList[rc1].begin(); it != m_adjList[rc1].end(); ++it)
158 if(it->first == rc2){
159 it->second = 100;
160 break;
161 }
162
163 for(auto it = m_adjList[rc2].begin(); it != m_adjList[rc2].end(); ++it)
164 if(it->first == rc1){
165 it->second = 100;
166 break;
167 }
168
170 }
171
172 void
174 {
175 NS_LOG_FUNCTION(this << source << destination);
177 uint32_t rc2 {GetColumn(destination)};
178 for(auto it = m_adjList[rc1].begin(); it != m_adjList[rc1].end(); ++it)
179 if(it->first == rc2){
180 it->second = 1;
181 break;
182 }
183 for(auto it = m_adjList[rc2].begin(); it != m_adjList[rc2].end(); ++it)
184 if(it->first == rc1){
185 it->second = 1;
186 break;
187 }
188
190 }
191
192
193 // Given an Adjacency List, find all shortest paths from "start" to all other vertices.
194 std::vector< std::pair<uint32_t, uint32_t> >
196 std::vector< std::vector<std::pair<uint32_t, uint32_t> > > adjList,
197 uint32_t start)
198 {
199 std::vector<std::pair<uint32_t, uint32_t> > dist; // First int is dist, second is the previous node.
200
201 // Initialize all source->vertex as infinite.
202 int n = adjList.size();
203 for(int i = 0; i < n; i++)
204 {
205 //dist.push_back(std::make_pair(uint32_t(1000000007), uint32_t(i))); // Define "infinity" as necessary by constraints.
206 dist.emplace_back(1000000007u, static_cast<uint32_t>(i));
207
208 }
209
210 // Create a PQ.
211 std::priority_queue<std::pair<int, int>, std::vector< std::pair<int, int> >, std::greater<std::pair<int, int> > > pq;
212
213 // Add source to pq, where distance is 0.
214 pq.emplace(int(start), 0);
215 dist[start] = std::make_pair(uint32_t(0), start);
216
217 // While pq isn't empty...
218 while(!pq.empty())
219 {
220 // Get min distance vertex from pq.(Call it u.)
221 int u = pq.top().first;
222 pq.pop();
223
224 // Visit all of u's friends. For each one(called v)....
225 int listSize = adjList[u].size();
226 for(int i = 0; i < listSize; i++)
227 {
228 uint32_t v = adjList[u][i].first;
229 uint32_t weight = adjList[u][i].second;
230
231 // If the distance to v is shorter by going through u...
232 if(dist[v].first > dist[u].first + weight)
233 {
234 // Update the distance of v.
235 dist[v].first = dist[u].first + weight;
236 // Update the previous node of v.
237 dist[v].second = u;
238 // Insert v into the pq.
239 pq.push(std::make_pair(v, dist[v].first));
240 }
241 }
242 }
243
244 return dist;
245 }
246
247
248 void
250 {
251 NS_LOG_FUNCTION(this);
252
253 std::vector<std::pair<uint32_t, uint32_t> > dist; // First int is dist, second is the previous node.
254 for(auto el : m_controllers)
255 {
256 el.second->ClearRoutingTable();
258 NS_LOG_FUNCTION(this << dist.size() << GetColumn(el.first));
259 int distSize = dist.size();
260 for(int i = 0; i < distSize; i++)
261 {
262 int currnode = i;
263 std::vector<uint32_t> path;
264 while(currnode != int(GetColumn(el.first)))
265 {
266 path.push_back(currnode);
267 currnode = dist[currnode].second;
268 }
269 /*
270 path is empty if the node is the node!
271 the first element in path is destination node!
272 the last element in path is the next hop!
273 GetColumn(el.fist) is the source node!
274 dist[i].first is number of hops
275 i is source node as well
276 */
277 uint32_t hops = dist[i].first;
278 if(hops >= 1){ //Populate routing table
279 uint32_t nextHop = ReverseColumn(path[path.size()-1]);
280 Ipv4Address nextHopAddress = m_controllers.find(nextHop)->second->GetLocalKMAddress();
281 uint32_t dstNodeId = ReverseColumn(uint32_t(i));
282 Ipv4Address dstNodeAddress = m_controllers.find(dstNodeId)->second->GetLocalKMAddress();
283 std::string dstKmId = m_controllers.find(dstNodeId)->second->GetLocalKMId();
285 nextHop,//nextHop KM node ID
286 nextHopAddress, //nextHop KM address
287 hops, // Dirrect p2p connection(number of hops)
288 dstNodeId, //Destination KM node ID
289 dstNodeAddress, //Destination KM address
290 dstKmId
291 );
292 el.second->AddRouteEntry(newEntry);
293 }
294
295 }
296
297 }
298 }
299
300
301} // namespace ns3
Ipv4 addresses are stored in host order in this class.
A base class which provides memory management and object aggregation.
Definition object.h:78
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:66
std::vector< std::vector< std::pair< uint32_t, uint32_t > > > m_adjList
std::map< uint32_t, Ptr< QKDControl > > m_controllers
void LinkDown(uint32_t source, uint32_t destination)
~QCenController() override
uint32_t GetColumn(uint32_t nodeId)
static TypeId GetTypeId()
void LinkUp(uint32_t source, uint32_t destination)
std::vector< Ptr< QKDControl > > m_controllerList
List of all controllers.
void SetNode(Ptr< Node > node)
std::vector< std::pair< uint32_t, uint32_t > > DijkstraSP(std::vector< std::vector< std::pair< uint32_t, uint32_t > > > adjList, uint32_t start)
void RegisterDControllers(std::vector< Ptr< QKDControl > > controllers)
uint32_t ReverseColumn(uint32_t position)
Introspection did not find any typical Config paths.
a unique identifier for an interface.
Definition type-id.h:49
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition log.h:243
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Definition first.py:1
Every class exported by the ns3 library is enclosed in the ns3 namespace.