@@ -234,6 +234,7 @@ typedef struct _lwip_socket_obj_t {
234234 struct pbuf * pbuf ;
235235 struct tcp_pcb * connection ;
236236 } incoming ;
237+ mp_obj_t callback ;
237238 byte peer [4 ];
238239 mp_uint_t peer_port ;
239240 mp_uint_t timeout ;
@@ -261,6 +262,12 @@ static inline void poll_sockets(void) {
261262/*******************************************************************************/
262263// Callback functions for the lwIP raw API.
263264
265+ static inline void exec_user_callback (lwip_socket_obj_t * socket ) {
266+ if (socket -> callback != MP_OBJ_NULL ) {
267+ mp_call_function_1 (socket -> callback , socket );
268+ }
269+ }
270+
264271// Callback for incoming UDP packets. We simply stash the packet and the source address,
265272// in case we need it for recvfrom.
266273STATIC void _lwip_udp_incoming (void * arg , struct udp_pcb * upcb , struct pbuf * p , ip_addr_t * addr , u16_t port ) {
@@ -315,6 +322,7 @@ STATIC err_t _lwip_tcp_accept(void *arg, struct tcp_pcb *newpcb, err_t err) {
315322 return ERR_BUF ;
316323 } else {
317324 socket -> incoming .connection = newpcb ;
325+ exec_user_callback (socket );
318326 return ERR_OK ;
319327 }
320328}
@@ -327,12 +335,16 @@ STATIC err_t _lwip_tcp_recv(void *arg, struct tcp_pcb *tcpb, struct pbuf *p, err
327335 // Other side has closed connection.
328336 DEBUG_printf ("_lwip_tcp_recv[%p]: other side closed connection\n" , socket );
329337 socket -> state = STATE_PEER_CLOSED ;
338+ exec_user_callback (socket );
330339 return ERR_OK ;
331340 } else if (socket -> incoming .pbuf != NULL ) {
332341 // No room in the inn, let LWIP know it's still responsible for delivery later
333342 return ERR_BUF ;
334343 }
335344 socket -> incoming .pbuf = p ;
345+
346+ exec_user_callback (socket );
347+
336348 return ERR_OK ;
337349}
338350
@@ -542,6 +554,7 @@ STATIC mp_obj_t lwip_socket_make_new(const mp_obj_type_t *type, mp_uint_t n_args
542554 socket -> base .type = (mp_obj_t )& lwip_socket_type ;
543555 socket -> domain = MOD_NETWORK_AF_INET ;
544556 socket -> type = MOD_NETWORK_SOCK_STREAM ;
557+ socket -> callback = MP_OBJ_NULL ;
545558 if (n_args >= 1 ) {
546559 socket -> domain = mp_obj_get_int (args [0 ]);
547560 if (n_args >= 2 ) {
@@ -717,6 +730,7 @@ STATIC mp_obj_t lwip_socket_accept(mp_obj_t self_in) {
717730 socket2 -> timeout = socket -> timeout ;
718731 socket2 -> state = STATE_CONNECTED ;
719732 socket2 -> leftover_count = 0 ;
733+ socket2 -> callback = MP_OBJ_NULL ;
720734 tcp_arg (socket2 -> pcb .tcp , (void * )socket2 );
721735 tcp_err (socket2 -> pcb .tcp , _lwip_tcp_error );
722736 tcp_recv (socket2 -> pcb .tcp , _lwip_tcp_recv );
@@ -978,8 +992,20 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(lwip_socket_setblocking_obj, lwip_socket_setblo
978992STATIC mp_obj_t lwip_socket_setsockopt (mp_uint_t n_args , const mp_obj_t * args ) {
979993 (void )n_args ; // always 4
980994 lwip_socket_obj_t * socket = args [0 ];
995+
996+ int opt = mp_obj_get_int (args [2 ]);
997+ if (opt == 20 ) {
998+ if (args [3 ] == mp_const_none ) {
999+ socket -> callback = MP_OBJ_NULL ;
1000+ } else {
1001+ socket -> callback = args [3 ];
1002+ }
1003+ return mp_const_none ;
1004+ }
1005+
1006+ // Integer options
9811007 mp_int_t val = mp_obj_get_int (args [3 ]);
982- switch (mp_obj_get_int ( args [ 2 ]) ) {
1008+ switch (opt ) {
9831009 case SOF_REUSEADDR :
9841010 // Options are common for UDP and TCP pcb's.
9851011 if (val ) {
0 commit comments