Communication Library for Autonomous Systems v1.0
Reliable and secure communication library for autonomous vehicle systems
Loading...
Searching...
No Matches
vehicleRSUManager.h
Go to the documentation of this file.
1#ifndef VEHICLE_RSU_MANAGER_H
2#define VEHICLE_RSU_MANAGER_H
3
4#include <vector>
5#include <mutex>
6#include <chrono>
7#include <algorithm>
8#include <cmath>
9#include <memory>
10#include <limits>
11#include <cstdio> // For snprintf in debug logging
12
14#include "api/framework/clock.h"
16#include "api/util/geo_utils.h"
17#include "api/util/debug.h"
19
20// Forward declaration for Protocol
21// template <typename NIC> class Protocol;
22
32template <typename Protocol_T>
34public:
35 struct RSUInfo {
36 typename Protocol_T::Address address; // RSU network address
37 double x; // RSU position
38 double y;
39 double radius; // RSU coverage radius (for info only)
40 MacKeyType group_key; // RSU authentication key
41 std::chrono::steady_clock::time_point last_seen; // Last STATUS message time
42 double distance_to_vehicle; // Calculated distance (updated dynamically)
43
45
46 RSUInfo(const typename Protocol_T::Address& addr, double x_coord, double y_coord,
47 double r, const MacKeyType& key)
51 };
52
53private:
54 std::vector<RSUInfo> _known_rsus; // List of known RSUs
55 mutable std::mutex _rsu_list_mutex; // Thread safety
56 RSUInfo* _current_leader; // Current closest RSU
57 std::chrono::seconds _rsu_timeout; // RSU timeout period
58 unsigned int _vehicle_id; // For logging
59
60 // Neighbor RSU keys (just keys, not full info)
61 std::vector<MacKeyType> _neighbor_rsu_keys;
62 mutable std::mutex _neighbor_keys_mutex; // Thread safety for neighbor keys
63
64 // Periodic cleanup thread
65 std::unique_ptr<Periodic_Thread<VehicleRSUManager>> _cleanup_thread;
66 std::atomic<bool> _running;
67
68public:
70 std::chrono::seconds timeout = std::chrono::seconds(10))
71 : _current_leader(nullptr), _rsu_timeout(timeout), _vehicle_id(vehicle_id), _running(true) {
72 db<VehicleRSUManager>(INF) << "[RSUManager " << _vehicle_id
73 << "] RSU Manager initialized with "
74 << timeout.count() << "s timeout\n";
75
76 // Start periodic cleanup thread (cleanup every 5 seconds)
77 db<VehicleRSUManager>(TRC) << "[RSUManager " << _vehicle_id
78 << "] Starting periodic cleanup thread (5s interval)\n";
79 _cleanup_thread = std::make_unique<Periodic_Thread<VehicleRSUManager>>(
81 );
82 _cleanup_thread->start(1000000); // 1 seconds in microseconds
83 db<VehicleRSUManager>(TRC) << "[RSUManager " << _vehicle_id
84 << "] Periodic cleanup thread started\n";
85 }
86
88 db<VehicleRSUManager>(TRC) << "[RSUManager " << _vehicle_id
89 << "] RSU Manager shutting down\n";
90 _running.store(false, std::memory_order_release);
91 if (_cleanup_thread) {
92 db<VehicleRSUManager>(TRC) << "[RSUManager " << _vehicle_id
93 << "] Stopping periodic cleanup thread\n";
94 _cleanup_thread->join();
95 }
96 db<VehicleRSUManager>(INF) << "[RSUManager " << _vehicle_id << "] RSU Manager destroyed\n";
97 }
98
99 // Process incoming RSU STATUS message
100 void process_rsu_status(const typename Protocol_T::Address& rsu_address,
101 double x, double y, double radius,
102 const MacKeyType& group_key) {
103 if (!_running.load(std::memory_order_acquire)) return;
104
105 std::lock_guard<std::mutex> lock(_rsu_list_mutex);
106
107 db<VehicleRSUManager>(TRC) << "[RSUManager " << _vehicle_id
108 << "] Processing RSU STATUS from " << rsu_address.to_string()
109 << " at (" << x << ", " << y << ") radius=" << radius << "m\n";
110
111 // Debug logging: Show RSU key
112 std::string rsu_key_hex = "";
113 for (size_t i = 0; i < 16; ++i) {
114 char hex_byte[4];
115 snprintf(hex_byte, sizeof(hex_byte), "%02X ", group_key[i]);
117 }
118 db<VehicleRSUManager>(INF) << "[RSUManager " << _vehicle_id
119 << "] RSU key received: " << rsu_key_hex << "\n";
120
121 // Check if this key exists in neighbor keys and remove it (we now have full info)
122 remove_neighbor_rsu_key(group_key);
123
124 // Find existing RSU or create new one
125 auto it = find_rsu_by_address(rsu_address);
126 if (it != _known_rsus.end()) {
127 // Update existing RSU
128 it->x = x;
129 it->y = y;
130 it->radius = radius;
131 it->group_key = group_key;
132 it->last_seen = std::chrono::steady_clock::now();
133 db<VehicleRSUManager>(INF) << "[RSUManager " << _vehicle_id
134 << "] Updated RSU " << rsu_address.to_string() << "\n";
135 } else {
136 // Add new RSU
137 _known_rsus.emplace_back(rsu_address, x, y, radius, group_key);
138 db<VehicleRSUManager>(INF) << "[RSUManager " << _vehicle_id
139 << "] Discovered new RSU " << rsu_address.to_string()
140 << " at (" << x << ", " << y << ")\n";
141 }
142 // Trigger leader selection update
144 }
145
146 // Update distances and leader selection
148 // Must be called with _rsu_list_mutex held
149 if (_known_rsus.empty()) {
150 if (_current_leader != nullptr) {
151 db<VehicleRSUManager>(INF) << "[RSUManager " << _vehicle_id
152 << "] Lost all RSUs - clearing leader\n";
153 }
154 _current_leader = nullptr;
155 db<VehicleRSUManager>(TRC) << "[RSUManager " << _vehicle_id
156 << "] No RSUs available for leader selection\n";
157 return;
158 }
159
160 // if (_known_rsus.size() == 1) {
161 // db<VehicleRSUManager>(TRC) << "[RSUManager " << _vehicle_id
162 // << "] Only one known rsu : keeping leader\n";
163 // return;
164 // }
165
166 db<VehicleRSUManager>(TRC) << "[RSUManager " << _vehicle_id
167 << "] Updating leader selection among " << _known_rsus.size() << " RSUs\n";
168
169 // Update distances to all RSUs
171
172 // Sort RSUs by distance (closest first)
173 std::sort(_known_rsus.begin(), _known_rsus.end(),
174 [](const RSUInfo& a, const RSUInfo& b) {
175 return a.distance_to_vehicle < b.distance_to_vehicle;
176 });
177
178 // Log all RSU distances for debugging
179 for (size_t i = 0; i < _known_rsus.size(); ++i) {
180 const auto& rsu = _known_rsus[i];
181 db<VehicleRSUManager>(TRC) << "[RSUManager " << _vehicle_id
182 << "] RSU " << rsu.address.to_string()
183 << " distance=" << rsu.distance_to_vehicle << "m\n";
184 }
185
186 // Select closest RSU (we can communicate with all RSUs in our list)
187 // If we received STATUS messages from them, they are within collision domain
188 RSUInfo* new_leader = &_known_rsus[0]; // Closest RSU
189
190 // Check if leader changed
191 bool leader_changed = (_current_leader != new_leader);
192
193 if (leader_changed) {
194 if (_current_leader && new_leader) {
195 db<VehicleRSUManager>(INF) << "[RSUManager " << _vehicle_id
196 << "] Leader changed from " << _current_leader->address.to_string()
197 << " to " << new_leader->address.to_string() << "\n";
198 } else if (!_current_leader && new_leader) {
199 db<VehicleRSUManager>(INF) << "[RSUManager " << _vehicle_id
200 << "] First leader selected: " << new_leader->address.to_string() << "\n";
201 }
202 }
203
204 _current_leader = new_leader;
205
206 if (_current_leader) {
207 db<VehicleRSUManager>(INF) << "[RSUManager " << _vehicle_id
208 << "] Current leader: " << _current_leader->address.to_string()
209 << " (distance: " << _current_leader->distance_to_vehicle << "m)\n";
210
211 if (leader_changed) {
212 // Update global leader storage
213 LeaderIdType leader_id = static_cast<LeaderIdType>(_current_leader->address.paddr().bytes[5]);
214 db<VehicleRSUManager>(TRC) << "[RSUManager " << _vehicle_id
215 << "] Updating global leader storage with ID " << (int)leader_id << "\n";
216
217 LeaderKeyStorage::getInstance().setLeaderId(_current_leader->address.paddr());
218 LeaderKeyStorage::getInstance().setGroupMacKey(_current_leader->group_key);
219
220 // Update Clock for PTP synchronization
222 Clock::getInstance().activate(nullptr);
223 }
224 }
225 }
226
227 // Calculate distances from vehicle to all RSUs
229 // Get current vehicle position
230 double vehicle_x, vehicle_y;
232
233 db<VehicleRSUManager>(TRC) << "[RSUManager " << _vehicle_id
234 << "] Vehicle position: (" << vehicle_x << ", " << vehicle_y << ")\n";
235
236 // Calculate distance to each RSU
237 for (auto& rsu : _known_rsus) {
238 rsu.distance_to_vehicle = GeoUtils::euclideanDistance(
239 vehicle_x, vehicle_y, rsu.x, rsu.y);
240 }
241 }
242
243 // Cleanup stale RSUs (called by periodic thread)
245 if (!_running.load(std::memory_order_acquire)) return;
246
247 std::lock_guard<std::mutex> lock(_rsu_list_mutex);
248 auto now = std::chrono::steady_clock::now();
249 bool list_changed = false;
250
251 db<VehicleRSUManager>(TRC) << "[RSUManager " << _vehicle_id
252 << "] Running periodic RSU cleanup, checking " << _known_rsus.size() << " RSUs\n";
253
254 auto it = _known_rsus.begin();
255 while (it != _known_rsus.end()) {
256 auto time_since_last_seen = std::chrono::duration_cast<std::chrono::seconds>(now - it->last_seen);
257
258 if (time_since_last_seen > _rsu_timeout) {
259 db<VehicleRSUManager>(INF) << "[RSUManager " << _vehicle_id
260 << "] Removing stale RSU " << it->address.to_string()
261 << " (last seen " << time_since_last_seen.count() << "s ago)\n";
262
263 // Check if we're removing the current leader
264 if (_current_leader == &(*it)) {
265 db<VehicleRSUManager>(WRN) << "[RSUManager " << _vehicle_id
266 << "] Removing current leader due to timeout\n";
267 _current_leader = nullptr;
268 list_changed = true;
269 }
270
271 it = _known_rsus.erase(it);
272 list_changed = true;
273 } else {
274 db<VehicleRSUManager>(TRC) << "[RSUManager " << _vehicle_id
275 << "] RSU " << it->address.to_string()
276 << " is fresh (last seen " << time_since_last_seen.count() << "s ago)\n";
277 ++it;
278 }
279 }
280
281 if (list_changed) {
282 db<VehicleRSUManager>(INF) << "[RSUManager " << _vehicle_id
283 << "] RSU list changed after cleanup, updating leader selection\n";
285 } else {
286 db<VehicleRSUManager>(TRC) << "[RSUManager " << _vehicle_id
287 << "] No changes after RSU cleanup\n";
288 }
289 }
290
291 // Get current leader info (for debugging)
293 std::lock_guard<std::mutex> lock(_rsu_list_mutex);
294 return _current_leader;
295 }
296
297 // Get all known RSUs (for debugging)
298 std::vector<RSUInfo> get_known_rsus() {
299 std::lock_guard<std::mutex> lock(_rsu_list_mutex);
300 return _known_rsus; // Copy for thread safety
301 }
302
303 // Add neighbor RSU key
305 std::lock_guard<std::mutex> lock(_neighbor_keys_mutex);
306 // Check if key already exists
307 for (const auto& existing_key : _neighbor_rsu_keys) {
308 if (existing_key == key) {
309 db<VehicleRSUManager>(INF) << "[RSUManager " << _vehicle_id
310 << "] Neighbor RSU key already exists\n";
311 return;
312 }
313 }
314 _neighbor_rsu_keys.push_back(key);
315 db<VehicleRSUManager>(INF) << "[RSUManager " << _vehicle_id
316 << "] Added neighbor RSU key (total: " << _neighbor_rsu_keys.size() << ")\n";
317 }
318
319 // Get all neighbor RSU keys (for MAC verification)
320 std::vector<MacKeyType> get_neighbor_rsu_keys() {
321 std::lock_guard<std::mutex> lock(_neighbor_keys_mutex);
322 return _neighbor_rsu_keys; // Copy for thread safety
323 }
324
325 // Remove neighbor RSU key (when we get full RSU info via STATUS)
327 std::lock_guard<std::mutex> lock(_neighbor_keys_mutex);
328 auto it = std::find(_neighbor_rsu_keys.begin(), _neighbor_rsu_keys.end(), key);
329 if (it != _neighbor_rsu_keys.end()) {
330 _neighbor_rsu_keys.erase(it);
331 db<VehicleRSUManager>(INF) << "[RSUManager " << _vehicle_id
332 << "] Removed neighbor RSU key (remaining: " << _neighbor_rsu_keys.size() << ")\n";
333 return true;
334 }
335 return false;
336 }
337
338private:
339 // Find RSU by address
340 typename std::vector<RSUInfo>::iterator find_rsu_by_address(
341 const typename Protocol_T::Address& address) {
342 return std::find_if(_known_rsus.begin(), _known_rsus.end(),
343 [&address](const RSUInfo& info) {
344 return info.address == address;
345 });
346 }
347};
348
349#endif // VEHICLE_RSU_MANAGER_H
void setSelfId(LeaderIdType id)
Set the self ID for this clock instance (node's own PTP-relevant ID)
Definition clock.h:156
void activate(const PtpRelevantData *new_msg_data)
Activate the state machine with new PTP data.
Definition clock.h:177
static Clock & getInstance()
Get the singleton instance.
Definition clock.h:145
static double euclideanDistance(double x1, double y1, double x2, double y2)
Definition geo_utils.h:16
void setLeaderId(const Ethernet::Address &leader_id)
Set the current leader ID.
Definition leaderKeyStorage.h:65
static LeaderKeyStorage & getInstance()
Get the singleton instance.
Definition leaderKeyStorage.h:54
void setGroupMacKey(const MacKeyType &key)
Set the current group MAC key.
Definition leaderKeyStorage.h:93
static void getCurrentCoordinates(double &x, double &y)
Definition location_service.h:91
Definition vehicleRSUManager.h:33
std::vector< RSUInfo > get_known_rsus()
Definition vehicleRSUManager.h:298
void add_neighbor_rsu_key(const MacKeyType &key)
Definition vehicleRSUManager.h:304
std::vector< MacKeyType > get_neighbor_rsu_keys()
Definition vehicleRSUManager.h:320
void cleanup_stale_rsus()
Definition vehicleRSUManager.h:244
void update_distances()
Definition vehicleRSUManager.h:228
bool remove_neighbor_rsu_key(const MacKeyType &key)
Definition vehicleRSUManager.h:326
RSUInfo * get_current_leader()
Definition vehicleRSUManager.h:292
~VehicleRSUManager()
Definition vehicleRSUManager.h:87
void update_leader_selection()
Definition vehicleRSUManager.h:147
void process_rsu_status(const typename Protocol_T::Address &rsu_address, double x, double y, double radius, const MacKeyType &group_key)
Definition vehicleRSUManager.h:100
VehicleRSUManager(unsigned int vehicle_id, std::chrono::seconds timeout=std::chrono::seconds(10))
Definition vehicleRSUManager.h:69
uint32_t LeaderIdType
Definition clock.h:26
@ INF
Definition debug.h:208
Select_Debug<(Traits< T >::debugged &&Traits< Debug >::error)> db(Debug_Error l)
Definition debug.h:166
@ TRC
Definition debug.h:231
@ WRN
Definition debug.h:185
std::array< uint8_t, 16 > MacKeyType
Definition leaderKeyStorage.h:15
Definition vehicleRSUManager.h:35
RSUInfo()
Definition vehicleRSUManager.h:44
MacKeyType group_key
Definition vehicleRSUManager.h:40
Protocol_T::Address address
Definition vehicleRSUManager.h:36
RSUInfo(const typename Protocol_T::Address &addr, double x_coord, double y_coord, double r, const MacKeyType &key)
Definition vehicleRSUManager.h:46
double x
Definition vehicleRSUManager.h:37
double distance_to_vehicle
Definition vehicleRSUManager.h:42
std::chrono::steady_clock::time_point last_seen
Definition vehicleRSUManager.h:41
double y
Definition vehicleRSUManager.h:38
double radius
Definition vehicleRSUManager.h:39