@@ -55,11 +55,14 @@ ESP8266Interface::ESP8266Interface()
55
55
: _esp(MBED_CONF_ESP8266_TX, MBED_CONF_ESP8266_RX, MBED_CONF_ESP8266_DEBUG, MBED_CONF_ESP8266_RTS, MBED_CONF_ESP8266_CTS),
56
56
_rst_pin(MBED_CONF_ESP8266_RST), // Notice that Pin7 CH_EN cannot be left floating if used as reset
57
57
_ap_sec(NSAPI_SECURITY_UNKNOWN),
58
+ _if_blocking(true ),
59
+ _if_connected(_cmutex),
58
60
_initialized(false ),
59
61
_conn_stat(NSAPI_STATUS_DISCONNECTED),
60
62
_conn_stat_cb(NULL ),
61
63
_global_event_queue(NULL ),
62
- _oob_event_id(0 )
64
+ _oob_event_id(0 ),
65
+ _connect_event_id(0 )
63
66
{
64
67
memset (_cbs, 0 , sizeof (_cbs));
65
68
memset (ap_ssid, 0 , sizeof (ap_ssid));
@@ -83,11 +86,14 @@ ESP8266Interface::ESP8266Interface(PinName tx, PinName rx, bool debug, PinName r
83
86
: _esp(tx, rx, debug, rts, cts),
84
87
_rst_pin(rst),
85
88
_ap_sec(NSAPI_SECURITY_UNKNOWN),
89
+ _if_blocking(true ),
90
+ _if_connected(_cmutex),
86
91
_initialized(false ),
87
92
_conn_stat(NSAPI_STATUS_DISCONNECTED),
88
93
_conn_stat_cb(NULL ),
89
94
_global_event_queue(NULL ),
90
- _oob_event_id(0 )
95
+ _oob_event_id(0 ),
96
+ _connect_event_id(0 )
91
97
{
92
98
memset (_cbs, 0 , sizeof (_cbs));
93
99
memset (ap_ssid, 0 , sizeof (ap_ssid));
@@ -111,6 +117,12 @@ ESP8266Interface::~ESP8266Interface()
111
117
_global_event_queue->cancel (_oob_event_id);
112
118
}
113
119
120
+ _cmutex.lock ();
121
+ if (_connect_event_id) {
122
+ _global_event_queue->cancel (_connect_event_id);
123
+ }
124
+ _cmutex.unlock ();
125
+
114
126
// Power down the modem
115
127
_rst_pin.rst_assert ();
116
128
}
@@ -167,9 +179,36 @@ void ESP8266Interface::_oob2global_event_queue()
167
179
}
168
180
}
169
181
182
+ void ESP8266Interface::_connect_async ()
183
+ {
184
+ _cmutex.lock ();
185
+ if (!_connect_event_id) {
186
+ tr_debug (" _connect_async(): cancelled" );
187
+ _cmutex.unlock ();
188
+ return ;
189
+ }
190
+
191
+ if (_esp.connect (ap_ssid, ap_pass) != NSAPI_ERROR_OK) {
192
+ // Postpone to give other stuff time to run
193
+ _connect_event_id = _global_event_queue->call_in (ESP8266_CONNECT_TIMEOUT, callback (this , &ESP8266Interface::_connect_async));
194
+
195
+ if (!_connect_event_id) {
196
+ MBED_ERROR (MBED_MAKE_ERROR (MBED_MODULE_DRIVER, MBED_ERROR_CODE_ENOMEM), \
197
+ " _connect_async(): unable to add event to queue" );
198
+ }
199
+ } else {
200
+ _connect_event_id = 0 ;
201
+ _if_connected.notify_all ();
202
+ }
203
+ _cmutex.unlock ();
204
+ }
205
+
170
206
int ESP8266Interface::connect ()
171
207
{
172
- nsapi_error_t status;
208
+ nsapi_error_t status = _conn_status_to_error ();
209
+ if (status != NSAPI_ERROR_NO_CONNECTION) {
210
+ return status;
211
+ }
173
212
174
213
if (strlen (ap_ssid) == 0 ) {
175
214
return NSAPI_ERROR_NO_SSID;
@@ -194,11 +233,32 @@ int ESP8266Interface::connect()
194
233
return NSAPI_ERROR_DHCP_FAILURE;
195
234
}
196
235
197
- return _esp.connect (ap_ssid, ap_pass);
236
+ _cmutex.lock ();
237
+
238
+ MBED_ASSERT (!_connect_event_id);
239
+ _connect_event_id = _global_event_queue->call (callback (this , &ESP8266Interface::_connect_async));
240
+
241
+ if (!_connect_event_id) {
242
+ MBED_ERROR (MBED_MAKE_ERROR (MBED_MODULE_DRIVER, MBED_ERROR_CODE_ENOMEM), \
243
+ " connect(): unable to add event to queue" );
244
+ }
245
+
246
+ while (_if_blocking && (_conn_status_to_error () != NSAPI_ERROR_IS_CONNECTED)) {
247
+ _if_connected.wait ();
248
+ }
249
+
250
+ _cmutex.unlock ();
251
+
252
+ return NSAPI_ERROR_OK;
198
253
}
199
254
200
255
int ESP8266Interface::set_credentials (const char *ssid, const char *pass, nsapi_security_t security)
201
256
{
257
+ nsapi_error_t status = _conn_status_to_error ();
258
+ if (status != NSAPI_ERROR_NO_CONNECTION) {
259
+ return status;
260
+ }
261
+
202
262
_ap_sec = security;
203
263
204
264
if (!ssid) {
@@ -244,10 +304,16 @@ int ESP8266Interface::set_channel(uint8_t channel)
244
304
245
305
int ESP8266Interface::disconnect ()
246
306
{
307
+ _cmutex.lock ();
308
+ if (_connect_event_id) {
309
+ _global_event_queue->cancel (_connect_event_id);
310
+ _connect_event_id = 0 ; // cancel asynchronous connection attempt if one is ongoing
311
+ }
312
+ _cmutex.unlock ();
247
313
_initialized = false ;
248
314
249
- if (_conn_stat == NSAPI_STATUS_DISCONNECTED || ! get_ip_address ())
250
- {
315
+ nsapi_error_t status = _conn_status_to_error ();
316
+ if (status == NSAPI_ERROR_NO_CONNECTION || ! get_ip_address ()) {
251
317
return NSAPI_ERROR_NO_CONNECTION;
252
318
}
253
319
@@ -716,4 +782,35 @@ void ESP8266Interface::proc_oob_evnt()
716
782
_esp.bg_process_oob (ESP8266_RECV_TIMEOUT, true );
717
783
}
718
784
785
+ nsapi_error_t ESP8266Interface::_conn_status_to_error ()
786
+ {
787
+ nsapi_error_t ret;
788
+
789
+ _esp.bg_process_oob (ESP8266_RECV_TIMEOUT, true );
790
+
791
+ switch (_conn_stat) {
792
+ case NSAPI_STATUS_DISCONNECTED:
793
+ ret = NSAPI_ERROR_NO_CONNECTION;
794
+ break ;
795
+ case NSAPI_STATUS_CONNECTING:
796
+ ret = NSAPI_ERROR_ALREADY;
797
+ break ;
798
+ case NSAPI_STATUS_GLOBAL_UP:
799
+ ret = NSAPI_ERROR_IS_CONNECTED;
800
+ break ;
801
+ default :
802
+ ret = NSAPI_ERROR_DEVICE_ERROR;
803
+ }
804
+
805
+ return ret;
806
+ }
807
+
808
+ nsapi_error_t ESP8266Interface::set_blocking (bool blocking)
809
+ {
810
+ _if_blocking = blocking;
811
+
812
+ return NSAPI_ERROR_OK;
813
+ }
814
+
815
+
719
816
#endif
0 commit comments