Refactoring
This commit is contained in:
parent
e021e70815
commit
f2f942d084
@ -1,4 +1,4 @@
|
||||
#include "Participant.h"
|
||||
#include "ArduinoParticipant.h"
|
||||
|
||||
#if defined(ARDUINO)
|
||||
#if defined(ARDUINO_ARCH_ESP8266)
|
||||
@ -19,7 +19,7 @@
|
||||
namespace RoboidControl {
|
||||
namespace Arduino {
|
||||
|
||||
void Participant::Setup(int localPort, const char* remoteIpAddress, int remotePort) {
|
||||
void LocalParticipant::Setup(int localPort, const char* remoteIpAddress, int remotePort) {
|
||||
#if defined(ARDUINO)
|
||||
this->remoteIpAddress = remoteIpAddress;
|
||||
this->remotePort = remotePort;
|
||||
@ -42,7 +42,7 @@ void Participant::Setup(int localPort, const char* remoteIpAddress, int remotePo
|
||||
#endif
|
||||
}
|
||||
|
||||
void Participant::GetBroadcastAddress() {
|
||||
void LocalParticipant::GetBroadcastAddress() {
|
||||
#if defined(ARDUINO)
|
||||
IPAddress broadcastAddress = WiFi.localIP();
|
||||
broadcastAddress[3] = 255;
|
||||
@ -53,7 +53,7 @@ void Participant::GetBroadcastAddress() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void Participant::Receive() {
|
||||
void LocalParticipant::Receive() {
|
||||
#if defined(ARDUINO)
|
||||
int packetSize = udp.parsePacket();
|
||||
while (packetSize > 0) {
|
||||
@ -64,7 +64,7 @@ void Participant::Receive() {
|
||||
senderAddress.toCharArray(sender_ipAddress, 16);
|
||||
unsigned int sender_port = udp.remotePort();
|
||||
|
||||
// RemoteParticipant* remoteParticipant = this->GetParticipant(sender_ipAddress, sender_port);
|
||||
// Participant* remoteParticipant = this->GetParticipant(sender_ipAddress, sender_port);
|
||||
// if (remoteParticipant == nullptr) {
|
||||
// remoteParticipant = this->AddParticipant(sender_ipAddress, sender_port);
|
||||
// // std::cout << "New sender " << sender_ipAddress << ":" << sender_port
|
||||
@ -81,7 +81,7 @@ void Participant::Receive() {
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Participant::Send(RemoteParticipant* remoteParticipant, int bufferSize) {
|
||||
bool LocalParticipant::Send(Participant* remoteParticipant, int bufferSize) {
|
||||
#if defined(ARDUINO)
|
||||
// std::cout << "Sending to:\n " << remoteParticipant->ipAddress << ":"
|
||||
// << remoteParticipant->port << "\n";
|
||||
@ -101,7 +101,7 @@ bool Participant::Send(RemoteParticipant* remoteParticipant, int bufferSize) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Participant::Publish(IMessage* msg) {
|
||||
bool LocalParticipant::Publish(IMessage* msg) {
|
||||
#ifdef ARDUINO
|
||||
int bufferSize = msg->Serialize((char*)this->buffer);
|
||||
if (bufferSize <= 0)
|
@ -1,15 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "../Participant.h"
|
||||
#include "../LocalParticipant.h"
|
||||
|
||||
namespace RoboidControl {
|
||||
namespace Arduino {
|
||||
|
||||
class Participant : public RoboidControl::Participant {
|
||||
class LocalParticipant : public RoboidControl::LocalParticipant {
|
||||
public:
|
||||
void Setup(int localPort, const char* remoteIpAddress, int remotePort);
|
||||
void Receive();
|
||||
bool Send(RemoteParticipant* remoteParticipant, int bufferSize);
|
||||
bool Send(Participant* remoteParticipant, int bufferSize);
|
||||
bool Publish(IMessage* msg);
|
||||
|
||||
protected:
|
@ -5,7 +5,7 @@
|
||||
namespace RoboidControl {
|
||||
namespace Arduino {
|
||||
|
||||
DigitalInput::DigitalInput(RemoteParticipant* participant, unsigned char pin) : TouchSensor(participant) {
|
||||
DigitalInput::DigitalInput(Participant* participant, unsigned char pin) : TouchSensor(participant) {
|
||||
this->pin = pin;
|
||||
|
||||
pinMode(pin, INPUT);
|
||||
|
@ -7,7 +7,7 @@ namespace Arduino {
|
||||
|
||||
class DigitalInput : public TouchSensor {
|
||||
public:
|
||||
DigitalInput(RemoteParticipant* participant, unsigned char pin);
|
||||
DigitalInput(Participant* participant, unsigned char pin);
|
||||
|
||||
virtual void Update(unsigned long currentTimeMs) override;
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
namespace RoboidControl {
|
||||
namespace Arduino {
|
||||
|
||||
UltrasonicSensor::UltrasonicSensor(RemoteParticipant* participant, unsigned char pinTrigger, unsigned char pinEcho)
|
||||
UltrasonicSensor::UltrasonicSensor(Participant* participant, unsigned char pinTrigger, unsigned char pinEcho)
|
||||
: TouchSensor(participant) {
|
||||
this->pinTrigger = pinTrigger;
|
||||
this->pinEcho = pinEcho;
|
||||
|
@ -7,7 +7,7 @@ namespace Arduino {
|
||||
|
||||
class UltrasonicSensor : public TouchSensor {
|
||||
public:
|
||||
UltrasonicSensor(RemoteParticipant* participant, unsigned char pinTrigger, unsigned char pinEcho);
|
||||
UltrasonicSensor(Participant* participant, unsigned char pinTrigger, unsigned char pinEcho);
|
||||
|
||||
// parameters
|
||||
|
||||
|
299
LocalParticipant.cpp
Normal file
299
LocalParticipant.cpp
Normal file
@ -0,0 +1,299 @@
|
||||
#include "LocalParticipant.h"
|
||||
|
||||
#include "Thing.h"
|
||||
|
||||
#include "Arduino/ArduinoParticipant.h"
|
||||
#include "Posix/PosixParticipant.h"
|
||||
#include "Windows/WindowsParticipant.h"
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#pragma comment(lib, "ws2_32.lib")
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
#include <arpa/inet.h>
|
||||
#include <fcntl.h> // For fcntl
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <chrono>
|
||||
#endif
|
||||
|
||||
namespace RoboidControl {
|
||||
|
||||
// LocalParticipant::LocalParticipant() {}
|
||||
|
||||
LocalParticipant::LocalParticipant(int port) {
|
||||
this->ipAddress = "0.0.0.0";
|
||||
this->port = port;
|
||||
}
|
||||
|
||||
LocalParticipant::LocalParticipant(const char* ipAddress, int port) {
|
||||
this->ipAddress = ipAddress; // maybe this is not needed anymore, keeping it to "0.0.0.0"
|
||||
this->port = port;
|
||||
this->site = new Participant(ipAddress, port);
|
||||
}
|
||||
|
||||
void LocalParticipant::begin() {
|
||||
SetupUDP(this->port, this->ipAddress, this->port);
|
||||
}
|
||||
|
||||
void LocalParticipant::SetupUDP(int localPort, const char* remoteIpAddress, int remotePort) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
Windows::LocalParticipant* thisWindows = static_cast<Windows::LocalParticipant*>(this);
|
||||
thisWindows->Setup(localPort, remoteIpAddress, remotePort);
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
Posix::LocalParticipant* thisPosix = static_cast<Posix::LocalParticipant*>(this);
|
||||
thisPosix->Setup(localPort, remoteIpAddress, remotePort);
|
||||
#elif defined(ARDUINO)
|
||||
Arduino::LocalParticipant* thisArduino = static_cast<Arduino::LocalParticipant*>(this);
|
||||
thisArduino->Setup(localPort, remoteIpAddress, remotePort);
|
||||
#endif
|
||||
this->connected = true;
|
||||
}
|
||||
|
||||
void LocalParticipant::Update(unsigned long currentTimeMs) {
|
||||
if (currentTimeMs == 0) {
|
||||
#if defined(ARDUINO)
|
||||
currentTimeMs = millis();
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
|
||||
currentTimeMs = static_cast<unsigned long>(ms.count());
|
||||
#endif
|
||||
}
|
||||
|
||||
if (this->connected == false)
|
||||
begin();
|
||||
|
||||
if (this->publishInterval > 0 && currentTimeMs > this->nextPublishMe) {
|
||||
ParticipantMsg* msg = new ParticipantMsg(this->networkId);
|
||||
if (this->site == nullptr)
|
||||
this->Publish(msg);
|
||||
else
|
||||
this->Send(this->site, msg);
|
||||
delete msg;
|
||||
|
||||
this->nextPublishMe = currentTimeMs + this->publishInterval;
|
||||
}
|
||||
this->ReceiveUDP();
|
||||
|
||||
for (Thing* thing : this->things) {
|
||||
if (thing != nullptr) {
|
||||
thing->Update(currentTimeMs);
|
||||
PoseMsg* poseMsg = new PoseMsg(this->networkId, thing);
|
||||
for (Participant* sender : this->senders)
|
||||
this->Send(sender, poseMsg);
|
||||
delete poseMsg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LocalParticipant::ReceiveUDP() {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
Windows::LocalParticipant* thisWindows = static_cast<Windows::LocalParticipant*>(this);
|
||||
thisWindows->Receive();
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
Posix::LocalParticipant* thisPosix = static_cast<Posix::LocalParticipant*>(this);
|
||||
thisPosix->Receive();
|
||||
#elif defined(ARDUINO)
|
||||
Arduino::LocalParticipant* thisArduino = static_cast<Arduino::LocalParticipant*>(this);
|
||||
thisArduino->Receive();
|
||||
#endif
|
||||
}
|
||||
|
||||
Participant* LocalParticipant::GetParticipant(const char* ipAddress, int port) {
|
||||
for (Participant* sender : this->senders) {
|
||||
if (strcmp(sender->ipAddress, ipAddress) == 0 && sender->port == port)
|
||||
return sender;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Participant* LocalParticipant::AddParticipant(const char* ipAddress, int port) {
|
||||
std::cout << "New LocalParticipant " << ipAddress << ":" << port << "\n";
|
||||
Participant* participant = new Participant(ipAddress, port);
|
||||
participant->networkId = (unsigned char)this->senders.size();
|
||||
this->senders.push_back(participant);
|
||||
return participant;
|
||||
}
|
||||
|
||||
#pragma region Send
|
||||
|
||||
void LocalParticipant::SendThingInfo(Participant* remoteParticipant, Thing* thing) {
|
||||
std::cout << "Send thing info " << (int)thing->id << " \n";
|
||||
ThingMsg* thingMsg = new ThingMsg(this->networkId, thing);
|
||||
this->Send(remoteParticipant, thingMsg);
|
||||
delete thingMsg;
|
||||
NameMsg* nameMsg = new NameMsg(this->networkId, thing);
|
||||
this->Send(remoteParticipant, nameMsg);
|
||||
delete nameMsg;
|
||||
ModelUrlMsg* modelMsg = new ModelUrlMsg(this->networkId, thing);
|
||||
this->Send(remoteParticipant, modelMsg);
|
||||
delete modelMsg;
|
||||
PoseMsg* poseMsg = new PoseMsg(this->networkId, thing, true);
|
||||
this->Send(remoteParticipant, poseMsg);
|
||||
delete poseMsg;
|
||||
BinaryMsg* customMsg = new BinaryMsg(this->networkId, thing);
|
||||
this->Send(remoteParticipant, customMsg);
|
||||
delete customMsg;
|
||||
}
|
||||
|
||||
bool LocalParticipant::Send(Participant* remoteParticipant, IMessage* msg) {
|
||||
int bufferSize = msg->Serialize(this->buffer);
|
||||
if (bufferSize <= 0)
|
||||
return true;
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
Windows::LocalParticipant* thisWindows = static_cast<Windows::LocalParticipant*>(this);
|
||||
return thisWindows->Send(remoteParticipant, bufferSize);
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
Posix::LocalParticipant* thisPosix = static_cast<Posix::LocalParticipant*>(this);
|
||||
return thisPosix->Send(remoteParticipant, bufferSize);
|
||||
#elif defined(ARDUINO)
|
||||
Arduino::LocalParticipant* thisArduino = static_cast<Arduino::LocalParticipant*>(this);
|
||||
return thisArduino->Send(remoteParticipant, bufferSize);
|
||||
#endif
|
||||
}
|
||||
|
||||
void LocalParticipant::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;
|
||||
PoseMsg* poseMsg = new PoseMsg(this->networkId, thing, true);
|
||||
this->Publish(poseMsg);
|
||||
delete poseMsg;
|
||||
BinaryMsg* customMsg = new BinaryMsg(this->networkId, thing);
|
||||
this->Publish(customMsg);
|
||||
delete customMsg;
|
||||
}
|
||||
|
||||
bool LocalParticipant::Publish(IMessage* msg) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
Windows::LocalParticipant* thisWindows = static_cast<Windows::LocalParticipant*>(this);
|
||||
return thisWindows->Publish(msg);
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
Posix::LocalParticipant* thisPosix = static_cast<Posix::LocalParticipant*>(this);
|
||||
return thisPosix->Publish(msg);
|
||||
#elif defined(ARDUINO)
|
||||
Arduino::LocalParticipant* thisArduino = static_cast<Arduino::LocalParticipant*>(this);
|
||||
return thisArduino->Publish(msg);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Send
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Receive
|
||||
|
||||
void LocalParticipant::ReceiveData(unsigned char packetSize, char* senderIpAddress, unsigned int senderPort) {
|
||||
Participant* remoteParticipant = this->GetParticipant(senderIpAddress, senderPort);
|
||||
if (remoteParticipant == nullptr) {
|
||||
remoteParticipant = this->AddParticipant(senderIpAddress, senderPort);
|
||||
// std::cout << "New sender " << sender_ipAddress << ":" << sender_port
|
||||
// << "\n";
|
||||
// std::cout << "New remote participant " << remoteParticipant->ipAddress
|
||||
// << ":" << remoteParticipant->port << " "
|
||||
// << (int)remoteParticipant->networkId << "\n";
|
||||
}
|
||||
|
||||
ReceiveData(packetSize, remoteParticipant);
|
||||
}
|
||||
|
||||
void LocalParticipant::ReceiveData(unsigned char bufferSize, Participant* remoteParticipant) {
|
||||
unsigned char msgId = this->buffer[0];
|
||||
// std::cout << "receive msg " << (int)msgId << "\n";
|
||||
switch (msgId) {
|
||||
case ParticipantMsg::id: {
|
||||
ParticipantMsg* msg = new ParticipantMsg(this->buffer);
|
||||
Process(remoteParticipant, msg);
|
||||
delete msg;
|
||||
} break;
|
||||
case SiteMsg::id: {
|
||||
SiteMsg* msg = new SiteMsg(this->buffer);
|
||||
Process(remoteParticipant, msg);
|
||||
delete msg;
|
||||
} break;
|
||||
case InvestigateMsg::id: {
|
||||
InvestigateMsg* msg = new InvestigateMsg(this->buffer);
|
||||
Process(remoteParticipant, msg);
|
||||
delete msg;
|
||||
} break;
|
||||
case ThingMsg::id: {
|
||||
ThingMsg* msg = new ThingMsg(this->buffer);
|
||||
Process(remoteParticipant, msg);
|
||||
delete msg;
|
||||
} break;
|
||||
case NameMsg::id: {
|
||||
NameMsg* msg = new NameMsg(this->buffer);
|
||||
Process(remoteParticipant, msg);
|
||||
delete msg;
|
||||
} break;
|
||||
case PoseMsg::id: {
|
||||
PoseMsg* msg = new PoseMsg(this->buffer);
|
||||
Process(remoteParticipant, msg);
|
||||
delete msg;
|
||||
} break;
|
||||
case BinaryMsg::id: {
|
||||
BinaryMsg* msg = new BinaryMsg(this->buffer);
|
||||
Process(remoteParticipant, msg);
|
||||
delete msg;
|
||||
} break;
|
||||
};
|
||||
}
|
||||
|
||||
void LocalParticipant::Process(Participant* sender, ParticipantMsg* msg) {}
|
||||
|
||||
void LocalParticipant::Process(Participant* sender, SiteMsg* msg) {
|
||||
std::cout << this->name << ": process NetworkId [" << (int)this->networkId << "/" << (int)msg->networkId << "]\n";
|
||||
if (this->networkId != msg->networkId) {
|
||||
this->networkId = msg->networkId;
|
||||
std::cout << this->things.size() << " things\n";
|
||||
for (Thing* thing : this->things)
|
||||
this->SendThingInfo(sender, thing);
|
||||
}
|
||||
}
|
||||
|
||||
void LocalParticipant::Process(Participant* sender, InvestigateMsg* msg) {}
|
||||
|
||||
void LocalParticipant::Process(Participant* sender, ThingMsg* msg) {}
|
||||
|
||||
void LocalParticipant::Process(Participant* sender, NameMsg* msg) {
|
||||
Thing* thing = sender->Get(msg->networkId, msg->thingId);
|
||||
if (thing != nullptr) {
|
||||
int nameLength = msg->nameLength;
|
||||
int stringLen = nameLength + 1;
|
||||
char* thingName = new char[stringLen];
|
||||
// Use strncpy with bounds checking for other platforms (Arduino, POSIX, ESP-IDF)
|
||||
strncpy(thingName, msg->name, stringLen - 1); // Leave space for null terminator
|
||||
thingName[nameLength] = '\0';
|
||||
thing->name = thingName;
|
||||
std::cout << "thing name = " << thing->name << " length = " << nameLength << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void LocalParticipant::Process(Participant* sender, PoseMsg* msg) {}
|
||||
|
||||
void LocalParticipant::Process(Participant* sender, BinaryMsg* msg) {
|
||||
// std::cout << this->name << ": process Binary [" << (int)this->networkId << "/"
|
||||
// << (int)msg->networkId << "]\n";
|
||||
Thing* thing = sender->Get(msg->networkId, msg->thingId);
|
||||
if (thing != nullptr)
|
||||
thing->ProcessBinary(msg->bytes);
|
||||
else
|
||||
std::cout << "custom msg for unknown thing [" << (int)msg->networkId << "/" << (int)msg->thingId << "]\n";
|
||||
}
|
||||
|
||||
// Receive
|
||||
#pragma endregion
|
||||
|
||||
} // namespace RoboidControl
|
96
LocalParticipant.h
Normal file
96
LocalParticipant.h
Normal file
@ -0,0 +1,96 @@
|
||||
#pragma once
|
||||
|
||||
#include "Messages/BinaryMsg.h"
|
||||
#include "Messages/InvestigateMsg.h"
|
||||
#include "Messages/ModelUrlMsg.h"
|
||||
#include "Messages/NameMsg.h"
|
||||
#include "Messages/ParticipantMsg.h"
|
||||
#include "Messages/PoseMsg.h"
|
||||
#include "Messages/SiteMsg.h"
|
||||
#include "Messages/ThingMsg.h"
|
||||
#include "Participant.h"
|
||||
|
||||
#include <list>
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#include <winsock2.h>
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#elif defined(ARDUINO)
|
||||
#include <WiFiUdp.h>
|
||||
#endif
|
||||
|
||||
namespace RoboidControl {
|
||||
|
||||
/// @brief A participant is device which can communicate with other participants
|
||||
class LocalParticipant : public Participant {
|
||||
public:
|
||||
char buffer[1024];
|
||||
long publishInterval = 3000; // 3 seconds
|
||||
|
||||
const char* name = "LocalParticipant";
|
||||
|
||||
// int localPort = 0;
|
||||
Participant* site = nullptr;
|
||||
|
||||
#if defined(ARDUINO)
|
||||
const char* remoteIpAddress = nullptr;
|
||||
unsigned short remotePort = 0;
|
||||
char* broadcastIpAddress = nullptr;
|
||||
|
||||
WiFiUDP udp;
|
||||
#else
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
SOCKET sock;
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
int sock;
|
||||
#endif
|
||||
sockaddr_in remote_addr;
|
||||
sockaddr_in server_addr;
|
||||
sockaddr_in broadcast_addr;
|
||||
|
||||
#endif
|
||||
|
||||
LocalParticipant(int port = 7681);
|
||||
LocalParticipant(const char* ipAddress, int port = 7681);
|
||||
|
||||
void begin();
|
||||
bool connected = false;
|
||||
|
||||
virtual void Update(unsigned long currentTimeMs = 0);
|
||||
|
||||
void SendThingInfo(Participant* remoteParticipant, Thing* thing);
|
||||
void PublishThingInfo(Thing* thing);
|
||||
|
||||
bool Send(Participant* remoteParticipant, IMessage* msg);
|
||||
bool Publish(IMessage* msg);
|
||||
|
||||
void ReceiveData(unsigned char bufferSize, char* senderIpAddress, unsigned int senderPort);
|
||||
void ReceiveData(unsigned char bufferSize, Participant* remoteParticipant);
|
||||
|
||||
std::list<Participant*> senders;
|
||||
|
||||
protected:
|
||||
unsigned long nextPublishMe = 0;
|
||||
|
||||
void SetupUDP(int localPort, const char* remoteIpAddress, int remotePort);
|
||||
|
||||
Participant* GetParticipant(const char* ipAddress, int port);
|
||||
Participant* AddParticipant(const char* ipAddress, int port);
|
||||
|
||||
void ReceiveUDP();
|
||||
|
||||
virtual void Process(Participant* sender, ParticipantMsg* msg);
|
||||
virtual void Process(Participant* sender, SiteMsg* msg);
|
||||
virtual void Process(Participant* sender, InvestigateMsg* msg);
|
||||
virtual void Process(Participant* sender, ThingMsg* msg);
|
||||
virtual void Process(Participant* sender, NameMsg* msg);
|
||||
virtual void Process(Participant* sender, PoseMsg* msg);
|
||||
virtual void Process(Participant* sender, BinaryMsg* msg);
|
||||
};
|
||||
|
||||
} // namespace RoboidControl
|
@ -1,7 +1,7 @@
|
||||
#include "Messages.h"
|
||||
|
||||
#include "LowLevelMessages.h"
|
||||
#include "Participant.h"
|
||||
//#include "Participant.h"
|
||||
#include "string.h"
|
||||
|
||||
namespace RoboidControl {
|
||||
@ -18,15 +18,15 @@ unsigned char IMessage::Serialize(char* buffer) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// bool IMessage::SendMsg(Participant *client, IMessage msg) {
|
||||
// bool IMessage::SendMsg(LocalParticipant *client, IMessage msg) {
|
||||
// // return SendMsg(client, client.buffer, );nameLength
|
||||
// return client->SendBuffer(msg.Serialize(client->buffer));
|
||||
// }
|
||||
|
||||
// bool IMessage::Publish(Participant *participant) {
|
||||
// bool IMessage::Publish(LocalParticipant *participant) {
|
||||
// return participant->PublishBuffer(Serialize(participant->buffer));
|
||||
// }
|
||||
// bool IMessage::SendTo(Participant *participant) {
|
||||
// bool IMessage::SendTo(LocalParticipant *participant) {
|
||||
// return participant->SendBuffer(Serialize(participant->buffer));
|
||||
// }
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
namespace RoboidControl {
|
||||
|
||||
class Participant;
|
||||
class LocalParticipant;
|
||||
|
||||
class IMessage {
|
||||
public:
|
||||
@ -15,8 +15,8 @@ class IMessage {
|
||||
|
||||
static unsigned char* ReceiveMsg(unsigned char packetSize);
|
||||
|
||||
// bool Publish(Participant *participant);
|
||||
// bool SendTo(Participant *participant);
|
||||
// bool Publish(LocalParticipant *participant);
|
||||
// bool SendTo(LocalParticipant *participant);
|
||||
};
|
||||
|
||||
} // namespace RoboidControl
|
||||
|
@ -19,7 +19,7 @@ unsigned char ParticipantMsg::Serialize(char* buffer) {
|
||||
return ParticipantMsg::length;
|
||||
}
|
||||
|
||||
// bool ParticipantMsg::Send(Participant *participant, unsigned char networkId) {
|
||||
// bool ParticipantMsg::Send(LocalParticipant *participant, unsigned char networkId) {
|
||||
// ParticipantMsg msg = ParticipantMsg()
|
||||
// }
|
||||
// Client Msg
|
||||
|
316
Participant.cpp
316
Participant.cpp
@ -1,299 +1,73 @@
|
||||
#include "Participant.h"
|
||||
|
||||
#include "Thing.h"
|
||||
|
||||
#include "Arduino/Participant.h"
|
||||
#include "Posix/Participant.h"
|
||||
#include "Windows/Participant.h"
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#pragma comment(lib, "ws2_32.lib")
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
#include <arpa/inet.h>
|
||||
#include <fcntl.h> // For fcntl
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <chrono>
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
namespace RoboidControl {
|
||||
|
||||
// Participant::Participant() {}
|
||||
|
||||
Participant::Participant(int port) {
|
||||
this->ipAddress = "0.0.0.0";
|
||||
this->port = port;
|
||||
}
|
||||
Participant::Participant() {}
|
||||
|
||||
Participant::Participant(const char* ipAddress, int port) {
|
||||
this->ipAddress = ipAddress; // maybe this is not needed anymore, keeping it to "0.0.0.0"
|
||||
// make a copy of the ip address string
|
||||
int addressLength = strlen(ipAddress);
|
||||
int stringLength = addressLength + 1;
|
||||
char* addressString = new char[stringLength];
|
||||
strncpy(addressString, ipAddress, addressLength);
|
||||
addressString[addressLength] = '\0';
|
||||
|
||||
this->ipAddress = addressString;
|
||||
this->port = port;
|
||||
this->site = new RemoteParticipant(ipAddress, port);
|
||||
}
|
||||
|
||||
void Participant::begin() {
|
||||
SetupUDP(this->port, this->ipAddress, this->port);
|
||||
Participant::~Participant() {
|
||||
delete[] this->ipAddress;
|
||||
}
|
||||
|
||||
void Participant::SetupUDP(int localPort, const char* remoteIpAddress, int remotePort) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
Windows::Participant* thisWindows = static_cast<Windows::Participant*>(this);
|
||||
thisWindows->Setup(localPort, remoteIpAddress, remotePort);
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
Posix::Participant* thisPosix = static_cast<Posix::Participant*>(this);
|
||||
thisPosix->Setup(localPort, remoteIpAddress, remotePort);
|
||||
#elif defined(ARDUINO)
|
||||
Arduino::Participant* thisArduino = static_cast<Arduino::Participant*>(this);
|
||||
thisArduino->Setup(localPort, remoteIpAddress, remotePort);
|
||||
#endif
|
||||
this->connected = true;
|
||||
}
|
||||
|
||||
void Participant::Update(unsigned long currentTimeMs) {
|
||||
if (currentTimeMs == 0) {
|
||||
#if defined(ARDUINO)
|
||||
currentTimeMs = millis();
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
|
||||
currentTimeMs = static_cast<unsigned long>(ms.count());
|
||||
#endif
|
||||
}
|
||||
|
||||
if (this->connected == false)
|
||||
begin();
|
||||
|
||||
if (this->publishInterval > 0 && currentTimeMs > this->nextPublishMe) {
|
||||
ParticipantMsg* msg = new ParticipantMsg(this->networkId);
|
||||
if (this->site == nullptr)
|
||||
this->Publish(msg);
|
||||
else
|
||||
this->Send(this->site, msg);
|
||||
delete msg;
|
||||
|
||||
this->nextPublishMe = currentTimeMs + this->publishInterval;
|
||||
}
|
||||
this->ReceiveUDP();
|
||||
|
||||
Thing* Participant::Get(unsigned char networkId, unsigned char thingId) {
|
||||
for (Thing* thing : this->things) {
|
||||
if (thing != nullptr) {
|
||||
thing->Update(currentTimeMs);
|
||||
PoseMsg* poseMsg = new PoseMsg(this->networkId, thing);
|
||||
for (RemoteParticipant* sender : this->senders)
|
||||
this->Send(sender, poseMsg);
|
||||
delete poseMsg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Participant::ReceiveUDP() {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
Windows::Participant* thisWindows = static_cast<Windows::Participant*>(this);
|
||||
thisWindows->Receive();
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
Posix::Participant* thisPosix = static_cast<Posix::Participant*>(this);
|
||||
thisPosix->Receive();
|
||||
#elif defined(ARDUINO)
|
||||
Arduino::Participant* thisArduino = static_cast<Arduino::Participant*>(this);
|
||||
thisArduino->Receive();
|
||||
#endif
|
||||
}
|
||||
|
||||
RemoteParticipant* Participant::GetParticipant(const char* ipAddress, int port) {
|
||||
for (RemoteParticipant* sender : this->senders) {
|
||||
if (strcmp(sender->ipAddress, ipAddress) == 0 && sender->port == port)
|
||||
return sender;
|
||||
//if (thing->networkId == networkId && thing->id == thingId)
|
||||
if (thing->id == thingId)
|
||||
return thing;
|
||||
}
|
||||
// std::cout << "Could not find thing " << this->ipAddress << ":" << this->port
|
||||
// << "[" << (int)networkId << "/" << (int)thingId << "]\n";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RemoteParticipant* Participant::AddParticipant(const char* ipAddress, int port) {
|
||||
std::cout << "New Participant " << ipAddress << ":" << port << "\n";
|
||||
RemoteParticipant* participant = new RemoteParticipant(ipAddress, port);
|
||||
participant->networkId = (unsigned char)this->senders.size();
|
||||
this->senders.push_back(participant);
|
||||
return participant;
|
||||
void Participant::Add(Thing* thing, bool checkId) {
|
||||
if (checkId && thing->id == 0) {
|
||||
// allocate a new thing ID
|
||||
thing->id = this->things.size() + 1;
|
||||
this->things.push_back(thing);
|
||||
// std::cout << "Add thing with generated ID " << this->ipAddress << ":" << this->port << "[" << (int)thing->networkId << "/"
|
||||
// << (int)thing->id << "]\n";
|
||||
} else {
|
||||
Thing* foundThing = Get(thing->networkId, thing->id);
|
||||
if (foundThing == nullptr) {
|
||||
this->things.push_back(thing);
|
||||
// std::cout << "Add thing " << this->ipAddress << ":" << this->port << "[" << (int)thing->networkId << "/"
|
||||
// << (int)thing->id << "]\n";
|
||||
}
|
||||
// else
|
||||
// std::cout << "Did not add, existing thing " << this->ipAddress << ":" << this->port << "["
|
||||
// << (int)thing->networkId << "/" << (int)thing->id << "]\n";
|
||||
}
|
||||
}
|
||||
|
||||
#pragma region Send
|
||||
|
||||
void Participant::SendThingInfo(RemoteParticipant* remoteParticipant, Thing* thing) {
|
||||
std::cout << "Send thing info " << (int)thing->id << " \n";
|
||||
ThingMsg* thingMsg = new ThingMsg(this->networkId, thing);
|
||||
this->Send(remoteParticipant, thingMsg);
|
||||
delete thingMsg;
|
||||
NameMsg* nameMsg = new NameMsg(this->networkId, thing);
|
||||
this->Send(remoteParticipant, nameMsg);
|
||||
delete nameMsg;
|
||||
ModelUrlMsg* modelMsg = new ModelUrlMsg(this->networkId, thing);
|
||||
this->Send(remoteParticipant, modelMsg);
|
||||
delete modelMsg;
|
||||
PoseMsg* poseMsg = new PoseMsg(this->networkId, thing, true);
|
||||
this->Send(remoteParticipant, poseMsg);
|
||||
delete poseMsg;
|
||||
BinaryMsg* customMsg = new BinaryMsg(this->networkId, thing);
|
||||
this->Send(remoteParticipant, customMsg);
|
||||
delete customMsg;
|
||||
void Participant::Remove(Thing* thing) {
|
||||
this->things.remove_if([thing](Thing* obj) { return obj == thing; });
|
||||
std::cout << "Removing " << thing->networkId << "/" << thing->id << " list size = " << this->things.size() << "\n";
|
||||
}
|
||||
|
||||
bool Participant::Send(RemoteParticipant* remoteParticipant, IMessage* msg) {
|
||||
int bufferSize = msg->Serialize(this->buffer);
|
||||
if (bufferSize <= 0)
|
||||
return true;
|
||||
void Participant::UpdateAll(unsigned long currentTimeMs) {
|
||||
// Not very efficient, but it works for now.
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
Windows::Participant* thisWindows = static_cast<Windows::Participant*>(this);
|
||||
return thisWindows->Send(remoteParticipant, bufferSize);
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
Posix::Participant* thisPosix = static_cast<Posix::Participant*>(this);
|
||||
return thisPosix->Send(remoteParticipant, bufferSize);
|
||||
#elif defined(ARDUINO)
|
||||
Arduino::Participant* thisArduino = static_cast<Arduino::Participant*>(this);
|
||||
return thisArduino->Send(remoteParticipant, bufferSize);
|
||||
#endif
|
||||
}
|
||||
|
||||
void 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;
|
||||
PoseMsg* poseMsg = new PoseMsg(this->networkId, thing, true);
|
||||
this->Publish(poseMsg);
|
||||
delete poseMsg;
|
||||
BinaryMsg* customMsg = new BinaryMsg(this->networkId, thing);
|
||||
this->Publish(customMsg);
|
||||
delete customMsg;
|
||||
}
|
||||
|
||||
bool Participant::Publish(IMessage* msg) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
Windows::Participant* thisWindows = static_cast<Windows::Participant*>(this);
|
||||
return thisWindows->Publish(msg);
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
Posix::Participant* thisPosix = static_cast<Posix::Participant*>(this);
|
||||
return thisPosix->Publish(msg);
|
||||
#elif defined(ARDUINO)
|
||||
Arduino::Participant* thisArduino = static_cast<Arduino::Participant*>(this);
|
||||
return thisArduino->Publish(msg);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Send
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Receive
|
||||
|
||||
void Participant::ReceiveData(unsigned char packetSize, char* senderIpAddress, unsigned int senderPort) {
|
||||
RemoteParticipant* remoteParticipant = this->GetParticipant(senderIpAddress, senderPort);
|
||||
if (remoteParticipant == nullptr) {
|
||||
remoteParticipant = this->AddParticipant(senderIpAddress, senderPort);
|
||||
// std::cout << "New sender " << sender_ipAddress << ":" << sender_port
|
||||
for (Thing* thing : this->things) {
|
||||
if (thing != nullptr && thing->GetParent() == nullptr) { // update all root things
|
||||
// std::cout << " update " << (int)ix << " thingid " << (int)thing->id
|
||||
// << "\n";
|
||||
// std::cout << "New remote participant " << remoteParticipant->ipAddress
|
||||
// << ":" << remoteParticipant->port << " "
|
||||
// << (int)remoteParticipant->networkId << "\n";
|
||||
}
|
||||
|
||||
ReceiveData(packetSize, remoteParticipant);
|
||||
}
|
||||
|
||||
void Participant::ReceiveData(unsigned char bufferSize, RemoteParticipant* remoteParticipant) {
|
||||
unsigned char msgId = this->buffer[0];
|
||||
// std::cout << "receive msg " << (int)msgId << "\n";
|
||||
switch (msgId) {
|
||||
case ParticipantMsg::id: {
|
||||
ParticipantMsg* msg = new ParticipantMsg(this->buffer);
|
||||
Process(remoteParticipant, msg);
|
||||
delete msg;
|
||||
} break;
|
||||
case SiteMsg::id: {
|
||||
SiteMsg* msg = new SiteMsg(this->buffer);
|
||||
Process(remoteParticipant, msg);
|
||||
delete msg;
|
||||
} break;
|
||||
case InvestigateMsg::id: {
|
||||
InvestigateMsg* msg = new InvestigateMsg(this->buffer);
|
||||
Process(remoteParticipant, msg);
|
||||
delete msg;
|
||||
} break;
|
||||
case ThingMsg::id: {
|
||||
ThingMsg* msg = new ThingMsg(this->buffer);
|
||||
Process(remoteParticipant, msg);
|
||||
delete msg;
|
||||
} break;
|
||||
case NameMsg::id: {
|
||||
NameMsg* msg = new NameMsg(this->buffer);
|
||||
Process(remoteParticipant, msg);
|
||||
delete msg;
|
||||
} break;
|
||||
case PoseMsg::id: {
|
||||
PoseMsg* msg = new PoseMsg(this->buffer);
|
||||
Process(remoteParticipant, msg);
|
||||
delete msg;
|
||||
} break;
|
||||
case BinaryMsg::id: {
|
||||
BinaryMsg* msg = new BinaryMsg(this->buffer);
|
||||
Process(remoteParticipant, msg);
|
||||
delete msg;
|
||||
} break;
|
||||
};
|
||||
}
|
||||
|
||||
void Participant::Process(RemoteParticipant* sender, ParticipantMsg* msg) {}
|
||||
|
||||
void Participant::Process(RemoteParticipant* sender, SiteMsg* msg) {
|
||||
std::cout << this->name << ": process NetworkId [" << (int)this->networkId << "/" << (int)msg->networkId << "]\n";
|
||||
if (this->networkId != msg->networkId) {
|
||||
this->networkId = msg->networkId;
|
||||
std::cout << this->things.size() << " things\n";
|
||||
for (Thing* thing : this->things)
|
||||
this->SendThingInfo(sender, thing);
|
||||
thing->Update(currentTimeMs);
|
||||
}
|
||||
}
|
||||
|
||||
void Participant::Process(RemoteParticipant* sender, InvestigateMsg* msg) {}
|
||||
|
||||
void Participant::Process(RemoteParticipant* sender, ThingMsg* msg) {}
|
||||
|
||||
void Participant::Process(RemoteParticipant* sender, NameMsg* msg) {
|
||||
Thing* thing = sender->Get(msg->networkId, msg->thingId);
|
||||
if (thing != nullptr) {
|
||||
int nameLength = msg->nameLength;
|
||||
int stringLen = nameLength + 1;
|
||||
char* thingName = new char[stringLen];
|
||||
// Use strncpy with bounds checking for other platforms (Arduino, POSIX, ESP-IDF)
|
||||
strncpy(thingName, msg->name, stringLen - 1); // Leave space for null terminator
|
||||
thingName[nameLength] = '\0';
|
||||
thing->name = thingName;
|
||||
std::cout << "thing name = " << thing->name << " length = " << nameLength << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void Participant::Process(RemoteParticipant* sender, PoseMsg* msg) {}
|
||||
|
||||
void Participant::Process(RemoteParticipant* sender, BinaryMsg* msg) {
|
||||
// std::cout << this->name << ": process Binary [" << (int)this->networkId << "/"
|
||||
// << (int)msg->networkId << "]\n";
|
||||
Thing* thing = sender->Get(msg->networkId, msg->thingId);
|
||||
if (thing != nullptr)
|
||||
thing->ProcessBinary(msg->bytes);
|
||||
else
|
||||
std::cout << "custom msg for unknown thing [" << (int)msg->networkId << "/" << (int)msg->thingId << "]\n";
|
||||
}
|
||||
|
||||
// Receive
|
||||
#pragma endregion
|
||||
|
||||
} // namespace RoboidControl
|
||||
|
@ -1,96 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include "Messages/BinaryMsg.h"
|
||||
#include "Messages/InvestigateMsg.h"
|
||||
#include "Messages/ModelUrlMsg.h"
|
||||
#include "Messages/NameMsg.h"
|
||||
#include "Messages/ParticipantMsg.h"
|
||||
#include "Messages/PoseMsg.h"
|
||||
#include "Messages/SiteMsg.h"
|
||||
#include "Messages/ThingMsg.h"
|
||||
#include "RemoteParticipant.h"
|
||||
|
||||
#include <list>
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#include <winsock2.h>
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#elif defined(ARDUINO)
|
||||
#include <WiFiUdp.h>
|
||||
#endif
|
||||
#include "Thing.h"
|
||||
|
||||
namespace RoboidControl {
|
||||
|
||||
/// @brief A participant is device which can communicate with other participants
|
||||
class Participant : public RemoteParticipant {
|
||||
class Participant {
|
||||
public:
|
||||
char buffer[1024];
|
||||
long publishInterval = 3000; // 3 seconds
|
||||
const char *ipAddress = "0.0.0.0";
|
||||
int port = 0;
|
||||
|
||||
const char* name = "Participant";
|
||||
unsigned char networkId = 0;
|
||||
|
||||
// int localPort = 0;
|
||||
RemoteParticipant* site = nullptr;
|
||||
|
||||
#if defined(ARDUINO)
|
||||
const char* remoteIpAddress = nullptr;
|
||||
unsigned short remotePort = 0;
|
||||
char* broadcastIpAddress = nullptr;
|
||||
|
||||
WiFiUDP udp;
|
||||
#else
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
SOCKET sock;
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
int sock;
|
||||
#endif
|
||||
sockaddr_in remote_addr;
|
||||
sockaddr_in server_addr;
|
||||
sockaddr_in broadcast_addr;
|
||||
|
||||
#endif
|
||||
|
||||
Participant(int port = 7681);
|
||||
Participant(const char* ipAddress, int port = 7681);
|
||||
|
||||
void begin();
|
||||
bool connected = false;
|
||||
|
||||
virtual void Update(unsigned long currentTimeMs = 0);
|
||||
|
||||
void SendThingInfo(RemoteParticipant* remoteParticipant, Thing* thing);
|
||||
void PublishThingInfo(Thing* thing);
|
||||
|
||||
bool Send(RemoteParticipant* remoteParticipant, IMessage* msg);
|
||||
bool Publish(IMessage* msg);
|
||||
|
||||
void ReceiveData(unsigned char bufferSize, char* senderIpAddress, unsigned int senderPort);
|
||||
void ReceiveData(unsigned char bufferSize, RemoteParticipant* remoteParticipant);
|
||||
|
||||
std::list<RemoteParticipant*> senders;
|
||||
Participant();
|
||||
Participant(const char *ipAddress, int port);
|
||||
~Participant();
|
||||
|
||||
protected:
|
||||
unsigned long nextPublishMe = 0;
|
||||
std::list<Thing *> things;
|
||||
|
||||
void SetupUDP(int localPort, const char* remoteIpAddress, int remotePort);
|
||||
|
||||
RemoteParticipant* GetParticipant(const char* ipAddress, int port);
|
||||
RemoteParticipant* AddParticipant(const char* ipAddress, int port);
|
||||
|
||||
void ReceiveUDP();
|
||||
|
||||
virtual void Process(RemoteParticipant* sender, ParticipantMsg* msg);
|
||||
virtual void Process(RemoteParticipant* sender, SiteMsg* msg);
|
||||
virtual void Process(RemoteParticipant* sender, InvestigateMsg* msg);
|
||||
virtual void Process(RemoteParticipant* sender, ThingMsg* msg);
|
||||
virtual void Process(RemoteParticipant* sender, NameMsg* msg);
|
||||
virtual void Process(RemoteParticipant* sender, PoseMsg* msg);
|
||||
virtual void Process(RemoteParticipant* sender, BinaryMsg* msg);
|
||||
public:
|
||||
Thing *Get(unsigned char networkId, unsigned char thingId);
|
||||
void Add(Thing *thing, bool checkId = true);
|
||||
void Remove(Thing *thing);
|
||||
void UpdateAll(unsigned long currentTimeMs);
|
||||
};
|
||||
|
||||
} // namespace RoboidControl
|
||||
} // namespace Control
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "Participant.h"
|
||||
#include "PosixParticipant.h"
|
||||
|
||||
#if defined(__unix__) || defined(__APPLE__)
|
||||
#include <arpa/inet.h>
|
||||
@ -11,7 +11,7 @@
|
||||
namespace RoboidControl {
|
||||
namespace Posix {
|
||||
|
||||
void Participant::Setup(int localPort, const char* remoteIpAddress, int remotePort) {
|
||||
void LocalParticipant::Setup(int localPort, const char* remoteIpAddress, int remotePort) {
|
||||
#if defined(__unix__) || defined(__APPLE__)
|
||||
|
||||
// Create a UDP socket
|
||||
@ -63,7 +63,7 @@ void Participant::Setup(int localPort, const char* remoteIpAddress, int remotePo
|
||||
#endif
|
||||
}
|
||||
|
||||
void Participant::Receive() {
|
||||
void LocalParticipant::Receive() {
|
||||
#if defined(__unix__) || defined(__APPLE__)
|
||||
sockaddr_in client_addr;
|
||||
socklen_t len = sizeof(client_addr);
|
||||
@ -74,7 +74,7 @@ void Participant::Receive() {
|
||||
unsigned int sender_port = ntohs(client_addr.sin_port);
|
||||
|
||||
ReceiveData(packetSize, sender_ipAddress, sender_port);
|
||||
// RoboidControl::RemoteParticipant* remoteParticipant = this->GetParticipant(sender_ipAddress, sender_port);
|
||||
// RoboidControl::Participant* remoteParticipant = this->GetParticipant(sender_ipAddress, sender_port);
|
||||
// if (remoteParticipant == nullptr) {
|
||||
// remoteParticipant = this->AddParticipant(sender_ipAddress, sender_port);
|
||||
// // std::cout << "New sender " << sender_ipAddress << ":" << sender_port
|
||||
@ -90,7 +90,7 @@ void Participant::Receive() {
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Participant::Send(RemoteParticipant* remoteParticipant, int bufferSize) {
|
||||
bool LocalParticipant::Send(Participant* remoteParticipant, int bufferSize) {
|
||||
#if defined(__unix__) || defined(__APPLE__)
|
||||
// std::cout << "Send to " << remoteParticipant->ipAddress << ":" << ntohs(remoteParticipant->port)
|
||||
// << "\n";
|
||||
@ -113,7 +113,7 @@ bool Participant::Send(RemoteParticipant* remoteParticipant, int bufferSize) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Participant::Publish(IMessage* msg) {
|
||||
bool LocalParticipant::Publish(IMessage* msg) {
|
||||
#if defined(__unix__) || defined(__APPLE__)
|
||||
int bufferSize = msg->Serialize(this->buffer);
|
||||
if (bufferSize <= 0)
|
@ -1,15 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "../Participant.h"
|
||||
#include "../LocalParticipant.h"
|
||||
|
||||
namespace RoboidControl {
|
||||
namespace Posix {
|
||||
|
||||
class Participant : public RoboidControl::Participant {
|
||||
class LocalParticipant : public RoboidControl::LocalParticipant {
|
||||
public:
|
||||
void Setup(int localPort, const char* remoteIpAddress, int remotePort);
|
||||
void Receive();
|
||||
bool Send(RemoteParticipant* remoteParticipant, int bufferSize);
|
||||
bool Send(Participant* remoteParticipant, int bufferSize);
|
||||
bool Publish(IMessage* msg);
|
||||
};
|
||||
|
@ -1,73 +0,0 @@
|
||||
#include "RemoteParticipant.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
namespace RoboidControl {
|
||||
|
||||
RemoteParticipant::RemoteParticipant() {}
|
||||
|
||||
RemoteParticipant::RemoteParticipant(const char* ipAddress, int port) {
|
||||
// make a copy of the ip address string
|
||||
int addressLength = strlen(ipAddress);
|
||||
int stringLength = addressLength + 1;
|
||||
char* addressString = new char[stringLength];
|
||||
strncpy(addressString, ipAddress, addressLength);
|
||||
addressString[addressLength] = '\0';
|
||||
|
||||
this->ipAddress = addressString;
|
||||
this->port = port;
|
||||
}
|
||||
|
||||
RemoteParticipant::~RemoteParticipant() {
|
||||
delete[] this->ipAddress;
|
||||
}
|
||||
|
||||
Thing* RemoteParticipant::Get(unsigned char networkId, unsigned char thingId) {
|
||||
for (Thing* thing : this->things) {
|
||||
//if (thing->networkId == networkId && thing->id == thingId)
|
||||
if (thing->id == thingId)
|
||||
return thing;
|
||||
}
|
||||
// std::cout << "Could not find thing " << this->ipAddress << ":" << this->port
|
||||
// << "[" << (int)networkId << "/" << (int)thingId << "]\n";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void RemoteParticipant::Add(Thing* thing, bool checkId) {
|
||||
if (checkId && thing->id == 0) {
|
||||
// allocate a new thing ID
|
||||
thing->id = this->things.size() + 1;
|
||||
this->things.push_back(thing);
|
||||
// std::cout << "Add thing with generated ID " << this->ipAddress << ":" << this->port << "[" << (int)thing->networkId << "/"
|
||||
// << (int)thing->id << "]\n";
|
||||
} else {
|
||||
Thing* foundThing = Get(thing->networkId, thing->id);
|
||||
if (foundThing == nullptr) {
|
||||
this->things.push_back(thing);
|
||||
// std::cout << "Add thing " << this->ipAddress << ":" << this->port << "[" << (int)thing->networkId << "/"
|
||||
// << (int)thing->id << "]\n";
|
||||
}
|
||||
// else
|
||||
// std::cout << "Did not add, existing thing " << this->ipAddress << ":" << this->port << "["
|
||||
// << (int)thing->networkId << "/" << (int)thing->id << "]\n";
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteParticipant::Remove(Thing* thing) {
|
||||
this->things.remove_if([thing](Thing* obj) { return obj == thing; });
|
||||
std::cout << "Removing " << thing->networkId << "/" << thing->id << " list size = " << this->things.size() << "\n";
|
||||
}
|
||||
|
||||
void RemoteParticipant::UpdateAll(unsigned long currentTimeMs) {
|
||||
// Not very efficient, but it works for now.
|
||||
|
||||
for (Thing* thing : this->things) {
|
||||
if (thing != nullptr && thing->GetParent() == nullptr) { // update all root things
|
||||
// std::cout << " update " << (int)ix << " thingid " << (int)thing->id
|
||||
// << "\n";
|
||||
thing->Update(currentTimeMs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace RoboidControl
|
@ -1,27 +0,0 @@
|
||||
#pragma once
|
||||
#include "Thing.h"
|
||||
|
||||
namespace RoboidControl {
|
||||
|
||||
class RemoteParticipant {
|
||||
public:
|
||||
const char *ipAddress = "0.0.0.0";
|
||||
int port = 0;
|
||||
|
||||
unsigned char networkId = 0;
|
||||
|
||||
RemoteParticipant();
|
||||
RemoteParticipant(const char *ipAddress, int port);
|
||||
~RemoteParticipant();
|
||||
|
||||
protected:
|
||||
std::list<Thing *> things;
|
||||
|
||||
public:
|
||||
Thing *Get(unsigned char networkId, unsigned char thingId);
|
||||
void Add(Thing *thing, bool checkId = true);
|
||||
void Remove(Thing *thing);
|
||||
void UpdateAll(unsigned long currentTimeMs);
|
||||
};
|
||||
|
||||
} // namespace Control
|
@ -4,6 +4,6 @@ namespace RoboidControl {
|
||||
|
||||
//DigitalSensor::DigitalSensor() {}
|
||||
|
||||
DigitalSensor::DigitalSensor(RemoteParticipant* participant, unsigned char networkId, unsigned char thingId) : Thing(participant) {}
|
||||
DigitalSensor::DigitalSensor(Participant* participant, unsigned char networkId, unsigned char thingId) : Thing(participant) {}
|
||||
|
||||
} // namespace RoboidControl
|
||||
|
@ -15,7 +15,7 @@ class DigitalSensor : public Thing {
|
||||
/// @brief Create a temperature sensor with the given ID
|
||||
/// @param networkId The network ID of the sensor
|
||||
/// @param thingId The ID of the thing
|
||||
DigitalSensor(RemoteParticipant* participant, unsigned char networkId, unsigned char thingId);
|
||||
DigitalSensor(Participant* participant, unsigned char networkId, unsigned char thingId);
|
||||
};
|
||||
|
||||
} // namespace RoboidControl
|
||||
|
@ -8,7 +8,7 @@ namespace RoboidControl {
|
||||
|
||||
//TemperatureSensor::TemperatureSensor() : Thing(Type::TemperatureSensor) {}
|
||||
|
||||
TemperatureSensor::TemperatureSensor(RemoteParticipant* participant, unsigned char networkId, unsigned char thingId)
|
||||
TemperatureSensor::TemperatureSensor(Participant* participant, unsigned char networkId, unsigned char thingId)
|
||||
: Thing(participant, networkId, thingId, Type::TemperatureSensor) {}
|
||||
|
||||
void TemperatureSensor::SetTemperature(float temp) {
|
||||
|
@ -15,7 +15,7 @@ class TemperatureSensor : public Thing {
|
||||
/// @brief Create a temperature sensor with the given ID
|
||||
/// @param networkId The network ID of the sensor
|
||||
/// @param thingId The ID of the thing
|
||||
TemperatureSensor(RemoteParticipant* participant, unsigned char networkId, unsigned char thingId);
|
||||
TemperatureSensor(Participant* participant, unsigned char networkId, unsigned char thingId);
|
||||
|
||||
/// @brief Manually override the measured temperature
|
||||
/// @param temperature The new temperature
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace RoboidControl {
|
||||
|
||||
TouchSensor::TouchSensor(RemoteParticipant* participant) : Thing(participant) {
|
||||
TouchSensor::TouchSensor(Participant* participant) : Thing(participant) {
|
||||
this->touchedSomething = false;
|
||||
this->type = (unsigned char)Thing::Type::TouchSensor;
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ class TouchSensor : public Thing {
|
||||
bool touchedSomething = false;
|
||||
|
||||
/// @brief Create a touch sensor
|
||||
TouchSensor(RemoteParticipant* participant);
|
||||
TouchSensor(Participant* participant);
|
||||
/// @brief Create a temperature sensor with the given ID
|
||||
/// @param networkId The network ID of the sensor
|
||||
/// @param thingId The ID of the thing
|
||||
|
@ -21,7 +21,7 @@ SiteServer::SiteServer(int port) {
|
||||
Register<TemperatureSensor>((unsigned char)Thing::Type::TemperatureSensor);
|
||||
}
|
||||
|
||||
void SiteServer::Process(RemoteParticipant *sender, ParticipantMsg *msg) {
|
||||
void SiteServer::Process(Participant *sender, ParticipantMsg *msg) {
|
||||
if (msg->networkId == 0) {
|
||||
std::cout << this->name << " received New Client -> " << sender->ipAddress
|
||||
<< ":" << (int)sender->port << "\n";
|
||||
@ -31,9 +31,9 @@ void SiteServer::Process(RemoteParticipant *sender, ParticipantMsg *msg) {
|
||||
}
|
||||
}
|
||||
|
||||
void SiteServer::Process(RemoteParticipant *sender, SiteMsg *msg) {}
|
||||
void SiteServer::Process(Participant *sender, SiteMsg *msg) {}
|
||||
|
||||
void SiteServer::Process(RemoteParticipant *sender, ThingMsg *msg) {
|
||||
void SiteServer::Process(Participant *sender, ThingMsg *msg) {
|
||||
Thing *thing = sender->Get(msg->networkId, msg->thingId);
|
||||
if (thing == nullptr) {
|
||||
auto thingMsgProcessor = thingMsgProcessors.find(msg->thingType);
|
||||
|
14
SiteServer.h
14
SiteServer.h
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "Participant.h"
|
||||
#include "LocalParticipant.h"
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
@ -9,7 +9,7 @@
|
||||
namespace RoboidControl {
|
||||
|
||||
/// @brief A participant is device which can communicate with other participants
|
||||
class SiteServer : public Participant {
|
||||
class SiteServer : public LocalParticipant {
|
||||
public:
|
||||
SiteServer(int port = 7681);
|
||||
|
||||
@ -17,7 +17,7 @@ class SiteServer : public Participant {
|
||||
|
||||
template <typename ThingClass>
|
||||
void Register(unsigned char thingType) {
|
||||
thingMsgProcessors[thingType] = [](RemoteParticipant* participant, unsigned char networkId, unsigned char thingId) {
|
||||
thingMsgProcessors[thingType] = [](Participant* participant, unsigned char networkId, unsigned char thingId) {
|
||||
return new ThingClass(participant, networkId, thingId);
|
||||
};
|
||||
};
|
||||
@ -25,11 +25,11 @@ class SiteServer : public Participant {
|
||||
protected:
|
||||
unsigned long nextPublishMe = 0;
|
||||
|
||||
virtual void Process(RemoteParticipant* sender, ParticipantMsg* msg) override;
|
||||
virtual void Process(RemoteParticipant* sender, SiteMsg* msg) override;
|
||||
virtual void Process(RemoteParticipant* sender, ThingMsg* msg) override;
|
||||
virtual void Process(Participant* sender, ParticipantMsg* msg) override;
|
||||
virtual void Process(Participant* sender, SiteMsg* msg) override;
|
||||
virtual void Process(Participant* sender, ThingMsg* msg) override;
|
||||
|
||||
using ThingConstructor = std::function<Thing*(RemoteParticipant* participant, unsigned char networkId, unsigned char thingId)>;
|
||||
using ThingConstructor = std::function<Thing*(Participant* participant, unsigned char networkId, unsigned char thingId)>;
|
||||
std::unordered_map<unsigned char, ThingConstructor> thingMsgProcessors;
|
||||
};
|
||||
|
||||
|
@ -4,13 +4,13 @@
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include "Participant.h"
|
||||
#include "LocalParticipant.h"
|
||||
|
||||
namespace RoboidControl {
|
||||
|
||||
Thing::Thing(RemoteParticipant* owner, Type thingType) : Thing(owner, (unsigned char)thingType) {}
|
||||
Thing::Thing(Participant* owner, Type thingType) : Thing(owner, (unsigned char)thingType) {}
|
||||
|
||||
Thing::Thing(RemoteParticipant* owner, unsigned char thingType) {
|
||||
Thing::Thing(Participant* owner, unsigned char thingType) {
|
||||
this->participant = owner;
|
||||
this->id = 0;
|
||||
this->type = thingType;
|
||||
@ -26,7 +26,7 @@ Thing::Thing(RemoteParticipant* owner, unsigned char thingType) {
|
||||
owner->Add(this);
|
||||
}
|
||||
|
||||
Thing::Thing(RemoteParticipant* owner, unsigned char networkId, unsigned char thingId, Type thingType) {
|
||||
Thing::Thing(Participant* owner, unsigned char networkId, unsigned char thingId, Type thingType) {
|
||||
// no participant reference yet..
|
||||
this->participant = owner;
|
||||
this->networkId = networkId;
|
||||
|
10
Thing.h
10
Thing.h
@ -6,7 +6,7 @@
|
||||
|
||||
namespace RoboidControl {
|
||||
|
||||
class RemoteParticipant;
|
||||
class Participant;
|
||||
|
||||
#define THING_STORE_SIZE 256
|
||||
// IMPORTANT: values higher than 256 will need to change the Thing::id type
|
||||
@ -15,7 +15,7 @@ class RemoteParticipant;
|
||||
/// @brief A thing is the primitive building block
|
||||
class Thing {
|
||||
public:
|
||||
RemoteParticipant* participant; // -> owner
|
||||
Participant* participant; // -> owner
|
||||
unsigned char networkId = 0;
|
||||
/// @brief The ID of the thing
|
||||
unsigned char id = 0;
|
||||
@ -43,16 +43,16 @@ class Thing {
|
||||
|
||||
/// @brief Create a new thing of the given type
|
||||
/// @param thingType The predefined type of thing
|
||||
Thing(RemoteParticipant* participant, Type thingType = Type::Undetermined);
|
||||
Thing(Participant* participant, Type thingType = Type::Undetermined);
|
||||
/// @brief Create a new thing of the give type
|
||||
/// @param thingType The custom type of the thing
|
||||
Thing(RemoteParticipant* participant, unsigned char thingType);
|
||||
Thing(Participant* participant, unsigned char thingType);
|
||||
/// @brief Create a new thing for the given participant
|
||||
/// @param participant The participant for which this thing is created
|
||||
/// @param networkId The network ID of the thing
|
||||
/// @param thingId The ID of the thing
|
||||
/// @param thingType The type of thing
|
||||
Thing(RemoteParticipant* participant,
|
||||
Thing(Participant* participant,
|
||||
unsigned char networkId,
|
||||
unsigned char thingId,
|
||||
Type thingType = Type::Undetermined);
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "Participant.h"
|
||||
#include "WindowsParticipant.h"
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#include <winsock2.h>
|
||||
@ -15,7 +15,7 @@
|
||||
namespace RoboidControl {
|
||||
namespace Windows {
|
||||
|
||||
void Participant::Setup(int localPort, const char* remoteIpAddress, int remotePort) {
|
||||
void LocalParticipant::Setup(int localPort, const char* remoteIpAddress, int remotePort) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
|
||||
// Create a UDP socket
|
||||
@ -94,7 +94,7 @@ void Participant::Setup(int localPort, const char* remoteIpAddress, int remotePo
|
||||
#endif
|
||||
}
|
||||
|
||||
void Participant::Receive() {
|
||||
void LocalParticipant::Receive() {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
// char ip_str[INET_ADDRSTRLEN];
|
||||
// inet_ntop(AF_INET, &(server_addr.sin_addr), ip_str, INET_ADDRSTRLEN);
|
||||
@ -123,7 +123,7 @@ void Participant::Receive() {
|
||||
unsigned int sender_port = ntohs(client_addr.sin_port);
|
||||
|
||||
ReceiveData(packetSize, sender_ipAddress, sender_port);
|
||||
// RoboidControl::Participant* remoteParticipant = this->GetParticipant(sender_ipAddress, sender_port);
|
||||
// RoboidControl::LocalParticipant* remoteParticipant = this->GetParticipant(sender_ipAddress, sender_port);
|
||||
// if (remoteParticipant == nullptr) {
|
||||
// remoteParticipant = this->AddParticipant(sender_ipAddress, sender_port);
|
||||
// // std::cout << "New sender " << sender_ipAddress << ":"
|
||||
@ -140,7 +140,7 @@ void Participant::Receive() {
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Participant::Send(RemoteParticipant* remoteParticipant, int bufferSize) {
|
||||
bool LocalParticipant::Send(Participant* remoteParticipant, int bufferSize) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
char ip_str[INET_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET, &(remote_addr.sin_addr), ip_str, INET_ADDRSTRLEN);
|
||||
@ -165,7 +165,7 @@ bool Participant::Send(RemoteParticipant* remoteParticipant, int bufferSize) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Participant::Publish(IMessage* msg) {
|
||||
bool LocalParticipant::Publish(IMessage* msg) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
int bufferSize = msg->Serialize(this->buffer);
|
||||
if (bufferSize <= 0)
|
@ -1,15 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "../Participant.h"
|
||||
#include "../LocalParticipant.h"
|
||||
|
||||
namespace RoboidControl {
|
||||
namespace Windows {
|
||||
|
||||
class Participant : public RoboidControl::Participant {
|
||||
class LocalParticipant : public RoboidControl::LocalParticipant {
|
||||
public:
|
||||
void Setup(int localPort, const char* remoteIpAddress, int remotePort);
|
||||
void Receive();
|
||||
bool Send(RemoteParticipant* remoteParticipant, int bufferSize);
|
||||
bool Send(Participant* remoteParticipant, int bufferSize);
|
||||
bool Publish(IMessage* msg);
|
||||
};
|
||||
|
@ -25,7 +25,7 @@ protected:
|
||||
};
|
||||
|
||||
TEST_F(ControlCoreSuite2, Dummytest2) {
|
||||
Participant participant = Participant("127.0.0.1", 7681);
|
||||
LocalParticipant participant = LocalParticipant("127.0.0.1", 7681);
|
||||
ASSERT_EQ(1, 1);
|
||||
}
|
||||
|
||||
|
@ -35,8 +35,8 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(ControlCoreSuite, Participant) {
|
||||
Participant participant = Participant("127.0.0.1", 7681);
|
||||
TEST_F(ControlCoreSuite, LocalParticipant) {
|
||||
LocalParticipant participant = LocalParticipant("127.0.0.1", 7681);
|
||||
|
||||
unsigned long milliseconds = get_time_ms();
|
||||
unsigned long startTime = milliseconds;
|
||||
@ -63,7 +63,7 @@ TEST_F(ControlCoreSuite, SiteServer) {
|
||||
|
||||
TEST_F(ControlCoreSuite, SiteParticipant) {
|
||||
SiteServer site = SiteServer(7681);
|
||||
Participant participant = Participant("127.0.0.1", 7681);
|
||||
LocalParticipant participant = LocalParticipant("127.0.0.1", 7681);
|
||||
|
||||
unsigned long milliseconds = get_time_ms();
|
||||
unsigned long startTime = milliseconds;
|
||||
@ -79,7 +79,7 @@ TEST_F(ControlCoreSuite, SiteParticipant) {
|
||||
|
||||
TEST_F(ControlCoreSuite, Thing) {
|
||||
SiteServer site = SiteServer(7681);
|
||||
Participant participant = Participant("127.0.0.1", 7681);
|
||||
LocalParticipant participant = LocalParticipant("127.0.0.1", 7681);
|
||||
Thing thing = Thing(&participant);
|
||||
|
||||
unsigned long milliseconds = get_time_ms();
|
||||
|
Loading…
x
Reference in New Issue
Block a user