Skip to content

Check for OOBs on background #106

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Oct 26, 2018
33 changes: 30 additions & 3 deletions ESP8266/ESP8266.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ ESP8266::ESP8266(PinName tx, PinName rx, bool debug, PinName rts, PinName cts)
// Don't see a reason to make distiction between software(Software WDT reset) and hardware(wdt reset) watchdog treatment
//https://github.com/esp8266/Arduino/blob/4897e0006b5b0123a2fa31f67b14a3fff65ce561/doc/faq/a02-my-esp-crashes.md#watchdog
_parser.oob("Soft WDT reset", callback(this, &ESP8266::_oob_watchdog_reset));
_parser.oob("busy ", callback(this, &ESP8266::_oob_busy));

for(int i= 0; i < SOCKET_COUNT; i++) {
_sock_i[i].open = false;
Expand Down Expand Up @@ -590,18 +591,25 @@ void ESP8266::_process_oob(uint32_t timeout, bool all) {
set_timeout();
}

void ESP8266::bg_process_oob(uint32_t timeout, bool all)
{
_smutex.lock();
_process_oob(timeout, all);
_smutex.unlock();
}

int32_t ESP8266::_recv_tcp_passive(int id, void *data, uint32_t amount, uint32_t timeout)
{
int32_t len;
int32_t ret = (int32_t)NSAPI_ERROR_WOULD_BLOCK;

_smutex.lock();

// No flow control, drain the USART receive register ASAP to avoid data overrun
if (_serial_rts == NC) {
_process_oob(timeout, true);
}

_smutex.lock();

// NOTE: documentation v3.0 says '+CIPRECVDATA:<data_len>,' but it's not how the FW responds...
bool done = _parser.send("AT+CIPRECVDATA=%d,%lu", id, amount)
&& _parser.recv("+CIPRECVDATA,%ld:", &len)
Expand Down Expand Up @@ -832,10 +840,29 @@ void ESP8266::_oob_watchdog_reset()
_sock_i[i].open = false;
}

_conn_status = NSAPI_STATUS_DISCONNECTED;
// Makes possible to reinitialize
_conn_status = NSAPI_STATUS_ERROR_UNSUPPORTED;
_conn_stat_cb();
}

void ESP8266::_oob_busy()
{
char status[5];
if (_parser.recv("%4[^\"]\n", status)) {
if (strcmp(status, " s...\n") == 0) {
; //TODO maybe do something here, or not...
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the whole reason for this OOB handler if it does not do anything?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just making people aware there are this kind of events which might be raised. And especially to report an error if some new firmware introduces new messages on which we are to react.

} else if (strcmp(status, "p...\n") == 0) {
; //TODO maybe do something here, or not...
} else {
MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_DRIVER, MBED_ERROR_CODE_EBADMSG), \
"ESP8266::_oob_busy: unrecognized busy state\n");
}
} else {
MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_DRIVER, MBED_ERROR_CODE_ENOMSG), \
"ESP8266::_oob_busy: AT timeout\n");
}
}

void ESP8266::_oob_connect_err()
{
_fail = false;
Expand Down
11 changes: 11 additions & 0 deletions ESP8266/ESP8266.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@
#define ESP8266_H

#include "ATCmdParser.h"
#include "Mutex.h"
#include "nsapi_types.h"
#include "rtos.h"
#include "drivers/UARTSerial.h"

// Various timeouts for different ESP8266 operations
#ifndef ESP8266_CONNECT_TIMEOUT
Expand Down Expand Up @@ -342,6 +344,14 @@ class ESP8266
*/
bool cond_enable_tcp_passive_mode();

/**
* For executing OOB processing on background
*
* @param timeout AT parser receive timeout
* @param if TRUE, process all OOBs instead of only one
*/
void bg_process_oob(uint32_t timeout, bool all);

static const int8_t WIFIMODE_STATION = 1;
static const int8_t WIFIMODE_SOFTAP = 2;
static const int8_t WIFIMODE_STATION_SOFTAP = 3;
Expand Down Expand Up @@ -397,6 +407,7 @@ class ESP8266
void _oob_connection_status();
void _oob_socket_close_err();
void _oob_watchdog_reset();
void _oob_busy();

// OOB state variables
int _connect_error;
Expand Down
59 changes: 52 additions & 7 deletions ESP8266Interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
*/

#include <cstring>
#include "events/EventQueue.h"
#include "events/mbed_shared_queues.h"
#include "platform/Callback.h"
#include "ESP8266.h"
#include "ESP8266Interface.h"
#include "mbed_debug.h"
Expand Down Expand Up @@ -49,7 +52,9 @@ ESP8266Interface::ESP8266Interface()
_initialized(false),
_started(false),
_conn_stat(NSAPI_STATUS_DISCONNECTED),
_conn_stat_cb(NULL)
_conn_stat_cb(NULL),
_global_event_queue(NULL),
_oob_event_id(0)
{
memset(_cbs, 0, sizeof(_cbs));
memset(ap_ssid, 0, sizeof(ap_ssid));
Expand All @@ -73,7 +78,9 @@ ESP8266Interface::ESP8266Interface(PinName tx, PinName rx, bool debug, PinName r
_initialized(false),
_started(false),
_conn_stat(NSAPI_STATUS_DISCONNECTED),
_conn_stat_cb(NULL)
_conn_stat_cb(NULL),
_global_event_queue(NULL),
_oob_event_id(0)
{
memset(_cbs, 0, sizeof(_cbs));
memset(ap_ssid, 0, sizeof(ap_ssid));
Expand All @@ -89,6 +96,13 @@ ESP8266Interface::ESP8266Interface(PinName tx, PinName rx, bool debug, PinName r
}
}

ESP8266Interface::~ESP8266Interface()
{
if (_oob_event_id) {
_global_event_queue->cancel(_oob_event_id);
}
}

int ESP8266Interface::connect(const char *ssid, const char *pass, nsapi_security_t security,
uint8_t channel)
{
Expand All @@ -104,6 +118,17 @@ int ESP8266Interface::connect(const char *ssid, const char *pass, nsapi_security
return connect();
}

void ESP8266Interface::_oob2global_event_queue()
{
_global_event_queue = mbed_event_queue();
_oob_event_id = _global_event_queue->call_every(ESP8266_RECV_TIMEOUT, callback(this, &ESP8266Interface::proc_oob_evnt));

if (!_oob_event_id) {
MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_DRIVER, MBED_ERROR_CODE_ENOMEM), \
"ESP8266::_oob2geq: unable to allocate OOB event");
}
}

int ESP8266Interface::connect()
{
nsapi_error_t status;
Expand All @@ -123,6 +148,10 @@ int ESP8266Interface::connect()
return status;
}

if (!_oob_event_id) {
_oob2global_event_queue();
}

if(get_ip_address()) {
return NSAPI_ERROR_IS_CONNECTED;
}
Expand Down Expand Up @@ -196,10 +225,16 @@ int ESP8266Interface::set_channel(uint8_t channel)

int ESP8266Interface::disconnect()
{
_started = false;
_initialized = false;
int ret = _esp.disconnect() ? NSAPI_ERROR_OK : NSAPI_ERROR_DEVICE_ERROR;

return _esp.disconnect() ? NSAPI_ERROR_OK : NSAPI_ERROR_DEVICE_ERROR;
if (ret == NSAPI_ERROR_OK) {
// Try to lure the nw status update from ESP8266, might come later
_esp.bg_process_oob(ESP8266_RECV_TIMEOUT, true);
// In case the status update arrives later
_conn_stat = NSAPI_STATUS_DISCONNECTED;
}

return ret;
}

const char *ESP8266Interface::get_ip_address()
Expand Down Expand Up @@ -613,17 +648,27 @@ void ESP8266Interface::update_conn_state_cb()
// Start from scratch if connection drops/is dropped
case NSAPI_STATUS_DISCONNECTED:
_started = false;
_initialized = false;
break;
// Handled on AT layer
case NSAPI_STATUS_LOCAL_UP:
case NSAPI_STATUS_ERROR_UNSUPPORTED:
default:
MBED_ASSERT(false);
_started = false;
_initialized = false;
_global_event_queue->cancel(_oob_event_id);
_oob_event_id = 0;
_conn_stat = NSAPI_STATUS_DISCONNECTED;
}

// Inform upper layers
if (_conn_stat_cb) {
_conn_stat_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, _conn_stat);
}
}

void ESP8266Interface::proc_oob_evnt()
{
if (_initialized) {
_esp.bg_process_oob(ESP8266_RECV_TIMEOUT, true);
}
}
23 changes: 22 additions & 1 deletion ESP8266Interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,17 @@
#define ESP8266_INTERFACE_H

#include "mbed.h"
#include "ESP8266.h"

#include "events/EventQueue.h"
#include "events/mbed_shared_queues.h"
#include "platform/Callback.h"
#include "netsocket/nsapi_types.h"
#include "netsocket/NetworkInterface.h"
#include "netsocket/NetworkStack.h"
#include "netsocket/WiFiAccessPoint.h"
#include "netsocket/WiFiInterface.h"

#include "ESP8266.h"

#define ESP8266_SOCKET_COUNT 5

Expand All @@ -44,6 +53,11 @@ class ESP8266Interface : public NetworkStack, public WiFiInterface
*/
ESP8266Interface(PinName tx, PinName rx, bool debug=false, PinName rts=NC, PinName cts=NC);

/**
* @brief ESP8266Interface default destructor
*/
~ESP8266Interface();

/** Start the interface
*
* Attempts to connect to a WiFi network. Requires ssid and passphrase to be set.
Expand Down Expand Up @@ -354,6 +368,13 @@ class ESP8266Interface : public NetworkStack, public WiFiInterface
// Connection state reporting to application
nsapi_connection_status_t _conn_stat;
Callback<void(nsapi_event_t, intptr_t)> _conn_stat_cb;

// Background OOB processing
// Use global EventQueue
events::EventQueue *_global_event_queue;
int _oob_event_id;
void proc_oob_evnt();
void _oob2global_event_queue();
};

#endif