RoboidControl-cpp/Posix/PosixMQTT.cpp
2025-06-29 13:01:31 +02:00

95 lines
2.6 KiB
C++

#include "PosixMQTT.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>
#include <chrono>
#include <thread>
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