diff --git a/CMakeLists.txt b/CMakeLists.txt index 8023ded..7430327 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,14 +27,9 @@ else() . LinearAlgebra ) - add_library(ControlCore STATIC - "Thing.cpp" - "LowLevelMessages.cpp" - "Messages.cpp" - "Participant.cpp" - "float16.cpp" - ) - + file(GLOB srcs *.cpp) + add_library(ControlCore STATIC ${srcs}) + enable_testing() file(GLOB_RECURSE test_srcs test/*_test.cc) diff --git a/ClientMsg.cpp b/ClientMsg.cpp new file mode 100644 index 0000000..c749092 --- /dev/null +++ b/ClientMsg.cpp @@ -0,0 +1,21 @@ +#include "ClientMsg.h" + +namespace Passer::Control { + +ClientMsg::ClientMsg(char networkId) { this->networkId = networkId; } + +ClientMsg::ClientMsg(const char *buffer) { this->networkId = buffer[1]; } + +unsigned char ClientMsg::Serialize(char *buffer) { + unsigned char ix = 0; + buffer[ix++] = this->id; + buffer[ix++] = this->networkId; + return ClientMsg::length; +} + +// bool ClientMsg::Send(Participant *participant, unsigned char networkId) { +// ClientMsg msg = ClientMsg() +// } +// Client Msg + +} // namespace Passer::Control \ No newline at end of file diff --git a/ClientMsg.h b/ClientMsg.h new file mode 100644 index 0000000..ca643db --- /dev/null +++ b/ClientMsg.h @@ -0,0 +1,22 @@ +#include "Messages.h" + +namespace Passer { +namespace Control { + +/// @brief A client message announces the presence of a participant +/// When received by another participant, it can be followed by a NetworkIdMsg +/// to announce that participant to this client such that it can join privately +class ClientMsg : public IMessage { +public: + static const unsigned char id = 0xA0; + static const unsigned char length = 2; + unsigned char networkId; + + ClientMsg(char networkId); + ClientMsg(const char *buffer); + + virtual unsigned char Serialize(char *buffer) override; +}; + +} // namespace Control +} // namespace Passer \ No newline at end of file diff --git a/Messages.cpp b/Messages.cpp index 5dcfbd0..e9d7358 100644 --- a/Messages.cpp +++ b/Messages.cpp @@ -23,33 +23,16 @@ unsigned char *IMessage::ReceiveMsg(unsigned char packetSize) { return nullptr; } -bool IMessage::Publish(Participant *participant) { - return participant->PublishBuffer(Serialize(participant->buffer)); -} -bool IMessage::SendTo(Participant *participant) { - return participant->SendBuffer(Serialize(participant->buffer)); -} +// bool IMessage::Publish(Participant *participant) { +// return participant->PublishBuffer(Serialize(participant->buffer)); +// } +// bool IMessage::SendTo(Participant *participant) { +// return participant->SendBuffer(Serialize(participant->buffer)); +// } // IMessage #pragma endregion -#pragma region Client - -ClientMsg::ClientMsg(char networkId) { this->networkId = networkId; } - -unsigned char ClientMsg::Serialize(char *buffer) { - unsigned char ix = 0; - buffer[ix++] = this->id; - buffer[ix++] = this->networkId; - return ClientMsg::length; -} - -// bool ClientMsg::Send(Participant *participant, unsigned char networkId) { -// ClientMsg msg = ClientMsg() -// } -// Client Msg -#pragma endregion - #pragma region Network Id NetworkIdMsg::NetworkIdMsg(char *buffer) { this->networkId = buffer[1]; } @@ -95,108 +78,6 @@ unsigned char InvestigateMsg::Serialize(char *buffer) { // Investigate #pragma endregion -#pragma region Thing - -ThingMsg::ThingMsg(char *buffer) { - unsigned char ix = 1; // first byte is msg id - this->networkId = buffer[ix++]; - this->thingId = buffer[ix++]; - this->thingType = buffer[ix++]; - this->parentId = buffer[ix++]; -} - -ThingMsg::ThingMsg(unsigned char networkId, unsigned char thingId, - unsigned char thingType, unsigned char parentId) { - this->networkId = networkId; - this->thingId = thingId; - this->thingType = thingType; - this->parentId = parentId; -} - -unsigned char ThingMsg::Serialize(char *buffer) { - unsigned char ix = 0; - buffer[ix++] = this->id; - buffer[ix++] = this->networkId; - buffer[ix++] = this->thingId; - buffer[ix++] = this->thingType; - buffer[ix++] = this->parentId; - return ix; -} - -// bool ThingMsg::Send(Participant *participant, unsigned char networkId, -// unsigned char thingId, unsigned char thingType, -// unsigned char parentId) { -// ThingMsg msg = ThingMsg(networkId, thingId, thingType, parentId); -// return msg.Send(participant); -// } - -// Thing -#pragma endregion - -#pragma region Name - -NameMsg::NameMsg(unsigned char networkId, unsigned char thingId, - const char *name, unsigned char nameLength) { - this->networkId = networkId; - this->thingId = thingId; - this->name = name; - this->nameLength = nameLength; -} - -unsigned char NameMsg::Serialize(char *buffer) { - unsigned char ix = 0; - buffer[ix++] = this->id; - buffer[ix++] = this->networkId; - buffer[ix++] = this->thingId; - buffer[ix++] = this->nameLength; - for (int nameIx = 0; nameIx < this->nameLength; nameIx++) - buffer[ix++] = this->name[nameIx]; - - return ix; -} - -// bool NameMsg::Send(Participant *participant, Thing *thing, -// unsigned char nameLength) { -// if (thing->name == nullptr) -// return true; // nothing sent, but still a success! - -// if (strlen(thing->name) == 0) -// return true; - -// NameMsg msg = NameMsg(thing->networkId, thing->id, thing->name, -// nameLength); return msg.Send(participant); -// } - -// Name -#pragma endregion - -#pragma region ModelUrl - -ModelUrlMsg::ModelUrlMsg(unsigned char networkId, unsigned char thingId, - unsigned char urlLength, const char *url, - float scale) { - this->networkId = networkId; - this->thingId = thingId; - this->urlLength = urlLength; - this->url = url; - this->scale = scale; -} - -unsigned char ModelUrlMsg::Serialize(char *buffer) { - unsigned char ix = 0; - buffer[ix++] = this->id; - buffer[ix++] = this->networkId; - buffer[ix++] = this->thingId; - LowLevelMessages::SendFloat16(buffer, &ix, this->scale); - buffer[ix++] = this->urlLength; - for (int urlIx = 0; urlIx < this->urlLength; urlIx++) - buffer[ix++] = url[urlIx]; - return ix; -} - -// Model Url -#pragma endregion - #pragma region PoseMsg PoseMsg::PoseMsg(unsigned char networkId, unsigned char thingId, diff --git a/Messages.h b/Messages.h index 935bcdb..37da6c1 100644 --- a/Messages.h +++ b/Messages.h @@ -17,21 +17,8 @@ public: static unsigned char *ReceiveMsg(unsigned char packetSize); - bool Publish(Participant *participant); - bool SendTo(Participant *participant); -}; - -/// @brief A client message announces the presence of a participant -/// When received by another participant, it can be followed by a NetworkIdMsg -/// to announce that participant to this client such that it can join privately -class ClientMsg : public IMessage { -public: - static const unsigned char id = 0xA0; - static const unsigned char length = 2; - unsigned char networkId; - - ClientMsg(char networkId); - virtual unsigned char Serialize(char *buffer) override; + // bool Publish(Participant *participant); + // bool SendTo(Participant *participant); }; class NetworkIdMsg : public IMessage { @@ -58,54 +45,6 @@ public: virtual unsigned char Serialize(char *buffer) override; }; -class ThingMsg : public IMessage { -public: - static const unsigned char id = 0x80; - static const unsigned char length = 5; - unsigned char networkId; - unsigned char thingId; - unsigned char thingType; - unsigned char parentId; - - ThingMsg(char *buffer); - ThingMsg(unsigned char networkId, unsigned char thingId, - unsigned char thingType, unsigned char parentId); - - virtual unsigned char Serialize(char *buffer) override; -}; - -class NameMsg : public IMessage { -public: - static const unsigned char id = 0x91; - static const unsigned char length = 4; - unsigned char networkId; - unsigned char thingId; - unsigned char nameLength; - const char *name; - - NameMsg(unsigned char networkId, unsigned char thingId, const char *name, - unsigned char nameLength); - - virtual unsigned char Serialize(char *buffer) override; -}; - -class ModelUrlMsg : public IMessage { -public: - static const unsigned char id = 0x90; - - unsigned char networkId; - unsigned char thingId; - - float scale; - unsigned char urlLength; - const char *url; - - ModelUrlMsg(unsigned char networkId, unsigned char thingId, - unsigned char urlLegth, const char *url, float scale = 1); - - virtual unsigned char Serialize(char *buffer) override; -}; - class PoseMsg : public IMessage { public: static const unsigned char id = 0x10; diff --git a/ModelUrlMsg.cpp b/ModelUrlMsg.cpp new file mode 100644 index 0000000..1d4f0da --- /dev/null +++ b/ModelUrlMsg.cpp @@ -0,0 +1,45 @@ +#include "ModelUrlMsg.h" + +namespace Passer { +namespace Control { + +// ModelUrlMsg::ModelUrlMsg(unsigned char networkId, unsigned char thingId, +// unsigned char urlLength, const char *url, +// float scale) { +// this->networkId = networkId; +// this->thingId = thingId; +// this->urlLength = urlLength; +// this->url = url; +// this->scale = scale; +// } + +ModelUrlMsg::ModelUrlMsg(const char *buffer) { + unsigned char ix = 1; // first byte is msg id + this->networkId = buffer[ix++]; + this->thingId = buffer[ix++]; + this->urlLength = buffer[ix++]; + this->url = &buffer[ix]; // dangerous! name should not be used anymore after + // buffer has been re-used... +} + +ModelUrlMsg::ModelUrlMsg(unsigned char networkId, Thing *thing) { + this->networkId = networkId; + this->thingId = thing->id; + this->urlLength = strlen(thing->modelUrl); + this->url = thing->modelUrl; // dangerous! +} + +unsigned char ModelUrlMsg::Serialize(char *buffer) { + unsigned char ix = 0; + buffer[ix++] = this->id; + buffer[ix++] = this->networkId; + buffer[ix++] = this->thingId; + // LowLevelMessages::SendFloat16(buffer, &ix, this->scale); + buffer[ix++] = this->urlLength; + for (int urlIx = 0; urlIx < this->urlLength; urlIx++) + buffer[ix++] = url[urlIx]; + return ix; +} + +} // namespace Control +} // namespace Passer \ No newline at end of file diff --git a/ModelUrlMsg.h b/ModelUrlMsg.h new file mode 100644 index 0000000..780529e --- /dev/null +++ b/ModelUrlMsg.h @@ -0,0 +1,26 @@ +#include "Messages.h" + +namespace Passer { +namespace Control { + +class ModelUrlMsg : public IMessage { +public: + static const unsigned char id = 0x90; + + unsigned char networkId; + unsigned char thingId; + + float scale; + unsigned char urlLength; + const char *url; + + ModelUrlMsg(const char *buffer); + ModelUrlMsg(unsigned char networkId, Thing *thing); + // ModelUrlMsg(unsigned char networkId, unsigned char thingId, + // unsigned char urlLegth, const char *url, float scale = 1); + + virtual unsigned char Serialize(char *buffer) override; +}; + +} // namespace Control +} // namespace Passer \ No newline at end of file diff --git a/NameMsg.cpp b/NameMsg.cpp new file mode 100644 index 0000000..a49dbc0 --- /dev/null +++ b/NameMsg.cpp @@ -0,0 +1,43 @@ +#include "NameMsg.h" + +namespace Passer { +namespace Control { + +NameMsg::NameMsg(const char *buffer) { + unsigned char ix = 1; // first byte is msg id + this->networkId = buffer[ix++]; + this->thingId = buffer[ix++]; + this->nameLength = buffer[ix++]; + this->name = &buffer[ix]; // dangerous! name should not be used anymore after + // buffer has been re-used... +} + +NameMsg::NameMsg(unsigned char networkId, Thing *thing) { + this->networkId = networkId; + this->thingId = thing->id; + this->nameLength = strlen(thing->name); + this->name = thing->name; // dangerous! +} + +// NameMsg::NameMsg(unsigned char networkId, unsigned char thingId, +// const char *name, unsigned char nameLength) { +// this->networkId = networkId; +// this->thingId = thingId; +// this->name = name; +// this->nameLength = nameLength; +// } + +unsigned char NameMsg::Serialize(char *buffer) { + unsigned char ix = 0; + buffer[ix++] = this->id; + buffer[ix++] = this->networkId; + buffer[ix++] = this->thingId; + buffer[ix++] = this->nameLength; + for (int nameIx = 0; nameIx < this->nameLength; nameIx++) + buffer[ix++] = this->name[nameIx]; + + return ix; +} + +} // namespace Control +} // namespace Passer \ No newline at end of file diff --git a/NameMsg.h b/NameMsg.h new file mode 100644 index 0000000..80ba56e --- /dev/null +++ b/NameMsg.h @@ -0,0 +1,24 @@ +#include "Messages.h" + +namespace Passer { +namespace Control { + +class NameMsg : public IMessage { +public: + static const unsigned char id = 0x91; + static const unsigned char length = 4; + unsigned char networkId; + unsigned char thingId; + unsigned char nameLength; + const char *name; + + NameMsg(const char *buffer); + NameMsg(unsigned char networkId, Thing *thing); + // NameMsg(unsigned char networkId, unsigned char thingId, const char *name, + // unsigned char nameLength); + + virtual unsigned char Serialize(char *buffer) override; +}; + +} // namespace Control +} // namespace Passer diff --git a/Participant.cpp b/Participant.cpp index 053f509..dce6631 100644 --- a/Participant.cpp +++ b/Participant.cpp @@ -1,5 +1,7 @@ #include "Participant.h" +// #include + #define BUF_SIZE 1024 #if defined(_WIN32) || defined(_WIN64) @@ -13,7 +15,11 @@ #include #endif -Passer::Control::Participant::Participant(const char *ipAddress, int port) { +Participant::Participant() {} + +Participant::Participant(const char *ipAddress, int port) { + this->ipAddress = ipAddress; + this->port = port; // Create a UDP socket #if defined(_WIN32) || defined(_WIN64) @@ -40,13 +46,23 @@ Passer::Control::Participant::Participant(const char *ipAddress, int port) { memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons((u_short)port); // Port to send the packet to - if (inet_pton(AF_INET, "255.255.255.255", &server_addr.sin_addr) <= 0) { + if (inet_pton(AF_INET, ipAddress, &server_addr.sin_addr) <= 0) { std::cerr << "Invalid address" << std::endl; closesocket(sock); WSACleanup(); return; } + // Set up the broadcast address + memset(&broadcast_addr, 0, sizeof(broadcast_addr)); + broadcast_addr.sin_family = AF_INET; + broadcast_addr.sin_port = htons((u_short)port); // Port to send the packet to + if (inet_pton(AF_INET, "255.255.255.255", &broadcast_addr.sin_addr) <= 0) { + std::cerr << "Invalid address" << std::endl; + closesocket(sock); + WSACleanup(); + return; + } BOOL broadcast = TRUE; if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&broadcast, sizeof(broadcast)) == SOCKET_ERROR) { @@ -58,24 +74,32 @@ void Participant::Update(unsigned long currentTimeMs) { // std::cout << "update\n"; if (currentTimeMs > this->nextPublishMe) { ClientMsg msg = ClientMsg(this->networkId); - this->Publish(msg); + this->Publish(&msg); // Console.WriteLine($"{this.name} Sent ClientMsg {this.networkId}"); std::cout << this->name << " sent ClientMsg\n"; this->nextPublishMe = currentTimeMs + this->publishInterval; } } -bool Participant::SendBuffer(unsigned char bufferSize) { return false; } +#pragma region Send -bool Participant::PublishBuffer(unsigned char bufferSize) { return false; } +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; + this->Send(&ModelUrlMsg(this->networkId, thing)); +} -#include - -bool Participant::Publish( - ClientMsg msg) { // I want to use IMessage here, but then the serialize - // calls the IMessage.Serialize... +bool Participant::Send(IMessage *msg) { // Send the message to the specified address and port - int bufferSize = msg.Serialize(this->buffer); + int bufferSize = msg->Serialize(this->buffer); std::cout << "buffer size " << bufferSize << "\n"; if (bufferSize <= 0) return true; @@ -96,13 +120,44 @@ bool Participant::Publish( return true; } -void Participant::ReceiveData(unsigned char bufferSize) { +bool Participant::Publish(IMessage *msg) { + // Send the message to the specified address and port + int bufferSize = msg->Serialize(this->buffer); + std::cout << "buffer size " << bufferSize << "\n"; + if (bufferSize <= 0) + return true; + + // char ip_str[INET_ADDRSTRLEN]; + // inet_ntop(AF_INET, &(server_addr.sin_addr), ip_str, INET_ADDRSTRLEN); + // std::cout << "Publish to " << ip_str << ":" << ntohs(server_addr.sin_port) + // << "\n"; + int sent_bytes = + sendto(sock, this->buffer, bufferSize, 0, + (struct sockaddr *)&broadcast_addr, sizeof(broadcast_addr)); + 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; + closesocket(sock); + WSACleanup(); + return false; + } + return true; +} + +// 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: { + Process(remoteParticipant, &ClientMsg(this->buffer)); + } case NetworkIdMsg::id: { - // NetworkIdMsg msg = NetworkIdMsg::Receive(this->buffer, bufferSize); - NetworkIdMsg msg = NetworkIdMsg(this->buffer); - ProcessNetworkIdMsg(msg); + Process(remoteParticipant, &NetworkIdMsg(this->buffer)); } break; case InvestigateMsg::id: { InvestigateMsg msg = InvestigateMsg(this->buffer); @@ -123,7 +178,23 @@ void Participant::ReceiveData(unsigned char bufferSize) { }; } -void Participant::ProcessNetworkIdMsg(NetworkIdMsg msg) {} +void Participant::Process(Participant *sender, ClientMsg *msg) {} + +void Participant::Process(Participant *sender, NetworkIdMsg *msg) { + std::cout << this->name << " receive network id " << this->networkId << " " + << 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); + } + } +} void Participant::ProcessInvestigateMsg(InvestigateMsg msg) {} @@ -131,4 +202,7 @@ void Participant::ProcessThingMsg(ThingMsg msg) {} void Passer::Control::Participant::ProcessPoseMsg(PoseMsg msg) {} -void Participant::ProcessCustomMsg(CustomMsg msg) {} \ No newline at end of file +void Participant::ProcessCustomMsg(CustomMsg msg) {} + +// Receive +#pragma endregion \ No newline at end of file diff --git a/Participant.h b/Participant.h index 5af2732..83f927e 100644 --- a/Participant.h +++ b/Participant.h @@ -1,6 +1,10 @@ #pragma once +#include "ClientMsg.h" #include "Messages.h" +#include "ModelUrlMsg.h" +#include "NameMsg.h" +#include "ThingMsg.h" #if defined(_WIN32) || defined(_WIN64) #include @@ -15,26 +19,33 @@ public: char buffer[1024]; long publishInterval = 3000; // 3 seconds unsigned char networkId = 0; + const char *name = "Participant"; + const char *ipAddress = "0.0.0.0"; + int port = 0; + SOCKET sock; sockaddr_in server_addr; + sockaddr_in broadcast_addr; + Participant(); Participant(const char *ipAddress, int port); virtual void Update(unsigned long currentTimeMs); - virtual bool SendBuffer(unsigned char bufferSize); - virtual bool PublishBuffer(unsigned char bufferSize); + void SendThingInfo(Thing *thing); - bool Publish(ClientMsg msg); + bool Send(IMessage *msg); + bool Publish(IMessage *msg); - void ReceiveData(unsigned char bufferSize); + void ReceiveData(unsigned char bufferSize, Participant *remoteParticipant); protected: unsigned long nextPublishMe = 0; - virtual void ProcessNetworkIdMsg(NetworkIdMsg msg); + virtual void Process(Participant *sender, ClientMsg *msg); + virtual void Process(Participant *sender, NetworkIdMsg *msg); virtual void ProcessInvestigateMsg(InvestigateMsg msg); virtual void ProcessThingMsg(ThingMsg msg); virtual void ProcessPoseMsg(PoseMsg msg); diff --git a/SiteServer.cpp b/SiteServer.cpp new file mode 100644 index 0000000..15721ac --- /dev/null +++ b/SiteServer.cpp @@ -0,0 +1,22 @@ +#include "SiteServer.h" + +Passer::Control::SiteServer::SiteServer(int port) { + this->name = "Site Server"; + + this->ipAddress = "0.0.0.0"; + this->port = port; +} + +void Passer::Control::SiteServer::Update(unsigned long currentTimeMs) { + Thing::UpdateAll(currentTimeMs); +} + +void Passer::Control::SiteServer::Process(Participant *sender, ClientMsg *msg) { + if (msg->networkId == 0) { + std::cout << this->name << " received New Client -> " << sender->networkId + << "\n"; + } +} + +void Passer::Control::SiteServer::Process(Participant *sender, + NetworkIdMsg *msg) {} diff --git a/SiteServer.h b/SiteServer.h new file mode 100644 index 0000000..94e37d5 --- /dev/null +++ b/SiteServer.h @@ -0,0 +1,24 @@ +#pragma once + +#include "Participant.h" + +namespace Passer { +namespace Control { + +/// @brief A participant is device which can communicate with other participants +class SiteServer : public Participant { +public: + SiteServer(int port = 7681); + + virtual void Update(unsigned long currentTimeMs) override; + +protected: + unsigned long nextPublishMe = 0; + + virtual void Process(Participant *sender, ClientMsg *msg) override; + virtual void Process(Participant *sender, NetworkIdMsg *msg) override; +}; + +} // namespace Control +} // namespace Passer +using namespace Passer::Control; \ No newline at end of file diff --git a/Thing.cpp b/Thing.cpp index 04978f1..f765603 100644 --- a/Thing.cpp +++ b/Thing.cpp @@ -154,6 +154,8 @@ Spherical16 Thing::GetAngularVelocity() { return this->angularVelocity; } // All things Thing *Thing::allThings[THING_STORE_SIZE] = {nullptr}; +Thing **Passer::Control::Thing::GetAllThings() { return allThings; } + Thing *Thing::Get(unsigned char networkId, unsigned char thingId) { for (uint16_t ix = 0; ix < THING_STORE_SIZE; ix++) { Thing *thing = allThings[ix]; diff --git a/Thing.h b/Thing.h index a8e8219..1a5e10e 100644 --- a/Thing.h +++ b/Thing.h @@ -123,6 +123,7 @@ protected: //------------ All things public: + static Thing **GetAllThings(); static Thing *Get(unsigned char networkId, unsigned char thingId); static int Add(Thing *thing); static void Remove(Thing *thing); diff --git a/ThingMsg.cpp b/ThingMsg.cpp new file mode 100644 index 0000000..8fa51f3 --- /dev/null +++ b/ThingMsg.cpp @@ -0,0 +1,44 @@ +#include "ThingMsg.h" + +namespace Passer { +namespace Control { + +ThingMsg::ThingMsg(const char *buffer) { + unsigned char ix = 1; // first byte is msg id + this->networkId = buffer[ix++]; + this->thingId = buffer[ix++]; + this->thingType = buffer[ix++]; + this->parentId = buffer[ix++]; +} + +ThingMsg::ThingMsg(unsigned char networkId, Thing *thing) { + this->networkId = networkId; + this->thingId = thing->id; + this->thingType = thing->type; + Thing *parent = thing->GetParent(); + if (parent != nullptr) + this->parentId = parent->id; + else + this->parentId = 0; +} + +// ThingMsg::ThingMsg(unsigned char networkId, unsigned char thingId, +// unsigned char thingType, unsigned char parentId) { +// this->networkId = networkId; +// this->thingId = thingId; +// this->thingType = thingType; +// this->parentId = parentId; +// } + +unsigned char ThingMsg::Serialize(char *buffer) { + unsigned char ix = 0; + buffer[ix++] = this->id; + buffer[ix++] = this->networkId; + buffer[ix++] = this->thingId; + buffer[ix++] = this->thingType; + buffer[ix++] = this->parentId; + return ix; +} + +} // namespace Control +} // namespace Passer \ No newline at end of file diff --git a/ThingMsg.h b/ThingMsg.h new file mode 100644 index 0000000..edda54e --- /dev/null +++ b/ThingMsg.h @@ -0,0 +1,24 @@ +#include "Messages.h" + +namespace Passer { +namespace Control { + +class ThingMsg : public IMessage { +public: + static const unsigned char id = 0x80; + static const unsigned char length = 5; + unsigned char networkId; + unsigned char thingId; + unsigned char thingType; + unsigned char parentId; + + ThingMsg(const char *buffer); + ThingMsg(unsigned char networkId, Thing *thing); + // ThingMsg(unsigned char networkId, unsigned char thingId, + // unsigned char thingType, unsigned char parentId); + + virtual unsigned char Serialize(char *buffer) override; +}; + +} // namespace Control +} // namespace Passer \ No newline at end of file diff --git a/test/thing_test.cc b/test/thing_test.cc index 9000456..d38fad4 100644 --- a/test/thing_test.cc +++ b/test/thing_test.cc @@ -8,6 +8,7 @@ #include #include "Participant.h" +#include "SiteServer.h" #include "Thing.h" namespace Passer { @@ -33,58 +34,6 @@ protected: } }; -void send_udp_message(const char *message, const char *ip, int port) { - WSADATA wsaData; - SOCKET sock; - struct sockaddr_in server_addr; - - // Initialize Winsock - if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { - std::cerr << "WSAStartup failed" << std::endl; - return; - } - - // Create a UDP socket - sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (sock == INVALID_SOCKET) { - std::cerr << "Socket creation failed" << std::endl; - WSACleanup(); - return; - } - - // Set up the sockaddr_in structure for the destination - memset(&server_addr, 0, sizeof(server_addr)); - server_addr.sin_family = AF_INET; - server_addr.sin_port = htons((u_short)port); - - // Convert the IP address - if (inet_pton(AF_INET, ip, &server_addr.sin_addr) <= 0) { - std::cerr << "Invalid address" << std::endl; - closesocket(sock); - WSACleanup(); - return; - } - - // Send the UDP message - int sent_bytes = sendto(sock, message, strlen(message), 0, - (struct sockaddr *)&server_addr, sizeof(server_addr)); - if (sent_bytes == SOCKET_ERROR) { - std::cerr << "sendto failed with error: " << WSAGetLastError() << std::endl; - } else { - std::cout << "Message sent successfully!" << std::endl; - } - - // Close the socket and clean up Winsock - closesocket(sock); - WSACleanup(); -} - -TEST_F(ControlCoreSuite, Dummytest) { - - send_udp_message("Hello, UDP!", "127.0.0.1", 8080); // Send to localhost - ASSERT_EQ(1, 1); -} - TEST_F(ControlCoreSuite, Participant) { Participant participant = Participant("127.0.0.1", 7681); @@ -97,5 +46,19 @@ TEST_F(ControlCoreSuite, Participant) { } ASSERT_EQ(1, 1); } + +TEST_F(ControlCoreSuite, SiteServer) { + SiteServer site = SiteServer(7681); + + unsigned long milliseconds = get_time_ms(); + unsigned long startTime = milliseconds; + while (milliseconds < startTime + 1000) { + site.Update(milliseconds); + + milliseconds = get_time_ms(); + } + ASSERT_EQ(1, 1); +} + } // namespace Passer #endif