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

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

1.3.0.0に対応

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