summaryrefslogtreecommitdiffstatshomepage
path: root/extmod/modlwip.c
diff options
context:
space:
mode:
Diffstat (limited to 'extmod/modlwip.c')
-rw-r--r--extmod/modlwip.c132
1 files changed, 74 insertions, 58 deletions
diff --git a/extmod/modlwip.c b/extmod/modlwip.c
index 090e1005a8..cb7cc6596f 100644
--- a/extmod/modlwip.c
+++ b/extmod/modlwip.c
@@ -26,13 +26,13 @@
*/
#include <string.h>
-#include <errno.h>
#include <stdio.h>
#include "py/nlr.h"
#include "py/objlist.h"
#include "py/runtime.h"
#include "py/stream.h"
+#include "py/mperrno.h"
#include "py/mphal.h"
#include "netutils.h"
@@ -172,45 +172,45 @@ STATIC const mp_obj_type_t lwip_slip_type = {
// investigate in more detail.
#if LWIP_VERSION < 0x01040100
static const int error_lookup_table[] = {
- 0, /* ERR_OK 0 No error, everything OK. */
- ENOMEM, /* ERR_MEM -1 Out of memory error. */
- ENOBUFS, /* ERR_BUF -2 Buffer error. */
- EWOULDBLOCK, /* ERR_TIMEOUT -3 Timeout */
- EHOSTUNREACH, /* ERR_RTE -4 Routing problem. */
- EINPROGRESS, /* ERR_INPROGRESS -5 Operation in progress */
- EINVAL, /* ERR_VAL -6 Illegal value. */
- EWOULDBLOCK, /* ERR_WOULDBLOCK -7 Operation would block. */
-
- ECONNABORTED, /* ERR_ABRT -8 Connection aborted. */
- ECONNRESET, /* ERR_RST -9 Connection reset. */
- ENOTCONN, /* ERR_CLSD -10 Connection closed. */
- ENOTCONN, /* ERR_CONN -11 Not connected. */
- EIO, /* ERR_ARG -12 Illegal argument. */
- EADDRINUSE, /* ERR_USE -13 Address in use. */
- -1, /* ERR_IF -14 Low-level netif error */
- EALREADY, /* ERR_ISCONN -15 Already connected. */
- EBADF, /* _ERR_BADF -16 Closed socket (null pcb) */
+ 0, /* ERR_OK 0 No error, everything OK. */
+ MP_ENOMEM, /* ERR_MEM -1 Out of memory error. */
+ MP_ENOBUFS, /* ERR_BUF -2 Buffer error. */
+ MP_EWOULDBLOCK, /* ERR_TIMEOUT -3 Timeout */
+ MP_EHOSTUNREACH, /* ERR_RTE -4 Routing problem. */
+ MP_EINPROGRESS, /* ERR_INPROGRESS -5 Operation in progress */
+ MP_EINVAL, /* ERR_VAL -6 Illegal value. */
+ MP_EWOULDBLOCK, /* ERR_WOULDBLOCK -7 Operation would block. */
+
+ MP_ECONNABORTED, /* ERR_ABRT -8 Connection aborted. */
+ MP_ECONNRESET, /* ERR_RST -9 Connection reset. */
+ MP_ENOTCONN, /* ERR_CLSD -10 Connection closed. */
+ MP_ENOTCONN, /* ERR_CONN -11 Not connected. */
+ MP_EIO, /* ERR_ARG -12 Illegal argument. */
+ MP_EADDRINUSE, /* ERR_USE -13 Address in use. */
+ -1, /* ERR_IF -14 Low-level netif error */
+ MP_EALREADY, /* ERR_ISCONN -15 Already connected. */
+ MP_EBADF, /* _ERR_BADF -16 Closed socket (null pcb) */
};
#else
static const int error_lookup_table[] = {
- 0, /* ERR_OK 0 No error, everything OK. */
- ENOMEM, /* ERR_MEM -1 Out of memory error. */
- ENOBUFS, /* ERR_BUF -2 Buffer error. */
- EWOULDBLOCK, /* ERR_TIMEOUT -3 Timeout */
- EHOSTUNREACH, /* ERR_RTE -4 Routing problem. */
- EINPROGRESS, /* ERR_INPROGRESS -5 Operation in progress */
- EINVAL, /* ERR_VAL -6 Illegal value. */
- EWOULDBLOCK, /* ERR_WOULDBLOCK -7 Operation would block. */
-
- EADDRINUSE, /* ERR_USE -8 Address in use. */
- EALREADY, /* ERR_ISCONN -9 Already connected. */
- ECONNABORTED, /* ERR_ABRT -10 Connection aborted. */
- ECONNRESET, /* ERR_RST -11 Connection reset. */
- ENOTCONN, /* ERR_CLSD -12 Connection closed. */
- ENOTCONN, /* ERR_CONN -13 Not connected. */
- EIO, /* ERR_ARG -14 Illegal argument. */
- -1, /* ERR_IF -15 Low-level netif error */
- EBADF, /* _ERR_BADF -16 Closed socket (null pcb) */
+ 0, /* ERR_OK 0 No error, everything OK. */
+ MP_ENOMEM, /* ERR_MEM -1 Out of memory error. */
+ MP_ENOBUFS, /* ERR_BUF -2 Buffer error. */
+ MP_EWOULDBLOCK, /* ERR_TIMEOUT -3 Timeout */
+ MP_EHOSTUNREACH, /* ERR_RTE -4 Routing problem. */
+ MP_EINPROGRESS, /* ERR_INPROGRESS -5 Operation in progress */
+ MP_EINVAL, /* ERR_VAL -6 Illegal value. */
+ MP_EWOULDBLOCK, /* ERR_WOULDBLOCK -7 Operation would block. */
+
+ MP_EADDRINUSE, /* ERR_USE -8 Address in use. */
+ MP_EALREADY, /* ERR_ISCONN -9 Already connected. */
+ MP_ECONNABORTED, /* ERR_ABRT -10 Connection aborted. */
+ MP_ECONNRESET, /* ERR_RST -11 Connection reset. */
+ MP_ENOTCONN, /* ERR_CLSD -12 Connection closed. */
+ MP_ENOTCONN, /* ERR_CONN -13 Not connected. */
+ MP_EIO, /* ERR_ARG -14 Illegal argument. */
+ -1, /* ERR_IF -15 Low-level netif error */
+ MP_EBADF, /* _ERR_BADF -16 Closed socket (null pcb) */
};
#endif
@@ -311,6 +311,17 @@ STATIC err_t _lwip_tcp_recv_unaccepted(void *arg, struct tcp_pcb *pcb, struct pb
return ERR_BUF;
}
+// "Poll" (idle) callback to be called ASAP after accept callback
+// to execute Python callback function, as it can't be executed
+// from accept callback itself.
+STATIC err_t _lwip_tcp_accept_finished(void *arg, struct tcp_pcb *pcb)
+{
+ lwip_socket_obj_t *socket = (lwip_socket_obj_t*)arg;
+ tcp_poll(pcb, NULL, 0);
+ exec_user_callback(socket);
+ return ERR_OK;
+}
+
// Callback for incoming tcp connections.
STATIC err_t _lwip_tcp_accept(void *arg, struct tcp_pcb *newpcb, err_t err) {
lwip_socket_obj_t *socket = (lwip_socket_obj_t*)arg;
@@ -323,7 +334,12 @@ STATIC err_t _lwip_tcp_accept(void *arg, struct tcp_pcb *newpcb, err_t err) {
return ERR_BUF;
} else {
socket->incoming.connection = newpcb;
- exec_user_callback(socket);
+ if (socket->callback != MP_OBJ_NULL) {
+ // Schedule accept callback to be called when lwIP is done
+ // with processing this incoming connection on its side and
+ // is idle.
+ tcp_poll(newpcb, _lwip_tcp_accept_finished, 1);
+ }
return ERR_OK;
}
}
@@ -363,7 +379,7 @@ STATIC mp_uint_t lwip_udp_send(lwip_socket_obj_t *socket, const byte *buf, mp_ui
// FIXME: maybe PBUF_ROM?
struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM);
if (p == NULL) {
- *_errno = ENOMEM;
+ *_errno = MP_ENOMEM;
return -1;
}
@@ -401,7 +417,7 @@ STATIC mp_uint_t lwip_udp_receive(lwip_socket_obj_t *socket, byte *buf, mp_uint_
if (socket->incoming.pbuf != NULL) break;
}
if (socket->incoming.pbuf == NULL) {
- *_errno = ETIMEDOUT;
+ *_errno = MP_ETIMEDOUT;
return -1;
}
} else {
@@ -444,7 +460,7 @@ STATIC mp_uint_t lwip_tcp_send(lwip_socket_obj_t *socket, const byte *buf, mp_ui
if (available == 0) {
// Non-blocking socket
if (socket->timeout == 0) {
- *_errno = EAGAIN;
+ *_errno = MP_EAGAIN;
return MP_STREAM_ERROR;
}
@@ -457,7 +473,7 @@ STATIC mp_uint_t lwip_tcp_send(lwip_socket_obj_t *socket, const byte *buf, mp_ui
// Avoid sending too small packets, so wait until at least 16 bytes available
while (socket->state >= STATE_CONNECTED && (available = tcp_sndbuf(socket->pcb.tcp)) < 16) {
if (socket->timeout != -1 && mp_hal_ticks_ms() - start > socket->timeout) {
- *_errno = ETIMEDOUT;
+ *_errno = MP_ETIMEDOUT;
return MP_STREAM_ERROR;
}
poll_sockets();
@@ -491,14 +507,14 @@ STATIC mp_uint_t lwip_tcp_receive(lwip_socket_obj_t *socket, byte *buf, mp_uint_
if (socket->state == STATE_PEER_CLOSED) {
return 0;
}
- *_errno = EAGAIN;
+ *_errno = MP_EAGAIN;
return -1;
}
mp_uint_t start = mp_hal_ticks_ms();
while (socket->state == STATE_CONNECTED && socket->incoming.pbuf == NULL) {
if (socket->timeout != -1 && mp_hal_ticks_ms() - start > socket->timeout) {
- *_errno = ETIMEDOUT;
+ *_errno = MP_ETIMEDOUT;
return -1;
}
poll_sockets();
@@ -570,11 +586,11 @@ STATIC mp_obj_t lwip_socket_make_new(const mp_obj_type_t *type, mp_uint_t n_args
case MOD_NETWORK_SOCK_STREAM: socket->pcb.tcp = tcp_new(); break;
case MOD_NETWORK_SOCK_DGRAM: socket->pcb.udp = udp_new(); break;
//case MOD_NETWORK_SOCK_RAW: socket->pcb.raw = raw_new(); break;
- default: nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EINVAL)));
+ default: nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_EINVAL)));
}
if (socket->pcb.tcp == NULL) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(ENOMEM)));
+ nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_ENOMEM)));
}
switch (socket->type) {
@@ -670,15 +686,15 @@ STATIC mp_obj_t lwip_socket_listen(mp_obj_t self_in, mp_obj_t backlog_in) {
mp_int_t backlog = mp_obj_get_int(backlog_in);
if (socket->pcb.tcp == NULL) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EBADF)));
+ nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_EBADF)));
}
if (socket->type != MOD_NETWORK_SOCK_STREAM) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EOPNOTSUPP)));
+ nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_EOPNOTSUPP)));
}
struct tcp_pcb *new_pcb = tcp_listen_with_backlog(socket->pcb.tcp, (u8_t)backlog);
if (new_pcb == NULL) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(ENOMEM)));
+ nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_ENOMEM)));
}
socket->pcb.tcp = new_pcb;
tcp_accept(new_pcb, _lwip_tcp_accept);
@@ -691,15 +707,15 @@ STATIC mp_obj_t lwip_socket_accept(mp_obj_t self_in) {
lwip_socket_obj_t *socket = self_in;
if (socket->pcb.tcp == NULL) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EBADF)));
+ nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_EBADF)));
}
if (socket->type != MOD_NETWORK_SOCK_STREAM) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EOPNOTSUPP)));
+ nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_EOPNOTSUPP)));
}
// I need to do this because "tcp_accepted", later, is a macro.
struct tcp_pcb *listener = socket->pcb.tcp;
if (listener->state != LISTEN) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EINVAL)));
+ nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_EINVAL)));
}
// accept incoming connection
@@ -710,7 +726,7 @@ STATIC mp_obj_t lwip_socket_accept(mp_obj_t self_in) {
if (socket->incoming.connection != NULL) break;
}
if (socket->incoming.connection == NULL) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(ETIMEDOUT)));
+ nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_ETIMEDOUT)));
}
} else {
while (socket->incoming.connection == NULL) {
@@ -757,7 +773,7 @@ STATIC mp_obj_t lwip_socket_connect(mp_obj_t self_in, mp_obj_t addr_in) {
lwip_socket_obj_t *socket = self_in;
if (socket->pcb.tcp == NULL) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EBADF)));
+ nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_EBADF)));
}
// get address
@@ -772,9 +788,9 @@ STATIC mp_obj_t lwip_socket_connect(mp_obj_t self_in, mp_obj_t addr_in) {
case MOD_NETWORK_SOCK_STREAM: {
if (socket->state != STATE_NEW) {
if (socket->state == STATE_CONNECTED) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EALREADY)));
+ nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_EALREADY)));
} else {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EINPROGRESS)));
+ nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_EINPROGRESS)));
}
}
// Register our recieve callback.
@@ -794,7 +810,7 @@ STATIC mp_obj_t lwip_socket_connect(mp_obj_t self_in, mp_obj_t addr_in) {
if (socket->state != STATE_CONNECTING) break;
}
if (socket->state == STATE_CONNECTING) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(ETIMEDOUT)));
+ nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_ETIMEDOUT)));
}
} else {
while (socket->state == STATE_CONNECTING) {
@@ -982,7 +998,7 @@ STATIC mp_obj_t lwip_socket_sendall(mp_obj_t self_in, mp_obj_t buf_in) {
// most useful behavior is: check whether we will be able to send all of input
// data without EAGAIN, and if won't be, raise it without sending any.
if (bufinfo.len > tcp_sndbuf(socket->pcb.tcp)) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EAGAIN)));
+ nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_EAGAIN)));
}
}
// TODO: In CPython3.5, socket timeout should apply to the