source: azure_iot_hub_riscv/trunk/app_iothub_client/src/esp_at_socket.c@ 453

Last change on this file since 453 was 453, checked in by coas-nagasima, 4 years ago

ファイルを追加

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