Skip to content

Commit 0f3b271

Browse files
committed
more compatible sockets:
socket_write() and send() return the number of bytes sent add some of the constants used by httpserver (others missing) dummy entries for setsockopt(), listen() and setblocking() implement bind() by using ninafw start_server() implement accept() by getting a clien socket from that server add back socknum parameter to allow wrapping a Socket around a ninafw socket number, which is required to be able to receive a connection from the server
1 parent 2ddf9fa commit 0f3b271

File tree

2 files changed

+56
-8
lines changed

2 files changed

+56
-8
lines changed

adafruit_esp32spi/adafruit_esp32spi.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -844,7 +844,8 @@ def socket_connected(self, socket_num):
844844
return self.socket_status(socket_num) == SOCKET_ESTABLISHED
845845

846846
def socket_write(self, socket_num, buffer, conn_mode=TCP_MODE):
847-
"""Write the bytearray buffer to a socket"""
847+
"""Write the bytearray buffer to a socket.
848+
Returns the number of bytes written"""
848849
if self._debug:
849850
print("Writing:", buffer)
850851
self._socknum_ll[0][0] = socket_num
@@ -874,7 +875,7 @@ def socket_write(self, socket_num, buffer, conn_mode=TCP_MODE):
874875
resp = self._send_command_get_response(_SEND_UDP_DATA_CMD, self._socknum_ll)
875876
if resp[0][0] != 1:
876877
raise ConnectionError("Failed to send UDP data")
877-
return
878+
return sent
878879

879880
if sent != len(buffer):
880881
self.socket_close(socket_num)
@@ -886,6 +887,8 @@ def socket_write(self, socket_num, buffer, conn_mode=TCP_MODE):
886887
if resp[0][0] != 1:
887888
raise ConnectionError("Failed to verify data sent")
888889

890+
return sent
891+
889892
def socket_available(self, socket_num):
890893
"""Determine how many bytes are waiting to be read on the socket"""
891894
self._socknum_ll[0][0] = socket_num

adafruit_esp32spi/adafruit_esp32spi_socketpool.py

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,15 @@
3333
class SocketPool:
3434
"""ESP32SPI SocketPool library"""
3535

36-
SOCK_STREAM = const(0)
37-
SOCK_DGRAM = const(1)
36+
# socketpool constants
37+
SOCK_STREAM = const(1)
38+
SOCK_DGRAM = const(2)
3839
AF_INET = const(2)
39-
NO_SOCKET_AVAIL = const(255)
40+
SOL_SOCKET = const(0xfff)
41+
SO_REUSEADDR = const(0x0004)
4042

43+
# implementation specific constants
44+
NO_SOCKET_AVAIL = const(255)
4145
MAX_PACKET = const(4000)
4246

4347
def __new__(cls, iface: ESP_SPIcontrol):
@@ -81,14 +85,15 @@ def __init__( # pylint: disable=redefined-builtin,too-many-arguments,unused-arg
8185
type: int = SocketPool.SOCK_STREAM,
8286
proto: int = 0,
8387
fileno: Optional[int] = None,
88+
socknum: Optional[int] = None,
8489
):
8590
if family != SocketPool.AF_INET:
8691
raise ValueError("Only AF_INET family supported")
8792
self._socket_pool = socket_pool
8893
self._interface = self._socket_pool._interface
8994
self._type = type
9095
self._buffer = b""
91-
self._socknum = self._interface.get_socket()
96+
self._socknum = socknum if socknum is not None else self._interface.get_socket()
9297
self.settimeout(0)
9398

9499
def __enter__(self):
@@ -122,13 +127,14 @@ def send(self, data):
122127
conntype = self._interface.UDP_MODE
123128
else:
124129
conntype = self._interface.TCP_MODE
125-
self._interface.socket_write(self._socknum, data, conn_mode=conntype)
130+
sent = self._interface.socket_write(self._socknum, data, conn_mode=conntype)
126131
gc.collect()
132+
return sent
127133

128134
def sendto(self, data, address):
129135
"""Connect and send some data to the socket."""
130136
self.connect(address)
131-
self.send(data)
137+
return self.send(data)
132138

133139
def recv(self, bufsize: int) -> bytes:
134140
"""Reads some bytes from the connected remote address. Will only return
@@ -224,3 +230,42 @@ def _connected(self):
224230
def close(self):
225231
"""Close the socket, after reading whatever remains"""
226232
self._interface.socket_close(self._socknum)
233+
234+
####################################################################
235+
# WORK IN PROGRESS
236+
####################################################################
237+
238+
def setsockopt(self, *opts, **kwopts):
239+
"""Dummy call for compatibility."""
240+
# FIXME
241+
pass
242+
243+
def listen(self, backlog):
244+
"""Dummy call for compatibility."""
245+
# FIXME
246+
# probably nothing to do actually
247+
# maybe check that we have called bind or something ?
248+
pass
249+
250+
def setblocking(self, blocking):
251+
"""Dummy call for compatibility."""
252+
# FIXME
253+
# is this settimeout(0) ? (if True) or something else ?
254+
pass
255+
256+
def bind(self, host_port):
257+
host, port = host_port
258+
self._interface.start_server(port, self._socknum)
259+
print(f"Binding to {self._socknum}")
260+
261+
def accept(self):
262+
client_sock_num = self._interface.socket_available(self._socknum)
263+
if client_sock_num != SocketPool.NO_SOCKET_AVAIL:
264+
sock = Socket(self._socket_pool, socknum=client_sock_num)
265+
# get remote information (addr and port)
266+
remote = self._interface.get_remote_data(client_sock_num)
267+
IP_ADDRESS = "{}.{}.{}.{}".format(*remote['ip_addr'])
268+
PORT = remote['port']
269+
client_address = (IP_ADDRESS, PORT)
270+
return sock, client_address
271+
raise OSError(errno.ECONNRESET)

0 commit comments

Comments
 (0)