#include "PosixMQTT.h" #if defined(__unix__) || defined(__APPLE__) #include #include // For fcntl #include #include #include #include #include namespace RoboidControl { MQTTParticipant::MQTTParticipant(const char* remoteIpAddress, int port) : MQTTParticipantBase(remoteIpAddress, port) { SetupTCP(); std::this_thread::sleep_for(std::chrono::milliseconds(1000)); send_mqtt_connect("RoboidControl1"); // sendSubscribe("domoticz/out"); } void MQTTParticipant::SetupTCP() { // Create a TCP socket this->sock = socket(AF_INET, SOCK_STREAM, 0); if (this->sock < 0) { std::cerr << "Error creating socket" << std::endl; return; } // Set the socket to non-blocking mode int flags = fcntl(this->sock, F_GETFL, 0); fcntl(this->sock, F_SETFL, flags | O_NONBLOCK); this->remote_addr.sin_family = AF_INET; this->remote_addr.sin_port = htons(this->remoteSite->port); int result = inet_pton(AF_INET, this->remoteSite->ipAddress, &remote_addr.sin_addr); if (result <= 0) { std::cerr << "Invalid address/ Address not supported" << std::endl; close(this->sock); return; } int connect_result = connect(this->sock, (struct sockaddr*)&remote_addr, sizeof(remote_addr)); if (connect_result < 0 && errno != EINPROGRESS) { std::cerr << "Error connecting to server:" << (int)errno << std::endl; close(this->sock); return; } std::cout << "TCP connection to " << this->remoteSite->ipAddress << ":" << this->remoteSite->port << "\n"; this->connected = true; } void MQTTParticipant::SendTCP(int bufferSize) { send(this->sock, this->buffer, bufferSize, 0); std::cout << "Posix: sent TCP\n"; } int MQTTParticipant::ReceiveTCP() { if (this->connected == false) return 0; int bytesReceived = recv(this->sock, this->buffer, sizeof(this->buffer) - 1, 0); if (bytesReceived > 0) { std::cout << " !\n"; buffer[bytesReceived] = '\0'; // Null-terminate the received data std::cout << "Received: " << this->buffer << std::endl; return bytesReceived; } else if (bytesReceived == 0) { this->connected = false; // Connection has been gracefully closed std::cout << "Connection closed by the server." << std::endl; return 0; } else { if (errno == EAGAIN || errno == EWOULDBLOCK) { // No data available to read, continue the loop // std::cout << "No data available" << std::endl; } else { std::cerr << "Error receiving data: " << strerror(errno) << std::endl; } return 0; } return 0; } } // namespace RoboidControl #endif