@@ -17,14 +17,25 @@ class ESP_SPIcontrol:
17
17
GET_CURR_ENCT_CMD = const (0x26 )
18
18
19
19
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 )
20
29
GET_IDX_RSSI_CMD = const (0x32 )
21
30
GET_IDX_ENCT_CMD = const (0x33 )
22
31
REQ_HOST_BY_NAME_CMD = const (0x34 )
23
32
GET_HOST_BY_NAME_CMD = const (0x35 )
24
33
START_SCAN_NETWORKS = const (0x36 )
34
+ GET_FW_VERSION_CMD = const (0x37 )
25
35
PING_CMD = const (0x3E )
26
36
27
- GET_FW_VERSION_CMD = const (0x37 )
37
+ SEND_DATA_TCP_CMD = const (0x44 )
38
+
28
39
29
40
START_CMD = const (0xE0 )
30
41
END_CMD = const (0xEE )
@@ -39,6 +50,20 @@ class ESP_SPIcontrol:
39
50
WL_SCAN_COMPLETED = const (2 )
40
51
WL_CONNECTED = const (3 )
41
52
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
+
42
67
def __init__ (self , spi , cs_pin , ready_pin , reset_pin , gpio0_pin , * , debug = False ):
43
68
self ._debug = debug
44
69
self ._buffer = bytearray (10 )
@@ -96,7 +121,7 @@ def wait_for_slave_select(self):
96
121
self .wait_for_slave_ready ()
97
122
self .spi_slave_select ()
98
123
99
- def send_command (self , cmd , params = None ):
124
+ def send_command (self , cmd , params = None , * , param_len_16 = False ):
100
125
if not params :
101
126
params = []
102
127
packet = []
@@ -105,8 +130,12 @@ def send_command(self, cmd, params=None):
105
130
packet .append (len (params ))
106
131
107
132
# 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 )
110
139
packet += (param )
111
140
112
141
packet .append (END_CMD )
@@ -167,8 +196,8 @@ def wait_response_cmd(self, cmd, num_responses=None):
167
196
self .slave_deselect ()
168
197
return responses
169
198
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 )
172
201
return self .wait_response_cmd (cmd , reply_params )
173
202
174
203
@property
@@ -275,7 +304,13 @@ def connect_AP(self, ssid, password):
275
304
def pretty_ip (self , ip ):
276
305
return "%d.%d.%d.%d" % (ip [0 ], ip [1 ], ip [2 ], ip [3 ])
277
306
307
+ def unpretty_ip (self , ip ):
308
+ octets = [int (x ) for x in ip .split ('.' )]
309
+ return bytes (octets )
310
+
278
311
def get_host_by_name (self , hostname ):
312
+ if self ._debug :
313
+ print ("*** Get host by name" )
279
314
if isinstance (hostname , str ):
280
315
hostname = bytes (hostname , 'utf-8' )
281
316
resp = self .send_command_get_response (REQ_HOST_BY_NAME_CMD , [hostname ])
@@ -285,10 +320,57 @@ def get_host_by_name(self, hostname):
285
320
return resp [0 ]
286
321
287
322
def ping (self , dest , ttl = 250 ):
288
- self ._debug = True
289
323
if isinstance (dest , str ): # convert to IP address
290
324
dest = self .get_host_by_name (dest )
291
325
# ttl must be between 0 and 255
292
326
ttl = max (0 , min (ttl , 255 ))
293
327
resp = self .send_command_get_response (PING_CMD , [dest , [ttl ]])
294
328
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