11#include " ../include/bus_manager.h"
22
3- BusManager* BusManager::instance = nullptr ;
3+ // Initialize static instance to nullptr
4+ BusManager *BusManager::instance = nullptr ;
45std::mutex BusManager::managerMutex;
56
6- // Private constructor
7- BusManager::BusManager (std::vector<uint32_t > idShouldConnect, uint32_t limit) :server(8080 , std::bind(&BusManager::receiveData, this , std::placeholders::_1))// ,syncCommunication(idShouldConnect, limit)
7+ // Private constructor: initializes the server and starts the collision timer
8+ BusManager::BusManager (std::vector<uint32_t > idShouldConnect, uint32_t limit)
9+ : server(8080 ,
10+ std::bind (&BusManager::receiveData, this , std::placeholders::_1)),
11+ lastPacket(nullptr ), stopFlag(false )
812{
9- // Setup the signal handler for SIGINT
13+ startCollisionTimer (); // Start collision management timer
1014}
1115
12- // Static function to return a singleton instance
13- BusManager* BusManager::getInstance (std::vector<uint32_t > idShouldConnect, uint32_t limit) {
16+ // Singleton getter: ensures only one instance of Manager
17+ BusManager *BusManager::getInstance (std::vector<uint32_t > idShouldConnect,
18+ uint32_t limit)
19+ {
1420 if (instance == nullptr ) {
15- // Lock the mutex to prevent multiple threads from creating instances simultaneously
1621 std::lock_guard<std::mutex> lock (managerMutex);
1722 if (instance == nullptr ) {
1823 instance = new BusManager (idShouldConnect, limit);
@@ -21,44 +26,88 @@ BusManager* BusManager::getInstance(std::vector<uint32_t> idShouldConnect, uint3
2126 return instance;
2227}
2328
24- // Sends to the server to listen for requests
29+ // Starts the server connection and listens for incoming requests
2530ErrorCode BusManager::startConnection ()
2631{
27-
28- ErrorCode isConnected = server.startConnection ();
29- // syncCommunication.notifyProcess()
30- return isConnected;
32+ return server.startConnection ();
3133}
3234
33- // Receives the packet that arrived and checks it before sending it out
35+ // Receives a packet, checks for collisions, and sends it if valid
3436void BusManager::receiveData (Packet &p)
3537{
36- ErrorCode res = sendToClients (p);
37-
38- // Checking the case of collision and priority in functions : checkCollision,packetPriority
39- // Packet* resolvedPacket = checkCollision(*p);
40- // if (resolvedPacket)
41- // server.sendToClients(*resolvedPacket);
38+ checkCollision (p); // Handle packet collisions
4239}
4340
44- // Sending according to broadcast variable
41+ // Sends a packet either as broadcast or to a specific destination
4542ErrorCode BusManager::sendToClients (const Packet &packet)
4643{
47- if (packet.getIsBroadcast ())
48- return server.sendBroadcast (packet);
49- return server.sendDestination (packet);
44+ if (packet.getIsBroadcast ()) {
45+ return server.sendBroadcast (packet); // Broadcast message
46+ }
47+ return server.sendDestination (packet); // Send to specific client
5048}
5149
52- // Implement according to the conflict management of the CAN bus protocol
53- Packet BusManager::checkCollision (Packet ¤tPacket)
50+ // Manages collisions based on the CAN BUS protocol
51+ void BusManager::checkCollision (Packet ¤tPacket)
5452{
55- return currentPacket;
53+ std::lock_guard<std::mutex> lock (lastPacketMutex);
54+ if (lastPacket == nullptr ) {
55+ // No previous packet, store the current one
56+ lastPacket = new Packet (currentPacket);
57+ if (lastPacket == nullptr ) {
58+ }
59+ }
60+ else {
61+ if (lastPacket->getTimestamp () == currentPacket.getTimestamp ()) {
62+ // Same timestamp indicates potential collision, check priority
63+ Packet *prioritizedPacket =
64+ packetPriority (*lastPacket, currentPacket);
65+ if (prioritizedPacket == ¤tPacket) {
66+ delete lastPacket; // Replace last packet if current packet has priority
67+ lastPacket = new Packet (currentPacket);
68+ }
69+ }
70+ }
5671}
5772
58- // Implement a priority check according to the CAN bus
59- Packet BusManager::packetPriority (Packet &a, Packet &b)
73+ // Determines which packet has higher priority ( CAN BUS logic)
74+ Packet * BusManager::packetPriority (Packet &a, Packet &b)
6075{
61- return (a.getSrcId () < b.getSrcId ()) ? a : b;
76+ if (a.getIsPassive () && !b.getIsPassive ()) {
77+ return &b; // Non-passive packet takes priority
78+ }
79+ else if (!a.getIsPassive () && b.getIsPassive ()) {
80+ return &a; // Non-passive packet takes priority
81+ }
82+ else {
83+ return (a > b) ? &a
84+ : &b; // If both are the same type, compare based on ID
85+ }
86+ }
87+
88+ // Starts the collision timer to periodically check for packet collisions
89+ void BusManager::startCollisionTimer ()
90+ {
91+ stopFlag = false ;
92+ collisionTimerThread = std::thread ([this ]() {
93+ while (!stopFlag) {
94+ GlobalClock::waitForNextTick ();
95+ if (!stopFlag) {
96+ checkLastPacket (); // Check and send last packet if necessary
97+ }
98+ }
99+ });
100+ }
101+
102+ // Checks the last packet and sends it if it hasn't been sent yet
103+ void BusManager::checkLastPacket ()
104+ {
105+ std::lock_guard<std::mutex> lock (lastPacketMutex);
106+ if (lastPacket != nullptr ) {
107+ ErrorCode res = sendToClients (*lastPacket);
108+ delete lastPacket; // Clear last packet after sending
109+ lastPacket = nullptr ;
110+ }
62111}
63112
64113// shut down the server
@@ -69,6 +118,13 @@ void BusManager::stopConnection()
69118 }
70119}
71120
72- BusManager::~BusManager () {
121+ // Destructor: ensures proper cleanup of threads and resources
122+ BusManager::~BusManager ()
123+ {
124+ stopFlag = true ; // Stop collision timer thread
125+ if (collisionTimerThread.joinable ()) {
126+ collisionTimerThread.join ();
127+ }
128+ delete lastPacket; // Clean up lastPacket
73129 instance = nullptr ;
74- }
130+ }
0 commit comments