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

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

Azure IoT への送信内容を、検出したpersonとcarの数を送信するよう変更。
Azure IoT CentralからLEDのON/OFFが出来るよう更新。

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