summaryrefslogtreecommitdiff
path: root/shared-bindings/socket
diff options
context:
space:
mode:
authorBenjamin Shockley <benjaminshockley@hotmail.com>2020-08-20 13:48:15 -0500
committerGitHub <noreply@github.com>2020-08-20 13:48:15 -0500
commit0084f0af24e4e219bc040c52ee723959423de6e2 (patch)
tree1aebdb362f08bf6417caa87836e3e4e739afc964 /shared-bindings/socket
parent9aebe2f1efc99871fcf283c304e3a8700050d736 (diff)
parent4d7b9cde33934a44c4c905a49d2f831339fc8bd2 (diff)
Merge pull request #2 from adafruit/master
Master
Diffstat (limited to 'shared-bindings/socket')
-rw-r--r--shared-bindings/socket/__init__.c203
1 files changed, 122 insertions, 81 deletions
diff --git a/shared-bindings/socket/__init__.c b/shared-bindings/socket/__init__.c
index d860c40c8..19c4850cd 100644
--- a/shared-bindings/socket/__init__.c
+++ b/shared-bindings/socket/__init__.c
@@ -37,31 +37,26 @@
#include "shared-module/network/__init__.h"
-//| :mod:`socket` --- TCP, UDP and RAW socket support
-//| =================================================
-//|
-//| .. module:: socket
-//| :synopsis: TCP, UDP and RAW sockets
-//| :platform: SAMD21, SAMD51
+//| """TCP, UDP and RAW socket support
+//|
+//| Create TCP, UDP and RAW sockets for communicating over the Internet."""
//|
-//| Create TCP, UDP and RAW sockets for communicating over the Internet.
-//|
STATIC const mp_obj_type_t socket_type;
-//| .. currentmodule:: socket
+//| class socket:
//|
-//| .. class:: socket(family, type, proto, ...)
-//|
-//| Create a new socket
+//| def __init__(self, family: int, type: int, proto: int):
+//| """Create a new socket
//|
-//| :param ~int family: AF_INET or AF_INET6
-//| :param ~int type: SOCK_STREAM, SOCK_DGRAM or SOCK_RAW
-//| :param ~int proto: IPPROTO_TCP, IPPROTO_UDP or IPPROTO_RAW (ignored)
+//| :param ~int family: AF_INET or AF_INET6
+//| :param ~int type: SOCK_STREAM, SOCK_DGRAM or SOCK_RAW
+//| :param ~int proto: IPPROTO_TCP, IPPROTO_UDP or IPPROTO_RAW (ignored)"""
+//| ...
//|
-STATIC mp_obj_t socket_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
- mp_arg_check_num(n_args, n_kw, 0, 4, false);
+STATIC mp_obj_t socket_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
+ mp_arg_check_num(n_args, kw_args, 0, 4, false);
// create socket object (not bound to any NIC yet)
mod_network_socket_obj_t *s = m_new_obj_with_finaliser(mod_network_socket_obj_t);
@@ -98,11 +93,11 @@ STATIC void socket_select_nic(mod_network_socket_obj_t *self, const byte *ip) {
}
}
-//| .. method:: bind(address)
-//|
-//| Bind a socket to an address
+//| def bind(self, address: tuple) -> Any:
+//| """Bind a socket to an address
//|
-//| :param ~tuple address: tuple of (remote_address, remote_port)
+//| :param ~tuple address: tuple of (remote_address, remote_port)"""
+//| ...
//|
STATIC mp_obj_t socket_bind(mp_obj_t self_in, mp_obj_t addr_in) {
@@ -125,11 +120,11 @@ STATIC mp_obj_t socket_bind(mp_obj_t self_in, mp_obj_t addr_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_bind_obj, socket_bind);
-//| .. method:: listen(backlog)
-//|
-//| Set socket to listen for incoming connections
+//| def listen(self, backlog: int) -> Any:
+//| """Set socket to listen for incoming connections
//|
-//| :param ~int backlog: length of backlog queue for waiting connetions
+//| :param ~int backlog: length of backlog queue for waiting connetions"""
+//| ...
//|
STATIC mp_obj_t socket_listen(mp_obj_t self_in, mp_obj_t backlog) {
@@ -150,11 +145,10 @@ STATIC mp_obj_t socket_listen(mp_obj_t self_in, mp_obj_t backlog) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_listen_obj, socket_listen);
-//| .. method:: accept()
-//|
-//| Accept a connection on a listening socket of type SOCK_STREAM,
-//| creating a new socket of type SOCK_STREAM.
-//| Returns a tuple of (new_socket, remote_address)
+//| def accept(self, ) -> Any:
+//| """Accept a connection on a listening socket of type SOCK_STREAM,
+//| creating a new socket of type SOCK_STREAM.
+//| Returns a tuple of (new_socket, remote_address)"""
//|
STATIC mp_obj_t socket_accept(mp_obj_t self_in) {
@@ -188,11 +182,11 @@ STATIC mp_obj_t socket_accept(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(socket_accept_obj, socket_accept);
-//| .. method:: connect(address)
-//|
-//| Connect a socket to a remote address
+//| def connect(self, address: tuple) -> Any:
+//| """Connect a socket to a remote address
//|
-//| :param ~tuple address: tuple of (remote_address, remote_port)
+//| :param ~tuple address: tuple of (remote_address, remote_port)"""
+//| ...
//|
STATIC mp_obj_t socket_connect(mp_obj_t self_in, mp_obj_t addr_in) {
@@ -215,12 +209,12 @@ STATIC mp_obj_t socket_connect(mp_obj_t self_in, mp_obj_t addr_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_connect_obj, socket_connect);
-//| .. method:: send(bytes)
+//| def send(self, bytes: bytes) -> Any:
+//| """Send some bytes to the connected remote address.
+//| Suits sockets of type SOCK_STREAM
//|
-//| Send some bytes to the connected remote address.
-//| Suits sockets of type SOCK_STREAM
-//|
-//| :param ~bytes bytes: some bytes to send
+//| :param ~bytes bytes: some bytes to send"""
+//| ...
//|
STATIC mp_obj_t socket_send(mp_obj_t self_in, mp_obj_t buf_in) {
@@ -240,13 +234,62 @@ STATIC mp_obj_t socket_send(mp_obj_t self_in, mp_obj_t buf_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_send_obj, socket_send);
-//| .. method:: recv(bufsize)
+
+// helper function for socket_recv and socket_recv_into to handle common operations of both
+STATIC mp_int_t _socket_recv_into(mod_network_socket_obj_t *sock, byte *buf, mp_int_t len) {
+ int _errno;
+ mp_int_t ret = sock->nic_type->recv(sock, buf, len, &_errno);
+ if (ret == -1) {
+ mp_raise_OSError(_errno);
+ }
+ return ret;
+}
+
+
+//| def recv_into(self, buffer: bytearray, bufsize: int) -> Any:
+//| """Reads some bytes from the connected remote address, writing
+//| into the provided buffer. If bufsize <= len(buffer) is given,
+//| a maximum of bufsize bytes will be read into the buffer. If no
+//| valid value is given for bufsize, the default is the length of
+//| the given buffer.
+//|
+//| Suits sockets of type SOCK_STREAM
+//| Returns an int of number of bytes read.
+//|
+//| :param bytearray buffer: buffer to receive into
+//| :param int bufsize: optionally, a maximum number of bytes to read."""
+//| ...
+//|
+
+STATIC mp_obj_t socket_recv_into(size_t n_args, const mp_obj_t *args) {
+ mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(args[0]);
+ if (self->nic == MP_OBJ_NULL) {
+ // not connected
+ mp_raise_OSError(MP_ENOTCONN);
+ }
+ mp_buffer_info_t bufinfo;
+ mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE);
+ mp_int_t len = bufinfo.len;
+ if (n_args == 3) {
+ mp_int_t given_len = mp_obj_get_int(args[2]);
+ if (given_len < len) {
+ len = given_len;
+ }
+ }
+
+ mp_int_t ret = _socket_recv_into(self, (byte*)bufinfo.buf, len);
+ return mp_obj_new_int_from_uint(ret);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socket_recv_into_obj, 2, 3, socket_recv_into);
+
+//| def recv(self, bufsize: int) -> Any:
+//| """Reads some bytes from the connected remote address.
+//| Suits sockets of type SOCK_STREAM
+//| Returns a bytes() of length <= bufsize
+//|
+//| :param ~int bufsize: maximum number of bytes to receive"""
+//| ...
//|
-//| Reads some bytes from the connected remote address.
-//| Suits sockets of type SOCK_STREAM
-//| Returns a bytes() of length <= bufsize
-//|
-//| :param ~int bufsize: maximum number of bytes to receive
STATIC mp_obj_t socket_recv(mp_obj_t self_in, mp_obj_t len_in) {
mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in);
@@ -257,11 +300,7 @@ STATIC mp_obj_t socket_recv(mp_obj_t self_in, mp_obj_t len_in) {
mp_int_t len = mp_obj_get_int(len_in);
vstr_t vstr;
vstr_init_len(&vstr, len);
- int _errno;
- mp_int_t ret = self->nic_type->recv(self, (byte*)vstr.buf, len, &_errno);
- if (ret == -1) {
- mp_raise_OSError(_errno);
- }
+ mp_int_t ret = _socket_recv_into(self, (byte*)vstr.buf, len);
if (ret == 0) {
return mp_const_empty_bytes;
}
@@ -270,13 +309,13 @@ STATIC mp_obj_t socket_recv(mp_obj_t self_in, mp_obj_t len_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_recv_obj, socket_recv);
-//| .. method:: sendto(bytes, address)
+//| def sendto(self, bytes: bytes, address: tuple) -> Any:
+//| """Send some bytes to a specific address.
+//| Suits sockets of type SOCK_DGRAM
//|
-//| Send some bytes to a specific address.
-//| Suits sockets of type SOCK_DGRAM
-//|
-//| :param ~bytes bytes: some bytes to send
-//| :param ~tuple address: tuple of (remote_address, remote_port)
+//| :param ~bytes bytes: some bytes to send
+//| :param ~tuple address: tuple of (remote_address, remote_port)"""
+//| ...
//|
STATIC mp_obj_t socket_sendto(mp_obj_t self_in, mp_obj_t data_in, mp_obj_t addr_in) {
@@ -304,16 +343,16 @@ STATIC mp_obj_t socket_sendto(mp_obj_t self_in, mp_obj_t data_in, mp_obj_t addr_
}
STATIC MP_DEFINE_CONST_FUN_OBJ_3(socket_sendto_obj, socket_sendto);
-//| .. method:: recvfrom(bufsize)
-//|
-//| Reads some bytes from the connected remote address.
-//| Suits sockets of type SOCK_STREAM
+//| def recvfrom(self, bufsize: int) -> Any:
+//| """Reads some bytes from the connected remote address.
+//| Suits sockets of type SOCK_STREAM
//|
-//| Returns a tuple containing
-//| * a bytes() of length <= bufsize
-//| * a remote_address, which is a tuple of ip address and port number
+//| Returns a tuple containing
+//| * a bytes() of length <= bufsize
+//| * a remote_address, which is a tuple of ip address and port number
//|
-//| :param ~int bufsize: maximum number of bytes to receive
+//| :param ~int bufsize: maximum number of bytes to receive"""
+//| ...
//|
STATIC mp_obj_t socket_recvfrom(mp_obj_t self_in, mp_obj_t len_in) {
@@ -343,9 +382,9 @@ STATIC mp_obj_t socket_recvfrom(mp_obj_t self_in, mp_obj_t len_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_recvfrom_obj, socket_recvfrom);
-//| .. method:: setsockopt(level, optname, value)
-//|
-//| Sets socket options
+//| def setsockopt(self, level: Any, optname: Any, value: Any) -> Any:
+//| """Sets socket options"""
+//| ...
//|
STATIC mp_obj_t socket_setsockopt(size_t n_args, const mp_obj_t *args) {
@@ -377,11 +416,11 @@ STATIC mp_obj_t socket_setsockopt(size_t n_args, const mp_obj_t *args) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socket_setsockopt_obj, 4, 4, socket_setsockopt);
-//| .. method:: settimeout(value)
+//| def settimeout(self, value: int) -> Any:
+//| """Set the timeout value for this socket.
//|
-//| Set the timeout value for this socket.
-//|
-//| :param ~int value: timeout in seconds. 0 means non-blocking. None means block indefinitely.
+//| :param ~int value: timeout in seconds. 0 means non-blocking. None means block indefinitely."""
+//| ...
//|
STATIC mp_obj_t socket_settimeout(mp_obj_t self_in, mp_obj_t timeout_in) {
@@ -408,11 +447,11 @@ STATIC mp_obj_t socket_settimeout(mp_obj_t self_in, mp_obj_t timeout_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_settimeout_obj, socket_settimeout);
-//| .. method:: setblocking(flag)
-//|
-//| Set the blocking behaviour of this socket.
+//| def setblocking(self, flag: bool) -> Any:
+//| """Set the blocking behaviour of this socket.
//|
-//| :param ~bool flag: False means non-blocking, True means block indefinitely.
+//| :param ~bool flag: False means non-blocking, True means block indefinitely."""
+//| ...
//|
// method socket.setblocking(flag)
@@ -436,6 +475,7 @@ STATIC const mp_rom_map_elem_t socket_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_recv), MP_ROM_PTR(&socket_recv_obj) },
{ MP_ROM_QSTR(MP_QSTR_sendto), MP_ROM_PTR(&socket_sendto_obj) },
{ MP_ROM_QSTR(MP_QSTR_recvfrom), MP_ROM_PTR(&socket_recvfrom_obj) },
+ { MP_ROM_QSTR(MP_QSTR_recv_into), MP_ROM_PTR(&socket_recv_into_obj) },
{ MP_ROM_QSTR(MP_QSTR_setsockopt), MP_ROM_PTR(&socket_setsockopt_obj) },
{ MP_ROM_QSTR(MP_QSTR_settimeout), MP_ROM_PTR(&socket_settimeout_obj) },
{ MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&socket_setblocking_obj) },
@@ -456,6 +496,7 @@ mp_uint_t socket_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *
}
STATIC const mp_stream_p_t socket_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.ioctl = socket_ioctl,
.is_text = false,
};
@@ -468,13 +509,13 @@ STATIC const mp_obj_type_t socket_type = {
.locals_dict = (mp_obj_dict_t*)&socket_locals_dict,
};
-//| .. function:: getaddrinfo(host, port)
-//|
-//| Gets the address information for a hostname and port
+//| def getaddrinfo(host: Any, port: Any) -> Any:
+//| """Gets the address information for a hostname and port
//|
-//| Returns the appropriate family, socket type, socket protocol and
-//| address information to call socket.socket() and socket.connect() with,
-//| as a tuple.
+//| Returns the appropriate family, socket type, socket protocol and
+//| address information to call socket.socket() and socket.connect() with,
+//| as a tuple."""
+//| ...
//|
STATIC mp_obj_t socket_getaddrinfo(mp_obj_t host_in, mp_obj_t port_in) {