Merge branch 'gracefully_disconnect' of https://github.com/jarvte/mbed-os into dev_rollup

pull/8862/head
Martin Kojtal 2018-11-24 21:15:38 +00:00
commit 5ad7c3ee6e
5 changed files with 59 additions and 16 deletions

View File

@ -230,7 +230,7 @@ public:
*/
virtual nsapi_error_t get_attach(AttachStatus &status) = 0;
/** Request detach from a network.
/** Request detach and deregister from a network.
*
* @return NSAPI_ERROR_OK on success
* NSAPI_ERROR_DEVICE_ERROR on failure

View File

@ -72,7 +72,6 @@ ATHandler::ATHandler(FileHandle *fh, EventQueue &queue, int timeout, const char
_previous_at_timeout(timeout),
_at_send_delay(send_delay),
_last_response_stop(0),
_fh_sigio_set(false),
_processing(false),
_ref_count(1),
_is_fh_usable(true),
@ -109,9 +108,7 @@ ATHandler::ATHandler(FileHandle *fh, EventQueue &queue, int timeout, const char
set_tag(&_info_stop, CRLF);
set_tag(&_elem_stop, ")");
_fileHandle->set_blocking(false);
set_filehandle_sigio();
set_file_handle(fh);
}
void ATHandler::set_debug(bool debug_on)
@ -154,6 +151,8 @@ FileHandle *ATHandler::get_file_handle()
void ATHandler::set_file_handle(FileHandle *fh)
{
_fileHandle = fh;
_fileHandle->set_blocking(false);
set_filehandle_sigio();
}
void ATHandler::set_is_filehandle_usable(bool usable)
@ -312,11 +311,7 @@ void ATHandler::process_oob()
void ATHandler::set_filehandle_sigio()
{
if (_fh_sigio_set) {
return;
}
_fileHandle->sigio(mbed::Callback<void()>(this, &ATHandler::event));
_fh_sigio_set = true;
}
void ATHandler::reset_buffer()
@ -1230,3 +1225,26 @@ void ATHandler::debug_print(const char *p, int len)
}
#endif // MBED_CONF_CELLULAR_DEBUG_AT
}
bool ATHandler::sync(int timeout_ms)
{
tr_debug("AT sync");
// poll for 10 seconds
for (int i = 0; i < 10; i++) {
lock();
set_at_timeout(timeout_ms, false);
// For sync use an AT command that is supported by all modems and likely not used frequently,
// especially a common response like OK could be response to previous request.
cmd_start("AT+CMEE?");
cmd_stop();
resp_start("+CMEE:");
resp_stop();
restore_at_timeout();
unlock();
if (!_last_err) {
return true;
}
}
tr_error("AT sync failed");
return false;
}

View File

@ -181,6 +181,13 @@ public:
*/
void set_is_filehandle_usable(bool usable);
/** Synchronize AT command and response handling to modem.
*
* @param timeout_ms ATHandler timeout when trying to sync. Will be restored when function returns.
* @return true is synchronization was successful, false in case of failure
*/
bool sync(int timeout_ms);
protected:
void event();
#ifdef AT_HANDLER_MUTEX
@ -211,8 +218,6 @@ private:
uint16_t _at_send_delay;
uint64_t _last_response_stop;
bool _fh_sigio_set;
bool _processing;
int32_t _ref_count;
bool _is_fh_usable;

View File

@ -28,6 +28,7 @@
#define DEVICE_TIMEOUT 5 * 60 * 1000 // 5 minutes
#if NSAPI_PPP_AVAILABLE
#define AT_SYNC_TIMEOUT 1000 // 1 second timeout
#include "nsapi_ppp.h"
#endif
@ -557,6 +558,8 @@ void AT_CellularContext::do_connect()
tr_error("Failed to open data channel!");
call_network_cb(NSAPI_STATUS_DISCONNECTED);
_is_connected = false;
} else {
_is_context_activated = true;
}
}
#else
@ -630,13 +633,17 @@ nsapi_error_t AT_CellularContext::disconnect()
_at.lock();
_at.set_file_handle(_at.get_file_handle());
_at.set_is_filehandle_usable(true);
//_at.sync(); // consume extra characters after ppp disconnect, also it may take a while until modem listens AT commands
if (!_at.sync(AT_SYNC_TIMEOUT)) { // consume extra characters after ppp disconnect, also it may take a while until modem listens AT commands
tr_error("AT sync failed after PPP Disconnect");
}
_at.unlock();
#endif // NSAPI_PPP_AVAILABLE
_at.lock();
// deactivate a context only if we have activated
if (_is_context_activated) {
// CGACT and CGATT commands might take up to 3 minutes to respond.
_at.set_at_timeout(180 * 1000);
_is_context_active = false;
size_t active_contexts_count = 0;
_at.cmd_start("AT+CGACT?");
@ -662,16 +669,26 @@ nsapi_error_t AT_CellularContext::disconnect()
// 3GPP TS 27.007:
// For EPS, if an attempt is made to disconnect the last PDN connection, then the MT responds with ERROR
if (_is_context_active && (rat < CellularNetwork::RAT_E_UTRAN || active_contexts_count > 1)) {
_at.clear_error();
_at.cmd_start("AT+CGACT=0,");
_at.write_int(_cid);
_at.cmd_stop_read_resp();
}
if (_new_context_set) {
_at.clear_error();
_at.cmd_start("AT+CGDCONT=");
_at.write_int(_cid);
_at.cmd_stop_read_resp();
}
_at.clear_error();
_at.cmd_start("AT+CGATT=0");
_at.cmd_stop_read_resp();
_at.restore_at_timeout();
}
if (!_at.get_last_error()) {
_is_connected = false;
call_network_cb(NSAPI_STATUS_DISCONNECTED);
}
_is_connected = false;
call_network_cb(NSAPI_STATUS_DISCONNECTED);
return _at.unlock_return_error();
}

View File

@ -361,6 +361,9 @@ nsapi_error_t AT_CellularNetwork::detach()
_at.cmd_start("AT+CGATT=0");
_at.cmd_stop_read_resp();
_at.cmd_start("AT+COPS=2");
_at.cmd_stop_read_resp();
call_network_cb(NSAPI_STATUS_DISCONNECTED);
return _at.unlock_return_error();