#include "Participant.h" // #include #define BUF_SIZE 1024 #include "UdpArduino.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(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(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(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(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 = InvestigateMsg(this->buffer); ProcessInvestigateMsg(msg); } break; case ThingMsg::id: { ThingMsg msg = ThingMsg(this->buffer); ProcessThingMsg(msg); } break; case PoseMsg::id: { PoseMsg msg = PoseMsg(this->buffer); ProcessPoseMsg(msg); } break; case CustomMsg::id: { CustomMsg msg = CustomMsg(this->buffer); ProcessCustomMsg(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 : allThings) { sender->SendThingInfo(thing); } } } void Participant::ProcessInvestigateMsg(InvestigateMsg msg) {} void Participant::ProcessThingMsg(ThingMsg msg) {} void Passer::Control::Participant::ProcessPoseMsg(PoseMsg msg) {} void Participant::ProcessCustomMsg(CustomMsg msg) {} // Receive #pragma endregion