Major refactoring participants

This commit is contained in:
Pascal Serrarens 2025-06-27 12:38:44 +02:00
parent 9a26e98b0f
commit b5f07f77c2
18 changed files with 542 additions and 231 deletions

View File

@ -1,4 +1,5 @@
#include "ArduinoParticipant.h" #include "ArduinoParticipant.h"
#if defined(ARDUINO)
#if !defined(NO_STD) #if !defined(NO_STD)
#include <iostream> #include <iostream>
@ -21,7 +22,6 @@
#endif #endif
namespace RoboidControl { namespace RoboidControl {
namespace Arduino {
#if defined(ARDUINO) && defined(HAS_WIFI) #if defined(ARDUINO) && defined(HAS_WIFI)
WiFiUDP* udp; WiFiUDP* udp;
@ -88,7 +88,7 @@ void ParticipantUDP::Receive() {
#endif #endif
} }
bool ParticipantUDP::SendTo(Participant* remoteParticipant, int bufferSize) { bool ParticipantUDP::SendTo(RemoteParticipantUDP* remoteParticipant, int bufferSize) {
#if defined(ARDUINO) && defined(HAS_WIFI) #if defined(ARDUINO) && defined(HAS_WIFI)
// std::cout << "Sending to:\n " << remoteParticipant->ipAddress << ":" // std::cout << "Sending to:\n " << remoteParticipant->ipAddress << ":"
// << remoteParticipant->port << "\n"; // << remoteParticipant->port << "\n";
@ -131,5 +131,5 @@ bool ParticipantUDP::Publish(IMessage* msg) {
return true; return true;
}; };
} // namespace Arduino
} // namespace RoboidControl } // namespace RoboidControl
#endif

View File

@ -1,15 +1,15 @@
#pragma once #pragma once
#if defined(ARDUINO)
#include "Participants/ParticipantUDP.h" #include "Participants/ParticipantUDP.h"
namespace RoboidControl { namespace RoboidControl {
namespace Arduino {
class ParticipantUDP : public RoboidControl::ParticipantUDP { class ParticipantUDP : public ParticipantUDPGeneric {
public: public:
void Setup(); void Setup();
void Receive(); void Receive();
bool SendTo(Participant* remoteParticipant, int bufferSize); bool SendTo(RemoteParticipantUDP* remoteParticipant, int bufferSize);
bool Publish(IMessage* msg); bool Publish(IMessage* msg);
protected: protected:
@ -18,5 +18,5 @@ class ParticipantUDP : public RoboidControl::ParticipantUDP {
void GetBroadcastAddress(); void GetBroadcastAddress();
}; };
} // namespace Arduino
} // namespace RoboidControl } // namespace RoboidControl
#endif

View File

@ -19,7 +19,7 @@
using namespace RoboidControl; using namespace RoboidControl;
using namespace RoboidControl::Arduino; using namespace RoboidControl::Arduino;
ParticipantUDP* localParticipant; ParticipantUDPGeneric* localParticipant;
DifferentialDrive* bb2b; DifferentialDrive* bb2b;
TouchSensor* touchLeft; TouchSensor* touchLeft;
@ -34,7 +34,7 @@ void setup() {
Serial.println("started"); Serial.println("started");
StartWifi("serrarens", "192.168.76.44"); StartWifi("serrarens", "192.168.76.44");
localParticipant = new ParticipantUDP("192.168.77.76"); localParticipant = new ParticipantUDPGeneric("192.168.77.76");
bb2b = new DifferentialDrive(); bb2b = new DifferentialDrive();
touchLeft = new TouchSensor(bb2b); touchLeft = new TouchSensor(bb2b);

View File

@ -4,10 +4,10 @@
#include "esp_wifi.h" #include "esp_wifi.h"
#endif #endif
#include <arpa/inet.h>
namespace RoboidControl { namespace RoboidControl {
namespace EspIdf {
void ParticipantUDP::Setup(int localPort, void ParticipantUDP::SetupUDP(int localPort,
const char* remoteIpAddress, const char* remoteIpAddress,
int remotePort) { int remotePort) {
#if defined(IDF_VER) #if defined(IDF_VER)
@ -29,7 +29,8 @@ void ParticipantUDP::Setup(int localPort,
return; return;
} }
// Set up the receiving address /*
// Set up the receiving(local) address
struct sockaddr_in local_addr; struct sockaddr_in local_addr;
memset(&local_addr, 0, sizeof(local_addr)); memset(&local_addr, 0, sizeof(local_addr));
local_addr.sin_family = AF_INET; local_addr.sin_family = AF_INET;
@ -44,18 +45,33 @@ void ParticipantUDP::Setup(int localPort,
vTaskDelete(NULL); vTaskDelete(NULL);
return; return;
} }
*/
// Initialize the dest_addr structure // Initialize the destination(remote) address
memset(&this->dest_addr, 0, memset(&this->dest_addr, 0,
sizeof(this->dest_addr)); // Clear the entire structure sizeof(this->dest_addr)); // Clear the entire structure
this->dest_addr.sin_family = AF_INET; this->dest_addr.sin_family = AF_INET;
this->dest_addr.sin_port = htons(this->remoteSite->port); this->dest_addr.sin_port = htons(this->remoteSite->port);
inet_pton(AF_INET, this->remoteSite->ipAddress, this->dest_addr.sin_addr.s_addr = inet_addr(this->remoteSite->ipAddress);
&this->dest_addr.sin_addr.s_addr); // inet_pton(AF_INET, this->remoteSite->ipAddress,
// &this->dest_addr.sin_addr.s_addr);
std::cout << "Wifi sync started local " << localPort << ", remote " std::cout << "Wifi sync started local " << localPort << ", remote "
<< this->remoteSite->ipAddress << ":" << this->remoteSite->port << this->remoteSite->ipAddress << ":" << this->remoteSite->port
<< "\n"; << "\n";
std::cout << "socket: " << (int)this->sock << std::endl;
ParticipantMsg* msg = new ParticipantMsg(this->networkId);
int bufferSize = msg->Serialize(this->buffer);
int err = sendto(this->sock, buffer, bufferSize, 0,
(struct sockaddr*)&dest_addr, sizeof(dest_addr));
if (errno != 0)
std::cout << "AASend error " << err << " or " << errno << "\n";
else
std::cout << "AASend SUCCESS\n";
SendTest();
#endif // IDF_VER #endif // IDF_VER
} }
@ -82,8 +98,9 @@ void ParticipantUDP::GetBroadcastAddress() {
#endif // IDF_VER #endif // IDF_VER
} }
void ParticipantUDP::Receive() { void ParticipantUDP::ReceiveUDP() {
#if defined(IDF_VER) #if defined(IDF_VER)
/*
struct pollfd fds[1]; struct pollfd fds[1];
fds[0].fd = sock; fds[0].fd = sock;
fds[0].events = POLLIN; // We're looking for data available to read fds[0].events = POLLIN; // We're looking for data available to read
@ -125,17 +142,50 @@ void ParticipantUDP::Receive() {
} }
} }
// std::cout << "no more messages\n"; // std::cout << "no more messages\n";
*/
#endif // IDF_VER #endif // IDF_VER
} }
bool ParticipantUDP::SendTo(Participant* remoteParticipant, int bufferSize) { ParticipantUDP::ParticipantUDP(int port) : ParticipantUDPGeneric(port) {}
#if defined(IDF_VER)
std::cout << "Sending to " << remoteParticipant->ipAddress << ":"
<< remoteParticipant->port << "\n";
ParticipantUDP::ParticipantUDP(const char* ipAddress, int port, int localPort)
: ParticipantUDPGeneric(ipAddress, port, localPort) {}
bool ParticipantUDP::SendTest() {
#if defined(IDF_VER)
std::cout << "socket: " << (int)this->sock << std::endl;
ParticipantMsg* msg = new ParticipantMsg(this->networkId);
int bSize = msg->Serialize(this->buffer);
int err = sendto(this->sock, buffer, bSize, 0, (struct sockaddr*)&dest_addr,
sizeof(dest_addr));
if (errno != 0)
std::cout << "BBSend error " << err << " or " << errno << "\n";
else
std::cout << "BBSend SUCCESS\n";
#endif
return true;
}
bool ParticipantUDP::SendTo(RemoteParticipantUDP* remoteParticipant,
int bufferSize) {
#if defined(IDF_VER)
uint16_t port = ntohs(dest_addr.sin_port);
char ip_str[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &dest_addr.sin_addr, ip_str, sizeof(ip_str));
std::cout << "Sending to " << ip_str << ":" << port << "\n";
// Print the IP address and port
// printf("IP Address: %s\n", ip_str);
// printf("Port: %d\n", port);
this->dest_addr.sin_port = htons(remoteParticipant->port);
this->dest_addr.sin_addr.s_addr = inet_addr(remoteParticipant->ipAddress);
std::cout << "socket: " << (int)this->sock << std::endl;
int err = sendto(this->sock, buffer, bufferSize, 0, int err = sendto(this->sock, buffer, bufferSize, 0,
(struct sockaddr*)&dest_addr, sizeof(dest_addr)); (struct sockaddr*)&this->dest_addr, sizeof(this->dest_addr));
if (errno != 0) if (errno != 0)
std::cout << "Send error " << err << " or " << errno << "\n"; std::cout << "Send error " << err << " or " << errno << "\n";
@ -161,5 +211,4 @@ bool ParticipantUDP::Publish(IMessage* msg) {
return true; return true;
}; };
} // namespace EspIdf
} // namespace RoboidControl } // namespace RoboidControl

View File

@ -1,21 +1,39 @@
#pragma once #pragma once
#if defined(IDF_VER)
#include "Participants/ParticipantUDP.h" #include "Participants/ParticipantUDP.h"
#if defined(IDF_VER)
#include "lwip/sockets.h" #include "lwip/sockets.h"
#endif
namespace RoboidControl { namespace RoboidControl {
namespace EspIdf {
class ParticipantUDP : public RoboidControl::ParticipantUDP { class ParticipantUDP : public ParticipantUDPGeneric {
public: public:
/// @brief Create a participant without connecting to a site
/// @param port The port on which the participant communicates
/// These participant typically broadcast Participant messages to let site
/// servers on the local network know their presence. Alternatively they can
/// broadcast information which can be used directly by other participants.
ParticipantUDP(int port = 7681);
/// @brief Create a participant which will try to connect to a site.
/// @param ipAddress The IP address of the site
/// @param port The port used by the site
/// @param localPort The port used by the local participant
ParticipantUDP(const char* ipAddress,
int port = 7681,
int localPort = 7681);
void Setup(int localPort, const char* remoteIpAddress, int remotePort); void Setup(int localPort, const char* remoteIpAddress, int remotePort);
void Receive(); void Receive();
bool SendTo(Participant* remoteParticipant, int bufferSize); bool SendTo(RemoteParticipantUDP* remoteParticipant, int bufferSize);
bool Publish(IMessage* msg); bool Publish(IMessage* msg);
bool SendTest();
//bool Send(IMessage* msg) override;
void SetupUDP(int localPort, const char* remoteIpAddress, int remotePort) override;
void ReceiveUDP() override;
protected: protected:
#if defined(IDF_VER) #if defined(IDF_VER)
char broadcastIpAddress[INET_ADDRSTRLEN]; char broadcastIpAddress[INET_ADDRSTRLEN];
@ -28,5 +46,7 @@ class ParticipantUDP : public RoboidControl::ParticipantUDP {
void GetBroadcastAddress(); void GetBroadcastAddress();
}; };
} // namespace EspIdf
} // namespace RoboidControl } // namespace RoboidControl
#endif

View File

@ -10,8 +10,6 @@ namespace RoboidControl {
#pragma region Participant #pragma region Participant
ParticipantRegistry Participant::registry;
Participant* Participant::LocalParticipant = new Participant(); Participant* Participant::LocalParticipant = new Participant();
void Participant::ReplaceLocalParticipant(Participant& newParticipant) { void Participant::ReplaceLocalParticipant(Participant& newParticipant) {
@ -24,6 +22,7 @@ Participant::Participant() {
//this->Add(this->root); //this->Add(this->root);
} }
/*
Participant::Participant(const char* ipAddress, int port) { Participant::Participant(const char* ipAddress, int port) {
Thing::CreateRoot(this); Thing::CreateRoot(this);
//this->Add(this->root); //this->Add(this->root);
@ -43,10 +42,10 @@ Participant::Participant(const char* ipAddress, int port) {
this->ipAddress = addressString; this->ipAddress = addressString;
this->port = port; this->port = port;
} }
*/
Participant::~Participant() { Participant::~Participant() {
// registry.Remove(this); // registry.Remove(this);
delete[] this->ipAddress; // delete[] this->ipAddress;
} }
void Participant::Update(bool recurse) { void Participant::Update(bool recurse) {
@ -56,6 +55,13 @@ void Participant::Update(bool recurse) {
} }
} }
bool Participant::Send(IMessage* msg) {
std::cout << "sending message " << (static_cast<int>(this->buffer[0]) & 0xff)
<< " to base Participant without communcation support " << std::endl;
return true;
}
/*
bool Participant::Send(IMessage* msg) { bool Participant::Send(IMessage* msg) {
int bufferSize = msg->Serialize(this->buffer); int bufferSize = msg->Serialize(this->buffer);
if (bufferSize <= 0) if (bufferSize <= 0)
@ -83,13 +89,14 @@ bool Participant::Send(IMessage* msg) {
return false; return false;
#endif #endif
} }
*/
Thing* Participant::Get(unsigned char networkId, unsigned char thingId) { Thing* Participant::Get(unsigned char networkId, unsigned char thingId) {
for (Thing* thing : this->things) { for (Thing* thing : this->things) {
if (thing->owner->networkId == networkId && thing->id == thingId) if (thing->owner->networkId == networkId && thing->id == thingId)
return thing; return thing;
} }
std::cout << "Could not find thing " << this->ipAddress << ":" << this->port std::cout << "Could not find thing " //<< this->ipAddress << ":" << this->port
<< "[" << (int)thingId << "]\n"; << "[" << (int)thingId << "]\n";
return nullptr; return nullptr;
} }
@ -112,8 +119,9 @@ void Participant::Add(Thing* thing, bool checkId) {
thing->id = highestIx + 1; thing->id = highestIx + 1;
this->things.push_back(thing); this->things.push_back(thing);
#endif #endif
std::cout << "Add thing with generated ID " << this->ipAddress << ":" std::cout << "Add thing with generated ID "
<< this->port << "[" << (int)thing->id << "]\n"; //<< this->ipAddress << ":" << this->port
<< "[" << (int)thing->id << "]\n";
} else { } else {
Thing* foundThing = Get(thing->owner->networkId, thing->id); Thing* foundThing = Get(thing->owner->networkId, thing->id);
if (foundThing == nullptr) { if (foundThing == nullptr) {
@ -122,12 +130,13 @@ void Participant::Add(Thing* thing, bool checkId) {
#else #else
this->things.push_back(thing); this->things.push_back(thing);
#endif #endif
std::cout << "Add thing " << this->ipAddress << ":" << this->port << std::cout << "Add thing " << //this->ipAddress << ":" << this->port <<
"[" "["
<< (int)thing->id << "]\n"; << (int)thing->id << "]\n";
} else { } else {
std::cout << "Did not add, existing thing " << this->ipAddress << ":" std::cout << "Did not add, existing thing "
<< this->port << "[" << (int)thing->id << "]\n"; //<< this->ipAddress << ":" << this->port
<< "[" << (int)thing->id << "]\n";
} }
} }
} }
@ -155,86 +164,88 @@ void Participant::Remove(Thing* thing) {
#pragma endregion #pragma endregion
#pragma region ParticipantRegistry // #pragma region ParticipantRegistry
Participant* ParticipantRegistry::Get(const char* ipAddress, // /*
unsigned int port) { // Participant* ParticipantRegistry::Get(const char* ipAddress,
#if !defined(NO_STD) // unsigned int port) {
for (Participant* participant : ParticipantRegistry::participants) { // #if !defined(NO_STD)
if (participant == nullptr) // for (Participant* participant : ParticipantRegistry::participants) {
continue; // if (participant == nullptr)
if (strcmp(participant->ipAddress, ipAddress) == 0 && // continue;
participant->port == port) { // if (strcmp(participant->ipAddress, ipAddress) == 0 &&
// std::cout << "found participant " << participant->ipAddress << ":" // participant->port == port) {
// << (int)participant->port << std::endl; // // std::cout << "found participant " << participant->ipAddress << ":"
return participant; // // << (int)participant->port << std::endl;
} // return participant;
} // }
std::cout << "Could not find participant " << ipAddress << ":" << (int)port // }
<< std::endl; // std::cout << "Could not find participant " << ipAddress << ":" << (int)port
#endif // << std::endl;
return nullptr; // #endif
} // return nullptr;
// }
// */
// Participant* ParticipantRegistry::Get(unsigned char participantId) {
// #if !defined(NO_STD)
// for (Participant* participant : ParticipantRegistry::participants) {
// if (participant == nullptr)
// continue;
// if (participant->networkId == participantId)
// return participant;
// }
// std::cout << "Could not find participant " << (int)participantId << std::endl;
// #endif
// return nullptr;
// }
Participant* ParticipantRegistry::Get(unsigned char participantId) { // // Participant* ParticipantRegistry::Add(const char* ipAddress,
#if !defined(NO_STD) // // unsigned int port) {
for (Participant* participant : ParticipantRegistry::participants) { // // Participant* participant = new Participant(ipAddress, port);
if (participant == nullptr) // // Add(participant);
continue; // // return participant;
if (participant->networkId == participantId) // // }
return participant;
}
std::cout << "Could not find participant " << (int)participantId << std::endl;
#endif
return nullptr;
}
Participant* ParticipantRegistry::Add(const char* ipAddress, // void ParticipantRegistry::Add(Participant* participant) {
unsigned int port) { // Participant* foundParticipant =
Participant* participant = new Participant(ipAddress, port); // Get(participant->networkId);
Add(participant); // //Get(participant->ipAddress, participant->port);
return participant;
}
void ParticipantRegistry::Add(Participant* participant) { // if (foundParticipant == nullptr) {
Participant* foundParticipant = // #if defined(NO_STD)
Get(participant->ipAddress, participant->port); // // this->things[this->thingCount++] = thing;
// #else
// ParticipantRegistry::participants.push_back(participant);
// #endif
// // std::cout << "Add participant " << participant->ipAddress << ":"
// // << participant->port << "[" << (int)participant->networkId
// // << "]\n";
// // std::cout << "participants " <<
// // ParticipantRegistry::participants.size()
// // << "\n";
// // } else {
// // std::cout << "Did not add, existing participant " <<
// // participant->ipAddress
// // << ":" << participant->port << "[" <<
// // (int)participant->networkId
// // << "]\n";
// }
// }
if (foundParticipant == nullptr) { // void ParticipantRegistry::Remove(Participant* participant) {
#if defined(NO_STD) // // participants.remove(participant);
// this->things[this->thingCount++] = thing; // }
#else
ParticipantRegistry::participants.push_back(participant);
#endif
// std::cout << "Add participant " << participant->ipAddress << ":"
// << participant->port << "[" << (int)participant->networkId
// << "]\n";
// std::cout << "participants " <<
// ParticipantRegistry::participants.size()
// << "\n";
// } else {
// std::cout << "Did not add, existing participant " <<
// participant->ipAddress
// << ":" << participant->port << "[" <<
// (int)participant->networkId
// << "]\n";
}
}
void ParticipantRegistry::Remove(Participant* participant) { // #if defined(NO_STD)
// participants.remove(participant); // Participant** ParticipantRegistry::GetAll() const {
} // return ParticipantRegistry::participants;
// }
// #else
// const std::list<Participant*>& ParticipantRegistry::GetAll() const {
// return ParticipantRegistry::participants;
// }
// #endif
#if defined(NO_STD) // #pragma endregion ParticipantRegistry
Participant** ParticipantRegistry::GetAll() const {
return ParticipantRegistry::participants;
}
#else
const std::list<Participant*>& ParticipantRegistry::GetAll() const {
return ParticipantRegistry::participants;
}
#endif
#pragma endregion ParticipantRegistry
} // namespace RoboidControl } // namespace RoboidControl

View File

@ -7,6 +7,7 @@ namespace RoboidControl {
constexpr int MAX_THING_COUNT = 256; constexpr int MAX_THING_COUNT = 256;
/*
/// @brief class which manages all known participants /// @brief class which manages all known participants
class ParticipantRegistry { class ParticipantRegistry {
public: public:
@ -14,7 +15,7 @@ class ParticipantRegistry {
/// @param ipAddress The IP address of the participant /// @param ipAddress The IP address of the participant
/// @param port The port number of the participant /// @param port The port number of the participant
/// @return The participant or a nullptr when it could not be found /// @return The participant or a nullptr when it could not be found
Participant* Get(const char* ipAddress, unsigned int port); //Participant* Get(const char* ipAddress, unsigned int port);
/// @brief Retrieve a participant by its network ID /// @brief Retrieve a participant by its network ID
/// @param networkID The network ID of the participant /// @param networkID The network ID of the participant
/// @return The participant or a nullptr when it could not be found /// @return The participant or a nullptr when it could not be found
@ -24,7 +25,8 @@ class ParticipantRegistry {
/// @param ipAddress The IP address of the participant /// @param ipAddress The IP address of the participant
/// @param port The port number of the participant /// @param port The port number of the participant
/// @return The added participant /// @return The added participant
Participant* Add(const char* ipAddress, unsigned int port); //Participant* Add(const char* ipAddress, unsigned int port);
/// @brief Add a participant /// @brief Add a participant
/// @param participant The participant to add /// @param participant The participant to add
void Add(Participant* participant); void Add(Participant* participant);
@ -52,6 +54,7 @@ class ParticipantRegistry {
std::list<Participant*> participants; std::list<Participant*> participants;
#endif #endif
}; };
*/
/// @brief A participant is a device which manages things. /// @brief A participant is a device which manages things.
/// It can communicate with other participant to synchronise the state of /// It can communicate with other participant to synchronise the state of
@ -88,15 +91,6 @@ class Participant {
/// @brief The name of the participant /// @brief The name of the participant
const char* name = "Participant"; const char* name = "Participant";
/// @brief The Ip Address of a participant.
/// @remarks This does not belong here, it should move to ParticipantUDP or
/// something like that in the future
const char* ipAddress = "0.0.0.0";
/// @brief The port number for UDP communication with the participant.
/// @remarks This does not belong here, it should move to ParticipantUDP or
/// something like that in the future
unsigned int port = 0;
/// @brief The network Id to identify the participant /// @brief The network Id to identify the participant
unsigned char networkId = 0; unsigned char networkId = 0;
@ -143,12 +137,12 @@ class Participant {
#pragma endregion Send #pragma endregion Send
#pragma region Participant Registry // #pragma region Participant Registry
public: // public:
static ParticipantRegistry registry; // static ParticipantRegistry registry;
#pragma endregion Participant Registry // #pragma endregion Participant Registry
}; };
} // namespace RoboidControl } // namespace RoboidControl

View File

@ -1,14 +1,16 @@
/*
#include "IsolatedParticipant.h" #include "IsolatedParticipant.h"
#include "ParticipantUDP.h" #include "ParticipantUDP.h"
namespace RoboidControl { namespace RoboidControl {
static ParticipantUDP* isolatedParticipant = nullptr; static ParticipantUDPGeneric* isolatedParticipant = nullptr;
Participant* IsolatedParticipant::Isolated() { Participant* IsolatedParticipant::Isolated() {
if (isolatedParticipant == nullptr) if (isolatedParticipant == nullptr)
isolatedParticipant = new ParticipantUDP(0); isolatedParticipant = new ParticipantUDPGeneric(0);
return isolatedParticipant; return isolatedParticipant;
} }
} // namespace RoboidControl } // namespace RoboidControl
*/

View File

@ -1,3 +1,4 @@
/*
#include "Participant.h" #include "Participant.h"
namespace RoboidControl { namespace RoboidControl {
@ -10,4 +11,5 @@ class IsolatedParticipant {
static Participant* Isolated(); static Participant* Isolated();
}; };
} }
*/

View File

@ -16,14 +16,145 @@
namespace RoboidControl { namespace RoboidControl {
#pragma region ParticipantRegistry
ParticipantRegistry ParticipantUDPGeneric::registry;
RemoteParticipantUDP* ParticipantRegistry::Get(const char* ipAddress,
unsigned int port) {
#if !defined(NO_STD)
for (RemoteParticipantUDP* participant : ParticipantRegistry::participants) {
if (participant == nullptr)
continue;
if (strcmp(participant->ipAddress, ipAddress) == 0 &&
participant->port == port) {
// std::cout << "found participant " << participant->ipAddress << ":"
// << (int)participant->port << std::endl;
return participant;
}
}
std::cout << "Could not find participant " << ipAddress << ":" << (int)port
<< std::endl;
#endif
return nullptr;
}
RemoteParticipantUDP* ParticipantRegistry::Get(unsigned char participantId) {
#if !defined(NO_STD)
for (RemoteParticipantUDP* participant : ParticipantRegistry::participants) {
if (participant == nullptr)
continue;
if (participant->networkId == participantId)
return participant;
}
std::cout << "Could not find participant " << (int)participantId << std::endl;
#endif
return nullptr;
}
RemoteParticipantUDP* ParticipantRegistry::Add(const char* ipAddress,
unsigned int port) {
RemoteParticipantUDP* participant = new RemoteParticipantUDP(ipAddress, port);
Add(participant);
return participant;
}
void ParticipantRegistry::Add(RemoteParticipantUDP* participant) {
Participant* foundParticipant = Get(participant->networkId);
// Get(participant->ipAddress, participant->port);
if (foundParticipant == nullptr) {
#if defined(NO_STD)
// this->things[this->thingCount++] = thing;
#else
ParticipantRegistry::participants.push_back(participant);
#endif
// std::cout << "Add participant " << participant->ipAddress << ":"
// << participant->port << "[" << (int)participant->networkId
// << "]\n";
// std::cout << "participants " <<
// ParticipantRegistry::participants.size()
// << "\n";
// } else {
// std::cout << "Did not add, existing participant " <<
// participant->ipAddress
// << ":" << participant->port << "[" <<
// (int)participant->networkId
// << "]\n";
}
}
void ParticipantRegistry::Remove(RemoteParticipantUDP* participant) {
// participants.remove(participant);
}
#if defined(NO_STD)
RemoteParticipantUDP** ParticipantRegistry::GetAll() const {
return ParticipantRegistry::participants;
}
#else
const std::list<RemoteParticipantUDP*>& ParticipantRegistry::GetAll() const {
return ParticipantRegistry::participants;
}
#endif
#pragma endregion ParticipantRegistry
RemoteParticipantUDP::RemoteParticipantUDP(const char* ipAddress, int port) {
// make a copy of the ip address string
int addressLength = (int)strlen(ipAddress);
int stringLength = addressLength + 1;
char* addressString = new char[stringLength];
#if defined(_WIN32) || defined(_WIN64)
strncpy_s(addressString, stringLength, ipAddress,
addressLength); // Leave space for null terminator
#else
strncpy(addressString, ipAddress, addressLength);
#endif
addressString[addressLength] = '\0';
this->ipAddress = addressString;
this->port = port;
}
bool RemoteParticipantUDP::Send(IMessage* msg) {
int bufferSize = msg->Serialize(this->buffer);
if (bufferSize <= 0)
return true;
// std::cout << "send msg " << (static_cast<int>(this->buffer[0]) & 0xff)
// << " to " << this->ipAddress << std::endl;
// #if defined(_WIN32) || defined(_WIN64)
// Windows::ParticipantUDP* thisWindows =
// static_cast<Windows::ParticipantUDP*>(this);
// return thisWindows->SendTo(this, bufferSize);
// #elif defined(__unix__) || defined(__APPLE__)
// Posix::ParticipantUDP* thisPosix =
// static_cast<Posix::ParticipantUDP*>(this); return thisPosix->SendTo(this,
// bufferSize);
// #elif defined(ARDUINO)
// Arduino::ParticipantUDP* thisArduino =
// static_cast<Arduino::ParticipantUDP*>(this);
// return thisArduino->SendTo(this, bufferSize);
// #elif defined(IDF_VER)
// EspIdf::ParticipantUDP* thisEspIdf =
// static_cast<EspIdf::ParticipantUDP*>(this);
// return thisEspIdf->SendTo(this, bufferSize);
// #else
return false;
// #endif
}
#pragma region Init #pragma region Init
ParticipantUDP::ParticipantUDP(int port) : Participant("127.0.0.1", port) { ParticipantUDPGeneric::ParticipantUDPGeneric(int port)
: RemoteParticipantUDP("127.0.0.1", port) {
this->name = "ParticipantUDP"; this->name = "ParticipantUDP";
this->remoteSite = nullptr; this->remoteSite = nullptr;
if (this->port == 0) if (this->port == 0)
this->isIsolated = true; this->isIsolated = true;
Participant::registry.Add(this); registry.Add(this);
this->root = Thing::LocalRoot(); //::LocalParticipant->root; this->root = Thing::LocalRoot(); //::LocalParticipant->root;
this->root->owner = this; this->root->owner = this;
@ -34,14 +165,16 @@ ParticipantUDP::ParticipantUDP(int port) : Participant("127.0.0.1", port) {
Participant::ReplaceLocalParticipant(*this); Participant::ReplaceLocalParticipant(*this);
} }
ParticipantUDP::ParticipantUDP(const char* ipAddress, int port, int localPort) ParticipantUDPGeneric::ParticipantUDPGeneric(const char* ipAddress,
: Participant("127.0.0.1", localPort) { int port,
int localPort)
: RemoteParticipantUDP("127.0.0.1", localPort) {
this->name = "ParticipantUDP"; this->name = "ParticipantUDP";
if (this->port == 0) if (this->port == 0)
this->isIsolated = true; this->isIsolated = true;
else else
this->remoteSite = new Participant(ipAddress, port); this->remoteSite = new RemoteParticipantUDP(ipAddress, port);
Participant::registry.Add(this); registry.Add(this);
this->root = Thing::LocalRoot(); // Participant::LocalParticipant->root; this->root = Thing::LocalRoot(); // Participant::LocalParticipant->root;
this->root->owner = this; this->root->owner = this;
@ -52,14 +185,15 @@ ParticipantUDP::ParticipantUDP(const char* ipAddress, int port, int localPort)
Participant::ReplaceLocalParticipant(*this); Participant::ReplaceLocalParticipant(*this);
} }
void ParticipantUDP::begin() { void ParticipantUDPGeneric::begin() {
if (this->isIsolated || this->remoteSite == nullptr) if (this->isIsolated || this->remoteSite == nullptr)
return; return;
SetupUDP(this->port, this->remoteSite->ipAddress, this->remoteSite->port); SetupUDP(this->port, this->remoteSite->ipAddress, this->remoteSite->port);
} }
void ParticipantUDP::SetupUDP(int localPort, /*
void ParticipantUDPGeneric::SetupUDP(int localPort,
const char* remoteIpAddress, const char* remoteIpAddress,
int remotePort) { int remotePort) {
#if defined(_WIN32) || defined(_WIN64) #if defined(_WIN32) || defined(_WIN64)
@ -80,6 +214,7 @@ void ParticipantUDP::SetupUDP(int localPort,
#endif #endif
this->connected = true; this->connected = true;
} }
*/
#pragma endregion Init #pragma endregion Init
@ -89,32 +224,38 @@ void ParticipantUDP::SetupUDP(int localPort,
// 1. receive external messages // 1. receive external messages
// 2. update the state // 2. update the state
// 3. send out the updated messages // 3. send out the updated messages
void ParticipantUDP::Update(bool recurse) { void ParticipantUDPGeneric::Update(bool recurse) {
unsigned long currentTimeMs = Thing::GetTimeMs(); unsigned long currentTimeMs = Thing::GetTimeMs();
if (this->isIsolated == false) { if (this->isIsolated == false) {
if (this->connected == false) if (this->connected == false)
begin(); begin();
// EspIdf::ParticipantUDP* thisEspIdf =
// static_cast<EspIdf::ParticipantUDP*>(this);
// thisEspIdf->SendTest();
if (this->publishInterval > 0 && currentTimeMs > this->nextPublishMe) { if (this->publishInterval > 0 && currentTimeMs > this->nextPublishMe) {
ParticipantMsg* msg = new ParticipantMsg(this->networkId); ParticipantMsg* msg = new ParticipantMsg(this->networkId);
if (this->remoteSite == nullptr) if (this->remoteSite == nullptr)
this->Publish(msg); this->Publish(msg);
else else
this->Send(msg); this->Send(msg);
// thisEspIdf->SendTest();
delete msg; delete msg;
this->nextPublishMe = currentTimeMs + this->publishInterval; this->nextPublishMe = currentTimeMs + this->publishInterval;
} }
this->ReceiveUDP(); // this->ReceiveUDP();
} }
UpdateMyThings(); // UpdateMyThings();
UpdateOtherThings(); // UpdateOtherThings();
} }
void ParticipantUDP::UpdateMyThings() { void ParticipantUDPGeneric::UpdateMyThings() {
std::cout << "# things = " << this->things.size() << std::endl; std::cout << "# things = " << this->things.size() << std::endl;
for (Thing* thing : this->things) { for (Thing* thing : this->things) {
std::cout << ".\n"; std::cout << ".\n";
@ -133,13 +274,13 @@ void ParticipantUDP::UpdateMyThings() {
} }
} }
void ParticipantUDP::UpdateOtherThings() { void ParticipantUDPGeneric::UpdateOtherThings() {
#if defined(NO_STD) #if defined(NO_STD)
Participant** participants = Participant::registry.GetAll(); Participant** participants = Participant::registry.GetAll();
for (int ix = 0; ix < Participant::registry.count; ix++) { for (int ix = 0; ix < Participant::registry.count; ix++) {
Participant* participant = participants[ix]; Participant* participant = participants[ix];
#else #else
for (Participant* participant : Participant::registry.GetAll()) { for (Participant* participant : registry.GetAll()) {
#endif #endif
if (participant == nullptr || participant == this) if (participant == nullptr || participant == this)
continue; continue;
@ -167,8 +308,8 @@ void ParticipantUDP::UpdateOtherThings() {
#pragma region Send #pragma region Send
void ParticipantUDP::SendThingInfo(Participant* remoteParticipant, void ParticipantUDPGeneric::SendThingInfo(Participant* remoteParticipant,
Thing* thing) { Thing* thing) {
// std::cout << "Send thing info [" << (int)thing->id << "] \n"; // std::cout << "Send thing info [" << (int)thing->id << "] \n";
ThingMsg* thingMsg = new ThingMsg(this->networkId, thing); ThingMsg* thingMsg = new ThingMsg(this->networkId, thing);
remoteParticipant->Send(thingMsg); remoteParticipant->Send(thingMsg);
@ -187,14 +328,14 @@ void ParticipantUDP::SendThingInfo(Participant* remoteParticipant,
delete binaryMsg; delete binaryMsg;
} }
bool ParticipantUDP::Send(IMessage* msg) { bool ParticipantUDPGeneric::Send(IMessage* msg) {
if (this->remoteSite != nullptr) if (this->remoteSite != nullptr)
return this->remoteSite->Send(msg); return this->remoteSite->Send(msg);
return true; return true;
} }
void ParticipantUDP::PublishThingInfo(Thing* thing) { void ParticipantUDPGeneric::PublishThingInfo(Thing* thing) {
// std::cout << "Publish thing info" << thing->networkId << "\n"; // std::cout << "Publish thing info" << thing->networkId << "\n";
// Strange, when publishing, the network id is irrelevant, because it is // Strange, when publishing, the network id is irrelevant, because it is
// connected to a specific site... // connected to a specific site...
@ -215,7 +356,8 @@ void ParticipantUDP::PublishThingInfo(Thing* thing) {
delete customMsg; delete customMsg;
} }
bool ParticipantUDP::Publish(IMessage* msg) { /*
bool ParticipantUDPGeneric::Publish(IMessage* msg) {
// std::cout << "publish msg\n"; // std::cout << "publish msg\n";
#if defined(_WIN32) || defined(_WIN64) #if defined(_WIN32) || defined(_WIN64)
Windows::ParticipantUDP* thisWindows = Windows::ParticipantUDP* thisWindows =
@ -236,13 +378,15 @@ bool ParticipantUDP::Publish(IMessage* msg) {
return false; return false;
#endif #endif
} }
*/
// Send // Send
#pragma endregion #pragma endregion
#pragma region Receive #pragma region Receive
void ParticipantUDP::ReceiveUDP() { /*
void ParticipantUDPGeneric::ReceiveUDP() {
#if defined(_WIN32) || defined(_WIN64) #if defined(_WIN32) || defined(_WIN64)
Windows::ParticipantUDP* thisWindows = Windows::ParticipantUDP* thisWindows =
static_cast<Windows::ParticipantUDP*>(this); static_cast<Windows::ParticipantUDP*>(this);
@ -260,26 +404,28 @@ void ParticipantUDP::ReceiveUDP() {
thisEspIdf->Receive(); thisEspIdf->Receive();
#endif #endif
} }
*/
void ParticipantUDP::ReceiveData(unsigned char packetSize, void ParticipantUDPGeneric::ReceiveData(unsigned char packetSize,
char* senderIpAddress, char* senderIpAddress,
unsigned int senderPort) { unsigned int senderPort) {
// std::cout << "Receive data from " << senderIpAddress << ":" << senderPort // std::cout << "Receive data from " << senderIpAddress << ":" << senderPort
// << std::endl; // << std::endl;
Participant* sender = this->registry.Get(senderIpAddress, senderPort); RemoteParticipantUDP* sender =
this->registry.Get(senderIpAddress, senderPort);
if (sender == nullptr) { if (sender == nullptr) {
sender = this->registry.Add(senderIpAddress, senderPort); sender = this->registry.Add(senderIpAddress, senderPort);
#if !defined(NO_STD) #if !defined(NO_STD)
std::cout << "New remote participant " << sender->ipAddress << ":" // std::cout << "New remote participant " << sender->ipAddress << ":"
<< sender->port << std::endl; // << sender->port << std::endl;
#endif #endif
} }
ReceiveData(packetSize, sender); ReceiveData(packetSize, sender);
} }
void ParticipantUDP::ReceiveData(unsigned char bufferSize, void ParticipantUDPGeneric::ReceiveData(unsigned char bufferSize,
Participant* sender) { RemoteParticipantUDP* sender) {
unsigned char msgId = this->buffer[0]; unsigned char msgId = this->buffer[0];
// std::cout << "receive msg " << (int)msgId << "\n"; // std::cout << "receive msg " << (int)msgId << "\n";
// std::cout << " buffer size = " <<(int) bufferSize << "\n"; // std::cout << " buffer size = " <<(int) bufferSize << "\n";
@ -352,14 +498,16 @@ void ParticipantUDP::ReceiveData(unsigned char bufferSize,
#endif #endif
} }
void ParticipantUDP::Process(Participant* sender, ParticipantMsg* msg) { void ParticipantUDPGeneric::Process(RemoteParticipantUDP* sender,
ParticipantMsg* msg) {
#if defined(DEBUG) #if defined(DEBUG)
std::cout << this->name << ": Process ParticipantMsg " << (int)msg->networkId std::cout << this->name << ": Process ParticipantMsg " << (int)msg->networkId
<< "\n"; << "\n";
#endif #endif
} }
void ParticipantUDP::Process(Participant* sender, NetworkIdMsg* msg) { void ParticipantUDPGeneric::Process(RemoteParticipantUDP* sender,
NetworkIdMsg* msg) {
#if defined(DEBUG) #if defined(DEBUG)
std::cout << this->name << ": process NetworkIdMsg " << (int)this->networkId std::cout << this->name << ": process NetworkIdMsg " << (int)this->networkId
<< " -> " << (int)msg->networkId << "\n"; << " -> " << (int)msg->networkId << "\n";
@ -374,24 +522,26 @@ void ParticipantUDP::Process(Participant* sender, NetworkIdMsg* msg) {
} }
} }
void ParticipantUDP::Process(Participant* sender, InvestigateMsg* msg) { void ParticipantUDPGeneric::Process(RemoteParticipantUDP* sender,
InvestigateMsg* msg) {
#if defined(DEBUG) #if defined(DEBUG)
std::cout << this->name << ": Process InvestigateMsg [" << (int)msg->networkId std::cout << this->name << ": Process InvestigateMsg [" << (int)msg->networkId
<< "/" << (int)msg->thingId << "]\n"; << "/" << (int)msg->thingId << "]\n";
#endif #endif
} }
void ParticipantUDP::Process(Participant* sender, ThingMsg* msg) { void ParticipantUDPGeneric::Process(RemoteParticipantUDP* sender,
ThingMsg* msg) {
#if defined(DEBUG) #if defined(DEBUG)
std::cout << this->name << ": process ThingMsg [" << (int)msg->networkId std::cout << this->name << ": process ThingMsg [" << (int)msg->networkId
<< "/" << (int)msg->thingId << "] " << (int)msg->thingType << " " << "/" << (int)msg->thingId << "] " << (int)msg->thingType << " "
<< (int)msg->parentId << "\n"; << (int)msg->parentId << "\n";
#endif #endif
Participant* owner = Participant::registry.Get(msg->networkId); RemoteParticipantUDP* owner = registry.Get(msg->networkId);
if (owner == nullptr) { if (owner == nullptr) {
owner = new Participant(); owner = new RemoteParticipantUDP(sender->ipAddress, sender->port);
owner->networkId = msg->networkId; owner->networkId = msg->networkId;
Participant::registry.Add(owner); registry.Add(owner);
} }
Thing* thing = owner->Get(msg->networkId, msg->thingId); Thing* thing = owner->Get(msg->networkId, msg->thingId);
@ -411,9 +561,9 @@ void ParticipantUDP::Process(Participant* sender, ThingMsg* msg) {
thing->SetParent(nullptr); thing->SetParent(nullptr);
} }
Thing* ParticipantUDP::ProcessNewThing(Participant* owner, Thing* ParticipantUDPGeneric::ProcessNewThing(RemoteParticipantUDP* owner,
ThingMsg* msg, ThingMsg* msg,
bool isRemote) { bool isRemote) {
switch (msg->thingType) { switch (msg->thingType) {
case Thing::Type::DistanceSensor: case Thing::Type::DistanceSensor:
return new DistanceSensor(owner->root); return new DistanceSensor(owner->root);
@ -426,7 +576,8 @@ Thing* ParticipantUDP::ProcessNewThing(Participant* owner,
} }
} }
void ParticipantUDP::Process(Participant* sender, NameMsg* msg) { void ParticipantUDPGeneric::Process(RemoteParticipantUDP* sender,
NameMsg* msg) {
#if defined(DEBUG) #if defined(DEBUG)
std::cout << this->name << ": process NameMsg [" << (int)msg->networkId << "/" std::cout << this->name << ": process NameMsg [" << (int)msg->networkId << "/"
<< (int)msg->thingId << "] "; << (int)msg->thingId << "] ";
@ -458,19 +609,21 @@ void ParticipantUDP::Process(Participant* sender, NameMsg* msg) {
#endif #endif
} }
void ParticipantUDP::Process(Participant* sender, ModelUrlMsg* msg) { void ParticipantUDPGeneric::Process(RemoteParticipantUDP* sender,
ModelUrlMsg* msg) {
#if defined(DEBUG) #if defined(DEBUG)
std::cout << this->name << ": process ModelUrlMsg [" << (int)msg->networkId std::cout << this->name << ": process ModelUrlMsg [" << (int)msg->networkId
<< "/" << (int)msg->thingId << "]\n"; << "/" << (int)msg->thingId << "]\n";
#endif #endif
} }
void ParticipantUDP::Process(Participant* sender, PoseMsg* msg) { void ParticipantUDPGeneric::Process(RemoteParticipantUDP* sender,
PoseMsg* msg) {
#if !defined(DEBUG) && !defined(NO_STD) #if !defined(DEBUG) && !defined(NO_STD)
std::cout << this->name << ": process PoseMsg [" << (int)this->networkId std::cout << this->name << ": process PoseMsg [" << (int)this->networkId
<< "/" << (int)msg->networkId << "] " << (int)msg->poseType << "\n"; << "/" << (int)msg->networkId << "] " << (int)msg->poseType << "\n";
#endif #endif
Participant* owner = Participant::registry.Get(msg->networkId); Participant* owner = registry.Get(msg->networkId);
if (owner == nullptr) if (owner == nullptr)
return; return;
@ -488,13 +641,14 @@ void ParticipantUDP::Process(Participant* sender, PoseMsg* msg) {
thing->SetAngularVelocity(msg->angularVelocity); thing->SetAngularVelocity(msg->angularVelocity);
} }
void ParticipantUDP::Process(Participant* sender, BinaryMsg* msg) { void ParticipantUDPGeneric::Process(RemoteParticipantUDP* sender,
BinaryMsg* msg) {
#if defined(DEBUG) #if defined(DEBUG)
std::cout << this->name << ": process BinaryMsg [" << (int)msg->networkId std::cout << this->name << ": process BinaryMsg [" << (int)msg->networkId
<< "/" << (int)msg->thingId << "]\n"; << "/" << (int)msg->thingId << "]\n";
#endif #endif
Participant* owner = Participant::registry.Get(msg->networkId); Participant* owner = registry.Get(msg->networkId);
if (owner != nullptr) { if (owner != nullptr) {
Thing* thing = owner->Get(msg->networkId, msg->thingId); Thing* thing = owner->Get(msg->networkId, msg->thingId);
if (thing != nullptr) if (thing != nullptr)
@ -510,14 +664,16 @@ void ParticipantUDP::Process(Participant* sender, BinaryMsg* msg) {
} }
} }
void ParticipantUDP::Process(Participant* sender, TextMsg* msg) { void ParticipantUDPGeneric::Process(RemoteParticipantUDP* sender,
TextMsg* msg) {
#if defined(DEBUG) #if defined(DEBUG)
std::cout << this->name << ": process TextMsg " << (int)msg->textLength << " " std::cout << this->name << ": process TextMsg " << (int)msg->textLength << " "
<< (int)msg->text << "\n"; << (int)msg->text << "\n";
#endif #endif
} }
void ParticipantUDP::Process(Participant* sender, DestroyMsg* msg) { void ParticipantUDPGeneric::Process(RemoteParticipantUDP* sender,
DestroyMsg* msg) {
#if defined(DEBUG) #if defined(DEBUG)
std::cout << this->name << ": process Destroy [" << (int)msg->networkId << "/" std::cout << this->name << ": process Destroy [" << (int)msg->networkId << "/"
<< (int)msg->thingId << "]\n"; << (int)msg->thingId << "]\n";

View File

@ -5,11 +5,11 @@
#include "Messages/InvestigateMsg.h" #include "Messages/InvestigateMsg.h"
#include "Messages/ModelUrlMsg.h" #include "Messages/ModelUrlMsg.h"
#include "Messages/NameMsg.h" #include "Messages/NameMsg.h"
#include "Messages/NetworkIdMsg.h"
#include "Messages/ParticipantMsg.h" #include "Messages/ParticipantMsg.h"
#include "Messages/PoseMsg.h" #include "Messages/PoseMsg.h"
#include "Messages/NetworkIdMsg.h"
#include "Messages/ThingMsg.h"
#include "Messages/TextMsg.h" #include "Messages/TextMsg.h"
#include "Messages/ThingMsg.h"
#include "Participant.h" #include "Participant.h"
#if !defined(NO_STD) #if !defined(NO_STD)
@ -31,6 +31,74 @@ namespace RoboidControl {
constexpr int MAX_SENDER_COUNT = 256; constexpr int MAX_SENDER_COUNT = 256;
class RemoteParticipantUDP : public Participant {
public:
/// @brief Create a new participant with the given communcation info
/// @param ipAddress The IP address of the participant
/// @param port The UDP port of the participant
/// @remarks This does not belong here, it should move to ParticipantUDP or
/// something like that in the future
RemoteParticipantUDP(const char* ipAddress, int port);
/// @brief The Ip Address of a participant.
/// @remarks This does not belong here, it should move to ParticipantUDP or
/// something like that in the future
const char* ipAddress = "0.0.0.0";
/// @brief The port number for UDP communication with the participant.
/// @remarks This does not belong here, it should move to ParticipantUDP or
/// something like that in the future
unsigned int port = 0;
bool Send(IMessage* msg) override;
};
/// @brief class which manages all known participants
class ParticipantRegistry {
public:
/// @brief Retrieve a participant by its address
/// @param ipAddress The IP address of the participant
/// @param port The port number of the participant
/// @return The participant or a nullptr when it could not be found
RemoteParticipantUDP* Get(const char* ipAddress, unsigned int port);
/// @brief Retrieve a participant by its network ID
/// @param networkID The network ID of the participant
/// @return The participant or a nullptr when it could not be found
RemoteParticipantUDP* Get(unsigned char networkID);
/// @brief Add a participant with the given details
/// @param ipAddress The IP address of the participant
/// @param port The port number of the participant
/// @return The added participant
RemoteParticipantUDP* Add(const char* ipAddress, unsigned int port);
/// @brief Add a participant
/// @param participant The participant to add
void Add(RemoteParticipantUDP* participant);
/// @brief Remove a participant
/// @param participant The participant to remove
void Remove(RemoteParticipantUDP* participant);
private:
#if defined(NO_STD)
public:
RemoteParticipantUDP** GetAll() const;
int count = 0;
private:
RemoteParticipantUDP** participants;
#else
public:
/// @brief Get all participants
/// @return All participants
const std::list<RemoteParticipantUDP*>& GetAll() const;
private:
/// @brief The list of known participants
std::list<RemoteParticipantUDP*> participants;
#endif
};
/// @brief A participant using UDP communication /// @brief A participant using UDP communication
/// A local participant is the local device which can communicate with /// A local participant is the local device which can communicate with
/// other participants It manages all local things and communcation with other /// other participants It manages all local things and communcation with other
@ -43,8 +111,7 @@ constexpr int MAX_SENDER_COUNT = 256;
/// participant is created which can be obtained using /// participant is created which can be obtained using
/// RoboidControl::IsolatedParticipant::Isolated(). /// RoboidControl::IsolatedParticipant::Isolated().
/// @sa RoboidControl::Thing::Thing() /// @sa RoboidControl::Thing::Thing()
class ParticipantUDP : public Participant { class ParticipantUDPGeneric : public RemoteParticipantUDP {
#pragma region Init #pragma region Init
public: public:
@ -53,31 +120,32 @@ class ParticipantUDP : public Participant {
/// These participant typically broadcast Participant messages to let site /// These participant typically broadcast Participant messages to let site
/// servers on the local network know their presence. Alternatively they can /// servers on the local network know their presence. Alternatively they can
/// broadcast information which can be used directly by other participants. /// broadcast information which can be used directly by other participants.
ParticipantUDP(int port = 7681); ParticipantUDPGeneric(int port = 7681);
/// @brief Create a participant which will try to connect to a site. /// @brief Create a participant which will try to connect to a site.
/// @param ipAddress The IP address of the site /// @param ipAddress The IP address of the site
/// @param port The port used by the site /// @param port The port used by the site
/// @param localPort The port used by the local participant /// @param localPort The port used by the local participant
ParticipantUDP(const char* ipAddress, int port = 7681, int localPort = 7681); ParticipantUDPGeneric(const char* ipAddress,
int port = 7681,
int localPort = 7681);
#pragma endregion Init #pragma endregion Init
#pragma region Properties #pragma region Properties
public: public:
/// @brief True if the participant is running isolated. /// @brief True if the participant is running isolated.
/// Isolated participants do not communicate with other participants /// Isolated participants do not communicate with other participants
bool isIsolated = false; bool isIsolated = false;
/// @brief The remote site when this participant is connected to a site /// @brief The remote site when this participant is connected to a site
Participant* remoteSite = nullptr; RemoteParticipantUDP* remoteSite = nullptr;
/// The interval in milliseconds for publishing (broadcasting) data on the /// The interval in milliseconds for publishing (broadcasting) data on the
/// local network /// local network
long publishInterval = 3000; // 3 seconds long publishInterval = 3000; // 3 seconds
protected: protected:
#if !defined(ARDUINO) #if !defined(ARDUINO)
#if defined(__unix__) || defined(__APPLE__) #if defined(__unix__) || defined(__APPLE__)
int sock; int sock;
@ -102,7 +170,7 @@ public:
unsigned long nextPublishMe = 0; unsigned long nextPublishMe = 0;
/// @brief Prepare the local things for the next update /// @brief Prepare the local things for the next update
//virtual void PrepMyThings(); // virtual void PrepMyThings();
virtual void UpdateMyThings(); virtual void UpdateMyThings();
virtual void UpdateOtherThings(); virtual void UpdateOtherThings();
@ -113,39 +181,46 @@ public:
void SendThingInfo(Participant* remoteParticipant, Thing* thing); void SendThingInfo(Participant* remoteParticipant, Thing* thing);
void PublishThingInfo(Thing* thing); void PublishThingInfo(Thing* thing);
virtual bool Send(IMessage* msg) override; virtual bool Send(IMessage* msg);
bool Publish(IMessage* msg); virtual bool Publish(IMessage* msg) = 0;
#pragma endregion Send #pragma endregion Send
#pragma region Receive #pragma region Receive
protected: protected:
void ReceiveData(unsigned char bufferSize, void ReceiveData(unsigned char bufferSize,
char* senderIpAddress, char* senderIpAddress,
unsigned int senderPort); unsigned int senderPort);
void ReceiveData(unsigned char bufferSize, Participant* remoteParticipant); void ReceiveData(unsigned char bufferSize, RemoteParticipantUDP* remoteParticipant);
void SetupUDP(int localPort, const char* remoteIpAddress, int remotePort); virtual void SetupUDP(int localPort, const char* remoteIpAddress, int remotePort) = 0;
void ReceiveUDP(); virtual void ReceiveUDP() = 0;
virtual void Process(Participant* sender, ParticipantMsg* msg); virtual void Process(RemoteParticipantUDP* sender, ParticipantMsg* msg);
virtual void Process(Participant* sender, NetworkIdMsg* msg); virtual void Process(RemoteParticipantUDP* sender, NetworkIdMsg* msg);
virtual void Process(Participant* sender, InvestigateMsg* msg); virtual void Process(RemoteParticipantUDP* sender, InvestigateMsg* msg);
virtual void Process(Participant* sender, ThingMsg* msg); virtual void Process(RemoteParticipantUDP* sender, ThingMsg* msg);
virtual Thing* ProcessNewThing(Participant* sender, ThingMsg* msg, bool isRemote); virtual Thing* ProcessNewThing(RemoteParticipantUDP* sender,
ThingMsg* msg,
bool isRemote);
virtual void Process(Participant* sender, NameMsg* msg); virtual void Process(RemoteParticipantUDP* sender, NameMsg* msg);
virtual void Process(Participant* sender, ModelUrlMsg* msg); virtual void Process(RemoteParticipantUDP* sender, ModelUrlMsg* msg);
virtual void Process(Participant* sender, PoseMsg* msg); virtual void Process(RemoteParticipantUDP* sender, PoseMsg* msg);
virtual void Process(Participant* sender, BinaryMsg* msg); virtual void Process(RemoteParticipantUDP* sender, BinaryMsg* msg);
virtual void Process(Participant* sender, TextMsg* msg); virtual void Process(RemoteParticipantUDP* sender, TextMsg* msg);
virtual void Process(Participant* sender, DestroyMsg* msg); virtual void Process(RemoteParticipantUDP* sender, DestroyMsg* msg);
#pragma endregion Receive #pragma endregion Receive
public:
static ParticipantRegistry registry;
}; };
} // namespace RoboidControl } // namespace RoboidControl
#include "EspIdf/EspIdfParticipant.h"

View File

@ -11,11 +11,11 @@ namespace RoboidControl {
#pragma region Init #pragma region Init
SiteServer::SiteServer(int port) : ParticipantUDP(port) { SiteServer::SiteServer(int port) : ParticipantUDPGeneric(port) {
this->name = "Site Server"; this->name = "Site Server";
this->publishInterval = 0; this->publishInterval = 0;
SetupUDP(port, ipAddress, 0); //SetupUDP(port, ipAddress, 0);
} }
#pragma endregion Init #pragma endregion Init
@ -36,7 +36,7 @@ void SiteServer::UpdateMyThings() {
for (int ix = 0; ix < Participant::registry.count; ix++) { for (int ix = 0; ix < Participant::registry.count; ix++) {
Participant* participant = participants[ix]; Participant* participant = participants[ix];
#else #else
for (Participant* participant : Participant::registry.GetAll()) { for (Participant* participant : registry.GetAll()) {
#endif #endif
if (participant == nullptr || participant == this) if (participant == nullptr || participant == this)
continue; continue;
@ -56,7 +56,7 @@ void SiteServer::UpdateMyThings() {
#pragma region Receive #pragma region Receive
void SiteServer::Process(Participant* sender, ParticipantMsg* msg) { void SiteServer::Process(RemoteParticipantUDP* sender, ParticipantMsg* msg) {
if (msg->networkId != sender->networkId) { if (msg->networkId != sender->networkId) {
// std::cout << this->name << " received New Client -> " << // std::cout << this->name << " received New Client -> " <<
// sender->ipAddress // sender->ipAddress
@ -67,9 +67,9 @@ void SiteServer::Process(Participant* sender, ParticipantMsg* msg) {
} }
} }
void SiteServer::Process(Participant* sender, NetworkIdMsg* msg) {} void SiteServer::Process(RemoteParticipantUDP* sender, NetworkIdMsg* msg) {}
void SiteServer::Process(Participant* sender, ThingMsg* msg) { void SiteServer::Process(RemoteParticipantUDP* sender, ThingMsg* msg) {
Thing* thing = sender->Get(msg->networkId, msg->thingId); Thing* thing = sender->Get(msg->networkId, msg->thingId);
if (thing == nullptr) { if (thing == nullptr) {
// new Thing(sender, (Thing::Type)msg->thingType, msg->thingId); // new Thing(sender, (Thing::Type)msg->thingType, msg->thingId);

View File

@ -11,7 +11,7 @@
namespace RoboidControl { namespace RoboidControl {
/// @brief A participant is device which can communicate with other participants /// @brief A participant is device which can communicate with other participants
class SiteServer : public ParticipantUDP { class SiteServer : public ParticipantUDPGeneric {
#pragma region Init #pragma region Init
@ -33,9 +33,9 @@ class SiteServer : public ParticipantUDP {
protected: protected:
unsigned long nextPublishMe = 0; unsigned long nextPublishMe = 0;
virtual void Process(Participant* sender, ParticipantMsg* msg) override; virtual void Process(RemoteParticipantUDP* sender, ParticipantMsg* msg) override;
virtual void Process(Participant* sender, NetworkIdMsg* msg) override; virtual void Process(RemoteParticipantUDP* sender, NetworkIdMsg* msg) override;
virtual void Process(Participant* sender, ThingMsg* msg) override; virtual void Process(RemoteParticipantUDP* sender, ThingMsg* msg) override;
#pragma endregion Receive #pragma endregion Receive

View File

@ -1,4 +1,5 @@
#include "PosixParticipant.h" #include "PosixParticipant.h"
#if defined(__unix__) || defined(__APPLE__)
#if defined(__unix__) || defined(__APPLE__) #if defined(__unix__) || defined(__APPLE__)
#include <arpa/inet.h> #include <arpa/inet.h>
@ -9,7 +10,6 @@
#endif #endif
namespace RoboidControl { namespace RoboidControl {
namespace Posix {
void ParticipantUDP::Setup(int localPort, const char* remoteIpAddress, int remotePort) { void ParticipantUDP::Setup(int localPort, const char* remoteIpAddress, int remotePort) {
#if defined(__unix__) || defined(__APPLE__) #if defined(__unix__) || defined(__APPLE__)
@ -90,7 +90,7 @@ void ParticipantUDP::Receive() {
#endif #endif
} }
bool ParticipantUDP::SendTo(Participant* remoteParticipant, int bufferSize) { bool ParticipantUDP::SendTo(RemoteParticipantUDP* remoteParticipant, int bufferSize) {
#if defined(__unix__) || defined(__APPLE__) #if defined(__unix__) || defined(__APPLE__)
// std::cout << "Send to " << remoteParticipant->ipAddress << ":" << ntohs(remoteParticipant->port) // std::cout << "Send to " << remoteParticipant->ipAddress << ":" << ntohs(remoteParticipant->port)
// << "\n"; // << "\n";
@ -132,5 +132,6 @@ bool ParticipantUDP::Publish(IMessage* msg) {
return true; return true;
} }
} // namespace Posix
} // namespace RoboidControl } // namespace RoboidControl
#endif

View File

@ -1,15 +1,15 @@
#pragma once #pragma once
#if defined(__unix__) || defined(__APPLE__)
#include "Participants/ParticipantUDP.h" #include "Participants/ParticipantUDP.h"
namespace RoboidControl { namespace RoboidControl {
namespace Posix {
class ParticipantUDP : public RoboidControl::ParticipantUDP { class ParticipantUDP : public ParticipantUDPGeneric {
public: public:
void Setup(int localPort, const char* remoteIpAddress, int remotePort); void Setup(int localPort, const char* remoteIpAddress, int remotePort);
void Receive(); void Receive();
bool SendTo(Participant* remoteParticipant, int bufferSize); bool SendTo(RemoteParticipantUDP* remoteParticipant, int bufferSize);
bool Publish(IMessage* msg); bool Publish(IMessage* msg);
protected: protected:
@ -20,5 +20,5 @@ class ParticipantUDP : public RoboidControl::ParticipantUDP {
#endif #endif
}; };
} // namespace Posix
} // namespace RoboidControl } // namespace RoboidControl
#endif

View File

@ -10,7 +10,7 @@
namespace RoboidControl { namespace RoboidControl {
class Participant; class Participant;
class ParticipantUDP; class ParticipantUDPGeneric;
#define THING_STORE_SIZE 256 #define THING_STORE_SIZE 256
// IMPORTANT: values higher than 256 will need to change the Thing::id type // IMPORTANT: values higher than 256 will need to change the Thing::id type

View File

@ -1,4 +1,5 @@
#include "WindowsParticipant.h" #include "WindowsParticipant.h"
#if defined(_WIN32) || defined(_WIN64)
#if defined(_WIN32) || defined(_WIN64) #if defined(_WIN32) || defined(_WIN64)
#include <winsock2.h> #include <winsock2.h>
@ -7,7 +8,6 @@
#endif #endif
namespace RoboidControl { namespace RoboidControl {
namespace Windows {
void ParticipantUDP::Setup(int localPort, const char* remoteIpAddress, int remotePort) { void ParticipantUDP::Setup(int localPort, const char* remoteIpAddress, int remotePort) {
#if defined(_WIN32) || defined(_WIN64) #if defined(_WIN32) || defined(_WIN64)
@ -102,7 +102,7 @@ void ParticipantUDP::Receive() {
#endif // _WIN32 || _WIN64 #endif // _WIN32 || _WIN64
} }
bool ParticipantUDP::SendTo(Participant* remoteParticipant, int bufferSize) { bool ParticipantUDP::SendTo(RemoteParticipantUDP* remoteParticipant, int bufferSize) {
#if defined(_WIN32) || defined(_WIN64) #if defined(_WIN32) || defined(_WIN64)
char ip_str[INET_ADDRSTRLEN]; char ip_str[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &(remote_addr.sin_addr), ip_str, INET_ADDRSTRLEN); inet_ntop(AF_INET, &(remote_addr.sin_addr), ip_str, INET_ADDRSTRLEN);
@ -142,5 +142,6 @@ bool ParticipantUDP::Publish(IMessage* msg) {
return true; return true;
} }
} // namespace Windows
} // namespace RoboidControl } // namespace RoboidControl
#endif

View File

@ -1,15 +1,15 @@
#pragma once #pragma once
#if defined(_WIN32) || defined(_WIN64)
#include "Participants/ParticipantUDP.h" #include "Participants/ParticipantUDP.h"
namespace RoboidControl { namespace RoboidControl {
namespace Windows {
class ParticipantUDP : public RoboidControl::ParticipantUDP { class ParticipantUDP : public ParticipantUDPGeneric {
public: public:
void Setup(int localPort, const char* remoteIpAddress, int remotePort); void Setup(int localPort, const char* remoteIpAddress, int remotePort);
void Receive(); void Receive();
bool SendTo(Participant* remoteParticipant, int bufferSize); bool SendTo(RemoteParticipantUDP* remoteParticipant, int bufferSize);
bool Publish(IMessage* msg); bool Publish(IMessage* msg);
protected: protected:
@ -18,5 +18,5 @@ class ParticipantUDP : public RoboidControl::ParticipantUDP {
#endif #endif
}; };
} // namespace Windows
} // namespace RoboidControl } // namespace RoboidControl
#endif