From 7f29ac4205b370becd80b80b5673926986cea544 Mon Sep 17 00:00:00 2001 From: Pascal Serrarens Date: Fri, 3 Jan 2025 10:35:51 +0100 Subject: [PATCH] Site Server test runs --- CMakeLists.txt | 11 ++-- ClientMsg.cpp | 21 ++++++++ ClientMsg.h | 22 ++++++++ Messages.cpp | 131 +++------------------------------------------ Messages.h | 65 +--------------------- ModelUrlMsg.cpp | 45 ++++++++++++++++ ModelUrlMsg.h | 26 +++++++++ NameMsg.cpp | 43 +++++++++++++++ NameMsg.h | 24 +++++++++ Participant.cpp | 108 +++++++++++++++++++++++++++++++------ Participant.h | 21 ++++++-- SiteServer.cpp | 22 ++++++++ SiteServer.h | 24 +++++++++ Thing.cpp | 2 + Thing.h | 1 + ThingMsg.cpp | 44 +++++++++++++++ ThingMsg.h | 24 +++++++++ test/thing_test.cc | 67 ++++++----------------- 18 files changed, 431 insertions(+), 270 deletions(-) create mode 100644 ClientMsg.cpp create mode 100644 ClientMsg.h create mode 100644 ModelUrlMsg.cpp create mode 100644 ModelUrlMsg.h create mode 100644 NameMsg.cpp create mode 100644 NameMsg.h create mode 100644 SiteServer.cpp create mode 100644 SiteServer.h create mode 100644 ThingMsg.cpp create mode 100644 ThingMsg.h 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