Restored (all?) changes
This commit is contained in:
		
							parent
							
								
									a8afeeb141
								
							
						
					
					
						commit
						8338e2f5cd
					
				@ -1,5 +1,7 @@
 | 
				
			|||||||
#include "ModelUrlMsg.h"
 | 
					#include "ModelUrlMsg.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Passer {
 | 
					namespace Passer {
 | 
				
			||||||
namespace Control {
 | 
					namespace Control {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -25,7 +27,11 @@ ModelUrlMsg::ModelUrlMsg(const char *buffer) {
 | 
				
			|||||||
ModelUrlMsg::ModelUrlMsg(unsigned char networkId, Thing *thing) {
 | 
					ModelUrlMsg::ModelUrlMsg(unsigned char networkId, Thing *thing) {
 | 
				
			||||||
  this->networkId = networkId;
 | 
					  this->networkId = networkId;
 | 
				
			||||||
  this->thingId = thing->id;
 | 
					  this->thingId = thing->id;
 | 
				
			||||||
 | 
					  if (thing->modelUrl == nullptr)
 | 
				
			||||||
 | 
					    this->urlLength = 0;
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
    this->urlLength = strlen(thing->modelUrl);
 | 
					    this->urlLength = strlen(thing->modelUrl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  this->url = thing->modelUrl; // dangerous!
 | 
					  this->url = thing->modelUrl; // dangerous!
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,7 @@
 | 
				
			|||||||
#include "NameMsg.h"
 | 
					#include "NameMsg.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Passer {
 | 
					namespace Passer {
 | 
				
			||||||
namespace Control {
 | 
					namespace Control {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -15,6 +17,9 @@ NameMsg::NameMsg(const char *buffer) {
 | 
				
			|||||||
NameMsg::NameMsg(unsigned char networkId, Thing *thing) {
 | 
					NameMsg::NameMsg(unsigned char networkId, Thing *thing) {
 | 
				
			||||||
  this->networkId = networkId;
 | 
					  this->networkId = networkId;
 | 
				
			||||||
  this->thingId = thing->id;
 | 
					  this->thingId = thing->id;
 | 
				
			||||||
 | 
					  if (thing->name == nullptr)
 | 
				
			||||||
 | 
					    this->nameLength = 0;
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
    this->nameLength = strlen(thing->name);
 | 
					    this->nameLength = strlen(thing->name);
 | 
				
			||||||
  this->name = thing->name; // dangerous!
 | 
					  this->name = thing->name; // dangerous!
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										254
									
								
								Participant.cpp
									
									
									
									
									
								
							
							
						
						
									
										254
									
								
								Participant.cpp
									
									
									
									
									
								
							@ -4,20 +4,32 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#define BUF_SIZE 1024
 | 
					#define BUF_SIZE 1024
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "UdpArduino.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(_WIN32) || defined(_WIN64)
 | 
					#if defined(_WIN32) || defined(_WIN64)
 | 
				
			||||||
#include <winsock2.h>
 | 
					#include <winsock2.h>
 | 
				
			||||||
#include <ws2tcpip.h>
 | 
					#include <ws2tcpip.h>
 | 
				
			||||||
#pragma comment(lib, "ws2_32.lib")
 | 
					#pragma comment(lib, "ws2_32.lib")
 | 
				
			||||||
#elif defined(__unix__) || defined(__APPLE__)
 | 
					#elif defined(__unix__) || defined(__APPLE__)
 | 
				
			||||||
#include <arpa/inet.h>
 | 
					#include <arpa/inet.h>
 | 
				
			||||||
 | 
					#include <fcntl.h> // For fcntl
 | 
				
			||||||
#include <netinet/in.h>
 | 
					#include <netinet/in.h>
 | 
				
			||||||
#include <sys/socket.h>
 | 
					#include <sys/socket.h>
 | 
				
			||||||
#include <unistd.h>
 | 
					#include <unistd.h>
 | 
				
			||||||
#include <fcntl.h> // For fcntl
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Participant::Participant() {}
 | 
					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) {
 | 
					Participant::Participant(const char *ipAddress, int port) {
 | 
				
			||||||
  this->ipAddress = ipAddress;
 | 
					  this->ipAddress = ipAddress;
 | 
				
			||||||
  this->port = port;
 | 
					  this->port = port;
 | 
				
			||||||
@ -31,124 +43,17 @@ Participant::Participant(const char *ipAddress, int port) {
 | 
				
			|||||||
void Passer::Control::Participant::SetupUDP(int localPort,
 | 
					void Passer::Control::Participant::SetupUDP(int localPort,
 | 
				
			||||||
                                            const char *remoteIpAddress,
 | 
					                                            const char *remoteIpAddress,
 | 
				
			||||||
                                            int remotePort) {
 | 
					                                            int remotePort) {
 | 
				
			||||||
  // Create a UDP socket
 | 
					 | 
				
			||||||
#if defined(_WIN32) || defined(_WIN64)
 | 
					#if defined(_WIN32) || defined(_WIN64)
 | 
				
			||||||
  // Windows-specific Winsock initialization
 | 
					  UdpWindows *thisWindows = static_cast<UdpWindows *>(this);
 | 
				
			||||||
  WSADATA wsaData;
 | 
					  thisWindows->Setup(localPort, remoteIpAddress, remotePort);
 | 
				
			||||||
  if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
 | 
					#elif defined(ARDUINO)
 | 
				
			||||||
    std::cerr << "WSAStartup failed" << std::endl;
 | 
					  UdpArduino *thisArduino = static_cast<UdpArduino *>(this);
 | 
				
			||||||
    return;
 | 
					  thisArduino->Setup(localPort, remoteIpAddress, remotePort);
 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
#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;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Participant::Update(unsigned long currentTimeMs) {
 | 
					void Participant::Update(unsigned long currentTimeMs) {
 | 
				
			||||||
  if (currentTimeMs > this->nextPublishMe) {
 | 
					  if (this->publishInterval > 0 && currentTimeMs > this->nextPublishMe) {
 | 
				
			||||||
    ClientMsg *msg = new ClientMsg(this->networkId);
 | 
					    ClientMsg *msg = new ClientMsg(this->networkId);
 | 
				
			||||||
    this->Publish(msg);
 | 
					    this->Publish(msg);
 | 
				
			||||||
    delete msg;
 | 
					    delete msg;
 | 
				
			||||||
@ -161,47 +66,13 @@ void Participant::Update(unsigned long currentTimeMs) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Participant::ReceiveUDP() {
 | 
					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)
 | 
					#if defined(_WIN32) || defined(_WIN64)
 | 
				
			||||||
  int len = sizeof(client_addr);
 | 
					  UdpWindows *thisWindows = static_cast<UdpWindows *>(this);
 | 
				
			||||||
#elif defined(__unix__) || defined(__APPLE__)
 | 
					  thisWindows->Receive();
 | 
				
			||||||
  socklen_t len = sizeof(client_addr);
 | 
					#elif defined(ARDUINO)
 | 
				
			||||||
 | 
					  UdpArduino *thisArduino = static_cast<UdpArduino *>(this);
 | 
				
			||||||
 | 
					  thisArduino->Receive();
 | 
				
			||||||
#endif
 | 
					#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) {
 | 
					Participant *Participant::GetParticipant(const char *ipAddress, int port) {
 | 
				
			||||||
@ -232,68 +103,41 @@ void Participant::SendThingInfo(Thing *thing) {
 | 
				
			|||||||
  msg = new ModelUrlMsg(this->networkId, thing);
 | 
					  msg = new ModelUrlMsg(this->networkId, thing);
 | 
				
			||||||
  this->Send(msg);
 | 
					  this->Send(msg);
 | 
				
			||||||
  delete 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) {
 | 
					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 defined(_WIN32) || defined(_WIN64)
 | 
				
			||||||
  if (sent_bytes <= SOCKET_ERROR) {
 | 
					  UdpWindows *thisWindows = static_cast<UdpWindows *>(this);
 | 
				
			||||||
    int error_code = WSAGetLastError(); // Get the error code on Windows
 | 
					  return thisWindows->Send(msg);
 | 
				
			||||||
    std::cerr << "sendto failed with error: " << error_code << std::endl;
 | 
					#elif defined(ARDUINO)
 | 
				
			||||||
    closesocket(sock);
 | 
					  UdpArduino *thisArduino = static_cast<UdpArduino *>(this);
 | 
				
			||||||
    WSACleanup();
 | 
					  return thisArduino->Send(msg);
 | 
				
			||||||
    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 Participant::Publish(IMessage *msg) {
 | 
					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 defined(_WIN32) || defined(_WIN64)
 | 
				
			||||||
  if (sent_bytes <= SOCKET_ERROR) {
 | 
					  UdpWindows *thisWindows = static_cast<UdpWindows *>(this);
 | 
				
			||||||
    int error_code = WSAGetLastError(); // Get the error code on Windows
 | 
					  return thisWindows->Publish(msg);
 | 
				
			||||||
    std::cerr << "sendto failed with error: " << error_code << std::endl;
 | 
					#elif defined(ARDUINO)
 | 
				
			||||||
    closesocket(sock);
 | 
					  UdpArduino *thisArduino = static_cast<UdpArduino *>(this);
 | 
				
			||||||
    WSACleanup();
 | 
					  return thisArduino->Publish(msg);
 | 
				
			||||||
    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;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Send
 | 
					// Send
 | 
				
			||||||
 | 
				
			|||||||
@ -16,6 +16,8 @@
 | 
				
			|||||||
#include <netinet/in.h>
 | 
					#include <netinet/in.h>
 | 
				
			||||||
#include <sys/socket.h>
 | 
					#include <sys/socket.h>
 | 
				
			||||||
#include <unistd.h>
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					#elif defined(ARDUINO)
 | 
				
			||||||
 | 
					#include <WiFiUdp.h>
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Passer {
 | 
					namespace Passer {
 | 
				
			||||||
@ -33,6 +35,14 @@ public:
 | 
				
			|||||||
  const char *ipAddress = "0.0.0.0";
 | 
					  const char *ipAddress = "0.0.0.0";
 | 
				
			||||||
  int port = 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)
 | 
					#if defined(_WIN32) || defined(_WIN64)
 | 
				
			||||||
  SOCKET sock;
 | 
					  SOCKET sock;
 | 
				
			||||||
#elif defined(__unix__) || defined(__APPLE__)
 | 
					#elif defined(__unix__) || defined(__APPLE__)
 | 
				
			||||||
@ -42,12 +52,19 @@ public:
 | 
				
			|||||||
  sockaddr_in server_addr;
 | 
					  sockaddr_in server_addr;
 | 
				
			||||||
  sockaddr_in broadcast_addr;
 | 
					  sockaddr_in broadcast_addr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Participant();
 | 
					  Participant();
 | 
				
			||||||
 | 
					  Participant(int port);
 | 
				
			||||||
  Participant(const char *ipAddress, 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);
 | 
					  virtual void Update(unsigned long currentTimeMs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void SendThingInfo(Thing *thing);
 | 
					  void SendThingInfo(Thing *thing);
 | 
				
			||||||
 | 
					  void PublishThingInfo(Thing *thing);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool Send(IMessage *msg);
 | 
					  bool Send(IMessage *msg);
 | 
				
			||||||
  bool Publish(IMessage *msg);
 | 
					  bool Publish(IMessage *msg);
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,9 @@
 | 
				
			|||||||
#include "Thing.h"
 | 
					#include "Thing.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Participant.h"
 | 
					#include "Participant.h"
 | 
				
			||||||
 | 
					#include <algorithm>
 | 
				
			||||||
#include <iostream>
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					#include <list>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Thing::Thing(unsigned char networkId, unsigned char thingType) {
 | 
					Thing::Thing(unsigned char networkId, unsigned char thingType) {
 | 
				
			||||||
@ -165,9 +167,11 @@ Thing *Thing::Get(unsigned char networkId, unsigned char thingId) {
 | 
				
			|||||||
  //     return thing;
 | 
					  //     return thing;
 | 
				
			||||||
  // }
 | 
					  // }
 | 
				
			||||||
  // return nullptr;
 | 
					  // return nullptr;
 | 
				
			||||||
  std::find_if(allThings.begin(), allThings.end(), [networkId, thingId](Thing* thing){
 | 
					  std::find_if(allThings.begin(), allThings.end(),
 | 
				
			||||||
 | 
					               [networkId, thingId](Thing *thing) {
 | 
				
			||||||
                 return thing->networkId == networkId && thing->id == thingId;
 | 
					                 return thing->networkId == networkId && thing->id == thingId;
 | 
				
			||||||
               });
 | 
					               });
 | 
				
			||||||
 | 
					  return nullptr;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int Thing::Add(Thing *newThing) {
 | 
					int Thing::Add(Thing *newThing) {
 | 
				
			||||||
@ -186,6 +190,7 @@ int Thing::Add(Thing *newThing) {
 | 
				
			|||||||
      return thing->id;
 | 
					      return thing->id;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  allThings.push_back(newThing);
 | 
					  allThings.push_back(newThing);
 | 
				
			||||||
 | 
					  return allThings.size() - 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Thing::Remove(Thing *thing) {
 | 
					void Thing::Remove(Thing *thing) {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										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