From 931e93a11beb4a97fdd7a06fe76cf5256970c31e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Jul 2025 00:20:43 +0200 Subject: [PATCH] Win32 socket vs POSIX sockets is not always happy together. Seperated the two to mimic the same behavior we have for /uart/. The code compiles but the socket doesnt work on Proxspace yet. More fixes to be done --- client/deps/mqtt/posix_sockets.h | 67 ++++++++--------------- client/deps/mqtt/win32_sockets.h | 91 ++++++++++++++++++++++++++++++++ client/src/cmdmqtt.c | 7 +++ 3 files changed, 121 insertions(+), 44 deletions(-) create mode 100644 client/deps/mqtt/win32_sockets.h diff --git a/client/deps/mqtt/posix_sockets.h b/client/deps/mqtt/posix_sockets.h index ab13f863d..d44e1c374 100644 --- a/client/deps/mqtt/posix_sockets.h +++ b/client/deps/mqtt/posix_sockets.h @@ -1,23 +1,21 @@ #if !defined(__POSIX_SOCKET_TEMPLATE_H__) #define __POSIX_SOCKET_TEMPLATE_H__ -#include -#include -#if !defined(WIN32) -#include -#include -#else -#include -#endif -#if defined(__VMS) -#include -#endif -#include -#include +#ifndef _WIN32 -/* - A template for opening a non-blocking POSIX socket. -*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// A template for opening a non-blocking POSIX socket. + +void close_nb_socket(int sockfd); int open_nb_socket(const char *addr, const char *port); int open_nb_socket(const char *addr, const char *port) { @@ -27,21 +25,23 @@ int open_nb_socket(const char *addr, const char *port) { hints.ai_family = AF_UNSPEC; /* IPv4 or IPv6 */ hints.ai_socktype = SOCK_STREAM; /* Must be TCP */ - int sockfd = -1; - int rv; + struct addrinfo *p, *servinfo; /* get address information */ - rv = getaddrinfo(addr, port, &hints, &servinfo); + int rv = getaddrinfo(addr, port, &hints, &servinfo); if (rv != 0) { fprintf(stderr, "Failed to open socket (getaddrinfo): %s\n", gai_strerror(rv)); return -1; } /* open the first possible socket */ + int sockfd = -1; for (p = servinfo; p != NULL; p = p->ai_next) { sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol); - if (sockfd == -1) continue; + if (sockfd == -1) { + continue; + } /* connect to server */ rv = connect(sockfd, p->ai_addr, p->ai_addrlen); @@ -53,42 +53,21 @@ int open_nb_socket(const char *addr, const char *port) { break; } - /* free servinfo */ + // free servinfo freeaddrinfo(servinfo); - /* make non-blocking */ -#if !defined(WIN32) + // make non-blocking if (sockfd != -1) { fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL) | O_NONBLOCK); } -#else - if (sockfd != INVALID_SOCKET) { - int iMode = 1; - ioctlsocket(sockfd, FIONBIO, &iMode); - } -#endif -#if defined(__VMS) - /* - OpenVMS only partially implements fcntl. It works on file descriptors - but silently fails on socket descriptors. So we need to fall back on - to the older ioctl system to set non-blocking IO - */ - int on = 1; - if (sockfd != -1) { - ioctl(sockfd, FIONBIO, &on); - } -#endif - - /* return the new socket fd */ return sockfd; } -void close_nb_socket(int sockfd); - void close_nb_socket(int sockfd) { if (sockfd != -1) { close(sockfd); } } #endif +#endif \ No newline at end of file diff --git a/client/deps/mqtt/win32_sockets.h b/client/deps/mqtt/win32_sockets.h new file mode 100644 index 000000000..126c7560d --- /dev/null +++ b/client/deps/mqtt/win32_sockets.h @@ -0,0 +1,91 @@ +#if !defined(__WIN32_SOCKET_TEMPLATE_H__) + +#include +#include + +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#include +#include + +void close_nb_socket(int sockfd); +int open_nb_socket(const char *addr, const char *port); + +int open_nb_socket(const char *addr, const char *port) { + + WSADATA wsaData; + int res = WSAStartup(MAKEWORD(2, 2), &wsaData); + if (res != 0) { + fprintf(stderr, "error: WSAStartup failed with error: %i", res); + return -1; + } + + struct addrinfo hints; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; // IPv4 or IPv6 + hints.ai_socktype = SOCK_STREAM; // Must be TCP + hints.ai_protocol = IPPROTO_TCP; // + + struct addrinfo *p, *servinfo; + // get address information + int rv = getaddrinfo(addr, port, &hints, &servinfo); + if (rv != 0) { + fprintf(stderr, "error: getaddrinfo: %s", gai_strerror(rv)); + WSACleanup(); + return -1; + } + + /* open the first possible socket */ + SOCKET hSocket = INVALID_SOCKET; + for (p = servinfo; p != NULL; p = p->ai_next) { + hSocket = socket(p->ai_family, p->ai_socktype, p->ai_protocol); + + if (hSocket == INVALID_SOCKET) { + continue; + } + + // connect to server + if (connect(hSocket, p->ai_addr, (int)p->ai_addrlen) != INVALID_SOCKET) { + break; + } + + closesocket(hSocket); + hSocket = INVALID_SOCKET; + + } + + // free servinfo + freeaddrinfo(servinfo); + + if (p == NULL) { // No address succeeded + fprintf(stderr, "error: Could not connect"); + WSACleanup(); + return -1; + } + + // make non-blocking + if (hSocket != INVALID_SOCKET) { + uint32_t mode; // FIONBIO returns size on 32b + ioctlsocket(hSocket, FIONBIO, (u_long *)&mode); + } + + int flag = 1; + res = setsockopt(hSocket, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(flag)); + if (res != 0) { + closesocket(hSocket); + WSACleanup(); + return -1; + } + + return hSocket; +} + +void close_nb_socket(int sockfd) { + if (sockfd != -1) { + close(sockfd); + } +} +#endif + +#endif \ No newline at end of file diff --git a/client/src/cmdmqtt.c b/client/src/cmdmqtt.c index 902ddb768..ba7d93685 100644 --- a/client/src/cmdmqtt.c +++ b/client/src/cmdmqtt.c @@ -21,7 +21,12 @@ #include "cliparser.h" #include "mqtt.h" // MQTT support //#include "mbedtls_sockets.h" // MQTT networkings examples + +#ifndef _WIN32 #include "posix_sockets.h" // MQTT networkings examples +#else +#include "win32_sockets.h" // MQTT networkings examples +#endif #include "util_posix.h" // time #include "fileutils.h" @@ -62,7 +67,9 @@ static int mqtt_exit(int status, int sockfd, pthread_t *client_daemon) { if (client_daemon != NULL) { pthread_cancel(*client_daemon); +#ifndef _WIN32 pthread_join(*client_daemon, NULL); // Wait for the thread to finish +#endif } return status; }