#pragma once #include "Messages/BinaryMsg.h" #include "Messages/InvestigateMsg.h" #include "Messages/ModelUrlMsg.h" #include "Messages/NameMsg.h" #include "Messages/ParticipantMsg.h" #include "Messages/PoseMsg.h" #include "Messages/SiteMsg.h" #include "Messages/ThingMsg.h" #include "Participant.h" #include #if defined(_WIN32) || defined(_WIN64) #include #elif defined(__unix__) || defined(__APPLE__) #include #include #include #include #elif defined(ARDUINO) #include #endif namespace RoboidControl { /// @brief 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 (@sa RoboidControl::Thing::Thing()). In that case an hidden isolated participant is created which can be /// obtained using RoboidControl::LocalParticipant::Isolated(). class LocalParticipant : 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); /// @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, int port = 7681); // Note to self: one cannot specify the port used by the local participant now!! /// @brief Isolated participant is used when the application is run without networking /// @return A participant without networking support static LocalParticipant* Isolated(); /// @brief True if the participant is running isolated. /// Isolated participants do not communicate with other participants bool isIsolated = false; /// The interval in milliseconds for publishing (broadcasting) data on the local network long publishInterval = 3000; // 3 seconds /// @brief The name of the participant const char* name = "LocalParticipant"; // int localPort = 0; /// @brief The remote site when this participant is connected to a site Participant* remoteSite = nullptr; #if defined(ARDUINO) const char* remoteIpAddress = nullptr; unsigned short remotePort = 0; char* broadcastIpAddress = nullptr; WiFiUDP udp; #else #if defined(__unix__) || defined(__APPLE__) int sock; #endif sockaddr_in remote_addr; sockaddr_in server_addr; sockaddr_in broadcast_addr; #endif void begin(); bool connected = false; virtual void Update(unsigned long currentTimeMs = 0); void SendThingInfo(Participant* remoteParticipant, Thing* thing); void PublishThingInfo(Thing* thing); bool Send(Participant* remoteParticipant, IMessage* msg); bool Publish(IMessage* msg); void ReceiveData(unsigned char bufferSize, char* senderIpAddress, unsigned int senderPort); void ReceiveData(unsigned char bufferSize, Participant* remoteParticipant); std::list senders; protected: unsigned long nextPublishMe = 0; char buffer[1024]; void SetupUDP(int localPort, const char* remoteIpAddress, int remotePort); Participant* GetParticipant(const char* ipAddress, int port); Participant* AddParticipant(const char* ipAddress, int port); void ReceiveUDP(); virtual void Process(Participant* sender, ParticipantMsg* msg); virtual void Process(Participant* sender, SiteMsg* 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, PoseMsg* msg); virtual void Process(Participant* sender, BinaryMsg* msg); }; } // namespace RoboidControl