Site Server test runs

This commit is contained in:
Pascal Serrarens 2025-01-03 10:35:51 +01:00
parent c4a778e563
commit 7f29ac4205
18 changed files with 431 additions and 270 deletions

View File

@ -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)

21
ClientMsg.cpp Normal file
View File

@ -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

22
ClientMsg.h Normal file
View File

@ -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

View File

@ -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,

View File

@ -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;

45
ModelUrlMsg.cpp Normal file
View File

@ -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

26
ModelUrlMsg.h Normal file
View File

@ -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

43
NameMsg.cpp Normal file
View File

@ -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

24
NameMsg.h Normal file
View File

@ -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

View File

@ -1,5 +1,7 @@
#include "Participant.h"
// #include <ws2tcpip.h>
#define BUF_SIZE 1024
#if defined(_WIN32) || defined(_WIN64)
@ -13,7 +15,11 @@
#include <unistd.h>
#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 <ws2tcpip.h>
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) {}
void Participant::ProcessCustomMsg(CustomMsg msg) {}
// Receive
#pragma endregion

View File

@ -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 <winsock2.h>
@ -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);

22
SiteServer.cpp Normal file
View File

@ -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) {}

24
SiteServer.h Normal file
View File

@ -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;

View File

@ -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];

View File

@ -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);

44
ThingMsg.cpp Normal file
View File

@ -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

24
ThingMsg.h Normal file
View File

@ -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

View File

@ -8,6 +8,7 @@
#include <ws2tcpip.h>
#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