@@ -217,6 +217,38 @@ STATIC mp_obj_t socket_recv(mp_obj_t self_in, mp_obj_t len_in) {
217
217
}
218
218
STATIC MP_DEFINE_CONST_FUN_OBJ_2 (socket_recv_obj , socket_recv );
219
219
220
+ STATIC mp_obj_t socket_recvfrom (mp_obj_t self_in , mp_obj_t len_in ) {
221
+ socket_obj_t * self = MP_OBJ_TO_PTR (self_in );
222
+
223
+ // create the destination buffer
224
+ mp_int_t len = mp_obj_get_int (len_in );
225
+ vstr_t vstr ;
226
+ vstr_init_len (& vstr , len );
227
+
228
+ // do the receive
229
+ struct sockaddr from ;
230
+ socklen_t fromlen = sizeof (from );
231
+ int ret = lwip_recvfrom_r (self -> fd , vstr .buf , len , 0 , & from , & fromlen );
232
+ if (ret == -1 ) {
233
+ exception_from_errno (errno );
234
+ }
235
+
236
+ // make the return value
237
+ mp_obj_t tuple [2 ];
238
+ if (ret == 0 ) {
239
+ tuple [0 ] = mp_const_empty_bytes ;
240
+ } else {
241
+ vstr .len = ret ;
242
+ tuple [0 ] = mp_obj_new_str_from_vstr (& mp_type_bytes , & vstr );
243
+ }
244
+ uint8_t * ip = (uint8_t * )& ((struct sockaddr_in * )& from )-> sin_addr ;
245
+ mp_uint_t port = lwip_ntohs (((struct sockaddr_in * )& from )-> sin_port );
246
+ tuple [1 ] = netutils_format_inet_addr (ip , port , NETUTILS_BIG );
247
+
248
+ return mp_obj_new_tuple (2 , tuple );
249
+ }
250
+ STATIC MP_DEFINE_CONST_FUN_OBJ_2 (socket_recvfrom_obj , socket_recvfrom );
251
+
220
252
STATIC mp_obj_t socket_send (const mp_obj_t arg0 , const mp_obj_t arg1 ) {
221
253
socket_obj_t * self = MP_OBJ_TO_PTR (arg0 );
222
254
mp_uint_t datalen ;
@@ -244,6 +276,29 @@ STATIC mp_obj_t socket_sendall(const mp_obj_t arg0, const mp_obj_t arg1) {
244
276
}
245
277
STATIC MP_DEFINE_CONST_FUN_OBJ_2 (socket_sendall_obj , socket_sendall );
246
278
279
+ STATIC mp_obj_t socket_sendto (mp_obj_t self_in , mp_obj_t data_in , mp_obj_t addr_in ) {
280
+ socket_obj_t * self = MP_OBJ_TO_PTR (self_in );
281
+
282
+ // get the buffer to send
283
+ mp_buffer_info_t bufinfo ;
284
+ mp_get_buffer_raise (data_in , & bufinfo , MP_BUFFER_READ );
285
+
286
+ // create the destination address
287
+ struct sockaddr_in to ;
288
+ to .sin_len = sizeof (to );
289
+ to .sin_family = AF_INET ;
290
+ to .sin_port = lwip_htons (netutils_parse_inet_addr (addr_in , (uint8_t * )& to .sin_addr , NETUTILS_BIG ));
291
+
292
+ // send the data
293
+ int ret = lwip_sendto_r (self -> fd , bufinfo .buf , bufinfo .len , 0 , (struct sockaddr * )& to , sizeof (to ));
294
+ if (ret == -1 ) {
295
+ exception_from_errno (errno );
296
+ }
297
+
298
+ return mp_obj_new_int_from_uint (ret );
299
+ }
300
+ STATIC MP_DEFINE_CONST_FUN_OBJ_3 (socket_sendto_obj , socket_sendto );
301
+
247
302
STATIC mp_obj_t socket_fileno (const mp_obj_t arg0 ) {
248
303
socket_obj_t * self = MP_OBJ_TO_PTR (arg0 );
249
304
return mp_obj_new_int (self -> fd );
@@ -315,9 +370,9 @@ STATIC const mp_map_elem_t socket_locals_dict_table[] = {
315
370
{ MP_OBJ_NEW_QSTR (MP_QSTR_connect ), (mp_obj_t )& socket_connect_obj },
316
371
{ MP_OBJ_NEW_QSTR (MP_QSTR_send ), (mp_obj_t )& socket_send_obj },
317
372
{ MP_OBJ_NEW_QSTR (MP_QSTR_sendall ), (mp_obj_t )& socket_sendall_obj },
373
+ { MP_OBJ_NEW_QSTR (MP_QSTR_sendto ), (mp_obj_t )& socket_sendto_obj },
318
374
{ MP_OBJ_NEW_QSTR (MP_QSTR_recv ), (mp_obj_t )& socket_recv_obj },
319
- { MP_OBJ_NEW_QSTR (MP_QSTR_sendto ), mp_const_none },
320
- { MP_OBJ_NEW_QSTR (MP_QSTR_recvfrom ), mp_const_none },
375
+ { MP_OBJ_NEW_QSTR (MP_QSTR_recvfrom ), (mp_obj_t )& socket_recvfrom_obj },
321
376
{ MP_OBJ_NEW_QSTR (MP_QSTR_setsockopt ), mp_const_none },
322
377
{ MP_OBJ_NEW_QSTR (MP_QSTR_settimeout ), (mp_obj_t )& socket_settimeout_obj },
323
378
{ MP_OBJ_NEW_QSTR (MP_QSTR_setblocking ), (mp_obj_t )& socket_setblocking_obj },
@@ -344,12 +399,20 @@ STATIC const mp_obj_type_t socket_type = {
344
399
};
345
400
346
401
STATIC mp_obj_t get_socket (mp_uint_t n_args , const mp_obj_t * args ) {
347
- // XXX TODO support for UDP and RAW.
348
402
socket_obj_t * sock = m_new_obj_with_finaliser (socket_obj_t );
349
403
sock -> base .type = & socket_type ;
350
404
sock -> domain = AF_INET ;
351
405
sock -> type = SOCK_STREAM ;
352
- sock -> proto = IPPROTO_TCP ;
406
+ sock -> proto = 0 ;
407
+ if (n_args > 0 ) {
408
+ sock -> domain = mp_obj_get_int (args [0 ]);
409
+ if (n_args > 1 ) {
410
+ sock -> type = mp_obj_get_int (args [1 ]);
411
+ if (n_args > 2 ) {
412
+ sock -> proto = mp_obj_get_int (args [2 ]);
413
+ }
414
+ }
415
+ }
353
416
sock -> fd = lwip_socket (sock -> domain , sock -> type , sock -> proto );
354
417
if (sock -> fd < 0 ) {
355
418
exception_from_errno (errno );
0 commit comments