Updated ConttrolCore
This commit is contained in:
		
							parent
							
								
									72c4657c74
								
							
						
					
					
						commit
						bec264b279
					
				@ -0,0 +1,99 @@
 | 
				
			|||||||
 | 
					#include "Participant.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(ARDUINO)
 | 
				
			||||||
 | 
					#if defined(ARDUINO_ARCH_ESP8266)
 | 
				
			||||||
 | 
					#include <ESP8266WiFi.h>
 | 
				
			||||||
 | 
					#elif defined(ESP32)
 | 
				
			||||||
 | 
					#include <WiFi.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Passer {
 | 
				
			||||||
 | 
					namespace RoboidControl {
 | 
				
			||||||
 | 
					namespace Arduino {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Participant::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->localPort);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::cout << "Wifi sync started to port " << this->remotePort << "\n";
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Participant::GetBroadcastAddress() {
 | 
				
			||||||
 | 
					#if ARDUINO
 | 
				
			||||||
 | 
					  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";
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Participant::Receive() {
 | 
				
			||||||
 | 
					#if ARDUINO
 | 
				
			||||||
 | 
					  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();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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
 | 
				
			||||||
 | 
					      //           << "\n";
 | 
				
			||||||
 | 
					      // std::cout << "New remote participant " << remoteParticipant->ipAddress
 | 
				
			||||||
 | 
					      //           << ":" << remoteParticipant->port << " "
 | 
				
			||||||
 | 
					      //           << (int)remoteParticipant->networkId << "\n";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ReceiveData(packetSize, remoteParticipant);
 | 
				
			||||||
 | 
					    packetSize = udp.parsePacket();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool Participant::Send(RemoteParticipant* remoteParticipant, int bufferSize) {
 | 
				
			||||||
 | 
					#if ARDUINO
 | 
				
			||||||
 | 
					  udp.beginPacket(remoteParticipant->ipAddress, remoteParticipant->port);
 | 
				
			||||||
 | 
					  udp.write(buffer, bufferSize);
 | 
				
			||||||
 | 
					  udp.endPacket();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //   std::cout << "Sent to " << this->remoteIpAddress << ":"
 | 
				
			||||||
 | 
					  //             << this->remotePort << "\n";
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					  return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool Participant::Publish(IMessage* msg) {
 | 
				
			||||||
 | 
					#ifdef ARDUINO
 | 
				
			||||||
 | 
					  int bufferSize = msg->Serialize((char*)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";
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					  return true;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace Arduino
 | 
				
			||||||
 | 
					}  // namespace RoboidControl
 | 
				
			||||||
 | 
					}  // namespace Passer
 | 
				
			||||||
@ -1,17 +1,19 @@
 | 
				
			|||||||
#include "Messages.h"
 | 
					#include "Messages.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "LowLevelMessages.h"
 | 
					#include "LowLevelMessages.h"
 | 
				
			||||||
// #include "Messages/BinaryMsg.h"
 | 
					 | 
				
			||||||
#include "Participant.h"
 | 
					#include "Participant.h"
 | 
				
			||||||
#include "string.h"
 | 
					#include "string.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Passer {
 | 
				
			||||||
 | 
					  namespace RoboidControl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#pragma region IMessage
 | 
					#pragma region IMessage
 | 
				
			||||||
 | 
					
 | 
				
			||||||
IMessage::IMessage() {}
 | 
					IMessage::IMessage() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// IMessage::IMessage(unsigned char *buffer) { Deserialize(buffer); }
 | 
					// IMessage::IMessage(unsigned char *buffer) { Deserialize(buffer); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
IMessage::IMessage(char* buffer) {}
 | 
					// IMessage::IMessage(char* buffer) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsigned char IMessage::Serialize(char* buffer) {
 | 
					unsigned char IMessage::Serialize(char* buffer) {
 | 
				
			||||||
  return 0;
 | 
					  return 0;
 | 
				
			||||||
@ -37,3 +39,5 @@ unsigned char IMessage::Serialize(char* buffer) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// IMessage
 | 
					// IMessage
 | 
				
			||||||
#pragma endregion
 | 
					#pragma endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  }}
 | 
				
			||||||
@ -6,7 +6,7 @@
 | 
				
			|||||||
#include "float16.h"
 | 
					#include "float16.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Passer {
 | 
					namespace Passer {
 | 
				
			||||||
namespace Control {
 | 
					namespace RoboidControl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Participant;
 | 
					class Participant;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -24,4 +24,4 @@ public:
 | 
				
			|||||||
} // namespace Control
 | 
					} // namespace Control
 | 
				
			||||||
} // namespace Passer
 | 
					} // namespace Passer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using namespace Passer::Control;
 | 
					using namespace Passer::RoboidControl;
 | 
				
			||||||
@ -165,7 +165,7 @@ bool Participant::Send(RemoteParticipant* remoteParticipant, IMessage* msg) {
 | 
				
			|||||||
  Windows::Participant* thisWindows = static_cast<Windows::Participant*>(this);
 | 
					  Windows::Participant* thisWindows = static_cast<Windows::Participant*>(this);
 | 
				
			||||||
  return thisWindows->Send(remoteParticipant, bufferSize);
 | 
					  return thisWindows->Send(remoteParticipant, bufferSize);
 | 
				
			||||||
#elif defined(__unix__) || defined(__APPLE__)
 | 
					#elif defined(__unix__) || defined(__APPLE__)
 | 
				
			||||||
  Posix::Participant* thisPosix = static_cast<Posix::Particiapant*>(this);
 | 
					  Posix::Participant* thisPosix = static_cast<Posix::Participant*>(this);
 | 
				
			||||||
  return thisPosix->Send(remoteParticipant, bufferSize);
 | 
					  return thisPosix->Send(remoteParticipant, bufferSize);
 | 
				
			||||||
#elif defined(ARDUINO)
 | 
					#elif defined(ARDUINO)
 | 
				
			||||||
  Arduino::Participant* thisArduino = static_cast<Arduino::Participant*>(this);
 | 
					  Arduino::Participant* thisArduino = static_cast<Arduino::Participant*>(this);
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,5 @@
 | 
				
			|||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//#include "Messages/"
 | 
					 | 
				
			||||||
#include "Messages/ParticipantMsg.h"
 | 
					#include "Messages/ParticipantMsg.h"
 | 
				
			||||||
#include "Messages/BinaryMsg.h"
 | 
					#include "Messages/BinaryMsg.h"
 | 
				
			||||||
#include "Messages/InvestigateMsg.h"
 | 
					#include "Messages/InvestigateMsg.h"
 | 
				
			||||||
@ -30,7 +29,7 @@ namespace RoboidControl {
 | 
				
			|||||||
/// @brief A participant is device which can communicate with other participants
 | 
					/// @brief A participant is device which can communicate with other participants
 | 
				
			||||||
class Participant : public RemoteParticipant {
 | 
					class Participant : public RemoteParticipant {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  unsigned char buffer[1024];
 | 
					  char buffer[1024];
 | 
				
			||||||
  long publishInterval = 3000; // 3 seconds
 | 
					  long publishInterval = 3000; // 3 seconds
 | 
				
			||||||
  // unsigned char networkId = 0;
 | 
					  // unsigned char networkId = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,138 @@
 | 
				
			|||||||
 | 
					#include "Participant.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(__unix__) || defined(__APPLE__)
 | 
				
			||||||
 | 
					#include <arpa/inet.h>
 | 
				
			||||||
 | 
					#include <fcntl.h>  // For fcntl
 | 
				
			||||||
 | 
					#include <netinet/in.h>
 | 
				
			||||||
 | 
					#include <sys/socket.h>
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Passer {
 | 
				
			||||||
 | 
					namespace RoboidControl {
 | 
				
			||||||
 | 
					namespace Posix {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Participant::Setup(int localPort, const char* remoteIpAddress, int remotePort) {
 | 
				
			||||||
 | 
					#if defined(__unix__) || defined(__APPLE__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Create a UDP socket
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  this->sock = socket(AF_INET, SOCK_DGRAM, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  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(remotePort);
 | 
				
			||||||
 | 
					    if (inet_pton(AF_INET, remoteIpAddress, &remote_addr.sin_addr) <= 0) {
 | 
				
			||||||
 | 
					      std::cerr << "Invalid address" << std::endl;
 | 
				
			||||||
 | 
					      close(sock);
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Set up the receiving address
 | 
				
			||||||
 | 
					  memset(&server_addr, 0, sizeof(server_addr));
 | 
				
			||||||
 | 
					  server_addr.sin_family = AF_INET;
 | 
				
			||||||
 | 
					  server_addr.sin_port = htons(localPort);
 | 
				
			||||||
 | 
					  if (inet_pton(AF_INET, "0.0.0.0", &server_addr.sin_addr) <= 0) {
 | 
				
			||||||
 | 
					    std::cerr << "Invalid address" << std::endl;
 | 
				
			||||||
 | 
					    close(sock);
 | 
				
			||||||
 | 
					    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;
 | 
				
			||||||
 | 
					    close(sock);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Participant::Receive() {
 | 
				
			||||||
 | 
					#if defined(__unix__) || defined(__APPLE__)
 | 
				
			||||||
 | 
					  sockaddr_in client_addr;
 | 
				
			||||||
 | 
					  socklen_t len = sizeof(client_addr);
 | 
				
			||||||
 | 
					  int packetSize = recvfrom(this->sock, buffer, sizeof(buffer), 0, (struct sockaddr*)&client_addr, &len);
 | 
				
			||||||
 | 
					  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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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
 | 
				
			||||||
 | 
					      //           << "\n";
 | 
				
			||||||
 | 
					      // std::cout << "New remote participant " << remoteParticipant->ipAddress
 | 
				
			||||||
 | 
					      //           << ":" << remoteParticipant->port << " "
 | 
				
			||||||
 | 
					      //           << (int)remoteParticipant->networkId << "\n";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ReceiveData(packetSize, remoteParticipant);
 | 
				
			||||||
 | 
					    // std::cout << "Received data\n";
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool Participant::Send(RemoteParticipant* remoteParticipant, int bufferSize) {
 | 
				
			||||||
 | 
					#if defined(__unix__) || defined(__APPLE__)
 | 
				
			||||||
 | 
					  // Set up the destination address
 | 
				
			||||||
 | 
					  // 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";
 | 
				
			||||||
 | 
					  struct sockaddr_in dest_addr;
 | 
				
			||||||
 | 
					  memset(&dest_addr, 0, sizeof(dest_addr));
 | 
				
			||||||
 | 
					  dest_addr.sin_family = AF_INET;
 | 
				
			||||||
 | 
					  dest_addr.sin_port = htons(remoteParticipant->port);
 | 
				
			||||||
 | 
					  dest_addr.sin_addr.s_addr = inet_addr(remoteParticipant->ipAddress);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Send the message
 | 
				
			||||||
 | 
					  int sent_bytes = sendto(sock, this->buffer, bufferSize, 0, (struct sockaddr*)&remote_addr, sizeof(remote_addr));
 | 
				
			||||||
 | 
					  if (sent_bytes < 0) {
 | 
				
			||||||
 | 
					    std::cerr << "sendto failed with error: " << sent_bytes << std::endl;
 | 
				
			||||||
 | 
					    close(sock);
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					  return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool Participant::Publish(IMessage* msg) {
 | 
				
			||||||
 | 
					#if defined(__unix__) || defined(__APPLE__)
 | 
				
			||||||
 | 
					  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 (sent_bytes < 0) {
 | 
				
			||||||
 | 
					    std::cerr << "sendto failed with error: " << sent_bytes << std::endl;
 | 
				
			||||||
 | 
					    close(sock);
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					  return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace Posix
 | 
				
			||||||
 | 
					}  // namespace RoboidControl
 | 
				
			||||||
 | 
					}  // namespace Passer
 | 
				
			||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
#include "RemoteParticipant.h"
 | 
					#include "RemoteParticipant.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Passer {
 | 
					namespace Passer {
 | 
				
			||||||
namespace Control {
 | 
					namespace RoboidControl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RemoteParticipant::RemoteParticipant() {}
 | 
					RemoteParticipant::RemoteParticipant() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -2,7 +2,7 @@
 | 
				
			|||||||
#include "Thing.h"
 | 
					#include "Thing.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Passer {
 | 
					namespace Passer {
 | 
				
			||||||
namespace Control {
 | 
					namespace RoboidControl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class RemoteParticipant {
 | 
					class RemoteParticipant {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,199 @@
 | 
				
			|||||||
 | 
					#include "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>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Passer {
 | 
				
			||||||
 | 
					namespace RoboidControl {
 | 
				
			||||||
 | 
					namespace Windows {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Participant::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 Participant::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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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 << "\n";
 | 
				
			||||||
 | 
					      // std::cout << "New remote participant " <<
 | 
				
			||||||
 | 
					      // remoteParticipant->ipAddress
 | 
				
			||||||
 | 
					      // << ":"
 | 
				
			||||||
 | 
					      //           << remoteParticipant->port << " "
 | 
				
			||||||
 | 
					      //           << (int)remoteParticipant->networkId << "\n";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ReceiveData(packetSize, remoteParticipant);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool Participant::Send(RemoteParticipant* 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);
 | 
				
			||||||
 | 
					  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 Participant::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 Windows
 | 
				
			||||||
 | 
					}  // namespace RoboidControl
 | 
				
			||||||
 | 
					}  // namespace Passer
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user