mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #9421 from VeijoPesonen/feature-esp8266_nonblocking_connect
ESP8266: implements possibility to decide between non-blocking/blocking connect.pull/9485/head
commit
f790fdd1cd
|
@ -55,11 +55,14 @@ ESP8266Interface::ESP8266Interface()
|
||||||
: _esp(MBED_CONF_ESP8266_TX, MBED_CONF_ESP8266_RX, MBED_CONF_ESP8266_DEBUG, MBED_CONF_ESP8266_RTS, MBED_CONF_ESP8266_CTS),
|
: _esp(MBED_CONF_ESP8266_TX, MBED_CONF_ESP8266_RX, MBED_CONF_ESP8266_DEBUG, MBED_CONF_ESP8266_RTS, MBED_CONF_ESP8266_CTS),
|
||||||
_rst_pin(MBED_CONF_ESP8266_RST), // Notice that Pin7 CH_EN cannot be left floating if used as reset
|
_rst_pin(MBED_CONF_ESP8266_RST), // Notice that Pin7 CH_EN cannot be left floating if used as reset
|
||||||
_ap_sec(NSAPI_SECURITY_UNKNOWN),
|
_ap_sec(NSAPI_SECURITY_UNKNOWN),
|
||||||
|
_if_blocking(true),
|
||||||
|
_if_connected(_cmutex),
|
||||||
_initialized(false),
|
_initialized(false),
|
||||||
_conn_stat(NSAPI_STATUS_DISCONNECTED),
|
_conn_stat(NSAPI_STATUS_DISCONNECTED),
|
||||||
_conn_stat_cb(NULL),
|
_conn_stat_cb(NULL),
|
||||||
_global_event_queue(NULL),
|
_global_event_queue(NULL),
|
||||||
_oob_event_id(0)
|
_oob_event_id(0),
|
||||||
|
_connect_event_id(0)
|
||||||
{
|
{
|
||||||
memset(_cbs, 0, sizeof(_cbs));
|
memset(_cbs, 0, sizeof(_cbs));
|
||||||
memset(ap_ssid, 0, sizeof(ap_ssid));
|
memset(ap_ssid, 0, sizeof(ap_ssid));
|
||||||
|
@ -83,11 +86,14 @@ ESP8266Interface::ESP8266Interface(PinName tx, PinName rx, bool debug, PinName r
|
||||||
: _esp(tx, rx, debug, rts, cts),
|
: _esp(tx, rx, debug, rts, cts),
|
||||||
_rst_pin(rst),
|
_rst_pin(rst),
|
||||||
_ap_sec(NSAPI_SECURITY_UNKNOWN),
|
_ap_sec(NSAPI_SECURITY_UNKNOWN),
|
||||||
|
_if_blocking(true),
|
||||||
|
_if_connected(_cmutex),
|
||||||
_initialized(false),
|
_initialized(false),
|
||||||
_conn_stat(NSAPI_STATUS_DISCONNECTED),
|
_conn_stat(NSAPI_STATUS_DISCONNECTED),
|
||||||
_conn_stat_cb(NULL),
|
_conn_stat_cb(NULL),
|
||||||
_global_event_queue(NULL),
|
_global_event_queue(NULL),
|
||||||
_oob_event_id(0)
|
_oob_event_id(0),
|
||||||
|
_connect_event_id(0)
|
||||||
{
|
{
|
||||||
memset(_cbs, 0, sizeof(_cbs));
|
memset(_cbs, 0, sizeof(_cbs));
|
||||||
memset(ap_ssid, 0, sizeof(ap_ssid));
|
memset(ap_ssid, 0, sizeof(ap_ssid));
|
||||||
|
@ -111,6 +117,12 @@ ESP8266Interface::~ESP8266Interface()
|
||||||
_global_event_queue->cancel(_oob_event_id);
|
_global_event_queue->cancel(_oob_event_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_cmutex.lock();
|
||||||
|
if (_connect_event_id) {
|
||||||
|
_global_event_queue->cancel(_connect_event_id);
|
||||||
|
}
|
||||||
|
_cmutex.unlock();
|
||||||
|
|
||||||
// Power down the modem
|
// Power down the modem
|
||||||
_rst_pin.rst_assert();
|
_rst_pin.rst_assert();
|
||||||
}
|
}
|
||||||
|
@ -167,9 +179,36 @@ void ESP8266Interface::_oob2global_event_queue()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ESP8266Interface::_connect_async()
|
||||||
|
{
|
||||||
|
_cmutex.lock();
|
||||||
|
if (!_connect_event_id) {
|
||||||
|
tr_debug("_connect_async(): cancelled");
|
||||||
|
_cmutex.unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_esp.connect(ap_ssid, ap_pass) != NSAPI_ERROR_OK) {
|
||||||
|
// Postpone to give other stuff time to run
|
||||||
|
_connect_event_id = _global_event_queue->call_in(ESP8266_CONNECT_TIMEOUT, callback(this, &ESP8266Interface::_connect_async));
|
||||||
|
|
||||||
|
if (!_connect_event_id) {
|
||||||
|
MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_DRIVER, MBED_ERROR_CODE_ENOMEM), \
|
||||||
|
"_connect_async(): unable to add event to queue");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_connect_event_id = 0;
|
||||||
|
_if_connected.notify_all();
|
||||||
|
}
|
||||||
|
_cmutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
int ESP8266Interface::connect()
|
int ESP8266Interface::connect()
|
||||||
{
|
{
|
||||||
nsapi_error_t status;
|
nsapi_error_t status = _conn_status_to_error();
|
||||||
|
if (status != NSAPI_ERROR_NO_CONNECTION) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
if (strlen(ap_ssid) == 0) {
|
if (strlen(ap_ssid) == 0) {
|
||||||
return NSAPI_ERROR_NO_SSID;
|
return NSAPI_ERROR_NO_SSID;
|
||||||
|
@ -194,11 +233,32 @@ int ESP8266Interface::connect()
|
||||||
return NSAPI_ERROR_DHCP_FAILURE;
|
return NSAPI_ERROR_DHCP_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _esp.connect(ap_ssid, ap_pass);
|
_cmutex.lock();
|
||||||
|
|
||||||
|
MBED_ASSERT(!_connect_event_id);
|
||||||
|
_connect_event_id = _global_event_queue->call(callback(this, &ESP8266Interface::_connect_async));
|
||||||
|
|
||||||
|
if (!_connect_event_id) {
|
||||||
|
MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_DRIVER, MBED_ERROR_CODE_ENOMEM), \
|
||||||
|
"connect(): unable to add event to queue");
|
||||||
|
}
|
||||||
|
|
||||||
|
while (_if_blocking && (_conn_status_to_error() != NSAPI_ERROR_IS_CONNECTED)) {
|
||||||
|
_if_connected.wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
_cmutex.unlock();
|
||||||
|
|
||||||
|
return NSAPI_ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ESP8266Interface::set_credentials(const char *ssid, const char *pass, nsapi_security_t security)
|
int ESP8266Interface::set_credentials(const char *ssid, const char *pass, nsapi_security_t security)
|
||||||
{
|
{
|
||||||
|
nsapi_error_t status = _conn_status_to_error();
|
||||||
|
if (status != NSAPI_ERROR_NO_CONNECTION) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
_ap_sec = security;
|
_ap_sec = security;
|
||||||
|
|
||||||
if (!ssid) {
|
if (!ssid) {
|
||||||
|
@ -244,10 +304,16 @@ int ESP8266Interface::set_channel(uint8_t channel)
|
||||||
|
|
||||||
int ESP8266Interface::disconnect()
|
int ESP8266Interface::disconnect()
|
||||||
{
|
{
|
||||||
|
_cmutex.lock();
|
||||||
|
if (_connect_event_id) {
|
||||||
|
_global_event_queue->cancel(_connect_event_id);
|
||||||
|
_connect_event_id = 0; // cancel asynchronous connection attempt if one is ongoing
|
||||||
|
}
|
||||||
|
_cmutex.unlock();
|
||||||
_initialized = false;
|
_initialized = false;
|
||||||
|
|
||||||
if (_conn_stat == NSAPI_STATUS_DISCONNECTED || !get_ip_address())
|
nsapi_error_t status = _conn_status_to_error();
|
||||||
{
|
if (status == NSAPI_ERROR_NO_CONNECTION || !get_ip_address()) {
|
||||||
return NSAPI_ERROR_NO_CONNECTION;
|
return NSAPI_ERROR_NO_CONNECTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -716,4 +782,35 @@ void ESP8266Interface::proc_oob_evnt()
|
||||||
_esp.bg_process_oob(ESP8266_RECV_TIMEOUT, true);
|
_esp.bg_process_oob(ESP8266_RECV_TIMEOUT, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsapi_error_t ESP8266Interface::_conn_status_to_error()
|
||||||
|
{
|
||||||
|
nsapi_error_t ret;
|
||||||
|
|
||||||
|
_esp.bg_process_oob(ESP8266_RECV_TIMEOUT, true);
|
||||||
|
|
||||||
|
switch (_conn_stat) {
|
||||||
|
case NSAPI_STATUS_DISCONNECTED:
|
||||||
|
ret = NSAPI_ERROR_NO_CONNECTION;
|
||||||
|
break;
|
||||||
|
case NSAPI_STATUS_CONNECTING:
|
||||||
|
ret = NSAPI_ERROR_ALREADY;
|
||||||
|
break;
|
||||||
|
case NSAPI_STATUS_GLOBAL_UP:
|
||||||
|
ret = NSAPI_ERROR_IS_CONNECTED;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ret = NSAPI_ERROR_DEVICE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsapi_error_t ESP8266Interface::set_blocking(bool blocking)
|
||||||
|
{
|
||||||
|
_if_blocking = blocking;
|
||||||
|
|
||||||
|
return NSAPI_ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -29,6 +29,8 @@
|
||||||
#include "features/netsocket/WiFiAccessPoint.h"
|
#include "features/netsocket/WiFiAccessPoint.h"
|
||||||
#include "features/netsocket/WiFiInterface.h"
|
#include "features/netsocket/WiFiInterface.h"
|
||||||
#include "platform/Callback.h"
|
#include "platform/Callback.h"
|
||||||
|
#include "rtos/ConditionVariable.h"
|
||||||
|
#include "rtos/Mutex.h"
|
||||||
|
|
||||||
#define ESP8266_SOCKET_COUNT 5
|
#define ESP8266_SOCKET_COUNT 5
|
||||||
|
|
||||||
|
@ -316,6 +318,13 @@ protected:
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Set blocking status of connect() which by default should be blocking.
|
||||||
|
*
|
||||||
|
* @param blocking Use true to make connect() blocking.
|
||||||
|
* @return NSAPI_ERROR_OK on success, negative error code on failure.
|
||||||
|
*/
|
||||||
|
virtual nsapi_error_t set_blocking(bool blocking);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// AT layer
|
// AT layer
|
||||||
ESP8266 _esp;
|
ESP8266 _esp;
|
||||||
|
@ -341,6 +350,12 @@ private:
|
||||||
char ap_pass[ESP8266_PASSPHRASE_MAX_LENGTH + 1]; /* The longest possible passphrase; +1 for the \0 */
|
char ap_pass[ESP8266_PASSPHRASE_MAX_LENGTH + 1]; /* The longest possible passphrase; +1 for the \0 */
|
||||||
nsapi_security_t _ap_sec;
|
nsapi_security_t _ap_sec;
|
||||||
|
|
||||||
|
bool _if_blocking; // NetworkInterface, blocking or not
|
||||||
|
rtos::ConditionVariable _if_connected;
|
||||||
|
|
||||||
|
// connect status reporting
|
||||||
|
nsapi_error_t _conn_status_to_error();
|
||||||
|
|
||||||
// Drivers's socket info
|
// Drivers's socket info
|
||||||
struct _sock_info {
|
struct _sock_info {
|
||||||
bool open;
|
bool open;
|
||||||
|
@ -369,8 +384,12 @@ private:
|
||||||
// Use global EventQueue
|
// Use global EventQueue
|
||||||
events::EventQueue *_global_event_queue;
|
events::EventQueue *_global_event_queue;
|
||||||
int _oob_event_id;
|
int _oob_event_id;
|
||||||
|
int _connect_event_id;
|
||||||
void proc_oob_evnt();
|
void proc_oob_evnt();
|
||||||
void _oob2global_event_queue();
|
void _oob2global_event_queue();
|
||||||
|
void _connect_async();
|
||||||
|
rtos::Mutex _cmutex; // Protect asynchronous connection logic
|
||||||
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue