Skip to content

Commit 1d9092d

Browse files
committed
some socket stuff
1 parent aee8569 commit 1d9092d

File tree

1 file changed

+89
-7
lines changed

1 file changed

+89
-7
lines changed

adafruit_esp32spi.py

Lines changed: 89 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,25 @@ class ESP_SPIcontrol:
1717
GET_CURR_ENCT_CMD = const(0x26)
1818

1919
SCAN_NETWORKS = const(0x27)
20+
GET_SOCKET_CMD = const(0x3F)
21+
GET_STATE_TCP_CMD = const(0x29)
22+
DATA_SENT_TCP_CMD = const(0x2A)
23+
AVAIL_DATA_TCP_CMD = const(0x2B)
24+
GET_DATA_TCP_CMD = const(0x2C)
25+
START_CLIENT_TCP_CMD = const(0x2D)
26+
STOP_CLIENT_TCP_CMD = const(0x2E)
27+
GET_CLIENT_STATE_TCP_CMD = const(0x2F)
28+
DISCONNECT_CMD = const(0x30)
2029
GET_IDX_RSSI_CMD = const(0x32)
2130
GET_IDX_ENCT_CMD = const(0x33)
2231
REQ_HOST_BY_NAME_CMD = const(0x34)
2332
GET_HOST_BY_NAME_CMD = const(0x35)
2433
START_SCAN_NETWORKS = const(0x36)
34+
GET_FW_VERSION_CMD = const(0x37)
2535
PING_CMD = const(0x3E)
2636

27-
GET_FW_VERSION_CMD = const(0x37)
37+
SEND_DATA_TCP_CMD = const(0x44)
38+
2839

2940
START_CMD = const(0xE0)
3041
END_CMD = const(0xEE)
@@ -39,6 +50,20 @@ class ESP_SPIcontrol:
3950
WL_SCAN_COMPLETED = const(2)
4051
WL_CONNECTED = const(3)
4152

53+
SOCKET_CLOSED = const(0)
54+
SOCKET_LISTEN = const(1)
55+
SOCKET_SYN_SENT = const(2)
56+
SOCKET_SYN_RCVD = const(3)
57+
SOCKET_ESTABLISHED = const(4)
58+
SOCKET_FIN_WAIT_1 = const(5)
59+
SOCKET_FIN_WAIT_2 = const(6)
60+
SOCKET_CLOSE_WAIT = const(7)
61+
SOCKET_CLOSING = const(8)
62+
SOCKET_LAST_ACK = const(9)
63+
SOCKET_TIME_WAIT = const(10)
64+
65+
TCP_MODE = const(0)
66+
4267
def __init__(self, spi, cs_pin, ready_pin, reset_pin, gpio0_pin, *, debug=False):
4368
self._debug = debug
4469
self._buffer = bytearray(10)
@@ -96,7 +121,7 @@ def wait_for_slave_select(self):
96121
self.wait_for_slave_ready()
97122
self.spi_slave_select()
98123

99-
def send_command(self, cmd, params=None):
124+
def send_command(self, cmd, params=None, *, param_len_16=False):
100125
if not params:
101126
params = []
102127
packet = []
@@ -105,8 +130,12 @@ def send_command(self, cmd, params=None):
105130
packet.append(len(params))
106131

107132
# handle parameters here
108-
for param in params:
109-
packet.append(len(param))
133+
for i, param in enumerate(params):
134+
if self._debug:
135+
print("sending param #%d is %d bytes long" % (i, len(param)))
136+
if param_len_16:
137+
packet.append((len(param) >> 8) & 0xFF)
138+
packet.append(len(param) & 0xFF)
110139
packet += (param)
111140

112141
packet.append(END_CMD)
@@ -167,8 +196,8 @@ def wait_response_cmd(self, cmd, num_responses=None):
167196
self.slave_deselect()
168197
return responses
169198

170-
def send_command_get_response(self, cmd, params=None, *, reply_params=1):
171-
self.send_command(cmd, params)
199+
def send_command_get_response(self, cmd, params=None, *, reply_params=1, param_len_16=False):
200+
self.send_command(cmd, params, param_len_16=param_len_16)
172201
return self.wait_response_cmd(cmd, reply_params)
173202

174203
@property
@@ -275,7 +304,13 @@ def connect_AP(self, ssid, password):
275304
def pretty_ip(self, ip):
276305
return "%d.%d.%d.%d" % (ip[0], ip[1], ip[2], ip[3])
277306

307+
def unpretty_ip(self, ip):
308+
octets = [int(x) for x in ip.split('.')]
309+
return bytes(octets)
310+
278311
def get_host_by_name(self, hostname):
312+
if self._debug:
313+
print("*** Get host by name")
279314
if isinstance(hostname, str):
280315
hostname = bytes(hostname, 'utf-8')
281316
resp = self.send_command_get_response(REQ_HOST_BY_NAME_CMD, [hostname])
@@ -285,10 +320,57 @@ def get_host_by_name(self, hostname):
285320
return resp[0]
286321

287322
def ping(self, dest, ttl=250):
288-
self._debug=True
289323
if isinstance(dest, str): # convert to IP address
290324
dest = self.get_host_by_name(dest)
291325
# ttl must be between 0 and 255
292326
ttl = max(0, min(ttl, 255))
293327
resp = self.send_command_get_response(PING_CMD, [dest, [ttl]])
294328
return struct.unpack('<H', resp[0])[0]
329+
330+
def get_socket(self):
331+
if self._debug:
332+
print("*** Get socket")
333+
resp = self.send_command_get_response(GET_SOCKET_CMD)
334+
resp = resp[0][0]
335+
if resp == 255:
336+
raise RuntimeError("No sockets available")
337+
return resp
338+
339+
def start_client(self, dest, ip, port, socket_num, conn_mode=TCP_MODE):
340+
if self._debug:
341+
print("*** Start Client")
342+
port_param = struct.pack('>H', port)
343+
resp = self.send_command_get_response(START_CLIENT_TCP_CMD,
344+
[ip, port_param,
345+
[socket_num], [conn_mode]])
346+
if resp[0][0] != 1:
347+
raise RuntimeError("Could not connect to remote server")
348+
349+
def socket_status(self, socket_num):
350+
resp = self.send_command_get_response(GET_CLIENT_STATE_TCP_CMD, [[socket_num]])
351+
return resp[0][0]
352+
353+
def socket_connected(self, socket_num):
354+
return self.socket_status(socket_num) == SOCKET_ESTABLISHED
355+
356+
def socket_write(self, socket_num, buffer):
357+
resp = self.send_command_get_response(SEND_DATA_TCP_CMD,
358+
[[socket_num], buffer],
359+
param_len_16=True)
360+
print(resp)
361+
362+
def socket_connect(self, dest, port):
363+
if self._debug:
364+
print("*** Socket connect")
365+
if isinstance(dest, str): # convert to IP address
366+
dest = self.get_host_by_name(dest)
367+
self.sock_num = self.get_socket()
368+
print("Socket #%d" % self.sock_num)
369+
370+
self.start_client(dest, dest, port, self.sock_num)
371+
times = time.monotonic()
372+
while (time.monotonic() - times) < 3: # wait 3 seconds
373+
if self.socket_connected(self.sock_num):
374+
return
375+
time.sleep(0.01)
376+
raise RuntimeError("Failed to establish connection")

0 commit comments

Comments
 (0)