#include "Participant.h" #include "Thing.h" #include "UdpArduino.h" #include "UdpPosix.h" #include "UdpWindows.h" #if defined(_WIN32) || defined(_WIN64) #include #include #pragma comment(lib, "ws2_32.lib") #elif defined(__unix__) || defined(__APPLE__) #include #include // For fcntl #include #include #include #endif Participant::Participant() {} Participant::Participant(int port) { this->ipAddress = "0.0.0.0"; this->port = port; this->participants.push_back(this); int randomPort = (rand() % (65535 - 49152 + 1)) + 49152; SetupUDP(randomPort, ipAddress, port); } Participant::Participant(const char *ipAddress, int port) { this->ipAddress = ipAddress; this->port = port; this->participants.push_back(this); int randomPort = (rand() % (65535 - 49152 + 1)) + 49152; SetupUDP(randomPort, ipAddress, port); } void Passer::Control::Participant::SetupUDP(int localPort, const char *remoteIpAddress, int remotePort) { #if defined(_WIN32) || defined(_WIN64) UdpWindows *thisWindows = static_cast(this); thisWindows->Setup(localPort, remoteIpAddress, remotePort); #elif defined(__unix__) || defined(__APPLE__) UdpPosix *thisPosix = static_cast(this); thisPosix->Setup(localPort, remoteIpAddress, remotePort); #elif defined(ARDUINO) UdpArduino *thisArduino = static_cast(this); thisArduino->Setup(localPort, remoteIpAddress, remotePort); #endif } void Participant::Update(unsigned long currentTimeMs) { if (this->publishInterval > 0 && currentTimeMs > this->nextPublishMe) { ClientMsg *msg = new ClientMsg(this->networkId); this->Publish(msg); delete msg; std::cout << this->name << " published ClientMsg\n"; this->nextPublishMe = currentTimeMs + this->publishInterval; } this->ReceiveUDP(); Thing::UpdateAll(currentTimeMs); } void Participant::ReceiveUDP() { #if defined(_WIN32) || defined(_WIN64) UdpWindows *thisWindows = static_cast(this); thisWindows->Receive(); #elif defined(__unix__) || defined(__APPLE__) UdpPosix *thisPosix = static_cast(this); thisPosix->Receive(); #elif defined(ARDUINO) UdpArduino *thisArduino = static_cast(this); thisArduino->Receive(); #endif } Participant *Participant::GetParticipant(const char *ipAddress, int port) { for (Participant *participant : this->participants) { if (participant->ipAddress == ipAddress && participant->port == port) return participant; } return nullptr; } Participant *Participant::AddParticipant(const char *ipAddress, int port) { Participant *participant = new Participant(ipAddress, port); participant->networkId = (unsigned char)this->participants.size(); this->participants.push_back(participant); return participant; } #pragma region Send void Participant::SendThingInfo(Thing *thing) { std::cout << "Send thing info\n"; IMessage *msg = new ThingMsg(this->networkId, thing); this->Send(msg); delete msg; msg = new NameMsg(this->networkId, thing); this->Send(msg); delete msg; msg = new ModelUrlMsg(this->networkId, thing); this->Send(msg); delete msg; } void Passer::Control::Participant::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... ThingMsg *thingMsg = new ThingMsg(this->networkId, thing); this->Publish(thingMsg); delete thingMsg; NameMsg *nameMsg = new NameMsg(this->networkId, thing); this->Publish(nameMsg); delete nameMsg; ModelUrlMsg *modelMsg = new ModelUrlMsg(this->networkId, thing); this->Publish(modelMsg); delete modelMsg; } bool Participant::Send(IMessage *msg) { #if defined(_WIN32) || defined(_WIN64) UdpWindows *thisWindows = static_cast(this); return thisWindows->Send(msg); #elif defined(__unix__) || defined(__APPLE__) UdpPosix *thisPosix = static_cast(this); return thisPosix->Send(msg); #elif defined(ARDUINO) UdpArduino *thisArduino = static_cast(this); return thisArduino->Send(msg); #endif } bool Participant::Publish(IMessage *msg) { #if defined(_WIN32) || defined(_WIN64) UdpWindows *thisWindows = static_cast(this); return thisWindows->Publish(msg); #elif defined(__unix__) || defined(__APPLE__) UdpPosix *thisPosix = static_cast(this); return thisPosix->Publish(msg); #elif defined(ARDUINO) UdpArduino *thisArduino = static_cast(this); return thisArduino->Publish(msg); #endif } // Send #pragma endregion #pragma region Receive void Participant::ReceiveData(unsigned char bufferSize, Participant *remoteParticipant) { unsigned char msgId = this->buffer[0]; switch (msgId) { case ClientMsg::id: { ClientMsg *msg = new ClientMsg(this->buffer); Process(remoteParticipant, msg); delete msg; } case NetworkIdMsg::id: { NetworkIdMsg *msg = new NetworkIdMsg(this->buffer); Process(remoteParticipant, msg); delete msg; } break; case InvestigateMsg::id: { InvestigateMsg *msg = new InvestigateMsg(this->buffer); Process(msg); delete msg; } break; case ThingMsg::id: { ThingMsg *msg = new ThingMsg(this->buffer); Process(msg); delete msg; } break; case PoseMsg::id: { PoseMsg *msg = new PoseMsg(this->buffer); Process(msg); delete msg; } break; case CustomMsg::id: { CustomMsg *msg = new CustomMsg(this->buffer); Process(msg); delete msg; } break; }; } void Participant::Process(Participant *sender, ClientMsg *msg) {} void Participant::Process(Participant *sender, NetworkIdMsg *msg) { std::cout << this->name << " receive network id " << (int)this->networkId << " " << (int)msg->networkId << "\n"; if (this->networkId != msg->networkId) { this->networkId = msg->networkId; // Thing **allThings = Thing::GetAllThings(); // for (uint16_t ix = 0; ix < THING_STORE_SIZE; ix++) { // Thing *thing = allThings[ix]; // if (thing == nullptr) // continue; // sender->SendThingInfo(thing); // } for (Thing *thing : Thing::allThings) { sender->SendThingInfo(thing); } } } void Participant::Process(InvestigateMsg *msg) {} void Participant::Process(ThingMsg *msg) {} void Participant::Process(PoseMsg *msg) {} void Participant::Process(CustomMsg *msg) { Thing *thing = Thing::Get(msg->networkId, msg->thingId); if (thing != nullptr) thing->ProcessBytes(msg->bytes); } // Receive #pragma endregion