source: azure_iot_hub_f767zi/trunk/app_iothub_client/src/esp_at_socket.c@ 473

Last change on this file since 473 was 473, checked in by coas-nagasima, 19 months ago

lwipとESP ATの両方使えるよう変更

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 45.6 KB
Line 
1/*
2 * TOPPERS/ASP Kernel
3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Advanced Standard Profile Kernel
5 *
6 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
8 * Copyright (C) 2004-2012 by Embedded and Real-Time Systems Laboratory
9 * Graduate School of Information Science, Nagoya Univ., JAPAN
10 *
11 * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
12 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
13 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
14 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
15 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
16 * スコード中に含まれていること.
17 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
18 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
19 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
20 * の無保証規定を掲載すること.
21 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
22 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
23 * と.
24 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
25 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
26 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
27 * 報告すること.
28 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
29 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
30 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
31 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
32 * 免責すること.
33 *
34 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
35 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
36 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
37 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
38 * の責任を負わない.
39 *
40 * $Id$
41 */
42
43#include <stddef.h>
44#include <stdbool.h>
45#include <kernel.h>
46#include <t_syslog.h>
47#include <t_stdlib.h>
48#include <target_syssvc.h>
49#include <stdio.h>
50#include <stdlib.h>
51#include <ctype.h>
52#include <string.h>
53#include <time.h>
54#include "syssvc/serial.h"
55#include "syssvc/syslog.h"
56#include "kernel_cfg.h"
57#include "device.h"
58#include "monitor.h"
59#include "main.h"
60#include "lwip/inet.h"
61#include "esp_at_socket.h"
62#include "azure_c_shared_utility/esp_at_socket.h"
63#include "azure_c_shared_utility/optimize_size.h"
64
65//#define AT_DEBUG
66time_t MINIMUM_YEAR;
67
68typedef enum at_param_type_t {
69 at_param_number,
70 at_param_string,
71 at_param_symbol,
72} at_param_type_t;
73
74typedef enum at_parse_state_t {
75 at_none,
76 at_informtion,
77 at_response,
78 at_link_id,
79 at_parameter,
80 at_number,
81 at_string_str,
82 at_string_esc,
83 at_string_edq,
84 at_symbol,
85 at_line_text,
86 at_cr,
87 at_crlf,
88 at_receive_data,
89} at_parse_state_t;
90
91typedef struct esp_serial_state_t esp_serial_state_t;
92typedef bool (*set_parameter_t)(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value);
93typedef at_parse_state_t (*exec_response_t)(esp_serial_state_t *esp_state, int pos);
94
95typedef struct at_response_table_t {
96 const char *name;
97 set_parameter_t next_parameter;
98 exec_response_t exec_response;
99} at_response_table_t;
100
101typedef enum at_response_kind_t {
102 at_response_kind_no_set,
103 at_response_kind_ok,
104 at_response_kind_send_ok,
105 at_response_kind_busy,
106 at_response_kind_ready,
107 at_response_kind_progress,
108 at_response_kind_connect,
109 at_response_kind_closed,
110 at_response_kind_error,
111 at_response_kind_fail,
112 at_response_kind_already_connect,
113 at_response_kind_received,
114} at_response_kind_t;
115
116typedef enum at_symbol_kind_t {
117 at_symbol_kind_unknown,
118 at_symbol_kind_apip,
119 at_symbol_kind_apmac,
120 at_symbol_kind_staip,
121 at_symbol_kind_stamac,
122 at_symbol_kind_gateway,
123 at_symbol_kind_netmask,
124} at_symbol_kind_t;
125
126typedef enum at_connection_mode_t {
127 at_single_connection_mode,
128 at_multiple_connections_mode
129} at_connection_mode_t;
130
131typedef enum at_encryption_method_t {
132 at_encryption_method_unknown,
133 at_encryption_method_open,
134 at_encryption_method_wep,
135 at_encryption_method_wpa_psk,
136 at_encryption_method_wpa2_psk,
137 at_encryption_method_wpa_wpa2_psk,
138 at_encryption_method_wpa2_enterprise,
139} at_encryption_method_t;
140
141typedef struct esp_ap_status_t {
142 at_encryption_method_t encryption_method;
143 char ssid[36];
144 int rssi;
145 struct ether_addr mac;
146 int channel;
147 int freq_offset;
148 int freq_calibration;
149} esp_ap_status_t;
150
151typedef struct esp_ap_config_t {
152 char ssid[36];
153 char pwd[64];
154 int channel;
155 at_encryption_method_t encryption_method;
156 int max_connection;
157 int ssid_hidden;
158} esp_ap_config_t;
159
160typedef enum at_wifi_mode_t {
161 at_wifi_mode_unknown,
162 at_wifi_mode_station,
163 at_wifi_mode_soft_ap,
164 at_wifi_mode_soft_ap_station,
165}at_wifi_mode_t;
166
167typedef enum at_wifi_state_t {
168 at_wifi_state_disconnected,
169 at_wifi_state_connected,
170 at_wifi_state_got_ip,
171 at_wifi_state_busy,
172}at_wifi_state_t;
173
174typedef struct esp_socket_state_t {
175 at_wifi_mode_t wifi_mode;
176 at_wifi_state_t wifi_state;
177 at_connection_mode_t connection_mode;
178 struct ether_addr ap_mac;
179 struct in_addr ap_ip;
180 struct in_addr ap_gateway;
181 struct in_addr ap_netmask;
182 struct ether_addr sta_mac;
183 struct in_addr sta_ip;
184 struct in_addr sta_gateway;
185 struct in_addr sta_netmask;
186 char ssid[36];
187 struct ether_addr baseid;
188 int channel;
189 int rssi;
190 at_symbol_kind_t symbol_kind;
191 int ap_status_count;
192 esp_ap_status_t ap_status[10];
193 esp_ap_config_t config;
194 int link_id;
195 int length;
196 struct in_addr remote_ip;
197 in_port_t remote_port;
198 int received;
199 int lost;
200 time_t date_time;
201} esp_socket_state_t;
202
203typedef enum esp_state_t {
204 esp_state_echo_off,
205 esp_state_reset,
206 esp_state_set_station_mode,
207 esp_state_auto_connect_to_ap_off,
208 esp_state_set_multiple_connections_mode,
209 esp_state_show_remote_ip_and_port,
210 esp_state_connect_ap,
211 esp_state_update_time,
212 esp_state_get_time,
213 esp_state_done
214} esp_state_t;
215
216typedef struct esp_serial_state_t {
217 esp_state_t esp_state;
218 char *ssid;
219 char *pwd;
220 ID dtqid;
221 at_parse_state_t parse_state;
222 char string[64];
223 int string_pos;
224 int number;
225 const at_response_table_t *response;
226 at_response_kind_t response_kind;
227 int param_pos;
228 esp_socket_state_t params;
229 esp_socket_state_t current_state;
230} esp_serial_state_t;
231
232typedef enum connection_state_t {
233 connection_state_disconnected,
234 connection_state_connecting,
235 connection_state_connected,
236 connection_state_disconnecting,
237} connection_state_t;
238
239typedef struct at_connection_t {
240 int link_id;
241 bool used;
242 connection_state_t state;
243 const char *ssl;
244 bool blocking;
245 unsigned int timeout;
246 esp_serial_state_t *esp_state;
247 uint8_t *rx_buff;
248 uint32_t rx_pos_w;
249 uint32_t rx_pos_r;
250} at_connection_t;
251
252esp_serial_state_t esp_serial_state;
253extern const at_response_table_t response_table[];
254extern const int response_table_count;
255ER esp_serial_clear(esp_serial_state_t *esp_state, TMO tmo);
256ER esp_serial_read(esp_serial_state_t *esp_state, at_response_kind_t *res_kind, TMO tmo);
257ER esp_serial_write(esp_serial_state_t *esp_state, const char *text, at_response_kind_t *res_kind, TMO tmo);
258int connection_read_data(at_connection_t *connection, void *data, int len);
259
260at_connection_t connections[5] = {
261 { 0, false },
262 { 1, false },
263 { 2, false },
264 { 3, false },
265 { 4, false },
266};
267
268at_connection_t *new_connection()
269{
270 for (int i = 0; i < sizeof(connections) / sizeof(connections[0]); i++) {
271 at_connection_t *connection = &connections[i];
272 if (connection->used)
273 continue;
274
275 memset(&connection->used, 0, sizeof(*connection) - offsetof(at_connection_t, used));
276 connection->rx_buff = calloc(1, AT_CONNECTION_RX_BUFF_SIZE);
277 if (connection->rx_buff == NULL)
278 return NULL;
279
280 connection->used = true;
281 return connection;
282 }
283
284 return NULL;
285}
286
287void delete_connection(at_connection_t *connection)
288{
289#ifdef AT_DEBUG
290 printf("delete_connection %d\n", connection->link_id);
291#endif
292 free(connection->rx_buff);
293 connection->used = false;
294}
295
296at_connection_t *get_connection(int link_id)
297{
298 for (int i = 0; i < sizeof(connections) / sizeof(connections[0]); i++) {
299 if (connections[i].link_id == link_id) {
300 return &connections[i];
301 }
302 }
303
304 return NULL;
305}
306
307void init_esp_at()
308{
309 struct tm tm = {
310 0, /* tm_sec */
311 0, /* tm_min */
312 0, /* tm_hour */
313 1, /* tm_mday */
314 0, /* tm_mon */
315 2020 - 1900, /* tm_year */
316 };
317 MINIMUM_YEAR = mktime(&tm);
318
319 esp_serial_state.current_state.wifi_mode = at_wifi_mode_station;
320 esp_serial_state.dtqid = DTQ_ESP_AT;
321}
322
323const at_response_table_t *get_response(const char *name)
324{
325 const at_response_table_t *result;
326
327 result = response_table;
328 for (int i = 0; i < response_table_count; i++, result++) {
329 if (strcmp(result->name, name) == 0)
330 return result;
331 }
332
333 return NULL;
334}
335
336at_symbol_kind_t get_symbol(const char *name)
337{
338 if (strcmp("APIP", name) == 0)
339 return at_symbol_kind_apip;
340 if (strcmp("APMAC", name) == 0)
341 return at_symbol_kind_apmac;
342 if (strcmp("STAIP", name) == 0)
343 return at_symbol_kind_staip;
344 if (strcmp("STAMAC", name) == 0)
345 return at_symbol_kind_stamac;
346 if (strcmp("gateway", name) == 0)
347 return at_symbol_kind_gateway;
348 if (strcmp("netmask", name) == 0)
349 return at_symbol_kind_netmask;
350 return at_symbol_kind_unknown;
351}
352
353bool append_char(esp_serial_state_t *esp_state, int c)
354{
355 if (esp_state->string_pos >= sizeof(esp_state->string)) {
356 esp_state->string[0] = '\0';
357 return false;
358 }
359
360 esp_state->string[esp_state->string_pos++] = c;
361
362 return true;
363}
364
365bool proc_atc_res(esp_serial_state_t *esp_state, int c)
366{
367 switch (esp_state->parse_state) {
368 case at_none:
369 if (c == '+') {
370 esp_state->string_pos = 0;
371 esp_state->string[esp_state->string_pos++] = c;
372 esp_state->parse_state = at_informtion;
373 return false;
374 }
375 else if (isalpha(c) || c == '>') {
376 esp_state->string_pos = 0;
377 esp_state->string[esp_state->string_pos++] = c;
378 esp_state->parse_state = at_response;
379 if (c == '>') {
380 append_char(esp_state, '\0');
381 esp_state->response = get_response(esp_state->string);
382 if (esp_state->response != NULL) {
383#ifdef AT_DEBUG
384 printf("\033[35m%s\033[0m\r\n", esp_state->response->name);
385#endif
386 esp_state->parse_state = esp_state->response->exec_response(esp_state, esp_state->param_pos);
387 esp_state->response = NULL;
388 return true;
389 }
390 }
391 return false;
392 }
393 else if (isdigit(c)) {
394 esp_state->number = c - '0';
395 esp_state->parse_state = at_link_id;
396 return false;
397 }
398 else if (c == '\r') {
399 esp_state->parse_state = at_crlf;
400 return false;
401 }
402 return false;
403 case at_informtion:
404 if ((c == ':') || (c == ',')) {
405 append_char(esp_state, '\0');
406 esp_state->response = get_response(esp_state->string);
407 if (esp_state->response != NULL) {
408 esp_state->param_pos = 0;
409 memset(&esp_state->params, 0, sizeof(esp_state->params));
410 esp_state->parse_state = at_parameter;
411 return false;
412 }
413 }
414 else if (isalpha(c) || isdigit(c) || c == ' ') {
415 append_char(esp_state, c);
416 esp_state->parse_state = at_informtion;
417 return false;
418 }
419 break;
420 case at_response:
421 if ((c == '\r') || (c == '.')) {
422 append_char(esp_state, '\0');
423 esp_state->response = get_response(esp_state->string);
424 if (esp_state->response != NULL) {
425 esp_state->param_pos = 0;
426 memset(&esp_state->params, 0, sizeof(esp_state->params));
427 esp_state->parse_state = at_crlf;
428 return false;
429 }
430 }
431 else if (isalpha(c) || isdigit(c) || c == ' ') {
432 append_char(esp_state, c);
433 esp_state->parse_state = at_response;
434 return false;
435 }
436 break;
437 case at_link_id:
438 if (isdigit(c)) {
439 esp_state->parse_state = at_link_id;
440 esp_state->number *= 10;
441 esp_state->number += c - '0';
442 return false;
443 }
444 else if (c == ',') {
445 esp_state->param_pos = 0;
446 memset(&esp_state->params, 0, sizeof(esp_state->params));
447 esp_state->params.link_id = esp_state->number;
448 esp_state->string_pos = 0;
449 esp_state->parse_state = at_response;
450 return false;
451 }
452 break;
453 case at_parameter:
454 if (isdigit(c)) {
455 esp_state->parse_state = at_number;
456 esp_state->number = c - '0';
457 return false;
458 }
459 else if (c == '"') {
460 esp_state->string_pos = 0;
461 esp_state->string[esp_state->string_pos] = '\0';
462 esp_state->parse_state = at_string_str;
463 return false;
464 }
465 else if (isalpha(c)) {
466 esp_state->string_pos = 0;
467 esp_state->string[esp_state->string_pos++] = c;
468 esp_state->parse_state = at_line_text;
469 return false;
470 }
471 break;
472 case at_number:
473 if (isdigit(c)) {
474 esp_state->parse_state = at_number;
475 esp_state->number *= 10;
476 esp_state->number += c - '0';
477 return false;
478 }
479 else if (c == ',') {
480 esp_state->param_pos++;
481 if (esp_state->response->next_parameter(esp_state, esp_state->param_pos, at_param_number, esp_state->number)) {
482 esp_state->parse_state = at_parameter;
483 return false;
484 }
485 }
486 else if (c == ':') {
487 esp_state->param_pos++;
488 if (esp_state->response->next_parameter(esp_state, esp_state->param_pos, at_param_number, esp_state->number)) {
489#ifdef AT_DEBUG
490 printf("\033[35m%s\033[0m\r\n", esp_state->response->name);
491#endif
492 esp_state->parse_state = esp_state->response->exec_response(esp_state, esp_state->param_pos);
493 esp_state->string_pos = 0;
494 esp_state->response = NULL;
495 return true;
496 }
497 }
498 else if (c == '\r') {
499 esp_state->param_pos++;
500 if (esp_state->response->next_parameter(esp_state, esp_state->param_pos, at_param_number, esp_state->number)) {
501 esp_state->parse_state = at_crlf;
502 return false;
503 }
504 }
505 break;
506 case at_string_str:
507 if (c == '"') {
508 esp_state->parse_state = at_string_edq;
509 return false;
510 }
511 else if (c == '\\') {
512 esp_state->parse_state = at_string_esc;
513 return false;
514 }
515 else {
516 append_char(esp_state, c);
517 esp_state->parse_state = at_string_str;
518 return false;
519 }
520 break;
521 case at_string_esc:
522 append_char(esp_state, c);
523 esp_state->parse_state = at_string_str;
524 return false;
525 case at_string_edq:
526 if (c == ',') {
527 append_char(esp_state, '\0');
528 esp_state->param_pos++;
529 if (esp_state->response->next_parameter(esp_state, esp_state->param_pos, at_param_string, (intptr_t)esp_state->string)) {
530 esp_state->parse_state = at_parameter;
531 return false;
532 }
533 }
534 else if (c == '\r') {
535 append_char(esp_state, '\0');
536 esp_state->param_pos++;
537 if (esp_state->response->next_parameter(esp_state, esp_state->param_pos, at_param_string, (intptr_t)esp_state->string)) {
538 esp_state->parse_state = at_crlf;
539 return false;
540 }
541 }
542 break;
543 case at_symbol:
544 if (c == ',' || c == ':') {
545 append_char(esp_state, '\0');
546 esp_state->param_pos++;
547 if (esp_state->response->next_parameter(esp_state, esp_state->param_pos, at_param_symbol, (intptr_t)get_symbol(esp_state->string))) {
548 esp_state->parse_state = at_parameter;
549 return false;
550 }
551 }
552 else if (c == '\r') {
553 append_char(esp_state, '\0');
554 esp_state->param_pos++;
555 if (esp_state->response->next_parameter(esp_state, esp_state->param_pos, at_param_symbol, (intptr_t)get_symbol(esp_state->string))) {
556 esp_state->parse_state = at_crlf;
557 return false;
558 }
559 }
560 else if (isalpha(c) || isdigit(c) || c == ' ') {
561 append_char(esp_state, c);
562 esp_state->parse_state = at_symbol;
563 return false;
564 }
565 break;
566 case at_line_text:
567 if (c == '\r') {
568 append_char(esp_state, '\0');
569 esp_state->param_pos++;
570 if (esp_state->response->next_parameter(esp_state, esp_state->param_pos, at_param_symbol, (intptr_t)esp_state->string)) {
571 esp_state->parse_state = at_crlf;
572 return false;
573 }
574 }
575 else if (isprint(c)) {
576 append_char(esp_state, c);
577 esp_state->parse_state = at_line_text;
578 return false;
579 }
580 break;
581 case at_cr:
582 if (c == '\r') {
583 esp_state->parse_state = at_crlf;
584 return false;
585 }
586 break;
587 case at_crlf:
588 if (c == '\n') {
589 if (esp_state->response != NULL) {
590#ifdef AT_DEBUG
591 printf("\033[35m%s\033[0m\r\n", esp_state->response->name);
592#endif
593 esp_state->parse_state = esp_state->response->exec_response(esp_state, esp_state->param_pos);
594 }
595 else {
596 esp_state->parse_state = at_none;
597 }
598 esp_state->string_pos = 0;
599 esp_state->response = NULL;
600 return true;
601 }
602 else if (c == '\r' || (c == '.')) {
603 esp_state->parse_state = at_crlf;
604 return false;
605 }
606 break;
607 case at_receive_data: {
608 esp_state->current_state.received++;
609 at_connection_t *connection = get_connection(esp_state->current_state.link_id);
610 if (connection != NULL) {
611 int pos = connection->rx_pos_w + 1;
612 if (pos >= AT_CONNECTION_RX_BUFF_SIZE)
613 pos = 0;
614 if (pos != connection->rx_pos_r) {
615 connection->rx_buff[connection->rx_pos_w] = c;
616 connection->rx_pos_w = pos;
617 }
618 else {
619 esp_state->current_state.lost++;
620 }
621 }
622 else {
623 esp_state->current_state.lost++;
624 }
625 if (esp_state->current_state.received >= esp_state->current_state.length) {
626#ifdef AT_DEBUG
627 printf("\033[35mrecv:%d, lost:%d\033[0m\r\n", esp_state->current_state.received, esp_state->current_state.lost);
628#endif
629 esp_state->parse_state = at_none;
630 esp_state->response_kind = at_response_kind_received;
631 return true;
632 }
633 return false;
634 }
635 }
636#ifdef AT_DEBUG
637 if (esp_state->parse_state != at_none)
638 printf("\033[35mparse error. state:%d\033[0m\r\n", esp_state->parse_state);
639#endif
640 esp_state->parse_state = at_none;
641 esp_state->response = NULL;
642 return false;
643}
644
645ER esp_serial_clear(esp_serial_state_t *esp_state, TMO tmo)
646{
647 return ini_dtq(esp_state->dtqid);
648}
649
650ER esp_serial_read(esp_serial_state_t *esp_state, at_response_kind_t *res_kind, TMO tmo)
651{
652 ER ret;
653 intptr_t data = 0;
654 ret = trcv_dtq(esp_state->dtqid, (intptr_t *)&data, tmo);
655 if ((ret != E_OK) && (ret != E_TMOUT)) {
656 printf("trcv_dtq error %s", itron_strerror(ret));
657 }
658 *res_kind = (at_response_kind_t)data;
659 return ret;
660}
661
662ER esp_serial_write(esp_serial_state_t *esp_state, const char *text, at_response_kind_t *res_kind, TMO tmo)
663{
664 ER ret;
665
666 ret = esp_serial_clear(esp_state, 100);
667 if ((ret != E_OK) && (ret != E_TMOUT)) {
668 printf("esp_serial_clear error %s", itron_strerror(ret));
669 return ret;
670 }
671
672#ifdef AT_DEBUG
673 printf("\033[32m%s\033[0m", text);
674#endif
675 ret = serial_wri_dat(AT_PORTID, text, (uint_t)strlen(text));
676 if (ret < 0) {
677 printf("serial_wri_dat error %s", itron_strerror(ret));
678 return ret;
679 }
680
681 return esp_serial_read(esp_state, res_kind, tmo);
682}
683
684int connection_read_data(at_connection_t *connection, void *data, int len)
685{
686 esp_serial_state_t *esp_state = connection->esp_state;
687 int ret = 0;
688
689 for (unsigned char *pos = (unsigned char *)data, *end = &pos[len]; pos < end; pos++) {
690 if (connection->rx_pos_w == connection->rx_pos_r) {
691 return ret;
692 }
693
694 *pos = connection->rx_buff[connection->rx_pos_r];
695 connection->rx_pos_r++;
696 if (connection->rx_pos_r >= AT_CONNECTION_RX_BUFF_SIZE)
697 connection->rx_pos_r = 0;
698
699 ret++;
700 }
701
702 return ret;
703}
704
705static bool at_cipmux_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
706{
707 esp_socket_state_t *params = &esp_state->params;
708
709 switch (pos) {
710 case 1:
711 switch (value) {
712 case 0:
713 params->connection_mode = at_single_connection_mode;
714 return true;
715 case 1:
716 params->connection_mode = at_multiple_connections_mode;
717 return true;
718 }
719 break;
720 }
721
722 return false;
723}
724
725static at_parse_state_t at_cipmux_exec(esp_serial_state_t *esp_state, int pos)
726{
727 if (pos >= 1)
728 esp_state->current_state.connection_mode = esp_state->params.connection_mode;
729
730 return at_none;
731}
732
733static bool at_cifsr_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
734{
735 esp_socket_state_t *params = &esp_state->params;
736
737 switch (pos) {
738 case 1:
739 params->symbol_kind = (at_symbol_kind_t)value;
740 return true;
741 case 2:
742 switch (params->symbol_kind)
743 {
744 case at_symbol_kind_apip:
745 if (inet_aton((const char *)value, &params->ap_ip)) {
746 return true;
747 }
748 break;
749 case at_symbol_kind_apmac:
750 if (ether_aton_r((const char *)value, &params->ap_mac)) {
751 return true;
752 }
753 break;
754 case at_symbol_kind_staip:
755 if (inet_aton((const char *)value, &params->sta_ip)) {
756 return true;
757 }
758 break;
759 case at_symbol_kind_stamac:
760 if (ether_aton_r((const char *)value, &params->sta_mac)) {
761 return true;
762 }
763 break;
764 }
765 break;
766 }
767
768 return false;
769}
770
771static at_parse_state_t at_cifsr_exec(esp_serial_state_t *esp_state, int pos)
772{
773 if (pos < 2)
774 return at_none;
775
776 switch (esp_state->params.symbol_kind)
777 {
778 case at_symbol_kind_apip:
779 esp_state->current_state.ap_ip = esp_state->params.ap_ip;
780 break;
781 case at_symbol_kind_apmac:
782 esp_state->current_state.ap_mac = esp_state->params.ap_mac;
783 break;
784 case at_symbol_kind_staip:
785 esp_state->current_state.sta_ip = esp_state->params.sta_ip;
786 break;
787 case at_symbol_kind_stamac:
788 esp_state->current_state.sta_mac = esp_state->params.sta_mac;
789 break;
790 }
791
792 return at_none;
793}
794
795static bool at_cipap_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
796{
797 esp_socket_state_t *params = &esp_state->params;
798
799 switch (pos) {
800 case 1:
801 params->symbol_kind = (at_symbol_kind_t)value;
802 return true;
803 case 2:
804 switch (params->symbol_kind)
805 {
806 case at_symbol_kind_gateway:
807 if (inet_aton((const char *)value, &params->ap_gateway)) {
808 return true;
809 }
810 break;
811 case at_symbol_kind_netmask:
812 if (inet_aton((const char *)value, &params->ap_netmask)) {
813 return true;
814 }
815 break;
816 }
817 break;
818 }
819
820 return false;
821}
822
823static at_parse_state_t at_cipap_exec(esp_serial_state_t *esp_state, int pos)
824{
825 if (pos < 2)
826 return at_none;
827
828 switch (esp_state->params.symbol_kind)
829 {
830 case at_symbol_kind_gateway:
831 esp_state->current_state.ap_gateway = esp_state->params.ap_gateway;
832 break;
833 case at_symbol_kind_netmask:
834 esp_state->current_state.ap_netmask = esp_state->params.ap_netmask;
835 break;
836 }
837
838 return at_none;
839}
840
841static bool at_cipsntptime_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
842{
843 esp_socket_state_t *params = &esp_state->params;
844 struct tm date_time = { 0 };
845
846 switch (pos) {
847 case 1:
848 if (strptime((const char *)value, "%a %b %d %T %Y", &date_time) != NULL) {
849 printf("%04d/%02d/%02d %02d:%02d:%02d\r\n",
850 date_time.tm_year+1900, date_time.tm_mon+1, date_time.tm_mday,
851 date_time.tm_hour, date_time.tm_min, date_time.tm_sec);
852 params->date_time = mktime(&date_time);
853 return true;
854 }
855 break;
856 }
857
858 return false;
859}
860
861static at_parse_state_t at_cipsntptime_exec(esp_serial_state_t *esp_state, int pos)
862{
863 esp_socket_state_t *params = &esp_state->params;
864 struct tm current_time_val = { 0 };
865 time_t current_time = params->date_time;
866
867 if (current_time <= MINIMUM_YEAR)
868 return at_none;
869
870 esp_state->current_state.date_time = current_time;
871 gmtime_r(&current_time, &current_time_val);
872 rtc_set_time((struct tm2 *)&current_time_val);
873
874 current_time = time(NULL);
875 printf("%s\r\n", ctime(&current_time));
876
877 return at_none;
878}
879
880static bool at_cipsta_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
881{
882 esp_socket_state_t *params = &esp_state->params;
883
884 switch (pos) {
885 case 1:
886 params->symbol_kind = (at_symbol_kind_t)value;
887 return true;
888 case 2:
889 switch (params->symbol_kind)
890 {
891 case at_symbol_kind_gateway:
892 if (inet_aton((const char *)value, &params->sta_gateway)) {
893 return true;
894 }
895 break;
896 case at_symbol_kind_netmask:
897 if (inet_aton((const char *)value, &params->sta_netmask)) {
898 return true;
899 }
900 break;
901 }
902 break;
903 }
904
905 return false;
906}
907
908static at_parse_state_t at_cipsta_exec(esp_serial_state_t *esp_state, int pos)
909{
910 if (pos < 2)
911 return at_none;
912
913 switch (esp_state->params.symbol_kind)
914 {
915 case at_symbol_kind_gateway:
916 esp_state->current_state.sta_gateway = esp_state->params.sta_gateway;
917 break;
918 case at_symbol_kind_netmask:
919 esp_state->current_state.sta_netmask = esp_state->params.sta_netmask;
920 break;
921 }
922
923 return at_none;
924}
925
926static bool at_cwjap_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
927{
928 esp_socket_state_t *params = &esp_state->params;
929
930 switch (pos) {
931 case 1:
932 if (type == at_param_string) {
933 strcpy(params->ssid, (const char *)value);
934 return true;
935 }
936 break;
937 case 2:
938 if (ether_aton_r((const char *)value, &params->baseid)) {
939 return true;
940 }
941 break;
942 case 3:
943 params->channel = (int)value;
944 return true;
945 case 4:
946 params->rssi = (int)value;
947 return true;
948 break;
949 }
950
951 return false;
952}
953
954static at_parse_state_t at_cwjap_exec(esp_serial_state_t *esp_state, int pos)
955{
956 if (pos >= 1)
957 strcpy(esp_state->current_state.ssid, esp_state->params.ssid);
958
959 if (pos >= 2)
960 esp_state->current_state.baseid = esp_state->params.baseid;
961
962 if (pos >= 3)
963 esp_state->current_state.channel = esp_state->params.channel;
964
965 if (pos >= 4)
966 esp_state->current_state.rssi = esp_state->params.rssi;
967
968 return at_none;
969}
970
971static bool at_cwlap_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
972{
973 if (esp_state->params.ap_status_count >= sizeof(esp_state->params.ap_status) / sizeof(esp_state->params.ap_status[0]))
974 return false;
975
976 esp_ap_status_t *ap_status = &esp_state->params.ap_status[esp_state->params.ap_status_count];
977
978 switch (pos) {
979 case 1:
980 switch (value) {
981 case 0:
982 ap_status->encryption_method = at_encryption_method_open;
983 return true;
984 case 1:
985 ap_status->encryption_method = at_encryption_method_wep;
986 return true;
987 case 2:
988 ap_status->encryption_method = at_encryption_method_wpa_psk;
989 return true;
990 case 3:
991 ap_status->encryption_method = at_encryption_method_wpa2_psk;
992 return true;
993 case 4:
994 ap_status->encryption_method = at_encryption_method_wpa_wpa2_psk;
995 return true;
996 case 5:
997 ap_status->encryption_method = at_encryption_method_wpa2_enterprise;
998 return true;
999 }
1000 break;
1001 case 2:
1002 strcpy(ap_status->ssid, (const char *)value);
1003 return true;
1004 case 3:
1005 ap_status->rssi = (int)value;
1006 return true;
1007 break;
1008 case 4:
1009 if (ether_aton_r((const char *)value, &ap_status->mac)) {
1010 return true;
1011 }
1012 break;
1013 case 5:
1014 ap_status->channel = (int)value;
1015 return true;
1016 case 6:
1017 ap_status->freq_offset = (int)value;
1018 return true;
1019 case 7:
1020 ap_status->freq_calibration = (int)value;
1021 return true;
1022 }
1023
1024 return false;
1025}
1026
1027static at_parse_state_t at_cwlap_exec(esp_serial_state_t *esp_state, int pos)
1028{
1029 esp_state->params.ap_status_count++;
1030
1031 return at_none;
1032}
1033
1034static bool at_cwmode_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
1035{
1036 esp_socket_state_t *params = &esp_state->params;
1037
1038 switch (pos) {
1039 case 1:
1040 switch (value) {
1041 case 1:
1042 params->wifi_mode = at_wifi_mode_unknown;
1043 return true;
1044 case 2:
1045 params->wifi_mode = at_wifi_mode_station;
1046 return true;
1047 case 3:
1048 params->wifi_mode = at_wifi_mode_soft_ap;
1049 return true;
1050 case 4:
1051 params->wifi_mode = at_wifi_mode_soft_ap_station;
1052 return true;
1053 }
1054 }
1055
1056 return false;
1057}
1058
1059static at_parse_state_t at_cwmode_exec(esp_serial_state_t *esp_state, int pos)
1060{
1061 if (pos >= 1)
1062 esp_state->current_state.wifi_mode = esp_state->params.wifi_mode;
1063
1064 return at_none;
1065}
1066
1067static bool at_cwsap_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
1068{
1069 esp_ap_config_t *ap_config = &esp_state->params.config;
1070
1071 switch (pos) {
1072 case 1:
1073 strcpy(ap_config->ssid, (const char *)value);
1074 return true;
1075 case 2:
1076 strcpy(ap_config->pwd, (const char *)value);
1077 return true;
1078 case 3:
1079 ap_config->channel = (int)value;
1080 return true;
1081 case 4:
1082 switch (value) {
1083 case 0:
1084 ap_config->encryption_method = at_encryption_method_open;
1085 return true;
1086 case 1:
1087 ap_config->encryption_method = at_encryption_method_wep;
1088 return true;
1089 case 2:
1090 ap_config->encryption_method = at_encryption_method_wpa_psk;
1091 return true;
1092 case 3:
1093 ap_config->encryption_method = at_encryption_method_wpa2_psk;
1094 return true;
1095 case 4:
1096 ap_config->encryption_method = at_encryption_method_wpa_wpa2_psk;
1097 return true;
1098 case 5:
1099 ap_config->encryption_method = at_encryption_method_wpa2_enterprise;
1100 return true;
1101 }
1102 break;
1103 case 5:
1104 ap_config->max_connection = (int)value;
1105 break;
1106 case 6:
1107 switch (value) {
1108 case 0:
1109 ap_config->ssid_hidden = 0;
1110 return true;
1111 case 1:
1112 ap_config->ssid_hidden = 1;
1113 return true;
1114 }
1115 }
1116
1117 return false;
1118}
1119
1120static at_parse_state_t at_cwsap_exec(esp_serial_state_t *esp_state, int pos)
1121{
1122 return at_none;
1123}
1124
1125static bool at_ipd_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
1126{
1127 esp_socket_state_t *params = &esp_state->params;
1128
1129 switch (pos) {
1130 case 1:
1131 if ((value >= 0) && (value <= 4)) {
1132 params->link_id = (int)value;
1133 return true;
1134 }
1135 break;
1136 case 2:
1137 if ((value >= 1) && (value <= AT_CONNECTION_RX_BUFF_SIZE)) {
1138 params->length = (int)value;
1139 return true;
1140 }
1141 break;
1142 case 3:
1143 if (inet_aton((const char *)value, &params->remote_ip)) {
1144 return true;
1145 }
1146 break;
1147 case 4:
1148 if (value >= 0 && value < 65536) {
1149 params->remote_port = (in_port_t)value;
1150 return true;
1151 }
1152 break;
1153 }
1154
1155 return false;
1156}
1157
1158static at_parse_state_t at_ipd_exec(esp_serial_state_t *esp_state, int pos)
1159{
1160 if (pos >= 1)
1161 esp_state->current_state.link_id = esp_state->params.link_id;
1162 if (pos >= 2)
1163 esp_state->current_state.length = esp_state->params.length;
1164 if (pos >= 3)
1165 esp_state->current_state.remote_ip = esp_state->params.remote_ip;
1166 if (pos >= 4)
1167 esp_state->current_state.remote_port = esp_state->params.remote_port;
1168
1169 esp_state->current_state.received = 0;
1170 esp_state->current_state.lost = 0;
1171 esp_state->response_kind = at_response_kind_no_set;
1172
1173 return at_receive_data;
1174}
1175
1176static bool at_already_connect_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
1177{
1178 // 引数なし
1179 return false;
1180}
1181
1182static at_parse_state_t at_already_connect_exec(esp_serial_state_t *esp_state, int pos)
1183{
1184 at_connection_t *connection = get_connection(esp_state->params.link_id);
1185 if (connection != NULL) {
1186 connection->state = connection_state_connected;
1187 }
1188
1189 esp_state->response_kind = at_response_kind_already_connect;
1190
1191 return at_none;
1192}
1193
1194static bool at_error_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
1195{
1196 // 引数なし
1197 return false;
1198}
1199
1200static at_parse_state_t at_error_exec(esp_serial_state_t *esp_state, int pos)
1201{
1202 esp_state->response_kind = at_response_kind_error;
1203
1204 return at_none;
1205}
1206
1207static bool at_fail_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
1208{
1209 // 引数なし
1210 return false;
1211}
1212
1213static at_parse_state_t at_fail_exec(esp_serial_state_t *esp_state, int pos)
1214{
1215 esp_state->response_kind = at_response_kind_fail;
1216
1217 return at_none;
1218}
1219
1220static bool at_ok_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
1221{
1222 // 引数なし
1223 return false;
1224}
1225
1226static at_parse_state_t at_ok_exec(esp_serial_state_t *esp_state, int pos)
1227{
1228 esp_state->response_kind = at_response_kind_ok;
1229
1230 return at_none;
1231}
1232
1233static bool at_send_ok_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
1234{
1235 // 引数なし
1236 return false;
1237}
1238
1239static at_parse_state_t at_send_ok_exec(esp_serial_state_t *esp_state, int pos)
1240{
1241 esp_state->response_kind = at_response_kind_send_ok;
1242
1243 return at_none;
1244}
1245
1246static bool at_wifi_connected_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
1247{
1248 // 引数なし
1249 return false;
1250}
1251
1252static at_parse_state_t at_wifi_connected_exec(esp_serial_state_t *esp_state, int pos)
1253{
1254 esp_state->current_state.wifi_state = at_wifi_state_connected;
1255
1256 return at_none;
1257}
1258
1259static bool at_wifi_disconnect_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
1260{
1261 // 引数なし
1262 return false;
1263}
1264
1265static at_parse_state_t at_wifi_disconnect_exec(esp_serial_state_t *esp_state, int pos)
1266{
1267 esp_state->current_state.wifi_state = at_wifi_state_disconnected;
1268
1269 return at_none;
1270}
1271
1272static bool at_wifi_got_ip_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
1273{
1274 // 引数なし
1275 return false;
1276}
1277
1278static at_parse_state_t at_wifi_got_ip_exec(esp_serial_state_t *esp_state, int pos)
1279{
1280 esp_state->current_state.wifi_state = at_wifi_state_got_ip;
1281
1282 return at_none;
1283}
1284
1285static bool at_busy_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
1286{
1287 // 引数なし
1288 return false;
1289}
1290
1291static at_parse_state_t at_busy_exec(esp_serial_state_t *esp_state, int pos)
1292{
1293 esp_state->response_kind = at_response_kind_busy;
1294 esp_state->current_state.wifi_state = at_wifi_state_busy;
1295
1296 return at_none;
1297}
1298
1299static bool at_ready_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
1300{
1301 // 引数なし
1302 return false;
1303}
1304
1305static at_parse_state_t at_ready_exec(esp_serial_state_t *esp_state, int pos)
1306{
1307 esp_state->response_kind = at_response_kind_ready;
1308 esp_state->current_state.wifi_state = at_wifi_state_disconnected;
1309
1310 return at_none;
1311}
1312
1313static bool at_progress_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
1314{
1315 // 引数なし
1316 return false;
1317}
1318
1319static at_parse_state_t at_progress_exec(esp_serial_state_t *esp_state, int pos)
1320{
1321 esp_state->response_kind = at_response_kind_progress;
1322
1323 return at_none;
1324}
1325
1326static bool at_connect_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
1327{
1328 // 引数なし
1329 return false;
1330}
1331
1332static at_parse_state_t at_connect_exec(esp_serial_state_t *esp_state, int pos)
1333{
1334 at_connection_t *connection = get_connection(esp_state->params.link_id);
1335 if (connection != NULL) {
1336 connection->state = connection_state_connected;
1337 }
1338
1339 esp_state->response_kind = at_response_kind_connect;
1340
1341 return at_none;
1342}
1343
1344static bool at_closed_set_param(esp_serial_state_t *esp_state, int pos, at_param_type_t type, intptr_t value)
1345{
1346 // 引数なし
1347 return false;
1348}
1349
1350static at_parse_state_t at_closed_exec(esp_serial_state_t *esp_state, int pos)
1351{
1352 at_connection_t *connection = get_connection(esp_state->params.link_id);
1353 if (connection != NULL) {
1354 connection->state = connection_state_disconnected;
1355 }
1356
1357 esp_state->response_kind = at_response_kind_closed;
1358
1359 return at_none;
1360}
1361
1362const at_response_table_t response_table[] = {
1363 { "+CIPMUX", at_cipmux_set_param, at_cipmux_exec },
1364 { "+CIFSR", at_cifsr_set_param, at_cifsr_exec },
1365 { "+CIPAP", at_cipap_set_param, at_cipap_exec },
1366 { "+CIPSNTPTIME", at_cipsntptime_set_param, at_cipsntptime_exec },
1367 { "+CIPSTA", at_cipsta_set_param, at_cipsta_exec },
1368 { "+CWJAP", at_cwjap_set_param, at_cwjap_exec },
1369 { "+CWLAP", at_cwlap_set_param, at_cwlap_exec },
1370 { "+CWMODE", at_cwmode_set_param, at_cwmode_exec },
1371 { "+CWSAP", at_cwsap_set_param, at_cwsap_exec },
1372 { "+IPD", at_ipd_set_param, at_ipd_exec },
1373 { "ALREADY CONNECT", at_already_connect_set_param, at_already_connect_exec },
1374 { "ERROR", at_error_set_param, at_error_exec },
1375 { "FAIL", at_fail_set_param, at_fail_exec },
1376 { "OK", at_ok_set_param, at_ok_exec },
1377 { "SEND OK", at_send_ok_set_param, at_send_ok_exec },
1378 { "WIFI CONNECTED", at_wifi_connected_set_param, at_wifi_connected_exec },
1379 { "WIFI DISCONNECT", at_wifi_disconnect_set_param, at_wifi_disconnect_exec },
1380 { "WIFI GOT IP", at_wifi_got_ip_set_param, at_wifi_got_ip_exec },
1381 { "busy p", at_busy_set_param, at_busy_exec },
1382 { "ready", at_ready_set_param, at_ready_exec },
1383 { ">", at_progress_set_param, at_progress_exec },
1384 { "CONNECT", at_connect_set_param, at_connect_exec},
1385 { "CLOSED", at_closed_set_param, at_closed_exec},
1386};
1387const int response_table_count = sizeof(response_table) / sizeof(response_table[0]);
1388
1389int esp_at_rx_handler(void *data, int len)
1390{
1391 esp_serial_state_t *esp_state = &esp_serial_state;
1392 uint8_t *c = (uint8_t *)data;
1393 ER ret;
1394
1395 for (uint8_t *end = &c[len]; c < end; c++) {
1396 if (proc_atc_res(esp_state, *c)) {
1397 if (esp_state->response_kind != at_response_kind_no_set) {
1398 ret = tsnd_dtq(esp_state->dtqid, (intptr_t)esp_state->response_kind, 20);
1399 if (ret != E_OK) {
1400 printf("snd_dtq error %s\n", itron_strerror(ret));
1401 }
1402 esp_state->response_kind = at_response_kind_no_set;
1403 }
1404 }
1405 }
1406
1407 return (int)((intptr_t)c - (intptr_t)data);
1408}
1409
1410void set_ssid_pwd(const char *ssid, const char *pwd)
1411{
1412 esp_serial_state_t *esp_state = &esp_serial_state;
1413
1414 free(esp_state->ssid);
1415 esp_state->ssid = strdup(ssid);
1416 free(esp_state->pwd);
1417 esp_state->pwd = strdup(pwd);
1418}
1419
1420bool prepare_esp_at()
1421{
1422 esp_serial_state_t *esp_state = &esp_serial_state;
1423 ER ret;
1424 char temp[64];
1425 int tmo = 0;
1426 at_response_kind_t res_kind = at_response_kind_no_set;
1427
1428 if (esp_state->current_state.wifi_state != at_wifi_state_got_ip)
1429 esp_state->esp_state = esp_state_echo_off;
1430
1431retry:
1432 ret = esp_serial_clear(esp_state, 100);
1433 if ((ret != E_OK) && (ret != E_TMOUT))
1434 return false;
1435
1436 switch (esp_state->esp_state) {
1437 case esp_state_reset:
1438 ret = esp_serial_write(esp_state, "AT+RST\r\n", &res_kind, 10000);
1439 if ((ret != E_OK) || (res_kind != at_response_kind_ok)) {
1440 printf("reset error %s %d\n", itron_strerror(ret), res_kind);
1441 return false;
1442 }
1443
1444 ret = esp_serial_read(esp_state, &res_kind, 10000);
1445 if ((ret != E_OK) || (res_kind != at_response_kind_ready)) {
1446 printf("ready error %s %d\n", itron_strerror(ret), res_kind);
1447 return false;
1448 }
1449 esp_state->esp_state = esp_state_echo_off;
1450 case esp_state_echo_off:
1451 ret = esp_serial_write(esp_state, "ATE0\r\n", &res_kind, 10000);
1452 if ((ret != E_OK) || (res_kind != at_response_kind_ok)) {
1453 printf("echo off error %s %d\n", itron_strerror(ret), res_kind);
1454 break;
1455 }
1456 esp_state->esp_state = esp_state_set_station_mode;
1457 case esp_state_set_station_mode:
1458 ret = esp_serial_write(esp_state, "AT+CWMODE=1\r\n", &res_kind, 10000);
1459 if ((ret != E_OK) || (res_kind != at_response_kind_ok)) {
1460 printf("set station mode error %s %d\n", itron_strerror(ret), res_kind);
1461 break;
1462 }
1463 esp_state->esp_state = esp_state_auto_connect_to_ap_off;
1464 case esp_state_auto_connect_to_ap_off:
1465 ret = esp_serial_write(esp_state, "AT+CWAUTOCONN=0\r\n", &res_kind, 10000);
1466 if ((ret != E_OK) || (res_kind != at_response_kind_ok)) {
1467 printf("auto connect off error %s %d\n", itron_strerror(ret), res_kind);
1468 break;
1469 }
1470 esp_state->esp_state = esp_state_set_multiple_connections_mode;
1471 case esp_state_set_multiple_connections_mode:
1472 ret = esp_serial_write(esp_state, "AT+CIPMUX=1\r\n", &res_kind, 10000);
1473 if ((ret != E_OK) || (res_kind != at_response_kind_ok)) {
1474 printf("set multiple connections mode error %s %d\n", itron_strerror(ret), res_kind);
1475 break;
1476 }
1477 esp_state->esp_state = esp_state_show_remote_ip_and_port;
1478 case esp_state_show_remote_ip_and_port:
1479 ret = esp_serial_write(esp_state, "AT+CIPDINFO=1\r\n", &res_kind, 10000);
1480 if ((ret != E_OK) || (res_kind != at_response_kind_ok)) {
1481 printf("show remote ip/port error %s %d\n", itron_strerror(ret), res_kind);
1482 break;
1483 }
1484 esp_state->esp_state = esp_state_connect_ap;
1485 case esp_state_connect_ap:
1486 if ((esp_state->ssid == NULL) || (esp_state->pwd == NULL)) {
1487 printf("ssid psw error %s %d\n", itron_strerror(ret), res_kind);
1488 break;
1489 }
1490
1491 sprintf(temp, "AT+CWJAP=\"%s\",\"%s\"\r\n", esp_state->ssid, esp_state->pwd);
1492 ret = esp_serial_write(esp_state, temp, &res_kind, 20000);
1493 if ((ret != E_OK) || (res_kind != at_response_kind_ok)) {
1494 printf("connect wifi error %s %d\n", itron_strerror(ret), res_kind);
1495 break;
1496 }
1497 esp_state->esp_state = esp_state_update_time;
1498 case esp_state_update_time:
1499 sprintf(temp, "AT+CIPSNTPCFG=%d,%d,\"%s\"\r\n", 1, 9, "ntp.nict.jp");
1500 ret = esp_serial_write(esp_state, temp, &res_kind, 10000);
1501 if ((ret != E_OK) || (res_kind != at_response_kind_ok)) {
1502 printf("ntp config error %s %d\n", itron_strerror(ret), res_kind);
1503 break;
1504 }
1505 esp_state->esp_state = esp_state_get_time;
1506 case esp_state_get_time:
1507 ret = esp_serial_write(esp_state, "AT+CIPSNTPTIME?\r\n", &res_kind, 10000);
1508 if ((ret != E_OK) || (res_kind != at_response_kind_ok)) {
1509 printf("get time error %s %d\n", itron_strerror(ret), res_kind);
1510 break;
1511 }
1512 if (esp_state->current_state.date_time <= MINIMUM_YEAR) {
1513 tmo++;
1514 if (tmo < 10) {
1515 printf("retry to get time %s\n", ctime(NULL));
1516 dly_tsk(1000);
1517 esp_state->esp_state = esp_state_get_time;
1518 goto retry;
1519 }
1520 }
1521 esp_state->esp_state = esp_state_done;
1522 case esp_state_done: {
1523 time_t ntp = esp_state->current_state.date_time;
1524 time_t local = time(NULL);
1525 if ((local > ntp) && ((local - ntp) > 60 * 60)) {
1526 esp_state->esp_state = esp_state_get_time;
1527 goto retry;
1528 }
1529 return true;
1530 }
1531 default:
1532 esp_state->esp_state = esp_state_echo_off;
1533 goto retry;
1534 }
1535
1536 if (res_kind == at_response_kind_busy){
1537 esp_state->esp_state = esp_state_reset;
1538 goto retry;
1539 }
1540
1541 printf("prepare error %s %d\n", itron_strerror(ret), res_kind);
1542 esp_state->esp_state = esp_state_echo_off;
1543 return false;
1544}
1545
1546ESP_AT_SOCKET_HANDLE esp_at_socket_create(bool ssl)
1547{
1548 at_connection_t *connection = new_connection();
1549 if (connection == NULL)
1550 return NULL;
1551
1552 connection->ssl = ssl ? "SSL" : "TCP";
1553 connection->esp_state = &esp_serial_state;
1554
1555 return (ESP_AT_SOCKET_HANDLE)connection;
1556}
1557
1558void esp_at_socket_set_blocking(ESP_AT_SOCKET_HANDLE espAtSocketHandle, bool blocking, unsigned int timeout)
1559{
1560 at_connection_t *connection = (at_connection_t *)espAtSocketHandle;
1561
1562 connection->blocking = blocking;
1563 connection->timeout = timeout;
1564
1565#ifdef AT_DEBUG
1566 printf("\033[35mblocking:%s timeout:%d\033[0m\n", blocking ? "true" : "false", timeout);
1567#endif
1568}
1569
1570void esp_at_socket_destroy(ESP_AT_SOCKET_HANDLE espAtSocketHandle)
1571{
1572 at_connection_t *connection = (at_connection_t *)espAtSocketHandle;
1573
1574 delete_connection(connection);
1575}
1576
1577extern int use_wifi;
1578
1579int esp_at_socket_connect(ESP_AT_SOCKET_HANDLE espAtSocketHandle, const char *host, const int port)
1580{
1581 at_connection_t *connection = (at_connection_t *)espAtSocketHandle;
1582 at_response_kind_t res_kind;
1583
1584 if (connection->state == connection_state_connected) {
1585 printf("esp_at_socket_connect state error %d\n", connection->state);
1586 return 0;
1587 }
1588
1589 if (!prepare_esp_at()) {
1590 printf("prepare_esp_at error\n");
1591 use_wifi = 0;
1592 return -MU_FAILURE;
1593 }
1594 use_wifi = 1;
1595
1596 connection->state = connection_state_connecting;
1597
1598 ER ret;
1599 char temp[128];
1600 sprintf(temp, "AT+CIPSTART=%d,\"%s\",\"%s\",%d\r\n", connection->link_id, connection->ssl, host, port);
1601 ret = esp_serial_write(connection->esp_state, temp, &res_kind, 10000);
1602 if ((ret != E_OK) || (res_kind != at_response_kind_connect)) {
1603 printf("connect error connect %s %d\n", itron_strerror(ret), res_kind);
1604 return -MU_FAILURE;
1605 }
1606 ret = esp_serial_read(connection->esp_state, &res_kind, 10000);
1607 if ((ret != E_OK) || (res_kind != at_response_kind_ok)) {
1608 printf("connect error done %s %d\n", itron_strerror(ret), res_kind);
1609 return -MU_FAILURE;
1610 }
1611#ifdef AT_DEBUG
1612 printf("\033[35mconnected !\033[0m\n");
1613#endif
1614 return 0;
1615}
1616
1617bool esp_at_socket_is_connected(ESP_AT_SOCKET_HANDLE espAtSocketHandle)
1618{
1619 at_connection_t *connection = (at_connection_t *)espAtSocketHandle;
1620
1621 return connection->state == connection_state_connected;
1622}
1623
1624void esp_at_socket_close(ESP_AT_SOCKET_HANDLE espAtSocketHandle)
1625{
1626 at_connection_t *connection = (at_connection_t *)espAtSocketHandle;
1627 at_response_kind_t res_kind;
1628
1629 if (connection->state == connection_state_disconnected) {
1630 printf("esp_at_socket_close state error %d\n", connection->state);
1631 return;
1632 }
1633
1634 connection->state = connection_state_disconnecting;
1635
1636 ER ret;
1637 char temp[64];
1638 sprintf(temp, "AT+CIPCLOSE=%d\r\n", connection->link_id);
1639 ret = esp_serial_write(connection->esp_state, temp, &res_kind, 10000);
1640 if (ret == E_OK) {
1641 if (res_kind == at_response_kind_closed) {
1642 ret = esp_serial_read(connection->esp_state, &res_kind, 10000);
1643 }
1644 if ((ret == E_OK) && (res_kind == at_response_kind_ok)) {
1645 return;
1646 }
1647}
1648
1649 printf("close error %s %d\n", itron_strerror(ret), res_kind);
1650}
1651
1652int esp_at_socket_send(ESP_AT_SOCKET_HANDLE espAtSocketHandle, const char *data, int length)
1653{
1654 at_connection_t *connection = (at_connection_t *)espAtSocketHandle;
1655 at_response_kind_t res_kind;
1656
1657 if (connection->state != connection_state_connected) {
1658 printf("esp_at_socket_send state error %d\n", connection->state);
1659 return -MU_FAILURE;
1660 }
1661
1662 ER ret;
1663 char temp[64];
1664 sprintf(temp, "AT+CIPSEND=%d,%d\r\n", connection->link_id, length);
1665 ret = esp_serial_write(connection->esp_state, temp, &res_kind, 10000);
1666 if ((ret != E_OK) || (res_kind != at_response_kind_ok)) {
1667 printf("send error command %s %d\n", itron_strerror(ret), res_kind);
1668 return -MU_FAILURE;
1669 }
1670 do {
1671 ret = esp_serial_read(connection->esp_state, &res_kind, 10000);
1672 if ((ret != E_OK) || ((res_kind != at_response_kind_ok)
1673 && (res_kind != at_response_kind_progress))) {
1674 printf("send error progress %s %d\n", itron_strerror(ret), res_kind);
1675 return -MU_FAILURE;
1676 }
1677 } while(res_kind == at_response_kind_ok);
1678 ret = serial_wri_dat(AT_PORTID, data, length);
1679 if (ret < 0) {
1680 printf("send error write data %s\n", itron_strerror(ret));
1681 return -MU_FAILURE;
1682 }
1683 do {
1684 ret = esp_serial_read(connection->esp_state, &res_kind, 60000);
1685 if (ret != E_OK) {
1686 printf("send error done %s\n", itron_strerror(ret));
1687 break;
1688 }
1689 if (res_kind == at_response_kind_send_ok)
1690 return length;
1691 } while ((res_kind == at_response_kind_no_set)
1692 || (res_kind == at_response_kind_ok));
1693
1694 printf("send error done kind=%d\n", res_kind);
1695
1696 return -MU_FAILURE;
1697}
1698
1699int esp_at_socket_receive(ESP_AT_SOCKET_HANDLE espAtSocketHandle, char *data, int length)
1700{
1701 at_connection_t *connection = (at_connection_t *)espAtSocketHandle;
1702
1703 if (connection->state != connection_state_connected) {
1704 printf("esp_at_socket_receive state error %d\n", connection->state);
1705 return -MU_FAILURE;
1706 }
1707
1708 int ret;
1709 ret = connection_read_data(connection, data, length);
1710 if (ret < 0) {
1711 printf("receive error %s\n", itron_strerror(ret));
1712 return -MU_FAILURE;
1713 }
1714#ifdef AT_DEBUG
1715 if (ret > 0)
1716 printf("\033[35mreceived %d\033[0m\n", ret);
1717#endif
1718 return ret;
1719}
Note: See TracBrowser for help on using the repository browser.