initial commit
This commit is contained in:
24
libraries/FastLED/src/platforms/win/README.md
Normal file
24
libraries/FastLED/src/platforms/win/README.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# FastLED Platform: win
|
||||
|
||||
Windows‑specific networking helpers.
|
||||
|
||||
## Files (quick pass)
|
||||
- `socket_win.h`: Normalizes POSIX‑style socket API on Windows (Winsock2). Provides typedefs, constants, and wrappers (`socket/bind/connect/...`) plus init/teardown helpers.
|
||||
- `socket_win.cpp`: Implementation.
|
||||
|
||||
## Behavior and constraints
|
||||
- Requires Winsock initialization (e.g., `WSAStartup` via helper) and cleanup; wraps errors to POSIX‑like errno values (e.g., `EWOULDBLOCK`).
|
||||
- Mirrors POSIX calls for cross‑platform code while respecting Windows differences (e.g., `closesocket` vs `close`).
|
||||
|
||||
## Winsock initialization sequence
|
||||
|
||||
Before using any socket functions on Windows:
|
||||
|
||||
1. Call `fl::win::socket_init()` (wrapper around `WSAStartup`).
|
||||
2. Use the POSIX‑style wrappers (`socket/bind/connect/send/recv`, etc.).
|
||||
3. On shutdown, call `fl::win::socket_cleanup()` (wrapper around `WSACleanup`).
|
||||
|
||||
Limitations vs POSIX:
|
||||
|
||||
- File descriptors are not interchangeable with CRT file handles; always use `closesocket()` (wrapped) rather than `close()`.
|
||||
- Non‑blocking and error codes map to POSIX‑like values, but not all errno values are identical. Check for `EWOULDBLOCK`/`EINPROGRESS` via wrapper helpers.
|
||||
318
libraries/FastLED/src/platforms/win/socket_win.cpp
Normal file
318
libraries/FastLED/src/platforms/win/socket_win.cpp
Normal file
@@ -0,0 +1,318 @@
|
||||
#if defined(FASTLED_HAS_NETWORKING) && 0
|
||||
#ifdef _WIN32
|
||||
|
||||
#include "socket_win.h"
|
||||
|
||||
// Additional includes for platform functions
|
||||
#include "fl/shared_ptr.h"
|
||||
|
||||
// Additional Windows header isolation for implementation
|
||||
#ifndef NOMSG
|
||||
#define NOMSG
|
||||
#endif
|
||||
#ifndef NOWINSTYLES
|
||||
#define NOWINSTYLES
|
||||
#endif
|
||||
#ifndef NOSYSMETRICS
|
||||
#define NOSYSMETRICS
|
||||
#endif
|
||||
#ifndef NOCLIPBOARD
|
||||
#define NOCLIPBOARD
|
||||
#endif
|
||||
#ifndef NOCOLOR
|
||||
#define NOCOLOR
|
||||
#endif
|
||||
#ifndef NOKERNEL
|
||||
#define NOKERNEL
|
||||
#endif
|
||||
#ifndef NONLS
|
||||
#define NONLS
|
||||
#endif
|
||||
#ifndef NOMEMMGR
|
||||
#define NOMEMMGR
|
||||
#endif
|
||||
#ifndef NOMETAFILE
|
||||
#define NOMETAFILE
|
||||
#endif
|
||||
#ifndef NOOPENFILE
|
||||
#define NOOPENFILE
|
||||
#endif
|
||||
#ifndef NOSCROLL
|
||||
#define NOSCROLL
|
||||
#endif
|
||||
#ifndef NOTEXTMETRIC
|
||||
#define NOTEXTMETRIC
|
||||
#endif
|
||||
#ifndef NOWH
|
||||
#define NOWH
|
||||
#endif
|
||||
#ifndef NOWINOFFSETS
|
||||
#define NOWINOFFSETS
|
||||
#endif
|
||||
#ifndef NOKANJI
|
||||
#define NOKANJI
|
||||
#endif
|
||||
#ifndef NOICONS
|
||||
#define NOICONS
|
||||
#endif
|
||||
#ifndef NORASTEROPS
|
||||
#define NORASTEROPS
|
||||
#endif
|
||||
#ifndef NOSHOWWINDOW
|
||||
#define NOSHOWWINDOW
|
||||
#endif
|
||||
#ifndef OEMRESOURCE
|
||||
#define OEMRESOURCE
|
||||
#endif
|
||||
#ifndef NOATOM
|
||||
#define NOATOM
|
||||
#endif
|
||||
#ifndef NOCTLMGR
|
||||
#define NOCTLMGR
|
||||
#endif
|
||||
#ifndef NODRAWTEXT
|
||||
#define NODRAWTEXT
|
||||
#endif
|
||||
|
||||
// Additional includes for implementation
|
||||
#include <sys/types.h>
|
||||
#include <cstdarg> // For va_list in fcntl emulation
|
||||
|
||||
namespace fl {
|
||||
|
||||
//=============================================================================
|
||||
// Helper Functions for Windows Socket Normalization
|
||||
//=============================================================================
|
||||
|
||||
bool initialize_winsock() {
|
||||
static bool initialized = false;
|
||||
if (!initialized) {
|
||||
WSADATA wsaData;
|
||||
int result = WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||
initialized = (result == 0);
|
||||
}
|
||||
return initialized;
|
||||
}
|
||||
|
||||
void cleanup_winsock() {
|
||||
WSACleanup();
|
||||
}
|
||||
|
||||
int translate_windows_error(int wsa_error) {
|
||||
switch (wsa_error) {
|
||||
case WSAEWOULDBLOCK: return EWOULDBLOCK;
|
||||
case WSAECONNREFUSED: return ECONNREFUSED;
|
||||
case WSAETIMEDOUT: return ETIMEDOUT;
|
||||
case WSAENETUNREACH: return ENETUNREACH;
|
||||
case WSAEACCES: return EACCES;
|
||||
case WSAEADDRINUSE: return EADDRINUSE;
|
||||
case WSAEINVAL: return EINVAL;
|
||||
case WSAENOTCONN: return ENOTCONN;
|
||||
case WSAECONNRESET: return ECONNRESET;
|
||||
case WSAECONNABORTED: return ECONNABORTED;
|
||||
default: return wsa_error;
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Normalized POSIX-Style Socket API Functions
|
||||
//=============================================================================
|
||||
|
||||
// Core Socket Operations
|
||||
int socket(int domain, int type, int protocol) {
|
||||
if (!initialize_winsock()) {
|
||||
return -1;
|
||||
}
|
||||
SOCKET sock = ::socket(domain, type, protocol);
|
||||
return (sock == INVALID_SOCKET) ? -1 : static_cast<int>(sock);
|
||||
}
|
||||
|
||||
int socketpair(int domain, int type, int protocol, int sv[2]) {
|
||||
// Windows doesn't support socketpair - return error
|
||||
(void)domain; (void)type; (void)protocol; (void)sv;
|
||||
WSASetLastError(WSAEAFNOSUPPORT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Addressing
|
||||
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
|
||||
SOCKET sock = static_cast<SOCKET>(sockfd);
|
||||
int result = ::bind(sock, reinterpret_cast<const ::sockaddr*>(addr), addrlen);
|
||||
return (result == SOCKET_ERROR) ? -1 : 0;
|
||||
}
|
||||
|
||||
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
|
||||
SOCKET sock = static_cast<SOCKET>(sockfd);
|
||||
int result = ::connect(sock, reinterpret_cast<const ::sockaddr*>(addr), addrlen);
|
||||
return (result == SOCKET_ERROR) ? -1 : 0;
|
||||
}
|
||||
|
||||
int listen(int sockfd, int backlog) {
|
||||
SOCKET sock = static_cast<SOCKET>(sockfd);
|
||||
int result = ::listen(sock, backlog);
|
||||
return (result == SOCKET_ERROR) ? -1 : 0;
|
||||
}
|
||||
|
||||
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
|
||||
SOCKET server_sock = static_cast<SOCKET>(sockfd);
|
||||
int addr_len = addrlen ? static_cast<int>(*addrlen) : 0;
|
||||
SOCKET client_sock = ::accept(server_sock, reinterpret_cast<::sockaddr*>(addr), &addr_len);
|
||||
if (addrlen) *addrlen = static_cast<socklen_t>(addr_len);
|
||||
return (client_sock == INVALID_SOCKET) ? -1 : static_cast<int>(client_sock);
|
||||
}
|
||||
|
||||
// Data Transfer
|
||||
ssize_t send(int sockfd, const void *buf, size_t len, int flags) {
|
||||
SOCKET sock = static_cast<SOCKET>(sockfd);
|
||||
int result = ::send(sock, static_cast<const char*>(buf), static_cast<int>(len), flags);
|
||||
return (result == SOCKET_ERROR) ? -1 : static_cast<ssize_t>(result);
|
||||
}
|
||||
|
||||
ssize_t recv(int sockfd, void *buf, size_t len, int flags) {
|
||||
SOCKET sock = static_cast<SOCKET>(sockfd);
|
||||
int result = ::recv(sock, static_cast<char*>(buf), static_cast<int>(len), flags);
|
||||
return (result == SOCKET_ERROR) ? -1 : static_cast<ssize_t>(result);
|
||||
}
|
||||
|
||||
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
|
||||
const struct sockaddr *dest_addr, socklen_t addrlen) {
|
||||
SOCKET sock = static_cast<SOCKET>(sockfd);
|
||||
int result = ::sendto(sock, static_cast<const char*>(buf), static_cast<int>(len), flags,
|
||||
reinterpret_cast<const ::sockaddr*>(dest_addr), addrlen);
|
||||
return (result == SOCKET_ERROR) ? -1 : static_cast<ssize_t>(result);
|
||||
}
|
||||
|
||||
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
|
||||
struct sockaddr *src_addr, socklen_t *addrlen) {
|
||||
SOCKET sock = static_cast<SOCKET>(sockfd);
|
||||
int addr_len = addrlen ? static_cast<int>(*addrlen) : 0;
|
||||
int result = ::recvfrom(sock, static_cast<char*>(buf), static_cast<int>(len), flags,
|
||||
reinterpret_cast<::sockaddr*>(src_addr), &addr_len);
|
||||
if (addrlen) *addrlen = static_cast<socklen_t>(addr_len);
|
||||
return (result == SOCKET_ERROR) ? -1 : static_cast<ssize_t>(result);
|
||||
}
|
||||
|
||||
// Connection Teardown
|
||||
int shutdown(int sockfd, int how) {
|
||||
SOCKET sock = static_cast<SOCKET>(sockfd);
|
||||
int result = ::shutdown(sock, how);
|
||||
return (result == SOCKET_ERROR) ? -1 : 0;
|
||||
}
|
||||
|
||||
int close(int fd) {
|
||||
SOCKET sock = static_cast<SOCKET>(fd);
|
||||
int result = ::closesocket(sock);
|
||||
return (result == SOCKET_ERROR) ? -1 : 0;
|
||||
}
|
||||
|
||||
// Socket Options
|
||||
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen) {
|
||||
SOCKET sock = static_cast<SOCKET>(sockfd);
|
||||
|
||||
// Handle SO_REUSEPORT specially - not supported on Windows
|
||||
if (level == SOL_SOCKET && optname == SO_REUSEPORT) {
|
||||
WSASetLastError(WSAENOPROTOOPT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int result = ::setsockopt(sock, level, optname, static_cast<const char*>(optval), optlen);
|
||||
return (result == SOCKET_ERROR) ? -1 : 0;
|
||||
}
|
||||
|
||||
int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen) {
|
||||
SOCKET sock = static_cast<SOCKET>(sockfd);
|
||||
int len = optlen ? static_cast<int>(*optlen) : 0;
|
||||
int result = ::getsockopt(sock, level, optname, static_cast<char*>(optval), &len);
|
||||
if (optlen) *optlen = static_cast<socklen_t>(len);
|
||||
return (result == SOCKET_ERROR) ? -1 : 0;
|
||||
}
|
||||
|
||||
// Address Information
|
||||
int getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
|
||||
SOCKET sock = static_cast<SOCKET>(sockfd);
|
||||
int len = addrlen ? static_cast<int>(*addrlen) : 0;
|
||||
int result = ::getpeername(sock, reinterpret_cast<::sockaddr*>(addr), &len);
|
||||
if (addrlen) *addrlen = static_cast<socklen_t>(len);
|
||||
return (result == SOCKET_ERROR) ? -1 : 0;
|
||||
}
|
||||
|
||||
int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
|
||||
SOCKET sock = static_cast<SOCKET>(sockfd);
|
||||
int len = addrlen ? static_cast<int>(*addrlen) : 0;
|
||||
int result = ::getsockname(sock, reinterpret_cast<::sockaddr*>(addr), &len);
|
||||
if (addrlen) *addrlen = static_cast<socklen_t>(len);
|
||||
return (result == SOCKET_ERROR) ? -1 : 0;
|
||||
}
|
||||
|
||||
// Address Resolution (simplified - Windows has these functions)
|
||||
int inet_pton(int af, const char *src, void *dst) {
|
||||
return ::inet_pton(af, src, dst);
|
||||
}
|
||||
|
||||
const char* inet_ntop(int af, const void *src, char *dst, socklen_t size) {
|
||||
return ::inet_ntop(af, src, dst, static_cast<size_t>(size));
|
||||
}
|
||||
|
||||
// fcntl emulation for non-blocking sockets
|
||||
int fcntl(int fd, int cmd, ...) {
|
||||
SOCKET sock = static_cast<SOCKET>(fd);
|
||||
|
||||
if (cmd == F_GETFL) {
|
||||
// Windows doesn't provide a way to query non-blocking status
|
||||
// Return 0 (blocking) as default
|
||||
return 0;
|
||||
} else if (cmd == F_SETFL) {
|
||||
va_list args;
|
||||
va_start(args, cmd);
|
||||
int flags = va_arg(args, int);
|
||||
va_end(args);
|
||||
|
||||
u_long mode = (flags & O_NONBLOCK) ? 1 : 0;
|
||||
int result = ioctlsocket(sock, FIONBIO, &mode);
|
||||
return (result == SOCKET_ERROR) ? -1 : 0;
|
||||
}
|
||||
|
||||
WSASetLastError(WSAEINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Error handling
|
||||
int get_errno() {
|
||||
return translate_windows_error(WSAGetLastError());
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Platform-specific functions (required by socket_factory.cpp)
|
||||
//=============================================================================
|
||||
|
||||
fl::shared_ptr<Socket> create_platform_socket(const SocketOptions& options) {
|
||||
// Windows doesn't have a specific Socket implementation class yet
|
||||
// Return nullptr for now - this will need a Windows Socket class implementation
|
||||
(void)options;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool platform_supports_ipv6() {
|
||||
// Windows supports IPv6
|
||||
return true;
|
||||
}
|
||||
|
||||
bool platform_supports_tls() {
|
||||
// TLS would need to be implemented at a higher level for Windows
|
||||
return false;
|
||||
}
|
||||
|
||||
bool platform_supports_non_blocking_connect() {
|
||||
// Windows supports non-blocking operations
|
||||
return true;
|
||||
}
|
||||
|
||||
bool platform_supports_socket_reuse() {
|
||||
// Windows supports SO_REUSEADDR
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace fl
|
||||
|
||||
#endif // _WIN32
|
||||
#endif // FASTLED_HAS_NETWORKING
|
||||
209
libraries/FastLED/src/platforms/win/socket_win.h
Normal file
209
libraries/FastLED/src/platforms/win/socket_win.h
Normal file
@@ -0,0 +1,209 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef FASTLED_HAS_NETWORKING && 0
|
||||
#ifdef _WIN32
|
||||
|
||||
#include "fl/string.h"
|
||||
#include "fl/stdint.h"
|
||||
|
||||
// Essential Windows header isolation
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#ifndef NOGDI
|
||||
#define NOGDI
|
||||
#endif
|
||||
#ifndef NOUSER
|
||||
#define NOUSER
|
||||
#endif
|
||||
|
||||
// Minimal Windows includes for type definitions
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
namespace fl {
|
||||
|
||||
//=============================================================================
|
||||
// Normalized POSIX-Style Socket Types
|
||||
//=============================================================================
|
||||
|
||||
// POSIX-style type definitions that normalize Windows socket types
|
||||
// Use existing Windows types when available to avoid conflicts
|
||||
using socklen_t = int;
|
||||
using ssize_t = int;
|
||||
|
||||
// Windows already defines sockaddr, sockaddr_in, sockaddr_in6, in_addr, in6_addr
|
||||
// We use the existing Windows types directly via using declarations
|
||||
using ::sockaddr;
|
||||
using ::sockaddr_in;
|
||||
using ::sockaddr_in6;
|
||||
using ::in_addr;
|
||||
using ::in6_addr;
|
||||
|
||||
// Type aliases for consistency with POSIX
|
||||
using sa_family_t = unsigned short; // Same as ADDRESS_FAMILY
|
||||
using in_port_t = unsigned short; // Same as USHORT
|
||||
|
||||
//=============================================================================
|
||||
// POSIX Socket Constants (Windows Normalization)
|
||||
//=============================================================================
|
||||
|
||||
// Address families
|
||||
#ifndef AF_INET
|
||||
#define AF_INET 2
|
||||
#endif
|
||||
#ifndef AF_INET6
|
||||
#define AF_INET6 23
|
||||
#endif
|
||||
|
||||
// Socket types
|
||||
#ifndef SOCK_STREAM
|
||||
#define SOCK_STREAM 1
|
||||
#endif
|
||||
#ifndef SOCK_DGRAM
|
||||
#define SOCK_DGRAM 2
|
||||
#endif
|
||||
|
||||
// Protocols
|
||||
#ifndef IPPROTO_TCP
|
||||
#define IPPROTO_TCP 6
|
||||
#endif
|
||||
#ifndef IPPROTO_UDP
|
||||
#define IPPROTO_UDP 17
|
||||
#endif
|
||||
|
||||
// Socket options
|
||||
#ifndef SOL_SOCKET
|
||||
#define SOL_SOCKET 0xffff
|
||||
#endif
|
||||
#ifndef SO_REUSEADDR
|
||||
#define SO_REUSEADDR 0x0004
|
||||
#endif
|
||||
#ifndef SO_REUSEPORT
|
||||
#define SO_REUSEPORT 0x0200 // Not supported on Windows - will return error
|
||||
#endif
|
||||
#ifndef TCP_NODELAY
|
||||
#define TCP_NODELAY 1
|
||||
#endif
|
||||
|
||||
// fcntl flags for non-blocking
|
||||
#ifndef F_GETFL
|
||||
#define F_GETFL 3
|
||||
#endif
|
||||
#ifndef F_SETFL
|
||||
#define F_SETFL 4
|
||||
#endif
|
||||
#ifndef O_NONBLOCK
|
||||
#define O_NONBLOCK 0x4000
|
||||
#endif
|
||||
|
||||
// Shutdown options
|
||||
#ifndef SHUT_RD
|
||||
#define SHUT_RD 0
|
||||
#endif
|
||||
#ifndef SHUT_WR
|
||||
#define SHUT_WR 1
|
||||
#endif
|
||||
#ifndef SHUT_RDWR
|
||||
#define SHUT_RDWR 2
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
// Helper Functions for Windows Socket Normalization
|
||||
//=============================================================================
|
||||
|
||||
bool initialize_winsock();
|
||||
void cleanup_winsock();
|
||||
int translate_windows_error(int wsa_error);
|
||||
|
||||
//=============================================================================
|
||||
// Normalized POSIX-Style Socket API Functions
|
||||
//=============================================================================
|
||||
|
||||
// Core Socket Operations
|
||||
int socket(int domain, int type, int protocol);
|
||||
int socketpair(int domain, int type, int protocol, int sv[2]);
|
||||
|
||||
// Addressing
|
||||
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
|
||||
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
|
||||
int listen(int sockfd, int backlog);
|
||||
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
|
||||
|
||||
// Data Transfer
|
||||
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
|
||||
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
|
||||
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
|
||||
const struct sockaddr *dest_addr, socklen_t addrlen);
|
||||
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
|
||||
struct sockaddr *src_addr, socklen_t *addrlen);
|
||||
|
||||
// Connection Teardown
|
||||
int shutdown(int sockfd, int how);
|
||||
int close(int fd);
|
||||
|
||||
// Socket Options
|
||||
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
|
||||
int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);
|
||||
|
||||
// Address Information
|
||||
int getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
|
||||
int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
|
||||
|
||||
// Address Resolution
|
||||
int inet_pton(int af, const char *src, void *dst);
|
||||
const char* inet_ntop(int af, const void *src, char *dst, socklen_t size);
|
||||
|
||||
// fcntl emulation for non-blocking sockets
|
||||
int fcntl(int fd, int cmd, ...);
|
||||
|
||||
// Error handling
|
||||
int get_errno();
|
||||
|
||||
// WASM CONSTRAINTS: The following functions are blocking calls and are
|
||||
// DISALLOWED and NOT AVAILABLE on WASM due to proxying limitations:
|
||||
// - select()
|
||||
// - poll()
|
||||
// These functions are not declared in this API and MUST NOT be used.
|
||||
// Use per-call non-blocking flags like MSG_DONTWAIT instead.
|
||||
// (Note: This constraint applies to WASM builds only - Windows builds are not affected)
|
||||
|
||||
// POSIX errno constants for Windows
|
||||
#ifndef EWOULDBLOCK
|
||||
#define EWOULDBLOCK WSAEWOULDBLOCK
|
||||
#endif
|
||||
#ifndef ECONNREFUSED
|
||||
#define ECONNREFUSED WSAECONNREFUSED
|
||||
#endif
|
||||
#ifndef ETIMEDOUT
|
||||
#define ETIMEDOUT WSAETIMEDOUT
|
||||
#endif
|
||||
#ifndef ENETUNREACH
|
||||
#define ENETUNREACH WSAENETUNREACH
|
||||
#endif
|
||||
#ifndef EACCES
|
||||
#define EACCES WSAEACCES
|
||||
#endif
|
||||
#ifndef EADDRINUSE
|
||||
#define EADDRINUSE WSAEADDRINUSE
|
||||
#endif
|
||||
#ifndef EINVAL
|
||||
#define EINVAL WSAEINVAL
|
||||
#endif
|
||||
#ifndef ENOTCONN
|
||||
#define ENOTCONN WSAENOTCONN
|
||||
#endif
|
||||
#ifndef ECONNRESET
|
||||
#define ECONNRESET WSAECONNRESET
|
||||
#endif
|
||||
#ifndef ECONNABORTED
|
||||
#define ECONNABORTED WSAECONNABORTED
|
||||
#endif
|
||||
|
||||
} // namespace fl
|
||||
|
||||
#endif // _WIN32
|
||||
#endif // FASTLED_HAS_NETWORKING
|
||||
Reference in New Issue
Block a user