RaspberrPi project source code
guowenxue
2023-08-26 d6b4a750258b34c79e3c643595a0ae1cb0e18bed
commit | author | age
d6b4a7 1 /*********************************************************************************
G 2  *      Copyright:  (C) 2023 LingYun IoT System Studio.
3  *                  All rights reserved.
4  *
5  *       Filename:  at-esp32.c
6  *    Description:  This file is ESP32 AT command low level API functions
7  *                 
8  *        Version:  1.0.0(11/08/23)
9  *         Author:  Guo Wenxue <guowenxue@gmail.com>
10  *      ChangeLog:  1, Release initial version on "11/08/23 16:18:43"
11  *                 
12  ********************************************************************************/
13
14 #include "logger.h"
15 #include "at-esp32.h"
16
17 /*+------------------------+
18  *|    Baisc AT command    |
19  *+------------------------+*/
20
21 static inline int check_at_ready(comport_t *comport)
22 {
23     int             times = 6;
24     int             ready = 0;
25
26     while( times-- )
27     {
28         if( 0 == send_atcmd_check_ok(comport, "AT", 500) )
29         {
30             ready = 1;
31             break;
32         }
33     }
34
35     return ready;
36 }
37
38 /* AT command: AT+RST */
39 int esp32_reset(comport_t *comport)
40 {
41     int             rv;
42
43     rv = send_atcmd(comport, "AT+RST", 5000, "ready", AT_ERRSTR, NULL, 0);
44     if( rv < 0)
45     {
46         log_error("send AT command to reset ESP32 failed, rv=%d\n", rv);
47         return -1;
48     }
49
50     if( check_at_ready(comport) )
51     {
52         log_info("send AT to reset ESP32 and AT command ready\n");
53         return 0;
54     }
55     else
56     {
57         log_info("send AT to reset ESP32 but AT command not ready\n");
58         return -3;
59     }
60 }
61
62 /* AT command: AT+RESTORE */
63 int esp32_restore(comport_t *comport)
64 {
65     int             rv;
66
67     //rv = send_atcmd_check_ok(comport, "AT+RESTORE", 5000);
68     rv = send_atcmd(comport, "AT+RESTORE", 5000, "ready", AT_ERRSTR, NULL, 0);
69     if( rv < 0)
70     {
71         log_error("send AT command to restore ESP32 failed, rv=%d\n", rv);
72         return -1;
73     }
74
75     if( check_at_ready(comport) )
76     {
77         log_info("send AT command to resstore ESP32 ready\n");
78         return 0;
79     }
80     else
81     {
82         log_error("send AT command to restore ESP32 but AT not ready\n");
83         return -3;
84     }
85 }
86
87 /* AT command: ATE1 or ATE0 */
88 int esp32_set_echo(comport_t *comport, int enable)
89 {
90     char           *at = enable? "ATE1" : "ATE0";
91
92     return send_atcmd_check_ok(comport, at, 500);
93 }
94
95 /* AT command: AT+GMR */
96 int esp32_get_firmware(comport_t *comport, char *version, int size)
97 {
98     if( !version || size<=0 )
99         return -1;
100
101     return send_atcmd_check_value(comport, "AT+GMR", 2000, version, size);
102 }
103
104 /* AT command: AT+SYSSTORE */
105 int esp32_set_sysstore(comport_t *comport, int enable)
106 {
107     char            at[ATCMD_LEN]={'\0'};
108
109     snprintf(at, sizeof(at), "AT+SYSSTORE=%d", enable?1:0);
110
111     return send_atcmd_check_ok(comport, at, 1000);
112 }
113
114 /*+------------------------+
115  *|    WiFi AT command     |
116  *+------------------------+*/
117
118 /* AT command: AT+CWMODE */
119 int esp32_set_wmode(comport_t *comport, workmode_t mode, int autoconn)
120 {
121     char            at[ATCMD_LEN]={'\0'};
122
123     snprintf(at, sizeof(at), "AT+CWMODE=%d,%d", mode, autoconn?1:0);
124     return send_atcmd_check_ok(comport, at, 1500);
125 }
126
127 /* AT command: AT+CIPSTAMAC/CIPAPMAC */
128 int esp32_get_macaddr(comport_t *comport, workmode_t mode, char *mac)
129 {
130     if( !mac )
131         return -1;
132
133     if( MODE_SOFTAP == mode )
134         return send_atcmd_check_request(comport, "AT+CIPAPMAC?", 3000, mac, MAC_LEN);
135     else
136         return send_atcmd_check_request(comport, "AT+CIPSTAMAC?", 3000, mac, MAC_LEN);
137 }
138
139 /* AT command: AT+CIPSTA/AT+CIPAP  */
140 int esp32_set_ipaddr(comport_t *comport, workmode_t mode, char *ip, char *gateway)
141 {
142     char            at[ATCMD_LEN]={'\0'};
143
144     if( !ip || !gateway )
145         return -1;
146
147     if( MODE_SOFTAP == mode )
148         snprintf(at, sizeof(at), "AT+CIPAP=\"%s\",\"%s\"", ip, gateway);
149     else
150         snprintf(at, sizeof(at), "AT+CIPSTA=\"%s\",\"%s\"", ip, gateway);
151
152     return send_atcmd_check_ok(comport, at, 2000);
153 }
154
155 /* AT command: AT+CIPSTA/AT+CIPAP  */
156 int esp32_get_ipaddr(comport_t *comport, workmode_t mode, char *ip, char *gateway)
157 {
158     char           *at = MODE_SOFTAP==mode? "AT+CIPAP?" : "AT+CIPSTA?";
159     char            buf[ATCMD_REPLY_LEN];
160     int             rv;
161
162     if( !ip || !gateway )
163         return -1;
164
165     rv = send_atcmd_check_value(comport, at, 3000, buf, sizeof(buf));
166     if( rv < 0)
167     {
168         log_error("AT command query IP address failed, rv=%d\n", rv);
169         return rv;
170     }
171
172     rv = parser_request_value(buf, "ip", ip, IP_LEN);
173     if( rv < 0 )
174     {
175         log_error("Parser query IP address failed, rv=%d\n", rv);
176         return rv;
177     }
178
179     rv = parser_request_value(buf, "gateway", gateway, IP_LEN);
180     if( rv < 0 )
181     {
182         log_error("Parser query gateway address failed, rv=%d\n", rv);
183         return rv;
184     }
185
186     return 0;
187 }
188
189 /* AT command: AT+CWDHCP */
190 int esp32_set_dhcp(comport_t *comport, workmode_t mode, int enable)
191 {
192     char            at[ATCMD_LEN]={'\0'};
193
194     snprintf(at, sizeof(at), "AT+CWDHCP=%d,%d", enable?1:0, mode);
195     return send_atcmd_check_ok(comport, at, 1500);
196 }
197
198 /* AT command: AT+CWAUTOCONN */
199 int esp32_set_autoconn(comport_t *comport, int enable)
200 {
201     char            at[ATCMD_LEN]={'\0'};
202
203     snprintf(at, sizeof(at), "AT+CWAUTOCONN=%d", enable?1:0);
204     return send_atcmd_check_ok(comport, at, 1500);
205 }
206
207 /* AT command: AT+CWLAP */
208 int esp32_list_ap(comport_t *comport, char *buf, int size)
209 {
210     if( !buf || size<=0 )
211         return -1;
212
213     return send_atcmd_check_value(comport, "AT+CWLAP", 8000, buf, size);
214 }
215
216 /* AT command: AT+CWJAP */
217 int esp32_connect_ap(comport_t *comport, char *ssid, char *pwd)
218 {
219     char            at[ATCMD_LEN]={'\0'};
220
221     if( !ssid || !pwd )
222         return -1;
223
224     snprintf(at, sizeof(at), "AT+CWJAP=\"%s\",\"%s\"", ssid, pwd);
225     return send_atcmd_check_ok(comport, at, 15000);
226 }
227
228 /* AT command: AT+CWQAP */
229 int esp32_disconn_ap(comport_t *comport)
230 {
231     return send_atcmd_check_ok(comport, "AT+CWQAP", 5000);
232 }
233
234
235 /* AT command: AT+CWSTATE?  status value:
236  * - 0: ESP32 station has not started any Wi-Fi connection.
237  * - 1: ESP32 station has connected to an AP, but does not get an IPv4 address yet.
238  * - 2: ESP32 station has connected to an AP, and got an IPv4 address.
239  * - 3: ESP32 station is in Wi-Fi connecting or reconnecting state.
240  * - 4: ESP32 station is in Wi-Fi disconnected state
241  */
242 int esp32_join_status(comport_t *comport, int *status, char *ssid)
243 {
244     char            buf[ATCMD_REPLY_LEN];
245     int             rv;
246
247     if( !status || !ssid )
248         return -1;
249
250     rv = send_atcmd_check_request(comport, "AT+CWSTATE?", 3000, buf, sizeof(buf));
251     if( rv < 0)
252     {
253         log_error("AT command query join status failed, rv=%d\n", rv);
254         return rv;
255     }
256
257     sscanf(buf, "%d,%s", status, ssid);
258
259     return 0;
260 }
261
262 /* AT command:  AT+PING */
263 int esp32_ping(comport_t *comport, char *host, int timeout)
264 {
265     char            at[ATCMD_LEN]={'\0'};
266
267     if( !host )
268         return -1;
269
270     snprintf(at, sizeof(at), "AT+PING=\"%s\"", host);
271     return send_atcmd_check_ok(comport, at, timeout);
272 }
273
274 /* AT command:  AT+CWSAP */
275 int esp32_set_softap(comport_t *comport, char *ssid, char *pwd, int channel, encmode_t encmode)
276 {
277     char            at[ATCMD_LEN]={'\0'};
278
279     if( !ssid || !pwd )
280         return -1;
281
282     snprintf(at, sizeof(at), "AT+CWSAP=\"%s\",\"%s\",%d,%d", ssid, pwd, channel, encmode);
283     return send_atcmd_check_ok(comport, at, 5000);
284 }
285
286 /* AT command: AT+CWLIF */
287 int esp32_list_client(comport_t *comport, char *buf, int size)
288 {
289     if( !buf || size<=0 )
290         return -1;
291
292     return send_atcmd_check_value(comport, "AT+CWLIF", 8000, buf, size);
293 }
294
295 /*+------------------------+
296  *|   Socket AT command    |
297  *+------------------------+*/
298
299 /* AT command: AT+CIPMUX */
300 int esp32_set_socket_mux(comport_t *comport, int enable)
301 {
302     char            at[ATCMD_LEN]={'\0'};
303
304     snprintf(at, sizeof(at), "AT+CIPMUX=%d", enable?1:0);
305
306     return send_atcmd_check_ok(comport, at, 1500);
307 }
308
309 /* AT command: AT+CIPSERVERMAXCONN */
310 int esp32_set_socket_clients(comport_t *comport, int max)
311 {
312     char            at[ATCMD_LEN]={'\0'};
313
314     if( max <= 0 )
315         return -1;
316
317     snprintf(at, sizeof(at), "AT+CIPSERVERMAXCONN=%d", max);
318
319     return send_atcmd_check_ok(comport, at, 1500);
320 }
321
322 /* AT command: AT+CIPSTO, timeout unit second */
323 int esp32_set_socket_timeout(comport_t *comport, int timeout)
324 {
325     char            at[ATCMD_LEN]={'\0'};
326
327     if( timeout <= 0 )
328         return -1;
329
330     snprintf(at, sizeof(at), "AT+CIPSTO=%d", timeout);
331
332     return send_atcmd_check_ok(comport, at, 1500);
333 }
334
335 /* AT command: AT+CIPSERVER */
336 int esp32_set_tcp_server(comport_t *comport, int port)
337 {
338     char            at[ATCMD_LEN]={'\0'};
339
340     if( port <= 0 )
341         return -1;
342
343     snprintf(at, sizeof(at), "AT+CIPSERVER=1,%d,\"TCP\"", port);
344
345     return send_atcmd_check_ok(comport, at, 1500);
346 }
347
348 /* AT command: AT+CIPSERVER */
349 int esp32_del_tcp_server(comport_t *comport, int port)
350 {
351     char            at[ATCMD_LEN]={'\0'};
352
353     if( port <= 0 )
354         return -1;
355
356     snprintf(at, sizeof(at), "AT+CIPSERVER=0,%d,\"TCP\"", port);
357
358     return send_atcmd_check_ok(comport, at, 1500);
359 }
360
361 /* AT command: AT+CIPSTART */
362 int esp32_set_tcp_client(comport_t *comport, int mux, char *host, int port)
363 {
364     char            at[ATCMD_LEN]={'\0'};
365     char            buf[ATCMD_REPLY_LEN]={'\0'};
366     int             keepalive = 60; /* unit second */
367     int             rv,linkid = 0;
368
369     if( !host || port <= 0 )
370         return -1;
371
372     rv = esp32_set_socket_mux(comport, mux);
373     if(rv < 0)
374         return rv;
375
376     if( mux )
377         snprintf(at, sizeof(at), "AT+CIPSTART=1,\"TCP\",\"%s\",%d,%d", host, port, keepalive);
378     else
379         snprintf(at, sizeof(at), "AT+CIPSTART=\"TCP\",\"%s\",%d,%d", host, port, keepalive);
380
381     rv = send_atcmd_check_value(comport, at, 1500, buf, sizeof(buf));
382     if(rv < 0)
383         return rv;
384
385     sscanf(buf, "%d,", &linkid);
386
387     return linkid;
388 }