source: rtos_arduino/trunk/arduino_lib/libraries/ESP8266_Arudino_AT/ESP8266.cpp@ 189

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

Thinkgspeakのサポート

File size: 28.4 KB
Line 
1/**
2 * @file ESP8266.cpp
3 * @brief The implementation of class ESP8266.
4 * @author Wu Pengfei<pengfei.wu@itead.cc>, Shinya Honda<honda@ertl.jp>
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#define MUXID_ANY 255
29#define MUXID_SINGLE 0
30
31#ifdef TOPPERS_WITH_ARDUINO
32#define WAIT_TIMEOUT delay(1);
33#define ENTER_CRITICAL
34#define LEAVE_CRITICAL
35#else /* !TOPPERS_WITH_ARDUINO */
36#define WAIT_TIMEOUT
37#define ENTER_CRITICAL
38#define LEAVE_CRITICAL
39#endif /* TOPPERS_WITH_ARDUINO */
40
41
42#ifdef TOPPERS_WITH_ARDUINO
43#define WAIT_TIMEOUT delay(1);
44#else /* !TOPPERS_WITH_ARDUINO */
45#define WAIT_TIMEOUT
46#endif /* TOPPERS_WITH_ARDUINO */
47
48#define logDebug(arg)\
49 do {\
50 if (LOG_OUTPUT_DEBUG)\
51 {\
52 if (LOG_OUTPUT_DEBUG_PREFIX)\
53 {\
54 Serial.print("[LOG Debug: ");\
55 Serial.print((const char*)__FILE__);\
56 Serial.print(",");\
57 Serial.print((unsigned int)__LINE__);\
58 Serial.print(",");\
59 Serial.print((const char*)__FUNCTION__);\
60 Serial.print("] ");\
61 }\
62 Serial.print(arg);\
63 }\
64 } while(0)
65
66ESP8266_RingBuffer::ESP8266_RingBuffer(void)
67{
68 free();
69 buffer = NULL;
70}
71
72void ESP8266_RingBuffer::init(void)
73{
74 free();
75 if(buffer!=NULL) {
76 ::free(buffer);
77 buffer = NULL;
78 }
79}
80
81bool ESP8266_RingBuffer::write(uint8_t c)
82{
83 if (len == ESP8266_RINGBUFFER_SIZE) {return false;}
84
85 if (buffer == NULL) {
86 buffer = (uint8_t*)malloc(ESP8266_RINGBUFFER_SIZE);
87 if(buffer == NULL) {return false;}
88 }
89
90 buffer[tail++] = c;
91 len++;
92
93 if (tail == ESP8266_RINGBUFFER_SIZE) {
94 tail = 0;
95 }
96 return true;
97}
98
99uint8_t ESP8266_RingBuffer::read(void)
100{
101 uint8_t c;
102 if (len == 0) {return 0;}
103 c = buffer[head++];
104 len--;
105 if (head == ESP8266_RINGBUFFER_SIZE) {
106 head = 0;
107 }
108 return c;
109}
110
111uint32_t ESP8266_RingBuffer::copy(uint8_t *pdata, uint32_t size)
112{
113 uint32_t ret;
114 uint32_t pdata_index = 0;
115
116 /* copy size */
117 ret = (len < size)? len : size;
118
119 while((pdata_index < ret)) {
120 pdata[pdata_index++] = buffer[head++];
121 if (head == ESP8266_RINGBUFFER_SIZE) {
122 head = 0;
123 }
124 }
125
126 len -= ret;
127
128 return ret;
129}
130
131uint8_t ESP8266_RingBuffer::peek(void)
132{
133 if (len == 0) {return 0;}
134 return buffer[head];
135}
136
137void ESP8266::initialize_status(void)
138{
139 wifi_status = ESP8266_STATUS_DISCONNECTED;
140 connection_bitmap = 0;
141 mux_mode = false;
142 rx_cmd = "";
143 for(int i = 0; i < ESP8266_NUM_CONNECTION; i++){
144 rx_buffer[i].init();
145 }
146}
147
148#ifdef ESP8266_USE_SOFTWARE_SERIAL
149int ESP8266::begin(SoftwareSerial &uart, uint32_t baud)
150#else /* !ESP8266_USE_SOFTWARE_SERIAL */
151int ESP8266::begin(HardwareSerial &uart, uint32_t baud)
152#endif /* ESP8266_USE_SOFTWARE_SERIAL */
153{
154 String version;
155 int ret = 0;
156
157 ENTER_CRITICAL;
158 m_puart = &uart;
159 m_baud = baud;
160 m_puart->begin(baud);
161 initialize_status();
162 rx_empty();
163
164 if (eAT()) {
165 eATGMR(version);
166 if(version.indexOf(ESP8266_SUPPORT_VERSION) == -1) {
167 ret = 2;
168 }
169 }
170 else {
171 ret = 1;
172 }
173 LEAVE_CRITICAL;
174
175 return ret;
176}
177
178bool ESP8266::kick(void)
179{
180 bool ret;
181
182 ENTER_CRITICAL;
183 ret = eAT();
184 LEAVE_CRITICAL;
185
186 return ret;
187}
188
189bool ESP8266::_restart(void)
190{
191 unsigned long start;
192 bool ret = false;
193
194 initialize_status();
195 if (eATRST()) {
196 m_puart->end();
197 delay(2000);
198 m_puart->begin(m_baud);
199 start = millis();
200 while (millis() - start < 3000) {
201 if (eAT()) {
202 delay(1500); /* Waiting for stable */
203 ret = true;
204 }
205 delay(100);
206 }
207 }
208
209 return ret;
210}
211
212bool ESP8266::restart(void)
213{
214 bool ret;
215
216 ENTER_CRITICAL;
217 ret = _restart();
218 LEAVE_CRITICAL;
219
220 return ret;
221}
222
223String ESP8266::getVersion(void)
224{
225 String version;
226
227 ENTER_CRITICAL;
228 eATGMR(version);
229 LEAVE_CRITICAL;
230
231 return version;
232}
233
234bool ESP8266::setOprToStation(void)
235{
236 uint8_t mode;
237 bool ret = false;
238
239 ENTER_CRITICAL;
240 if (qATCWMODE_CUR(&mode)) {
241 if (mode == ESP8266_WMODE_STATION) {
242 ret = true;
243 } else {
244 if (sATCWMODE_CUR(ESP8266_WMODE_STATION) && _restart()) {
245 ret = true;
246 }
247 }
248 }
249 LEAVE_CRITICAL;
250
251 return ret;
252}
253
254bool ESP8266::setOprToSoftAP(void)
255{
256 uint8_t mode;
257 bool ret = false;
258
259 ENTER_CRITICAL;
260 if (qATCWMODE_CUR(&mode)) {
261 if (mode == ESP8266_WMODE_SOFTAP) {
262 ret = true;
263 } else {
264 if (sATCWMODE_CUR(ESP8266_WMODE_SOFTAP) && _restart()) {
265 ret = true;
266 }
267 }
268 }
269 LEAVE_CRITICAL;
270
271 return ret;
272}
273
274bool ESP8266::setOprToStationSoftAP(void)
275{
276 uint8_t mode;
277 bool ret = false;
278
279 ENTER_CRITICAL;
280 if (qATCWMODE_CUR(&mode)) {
281 if (mode == ESP8266_WMODE_AP_STATION) {
282 ret = true;
283 } else {
284 if (sATCWMODE_CUR(ESP8266_WMODE_AP_STATION) && restart()) {
285 ret = true;
286 }
287 }
288 }
289 LEAVE_CRITICAL;
290
291 return ret;
292}
293
294String ESP8266::getAPList(void)
295{
296 String list;
297
298 ENTER_CRITICAL;
299 eATCWLAP(list);
300 LEAVE_CRITICAL;
301
302 return list;
303}
304
305bool ESP8266::joinAP(String ssid, String pwd)
306{
307 bool ret;
308
309 ENTER_CRITICAL;
310 ret = sATCWJAP_CUR(ssid, pwd);
311 LEAVE_CRITICAL;
312
313 return ret;
314}
315
316bool ESP8266::leaveAP(void)
317{
318 bool ret;
319
320 ENTER_CRITICAL;
321 ret = eATCWQAP();
322 LEAVE_CRITICAL;
323
324 return ret;
325}
326
327bool ESP8266::setSoftAPParam(String ssid, String pwd, uint8_t chl, uint8_t ecn)
328{
329 bool ret;
330
331 ENTER_CRITICAL;
332 ret = sATCWSAP_CUR(ssid, pwd, chl, ecn);
333 LEAVE_CRITICAL;
334
335 return ret;
336}
337
338String ESP8266::getJoinedDeviceIP(void)
339{
340 String list;
341
342 ENTER_CRITICAL;
343 eATCWLIF(list);
344 LEAVE_CRITICAL;
345
346 return list;
347}
348
349String ESP8266::getIPStatus(void)
350{
351 String list;
352
353 ENTER_CRITICAL;
354 eATCIPSTATUS(list);
355 LEAVE_CRITICAL;
356
357 return list;
358}
359
360String ESP8266::getLocalIP(void)
361{
362 String list = "";
363 int32_t index_start = -1;
364 int32_t index_end = -1;
365
366 ENTER_CRITICAL;
367 eATCIFSR(list);
368 index_start = list.indexOf('\"');
369 index_end = list.indexOf('\"', list.indexOf('\"')+1);
370 if ((index_start != -1) && (index_end != -1)) {
371 list = list.substring(index_start+1, index_end);
372 }
373 LEAVE_CRITICAL;
374
375 return list;
376}
377
378bool ESP8266::enableMUX(void)
379{
380 bool ret = false;
381
382 ENTER_CRITICAL;
383 if (sATCIPMUX(1)) {
384 mux_mode = true;
385 ret = true;
386 }
387 LEAVE_CRITICAL;
388
389 return ret;
390}
391
392bool ESP8266::disableMUX(void)
393{
394 bool ret = false;
395
396 ENTER_CRITICAL;
397 if (sATCIPMUX(0)){
398 mux_mode = false;
399 ret = true;
400 }
401 LEAVE_CRITICAL;
402
403 return ret;
404}
405
406bool ESP8266::createTCP(String addr, uint32_t port)
407{
408 bool ret = false;
409 if (mux_mode) return false;
410
411 ENTER_CRITICAL;
412 if((ret = sATCIPSTARTSingle("TCP", addr, port))) {
413 connection_bitmap = 1;
414 }
415 LEAVE_CRITICAL;
416
417 return ret;
418}
419
420bool ESP8266::releaseTCP(void)
421{
422 bool ret = false;
423 if (mux_mode) return false;
424
425 ENTER_CRITICAL;
426 if((ret = eATCIPCLOSESingle())) {
427 connection_bitmap = 0;
428 rx_buffer[MUXID_SINGLE].free();
429 }
430 LEAVE_CRITICAL;
431
432 return ret;
433}
434
435bool ESP8266::registerUDP(String addr, uint32_t port)
436{
437 bool ret = false;
438 if (mux_mode) return false;
439
440 ENTER_CRITICAL;
441 if((ret = sATCIPSTARTSingle("UDP", addr, port))) {
442 connection_bitmap = 1;
443 }
444 LEAVE_CRITICAL;
445
446 return ret;
447}
448
449bool ESP8266::unregisterUDP(void)
450{
451 bool ret = false;
452 if (mux_mode) return false;
453
454 ENTER_CRITICAL;
455 if((ret = eATCIPCLOSESingle())) {
456 connection_bitmap = 0;
457 rx_buffer[MUXID_SINGLE].free();
458 }
459 LEAVE_CRITICAL;
460
461 return ret;
462}
463
464bool ESP8266::createTCP(uint8_t mux_id, String addr, uint32_t port)
465{
466 bool ret = false;
467 if (!(mux_id < ESP8266_NUM_CONNECTION)) return false;
468 if (!mux_mode) return false;
469
470 ENTER_CRITICAL;
471 if((ret = sATCIPSTARTMultiple(mux_id, "TCP", addr, port))) {
472 connection_bitmap |= 1 << mux_id;
473 }
474 LEAVE_CRITICAL;
475
476 return ret;
477}
478
479bool ESP8266::releaseTCP(uint8_t mux_id)
480{
481 bool ret;
482 if (!(mux_id < ESP8266_NUM_CONNECTION)) return false;
483 if (!mux_mode) return false;
484
485 ENTER_CRITICAL;
486 if ((ret = sATCIPCLOSEMulitple(mux_id))) {
487 connection_bitmap &= ~(1 << mux_id);
488 rx_buffer[mux_id].free();
489 }
490 LEAVE_CRITICAL;
491
492 return ret;
493}
494
495bool ESP8266::registerUDP(uint8_t mux_id, String addr, uint32_t port)
496{
497 bool ret;
498 if (!(mux_id < ESP8266_NUM_CONNECTION)) return false;
499 if (!mux_mode) return false;
500
501 ENTER_CRITICAL;
502 if ((ret = sATCIPSTARTMultiple(mux_id, "UDP", addr, port))) {
503 connection_bitmap |= 1 << mux_id;
504 }
505 LEAVE_CRITICAL;
506
507 return ret;
508}
509
510bool ESP8266::unregisterUDP(uint8_t mux_id)
511{
512 bool ret;
513 if (!(mux_id < ESP8266_NUM_CONNECTION)) return false;
514 if (!mux_mode) return false;
515
516 ENTER_CRITICAL;
517 if ((ret = sATCIPCLOSEMulitple(mux_id))) {
518 connection_bitmap &= ~(1 << mux_id);
519 rx_buffer[mux_id].free();
520 }
521 LEAVE_CRITICAL;
522
523 return ret;
524}
525
526bool ESP8266::setTCPServerTimeout(uint32_t timeout)
527{
528 bool ret;
529 if (!mux_mode) return false;
530
531 ENTER_CRITICAL;
532 ret = sATCIPSTO(timeout);
533 LEAVE_CRITICAL;
534
535 return ret;
536}
537
538bool ESP8266::startTCPServer(uint32_t port)
539{
540 bool ret = false;
541 if (!mux_mode) return false;
542
543 ENTER_CRITICAL;
544 ret = sATCIPSERVER(1, port);
545 LEAVE_CRITICAL;
546
547 return ret;
548}
549
550bool ESP8266::stopTCPServer(void)
551{
552 bool ret = false;
553
554 ENTER_CRITICAL;
555 ret = sATCIPSERVER(0);
556 LEAVE_CRITICAL;
557
558 return ret;
559}
560
561bool ESP8266::startServer(uint32_t port)
562{
563 bool ret = false;
564 if (!mux_mode) return false;
565
566 ENTER_CRITICAL;
567 ret = startTCPServer(port);
568 LEAVE_CRITICAL;
569
570 return ret;
571}
572
573bool ESP8266::stopServer(void)
574{
575 bool ret;
576
577 ENTER_CRITICAL;
578 ret = stopTCPServer();
579 LEAVE_CRITICAL;
580
581 return ret;
582}
583
584bool ESP8266::send(const uint8_t *buffer, uint32_t len)
585{
586 bool ret;
587 if (mux_mode) return false;
588
589 ENTER_CRITICAL;
590 ret = sATCIPSENDSingle(buffer, len);
591 LEAVE_CRITICAL;
592
593 return ret;
594}
595
596bool ESP8266::send(uint8_t mux_id, const uint8_t *buffer, uint32_t len)
597{
598 bool ret;
599 if (!mux_mode) return false;
600
601 ENTER_CRITICAL;
602 ret = sATCIPSENDMultiple(mux_id, buffer, len);
603 LEAVE_CRITICAL;
604
605 return ret;
606}
607
608bool ESP8266::send(String &str)
609{
610 bool ret;
611 if (mux_mode) return 0;
612
613 ENTER_CRITICAL;
614 ret = sATCIPSENDSingle(str);
615 LEAVE_CRITICAL;
616
617 return ret;
618}
619
620bool ESP8266::send(uint8_t mux_id, String &str)
621{
622 bool ret;
623 if (!mux_mode) return false;
624 if (!(mux_id < ESP8266_NUM_CONNECTION)) return false;
625
626 ENTER_CRITICAL;
627 ret = sATCIPSENDMultiple(mux_id, str);
628 LEAVE_CRITICAL;
629
630 return ret;
631}
632
633uint32_t ESP8266::recv(uint8_t *buffer, uint32_t buffer_size, uint32_t timeout)
634{
635 uint32_t ret;
636 if (mux_mode) return 0;
637
638 ENTER_CRITICAL;
639 ret = recvPkg(buffer, buffer_size, timeout, 0, NULL);
640 LEAVE_CRITICAL;
641
642 return ret;
643}
644
645uint32_t ESP8266::recv(uint8_t mux_id, uint8_t *buffer, uint32_t buffer_size, uint32_t timeout)
646{
647 uint32_t ret;
648 if (!mux_mode) return false;
649 if (!(mux_id < ESP8266_NUM_CONNECTION)) return false;
650
651 ENTER_CRITICAL;
652 ret = recvPkg(buffer, buffer_size, timeout, mux_id, NULL);
653 LEAVE_CRITICAL;
654
655 return ret;
656}
657
658uint32_t ESP8266::recv(uint8_t *coming_mux_id, uint8_t *buffer, uint32_t buffer_size, uint32_t timeout)
659{
660 uint32_t ret;
661 if (!mux_mode) return false;
662
663 ENTER_CRITICAL;
664 ret = recvPkg(buffer, buffer_size, timeout, MUXID_ANY, coming_mux_id);
665 LEAVE_CRITICAL;
666
667 return ret;
668}
669
670bool ESP8266::isDataAvailable(uint8_t mux_id)
671{
672 bool ret;
673 if (!mux_mode) return false;
674 if (!(mux_id < ESP8266_NUM_CONNECTION)) return false;
675
676 ENTER_CRITICAL;
677 if(rx_buffer[mux_id].length() > 0) ret = true;
678 if (ret == false) {
679 rx_update();
680 if(rx_buffer[mux_id].length() > 0) ret = true;
681 }
682 LEAVE_CRITICAL;
683
684 return ret;
685}
686
687bool ESP8266::isDataAvailable(void)
688{
689 bool ret = false;
690
691 ENTER_CRITICAL;
692 if (mux_mode) {
693 for(int i = 0; i < ESP8266_NUM_CONNECTION; i++){
694 if(rx_buffer[i].length() > 0) ret = true;
695 }
696 if (ret == false) {
697 rx_update();
698 for(int i = 0; i < ESP8266_NUM_CONNECTION; i++){
699 if(rx_buffer[i].length() > 0) ret = true;
700 }
701 }
702 }
703 else {
704 /* single mode */
705 if(rx_buffer[0].length() > 0) ret = true;
706 if (ret == false) {
707 rx_update();
708 if(rx_buffer[0].length() > 0) ret = true;
709 }
710 }
711 LEAVE_CRITICAL;
712
713 return ret;
714}
715
716bool ESP8266::isConnected(void)
717{
718 bool ret;
719 if (mux_mode) return false;
720
721 ENTER_CRITICAL;
722 rx_update();
723 ret = (connection_bitmap == 1);
724 LEAVE_CRITICAL;
725
726 return ret;
727}
728
729bool ESP8266::isConnected(uint8_t mux_id)
730{
731 bool ret;
732 if (!mux_mode) return false;
733 if (!(mux_id < ESP8266_NUM_CONNECTION)) return false;
734
735 ENTER_CRITICAL;
736 rx_update();
737 ret = ((connection_bitmap & (1<<mux_id)) != 0);
738 LEAVE_CRITICAL;
739
740 return ret;
741}
742
743bool ESP8266::getMuxCStatus(uint8_t *mux_id_ptn)
744{
745 if (!mux_mode) return false;
746
747 ENTER_CRITICAL;
748 rx_update();
749 *mux_id_ptn = connection_bitmap;
750 LEAVE_CRITICAL;
751
752 return true;
753}
754
755/*----------------------------------------------------------------------------*/
756/* +IPD,<id>,<len>:<data> */
757/* +IPD,<len>:<data> */
758
759uint32_t ESP8266::recvPkg(uint8_t *buffer, uint32_t buffer_size, uint32_t timeout,
760 uint8_t mux_id, uint8_t *coming_mux_id)
761{
762 char a;
763 unsigned long start;
764 uint32_t ret;
765 uint32_t recv_mux_id = 0;
766
767 /*
768 * Try to recive data from rx_buffer
769 */
770 if (mux_id == MUXID_ANY) {
771 for(int i = 0; i < ESP8266_NUM_CONNECTION; i++){
772 if(rx_buffer[i].length() > 0) {
773 recv_mux_id = i;
774 *coming_mux_id = i;
775 break;
776 }
777 }
778 }
779 else {
780 recv_mux_id = mux_id;
781 }
782
783 if(rx_buffer[recv_mux_id].length() > 0) {
784 return rx_buffer[recv_mux_id].copy(buffer, buffer_size);
785 }
786
787 /*
788 * Try to recive data from uart
789 */
790 start = millis();
791 while (millis() - start < timeout) {
792 while(m_puart->available() > 0) {
793 a = m_puart->read();
794 rx_cmd += a;
795 if (rx_cmd.indexOf("+IPD,") != -1) {
796 if((ret = recvIPD(timeout - (millis() - start), buffer, buffer_size,
797 mux_id, coming_mux_id)) != 0) {
798 rx_cmd = "";
799 return ret;
800 }
801 } else {
802 recvAsyncdata();
803 }
804 }
805 WAIT_TIMEOUT;
806 }
807 return 0;
808}
809
810/*
811 * call after read +IPD,
812 * +IPD,<id>,<len>:<data>
813 * +IPD,<len>:<data>
814 */
815uint32_t ESP8266::recvIPD(uint32_t timeout, uint8_t *buffer, uint32_t buffer_size,
816 uint8_t mux_id, uint8_t *coming_mux_id)
817{
818 String data;
819 char a;
820 unsigned long start;
821 int32_t index_colon = -1; /* : */
822 int32_t index_comma = -1; /* , */
823 int32_t len = -1;
824 int8_t id = -1;
825 bool has_data = false;
826 uint32_t ret;
827 uint32_t i;
828 ESP8266_RingBuffer *p_rx_buffer;
829
830 start = millis();
831 while (millis() - start < timeout) {
832 if(m_puart->available() > 0) {
833 a = m_puart->read();
834 data += a;
835 if((index_colon = data.indexOf(':')) != -1) {
836 if(((index_comma = data.indexOf(',')) != -1) && index_comma < index_colon) {
837 /* +IPD,id,len:data */
838 id = data.substring(0, index_comma).toInt();
839 if (id < 0 || id > (ESP8266_NUM_CONNECTION-1)) {
840 return 0;
841 }
842 len = data.substring(index_comma + 1, index_colon).toInt();
843 if (len <= 0) {
844 return 0;
845 }
846 }
847 else {
848 /* +IPD,len:data */
849 len = data.substring(0, index_colon).toInt();
850 id = 0;
851 if (len <= 0) {
852 return 0;
853 }
854 }
855 has_data = true;
856 break;
857 }
858 }
859 else {
860 WAIT_TIMEOUT;
861 }
862 }
863
864 if (has_data) {
865 p_rx_buffer = (id == -1)? &rx_buffer[0] : &rx_buffer[id];
866 if (buffer == NULL || ((mux_id != MUXID_ANY) && (id != mux_id))) {
867 /* Store in rx_buffer */
868 start = millis();
869 i = 0;
870 while (millis() - start < 3000) {
871 while((m_puart->available() > 0) && (i < (uint32_t)len)) {
872 a = m_puart->read();
873 p_rx_buffer->write(a);
874 i++;
875 }
876 if (i == (uint32_t)len) {
877 return len;
878 }
879 WAIT_TIMEOUT
880 }
881 return i;
882 }
883 else {
884 /* Store in buffer */
885 i = 0;
886 ret = ((uint32_t)len > buffer_size) ? buffer_size : len;
887 start = millis();
888 while ((millis() - start) < 3000) {
889 while((m_puart->available() > 0) && (i < (uint32_t)len)) {
890 a = m_puart->read();
891 if(i < buffer_size) {
892 buffer[i] = a;
893 } else {
894 p_rx_buffer->write(a);
895 }
896 i++;
897 }
898 if (i == (uint32_t)len) {
899 if (mux_id == MUXID_ANY) {
900 *coming_mux_id = id;
901 }
902 return ret;
903 }
904 WAIT_TIMEOUT;
905 }
906 }
907 return i;
908 }
909
910 return 0;
911}
912
913void ESP8266::rx_empty(void)
914{
915 while(m_puart->available() > 0) {
916 m_puart->read();
917 }
918}
919
920void ESP8266::recvAsyncdata(uint32_t timeout)
921{
922 int index;
923 int id;
924
925 if (rx_cmd.indexOf("+IPD,") != -1) {
926 if(recvIPD(timeout) != 0) {
927 rx_cmd = "";
928 }
929 } else if (rx_cmd.indexOf("CLOSED") != -1) {
930 if ((index = rx_cmd.indexOf(",CLOSED")) != -1) {
931 /* <link ID>,CLOSED */
932 id = rx_cmd.substring(index-1, index).toInt();
933 connection_bitmap &= ~(1 << id);
934 } else {
935 connection_bitmap = 0;
936 }
937 rx_cmd = "";
938 } else if ((index = rx_cmd.indexOf(",CONNECT")) != -1) {
939 /* <link ID>,CONNECT */
940 id = rx_cmd.substring(index-1, index).toInt();
941 connection_bitmap |= (1 << id);
942 rx_cmd = "";
943 } else if ((index = rx_cmd.indexOf("WIFI CONNECTED")) != -1) {
944 wifi_status = ESP8266_STATUS_CONNECTED;
945 rx_cmd = "";
946 } else if ((index = rx_cmd.indexOf("WIFI GOT IP")) != -1) {
947 wifi_status = ESP8266_STATUS_GOTIP;
948 rx_cmd = "";
949 } else if ((index = rx_cmd.indexOf("WIFI DISCONNECT")) != -1) {
950 wifi_status = ESP8266_STATUS_DISCONNECTED;
951 rx_cmd = "";
952 }
953}
954
955void ESP8266::rx_update(void)
956{
957 char a;
958
959 while(m_puart->available() > 0) {
960 a = m_puart->read();
961 rx_cmd += a;
962 recvAsyncdata(3000);
963 }
964}
965
966int ESP8266::recvString(String target1, String target2, String target3, uint32_t timeout)
967{
968 char a;
969 unsigned long start = millis();
970 while (millis() - start < timeout) {
971 while (m_puart->available() > 0) {
972 a = m_puart->read();
973 rx_cmd += a;
974 if (rx_cmd.indexOf(target1) != -1) {
975 return 1;
976 } else if ((target2.length() != 0 ) && (rx_cmd.indexOf(target2) != -1)) {
977 return 2;
978 } else if ((target3.length() != 0 ) && (rx_cmd.indexOf(target3) != -1)) {
979 return 3;
980 } else {
981 recvAsyncdata(timeout - (millis() - start));
982 }
983 }
984 WAIT_TIMEOUT;
985 }
986 return -1;
987}
988
989bool ESP8266::recvFind(String target, uint32_t timeout)
990{
991 int ret;
992
993 ret = recvString(target, "", "", timeout);
994 if (ret != -1) rx_cmd = "";
995 return (ret == 1);
996}
997
998bool ESP8266::recvFindAndFilter(String target, String begin, String end, String &data, uint32_t timeout)
999{
1000 if (recvString(target, "", "", timeout) == 1) {
1001 int32_t index1 = rx_cmd.indexOf(begin);
1002 int32_t index2 = rx_cmd.indexOf(end);
1003 if (index1 != -1 && index2 != -1) {
1004 index1 += begin.length();
1005 data = rx_cmd.substring(index1, index2);
1006 rx_cmd = "";
1007 return true;
1008 }
1009 }
1010 data = "";
1011 return false;
1012}
1013
1014bool ESP8266::eAT(void)
1015{
1016 rx_update();
1017 m_puart->println("AT");
1018 return recvFind("OK");
1019}
1020
1021bool ESP8266::eATRST(void)
1022{
1023 rx_update();
1024 m_puart->println("AT+RST");
1025 return recvFind("OK");
1026}
1027
1028bool ESP8266::eATGMR(String &version)
1029{
1030 rx_update();
1031 m_puart->println("AT+GMR");
1032 return recvFindAndFilter("OK", "\r\r\n", "\r\nOK", version);
1033}
1034/* checked */
1035bool ESP8266::qATCWMODE_CUR(uint8_t *mode)
1036{
1037 String str_mode;
1038 bool ret;
1039 if (!mode) {
1040 return false;
1041 }
1042 rx_update();
1043 m_puart->println("AT+CWMODE_CUR?");
1044 ret = recvFindAndFilter("OK", "+CWMODE_CUR:", "\r\n\r\nOK", str_mode);
1045 if (ret) {
1046 *mode = (uint8_t)str_mode.toInt();
1047 return true;
1048 } else {
1049 return false;
1050 }
1051}
1052/* checked */
1053bool ESP8266::sATCWMODE_CUR(uint8_t mode)
1054{
1055 int ret;
1056
1057 rx_update();
1058 m_puart->print("AT+CWMODE_CUR=");
1059 m_puart->println(mode);
1060
1061 ret = recvString("OK", "ERROR", "");
1062 if (ret != -1) rx_cmd = "";
1063 return (ret == 1);
1064}
1065/* checked */
1066bool ESP8266::sATCWJAP_CUR(String ssid, String pwd)
1067{
1068 int ret;
1069
1070 rx_update();
1071 m_puart->print("AT+CWJAP_CUR=\"");
1072 m_puart->print(ssid);
1073 m_puart->print("\",\"");
1074 m_puart->print(pwd);
1075 m_puart->println("\"");
1076
1077 ret = recvString("OK", "FAIL", "", 10000);
1078 if (ret != -1) rx_cmd = "";
1079 return (ret == 1);
1080}
1081
1082bool ESP8266::eATCWLAP(String &list)
1083{
1084 rx_update();
1085 m_puart->println("AT+CWLAP");
1086 return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list, 10000);
1087}
1088
1089bool ESP8266::eATCWQAP(void)
1090{
1091 rx_update();
1092 m_puart->println("AT+CWQAP");
1093 return recvFind("OK");
1094}
1095/* checked */
1096bool ESP8266::sATCWSAP_CUR(String ssid, String pwd, uint8_t chl, uint8_t ecn)
1097{
1098 int ret;
1099
1100 rx_update();
1101 m_puart->print("AT+CWSAP_CUR=\"");
1102 m_puart->print(ssid);
1103 m_puart->print("\",\"");
1104 m_puart->print(pwd);
1105 m_puart->print("\",");
1106 m_puart->print(chl);
1107 m_puart->print(",");
1108 m_puart->println(ecn);
1109
1110 ret = recvString("OK", "ERROR", "", 5000);
1111 if (ret != -1) rx_cmd = "";
1112 return (ret == 1);
1113}
1114
1115bool ESP8266::eATCWLIF(String &list)
1116{
1117 rx_update();
1118 m_puart->println("AT+CWLIF");
1119 return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list);
1120}
1121
1122bool ESP8266::eATCIPSTATUS(String &list)
1123{
1124 rx_update();
1125 m_puart->println("AT+CIPSTATUS");
1126 return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list);
1127}
1128
1129bool ESP8266::sATCIPSTARTSingle(String type, String addr, uint32_t port)
1130{
1131 int ret;
1132
1133 rx_update();
1134 m_puart->print("AT+CIPSTART=\"");
1135 m_puart->print(type);
1136 m_puart->print("\",\"");
1137 m_puart->print(addr);
1138 m_puart->print("\",");
1139 m_puart->println(port);
1140
1141 ret = recvString("OK", "ERROR", "ALREADY CONNECT", 10000);
1142 if (ret != -1) rx_cmd = "";
1143 return (ret == 1 || ret == 3);
1144}
1145
1146bool ESP8266::sATCIPSTARTMultiple(uint8_t mux_id, String type, String addr, uint32_t port)
1147{
1148 int ret;
1149
1150 rx_update();
1151 m_puart->print("AT+CIPSTART=");
1152 m_puart->print(mux_id);
1153 m_puart->print(",\"");
1154 m_puart->print(type);
1155 m_puart->print("\",\"");
1156 m_puart->print(addr);
1157 m_puart->print("\",");
1158 m_puart->println(port);
1159
1160 ret = recvString("OK", "ERROR", "ALREADY CONNECT", 10000);
1161 if (ret != -1) rx_cmd = "";
1162 return ((ret == 1)||(ret == 3));
1163}
1164
1165bool ESP8266::sATCIPSENDSingle(const uint8_t *buffer, uint32_t len)
1166{
1167 bool ret;
1168 rx_update();
1169 m_puart->print("AT+CIPSEND=");
1170 m_puart->println(len);
1171 if (recvFind(">", 5000)) {
1172 for (uint32_t i = 0; i < len; i++) {
1173 m_puart->write(buffer[i]);
1174 }
1175 ret = recvFind("SEND OK", 10000);
1176 return ret;
1177 }
1178
1179 return false;
1180}
1181
1182bool ESP8266::sATCIPSENDMultiple(uint8_t mux_id, const uint8_t *buffer, uint32_t len)
1183{
1184 rx_update();
1185 m_puart->print("AT+CIPSEND=");
1186 m_puart->print(mux_id);
1187 m_puart->print(",");
1188 m_puart->println(len);
1189 if (recvFind(">", 5000)) {
1190 for (uint32_t i = 0; i < len; i++) {
1191 m_puart->write(buffer[i]);
1192 }
1193 return recvFind("SEND OK", 10000);
1194 }
1195 return false;
1196}
1197
1198bool ESP8266::sATCIPSENDSingle(String &str)
1199{
1200 rx_update();
1201 m_puart->print("AT+CIPSEND=");
1202 m_puart->println(str.length());
1203 if (recvFind(">", 5000)) {
1204 for (uint32_t i = 0; i < str.length(); i++) {
1205 m_puart->write(str.charAt(i));
1206 }
1207 return recvFind("SEND OK", 10000);
1208 }
1209 return false;
1210}
1211
1212bool ESP8266::sATCIPSENDMultiple(uint8_t mux_id, String &str)
1213{
1214 rx_update();
1215 m_puart->print("AT+CIPSEND=");
1216 m_puart->print(mux_id);
1217 m_puart->print(",");
1218 m_puart->println(str.length());
1219 if (recvFind(">", 5000)) {
1220 for (uint32_t i = 0; i < str.length(); i++) {
1221 m_puart->write(str.charAt(i));
1222 }
1223 return recvFind("SEND OK", 10000);
1224 }
1225 return false;
1226}
1227
1228bool ESP8266::sATCIPCLOSEMulitple(uint8_t mux_id)
1229{
1230 int ret;
1231
1232 rx_update();
1233 m_puart->print("AT+CIPCLOSE=");
1234 m_puart->println(mux_id);
1235
1236 ret = recvString("OK", "link is not", "", 5000);
1237 if (ret != -1) rx_cmd = "";
1238 return ((ret == 1) || (ret == 2));
1239}
1240
1241bool ESP8266::eATCIPCLOSESingle(void)
1242{
1243 int ret;
1244
1245 Serial.println(rx_cmd);
1246 rx_update();
1247 m_puart->println("AT+CIPCLOSE");
1248 ret = recvString("OK", "ERROR", "", 5000);
1249 if (ret != -1) rx_cmd = "";
1250 return ((ret == 1) || (ret == 2));
1251}
1252
1253bool ESP8266::eATCIFSR(String &list)
1254{
1255 rx_update();
1256 m_puart->println("AT+CIFSR");
1257 return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list);
1258}
1259/* checked */
1260bool ESP8266::sATCIPMUX(uint8_t mode)
1261{
1262 int ret;
1263
1264 rx_update();
1265 m_puart->print("AT+CIPMUX=");
1266 m_puart->println(mode);
1267
1268 ret = recvString("OK", "ERROR", "");
1269 if (ret != -1) rx_cmd = "";
1270 return (ret == 1);
1271}
1272
1273bool ESP8266::sATCIPSERVER(uint8_t mode, uint32_t port)
1274{
1275 int ret;
1276
1277 if (mode) {
1278 rx_update();
1279 m_puart->print("AT+CIPSERVER=1,");
1280 m_puart->println(port);
1281 ret = recvString("OK", "ERROR", "");
1282 if (ret != -1) rx_cmd = "";
1283 return (ret == 1);
1284 } else {
1285 rx_update();
1286 m_puart->println("AT+CIPSERVER=0");
1287 ret = recvString("OK", "ERROR", "");
1288 if (ret != -1) rx_cmd = "";
1289 return (ret == 1);
1290 }
1291}
1292bool ESP8266::sATCIPSTO(uint32_t timeout)
1293{
1294 rx_update();
1295 m_puart->print("AT+CIPSTO=");
1296 m_puart->println(timeout);
1297 return recvFind("OK");
1298}
1299
Note: See TracBrowser for help on using the repository browser.