|
36 | 36 | class SocketPool:
|
37 | 37 | """ESP32SPI SocketPool library"""
|
38 | 38 |
|
39 |
| - SOCK_STREAM = const(0) |
40 |
| - SOCK_DGRAM = const(1) |
| 39 | + # socketpool constants |
| 40 | + SOCK_STREAM = const(1) |
| 41 | + SOCK_DGRAM = const(2) |
41 | 42 | AF_INET = const(2)
|
42 |
| - NO_SOCKET_AVAIL = const(255) |
| 43 | + SOL_SOCKET = const(0xfff) |
| 44 | + SO_REUSEADDR = const(0x0004) |
43 | 45 |
|
| 46 | + # implementation specific constants |
| 47 | + NO_SOCKET_AVAIL = const(255) |
44 | 48 | MAX_PACKET = const(4000)
|
45 | 49 |
|
46 | 50 | def __new__(cls, iface: ESP_SPIcontrol):
|
@@ -82,14 +86,15 @@ def __init__(
|
82 | 86 | type: int = SocketPool.SOCK_STREAM,
|
83 | 87 | proto: int = 0,
|
84 | 88 | fileno: Optional[int] = None, # noqa: UP007
|
| 89 | + socknum: Optional[int] = None, # noqa: UP007 |
85 | 90 | ):
|
86 | 91 | if family != SocketPool.AF_INET:
|
87 | 92 | raise ValueError("Only AF_INET family supported")
|
88 | 93 | self._socket_pool = socket_pool
|
89 | 94 | self._interface = self._socket_pool._interface
|
90 | 95 | self._type = type
|
91 | 96 | self._buffer = b""
|
92 |
| - self._socknum = self._interface.get_socket() |
| 97 | + self._socknum = socknum if socknum is not None else self._interface.get_socket() |
93 | 98 | self.settimeout(0)
|
94 | 99 |
|
95 | 100 | def __enter__(self):
|
@@ -121,13 +126,14 @@ def send(self, data):
|
121 | 126 | conntype = self._interface.UDP_MODE
|
122 | 127 | else:
|
123 | 128 | 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) |
125 | 130 | gc.collect()
|
| 131 | + return sent |
126 | 132 |
|
127 | 133 | def sendto(self, data, address):
|
128 | 134 | """Connect and send some data to the socket."""
|
129 | 135 | self.connect(address)
|
130 |
| - self.send(data) |
| 136 | + return self.send(data) |
131 | 137 |
|
132 | 138 | def recv(self, bufsize: int) -> bytes:
|
133 | 139 | """Reads some bytes from the connected remote address. Will only return
|
@@ -217,3 +223,42 @@ def _connected(self):
|
217 | 223 | def close(self):
|
218 | 224 | """Close the socket, after reading whatever remains"""
|
219 | 225 | 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