Skip to content

Commit d50d5d1

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 063b90c commit d50d5d1

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
@@ -825,7 +825,8 @@ def socket_connected(self, socket_num):
825825
return self.socket_status(socket_num) == SOCKET_ESTABLISHED
826826

827827
def socket_write(self, socket_num, buffer, conn_mode=TCP_MODE):
828-
"""Write the bytearray buffer to a socket"""
828+
"""Write the bytearray buffer to a socket.
829+
Returns the number of bytes written"""
829830
if self._debug:
830831
print("Writing:", buffer)
831832
self._socknum_ll[0][0] = socket_num
@@ -853,7 +854,7 @@ def socket_write(self, socket_num, buffer, conn_mode=TCP_MODE):
853854
resp = self._send_command_get_response(_SEND_UDP_DATA_CMD, self._socknum_ll)
854855
if resp[0][0] != 1:
855856
raise ConnectionError("Failed to send UDP data")
856-
return
857+
return sent
857858

858859
if sent != len(buffer):
859860
self.socket_close(socket_num)
@@ -863,6 +864,8 @@ def socket_write(self, socket_num, buffer, conn_mode=TCP_MODE):
863864
if resp[0][0] != 1:
864865
raise ConnectionError("Failed to verify data sent")
865866

867+
return sent
868+
866869
def socket_available(self, socket_num):
867870
"""Determine how many bytes are waiting to be read on the socket"""
868871
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
@@ -36,11 +36,15 @@
3636
class SocketPool:
3737
"""ESP32SPI SocketPool library"""
3838

39-
SOCK_STREAM = const(0)
40-
SOCK_DGRAM = const(1)
39+
# socketpool constants
40+
SOCK_STREAM = const(1)
41+
SOCK_DGRAM = const(2)
4142
AF_INET = const(2)
42-
NO_SOCKET_AVAIL = const(255)
43+
SOL_SOCKET = const(0xfff)
44+
SO_REUSEADDR = const(0x0004)
4345

46+
# implementation specific constants
47+
NO_SOCKET_AVAIL = const(255)
4448
MAX_PACKET = const(4000)
4549

4650
def __new__(cls, iface: ESP_SPIcontrol):
@@ -82,14 +86,15 @@ def __init__(
8286
type: int = SocketPool.SOCK_STREAM,
8387
proto: int = 0,
8488
fileno: Optional[int] = None, # noqa: UP007
89+
socknum: Optional[int] = None, # noqa: UP007
8590
):
8691
if family != SocketPool.AF_INET:
8792
raise ValueError("Only AF_INET family supported")
8893
self._socket_pool = socket_pool
8994
self._interface = self._socket_pool._interface
9095
self._type = type
9196
self._buffer = b""
92-
self._socknum = self._interface.get_socket()
97+
self._socknum = socknum if socknum is not None else self._interface.get_socket()
9398
self.settimeout(0)
9499

95100
def __enter__(self):
@@ -121,13 +126,14 @@ def send(self, data):
121126
conntype = self._interface.UDP_MODE
122127
else:
123128
conntype = self._interface.TCP_MODE
124-
self._interface.socket_write(self._socknum, data, conn_mode=conntype)
129+
sent = self._interface.socket_write(self._socknum, data, conn_mode=conntype)
125130
gc.collect()
131+
return sent
126132

127133
def sendto(self, data, address):
128134
"""Connect and send some data to the socket."""
129135
self.connect(address)
130-
self.send(data)
136+
return self.send(data)
131137

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

0 commit comments

Comments
 (0)