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