source: rtos_arduino/trunk/arduino_lib/libraries/ESP8266/ESP8266.cpp@ 143

Last change on this file since 143 was 143, checked in by ertl-honda, 8 years ago

Milkcocoa用に更新

File size: 17.9 KB
Line 
1/**
2 * @file ESP8266.cpp
3 * @brief The implementation of class ESP8266.
4 * @author Wu Pengfei<pengfei.wu@itead.cc>
5 * @date 2015.02
6 *
7 * @par Copyright:
8 * Copyright (c) 2015 ITEAD Intelligent Systems Co., Ltd. \n\n
9 * Copyright (C) 2015 Embedded and Real-Time Systems Laboratory
10 * Graduate School of Information Science, Nagoya Univ., JAPAN \n\n
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; either version 2 of
14 * the License, or (at your option) any later version. \n\n
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 * THE SOFTWARE.
22 */
23#include "ESP8266.h"
24
25#define LOG_OUTPUT_DEBUG (1)
26#define LOG_OUTPUT_DEBUG_PREFIX (1)
27
28#ifdef TOPPERS_WITH_ARDUINO
29#define WAIT_TIMEOUT delay(1);
30#else /* !TOPPERS_WITH_ARDUINO */
31#define WAIT_TIMEOUT
32#endif /* TOPPERS_WITH_ARDUINO */
33
34#define logDebug(arg)\
35 do {\
36 if (LOG_OUTPUT_DEBUG)\
37 {\
38 if (LOG_OUTPUT_DEBUG_PREFIX)\
39 {\
40 Serial.print("[LOG Debug: ");\
41 Serial.print((const char*)__FILE__);\
42 Serial.print(",");\
43 Serial.print((unsigned int)__LINE__);\
44 Serial.print(",");\
45 Serial.print((const char*)__FUNCTION__);\
46 Serial.print("] ");\
47 }\
48 Serial.print(arg);\
49 }\
50 } while(0)
51
52#ifdef ESP8266_USE_SOFTWARE_SERIAL
53void ESP8266::begin(SoftwareSerial &uart, uint32_t baud)
54{
55 m_puart = &uart;
56 m_baud = baud;
57 m_puart->begin(baud);
58 rx_empty();
59}
60#else
61void ESP8266::begin(HardwareSerial &uart, uint32_t baud)
62{
63 m_puart = &uart;
64 m_baud = baud;
65 m_puart->begin(baud);
66 rx_empty();
67}
68#endif
69
70bool ESP8266::kick(void)
71{
72 return eAT();
73}
74
75bool ESP8266::restart(void)
76{
77 unsigned long start;
78 if (eATRST()) {
79 m_puart->end();
80 delay(2000);
81 m_puart->begin(m_baud);
82 start = millis();
83 while (millis() - start < 3000) {
84 if (eAT()) {
85 delay(1500); /* Waiting for stable */
86 return true;
87 }
88 delay(100);
89 }
90 }
91 return false;
92}
93
94String ESP8266::getVersion(void)
95{
96 String version;
97 eATGMR(version);
98 return version;
99}
100
101bool ESP8266::setOprToStation(void)
102{
103 uint8_t mode;
104 if (!qATCWMODE(&mode)) {
105 return false;
106 }
107 if (mode == 1) {
108 return true;
109 } else {
110 if (sATCWMODE(1) && restart()) {
111 return true;
112 } else {
113 return false;
114 }
115 }
116}
117
118bool ESP8266::setOprToSoftAP(void)
119{
120 uint8_t mode;
121 if (!qATCWMODE(&mode)) {
122 return false;
123 }
124 if (mode == 2) {
125 return true;
126 } else {
127 if (sATCWMODE(2) && restart()) {
128 return true;
129 } else {
130 return false;
131 }
132 }
133}
134
135bool ESP8266::setOprToStationSoftAP(void)
136{
137 uint8_t mode;
138 if (!qATCWMODE(&mode)) {
139 return false;
140 }
141 if (mode == 3) {
142 return true;
143 } else {
144 if (sATCWMODE(3) && restart()) {
145 return true;
146 } else {
147 return false;
148 }
149 }
150}
151
152String ESP8266::getAPList(void)
153{
154 String list;
155 eATCWLAP(list);
156 return list;
157}
158
159bool ESP8266::joinAP(String ssid, String pwd)
160{
161 return sATCWJAP(ssid, pwd);
162}
163
164bool ESP8266::leaveAP(void)
165{
166 return eATCWQAP();
167}
168
169bool ESP8266::setSoftAPParam(String ssid, String pwd, uint8_t chl, uint8_t ecn)
170{
171 return sATCWSAP(ssid, pwd, chl, ecn);
172}
173
174String ESP8266::getJoinedDeviceIP(void)
175{
176 String list;
177 eATCWLIF(list);
178 return list;
179}
180
181String ESP8266::getIPStatus(void)
182{
183 String list;
184 eATCIPSTATUS(list);
185 return list;
186}
187
188String ESP8266::getLocalIP(void)
189{
190 String list;
191 eATCIFSR(list);
192 return list;
193}
194
195bool ESP8266::enableMUX(void)
196{
197 return sATCIPMUX(1);
198}
199
200bool ESP8266::disableMUX(void)
201{
202 return sATCIPMUX(0);
203}
204
205bool ESP8266::createTCP(String addr, uint32_t port)
206{
207 return sATCIPSTARTSingle("TCP", addr, port);
208}
209
210bool ESP8266::releaseTCP(void)
211{
212 return eATCIPCLOSESingle();
213}
214
215bool ESP8266::registerUDP(String addr, uint32_t port)
216{
217 return sATCIPSTARTSingle("UDP", addr, port);
218}
219
220bool ESP8266::unregisterUDP(void)
221{
222 return eATCIPCLOSESingle();
223}
224
225bool ESP8266::createTCP(uint8_t mux_id, String addr, uint32_t port)
226{
227 return sATCIPSTARTMultiple(mux_id, "TCP", addr, port);
228}
229
230bool ESP8266::releaseTCP(uint8_t mux_id)
231{
232 return sATCIPCLOSEMulitple(mux_id);
233}
234
235bool ESP8266::registerUDP(uint8_t mux_id, String addr, uint32_t port)
236{
237 return sATCIPSTARTMultiple(mux_id, "UDP", addr, port);
238}
239
240bool ESP8266::unregisterUDP(uint8_t mux_id)
241{
242 return sATCIPCLOSEMulitple(mux_id);
243}
244
245bool ESP8266::setTCPServerTimeout(uint32_t timeout)
246{
247 return sATCIPSTO(timeout);
248}
249
250bool ESP8266::startTCPServer(uint32_t port)
251{
252 if (sATCIPSERVER(1, port)) {
253 return true;
254 }
255 return false;
256}
257
258bool ESP8266::stopTCPServer(void)
259{
260 sATCIPSERVER(0);
261 restart();
262 return false;
263}
264
265bool ESP8266::startServer(uint32_t port)
266{
267 return startTCPServer(port);
268}
269
270bool ESP8266::stopServer(void)
271{
272 return stopTCPServer();
273}
274
275bool ESP8266::send(const uint8_t *buffer, uint32_t len)
276{
277 return sATCIPSENDSingle(buffer, len);
278}
279
280bool ESP8266::send(uint8_t mux_id, const uint8_t *buffer, uint32_t len)
281{
282 return sATCIPSENDMultiple(mux_id, buffer, len);
283}
284
285bool ESP8266::send(String &str)
286{
287 return sATCIPSENDSingle(str);
288}
289
290bool ESP8266::send(uint8_t mux_id, String &str)
291{
292 return sATCIPSENDMultiple(mux_id, str);
293}
294
295uint32_t ESP8266::recv(uint8_t *buffer, uint32_t buffer_size, uint32_t timeout)
296{
297 return recvPkg(buffer, buffer_size, NULL, timeout, NULL);
298}
299
300uint32_t ESP8266::recv(uint8_t mux_id, uint8_t *buffer, uint32_t buffer_size, uint32_t timeout)
301{
302 uint8_t id;
303 uint32_t ret;
304 ret = recvPkg(buffer, buffer_size, NULL, timeout, &id);
305 if (ret > 0 && id == mux_id) {
306 return ret;
307 }
308 return 0;
309}
310
311uint32_t ESP8266::recv(uint8_t *coming_mux_id, uint8_t *buffer, uint32_t buffer_size, uint32_t timeout)
312{
313 return recvPkg(buffer, buffer_size, NULL, timeout, coming_mux_id);
314}
315
316int ESP8266::dataAvailable(void)
317{
318 return (m_puart->available() > 0)? 1 : 0;
319}
320
321/*----------------------------------------------------------------------------*/
322/* +IPD,<id>,<len>:<data> */
323/* +IPD,<len>:<data> */
324
325uint32_t ESP8266::recvPkg(uint8_t *buffer, uint32_t buffer_size, uint32_t *data_len, uint32_t timeout, uint8_t *coming_mux_id)
326{
327 String data;
328 char a;
329 int32_t index_PIPDcomma = -1;
330 int32_t index_colon = -1; /* : */
331 int32_t index_comma = -1; /* , */
332 int32_t len = -1;
333 int8_t id = -1;
334 bool has_data = false;
335 uint32_t ret;
336 unsigned long start;
337 uint32_t i;
338
339 if (buffer == NULL) {
340 return 0;
341 }
342
343 start = millis();
344 while (millis() - start < timeout) {
345 if(m_puart->available() > 0) {
346 a = m_puart->read();
347 data += a;
348 }else{
349 WAIT_TIMEOUT;
350 }
351
352 index_PIPDcomma = data.indexOf("+IPD,");
353 if (index_PIPDcomma != -1) {
354 index_colon = data.indexOf(':', index_PIPDcomma + 5);
355 if (index_colon != -1) {
356 index_comma = data.indexOf(',', index_PIPDcomma + 5);
357 /* +IPD,id,len:data */
358 if (index_comma != -1 && index_comma < index_colon) {
359 id = data.substring(index_PIPDcomma + 5, index_comma).toInt();
360 if (id < 0 || id > 4) {
361 return 0;
362 }
363 len = data.substring(index_comma + 1, index_colon).toInt();
364 if (len <= 0) {
365 return 0;
366 }
367 } else { /* +IPD,len:data */
368 len = data.substring(index_PIPDcomma + 5, index_colon).toInt();
369 if (len <= 0) {
370 return 0;
371 }
372 }
373 has_data = true;
374 break;
375 }
376 }
377 }
378
379 if (has_data) {
380 i = 0;
381 ret = (uint32_t)len > buffer_size ? buffer_size : len;
382 start = millis();
383 while (millis() - start < 3000) {
384 while(m_puart->available() > 0 && i < ret) {
385 a = m_puart->read();
386 buffer[i++] = a;
387 }
388 if (i == ret) {
389 rx_empty();
390 if (data_len) {
391 *data_len = len;
392 }
393 if (index_comma != -1 && coming_mux_id) {
394 *coming_mux_id = id;
395 }
396 return ret;
397 }
398 WAIT_TIMEOUT
399 }
400 }
401 return 0;
402}
403
404void ESP8266::rx_empty(void)
405{
406 while(m_puart->available() > 0) {
407 m_puart->read();
408 }
409}
410
411String ESP8266::recvString(String target, uint32_t timeout)
412{
413 String data;
414 char a;
415 unsigned long start = millis();
416 while (millis() - start < timeout) {
417 while(m_puart->available() > 0) {
418 a = m_puart->read();
419 if(a == '\0') continue;
420 data += a;
421 }
422 if (data.indexOf(target) != -1) {
423 break;
424 }
425 WAIT_TIMEOUT
426 }
427 return data;
428}
429
430String ESP8266::recvString(String target1, String target2, uint32_t timeout)
431{
432 String data;
433 char a;
434 unsigned long start = millis();
435 while (millis() - start < timeout) {
436 while(m_puart->available() > 0) {
437 a = m_puart->read();
438 if(a == '\0') continue;
439 data += a;
440 }
441 if (data.indexOf(target1) != -1) {
442 break;
443 } else if (data.indexOf(target2) != -1) {
444 break;
445 }
446 WAIT_TIMEOUT
447 }
448 return data;
449}
450
451String ESP8266::recvString(String target1, String target2, String target3, uint32_t timeout)
452{
453 String data;
454 char a;
455 unsigned long start = millis();
456 while (millis() - start < timeout) {
457 while(m_puart->available() > 0) {
458 a = m_puart->read();
459 if(a == '\0') continue;
460 data += a;
461 }
462 if (data.indexOf(target1) != -1) {
463 break;
464 } else if (data.indexOf(target2) != -1) {
465 break;
466 } else if (data.indexOf(target3) != -1) {
467 break;
468 }
469 WAIT_TIMEOUT
470 }
471 return data;
472}
473
474bool ESP8266::recvFind(String target, uint32_t timeout)
475{
476 String data_tmp;
477 data_tmp = recvString(target, timeout);
478 if (data_tmp.indexOf(target) != -1) {
479 return true;
480 }
481 return false;
482}
483
484bool ESP8266::recvFindAndFilter(String target, String begin, String end, String &data, uint32_t timeout)
485{
486 String data_tmp;
487 data_tmp = recvString(target, timeout);
488 if (data_tmp.indexOf(target) != -1) {
489 int32_t index1 = data_tmp.indexOf(begin);
490 int32_t index2 = data_tmp.indexOf(end);
491 if (index1 != -1 && index2 != -1) {
492 index1 += begin.length();
493 data = data_tmp.substring(index1, index2);
494 return true;
495 }
496 }
497 data = "";
498 return false;
499}
500
501bool ESP8266::eAT(void)
502{
503 rx_empty();
504 m_puart->println("AT");
505 return recvFind("OK");
506}
507
508bool ESP8266::eATRST(void)
509{
510 rx_empty();
511 m_puart->println("AT+RST");
512 return recvFind("OK");
513}
514
515bool ESP8266::eATGMR(String &version)
516{
517 rx_empty();
518 m_puart->println("AT+GMR");
519 return recvFindAndFilter("OK", "\r\r\n", "\r\nOK", version);
520}
521
522bool ESP8266::qATCWMODE(uint8_t *mode)
523{
524 String str_mode;
525 bool ret;
526 if (!mode) {
527 return false;
528 }
529 rx_empty();
530 m_puart->println("AT+CWMODE?");
531 ret = recvFindAndFilter("OK", "+CWMODE:", "\r\n\r\nOK", str_mode);
532 if (ret) {
533 *mode = (uint8_t)str_mode.toInt();
534 return true;
535 } else {
536 return false;
537 }
538}
539
540bool ESP8266::sATCWMODE(uint8_t mode)
541{
542 String data;
543 rx_empty();
544 m_puart->print("AT+CWMODE=");
545 m_puart->println(mode);
546
547 data = recvString("OK", "no change");
548 if (data.indexOf("OK") != -1 || data.indexOf("no change") != -1) {
549 return true;
550 }
551 return false;
552}
553
554bool ESP8266::sATCWJAP(String ssid, String pwd)
555{
556 String data;
557 rx_empty();
558 m_puart->print("AT+CWJAP=\"");
559 m_puart->print(ssid);
560 m_puart->print("\",\"");
561 m_puart->print(pwd);
562 m_puart->println("\"");
563
564 data = recvString("OK", "FAIL", 10000);
565 if (data.indexOf("OK") != -1) {
566 return true;
567 }
568 return false;
569}
570
571bool ESP8266::eATCWLAP(String &list)
572{
573 String data;
574 rx_empty();
575 m_puart->println("AT+CWLAP");
576 return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list, 10000);
577}
578
579bool ESP8266::eATCWQAP(void)
580{
581 String data;
582 rx_empty();
583 m_puart->println("AT+CWQAP");
584 return recvFind("OK");
585}
586
587bool ESP8266::sATCWSAP(String ssid, String pwd, uint8_t chl, uint8_t ecn)
588{
589 String data;
590 rx_empty();
591 m_puart->print("AT+CWSAP=\"");
592 m_puart->print(ssid);
593 m_puart->print("\",\"");
594 m_puart->print(pwd);
595 m_puart->print("\",");
596 m_puart->print(chl);
597 m_puart->print(",");
598 m_puart->println(ecn);
599
600 data = recvString("OK", "ERROR", 5000);
601 if (data.indexOf("OK") != -1) {
602 return true;
603 }
604 return false;
605}
606
607bool ESP8266::eATCWLIF(String &list)
608{
609 String data;
610 rx_empty();
611 m_puart->println("AT+CWLIF");
612 return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list);
613}
614bool ESP8266::eATCIPSTATUS(String &list)
615{
616 String data;
617 delay(100);
618 rx_empty();
619 m_puart->println("AT+CIPSTATUS");
620 return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list);
621}
622bool ESP8266::sATCIPSTARTSingle(String type, String addr, uint32_t port)
623{
624 String data;
625 rx_empty();
626 m_puart->print("AT+CIPSTART=\"");
627 m_puart->print(type);
628 m_puart->print("\",\"");
629 m_puart->print(addr);
630 m_puart->print("\",");
631 m_puart->println(port);
632
633 data = recvString("OK", "ERROR", "ALREADY CONNECT", 10000);
634 if (data.indexOf("OK") != -1 || data.indexOf("ALREADY CONNECT") != -1) {
635 return true;
636 }
637 return false;
638}
639bool ESP8266::sATCIPSTARTMultiple(uint8_t mux_id, String type, String addr, uint32_t port)
640{
641 String data;
642 rx_empty();
643 m_puart->print("AT+CIPSTART=");
644 m_puart->print(mux_id);
645 m_puart->print(",\"");
646 m_puart->print(type);
647 m_puart->print("\",\"");
648 m_puart->print(addr);
649 m_puart->print("\",");
650 m_puart->println(port);
651
652 data = recvString("OK", "ERROR", "ALREADY CONNECT", 10000);
653 if (data.indexOf("OK") != -1 || data.indexOf("ALREADY CONNECT") != -1) {
654 return true;
655 }
656 return false;
657}
658bool ESP8266::sATCIPSENDSingle(const uint8_t *buffer, uint32_t len)
659{
660 rx_empty();
661 m_puart->print("AT+CIPSEND=");
662 m_puart->println(len);
663 if (recvFind(">", 5000)) {
664 rx_empty();
665 for (uint32_t i = 0; i < len; i++) {
666 m_puart->write(buffer[i]);
667 }
668 return recvFind("SEND OK", 10000);
669 }
670 return false;
671}
672bool ESP8266::sATCIPSENDMultiple(uint8_t mux_id, const uint8_t *buffer, uint32_t len)
673{
674 rx_empty();
675 m_puart->print("AT+CIPSEND=");
676 m_puart->print(mux_id);
677 m_puart->print(",");
678 m_puart->println(len);
679 if (recvFind(">", 5000)) {
680 rx_empty();
681 for (uint32_t i = 0; i < len; i++) {
682 m_puart->write(buffer[i]);
683 }
684 return recvFind("SEND OK", 10000);
685 }
686 return false;
687}
688bool ESP8266::sATCIPSENDSingle(String &str)
689{
690 rx_empty();
691 m_puart->print("AT+CIPSEND=");
692 m_puart->println(str.length());
693 if (recvFind(">", 5000)) {
694 rx_empty();
695 for (uint32_t i = 0; i < str.length(); i++) {
696 m_puart->write(str.charAt(i));
697 }
698 return recvFind("SEND OK", 10000);
699 }
700 return false;
701}
702bool ESP8266::sATCIPSENDMultiple(uint8_t mux_id, String &str)
703{
704 rx_empty();
705 m_puart->print("AT+CIPSEND=");
706 m_puart->print(mux_id);
707 m_puart->print(",");
708 m_puart->println(str.length());
709 if (recvFind(">", 5000)) {
710 rx_empty();
711 for (uint32_t i = 0; i < str.length(); i++) {
712 m_puart->write(str.charAt(i));
713 }
714 return recvFind("SEND OK", 10000);
715 }
716 return false;
717}
718bool ESP8266::sATCIPCLOSEMulitple(uint8_t mux_id)
719{
720 String data;
721 rx_empty();
722 m_puart->print("AT+CIPCLOSE=");
723 m_puart->println(mux_id);
724
725 data = recvString("OK", "link is not", 5000);
726 if (data.indexOf("OK") != -1 || data.indexOf("link is not") != -1) {
727 return true;
728 }
729 return false;
730}
731bool ESP8266::eATCIPCLOSESingle(void)
732{
733 rx_empty();
734 m_puart->println("AT+CIPCLOSE");
735 return recvFind("OK", 5000);
736}
737bool ESP8266::eATCIFSR(String &list)
738{
739 rx_empty();
740 m_puart->println("AT+CIFSR");
741 return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list);
742}
743bool ESP8266::sATCIPMUX(uint8_t mode)
744{
745 String data;
746 rx_empty();
747 m_puart->print("AT+CIPMUX=");
748 m_puart->println(mode);
749
750 data = recvString("OK", "Link is builded");
751 if (data.indexOf("OK") != -1) {
752 return true;
753 }
754 return false;
755}
756bool ESP8266::sATCIPSERVER(uint8_t mode, uint32_t port)
757{
758 String data;
759 if (mode) {
760 rx_empty();
761 m_puart->print("AT+CIPSERVER=1,");
762 m_puart->println(port);
763
764 data = recvString("OK", "no change");
765 if (data.indexOf("OK") != -1 || data.indexOf("no change") != -1) {
766 return true;
767 }
768 return false;
769 } else {
770 rx_empty();
771 m_puart->println("AT+CIPSERVER=0");
772 return recvFind("\r\r\n");
773 }
774}
775bool ESP8266::sATCIPSTO(uint32_t timeout)
776{
777 rx_empty();
778 m_puart->print("AT+CIPSTO=");
779 m_puart->println(timeout);
780 return recvFind("OK");
781}
782
Note: See TracBrowser for help on using the repository browser.