Skip to content

Commit

Permalink
w60x: Enable webrepl.
Browse files Browse the repository at this point in the history
Signed-off-by: robert-hh <robert@hammelrath.com>
  • Loading branch information
robert-hh committed Jul 22, 2023
1 parent ed6dbd0 commit 4648bb1
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 1 deletion.
94 changes: 94 additions & 0 deletions ports/w60x/modules/modsocket.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,79 @@ typedef struct _socket_obj_t {
uint8_t proto;
bool peer_closed;
unsigned int retries;
#if MICROPY_PY_SOCKET_EVENTS
mp_obj_t events_callback;
struct _socket_obj_t *events_next;
#endif
} socket_obj_t;

void _socket_settimeout(socket_obj_t *sock, uint64_t timeout_ms);

#if MICROPY_PY_SOCKET_EVENTS
// Support for callbacks on asynchronous socket events (when socket becomes readable)

// This divisor is used to reduce the load on the system, so it doesn't poll sockets too often
#define USOCKET_EVENTS_DIVISOR (8)

STATIC uint8_t socket_events_divisor;
STATIC socket_obj_t *socket_events_head;

void socket_events_deinit(void) {
socket_events_head = NULL;
}

// Assumes the socket is not already in the linked list, and adds it
STATIC void socket_events_add(socket_obj_t *sock) {
sock->events_next = socket_events_head;
socket_events_head = sock;
}

// Assumes the socket is already in the linked list, and removes it
STATIC void socket_events_remove(socket_obj_t *sock) {
for (socket_obj_t **s = &socket_events_head;; s = &(*s)->events_next) {
if (*s == sock) {
*s = (*s)->events_next;
return;
}
}
}

// Polls all registered sockets for readability and calls their callback if they are readable
void socket_events_handler(void) {
if (socket_events_head == NULL) {
return;
}
if (--socket_events_divisor) {
return;
}
socket_events_divisor = USOCKET_EVENTS_DIVISOR;

fd_set rfds;
FD_ZERO(&rfds);
int max_fd = 0;

for (socket_obj_t *s = socket_events_head; s != NULL; s = s->events_next) {
FD_SET(s->fd, &rfds);
max_fd = MAX(max_fd, s->fd);
}

// Poll the sockets
struct timeval timeout = { .tv_sec = 0, .tv_usec = 0 };
int r = select(max_fd + 1, &rfds, NULL, NULL, &timeout);
if (r <= 0) {
return;
}

// Call the callbacks
for (socket_obj_t *s = socket_events_head; s != NULL; s = s->events_next) {
if (FD_ISSET(s->fd, &rfds)) {
mp_call_function_1_protected(s->events_callback, s);
}
}
}

#endif // MICROPY_PY_SOCKET_EVENTS

NORETURN static void exception_from_errno(int _errno) {
// Here we need to convert from lwip errno values to MicroPython's standard ones
if (_errno == EINPROGRESS) {
Expand Down Expand Up @@ -220,6 +289,25 @@ STATIC mp_obj_t socket_setsockopt(size_t n_args, const mp_obj_t *args) {
break;
}

#if MICROPY_PY_SOCKET_EVENTS
// level: SOL_SOCKET
// special "register callback" option
case 20: {
if (args[3] == mp_const_none) {
if (self->events_callback != MP_OBJ_NULL) {
socket_events_remove(self);
self->events_callback = MP_OBJ_NULL;
}
} else {
if (self->events_callback == MP_OBJ_NULL) {
socket_events_add(self);
}
self->events_callback = args[3];
}
break;
}
#endif

// level: IPPROTO_IP
case IP_ADD_MEMBERSHIP: {
mp_buffer_info_t bufinfo;
Expand Down Expand Up @@ -507,6 +595,12 @@ STATIC mp_uint_t socket_stream_ioctl(mp_obj_t self_in, mp_uint_t request, uintpt
return ret;
} else if (request == MP_STREAM_CLOSE) {
if (socket->fd >= 0) {
#if MICROPY_PY_SOCKET_EVENTS
if (socket->events_callback != MP_OBJ_NULL) {
socket_events_remove(socket);
socket->events_callback = MP_OBJ_NULL;
}
#endif
int ret = lwip_close(socket->fd);
if (ret != 0) {
*errcode = errno;
Expand Down
11 changes: 10 additions & 1 deletion ports/w60x/mpconfigport.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,9 @@
#define MICROPY_HW_SOFTSPI_MIN_DELAY (0)
#define MICROPY_HW_SOFTSPI_MAX_BAUDRATE (mp_hal_get_cpu_freq() / 200) // roughly
#define MICROPY_PY_CRYPTOLIB (MICROPY_PY_SSL)
#define MICROPY_PY_WEBREPL (0)
#define MICROPY_PY_WEBREPL (1)
#define MICROPY_PY_WEBSOCKET (1)
#define MICROPY_PY_SOCKET_EVENTS (1)
#define MICROPY_PY_ONEWIRE (1)
#define MICROPY_PY_MACHINE_BITSTREAM (1)
#define FFCONF_H "lib/oofatfs/ffconf.h"
Expand Down Expand Up @@ -109,11 +110,18 @@
#define MICROPY_BEGIN_ATOMIC_SECTION() tls_os_set_critical()
#define MICROPY_END_ATOMIC_SECTION(state) tls_os_release_critical(state)

#if MICROPY_PY_SOCKET_EVENTS
#define MICROPY_PY_SOCKET_EVENTS_HANDLER extern void socket_events_handler(void); socket_events_handler();
#else
#define MICROPY_PY_SOCKET_EVENTS_HANDLER
#endif

#if MICROPY_PY_THREAD
#define MICROPY_EVENT_POLL_HOOK \
do { \
extern void mp_handle_pending(bool raise_exc); \
mp_handle_pending(true); \
MICROPY_PY_SOCKET_EVENTS_HANDLER \
MP_THREAD_GIL_EXIT(); \
tls_os_time_delay(1); \
MP_THREAD_GIL_ENTER(); \
Expand All @@ -122,6 +130,7 @@
#define MICROPY_EVENT_POLL_HOOK \
do { \
extern void mp_handle_pending(bool raise_exc); \
MICROPY_PY_SOCKET_EVENTS_HANDLER \
mp_handle_pending(true); \
tls_os_time_delay(1); \
} while (0);
Expand Down

0 comments on commit 4648bb1

Please sign in to comment.