8#include <zephyr/kernel.h>
9#include <zephyr/net/net_ip.h>
10#include <zephyr/net/socket.h>
11#include <zephyr/sys/util.h>
16 "WiFiClientZephyr requires CONFIG_NETWORKING=y");
19 "WiFiClientZephyr requires CONFIG_NET_TCP=y");
22 "WiFiClientZephyr requires CONFIG_NET_SOCKETS=y");
25 "WiFiClientZephyr requires CONFIG_DNS_RESOLVER=y");
63 virtual int connect(
const char* host, uint16_t port) {
66 struct sockaddr_storage addr = {};
67 socklen_t addrlen =
sizeof(addr);
69 if (
_resolve(host, port, (
struct sockaddr*)&addr, &addrlen) < 0) {
73 _sock = zsock_socket(addr.ss_family, SOCK_STREAM, IPPROTO_TCP);
80 if (zsock_connect(
_sock, (
struct sockaddr*)&addr, addrlen) < 0) {
95 virtual int connect(uint32_t ip, uint16_t port) {
96 char host[INET_ADDRSTRLEN];
97 struct in_addr addr_in;
99 zsock_inet_ntop(AF_INET, &addr_in, host,
sizeof(host));
114 if (
_sock < 0)
return 0;
118 int rc = zsock_recv(
_sock, &probe, 0, ZSOCK_MSG_PEEK | ZSOCK_MSG_DONTWAIT);
119 if (rc == 0)
return 0;
120 if (rc < 0 && errno != EAGAIN && errno != EWOULDBLOCK)
return 0;
132 size_t write(
const uint8_t* buf,
size_t size) {
133 if (
_sock < 0 || !buf || size == 0)
return 0;
136 while (sent < size) {
137 ssize_t rc = zsock_send(
_sock, buf + sent, size - sent, 0);
149 return write((
const uint8_t*)str, strlen(str));
153 return print(str) +
write((
const uint8_t*)
"\r\n", 2);
158 snprintf(buf,
sizeof(buf),
"%d", value);
164 snprintf(buf,
sizeof(buf),
"%d", value);
176 if (
_sock < 0)
return -1;
181 if (zsock_ioctl(
_sock, ZFD_IOCTL_FIONREAD, &bytes) == 0) {
187 int rc = zsock_recv(
_sock, &b, 1, ZSOCK_MSG_DONTWAIT | ZSOCK_MSG_PEEK);
188 if (rc > 0)
return 1;
193 return (errno == EAGAIN || errno == EWOULDBLOCK) ? 0 : -1;
201 if (
_sock < 0)
return -1;
209 ssize_t rc = zsock_recv(
_sock, &b, 1, 0);
210 if (rc == 1)
return b;
219 int read(uint8_t* buf,
size_t size) {
220 if (
_sock < 0 || !buf || size == 0)
return -1;
231 if (size == 0)
return (
int)offset;
233 ssize_t rc = zsock_recv(
_sock, buf + offset, size, 0);
235 if (errno == EAGAIN || errno == EWOULDBLOCK)
return (
int)offset;
236 return offset > 0 ? (int)offset : -1;
239 return (
int)(offset + (size_t)rc);
247 if (
_sock < 0)
return -1;
251 ssize_t rc = zsock_recv(
_sock, &b, 1, ZSOCK_MSG_PEEK);
284 if (
_sock < 0)
return;
285 struct timeval tv = {};
288 zsock_setsockopt(
_sock, SOL_SOCKET, SO_RCVTIMEO, &tv,
sizeof(tv));
291 int _resolve(
const char* host, uint16_t port,
struct sockaddr* out,
293 struct zsock_addrinfo hints = {};
294 struct zsock_addrinfo* res =
nullptr;
296 snprintf(port_str,
sizeof(port_str),
"%u", port);
298 hints.ai_family = AF_UNSPEC;
299 hints.ai_socktype = SOCK_STREAM;
301 int rc = zsock_getaddrinfo(host, port_str, &hints, &res);
302 if (rc != 0 || !res)
return -1;
304 memcpy(out, res->ai_addr, res->ai_addrlen);
305 *outlen = res->ai_addrlen;
306 zsock_freeaddrinfo(res);
BUILD_ASSERT(IS_ENABLED(CONFIG_NETWORKING), "WiFiClientZephyr requires CONFIG_NETWORKING=y")