Communication Library for Autonomous Systems v1.0
Reliable and secure communication library for autonomous vehicle systems
Loading...
Searching...
No Matches
rsu.h
Go to the documentation of this file.
1#ifndef RSU_H
2#define RSU_H
3
4#include <chrono>
5#include <atomic>
6#include <vector>
7#include <cstdint>
8#include <cstring>
9
12#include "api/util/debug.h"
13#include "api/framework/clock.h"
15
16
17class RSU {
18public:
24
25 RSU(unsigned int rsu_id, Unit unit, std::chrono::milliseconds period,
26 double x = 0.0, double y = 0.0, double radius = 400.0, const void* data = nullptr, unsigned int data_size = 0);
27 ~RSU();
28 void start();
29 void stop();
30 bool running() const;
31 const Address& address() const;
32 Unit unit() const;
33 std::chrono::milliseconds period() const;
34 void adjust_period(std::chrono::milliseconds new_period);
35 void broadcast();
36
37 // Neighbor RSU management (directly in Protocol)
38 void initialize_neighbor_rsus(); // Initialize neighbor RSUs directly in Protocol
39
40private:
41 // RSU configuration
42 unsigned int _rsu_id;
43 Unit _unit;
44 std::chrono::milliseconds _period;
45 std::vector<std::uint8_t> _data;
46 MacKeyType _rsu_key;
47 double _x;
48 double _y;
49 double _radius;
50
51 // Note: Neighbor RSU information is now stored directly in Protocol's structure
52 // No need for RSU-level duplicate storage
53
54 // Network stack
55 Network* _network;
56 Communicator* _comm;
57
58 // Periodic broadcasting (order matters for initialization)
59 std::atomic<bool> _running;
60 Periodic_Thread<RSU> _periodic_thread;
61
62};
63
64/********** RSU Implementation **********/
65
66
75inline RSU::RSU(unsigned int rsu_id, Unit unit, std::chrono::milliseconds period,
76 double x, double y, double radius, const void* data, unsigned int data_size)
77 : _rsu_id(rsu_id), _unit(unit), _period(period), _x(x), _y(y), _radius(radius), _running(false),
78 _periodic_thread(this, &RSU::broadcast) {
79
80 db<RSU>(TRC) << "RSU::RSU() called with id=" << rsu_id << ", unit=" << unit << ", period=" << period.count() << "ms\n";
81
82 // Store broadcast data if provided
83 if (data && data_size > 0) {
84 _data.resize(data_size);
85 std::memcpy(_data.data(), data, data_size);
86 }
87
88 // Create network stack with RSU ID for MAC address generation
89 _network = new Network(_rsu_id, Network::EntityType::RSU);
90
91 // Set NIC radius to match RSU's configured radius for consistent collision domain filtering
92 _network->channel()->setRadius(_radius);
93
94 // Create communicator using the network's protocol channel and RSU's address
95 Address rsu_addr(_network->address(), _rsu_id);
96 _comm = new Communicator(_network->channel(), rsu_addr);
97
98 _rsu_key.fill(0);
99 // Use RSU ID in the key to make it unique
100 _rsu_key[0] = (rsu_id >> 8) & 0xFF;
101 _rsu_key[1] = rsu_id & 0xFF;
102 _rsu_key[2] = 0xAA; // Marker for RSU
103 _rsu_key[3] = 0xBB;
104
105 db<RSU>(INF) << "[RSU] RSU " << _rsu_id << " initialized with address " << rsu_addr.to_string() << "\n";
106
107 // Set self ID for the Clock instance
108 LeaderIdType self_leader_id = static_cast<LeaderIdType>(rsu_addr.paddr().bytes[5]);
111 db<RSU>(INF) << "[RSU] RSU " << _rsu_id << " registered self_id " << self_leader_id << " with Clock.\n";
112 Clock::getInstance().activate(nullptr); // Activate clock to evaluate leader state
113 } else {
114 db<RSU>(WRN) << "[RSU] RSU " << _rsu_id << " has an INVALID_LEADER_ID based on its MAC. Clock self_id not set.\n";
115 }
116
117 // Set RSU key in LeaderKeyStorage so it can be used for MAC verification
120 db<RSU>(INF) << "[RSU] RSU " << _rsu_id << " registered key in LeaderKeyStorage for MAC verification.\n";
121
122 // Initialize neighbor RSUs
124}
125
129inline RSU::~RSU() {
130 db<RSU>(TRC) << "RSU::~RSU() called!\n";
131
132 stop();
133
134 delete _comm;
135 delete _network;
136
137 db<RSU>(INF) << "[RSU] RSU " << _rsu_id << " destroyed\n";
138}
139
143inline void RSU::start() {
144 db<RSU>(TRC) << "RSU::start() called!\n";
145
146 if (!_running.load()) {
147 _running.store(true);
148 _periodic_thread.start(static_cast<std::int64_t>(_period.count()) * 1000);
149 db<RSU>(INF) << "[RSU] RSU " << _rsu_id << " started broadcasting every " << _period.count() << "ms\n";
150 }
151}
152
156inline void RSU::stop() {
157 db<RSU>(TRC) << "RSU::stop() called!\n";
158
159 if (_running.load(std::memory_order_acquire)) {
160 // Step 1: Signal RSU that it should stop its operations
161 _running.store(false, std::memory_order_release);
162 db<RSU>(INF) << "[RSU] RSU " << _rsu_id << " stopping broadcasting\n";
163
164 // Step 2: Stop periodic thread and wait for it to finish.
165 // This ensures RSU::broadcast() (and thus _comm->send()) is no longer called.
166 _periodic_thread.join();
167 db<RSU>(INF) << "[RSU] RSU " << _rsu_id << " periodic thread stopped\n";
168
169 // Step 3: Release communicator now that the thread is guaranteed to not use it.
170 _comm->release();
171
172 // Step 4: Stop network stack after threads are fully stopped
173 _network->stop();
174 db<RSU>(INF) << "[RSU] RSU " << _rsu_id << " stopped broadcasting\n";
175 }
176}
177
182inline bool RSU::running() const {
183 return _running.load(std::memory_order_acquire);
184}
185
190inline const RSU::Address& RSU::address() const {
191 return _comm->address();
192}
193
198inline RSU::Unit RSU::unit() const {
199 return _unit;
200}
201
206inline std::chrono::milliseconds RSU::period() const {
207 return _period;
208}
209
214inline void RSU::adjust_period(std::chrono::milliseconds new_period) {
215 db<RSU>(TRC) << "RSU::adjust_period() called with new_period=" << new_period.count() << "ms\n";
216
217 _period = new_period;
218 if (running()) {
219 _periodic_thread.adjust_period(static_cast<std::int64_t>(new_period.count()) * 1000);
220 }
221
222 db<RSU>(INF) << "[RSU] RSU " << _rsu_id << " period adjusted to " << new_period.count() << "ms\n";
223}
224
228inline void RSU::broadcast() {
229 if (!running()) {
230 return;
231 }
232
233 db<RSU>(TRC) << "RSU::broadcast() called!\n";
234
235 // Create STATUS message
236 Message* msg;
237
238 // Calculate payload size first
239 unsigned int payload_size = sizeof(_x) + sizeof(_y) + sizeof(_radius) + sizeof(_rsu_key) + _data.size();
240 std::vector<uint8_t> payload(payload_size); // Properly size the vector
241
242 unsigned int offset = 0;
243 std::memcpy(payload.data() + offset, &_x, sizeof(_x));
244 offset += sizeof(_x);
245 std::memcpy(payload.data() + offset, &_y, sizeof(_y));
246 offset += sizeof(_y);
247 std::memcpy(payload.data() + offset, &_radius, sizeof(_radius));
248 offset += sizeof(_radius);
249 std::memcpy(payload.data() + offset, &_rsu_key, sizeof(_rsu_key));
250 offset += sizeof(_rsu_key);
251
252 if (!_data.empty()) {
253 std::memcpy(payload.data() + offset, _data.data(), _data.size());
254 }
255
256 // With data payload
257 msg = new Message(Message::Type::STATUS, address(), _unit,
258 Message::ZERO, payload.data(), payload.size());
259
260 db<RSU>(TRC) << "[RSU] RSU " << _rsu_id << " broadcasting STATUS for unit " << _unit
261 << " with data size " << payload.size() << "\n";
262
263 // Send broadcast message
264 bool sent = _comm->send(msg);
265
266 if (sent) {
267 db<RSU>(INF) << "[RSU] RSU " << _rsu_id << " broadcast STATUS for unit " << _unit << "\n";
268 } else {
269 db<RSU>(WRN) << "[RSU] RSU " << _rsu_id << " failed to broadcast STATUS for unit " << _unit << "\n";
270 }
271
272 delete msg;
273}
274
275
276
282 if (!_network || !_network->channel()) {
283 db<RSU>(WRN) << "[RSU] Cannot initialize protocol neighbors - no network or protocol\n";
284 return;
285 }
286
287 db<RSU>(INF) << "[RSU] Initializing neighbor RSUs directly in Protocol for RSU " << _rsu_id << "\n";
288
289 // Clear existing neighbors in protocol first
290 _network->channel()->clear_neighbor_rsus();
291
292 // For demo purposes, let's assume we know about other RSUs
293 // In practice, this would be loaded from configuration or discovered
294
295 // Example: If this is RSU 1000, add RSU 1001, 1002, etc.
296 for (unsigned int neighbor_id = 1000; neighbor_id < 1010; ++neighbor_id) {
297 if (neighbor_id == _rsu_id) continue; // Skip self
298
299 // Create neighbor RSU key (similar to how we create our own key)
301 neighbor_key.fill(0);
302 neighbor_key[0] = (neighbor_id >> 8) & 0xFF;
303 neighbor_key[1] = neighbor_id & 0xFF;
304 neighbor_key[2] = 0xAA; // Marker for RSU
305 neighbor_key[3] = 0xBB;
306
307 // Create neighbor RSU address
309 neighbor_mac.bytes[0] = 0x02; // Locally administered
310 neighbor_mac.bytes[1] = 0x00;
311 neighbor_mac.bytes[2] = 0x00;
312 neighbor_mac.bytes[3] = 0x00;
313 neighbor_mac.bytes[4] = (neighbor_id >> 8) & 0xFF;
314 neighbor_mac.bytes[5] = neighbor_id & 0xFF;
315
317
318 // Add directly to Protocol structure
320 }
321
322 db<RSU>(INF) << "[RSU] Successfully initialized neighbor RSUs directly in Protocol\n";
323}
324
325#endif // RSU_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
Definition communicator.h:16
const Address & address() const
Definition communicator.h:134
bool send(const Message_T *message)
Definition communicator.h:78
void release()
Definition communicator.h:123
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
Template class for network messages with Clock integration.
Definition message.h:31
static constexpr Microseconds ZERO
Definition message.h:51
std::uint32_t Unit
Definition message.h:48
Definition network.h:8
void stop()
Definition network.h:19
Protocol * channel()
Definition network.h:67
const NIC::Address address()
Definition network.h:75
Definition periodicThread.h:72
void adjust_period(std::int64_t period)
Definition periodicThread.h:155
void start(std::int64_t period)
Definition periodicThread.h:130
void join()
Definition periodicThread.h:116
Definition protocol.h:134
Definition protocol.h:29
void setRadius(double radius)
Definition protocol.h:730
void clear_neighbor_rsus()
Definition protocol.h:1304
void add_neighbor_rsu(unsigned int rsu_id, const MacKeyType &key, const Address &address)
Definition protocol.h:1282
Definition rsu.h:17
void broadcast()
Send a single broadcast message (called by periodic thread)
Definition rsu.h:228
std::chrono::milliseconds period() const
Get the broadcasting period.
Definition rsu.h:206
Message::Unit Unit
Definition rsu.h:23
const Address & address() const
Get the RSU's network address.
Definition rsu.h:190
RSU(unsigned int rsu_id, Unit unit, std::chrono::milliseconds period, double x=0.0, double y=0.0, double radius=400.0, const void *data=nullptr, unsigned int data_size=0)
Construct a new RSU object.
Definition rsu.h:75
Protocol::Address Address
Definition rsu.h:21
bool running() const
Check if the RSU is running.
Definition rsu.h:182
~RSU()
Destroy the RSU object.
Definition rsu.h:129
void adjust_period(std::chrono::milliseconds new_period)
Adjust the broadcasting period.
Definition rsu.h:214
void stop()
Stop the RSU broadcasting.
Definition rsu.h:156
Network::Message Message
Definition rsu.h:22
Network::Communicator Communicator
Definition rsu.h:19
void start()
Start the RSU broadcasting.
Definition rsu.h:143
void initialize_neighbor_rsus()
Initialize neighbor RSUs directly in Protocol structure In a real system, this would be loaded from c...
Definition rsu.h:281
Unit unit() const
Get the unit type being broadcast.
Definition rsu.h:198
Network::Protocol Protocol
Definition rsu.h:20
uint32_t LeaderIdType
Definition clock.h:26
const LeaderIdType INVALID_LEADER_ID
Definition clock.h:27
@ 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::uint8_t payload[MTU]
Definition ethernet.h:3
std::array< uint8_t, 16 > MacKeyType
Definition leaderKeyStorage.h:15
T * data()
Definition protocol.h:24
Definition ethernet.h:16
std::uint8_t bytes[MAC_SIZE]
Definition ethernet.h:17