diff --git a/Arduino/ArduinoParticipant.cpp b/Arduino/ArduinoParticipant.cpp index 7594171..2b9330a 100644 --- a/Arduino/ArduinoParticipant.cpp +++ b/Arduino/ArduinoParticipant.cpp @@ -19,7 +19,7 @@ namespace RoboidControl { namespace Arduino { -void LocalParticipant::Setup(int localPort, +void ParticipantUDP::Setup(int localPort, const char* remoteIpAddress, int remotePort) { #if defined(ARDUINO) && defined(HAS_WIFI) @@ -44,7 +44,7 @@ void LocalParticipant::Setup(int localPort, #endif } -void LocalParticipant::GetBroadcastAddress() { +void ParticipantUDP::GetBroadcastAddress() { #if defined(ARDUINO) && defined(HAS_WIFI) IPAddress broadcastAddress = WiFi.localIP(); broadcastAddress[3] = 255; @@ -56,7 +56,7 @@ void LocalParticipant::GetBroadcastAddress() { #endif } -void LocalParticipant::Receive() { +void ParticipantUDP::Receive() { #if defined(ARDUINO) && defined(HAS_WIFI) int packetSize = udp.parsePacket(); while (packetSize > 0) { @@ -86,7 +86,7 @@ void LocalParticipant::Receive() { #endif } -bool LocalParticipant::Send(Participant* remoteParticipant, int bufferSize) { +bool ParticipantUDP::Send(Participant* remoteParticipant, int bufferSize) { #if defined(ARDUINO) && defined(HAS_WIFI) // std::cout << "Sending to:\n " << remoteParticipant->ipAddress << ":" // << remoteParticipant->port << "\n"; @@ -106,7 +106,7 @@ bool LocalParticipant::Send(Participant* remoteParticipant, int bufferSize) { return true; } -bool LocalParticipant::Publish(IMessage* msg) { +bool ParticipantUDP::Publish(IMessage* msg) { #if defined(ARDUINO) && defined(HAS_WIFI) int bufferSize = msg->Serialize((char*)this->buffer); if (bufferSize <= 0) diff --git a/Arduino/ArduinoParticipant.h b/Arduino/ArduinoParticipant.h index 1cf39a0..94196d7 100644 --- a/Arduino/ArduinoParticipant.h +++ b/Arduino/ArduinoParticipant.h @@ -9,7 +9,7 @@ namespace RoboidControl { namespace Arduino { -class LocalParticipant : public RoboidControl::LocalParticipant { +class ParticipantUDP : public RoboidControl::ParticipantUDP { public: void Setup(int localPort, const char* remoteIpAddress, int remotePort); void Receive(); diff --git a/CMakeLists.txt b/CMakeLists.txt index 18722d8..09c1b91 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,6 +9,7 @@ file(GLOB srcs Windows/*.cpp EspIdf/*.cpp LinearAlgebra/*.cpp + Participants/*.cpp ) if(ESP_PLATFORM) diff --git a/EspIdf/EspIdfParticipant.cpp b/EspIdf/EspIdfParticipant.cpp index 8e4dd66..5dd9ca0 100644 --- a/EspIdf/EspIdfParticipant.cpp +++ b/EspIdf/EspIdfParticipant.cpp @@ -1,11 +1,13 @@ #include "EspIdfParticipant.h" +#if defined(IDF_VER) #include "esp_wifi.h" +#endif namespace RoboidControl { namespace EspIdf { -void LocalParticipant::Setup(int localPort, +void ParticipantUDP::Setup(int localPort, const char* remoteIpAddress, int remotePort) { #if defined(IDF_VER) @@ -43,41 +45,41 @@ void LocalParticipant::Setup(int localPort, return; } - // struct sockaddr_in dest_addr; - memset(dest_addr.sin_zero, 0, sizeof(dest_addr.sin_zero)); - dest_addr.sin_family = AF_INET; - dest_addr.sin_port = htons(this->remoteSite->port); - inet_pton(AF_INET, this->remoteSite->ipAddress, &dest_addr.sin_addr.s_addr); + // Initialize the dest_addr structure + memset(&this->dest_addr, 0, sizeof(this->dest_addr)); // Clear the entire structure + this->dest_addr.sin_family = AF_INET; + this->dest_addr.sin_port = htons(this->remoteSite->port); + inet_pton(AF_INET, this->remoteSite->ipAddress, &this->dest_addr.sin_addr.s_addr); std::cout << "Wifi sync started local " << this->port << ", remote " << this->remoteSite->ipAddress << ":" << this->remoteSite->port << "\n"; -#endif +#endif // IDF_VER } -void LocalParticipant::GetBroadcastAddress() { - esp_netif_ip_info_t ip_info; - esp_netif_t* esp_netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"); +void ParticipantUDP::GetBroadcastAddress() { + // SOMEHOW, THIS FUNCTION RESULTS IN MEMORY CORRUPION... - // Get IP information (IP address, netmask, gateway) - if (esp_netif_get_ip_info(esp_netif, &ip_info) != ESP_OK) { - std::cout << "Failed to get IP info\n"; - return; - } + // esp_netif_ip_info_t ip_info; + // esp_netif_t* esp_netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"); - ip_addr_t broadcast_addr = {}; - broadcast_addr.u_addr.ip4.addr = - (ip_info.ip.addr & ip_info.netmask.addr) | ~ip_info.netmask.addr; + // // Get IP information (IP address, netmask, gateway) + // if (esp_netif_get_ip_info(esp_netif, &ip_info) != ESP_OK) { + // std::cout << "Failed to get IP info\n"; + // return; + // } - this->broadcastIpAddress = new char[16]; // IPv4 address can have a max of 15 - // characters + null terminator - snprintf(this->broadcastIpAddress, 16, IPSTR, - IP2STR(&broadcast_addr.u_addr.ip4)); - std::cout << "Broadcast address: " << this->broadcastIpAddress << "\n"; + // ip_addr_t broadcast_addr = {}; + // broadcast_addr.u_addr.ip4.addr = + // (ip_info.ip.addr & ip_info.netmask.addr) | ~ip_info.netmask.addr; + + // snprintf(this->broadcastIpAddress, INET_ADDRSTRLEN, IPSTR, + // IP2STR(&broadcast_addr.u_addr.ip4)); + // std::cout << "Broadcast address: " << this->broadcastIpAddress << "\n"; } -void LocalParticipant::Receive() { +void ParticipantUDP::Receive() { #if defined(IDF_VER) struct pollfd fds; fds.fd = sockfd; @@ -90,20 +92,21 @@ void LocalParticipant::Receive() { return; } socklen_t addr_len = sizeof(this->src_addr); + char sender_ipAddress[INET_ADDRSTRLEN]; while (ret > 0 && fds.revents & POLLIN) { - int packetSize = recvfrom(sockfd, buffer, sizeof(buffer) - 1, 0, + int packetSize = recvfrom(this->sockfd, buffer, sizeof(buffer) - 1, 0, (struct sockaddr*)&this->src_addr, &addr_len); if (packetSize < 0) { std::cout << "recvfrom() error\n"; return; } - char sender_ipAddress[16]; - inet_ntoa_r(this->src_addr.sin_addr, sender_ipAddress, INET_ADDRSTRLEN); - unsigned int sender_port = ntohs(this->src_addr.sin_port); + std::cout << "receiving " << packetSize << " bytes\n"; + // inet_ntoa_r(this->src_addr.sin_addr, sender_ipAddress, INET_ADDRSTRLEN); + // unsigned int sender_port = ntohs(this->src_addr.sin_port); - ReceiveData(packetSize, sender_ipAddress, sender_port); + // ReceiveData(packetSize, sender_ipAddress, sender_port); int ret = poll(&fds, 1, 0); if (ret == -1) { @@ -112,15 +115,15 @@ void LocalParticipant::Receive() { } } -#endif +#endif // IDF_VER } -bool LocalParticipant::Send(Participant* remoteParticipant, int bufferSize) { +bool ParticipantUDP::Send(Participant* remoteParticipant, int bufferSize) { #if defined(IDF_VER) std::cout << "Sending to " << remoteParticipant->ipAddress << ":" << remoteParticipant->port << "\n"; - int err = sendto(sockfd, buffer, bufferSize, 0, (struct sockaddr*)&dest_addr, + int err = sendto(this->sockfd, buffer, bufferSize, 0, (struct sockaddr*)&dest_addr, sizeof(dest_addr)); if (errno != 0) std::cout << "Send error " << err << " or " << errno << "\n"; @@ -129,7 +132,7 @@ bool LocalParticipant::Send(Participant* remoteParticipant, int bufferSize) { return true; } -bool LocalParticipant::Publish(IMessage* msg) { +bool ParticipantUDP::Publish(IMessage* msg) { #if defined(IDF_VER) int bufferSize = msg->Serialize((char*)this->buffer); if (bufferSize <= 0) diff --git a/EspIdf/EspIdfParticipant.h b/EspIdf/EspIdfParticipant.h index 1ff7a64..ecdad07 100644 --- a/EspIdf/EspIdfParticipant.h +++ b/EspIdf/EspIdfParticipant.h @@ -2,12 +2,14 @@ #include "Participants/ParticipantUDP.h" +#if defined(IDF_VER) #include "lwip/sockets.h" +#endif namespace RoboidControl { namespace EspIdf { -class ParticipantUDP : public RoboidControl::LocalParticipant { +class ParticipantUDP : public RoboidControl::ParticipantUDP { public: void Setup(int localPort, const char* remoteIpAddress, int remotePort); void Receive(); @@ -15,13 +17,13 @@ class ParticipantUDP : public RoboidControl::LocalParticipant { bool Publish(IMessage* msg); protected: - // const char* remoteIpAddress = nullptr; - // unsigned short remotePort = 0; - char* broadcastIpAddress = nullptr; +#if defined(IDF_VER) + char broadcastIpAddress[INET_ADDRSTRLEN]; int sockfd; struct sockaddr_in dest_addr; struct sockaddr_in src_addr; +#endif void GetBroadcastAddress(); }; diff --git a/Messages/Messages.cpp b/Messages/Messages.cpp index 422c687..e21662f 100644 --- a/Messages/Messages.cpp +++ b/Messages/Messages.cpp @@ -18,15 +18,15 @@ unsigned char IMessage::Serialize(char* buffer) { return 0; } -// bool IMessage::SendMsg(LocalParticipant *client, IMessage msg) { +// bool IMessage::SendMsg(ParticipantUDP *client, IMessage msg) { // // return SendMsg(client, client.buffer, );nameLength // return client->SendBuffer(msg.Serialize(client->buffer)); // } -// bool IMessage::Publish(LocalParticipant *participant) { +// bool IMessage::Publish(ParticipantUDP *participant) { // return participant->PublishBuffer(Serialize(participant->buffer)); // } -// bool IMessage::SendTo(LocalParticipant *participant) { +// bool IMessage::SendTo(ParticipantUDP *participant) { // return participant->SendBuffer(Serialize(participant->buffer)); // } diff --git a/Messages/Messages.h b/Messages/Messages.h index 4d1a2f8..df22544 100644 --- a/Messages/Messages.h +++ b/Messages/Messages.h @@ -6,7 +6,7 @@ namespace RoboidControl { -class LocalParticipant; +class ParticipantUDP; class IMessage { public: @@ -15,8 +15,8 @@ class IMessage { static unsigned char* ReceiveMsg(unsigned char packetSize); - // bool Publish(LocalParticipant *participant); - // bool SendTo(LocalParticipant *participant); + // bool Publish(ParticipantUDP *participant); + // bool SendTo(ParticipantUDP *participant); }; } // namespace RoboidControl diff --git a/Messages/ParticipantMsg.cpp b/Messages/ParticipantMsg.cpp index e989f39..16c3b72 100644 --- a/Messages/ParticipantMsg.cpp +++ b/Messages/ParticipantMsg.cpp @@ -19,7 +19,7 @@ unsigned char ParticipantMsg::Serialize(char* buffer) { return ParticipantMsg::length; } -// bool ParticipantMsg::Send(LocalParticipant *participant, unsigned char networkId) { +// bool ParticipantMsg::Send(ParticipantUDP *participant, unsigned char networkId) { // ParticipantMsg msg = ParticipantMsg() // } // Client Msg diff --git a/Participant.cpp b/Participant.cpp index c690c75..42a0d94 100644 --- a/Participant.cpp +++ b/Participant.cpp @@ -27,6 +27,8 @@ Participant::~Participant() { delete[] this->ipAddress; } +void Participant::Update(unsigned long currentTimeMs) {} + Thing* Participant::Get(unsigned char networkId, unsigned char thingId) { for (Thing* thing : this->things) { // if (thing->networkId == networkId && thing->id == thingId) diff --git a/Participant.h b/Participant.h index 94c5861..c03fdcf 100644 --- a/Participant.h +++ b/Participant.h @@ -33,6 +33,8 @@ class Participant { /// @brief Destructor for the participant ~Participant(); + virtual void Update(unsigned long currentTimeMs = 0); + protected: #if defined(NO_STD) unsigned char thingCount = 0; diff --git a/Participants/IsolatedParticipant.cpp b/Participants/IsolatedParticipant.cpp new file mode 100644 index 0000000..a89eab4 --- /dev/null +++ b/Participants/IsolatedParticipant.cpp @@ -0,0 +1,14 @@ +#include "IsolatedParticipant.h" +#include "ParticipantUDP.h" + +namespace RoboidControl { + +static ParticipantUDP* isolatedParticipant = nullptr; + +Participant* IsolatedParticipant::Isolated() { + if (isolatedParticipant == nullptr) + isolatedParticipant = new ParticipantUDP(0); + return isolatedParticipant; +} + +} // namespace RoboidControl \ No newline at end of file diff --git a/Participants/IsolatedParticipant.h b/Participants/IsolatedParticipant.h new file mode 100644 index 0000000..27e9e80 --- /dev/null +++ b/Participants/IsolatedParticipant.h @@ -0,0 +1,13 @@ +#include "Participant.h" + +namespace RoboidControl { + +class IsolatedParticipant { + public: + /// @brief Isolated participant is used when the application is run without + /// networking + /// @return A participant without networking support + static Participant* Isolated(); +}; + +} \ No newline at end of file diff --git a/Participants/ParticipantUDP.cpp b/Participants/ParticipantUDP.cpp index ba12dec..a443002 100644 --- a/Participants/ParticipantUDP.cpp +++ b/Participants/ParticipantUDP.cpp @@ -1,4 +1,4 @@ -#include "LocalParticipant.h" +#include "ParticipantUDP.h" #include "Thing.h" @@ -25,14 +25,14 @@ namespace RoboidControl { -LocalParticipant::LocalParticipant(int port) { +ParticipantUDP::ParticipantUDP(int port) { this->ipAddress = "0.0.0.0"; this->port = port; if (this->port == 0) this->isIsolated = true; } -LocalParticipant::LocalParticipant(const char* ipAddress, +ParticipantUDP::ParticipantUDP(const char* ipAddress, int port, int localPort) : Participant("127.0.0.1", localPort) { @@ -42,45 +42,45 @@ LocalParticipant::LocalParticipant(const char* ipAddress, this->remoteSite = new Participant(ipAddress, port); } -static LocalParticipant* isolatedParticipant = nullptr; +static ParticipantUDP* isolatedParticipant = nullptr; -LocalParticipant* LocalParticipant::Isolated() { +ParticipantUDP* ParticipantUDP::Isolated() { if (isolatedParticipant == nullptr) - isolatedParticipant = new LocalParticipant(0); + isolatedParticipant = new ParticipantUDP(0); return isolatedParticipant; } -void LocalParticipant::begin() { +void ParticipantUDP::begin() { if (this->isIsolated) return; SetupUDP(this->port, this->remoteSite->ipAddress, this->remoteSite->port); } -void LocalParticipant::SetupUDP(int localPort, +void ParticipantUDP::SetupUDP(int localPort, const char* remoteIpAddress, int remotePort) { #if defined(_WIN32) || defined(_WIN64) - Windows::LocalParticipant* thisWindows = - static_cast(this); + Windows::ParticipantUDP* thisWindows = + static_cast(this); thisWindows->Setup(localPort, remoteIpAddress, remotePort); #elif defined(__unix__) || defined(__APPLE__) - Posix::LocalParticipant* thisPosix = - static_cast(this); + Posix::ParticipantUDP* thisPosix = + static_cast(this); thisPosix->Setup(localPort, remoteIpAddress, remotePort); #elif defined(ARDUINO) - Arduino::LocalParticipant* thisArduino = - static_cast(this); + Arduino::ParticipantUDP* thisArduino = + static_cast(this); thisArduino->Setup(localPort, remoteIpAddress, remotePort); #elif defined(IDF_VER) - EspIdf::LocalParticipant* thisEspIdf = - static_cast(this); + EspIdf::ParticipantUDP* thisEspIdf = + static_cast(this); thisEspIdf->Setup(localPort, remoteIpAddress, remotePort); #endif this->connected = true; } -void LocalParticipant::Update(unsigned long currentTimeMs) { +void ParticipantUDP::Update(unsigned long currentTimeMs) { if (currentTimeMs == 0) currentTimeMs = Thing::GetTimeMs(); @@ -114,27 +114,27 @@ void LocalParticipant::Update(unsigned long currentTimeMs) { } } -void LocalParticipant::ReceiveUDP() { +void ParticipantUDP::ReceiveUDP() { #if defined(_WIN32) || defined(_WIN64) - Windows::LocalParticipant* thisWindows = - static_cast(this); + Windows::ParticipantUDP* thisWindows = + static_cast(this); thisWindows->Receive(); #elif defined(__unix__) || defined(__APPLE__) - Posix::LocalParticipant* thisPosix = - static_cast(this); + Posix::ParticipantUDP* thisPosix = + static_cast(this); thisPosix->Receive(); #elif defined(ARDUINO) - Arduino::LocalParticipant* thisArduino = - static_cast(this); + Arduino::ParticipantUDP* thisArduino = + static_cast(this); thisArduino->Receive(); #elif defined(IDF_VER) - EspIdf::LocalParticipant* thisEspIdf = - static_cast(this); + EspIdf::ParticipantUDP* thisEspIdf = + static_cast(this); thisEspIdf->Receive(); #endif } -Participant* LocalParticipant::GetParticipant(const char* ipAddress, int port) { +Participant* ParticipantUDP::GetParticipant(const char* ipAddress, int port) { for (Participant* sender : this->senders) { if (strcmp(sender->ipAddress, ipAddress) == 0 && sender->port == port) return sender; @@ -142,7 +142,7 @@ Participant* LocalParticipant::GetParticipant(const char* ipAddress, int port) { return nullptr; } -Participant* LocalParticipant::AddParticipant(const char* ipAddress, int port) { +Participant* ParticipantUDP::AddParticipant(const char* ipAddress, int port) { // std::cout << "New Participant " << ipAddress << ":" << port << "\n"; Participant* participant = new Participant(ipAddress, port); #if defined(NO_STD) @@ -157,7 +157,7 @@ Participant* LocalParticipant::AddParticipant(const char* ipAddress, int port) { #pragma region Send -void LocalParticipant::SendThingInfo(Participant* remoteParticipant, +void ParticipantUDP::SendThingInfo(Participant* remoteParticipant, Thing* thing) { // std::cout << "Send thing info " << (int)thing->id << " \n"; ThingMsg* thingMsg = new ThingMsg(this->networkId, thing); @@ -177,33 +177,33 @@ void LocalParticipant::SendThingInfo(Participant* remoteParticipant, delete customMsg; } -bool LocalParticipant::Send(Participant* remoteParticipant, IMessage* msg) { +bool ParticipantUDP::Send(Participant* remoteParticipant, IMessage* msg) { int bufferSize = msg->Serialize(this->buffer); if (bufferSize <= 0) return true; #if defined(_WIN32) || defined(_WIN64) - Windows::LocalParticipant* thisWindows = - static_cast(this); + Windows::ParticipantUDP* thisWindows = + static_cast(this); return thisWindows->Send(remoteParticipant, bufferSize); #elif defined(__unix__) || defined(__APPLE__) - Posix::LocalParticipant* thisPosix = - static_cast(this); + Posix::ParticipantUDP* thisPosix = + static_cast(this); return thisPosix->Send(remoteParticipant, bufferSize); #elif defined(ARDUINO) - Arduino::LocalParticipant* thisArduino = - static_cast(this); + Arduino::ParticipantUDP* thisArduino = + static_cast(this); return thisArduino->Send(remoteParticipant, bufferSize); #elif defined(IDF_VER) - EspIdf::LocalParticipant* thisEspIdf = - static_cast(this); + EspIdf::ParticipantUDP* thisEspIdf = + static_cast(this); return thisEspIdf->Send(remoteParticipant, bufferSize); #else return false; #endif } -void LocalParticipant::PublishThingInfo(Thing* thing) { +void ParticipantUDP::PublishThingInfo(Thing* thing) { // std::cout << "Publish thing info" << thing->networkId << "\n"; // Strange, when publishing, the network id is irrelevant, because it is // connected to a specific site... @@ -224,22 +224,22 @@ void LocalParticipant::PublishThingInfo(Thing* thing) { delete customMsg; } -bool LocalParticipant::Publish(IMessage* msg) { +bool ParticipantUDP::Publish(IMessage* msg) { #if defined(_WIN32) || defined(_WIN64) - Windows::LocalParticipant* thisWindows = - static_cast(this); + Windows::ParticipantUDP* thisWindows = + static_cast(this); return thisWindows->Publish(msg); #elif defined(__unix__) || defined(__APPLE__) - Posix::LocalParticipant* thisPosix = - static_cast(this); + Posix::ParticipantUDP* thisPosix = + static_cast(this); return thisPosix->Publish(msg); #elif defined(ARDUINO) - Arduino::LocalParticipant* thisArduino = - static_cast(this); + Arduino::ParticipantUDP* thisArduino = + static_cast(this); return thisArduino->Publish(msg); #elif defined(IDF_VER) - EspIdf::LocalParticipant* thisEspIdf = - static_cast(this); + EspIdf::ParticipantUDP* thisEspIdf = + static_cast(this); return thisEspIdf->Publish(msg); #else return false; @@ -251,7 +251,7 @@ bool LocalParticipant::Publish(IMessage* msg) { #pragma region Receive -void LocalParticipant::ReceiveData(unsigned char packetSize, +void ParticipantUDP::ReceiveData(unsigned char packetSize, char* senderIpAddress, unsigned int senderPort) { Participant* remoteParticipant = @@ -268,7 +268,7 @@ void LocalParticipant::ReceiveData(unsigned char packetSize, ReceiveData(packetSize, remoteParticipant); } -void LocalParticipant::ReceiveData(unsigned char bufferSize, +void ParticipantUDP::ReceiveData(unsigned char bufferSize, Participant* remoteParticipant) { unsigned char msgId = this->buffer[0]; // std::cout << "receive msg " << (int)msgId << "\n"; @@ -311,9 +311,9 @@ void LocalParticipant::ReceiveData(unsigned char bufferSize, }; } -void LocalParticipant::Process(Participant* sender, ParticipantMsg* msg) {} +void ParticipantUDP::Process(Participant* sender, ParticipantMsg* msg) {} -void LocalParticipant::Process(Participant* sender, SiteMsg* msg) { +void ParticipantUDP::Process(Participant* sender, SiteMsg* msg) { std::cout << this->name << ": process Site Id " << (int)this->networkId << "->" << (int)msg->networkId << "\n"; if (this->networkId != msg->networkId) { @@ -324,25 +324,14 @@ void LocalParticipant::Process(Participant* sender, SiteMsg* msg) { } } -void LocalParticipant::Process(Participant* sender, InvestigateMsg* msg) {} +void ParticipantUDP::Process(Participant* sender, InvestigateMsg* msg) {} -void LocalParticipant::Process(Participant* sender, ThingMsg* msg) { +void ParticipantUDP::Process(Participant* sender, ThingMsg* msg) { std::cout << this->name << ": process Thing [" << (int)msg->networkId << "/" << (int)msg->thingId << "]\n"; -#if !defined(NO_STD) - auto thingMsgProcessor = thingMsgProcessors.find(msg->thingType); - //Thing* newThing; - if (thingMsgProcessor != thingMsgProcessors.end()) { // found item - //newThing = - thingMsgProcessor->second(sender, msg->networkId, msg->thingId); - } else - //newThing = - new Thing(sender, msg->networkId, msg->thingId, - (Thing::Type)msg->thingType); -#endif } -void LocalParticipant::Process(Participant* sender, NameMsg* msg) { +void ParticipantUDP::Process(Participant* sender, NameMsg* msg) { std::cout << this->name << ": process Name [" << (int)msg->networkId << "/" << (int)msg->thingId << "]\n"; @@ -369,14 +358,14 @@ void LocalParticipant::Process(Participant* sender, NameMsg* msg) { } } -void LocalParticipant::Process(Participant* sender, PoseMsg* msg) { +void ParticipantUDP::Process(Participant* sender, PoseMsg* msg) { std::cout << this->name << ": process Pose [" << (int)this->networkId << "/" << (int)msg->networkId << "]\n"; } -void LocalParticipant::Process(Participant* sender, BinaryMsg* msg) { - std::cout << this->name << ": process Binary [" << (int)this->networkId << "/" - << (int)msg->networkId << "]\n"; +void ParticipantUDP::Process(Participant* sender, BinaryMsg* msg) { + std::cout << this->name << ": process Binary [" << (int)msg->networkId << "/" + << (int)msg->thingId << "]\n"; Thing* thing = sender->Get(msg->networkId, msg->thingId); if (thing != nullptr) thing->ProcessBinary(msg->bytes); diff --git a/Participants/ParticipantUDP.h b/Participants/ParticipantUDP.h index 260f794..4d82fb9 100644 --- a/Participants/ParticipantUDP.h +++ b/Participants/ParticipantUDP.h @@ -23,8 +23,6 @@ #include #include #include -#elif defined(ARDUINO) -// #include #endif namespace RoboidControl { @@ -40,20 +38,20 @@ constexpr int MAX_SENDER_COUNT = 256; /// It is possible to work with an hidden participant by creating things without /// specifying a participant in the constructor. In that case an hidden isolated /// participant is created which can be obtained using -/// RoboidControl::LocalParticipant::Isolated(). +/// RoboidControl::IsolatedParticipant::Isolated(). /// @sa RoboidControl::Thing::Thing() -class LocalParticipant : public Participant { +class ParticipantUDP : public Participant { 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. - LocalParticipant(int port = 7681); + 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 - LocalParticipant(const char* ipAddress, + ParticipantUDP(const char* ipAddress, int port = 7681, int localPort = 7681); // Note to self: one cannot specify the port used by the local participant @@ -62,7 +60,7 @@ class LocalParticipant : public Participant { /// @brief Isolated participant is used when the application is run without /// networking /// @return A participant without networking support - static LocalParticipant* Isolated(); + static ParticipantUDP* Isolated(); /// @brief True if the participant is running isolated. /// Isolated participants do not communicate with other participants @@ -73,7 +71,7 @@ class LocalParticipant : public Participant { long publishInterval = 3000; // 3 seconds /// @brief The name of the participant - const char* name = "LocalParticipant"; + const char* name = "ParticipantUDP"; // int localPort = 0; @@ -101,7 +99,7 @@ class LocalParticipant : public Participant { void begin(); bool connected = false; - virtual void Update(unsigned long currentTimeMs = 0); + virtual void Update(unsigned long currentTimeMs = 0) override; void SendThingInfo(Participant* remoteParticipant, Thing* thing); void PublishThingInfo(Thing* thing); @@ -142,31 +140,31 @@ class LocalParticipant : public Participant { virtual void Process(Participant* sender, BinaryMsg* msg); #if !defined(NO_STD) - public: - using ThingConstructor = std::function; +// public: +// using ThingConstructor = std::function; - template - void Register(unsigned char thingType) { - thingMsgProcessors[thingType] = [](Participant* participant, - unsigned char networkId, - unsigned char thingId) { - return new ThingClass(participant, networkId, thingId); - }; - }; +// template +// void Register(unsigned char thingType) { +// thingMsgProcessors[thingType] = [](Participant* participant, +// unsigned char networkId, +// unsigned char thingId) { +// return new ThingClass(participant, networkId, thingId); +// }; +// }; - template - void Register2(unsigned char thingType, ThingConstructor f) { - thingMsgProcessors[thingType] = [f](Participant* participant, - unsigned char networkId, - unsigned char thingId) { - return f(participant, networkId, thingId); - }; - }; +// template +// void Register2(unsigned char thingType, ThingConstructor f) { +// thingMsgProcessors[thingType] = [f](Participant* participant, +// unsigned char networkId, +// unsigned char thingId) { +// return f(participant, networkId, thingId); +// }; +// }; - protected: - std::unordered_map thingMsgProcessors; +// protected: +// std::unordered_map thingMsgProcessors; #endif }; diff --git a/Participants/SiteServer.h b/Participants/SiteServer.h index 84a0fe0..0fe2974 100644 --- a/Participants/SiteServer.h +++ b/Participants/SiteServer.h @@ -1,6 +1,6 @@ #pragma once -#include "LocalParticipant.h" +#include "ParticipantUDP.h" #if !defined(NO_STD) #include @@ -11,7 +11,7 @@ namespace RoboidControl { /// @brief A participant is device which can communicate with other participants -class SiteServer : public LocalParticipant { +class SiteServer : public ParticipantUDP { public: SiteServer(int port = 7681); diff --git a/Posix/PosixParticipant.cpp b/Posix/PosixParticipant.cpp index ff23848..88e18af 100644 --- a/Posix/PosixParticipant.cpp +++ b/Posix/PosixParticipant.cpp @@ -11,7 +11,7 @@ namespace RoboidControl { namespace Posix { -void LocalParticipant::Setup(int localPort, const char* remoteIpAddress, int remotePort) { +void Setup(int localPort, const char* remoteIpAddress, int remotePort) { #if defined(__unix__) || defined(__APPLE__) // Create a UDP socket @@ -63,7 +63,7 @@ void LocalParticipant::Setup(int localPort, const char* remoteIpAddress, int rem #endif } -void LocalParticipant::Receive() { +void Receive() { #if defined(__unix__) || defined(__APPLE__) sockaddr_in client_addr; socklen_t len = sizeof(client_addr); @@ -90,7 +90,7 @@ void LocalParticipant::Receive() { #endif } -bool LocalParticipant::Send(Participant* remoteParticipant, int bufferSize) { +bool Send(Participant* remoteParticipant, int bufferSize) { #if defined(__unix__) || defined(__APPLE__) // std::cout << "Send to " << remoteParticipant->ipAddress << ":" << ntohs(remoteParticipant->port) // << "\n"; @@ -113,7 +113,7 @@ bool LocalParticipant::Send(Participant* remoteParticipant, int bufferSize) { return true; } -bool LocalParticipant::Publish(IMessage* msg) { +bool Publish(IMessage* msg) { #if defined(__unix__) || defined(__APPLE__) int bufferSize = msg->Serialize(this->buffer); if (bufferSize <= 0) diff --git a/Posix/PosixParticipant.h b/Posix/PosixParticipant.h index 5f75a05..ec16d32 100644 --- a/Posix/PosixParticipant.h +++ b/Posix/PosixParticipant.h @@ -1,11 +1,11 @@ #pragma once -#include "../LocalParticipant.h" +#include "Participants/ParticipantUDP.h" namespace RoboidControl { namespace Posix { -class LocalParticipant : public RoboidControl::LocalParticipant { +class ParticipantUDP : public RoboidControl::ParticipantUDP { public: void Setup(int localPort, const char* remoteIpAddress, int remotePort); void Receive(); diff --git a/Thing.cpp b/Thing.cpp index 64d0be9..b57be7f 100644 --- a/Thing.cpp +++ b/Thing.cpp @@ -1,6 +1,7 @@ #include "Thing.h" -#include "LocalParticipant.h" +#include "Participant.h" +#include "Participants/IsolatedParticipant.h" #include @@ -21,7 +22,7 @@ namespace RoboidControl { // return isolatedParticipant; // } -Thing::Thing(int thingType) : Thing(LocalParticipant::Isolated(), thingType) {} +Thing::Thing(int thingType) : Thing(IsolatedParticipant::Isolated(), thingType) {} Thing::Thing(Participant* owner, Type thingType) : Thing(owner, (unsigned char)thingType) {} @@ -201,7 +202,7 @@ void Thing::Update(unsigned long currentTimeMs, bool recursive) { } void Thing::UpdateThings(unsigned long currentTimeMs) { - LocalParticipant::Isolated()->Update(currentTimeMs); + IsolatedParticipant::Isolated()->Update(currentTimeMs); } void Thing::GenerateBinary(char* buffer, unsigned char* ix) { diff --git a/Thing.h b/Thing.h index d7086e8..d640d8b 100644 --- a/Thing.h +++ b/Thing.h @@ -10,7 +10,7 @@ namespace RoboidControl { class Participant; -class LocalParticipant; +class ParticipantUDP; #define THING_STORE_SIZE 256 // IMPORTANT: values higher than 256 will need to change the Thing::id type diff --git a/Windows/WindowsParticipant.cpp b/Windows/WindowsParticipant.cpp index 9b5a8b3..d64eb1e 100644 --- a/Windows/WindowsParticipant.cpp +++ b/Windows/WindowsParticipant.cpp @@ -4,36 +4,22 @@ #include #include #pragma comment(lib, "ws2_32.lib") - -#elif defined(__unix__) || defined(__APPLE__) -#include -#include // For fcntl -#include -#include -#include #endif namespace RoboidControl { namespace Windows { -void LocalParticipant::Setup(int localPort, const char* remoteIpAddress, int remotePort) { +void ParticipantUDP::Setup(int localPort, const char* remoteIpAddress, int remotePort) { #if defined(_WIN32) || defined(_WIN64) // Create a UDP socket -#if defined(_WIN32) || defined(_WIN64) // Windows-specific Winsock initialization WSADATA wsaData; if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { std::cerr << "WSAStartup failed" << std::endl; return; } -#endif - -#if defined(_WIN32) || defined(_WIN64) this->sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); -#elif defined(__unix__) || defined(__APPLE__) - this->sock = socket(AF_INET, SOCK_DGRAM, 0); -#endif if (this->sock < 0) { std::cerr << "Error creating socket" << std::endl; @@ -41,13 +27,8 @@ void LocalParticipant::Setup(int localPort, const char* remoteIpAddress, int rem } // Set the socket to non-blocking mode -#if defined(_WIN32) || defined(_WIN64) u_long mode = 1; // 1 to enable non-blocking socket ioctlsocket(this->sock, FIONBIO, &mode); -#elif defined(__unix__) || defined(__APPLE__) - int flags = fcntl(this->sock, F_GETFL, 0); - fcntl(this->sock, F_SETFL, flags | O_NONBLOCK); -#endif if (remotePort != 0) { // Set up the address to send to @@ -56,12 +37,8 @@ void LocalParticipant::Setup(int localPort, const char* remoteIpAddress, int rem remote_addr.sin_port = htons((u_short)remotePort); if (inet_pton(AF_INET, remoteIpAddress, &remote_addr.sin_addr) <= 0) { std::cerr << "Invalid address" << std::endl; -#if defined(_WIN32) || defined(_WIN64) closesocket(sock); WSACleanup(); -#elif defined(__unix__) || defined(__APPLE__) - close(sock); -#endif return; } } @@ -72,30 +49,22 @@ void LocalParticipant::Setup(int localPort, const char* remoteIpAddress, int rem server_addr.sin_port = htons((u_short)localPort); if (inet_pton(AF_INET, "0.0.0.0", &server_addr.sin_addr) <= 0) { std::cerr << "Invalid address" << std::endl; -#if defined(_WIN32) || defined(_WIN64) closesocket(sock); WSACleanup(); -#elif defined(__unix__) || defined(__APPLE__) - close(sock); -#endif return; } // Bind the socket to the specified port if (bind(this->sock, (const struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) { std::cerr << "Bind failed" << std::endl; -#if defined(_WIN32) || defined(_WIN64) closesocket(sock); WSACleanup(); -#elif defined(__unix__) || defined(__APPLE__) - close(sock); -#endif } -#endif +#endif // _WIN32 || _WIN64 } -void LocalParticipant::Receive() { +void ParticipantUDP::Receive() { #if defined(_WIN32) || defined(_WIN64) // char ip_str[INET_ADDRSTRLEN]; // inet_ntop(AF_INET, &(server_addr.sin_addr), ip_str, INET_ADDRSTRLEN); @@ -103,28 +72,20 @@ void LocalParticipant::Receive() { // << ntohs(server_addr.sin_port) << "\n"; sockaddr_in client_addr; -#if defined(_WIN32) || defined(_WIN64) int len = sizeof(client_addr); -#elif defined(__unix__) || defined(__APPLE__) - socklen_t len = sizeof(client_addr); -#endif int packetSize = recvfrom(this->sock, buffer, sizeof(buffer), 0, (struct sockaddr*)&client_addr, &len); // std::cout << "received data " << packetSize << "\n"; if (packetSize < 0) { -#if defined(_WIN32) || defined(_WIN64) int error_code = WSAGetLastError(); // Get the error code on Windows if (error_code != WSAEWOULDBLOCK) std::cerr << "recvfrom failed with error: " << error_code << std::endl; -#else - // std::cerr << "recvfrom failed with error: " << packetSize << std::endl; -#endif } else if (packetSize > 0) { char sender_ipAddress[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &(client_addr.sin_addr), sender_ipAddress, INET_ADDRSTRLEN); unsigned int sender_port = ntohs(client_addr.sin_port); ReceiveData(packetSize, sender_ipAddress, sender_port); - // RoboidControl::LocalParticipant* remoteParticipant = this->GetParticipant(sender_ipAddress, sender_port); + // RoboidControl::ParticipantUDP* remoteParticipant = this->GetParticipant(sender_ipAddress, sender_port); // if (remoteParticipant == nullptr) { // remoteParticipant = this->AddParticipant(sender_ipAddress, sender_port); // // std::cout << "New sender " << sender_ipAddress << ":" @@ -138,16 +99,16 @@ void LocalParticipant::Receive() { // ReceiveData(packetSize, remoteParticipant); } -#endif +#endif // _WIN32 || _WIN64 } -bool LocalParticipant::Send(Participant* remoteParticipant, int bufferSize) { +bool ParticipantUDP::Send(Participant* remoteParticipant, int bufferSize) { #if defined(_WIN32) || defined(_WIN64) char ip_str[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &(remote_addr.sin_addr), ip_str, INET_ADDRSTRLEN); std::cout << "Send to " << ip_str << ":" << ntohs(remote_addr.sin_port) << "\n"; int sent_bytes = sendto(sock, this->buffer, bufferSize, 0, (struct sockaddr*)&remote_addr, sizeof(remote_addr)); -#if defined(_WIN32) || defined(_WIN64) + if (sent_bytes <= SOCKET_ERROR) { int error_code = WSAGetLastError(); // Get the error code on Windows std::cerr << "sendto failed with error: " << error_code << std::endl; @@ -155,18 +116,11 @@ bool LocalParticipant::Send(Participant* remoteParticipant, int bufferSize) { WSACleanup(); return false; } -#elif defined(__unix__) || defined(__APPLE__) - if (sent_bytes < 0) { - std::cerr << "sendto failed with error: " << sent_bytes << std::endl; - close(sock); - return false; - } -#endif -#endif +#endif // _WIN32 || _WIN64 return true; } -bool LocalParticipant::Publish(IMessage* msg) { +bool ParticipantUDP::Publish(IMessage* msg) { #if defined(_WIN32) || defined(_WIN64) int bufferSize = msg->Serialize(this->buffer); if (bufferSize <= 0) @@ -176,7 +130,7 @@ bool LocalParticipant::Publish(IMessage* msg) { inet_ntop(AF_INET, &(broadcast_addr.sin_addr), ip_str, INET_ADDRSTRLEN); std::cout << "Publish to " << ip_str << ":" << ntohs(broadcast_addr.sin_port) << "\n"; int sent_bytes = sendto(sock, this->buffer, bufferSize, 0, (struct sockaddr*)&broadcast_addr, sizeof(broadcast_addr)); -#if defined(_WIN32) || defined(_WIN64) + if (sent_bytes <= SOCKET_ERROR) { int error_code = WSAGetLastError(); // Get the error code on Windows std::cerr << "sendto failed with error: " << error_code << std::endl; @@ -184,14 +138,7 @@ bool LocalParticipant::Publish(IMessage* msg) { WSACleanup(); return false; } -#elif defined(__unix__) || defined(__APPLE__) - if (sent_bytes < 0) { - std::cerr << "sendto failed with error: " << sent_bytes << std::endl; - close(sock); - return false; - } -#endif -#endif +#endif // _WIN32 || _WIN64 return true; } diff --git a/Windows/WindowsParticipant.h b/Windows/WindowsParticipant.h index c0ec0ed..9a747d9 100644 --- a/Windows/WindowsParticipant.h +++ b/Windows/WindowsParticipant.h @@ -1,11 +1,11 @@ #pragma once -#include "../LocalParticipant.h" +#include "Participants/ParticipantUDP.h" namespace RoboidControl { namespace Windows { -class LocalParticipant : public RoboidControl::LocalParticipant { +class ParticipantUDP : public RoboidControl::ParticipantUDP { public: void Setup(int localPort, const char* remoteIpAddress, int remotePort); void Receive(); diff --git a/test/participant_test.cc b/test/participant_test.cc index 70a5e09..c826863 100644 --- a/test/participant_test.cc +++ b/test/participant_test.cc @@ -9,7 +9,7 @@ // #include #include "Participant.h" -#include "SiteServer.h" +#include "Participants/SiteServer.h" #include "Thing.h" using namespace RoboidControl; @@ -52,8 +52,8 @@ protected: -// TEST_F(ParticipantSuite, LocalParticipant) { -// LocalParticipant* participant = new LocalParticipant("127.0.0.1", 7681); +// TEST_F(ParticipantSuite, ParticipantUDP) { +// ParticipantUDP* participant = new ParticipantUDP("127.0.0.1", 7681); // unsigned long milliseconds = get_time_ms(); // unsigned long startTime = milliseconds; @@ -80,7 +80,7 @@ protected: // TEST_F(ParticipantSuite, SiteParticipant) { // SiteServer site = SiteServer(7681); -// LocalParticipant participant = LocalParticipant("127.0.0.1", 7681); +// ParticipantUDP participant = ParticipantUDP("127.0.0.1", 7681); // unsigned long milliseconds = get_time_ms(); // unsigned long startTime = milliseconds; @@ -96,7 +96,7 @@ protected: // TEST_F(ParticipantSuite, Thing) { // SiteServer site = SiteServer(7681); -// LocalParticipant participant = LocalParticipant("127.0.0.1", 7681); +// ParticipantUDP participant = ParticipantUDP("127.0.0.1", 7681); // Thing thing = Thing(&participant); // unsigned long milliseconds = get_time_ms(); diff --git a/test/thing_test.cc b/test/thing_test.cc index bc613a8..b8ceea1 100644 --- a/test/thing_test.cc +++ b/test/thing_test.cc @@ -4,7 +4,7 @@ // not supported using Visual Studio 2022 compiler... #include -#include "LocalParticipant.h" +#include "Participants/ParticipantUDP.h" #include "Thing.h" using namespace RoboidControl; @@ -23,7 +23,7 @@ TEST(RoboidControlSuite, HiddenParticipant) { } TEST(RoboidControlSuite, IsolatedParticipant) { - LocalParticipant* participant = LocalParticipant::Isolated(); + ParticipantUDP* participant = ParticipantUDP::Isolated(); Thing* thing = new Thing(participant); unsigned long milliseconds = Thing::GetTimeMs();