Skip to content
This repository was archived by the owner on Sep 6, 2023. It is now read-only.

Commit f1f9fc7

Browse files
committed
esp32/modsocket: Add support for DGRAM and RAW, and sendto/recvfrom.
1 parent 478bbec commit f1f9fc7

File tree

1 file changed

+67
-4
lines changed

1 file changed

+67
-4
lines changed

esp32/modsocket.c

Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,38 @@ STATIC mp_obj_t socket_recv(mp_obj_t self_in, mp_obj_t len_in) {
217217
}
218218
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_recv_obj, socket_recv);
219219

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+
220252
STATIC mp_obj_t socket_send(const mp_obj_t arg0, const mp_obj_t arg1) {
221253
socket_obj_t *self = MP_OBJ_TO_PTR(arg0);
222254
mp_uint_t datalen;
@@ -244,6 +276,29 @@ STATIC mp_obj_t socket_sendall(const mp_obj_t arg0, const mp_obj_t arg1) {
244276
}
245277
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_sendall_obj, socket_sendall);
246278

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+
247302
STATIC mp_obj_t socket_fileno(const mp_obj_t arg0) {
248303
socket_obj_t *self = MP_OBJ_TO_PTR(arg0);
249304
return mp_obj_new_int(self->fd);
@@ -315,9 +370,9 @@ STATIC const mp_map_elem_t socket_locals_dict_table[] = {
315370
{ MP_OBJ_NEW_QSTR(MP_QSTR_connect), (mp_obj_t)&socket_connect_obj },
316371
{ MP_OBJ_NEW_QSTR(MP_QSTR_send), (mp_obj_t)&socket_send_obj },
317372
{ 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 },
318374
{ 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 },
321376
{ MP_OBJ_NEW_QSTR(MP_QSTR_setsockopt), mp_const_none },
322377
{ MP_OBJ_NEW_QSTR(MP_QSTR_settimeout), (mp_obj_t)&socket_settimeout_obj },
323378
{ 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 = {
344399
};
345400

346401
STATIC mp_obj_t get_socket(mp_uint_t n_args, const mp_obj_t *args) {
347-
// XXX TODO support for UDP and RAW.
348402
socket_obj_t *sock = m_new_obj_with_finaliser(socket_obj_t);
349403
sock->base.type = &socket_type;
350404
sock->domain = AF_INET;
351405
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+
}
353416
sock->fd = lwip_socket(sock->domain, sock->type, sock->proto);
354417
if (sock->fd < 0) {
355418
exception_from_errno(errno);

0 commit comments

Comments
 (0)