WIP doesn't flush response before closing
This commit is contained in:
parent
301f3e0456
commit
61d0f7947b
@ -40,6 +40,9 @@
|
||||
#include "common-hal/pulseio/PulseIn.h"
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_WEB_WORKFLOW
|
||||
#include "supervisor/shared/web_workflow/web_workflow.h"
|
||||
#endif
|
||||
|
||||
void port_background_task(void) {
|
||||
// Zero delay in case FreeRTOS wants to switch to something else.
|
||||
@ -47,6 +50,10 @@ void port_background_task(void) {
|
||||
#if CIRCUITPY_PULSEIO
|
||||
pulsein_background();
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_WEB_WORKFLOW
|
||||
supervisor_web_workflow_background();
|
||||
#endif
|
||||
}
|
||||
|
||||
void port_start_background_task(void) {
|
||||
|
@ -37,6 +37,10 @@
|
||||
#include "components/lwip/lwip/src/include/lwip/sys.h"
|
||||
#include "components/lwip/lwip/src/include/lwip/netdb.h"
|
||||
|
||||
#include "esp_log.h"
|
||||
|
||||
static const char *TAG = "socket";
|
||||
|
||||
STATIC socketpool_socket_obj_t *open_socket_handles[CONFIG_LWIP_MAX_SOCKETS];
|
||||
|
||||
void socket_user_reset(void) {
|
||||
@ -62,8 +66,7 @@ bool register_open_socket(socketpool_socket_obj_t *self) {
|
||||
return false;
|
||||
}
|
||||
|
||||
socketpool_socket_obj_t *common_hal_socketpool_socket_accept(socketpool_socket_obj_t *self,
|
||||
uint8_t *ip, uint32_t *port) {
|
||||
int socketpool_socket_accept(socketpool_socket_obj_t *self, uint8_t *ip, uint32_t *port) {
|
||||
struct sockaddr_in accept_addr;
|
||||
socklen_t socklen = sizeof(accept_addr);
|
||||
int newsoc = -1;
|
||||
@ -81,7 +84,10 @@ socketpool_socket_obj_t *common_hal_socketpool_socket_accept(socketpool_socket_o
|
||||
newsoc = lwip_accept(self->num, (struct sockaddr *)&accept_addr, &socklen);
|
||||
// In non-blocking mode, fail instead of timing out
|
||||
if (newsoc == -1 && self->timeout_ms == 0) {
|
||||
mp_raise_OSError(MP_EAGAIN);
|
||||
if (errno != EAGAIN) {
|
||||
ESP_LOGE(TAG, "accept failed %d", errno);
|
||||
}
|
||||
return -MP_EAGAIN;
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,8 +96,17 @@ socketpool_socket_obj_t *common_hal_socketpool_socket_accept(socketpool_socket_o
|
||||
memcpy((void *)ip, (void *)&accept_addr.sin_addr.s_addr, sizeof(accept_addr.sin_addr.s_addr));
|
||||
*port = accept_addr.sin_port;
|
||||
} else {
|
||||
mp_raise_OSError(ETIMEDOUT);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
if (newsoc < 0) {
|
||||
return -MP_EBADF;
|
||||
}
|
||||
return newsoc;
|
||||
}
|
||||
|
||||
socketpool_socket_obj_t *common_hal_socketpool_socket_accept(socketpool_socket_obj_t *self,
|
||||
uint8_t *ip, uint32_t *port) {
|
||||
int newsoc = socketpool_socket_accept(self, ip, port);
|
||||
|
||||
if (newsoc > 0) {
|
||||
// Create the socket
|
||||
@ -108,7 +123,7 @@ socketpool_socket_obj_t *common_hal_socketpool_socket_accept(socketpool_socket_o
|
||||
lwip_fcntl(newsoc, F_SETFL, O_NONBLOCK);
|
||||
return sock;
|
||||
} else {
|
||||
mp_raise_OSError(MP_EBADF);
|
||||
mp_raise_OSError(-newsoc);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@ -125,17 +140,22 @@ bool common_hal_socketpool_socket_bind(socketpool_socket_obj_t *self,
|
||||
if (err != 0) {
|
||||
mp_raise_RuntimeError(translate("Cannot set socket options"));
|
||||
}
|
||||
int result = lwip_bind(self->num, (struct sockaddr *)&bind_addr, sizeof(bind_addr)) == 0;
|
||||
return result;
|
||||
int result = lwip_bind(self->num, (struct sockaddr *)&bind_addr, sizeof(bind_addr));
|
||||
ESP_LOGE(TAG, "bind result %d", result);
|
||||
return result == 0;
|
||||
}
|
||||
|
||||
void common_hal_socketpool_socket_close(socketpool_socket_obj_t *self) {
|
||||
void socketpool_socket_close(socketpool_socket_obj_t *self) {
|
||||
self->connected = false;
|
||||
if (self->num >= 0) {
|
||||
lwip_shutdown(self->num, 0);
|
||||
lwip_shutdown(self->num, SHUT_RDWR);
|
||||
lwip_close(self->num);
|
||||
self->num = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void common_hal_socketpool_socket_close(socketpool_socket_obj_t *self) {
|
||||
socketpool_socket_close(self);
|
||||
// Remove socket record
|
||||
for (size_t i = 0; i < MP_ARRAY_SIZE(open_socket_handles); i++) {
|
||||
if (open_socket_handles[i] == self) {
|
||||
@ -199,7 +219,9 @@ bool common_hal_socketpool_socket_get_connected(socketpool_socket_obj_t *self) {
|
||||
}
|
||||
|
||||
bool common_hal_socketpool_socket_listen(socketpool_socket_obj_t *self, int backlog) {
|
||||
return lwip_listen(self->num, backlog) == 0;
|
||||
int result = lwip_listen(self->num, backlog);
|
||||
ESP_LOGE(TAG, "listen result %d", result);
|
||||
return result == 0;
|
||||
}
|
||||
|
||||
mp_uint_t common_hal_socketpool_socket_recvfrom_into(socketpool_socket_obj_t *self,
|
||||
@ -242,7 +264,8 @@ mp_uint_t common_hal_socketpool_socket_recvfrom_into(socketpool_socket_obj_t *se
|
||||
return received;
|
||||
}
|
||||
|
||||
mp_uint_t common_hal_socketpool_socket_recv_into(socketpool_socket_obj_t *self, const uint8_t *buf, uint32_t len) {
|
||||
int socketpool_socket_recv_into(socketpool_socket_obj_t *self,
|
||||
const uint8_t *buf, uint32_t len) {
|
||||
int received = 0;
|
||||
bool timed_out = false;
|
||||
|
||||
@ -261,31 +284,52 @@ mp_uint_t common_hal_socketpool_socket_recv_into(socketpool_socket_obj_t *self,
|
||||
|
||||
// In non-blocking mode, fail instead of looping
|
||||
if (received == -1 && self->timeout_ms == 0) {
|
||||
mp_raise_OSError(MP_EAGAIN);
|
||||
if (errno != EAGAIN) {
|
||||
ESP_LOGE(TAG, "recv %d", errno);
|
||||
}
|
||||
return -MP_EAGAIN;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mp_raise_OSError(MP_EBADF);
|
||||
return -MP_EBADF;
|
||||
}
|
||||
|
||||
if (timed_out) {
|
||||
mp_raise_OSError(ETIMEDOUT);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
return received;
|
||||
}
|
||||
|
||||
mp_uint_t common_hal_socketpool_socket_send(socketpool_socket_obj_t *self, const uint8_t *buf, uint32_t len) {
|
||||
mp_uint_t common_hal_socketpool_socket_recv_into(socketpool_socket_obj_t *self, const uint8_t *buf, uint32_t len) {
|
||||
int received = socketpool_socket_recv_into(self, buf, len);
|
||||
if (received < 0) {
|
||||
mp_raise_OSError(received);
|
||||
}
|
||||
return received;
|
||||
}
|
||||
|
||||
int socketpool_socket_send(socketpool_socket_obj_t *self, const uint8_t *buf, uint32_t len) {
|
||||
int sent = -1;
|
||||
if (self->num != -1) {
|
||||
// LWIP Socket
|
||||
// TODO: deal with potential failure/add timeout?
|
||||
sent = lwip_send(self->num, buf, len, 0);
|
||||
} else {
|
||||
mp_raise_OSError(MP_EBADF);
|
||||
sent = -MP_EBADF;
|
||||
}
|
||||
|
||||
if (sent < 0) {
|
||||
mp_raise_OSError(errno);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
return sent;
|
||||
}
|
||||
|
||||
mp_uint_t common_hal_socketpool_socket_send(socketpool_socket_obj_t *self, const uint8_t *buf, uint32_t len) {
|
||||
int sent = socketpool_socket_send(self, buf, len);
|
||||
|
||||
if (sent < 0) {
|
||||
mp_raise_OSError(-sent);
|
||||
}
|
||||
return sent;
|
||||
}
|
||||
|
@ -40,29 +40,9 @@ void common_hal_socketpool_socketpool_construct(socketpool_socketpool_obj_t *sel
|
||||
}
|
||||
}
|
||||
|
||||
void socketpool_socket(socketpool_socketpool_obj_t *self,
|
||||
socketpool_socketpool_addressfamily_t family, socketpool_socketpool_sock_t type
|
||||
bool socketpool_socket(socketpool_socketpool_obj_t *self,
|
||||
socketpool_socketpool_addressfamily_t family, socketpool_socketpool_sock_t type,
|
||||
socketpool_socket_obj_t *sock) {
|
||||
sock->type = socket_type;
|
||||
sock->family = addr_family;
|
||||
sock->ipproto = ipproto;
|
||||
sock->pool = self;
|
||||
sock->timeout_ms = (uint)-1;
|
||||
|
||||
// Create LWIP socket
|
||||
int socknum = -1;
|
||||
socknum = lwip_socket(sock->family, sock->type, sock->ipproto);
|
||||
if (socknum < 0 || !register_open_socket(sock)) {
|
||||
mp_raise_RuntimeError(translate("Out of sockets"));
|
||||
}
|
||||
sock->num = socknum;
|
||||
// Sockets should be nonblocking in most cases
|
||||
lwip_fcntl(socknum, F_SETFL, O_NONBLOCK);
|
||||
}
|
||||
|
||||
socketpool_socket_obj_t *common_hal_socketpool_socket(socketpool_socketpool_obj_t *self,
|
||||
socketpool_socketpool_addressfamily_t family, socketpool_socketpool_sock_t type) {
|
||||
|
||||
int addr_family;
|
||||
int ipproto;
|
||||
if (family == SOCKETPOOL_AF_INET) {
|
||||
@ -81,15 +61,37 @@ socketpool_socket_obj_t *common_hal_socketpool_socket(socketpool_socketpool_obj_
|
||||
} else { // SOCKETPOOL_SOCK_RAW
|
||||
socket_type = SOCK_RAW;
|
||||
}
|
||||
sock->type = socket_type;
|
||||
sock->family = addr_family;
|
||||
sock->ipproto = ipproto;
|
||||
sock->pool = self;
|
||||
sock->timeout_ms = (uint)-1;
|
||||
|
||||
if (addr_family == AF_INET6 || ipproto == IPPROTO_IPV6) {
|
||||
// Create LWIP socket
|
||||
int socknum = -1;
|
||||
socknum = lwip_socket(sock->family, sock->type, sock->ipproto);
|
||||
if (socknum < 0) {
|
||||
return false;
|
||||
}
|
||||
sock->num = socknum;
|
||||
// Sockets should be nonblocking in most cases
|
||||
lwip_fcntl(socknum, F_SETFL, O_NONBLOCK);
|
||||
return true;
|
||||
}
|
||||
|
||||
socketpool_socket_obj_t *common_hal_socketpool_socket(socketpool_socketpool_obj_t *self,
|
||||
socketpool_socketpool_addressfamily_t family, socketpool_socketpool_sock_t type) {
|
||||
if (family != SOCKETPOOL_AF_INET) {
|
||||
mp_raise_NotImplementedError(translate("Only IPv4 sockets supported"));
|
||||
}
|
||||
|
||||
socketpool_socket_obj_t *sock = m_new_obj_with_finaliser(socketpool_socket_obj_t);
|
||||
sock->base.type = &socketpool_socket_type;
|
||||
|
||||
socketpool_socket(self, family, type, sock);
|
||||
if (!socketpool_socket(self, family, type, sock) ||
|
||||
!register_open_socket(sock)) {
|
||||
mp_raise_RuntimeError(translate("Out of sockets"));
|
||||
}
|
||||
return sock;
|
||||
}
|
||||
|
||||
|
@ -75,7 +75,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socketpool_socket___exit___obj, 4, 4,
|
||||
//| creating a new socket of type SOCK_STREAM.
|
||||
//| Returns a tuple of (new_socket, remote_address)"""
|
||||
//|
|
||||
STATIC mp_obj_t socketpool_socket_accept(mp_obj_t self_in) {
|
||||
STATIC mp_obj_t _socketpool_socket_accept(mp_obj_t self_in) {
|
||||
socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
uint8_t ip[4];
|
||||
uint32_t port;
|
||||
@ -87,7 +87,7 @@ STATIC mp_obj_t socketpool_socket_accept(mp_obj_t self_in) {
|
||||
tuple_contents[1] = netutils_format_inet_addr(ip, port, NETUTILS_BIG);
|
||||
return mp_obj_new_tuple(2, tuple_contents);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(socketpool_socket_accept_obj, socketpool_socket_accept);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(socketpool_socket_accept_obj, _socketpool_socket_accept);
|
||||
|
||||
//| def bind(self, address: Tuple[str, int]) -> None:
|
||||
//| """Bind a socket to an address
|
||||
@ -120,12 +120,12 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_bind_obj, socketpool_socket_b
|
||||
//| def close(self) -> None:
|
||||
//| """Closes this Socket and makes its resources available to its SocketPool."""
|
||||
//|
|
||||
STATIC mp_obj_t socketpool_socket_close(mp_obj_t self_in) {
|
||||
STATIC mp_obj_t _socketpool_socket_close(mp_obj_t self_in) {
|
||||
socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
common_hal_socketpool_socket_close(self);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(socketpool_socket_close_obj, socketpool_socket_close);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(socketpool_socket_close_obj, _socketpool_socket_close);
|
||||
|
||||
//| def connect(self, address: Tuple[str, int]) -> None:
|
||||
//| """Connect a socket to a remote address
|
||||
@ -208,7 +208,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_recvfrom_into_obj, socketpool
|
||||
//| :param int bufsize: optionally, a maximum number of bytes to read."""
|
||||
//| ...
|
||||
//|
|
||||
STATIC mp_obj_t socketpool_socket_recv_into(size_t n_args, const mp_obj_t *args) {
|
||||
STATIC mp_obj_t _socketpool_socket_recv_into(size_t n_args, const mp_obj_t *args) {
|
||||
socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(args[0]);
|
||||
if (common_hal_socketpool_socket_get_closed(self)) {
|
||||
// Bad file number.
|
||||
@ -238,7 +238,7 @@ STATIC mp_obj_t socketpool_socket_recv_into(size_t n_args, const mp_obj_t *args)
|
||||
mp_int_t ret = common_hal_socketpool_socket_recv_into(self, (byte *)bufinfo.buf, len);
|
||||
return mp_obj_new_int_from_uint(ret);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socketpool_socket_recv_into_obj, 2, 3, socketpool_socket_recv_into);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socketpool_socket_recv_into_obj, 2, 3, _socketpool_socket_recv_into);
|
||||
|
||||
//| def send(self, bytes: ReadableBuffer) -> int:
|
||||
//| """Send some bytes to the connected remote address.
|
||||
@ -247,7 +247,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socketpool_socket_recv_into_obj, 2, 3
|
||||
//| :param ~bytes bytes: some bytes to send"""
|
||||
//| ...
|
||||
//|
|
||||
STATIC mp_obj_t socketpool_socket_send(mp_obj_t self_in, mp_obj_t buf_in) {
|
||||
STATIC mp_obj_t _socketpool_socket_send(mp_obj_t self_in, mp_obj_t buf_in) {
|
||||
socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
if (common_hal_socketpool_socket_get_closed(self)) {
|
||||
// Bad file number.
|
||||
@ -264,7 +264,7 @@ STATIC mp_obj_t socketpool_socket_send(mp_obj_t self_in, mp_obj_t buf_in) {
|
||||
}
|
||||
return mp_obj_new_int_from_uint(ret);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_send_obj, socketpool_socket_send);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_send_obj, _socketpool_socket_send);
|
||||
|
||||
//| def sendto(self, bytes: ReadableBuffer, address: Tuple[str, int]) -> int:
|
||||
//| """Send some bytes to a specific address.
|
||||
|
@ -47,4 +47,11 @@ mp_uint_t common_hal_socketpool_socket_sendto(socketpool_socket_obj_t *self,
|
||||
const char *host, size_t hostlen, uint32_t port, const uint8_t *buf, uint32_t len);
|
||||
void common_hal_socketpool_socket_settimeout(socketpool_socket_obj_t *self, uint32_t timeout_ms);
|
||||
|
||||
// Non-allocating versions for internal use.
|
||||
int socketpool_socket_accept(socketpool_socket_obj_t *self, uint8_t *ip, uint32_t *port);
|
||||
void socketpool_socket_close(socketpool_socket_obj_t *self);
|
||||
int socketpool_socket_send(socketpool_socket_obj_t *self, const uint8_t *buf, uint32_t len);
|
||||
int socketpool_socket_recv_into(socketpool_socket_obj_t *self,
|
||||
const uint8_t *buf, uint32_t len);
|
||||
|
||||
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_SOCKETPOOL_SOCKET_H
|
||||
|
@ -52,4 +52,10 @@ socketpool_socket_obj_t *common_hal_socketpool_socket(socketpool_socketpool_obj_
|
||||
mp_obj_t common_hal_socketpool_socketpool_gethostbyname(socketpool_socketpool_obj_t *self,
|
||||
const char *host);
|
||||
|
||||
// Non-allocating version for internal use. These sockets are not registered and, therefore, not
|
||||
// closed automatically.
|
||||
bool socketpool_socket(socketpool_socketpool_obj_t *self,
|
||||
socketpool_socketpool_addressfamily_t family, socketpool_socketpool_sock_t type,
|
||||
socketpool_socket_obj_t *sock);
|
||||
|
||||
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_SOCKETPOOL_SOCKETPOOL_H
|
||||
|
@ -30,6 +30,10 @@
|
||||
#include "supervisor/shared/translate/translate.h"
|
||||
#include "supervisor/shared/web_workflow/web_workflow.h"
|
||||
|
||||
#include "shared-bindings/socketpool/__init__.h"
|
||||
#include "shared-bindings/socketpool/Socket.h"
|
||||
#include "shared-bindings/socketpool/SocketPool.h"
|
||||
|
||||
#if CIRCUITPY_WIFI
|
||||
#include "shared-bindings/wifi/__init__.h"
|
||||
#endif
|
||||
@ -38,10 +42,35 @@
|
||||
#include "shared-module/dotenv/__init__.h"
|
||||
#endif
|
||||
|
||||
#include "esp_log.h"
|
||||
|
||||
static const char *TAG = "CP webserver";
|
||||
|
||||
enum request_state {
|
||||
STATE_METHOD,
|
||||
STATE_PATH,
|
||||
STATE_VERSION,
|
||||
STATE_HEADER_KEY,
|
||||
STATE_HEADER_VALUE,
|
||||
STATE_BODY
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
enum request_state state;
|
||||
char method[6];
|
||||
char path[256];
|
||||
uint32_t content_length;
|
||||
size_t offset;
|
||||
} _request;
|
||||
|
||||
static wifi_radio_error_t wifi_status = WIFI_RADIO_ERROR_NONE;
|
||||
|
||||
static socketpool_socketpool_obj_t pool;
|
||||
static socketpool_socket_obj_t listening;
|
||||
static socketpool_socket_obj_t active;
|
||||
|
||||
static _request active_request;
|
||||
|
||||
|
||||
void supervisor_web_workflow_status(void) {
|
||||
serial_write_compressed(translate("Wi-Fi: "));
|
||||
@ -66,6 +95,13 @@ void supervisor_web_workflow_status(void) {
|
||||
|
||||
void supervisor_start_web_workflow(void) {
|
||||
#if CIRCUITPY_WEB_WORKFLOW && CIRCUITPY_WIFI
|
||||
|
||||
if (common_hal_wifi_radio_get_enabled(&common_hal_wifi_radio_obj) &&
|
||||
wifi_radio_get_ipv4_address(&common_hal_wifi_radio_obj) != 0) {
|
||||
// Already started.
|
||||
return;
|
||||
}
|
||||
|
||||
char ssid[33];
|
||||
char password[64];
|
||||
mp_int_t ssid_len = 0;
|
||||
@ -102,11 +138,19 @@ void supervisor_start_web_workflow(void) {
|
||||
|
||||
listening.base.type = &socketpool_socket_type;
|
||||
socketpool_socket(&pool, SOCKETPOOL_AF_INET, SOCKETPOOL_SOCK_STREAM, &listening);
|
||||
common_hal_socketpool_socket_settimeout(&listening, 0);
|
||||
// Bind to any ip.
|
||||
// TODO: Make this port .env configurable.
|
||||
common_hal_socketpool_socket_bind(&listening, "", 0, 80);
|
||||
const char *ip = "192.168.1.94";
|
||||
common_hal_socketpool_socket_bind(&listening, ip, strlen(ip), 80);
|
||||
common_hal_socketpool_socket_listen(&listening, 1);
|
||||
|
||||
ESP_LOGW(TAG, "listening on socket %d", listening.num);
|
||||
|
||||
active.base.type = &socketpool_socket_type;
|
||||
active.num = -1;
|
||||
active.connected = false;
|
||||
|
||||
// Accept a connection and start parsing:
|
||||
// * HTTP method
|
||||
// * HTTP path
|
||||
@ -135,5 +179,105 @@ void supervisor_start_web_workflow(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
static void _process_request(socketpool_socket_obj_t *socket, _request *request) {
|
||||
bool more = true;
|
||||
bool error = false;
|
||||
uint8_t c;
|
||||
while (more && !error) {
|
||||
int len = socketpool_socket_recv_into(socket, &c, 1);
|
||||
if (len != 1) {
|
||||
if (len != -EAGAIN && len != -EBADF) {
|
||||
ESP_LOGW(TAG, "received %d", len);
|
||||
}
|
||||
more = false;
|
||||
break;
|
||||
}
|
||||
ESP_LOGI(TAG, "%c", c);
|
||||
switch (request->state) {
|
||||
case STATE_METHOD: {
|
||||
if (c == ' ') {
|
||||
request->method[request->offset] = '\0';
|
||||
request->offset = 0;
|
||||
request->state = STATE_PATH;
|
||||
} else if (request->offset > sizeof(request->method) - 1) {
|
||||
// Skip methods that are too long.
|
||||
} else {
|
||||
request->method[request->offset] = c;
|
||||
request->offset++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case STATE_PATH: {
|
||||
if (c == ' ') {
|
||||
request->path[request->offset] = '\0';
|
||||
request->offset = 0;
|
||||
ESP_LOGW(TAG, "Request %s %s", request->method, request->path);
|
||||
request->state = STATE_VERSION;
|
||||
error = true;
|
||||
} else if (request->offset > sizeof(request->path) - 1) {
|
||||
// Skip methods that are too long.
|
||||
} else {
|
||||
request->path[request->offset] = c;
|
||||
request->offset++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case STATE_VERSION:
|
||||
break;
|
||||
case STATE_HEADER_KEY:
|
||||
break;
|
||||
case STATE_HEADER_VALUE:
|
||||
break;
|
||||
case STATE_BODY:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (error) {
|
||||
const char *error_response = "HTTP/1.1 501 Not Implemented";
|
||||
int nodelay = 1;
|
||||
int err = lwip_setsockopt(socket->num, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof(nodelay));
|
||||
int sent = socketpool_socket_send(socket, (const uint8_t *)error_response, strlen(error_response));
|
||||
ESP_LOGW(TAG, "sent %d %d", sent, err);
|
||||
vTaskDelay(0);
|
||||
socketpool_socket_close(socket);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void supervisor_web_workflow_background(void) {
|
||||
// Otherwise, see if we have another socket to accept.
|
||||
if (!common_hal_socketpool_socket_get_connected(&active) &&
|
||||
!common_hal_socketpool_socket_get_closed(&listening) &&
|
||||
listening.num > 0) {
|
||||
uint32_t ip;
|
||||
uint32_t port;
|
||||
int newsoc = socketpool_socket_accept(&listening, (uint8_t *)&ip, &port);
|
||||
if (newsoc != -11) {
|
||||
ESP_LOGI(TAG, "newsoc %d", newsoc);
|
||||
}
|
||||
if (newsoc > 0) {
|
||||
ESP_LOGE(TAG, "Accepted socket %d", newsoc);
|
||||
// TODO: Don't do this because it uses the private struct layout.
|
||||
// Create the socket
|
||||
active.num = newsoc;
|
||||
active.pool = &pool;
|
||||
active.connected = true;
|
||||
|
||||
|
||||
common_hal_socketpool_socket_settimeout(&active, 0);
|
||||
|
||||
active_request.state = STATE_METHOD;
|
||||
active_request.offset = 0;
|
||||
|
||||
lwip_fcntl(newsoc, F_SETFL, O_NONBLOCK);
|
||||
}
|
||||
}
|
||||
|
||||
// If we have a request in progress, continue working on it.
|
||||
if (common_hal_socketpool_socket_get_connected(&active)) {
|
||||
_process_request(&active, &active_request);
|
||||
}
|
||||
}
|
||||
|
||||
void supervisor_stop_web_workflow(void) {
|
||||
}
|
||||
|
@ -28,8 +28,9 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
void supervisor_wifi_background(void);
|
||||
void supervisor_wifi_init(void);
|
||||
// This background function should be called repeatedly. It cannot be done based
|
||||
// on events.
|
||||
void supervisor_web_workflow_background(void);
|
||||
void supervisor_web_workflow_status(void);
|
||||
void supervisor_start_web_workflow(void);
|
||||
void supervisor_stop_web_workflow(void);
|
||||
|
Loading…
Reference in New Issue
Block a user