Skip to content

Commit 6728fcd

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 71a07cc commit 6728fcd

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

841841
def socket_write(self, socket_num, buffer, conn_mode=TCP_MODE):
842-
"""Write the bytearray buffer to a socket"""
842+
"""Write the bytearray buffer to a socket.
843+
Returns the number of bytes written"""
843844
if self._debug:
844845
print("Writing:", buffer)
845846
self._socknum_ll[0][0] = socket_num
@@ -869,7 +870,7 @@ def socket_write(self, socket_num, buffer, conn_mode=TCP_MODE):
869870
resp = self._send_command_get_response(_SEND_UDP_DATA_CMD, self._socknum_ll)
870871
if resp[0][0] != 1:
871872
raise ConnectionError("Failed to send UDP data")
872-
return
873+
return sent
873874

874875
if sent != len(buffer):
875876
self.socket_close(socket_num)
@@ -881,6 +882,8 @@ def socket_write(self, socket_num, buffer, conn_mode=TCP_MODE):
881882
if resp[0][0] != 1:
882883
raise ConnectionError("Failed to verify data sent")
883884

885+
return sent
886+
884887
def socket_available(self, socket_num):
885888
"""Determine how many bytes are waiting to be read on the socket"""
886889
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)