Restored (all?) changes
This commit is contained in:
parent
a8afeeb141
commit
8338e2f5cd
@ -1,5 +1,7 @@
|
||||
#include "ModelUrlMsg.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
namespace Passer {
|
||||
namespace Control {
|
||||
|
||||
@ -25,7 +27,11 @@ ModelUrlMsg::ModelUrlMsg(const char *buffer) {
|
||||
ModelUrlMsg::ModelUrlMsg(unsigned char networkId, Thing *thing) {
|
||||
this->networkId = networkId;
|
||||
this->thingId = thing->id;
|
||||
this->urlLength = strlen(thing->modelUrl);
|
||||
if (thing->modelUrl == nullptr)
|
||||
this->urlLength = 0;
|
||||
else
|
||||
this->urlLength = strlen(thing->modelUrl);
|
||||
|
||||
this->url = thing->modelUrl; // dangerous!
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "NameMsg.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
namespace Passer {
|
||||
namespace Control {
|
||||
|
||||
@ -15,7 +17,10 @@ NameMsg::NameMsg(const char *buffer) {
|
||||
NameMsg::NameMsg(unsigned char networkId, Thing *thing) {
|
||||
this->networkId = networkId;
|
||||
this->thingId = thing->id;
|
||||
this->nameLength = strlen(thing->name);
|
||||
if (thing->name == nullptr)
|
||||
this->nameLength = 0;
|
||||
else
|
||||
this->nameLength = strlen(thing->name);
|
||||
this->name = thing->name; // dangerous!
|
||||
}
|
||||
|
||||
|
262
Participant.cpp
262
Participant.cpp
@ -4,20 +4,32 @@
|
||||
|
||||
#define BUF_SIZE 1024
|
||||
|
||||
#include "UdpArduino.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 <fcntl.h> // For fcntl
|
||||
#endif
|
||||
|
||||
Participant::Participant() {}
|
||||
|
||||
Participant::Participant(int port) {
|
||||
this->ipAddress = "0.0.0.0";
|
||||
this->port = port;
|
||||
|
||||
this->participants.push_back(this);
|
||||
|
||||
int randomPort = (rand() % (65535 - 49152 + 1)) + 49152;
|
||||
SetupUDP(randomPort, ipAddress, port);
|
||||
}
|
||||
|
||||
Participant::Participant(const char *ipAddress, int port) {
|
||||
this->ipAddress = ipAddress;
|
||||
this->port = port;
|
||||
@ -31,125 +43,18 @@ Participant::Participant(const char *ipAddress, int port) {
|
||||
void Passer::Control::Participant::SetupUDP(int localPort,
|
||||
const char *remoteIpAddress,
|
||||
int remotePort) {
|
||||
// Create a UDP socket
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
// Windows-specific Winsock initialization
|
||||
WSADATA wsaData;
|
||||
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
|
||||
std::cerr << "WSAStartup failed" << std::endl;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
this->sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
this->sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
#endif
|
||||
|
||||
if (this->sock < 0) {
|
||||
std::cerr << "Error creating socket" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the socket to non-blocking mode
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
u_long mode = 1; // 1 to enable non-blocking socket
|
||||
ioctlsocket(this->sock, FIONBIO, &mode);
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
int flags = fcntl(this->sock, F_GETFL, 0);
|
||||
fcntl(this->sock, F_SETFL, flags | O_NONBLOCK);
|
||||
#endif
|
||||
|
||||
if (remotePort != 0) {
|
||||
// Set up the address to send to
|
||||
memset(&remote_addr, 0, sizeof(remote_addr));
|
||||
remote_addr.sin_family = AF_INET;
|
||||
remote_addr.sin_port = htons((u_short)remotePort);
|
||||
if (inet_pton(AF_INET, remoteIpAddress, &remote_addr.sin_addr) <= 0) {
|
||||
std::cerr << "Invalid address" << std::endl;
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
closesocket(sock);
|
||||
WSACleanup();
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
close(sock);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Set up the receiving address
|
||||
memset(&server_addr, 0, sizeof(server_addr));
|
||||
server_addr.sin_family = AF_INET;
|
||||
server_addr.sin_port = htons((u_short)localPort);
|
||||
if (inet_pton(AF_INET, "0.0.0.0", &server_addr.sin_addr) <= 0) {
|
||||
std::cerr << "Invalid address" << std::endl;
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
closesocket(sock);
|
||||
WSACleanup();
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
close(sock);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
// Bind the socket to the specified port
|
||||
if (bind(this->sock, (const struct sockaddr *)&server_addr,
|
||||
sizeof(server_addr)) < 0) {
|
||||
std::cerr << "Bind failed" << std::endl;
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
closesocket(sock);
|
||||
WSACleanup();
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
close(sock);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
// Bind the socket to the specified port
|
||||
// if (bind(this->sock, (const struct sockaddr *)&server_addr,
|
||||
// sizeof(server_addr)) < 0) {
|
||||
// std::cerr << "Bind failed" << std::endl;
|
||||
// #if defined(_WIN32) || defined(_WIN64)
|
||||
// closesocket(sock);
|
||||
// WSACleanup();
|
||||
// #elif defined(__unix__) || defined(__APPLE__)
|
||||
// close(sock);
|
||||
// #endif
|
||||
// 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)remotePort);
|
||||
if (inet_pton(AF_INET, "255.255.255.255", &broadcast_addr.sin_addr) <= 0) {
|
||||
std::cerr << "Invalid address" << std::endl;
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
closesocket(sock);
|
||||
WSACleanup();
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
close(sock);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
BOOL broadcast = TRUE;
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&broadcast,
|
||||
sizeof(broadcast)) == SOCKET_ERROR) {
|
||||
std::cerr << "Setting socket option for broadcast failed" << std::endl;
|
||||
}
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
int broadcastEnable = 1;
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &broadcastEnable, sizeof(broadcastEnable)) < 0) {
|
||||
std::cerr << "Failed to set socket options" << std::endl;
|
||||
}
|
||||
UdpWindows *thisWindows = static_cast<UdpWindows *>(this);
|
||||
thisWindows->Setup(localPort, remoteIpAddress, remotePort);
|
||||
#elif defined(ARDUINO)
|
||||
UdpArduino *thisArduino = static_cast<UdpArduino *>(this);
|
||||
thisArduino->Setup(localPort, remoteIpAddress, remotePort);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Participant::Update(unsigned long currentTimeMs) {
|
||||
if (currentTimeMs > this->nextPublishMe) {
|
||||
ClientMsg* msg = new ClientMsg(this->networkId);
|
||||
if (this->publishInterval > 0 && currentTimeMs > this->nextPublishMe) {
|
||||
ClientMsg *msg = new ClientMsg(this->networkId);
|
||||
this->Publish(msg);
|
||||
delete msg;
|
||||
std::cout << this->name << " published ClientMsg\n";
|
||||
@ -161,47 +66,13 @@ void Participant::Update(unsigned long currentTimeMs) {
|
||||
}
|
||||
|
||||
void Participant::ReceiveUDP() {
|
||||
// char ip_str[INET_ADDRSTRLEN];
|
||||
// inet_ntop(AF_INET, &(server_addr.sin_addr), ip_str, INET_ADDRSTRLEN);
|
||||
// std::cout << this->name << " Receive on " << ip_str << ":"
|
||||
// << ntohs(server_addr.sin_port) << "\n";
|
||||
|
||||
sockaddr_in client_addr;
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
int len = sizeof(client_addr);
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
socklen_t len = sizeof(client_addr);
|
||||
UdpWindows *thisWindows = static_cast<UdpWindows *>(this);
|
||||
thisWindows->Receive();
|
||||
#elif defined(ARDUINO)
|
||||
UdpArduino *thisArduino = static_cast<UdpArduino *>(this);
|
||||
thisArduino->Receive();
|
||||
#endif
|
||||
int packetSize = recvfrom(this->sock, buffer, sizeof(buffer), 0,
|
||||
(struct sockaddr *)&client_addr, &len);
|
||||
// std::cout << "received data " << packetSize << "\n";
|
||||
if (packetSize < 0) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
int error_code = WSAGetLastError(); // Get the error code on Windows
|
||||
if (error_code != WSAEWOULDBLOCK)
|
||||
std::cerr << "recvfrom failed with error: " << error_code << std::endl;
|
||||
#else
|
||||
//std::cerr << "recvfrom failed with error: " << packetSize << std::endl;
|
||||
#endif
|
||||
} else if (packetSize > 0) {
|
||||
char sender_ipAddress[INET_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET, &(client_addr.sin_addr), sender_ipAddress,
|
||||
INET_ADDRSTRLEN);
|
||||
int sender_port = ntohs(client_addr.sin_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 << "\n";
|
||||
// std::cout << "New remote participant " << remoteParticipant->ipAddress << ":"
|
||||
// << remoteParticipant->port << " "
|
||||
// << (int)remoteParticipant->networkId << "\n";
|
||||
}
|
||||
|
||||
ReceiveData(packetSize, remoteParticipant);
|
||||
}
|
||||
}
|
||||
|
||||
Participant *Participant::GetParticipant(const char *ipAddress, int port) {
|
||||
@ -232,68 +103,41 @@ void Participant::SendThingInfo(Thing *thing) {
|
||||
msg = new ModelUrlMsg(this->networkId, thing);
|
||||
this->Send(msg);
|
||||
delete msg;
|
||||
// this->Send(&ModelUrlMsg(this->networkId, thing));
|
||||
}
|
||||
|
||||
void Passer::Control::Participant::PublishThingInfo(Thing *thing) {
|
||||
std::cout << "Publish thing info\n";
|
||||
// Strange, when publishing, the network id is irrelevant, because it is
|
||||
// connected to a specific site...
|
||||
ThingMsg *thingMsg = new ThingMsg(this->networkId, thing);
|
||||
this->Publish(thingMsg);
|
||||
delete thingMsg;
|
||||
NameMsg *nameMsg = new NameMsg(this->networkId, thing);
|
||||
this->Publish(nameMsg);
|
||||
delete nameMsg;
|
||||
ModelUrlMsg *modelMsg = new ModelUrlMsg(this->networkId, thing);
|
||||
this->Publish(modelMsg);
|
||||
delete modelMsg;
|
||||
}
|
||||
|
||||
bool Participant::Send(IMessage *msg) {
|
||||
// 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, &(remote_addr.sin_addr), ip_str, INET_ADDRSTRLEN);
|
||||
std::cout << "Send to " << ip_str << ":" << ntohs(remote_addr.sin_port)
|
||||
<< "\n";
|
||||
int sent_bytes = sendto(sock, this->buffer, bufferSize, 0,
|
||||
(struct sockaddr *)&remote_addr, sizeof(remote_addr));
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
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;
|
||||
}
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
if (sent_bytes < 0) {
|
||||
std::cerr << "sendto failed with error: " << sent_bytes << std::endl;
|
||||
close(sock);
|
||||
return false;
|
||||
}
|
||||
UdpWindows *thisWindows = static_cast<UdpWindows *>(this);
|
||||
return thisWindows->Send(msg);
|
||||
#elif defined(ARDUINO)
|
||||
UdpArduino *thisArduino = static_cast<UdpArduino *>(this);
|
||||
return thisArduino->Send(msg);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Participant::Publish(IMessage *msg) {
|
||||
int bufferSize = msg->Serialize(this->buffer);
|
||||
if (bufferSize <= 0)
|
||||
return true;
|
||||
|
||||
char ip_str[INET_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET, &(broadcast_addr.sin_addr), ip_str, INET_ADDRSTRLEN);
|
||||
std::cout << "Publish to " << ip_str << ":" << ntohs(broadcast_addr.sin_port)
|
||||
<< "\n";
|
||||
int sent_bytes =
|
||||
sendto(sock, this->buffer, bufferSize, 0,
|
||||
(struct sockaddr *)&broadcast_addr, sizeof(broadcast_addr));
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
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;
|
||||
}
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
if (sent_bytes < 0) {
|
||||
std::cerr << "sendto failed with error: " << sent_bytes << std::endl;
|
||||
close(sock);
|
||||
return false;
|
||||
}
|
||||
UdpWindows *thisWindows = static_cast<UdpWindows *>(this);
|
||||
return thisWindows->Publish(msg);
|
||||
#elif defined(ARDUINO)
|
||||
UdpArduino *thisArduino = static_cast<UdpArduino *>(this);
|
||||
return thisArduino->Publish(msg);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
// Send
|
||||
@ -306,12 +150,12 @@ void Participant::ReceiveData(unsigned char bufferSize,
|
||||
unsigned char msgId = this->buffer[0];
|
||||
switch (msgId) {
|
||||
case ClientMsg::id: {
|
||||
ClientMsg* msg = new ClientMsg(this->buffer);
|
||||
ClientMsg *msg = new ClientMsg(this->buffer);
|
||||
Process(remoteParticipant, msg);
|
||||
delete msg;
|
||||
}
|
||||
case NetworkIdMsg::id: {
|
||||
NetworkIdMsg* msg = new NetworkIdMsg(this->buffer);
|
||||
NetworkIdMsg *msg = new NetworkIdMsg(this->buffer);
|
||||
Process(remoteParticipant, msg);
|
||||
delete msg;
|
||||
} break;
|
||||
@ -349,7 +193,7 @@ void Participant::Process(Participant *sender, NetworkIdMsg *msg) {
|
||||
|
||||
// sender->SendThingInfo(thing);
|
||||
// }
|
||||
for (Thing* thing : allThings) {
|
||||
for (Thing *thing : allThings) {
|
||||
sender->SendThingInfo(thing);
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,8 @@
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#elif defined(ARDUINO)
|
||||
#include <WiFiUdp.h>
|
||||
#endif
|
||||
|
||||
namespace Passer {
|
||||
@ -33,21 +35,36 @@ public:
|
||||
const char *ipAddress = "0.0.0.0";
|
||||
int port = 0;
|
||||
|
||||
#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
|
||||
#endif
|
||||
sockaddr_in remote_addr;
|
||||
sockaddr_in server_addr;
|
||||
sockaddr_in broadcast_addr;
|
||||
|
||||
#endif
|
||||
|
||||
Participant();
|
||||
Participant(int port);
|
||||
Participant(const char *ipAddress, int port);
|
||||
// Bad design, you cannot use constructor in global scope
|
||||
// i.e.
|
||||
// Participant p = Participant("127.0.0.1", 8000);
|
||||
|
||||
virtual void Update(unsigned long currentTimeMs);
|
||||
|
||||
void SendThingInfo(Thing *thing);
|
||||
void PublishThingInfo(Thing *thing);
|
||||
|
||||
bool Send(IMessage *msg);
|
||||
bool Publish(IMessage *msg);
|
||||
|
17
Thing.cpp
17
Thing.cpp
@ -1,7 +1,9 @@
|
||||
#include "Thing.h"
|
||||
|
||||
#include "Participant.h"
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <string.h>
|
||||
|
||||
Thing::Thing(unsigned char networkId, unsigned char thingType) {
|
||||
@ -165,9 +167,11 @@ Thing *Thing::Get(unsigned char networkId, unsigned char thingId) {
|
||||
// return thing;
|
||||
// }
|
||||
// return nullptr;
|
||||
std::find_if(allThings.begin(), allThings.end(), [networkId, thingId](Thing* thing){
|
||||
return thing->networkId == networkId && thing->id == thingId;
|
||||
});
|
||||
std::find_if(allThings.begin(), allThings.end(),
|
||||
[networkId, thingId](Thing *thing) {
|
||||
return thing->networkId == networkId && thing->id == thingId;
|
||||
});
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int Thing::Add(Thing *newThing) {
|
||||
@ -181,17 +185,18 @@ int Thing::Add(Thing *newThing) {
|
||||
// return ix;
|
||||
// }
|
||||
// }
|
||||
for (Thing* thing : allThings) {
|
||||
for (Thing *thing : allThings) {
|
||||
if (thing == newThing)
|
||||
return thing->id;
|
||||
}
|
||||
allThings.push_back(newThing);
|
||||
return allThings.size() - 1;
|
||||
}
|
||||
|
||||
void Thing::Remove(Thing *thing) {
|
||||
// std::cout << " remove " << (int)thing->id << "\n";
|
||||
// allThings[thing->id] = nullptr;
|
||||
allThings.remove_if([thing](Thing* obj) { return obj == thing; });
|
||||
allThings.remove_if([thing](Thing *obj) { return obj == thing; });
|
||||
}
|
||||
|
||||
void Thing::UpdateAll(unsigned long currentTimeMs) {
|
||||
@ -205,7 +210,7 @@ void Thing::UpdateAll(unsigned long currentTimeMs) {
|
||||
// thing->Update(currentTimeMs);
|
||||
// }
|
||||
// }
|
||||
for (Thing* thing : allThings) {
|
||||
for (Thing *thing : allThings) {
|
||||
if (thing != nullptr &&
|
||||
thing->parent == nullptr) { // update all root things
|
||||
// std::cout << " update " << (int)ix << " thingid " << (int)thing->id
|
||||
|
91
UdpArduino.cpp
Normal file
91
UdpArduino.cpp
Normal file
@ -0,0 +1,91 @@
|
||||
#include "UdpArduino.h"
|
||||
|
||||
#if defined(ARDUINO)
|
||||
#include <ESP8266WiFi.h>
|
||||
#endif
|
||||
namespace Passer {
|
||||
namespace Control {
|
||||
|
||||
void UdpArduino::Setup(int localPort, const char *remoteIpAddress,
|
||||
int remotePort) {
|
||||
#if ARDUINO
|
||||
this->remoteIpAddress = remoteIpAddress;
|
||||
this->remotePort = remotePort;
|
||||
GetBroadcastAddress();
|
||||
|
||||
if (WiFi.isConnected() == false) {
|
||||
std::cout << "No network available!\n";
|
||||
return;
|
||||
}
|
||||
udp.begin(this->remotePort);
|
||||
|
||||
std::cout << "Wifi sync started to port " << this->remotePort << "\n";
|
||||
#endif
|
||||
}
|
||||
|
||||
void UdpArduino::GetBroadcastAddress() {
|
||||
IPAddress broadcastAddress = WiFi.localIP();
|
||||
broadcastAddress[3] = 255;
|
||||
String broadcastIpString = broadcastAddress.toString();
|
||||
this->broadcastIpAddress = new char[broadcastIpString.length() + 1];
|
||||
broadcastIpString.toCharArray(this->broadcastIpAddress,
|
||||
broadcastIpString.length() + 1);
|
||||
std::cout << "Broadcast address: " << broadcastIpAddress << "\n";
|
||||
}
|
||||
|
||||
void UdpArduino::Receive() {
|
||||
int packetSize = udp.parsePacket();
|
||||
while (packetSize > 0) {
|
||||
udp.read(buffer, packetSize);
|
||||
|
||||
String senderAddress = udp.remoteIP().toString();
|
||||
char sender_ipAddress[16];
|
||||
senderAddress.toCharArray(sender_ipAddress, 16);
|
||||
int sender_port = udp.remotePort();
|
||||
|
||||
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
|
||||
<< "\n";
|
||||
std::cout << "New remote participant " << remoteParticipant->ipAddress
|
||||
<< ":" << remoteParticipant->port << " "
|
||||
<< (int)remoteParticipant->networkId << "\n";
|
||||
}
|
||||
|
||||
ReceiveData(packetSize, remoteParticipant);
|
||||
packetSize = udp.parsePacket();
|
||||
}
|
||||
}
|
||||
|
||||
bool UdpArduino::Send(IMessage *msg) {
|
||||
int bufferSize = msg->Serialize(this->buffer);
|
||||
if (bufferSize <= 0)
|
||||
return true;
|
||||
|
||||
udp.beginPacket(this->remoteIpAddress, this->remotePort);
|
||||
udp.write(buffer, bufferSize);
|
||||
udp.endPacket();
|
||||
|
||||
// std::cout << "Sent to " << this->remoteIpAddress << ":"
|
||||
// << this->remotePort << "\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UdpArduino::Publish(IMessage *msg) {
|
||||
int bufferSize = msg->Serialize(this->buffer);
|
||||
if (bufferSize <= 0)
|
||||
return true;
|
||||
|
||||
udp.beginPacket(this->broadcastIpAddress, this->remotePort);
|
||||
udp.write(buffer, bufferSize);
|
||||
udp.endPacket();
|
||||
|
||||
// std::cout << "Publish to " << this->broadcastIpAddress << ":"
|
||||
// << this->remotePort << "\n";
|
||||
return true;
|
||||
};
|
||||
|
||||
} // namespace Control
|
||||
} // namespace Passer
|
20
UdpArduino.h
Normal file
20
UdpArduino.h
Normal file
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include "Participant.h"
|
||||
|
||||
namespace Passer {
|
||||
namespace Control {
|
||||
|
||||
class UdpArduino : public Participant {
|
||||
public:
|
||||
void Setup(int localPort, const char *remoteIpAddress, int remotePort);
|
||||
void Receive();
|
||||
bool Send(IMessage *msg);
|
||||
bool Publish(IMessage *msg);
|
||||
|
||||
protected:
|
||||
void GetBroadcastAddress();
|
||||
};
|
||||
|
||||
} // namespace Control
|
||||
} // namespace Passer
|
201
UdpWindows.cpp
Normal file
201
UdpWindows.cpp
Normal file
@ -0,0 +1,201 @@
|
||||
#include "UdpWindows.h"
|
||||
|
||||
namespace Passer {
|
||||
namespace Control {
|
||||
|
||||
void UdpWindows::Setup(int localPort, const char *remoteIpAddress,
|
||||
int remotePort) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
|
||||
// Create a UDP socket
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
// Windows-specific Winsock initialization
|
||||
WSADATA wsaData;
|
||||
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
|
||||
std::cerr << "WSAStartup failed" << std::endl;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
this->sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
this->sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
#endif
|
||||
|
||||
if (this->sock < 0) {
|
||||
std::cerr << "Error creating socket" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the socket to non-blocking mode
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
u_long mode = 1; // 1 to enable non-blocking socket
|
||||
ioctlsocket(this->sock, FIONBIO, &mode);
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
int flags = fcntl(this->sock, F_GETFL, 0);
|
||||
fcntl(this->sock, F_SETFL, flags | O_NONBLOCK);
|
||||
#endif
|
||||
|
||||
if (remotePort != 0) {
|
||||
// Set up the address to send to
|
||||
memset(&remote_addr, 0, sizeof(remote_addr));
|
||||
remote_addr.sin_family = AF_INET;
|
||||
remote_addr.sin_port = htons((u_short)remotePort);
|
||||
if (inet_pton(AF_INET, remoteIpAddress, &remote_addr.sin_addr) <= 0) {
|
||||
std::cerr << "Invalid address" << std::endl;
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
closesocket(sock);
|
||||
WSACleanup();
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
close(sock);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Set up the receiving address
|
||||
memset(&server_addr, 0, sizeof(server_addr));
|
||||
server_addr.sin_family = AF_INET;
|
||||
server_addr.sin_port = htons((u_short)localPort);
|
||||
if (inet_pton(AF_INET, "0.0.0.0", &server_addr.sin_addr) <= 0) {
|
||||
std::cerr << "Invalid address" << std::endl;
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
closesocket(sock);
|
||||
WSACleanup();
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
close(sock);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
// Bind the socket to the specified port
|
||||
if (bind(this->sock, (const struct sockaddr *)&server_addr,
|
||||
sizeof(server_addr)) < 0) {
|
||||
std::cerr << "Bind failed" << std::endl;
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
closesocket(sock);
|
||||
WSACleanup();
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
close(sock);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void UdpWindows::Receive() {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
// char ip_str[INET_ADDRSTRLEN];
|
||||
// inet_ntop(AF_INET, &(server_addr.sin_addr), ip_str, INET_ADDRSTRLEN);
|
||||
// std::cout << this->name << " Receive on " << ip_str << ":"
|
||||
// << ntohs(server_addr.sin_port) << "\n";
|
||||
|
||||
sockaddr_in client_addr;
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
int len = sizeof(client_addr);
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
socklen_t len = sizeof(client_addr);
|
||||
#endif
|
||||
int packetSize = recvfrom(this->sock, buffer, sizeof(buffer), 0,
|
||||
(struct sockaddr *)&client_addr, &len);
|
||||
// std::cout << "received data " << packetSize << "\n";
|
||||
if (packetSize < 0) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
int error_code = WSAGetLastError(); // Get the error code on Windows
|
||||
if (error_code != WSAEWOULDBLOCK)
|
||||
std::cerr << "recvfrom failed with error: " << error_code << std::endl;
|
||||
#else
|
||||
// std::cerr << "recvfrom failed with error: " << packetSize << std::endl;
|
||||
#endif
|
||||
} else if (packetSize > 0) {
|
||||
char sender_ipAddress[INET_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET, &(client_addr.sin_addr), sender_ipAddress,
|
||||
INET_ADDRSTRLEN);
|
||||
int sender_port = ntohs(client_addr.sin_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 << "\n";
|
||||
// std::cout << "New remote participant " <<
|
||||
// remoteParticipant->ipAddress
|
||||
// << ":"
|
||||
// << remoteParticipant->port << " "
|
||||
// << (int)remoteParticipant->networkId << "\n";
|
||||
}
|
||||
|
||||
ReceiveData(packetSize, remoteParticipant);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool UdpWindows::Send(
|
||||
IMessage *msg) { // Send the message to the specified address and port
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
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, &(remote_addr.sin_addr), ip_str, INET_ADDRSTRLEN);
|
||||
std::cout << "Send to " << ip_str << ":" << ntohs(remote_addr.sin_port)
|
||||
<< "\n";
|
||||
int sent_bytes = sendto(sock, this->buffer, bufferSize, 0,
|
||||
(struct sockaddr *)&remote_addr, sizeof(remote_addr));
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
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;
|
||||
}
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
if (sent_bytes < 0) {
|
||||
std::cerr << "sendto failed with error: " << sent_bytes << std::endl;
|
||||
close(sock);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UdpWindows::Publish(IMessage *msg) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
int bufferSize = msg->Serialize(this->buffer);
|
||||
if (bufferSize <= 0)
|
||||
return true;
|
||||
|
||||
char ip_str[INET_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET, &(broadcast_addr.sin_addr), ip_str, INET_ADDRSTRLEN);
|
||||
std::cout << "Publish to " << ip_str << ":" << ntohs(broadcast_addr.sin_port)
|
||||
<< "\n";
|
||||
int sent_bytes =
|
||||
sendto(sock, this->buffer, bufferSize, 0,
|
||||
(struct sockaddr *)&broadcast_addr, sizeof(broadcast_addr));
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
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;
|
||||
}
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
if (sent_bytes < 0) {
|
||||
std::cerr << "sendto failed with error: " << sent_bytes << std::endl;
|
||||
close(sock);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Control
|
||||
} // namespace Passer
|
17
UdpWindows.h
Normal file
17
UdpWindows.h
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "Participant.h"
|
||||
|
||||
namespace Passer {
|
||||
namespace Control {
|
||||
|
||||
class UdpWindows : public Participant {
|
||||
public:
|
||||
void Setup(int localPort, const char *remoteIpAddress, int remotePort);
|
||||
void Receive();
|
||||
bool Send(IMessage *msg);
|
||||
bool Publish(IMessage *msg);
|
||||
};
|
||||
|
||||
} // namespace Control
|
||||
} // namespace Passer
|
Loading…
x
Reference in New Issue
Block a user