70
70
71
71
#define TCP_NODELAY TF_NODELAY
72
72
73
+ // Socket flags
74
+ #define MSG_PEEK 0x01
75
+ #define MSG_DONTWAIT 0x02
76
+
73
77
// For compatibilily with older lwIP versions.
74
78
#ifndef ip_set_option
75
79
#define ip_set_option (pcb , opt ) ((pcb)->so_options |= (opt))
@@ -673,13 +677,13 @@ static mp_uint_t lwip_raw_udp_send(lwip_socket_obj_t *socket, const byte *buf, m
673
677
}
674
678
675
679
// Helper function for recv/recvfrom to handle raw/UDP packets
676
- static mp_uint_t lwip_raw_udp_receive (lwip_socket_obj_t * socket , byte * buf , mp_uint_t len , ip_addr_t * ip , mp_uint_t * port , int * _errno ) {
680
+ static mp_uint_t lwip_raw_udp_receive (lwip_socket_obj_t * socket , byte * buf , mp_uint_t len , mp_int_t flags , ip_addr_t * ip , mp_uint_t * port , int * _errno ) {
677
681
678
682
lwip_incoming_packet_t * slot = & socket -> incoming .udp_raw .array [socket -> incoming .udp_raw .iget ];
679
683
680
684
if (slot -> pbuf == NULL ) {
681
- if ( socket -> timeout == 0 ) {
682
- // Non-blocking socket.
685
+ // Non-blocking socket or flag
686
+ if ( socket -> timeout == 0 || ( flags & MSG_DONTWAIT )) {
683
687
* _errno = MP_EAGAIN ;
684
688
return -1 ;
685
689
}
@@ -705,9 +709,11 @@ static mp_uint_t lwip_raw_udp_receive(lwip_socket_obj_t *socket, byte *buf, mp_u
705
709
MICROPY_PY_LWIP_ENTER
706
710
707
711
u16_t result = pbuf_copy_partial (p , buf , ((p -> tot_len > len ) ? len : p -> tot_len ), 0 );
708
- pbuf_free (p );
709
- slot -> pbuf = NULL ;
710
- socket -> incoming .udp_raw .iget = (socket -> incoming .udp_raw .iget + 1 ) % LWIP_INCOMING_PACKET_QUEUE_LEN ;
712
+ if ((flags & MSG_PEEK ) == 0 ) {
713
+ pbuf_free (p );
714
+ slot -> pbuf = NULL ;
715
+ socket -> incoming .udp_raw .iget = (socket -> incoming .udp_raw .iget + 1 ) % LWIP_INCOMING_PACKET_QUEUE_LEN ;
716
+ }
711
717
712
718
MICROPY_PY_LWIP_EXIT
713
719
@@ -815,14 +821,14 @@ static mp_uint_t lwip_tcp_send(lwip_socket_obj_t *socket, const byte *buf, mp_ui
815
821
}
816
822
817
823
// Helper function for recv/recvfrom to handle TCP packets
818
- static mp_uint_t lwip_tcp_receive (lwip_socket_obj_t * socket , byte * buf , mp_uint_t len , int * _errno ) {
824
+ static mp_uint_t lwip_tcp_receive (lwip_socket_obj_t * socket , byte * buf , mp_uint_t len , mp_int_t flags , int * _errno ) {
819
825
// Check for any pending errors
820
826
STREAM_ERROR_CHECK (socket );
821
827
822
828
if (socket -> incoming .tcp .pbuf == NULL ) {
823
829
824
- // Non-blocking socket
825
- if (socket -> timeout == 0 ) {
830
+ // Non-blocking socket or flag
831
+ if (socket -> timeout == 0 || ( flags & MSG_DONTWAIT ) ) {
826
832
if (socket -> state == STATE_PEER_CLOSED ) {
827
833
return 0 ;
828
834
}
@@ -867,19 +873,21 @@ static mp_uint_t lwip_tcp_receive(lwip_socket_obj_t *socket, byte *buf, mp_uint_
867
873
868
874
memcpy (buf , (byte * )p -> payload + socket -> recv_offset , len );
869
875
870
- remaining -= len ;
871
- if (remaining == 0 ) {
872
- socket -> incoming .tcp .pbuf = p -> next ;
873
- // If we don't ref here, free() will free the entire chain,
874
- // if we ref, it does what we need: frees 1st buf, and decrements
875
- // next buf's refcount back to 1.
876
- pbuf_ref (p -> next );
877
- pbuf_free (p );
878
- socket -> recv_offset = 0 ;
879
- } else {
880
- socket -> recv_offset += len ;
876
+ if ((flags & MSG_PEEK ) == 0 ) {
877
+ remaining -= len ;
878
+ if (remaining == 0 ) {
879
+ socket -> incoming .tcp .pbuf = p -> next ;
880
+ // If we don't ref here, free() will free the entire chain,
881
+ // if we ref, it does what we need: frees 1st buf, and decrements
882
+ // next buf's refcount back to 1.
883
+ pbuf_ref (p -> next );
884
+ pbuf_free (p );
885
+ socket -> recv_offset = 0 ;
886
+ } else {
887
+ socket -> recv_offset += len ;
888
+ }
889
+ tcp_recved (socket -> pcb .tcp , len );
881
890
}
882
- tcp_recved (socket -> pcb .tcp , len );
883
891
884
892
MICROPY_PY_LWIP_EXIT
885
893
@@ -1271,40 +1279,58 @@ static mp_obj_t lwip_socket_send(mp_obj_t self_in, mp_obj_t buf_in) {
1271
1279
}
1272
1280
static MP_DEFINE_CONST_FUN_OBJ_2 (lwip_socket_send_obj , lwip_socket_send ) ;
1273
1281
1274
- static mp_obj_t lwip_socket_recv (mp_obj_t self_in , mp_obj_t len_in ) {
1275
- lwip_socket_obj_t * socket = MP_OBJ_TO_PTR (self_in );
1282
+ // Common implementation for recv & recvfrom
1283
+ static mp_obj_t lwip_socket_recv_common (size_t n_args , const mp_obj_t * args , ip_addr_t * ip , mp_uint_t * port ) {
1284
+ lwip_socket_obj_t * socket = MP_OBJ_TO_PTR (args [0 ]);
1285
+ mp_int_t len = mp_obj_get_int (args [1 ]);
1286
+ mp_int_t flags = n_args > 2 ? mp_obj_get_int (args [2 ]) : 0 ;
1276
1287
int _errno ;
1288
+ vstr_t vstr ;
1289
+ mp_uint_t ret = 0 ;
1277
1290
1278
1291
lwip_socket_check_connected (socket );
1279
1292
1280
- mp_int_t len = mp_obj_get_int (len_in );
1281
- vstr_t vstr ;
1282
1293
vstr_init_len (& vstr , len );
1283
1294
1284
- mp_uint_t ret = 0 ;
1285
1295
switch (socket -> type ) {
1286
- case MOD_NETWORK_SOCK_STREAM : {
1287
- ret = lwip_tcp_receive (socket , (byte * )vstr .buf , len , & _errno );
1296
+ case MOD_NETWORK_SOCK_STREAM :
1297
+ if (ip != NULL ) {
1298
+ * ip = socket -> tcp_peer_addr ;
1299
+ * port = (mp_uint_t )socket -> tcp_peer_port ;
1300
+ }
1301
+ ret = lwip_tcp_receive (socket , (byte * )vstr .buf , len , flags , & _errno );
1288
1302
break ;
1289
- }
1290
1303
case MOD_NETWORK_SOCK_DGRAM :
1291
1304
#if MICROPY_PY_LWIP_SOCK_RAW
1292
1305
case MOD_NETWORK_SOCK_RAW :
1293
1306
#endif
1294
- ret = lwip_raw_udp_receive (socket , (byte * )vstr .buf , len , NULL , NULL , & _errno );
1307
+ ret = lwip_raw_udp_receive (socket , (byte * )vstr .buf , len , flags , ip , port , & _errno );
1295
1308
break ;
1296
1309
}
1297
1310
if (ret == -1 ) {
1298
1311
mp_raise_OSError (_errno );
1299
1312
}
1300
-
1301
1313
if (ret == 0 ) {
1302
1314
return mp_const_empty_bytes ;
1303
1315
}
1304
1316
vstr .len = ret ;
1305
1317
return mp_obj_new_bytes_from_vstr (& vstr );
1306
1318
}
1307
- static MP_DEFINE_CONST_FUN_OBJ_2 (lwip_socket_recv_obj , lwip_socket_recv ) ;
1319
+
1320
+ static mp_obj_t lwip_socket_recv (size_t n_args , const mp_obj_t * args ) {
1321
+ return lwip_socket_recv_common (n_args , args , NULL , NULL );
1322
+ }
1323
+ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (lwip_socket_recv_obj , 2 , 3 , lwip_socket_recv ) ;
1324
+
1325
+ static mp_obj_t lwip_socket_recvfrom (size_t n_args , const mp_obj_t * args ) {
1326
+ ip_addr_t ip ;
1327
+ mp_uint_t port ;
1328
+ mp_obj_t tuple [2 ];
1329
+ tuple [0 ] = lwip_socket_recv_common (n_args , args , & ip , & port );
1330
+ tuple [1 ] = lwip_format_inet_addr (& ip , port );
1331
+ return mp_obj_new_tuple (2 , tuple );
1332
+ }
1333
+ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (lwip_socket_recvfrom_obj , 2 , 3 , lwip_socket_recvfrom ) ;
1308
1334
1309
1335
static mp_obj_t lwip_socket_sendto (mp_obj_t self_in , mp_obj_t data_in , mp_obj_t addr_in ) {
1310
1336
lwip_socket_obj_t * socket = MP_OBJ_TO_PTR (self_in );
@@ -1339,50 +1365,6 @@ static mp_obj_t lwip_socket_sendto(mp_obj_t self_in, mp_obj_t data_in, mp_obj_t
1339
1365
}
1340
1366
static MP_DEFINE_CONST_FUN_OBJ_3 (lwip_socket_sendto_obj , lwip_socket_sendto ) ;
1341
1367
1342
- static mp_obj_t lwip_socket_recvfrom (mp_obj_t self_in , mp_obj_t len_in ) {
1343
- lwip_socket_obj_t * socket = MP_OBJ_TO_PTR (self_in );
1344
- int _errno ;
1345
-
1346
- lwip_socket_check_connected (socket );
1347
-
1348
- mp_int_t len = mp_obj_get_int (len_in );
1349
- vstr_t vstr ;
1350
- vstr_init_len (& vstr , len );
1351
- ip_addr_t ip ;
1352
- mp_uint_t port ;
1353
-
1354
- mp_uint_t ret = 0 ;
1355
- switch (socket -> type ) {
1356
- case MOD_NETWORK_SOCK_STREAM : {
1357
- ip = socket -> tcp_peer_addr ;
1358
- port = (mp_uint_t )socket -> tcp_peer_port ;
1359
- ret = lwip_tcp_receive (socket , (byte * )vstr .buf , len , & _errno );
1360
- break ;
1361
- }
1362
- case MOD_NETWORK_SOCK_DGRAM :
1363
- #if MICROPY_PY_LWIP_SOCK_RAW
1364
- case MOD_NETWORK_SOCK_RAW :
1365
- #endif
1366
- ret = lwip_raw_udp_receive (socket , (byte * )vstr .buf , len , & ip , & port , & _errno );
1367
- break ;
1368
- }
1369
- if (ret == -1 ) {
1370
- mp_raise_OSError (_errno );
1371
- }
1372
-
1373
- mp_obj_t tuple [2 ];
1374
- if (ret == 0 ) {
1375
- tuple [0 ] = mp_const_empty_bytes ;
1376
- } else {
1377
- vstr .len = ret ;
1378
- tuple [0 ] = mp_obj_new_bytes_from_vstr (& vstr );
1379
- }
1380
- tuple [1 ] = lwip_format_inet_addr (& ip , port );
1381
-
1382
- return mp_obj_new_tuple (2 , tuple );
1383
- }
1384
- static MP_DEFINE_CONST_FUN_OBJ_2 (lwip_socket_recvfrom_obj , lwip_socket_recvfrom ) ;
1385
-
1386
1368
static mp_obj_t lwip_socket_sendall (mp_obj_t self_in , mp_obj_t buf_in ) {
1387
1369
lwip_socket_obj_t * socket = MP_OBJ_TO_PTR (self_in );
1388
1370
lwip_socket_check_connected (socket );
@@ -1542,12 +1524,12 @@ static mp_uint_t lwip_socket_read(mp_obj_t self_in, void *buf, mp_uint_t size, i
1542
1524
1543
1525
switch (socket -> type ) {
1544
1526
case MOD_NETWORK_SOCK_STREAM :
1545
- return lwip_tcp_receive (socket , buf , size , errcode );
1527
+ return lwip_tcp_receive (socket , buf , size , 0 , errcode );
1546
1528
case MOD_NETWORK_SOCK_DGRAM :
1547
1529
#if MICROPY_PY_LWIP_SOCK_RAW
1548
1530
case MOD_NETWORK_SOCK_RAW :
1549
1531
#endif
1550
- return lwip_raw_udp_receive (socket , buf , size , NULL , NULL , errcode );
1532
+ return lwip_raw_udp_receive (socket , buf , size , 0 , NULL , NULL , errcode );
1551
1533
}
1552
1534
// Unreachable
1553
1535
return MP_STREAM_ERROR ;
@@ -1919,6 +1901,8 @@ static const mp_rom_map_elem_t mp_module_lwip_globals_table[] = {
1919
1901
1920
1902
{ MP_ROM_QSTR (MP_QSTR_IPPROTO_TCP ), MP_ROM_INT (IP_PROTO_TCP ) },
1921
1903
{ MP_ROM_QSTR (MP_QSTR_TCP_NODELAY ), MP_ROM_INT (TCP_NODELAY ) },
1904
+ { MP_ROM_QSTR (MP_QSTR_MSG_PEEK ), MP_ROM_INT (MSG_PEEK ) },
1905
+ { MP_ROM_QSTR (MP_QSTR_MSG_DONTWAIT ), MP_ROM_INT (MSG_DONTWAIT ) },
1922
1906
};
1923
1907
1924
1908
static MP_DEFINE_CONST_DICT (mp_module_lwip_globals , mp_module_lwip_globals_table ) ;
0 commit comments