#include "WindowsMQTT.h" #if defined(_WIN32) || defined(_WIN64) #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("RoboidControl"); sendSubscribe("domoticz/out"); } void MQTTParticipant::SetupTCP() { // Initialize Winsock WSADATA wsaData; if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { std::cerr << "WSAStartup failed: " << std::endl; return; } // Create a TCP socket this->sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock == INVALID_SOCKET) { std::cerr << "TCP Socket creation failed: " << WSAGetLastError() << std::endl; WSACleanup(); return; } // Define the server address memset(&this->remote_addr, 0, sizeof(this->remote_addr)); this->remote_addr.sin_family = AF_INET; this->remote_addr.sin_port = htons((u_short)this->remoteSite->port); if (inet_pton(AF_INET, this->remoteSite->ipAddress, &this->remote_addr.sin_addr) <= 0) { std::cerr << "Invalid address" << std::endl; closesocket(sock); WSACleanup(); return; } // Connect to the server if (connect(sock, (sockaddr*)&this->remote_addr, sizeof(this->remote_addr)) == SOCKET_ERROR) { std::cerr << "Connection failed: " << WSAGetLastError() << std::endl; closesocket(sock); WSACleanup(); return; } // Set the socket to non-blocking mode u_long mode = 1; // 1 to enable non-blocking socket if (ioctlsocket(sock, FIONBIO, &mode) != NO_ERROR) { std::cerr << "Failed to set non-blocking mode: " << WSAGetLastError() << std::endl; closesocket(sock); WSACleanup(); return; } } int MQTTParticipant::ReceiveTCP() { int bytesReceived = recv(sock, buffer, sizeof(buffer) - 1, 0); if (bytesReceived > 0) { buffer[bytesReceived] = '\0'; // Null-terminate the received data std::cout << "Received: " << buffer << std::endl; return bytesReceived; } else if (bytesReceived == 0) { // Connection has been gracefully closed std::cout << "Connection closed by the server." << std::endl; return 0; } else { int error = WSAGetLastError(); if (error == WSAEWOULDBLOCK) { // No data available, continue with other tasks //std::cout << "No data available, continuing..." << std::endl; // You can add a sleep or other logic here to avoid busy waiting } else { std::cerr << "Receive failed: " << error << std::endl; } return 0; } return 0; } void MQTTParticipant::SendTCP(int bufferSize) { #if defined(_WIN32) || defined(_WIN64) send(sock, this->buffer, bufferSize, 0); #endif } } // namespace RoboidControl #endif