#pragma once #include "Messages/BinaryMsg.h" #include "Messages/DestroyMsg.h" #include "Messages/InvestigateMsg.h" #include "Messages/ModelUrlMsg.h" #include "Messages/NameMsg.h" #include "Messages/ParticipantMsg.h" #include "Messages/PoseMsg.h" #include "Messages/NetworkIdMsg.h" #include "Messages/ThingMsg.h" #include "Participant.h" #if !defined(NO_STD) #include #include // #include #endif #if defined(_WIN32) || defined(_WIN64) #include #elif defined(__unix__) || defined(__APPLE__) #include #include #include #include #endif namespace RoboidControl { constexpr int MAX_SENDER_COUNT = 256; /// @brief A participant using UDP communication /// A local participant is the local device which can communicate with /// other participants It manages all local things and communcation with other /// participants. Each application has a local participant which is usually /// explicit in the code. An participant can be isolated. In that case it is /// standalong and does not communicate with other participants. /// /// 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::IsolatedParticipant::Isolated(). /// @sa RoboidControl::Thing::Thing() class ParticipantUDP : public Participant { #pragma region Init 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); /// @brief Isolated participant is used when the application is run without /// networking /// @return A participant without networking support static ParticipantUDP* Isolated(); /// @brief True if the participant is running isolated. /// Isolated participants do not communicate with other participants #pragma endregion Init /// @brief True if the participant is running isolated. /// Isolated participants do not communicate with other participants bool isIsolated = false; /// @brief The remote site when this participant is connected to a site Participant* remoteSite = nullptr; /// The interval in milliseconds for publishing (broadcasting) data on the /// local network long publishInterval = 3000; // 3 seconds protected: char buffer[1024]; #if !defined(ARDUINO) #if defined(__unix__) || defined(__APPLE__) int sock; #elif defined(_WIN32) || defined(_WIN64) sockaddr_in remote_addr; sockaddr_in server_addr; sockaddr_in broadcast_addr; #endif #endif public: void begin(); bool connected = false; #pragma region Update public: virtual void Update() override; protected: unsigned long nextPublishMe = 0; /// @brief Prepare the local things for the next update virtual void PrepMyThings(); virtual void UpdateMyThings(); virtual void UpdateOtherThings(); #pragma endregion Update #pragma region Send void SendThingInfo(Participant* remoteParticipant, Thing* thing); void PublishThingInfo(Thing* thing); bool Send(Participant* remoteParticipant, IMessage* msg); bool Publish(IMessage* msg); #pragma endregion Send #pragma region Receive protected: void ReceiveData(unsigned char bufferSize, char* senderIpAddress, unsigned int senderPort); void ReceiveData(unsigned char bufferSize, Participant* remoteParticipant); void SetupUDP(int localPort, const char* remoteIpAddress, int remotePort); void ReceiveUDP(); virtual void Process(Participant* sender, ParticipantMsg* msg); virtual void Process(Participant* sender, NetworkIdMsg* msg); virtual void Process(Participant* sender, InvestigateMsg* msg); virtual void Process(Participant* sender, ThingMsg* msg); virtual void Process(Participant* sender, NameMsg* msg); virtual void Process(Participant* sender, ModelUrlMsg* msg); virtual void Process(Participant* sender, PoseMsg* msg); virtual void Process(Participant* sender, BinaryMsg* msg); #pragma endregion Receive }; } // namespace RoboidControl