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

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

マクロ名を更新.
実行モデルを変更.

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