@ -234,6 +234,7 @@ typedef struct _lwip_socket_obj_t {
struct pbuf * pbuf ;
struct tcp_pcb * connection ;
} incoming ;
mp_obj_t callback ;
byte peer [ 4 ] ;
mp_uint_t peer_port ;
mp_uint_t timeout ;
@ -261,6 +262,12 @@ static inline void poll_sockets(void) {
/*******************************************************************************/
// Callback functions for the lwIP raw API.
static inline void exec_user_callback ( lwip_socket_obj_t * socket ) {
if ( socket - > callback ! = MP_OBJ_NULL ) {
mp_call_function_1 ( socket - > callback , socket ) ;
}
}
// Callback for incoming UDP packets. We simply stash the packet and the source address,
// in case we need it for recvfrom.
STATIC 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) {
return ERR_BUF ;
} else {
socket - > incoming . connection = newpcb ;
exec_user_callback ( socket ) ;
return ERR_OK ;
}
}
@ -327,12 +335,16 @@ STATIC err_t _lwip_tcp_recv(void *arg, struct tcp_pcb *tcpb, struct pbuf *p, err
// Other side has closed connection.
DEBUG_printf ( " _lwip_tcp_recv[%p]: other side closed connection \n " , socket ) ;
socket - > state = STATE_PEER_CLOSED ;
exec_user_callback ( socket ) ;
return ERR_OK ;
} else if ( socket - > incoming . pbuf ! = NULL ) {
// No room in the inn, let LWIP know it's still responsible for delivery later
return ERR_BUF ;
}
socket - > incoming . pbuf = p ;
exec_user_callback ( socket ) ;
return ERR_OK ;
}
@ -542,6 +554,7 @@ STATIC mp_obj_t lwip_socket_make_new(const mp_obj_type_t *type, mp_uint_t n_args
socket - > base . type = ( mp_obj_t ) & lwip_socket_type ;
socket - > domain = MOD_NETWORK_AF_INET ;
socket - > type = MOD_NETWORK_SOCK_STREAM ;
socket - > callback = MP_OBJ_NULL ;
if ( n_args > = 1 ) {
socket - > domain = mp_obj_get_int ( args [ 0 ] ) ;
if ( n_args > = 2 ) {
@ -717,6 +730,7 @@ STATIC mp_obj_t lwip_socket_accept(mp_obj_t self_in) {
socket2 - > timeout = socket - > timeout ;
socket2 - > state = STATE_CONNECTED ;
socket2 - > leftover_count = 0 ;
socket2 - > callback = MP_OBJ_NULL ;
tcp_arg ( socket2 - > pcb . tcp , ( void * ) socket2 ) ;
tcp_err ( socket2 - > pcb . tcp , _lwip_tcp_error ) ;
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
STATIC mp_obj_t lwip_socket_setsockopt ( mp_uint_t n_args , const mp_obj_t * args ) {
( void ) n_args ; // always 4
lwip_socket_obj_t * socket = args [ 0 ] ;
int opt = mp_obj_get_int ( args [ 2 ] ) ;
if ( opt = = 20 ) {
if ( args [ 3 ] = = mp_const_none ) {
socket - > callback = MP_OBJ_NULL ;
} else {
socket - > callback = args [ 3 ] ;
}
return mp_const_none ;
}
// Integer options
mp_int_t val = mp_obj_get_int ( args [ 3 ] ) ;
switch ( mp_obj_get_int ( args [ 2 ] ) ) {
switch ( opt ) {
case SOF_REUSEADDR :
// Options are common for UDP and TCP pcb's.
if ( val ) {