Skip to content

Commit a655a53

Browse files
author
Teppo Järvelin
committed
Cellular: more gracefully disconnect.
1 parent d643034 commit a655a53

File tree

5 files changed

+59
-16
lines changed

5 files changed

+59
-16
lines changed

features/cellular/framework/API/CellularNetwork.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ class CellularNetwork {
228228
*/
229229
virtual nsapi_error_t get_attach(AttachStatus &status) = 0;
230230

231-
/** Request detach from a network.
231+
/** Request detach and deregister from a network.
232232
*
233233
* @return NSAPI_ERROR_OK on success
234234
* NSAPI_ERROR_DEVICE_ERROR on failure

features/cellular/framework/AT/ATHandler.cpp

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ ATHandler::ATHandler(FileHandle *fh, EventQueue &queue, int timeout, const char
6969
_previous_at_timeout(timeout),
7070
_at_send_delay(send_delay),
7171
_last_response_stop(0),
72-
_fh_sigio_set(false),
7372
_processing(false),
7473
_ref_count(1),
7574
_is_fh_usable(true),
@@ -106,9 +105,7 @@ ATHandler::ATHandler(FileHandle *fh, EventQueue &queue, int timeout, const char
106105
set_tag(&_info_stop, CRLF);
107106
set_tag(&_elem_stop, ")");
108107

109-
_fileHandle->set_blocking(false);
110-
111-
set_filehandle_sigio();
108+
set_file_handle(fh);
112109
}
113110

114111
void ATHandler::set_debug(bool debug_on)
@@ -151,6 +148,8 @@ FileHandle *ATHandler::get_file_handle()
151148
void ATHandler::set_file_handle(FileHandle *fh)
152149
{
153150
_fileHandle = fh;
151+
_fileHandle->set_blocking(false);
152+
set_filehandle_sigio();
154153
}
155154

156155
void ATHandler::set_is_filehandle_usable(bool usable)
@@ -309,11 +308,7 @@ void ATHandler::process_oob()
309308

310309
void ATHandler::set_filehandle_sigio()
311310
{
312-
if (_fh_sigio_set) {
313-
return;
314-
}
315311
_fileHandle->sigio(mbed::Callback<void()>(this, &ATHandler::event));
316-
_fh_sigio_set = true;
317312
}
318313

319314
void ATHandler::reset_buffer()
@@ -1207,3 +1202,26 @@ void ATHandler::debug_print(char *p, int len)
12071202
}
12081203
#endif // MBED_CONF_CELLULAR_DEBUG_AT
12091204
}
1205+
1206+
bool ATHandler::sync(int timeout_ms)
1207+
{
1208+
tr_debug("AT sync");
1209+
// poll for 10 seconds
1210+
for (int i = 0; i < 10; i++) {
1211+
lock();
1212+
set_at_timeout(timeout_ms, false);
1213+
// For sync use an AT command that is supported by all modems and likely not used frequently,
1214+
// especially a common response like OK could be response to previous request.
1215+
cmd_start("AT+CMEE?");
1216+
cmd_stop();
1217+
resp_start("+CMEE:");
1218+
resp_stop();
1219+
restore_at_timeout();
1220+
unlock();
1221+
if (!_last_err) {
1222+
return true;
1223+
}
1224+
}
1225+
tr_error("AT sync failed");
1226+
return false;
1227+
}

features/cellular/framework/AT/ATHandler.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,13 @@ class ATHandler {
181181
*/
182182
void set_is_filehandle_usable(bool usable);
183183

184+
/** Synchronize AT command and response handling to modem.
185+
*
186+
* @param timeout_ms ATHandler timeout when trying to sync. Will be restored when function returns.
187+
* @return true is synchronization was successful, false in case of failure
188+
*/
189+
bool sync(int timeout_ms);
190+
184191
protected:
185192
void event();
186193
#ifdef AT_HANDLER_MUTEX
@@ -211,8 +218,6 @@ class ATHandler {
211218
uint16_t _at_send_delay;
212219
uint64_t _last_response_stop;
213220

214-
bool _fh_sigio_set;
215-
216221
bool _processing;
217222
int32_t _ref_count;
218223
bool _is_fh_usable;

features/cellular/framework/AT/AT_CellularContext.cpp

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#define DEVICE_TIMEOUT 5 * 60 * 1000 // 5 minutes
2929

3030
#if NSAPI_PPP_AVAILABLE
31+
#define AT_SYNC_TIMEOUT 1000 // 1 second timeout
3132
#include "nsapi_ppp.h"
3233
#endif
3334

@@ -555,6 +556,8 @@ void AT_CellularContext::do_connect()
555556
tr_error("Failed to open data channel!");
556557
call_network_cb(NSAPI_STATUS_DISCONNECTED);
557558
_is_connected = false;
559+
} else {
560+
_is_context_activated = true;
558561
}
559562
}
560563
#else
@@ -627,13 +630,17 @@ nsapi_error_t AT_CellularContext::disconnect()
627630
_at.lock();
628631
_at.set_file_handle(_at.get_file_handle());
629632
_at.set_is_filehandle_usable(true);
630-
//_at.sync(); // consume extra characters after ppp disconnect, also it may take a while until modem listens AT commands
633+
if (!_at.sync(AT_SYNC_TIMEOUT)) { // consume extra characters after ppp disconnect, also it may take a while until modem listens AT commands
634+
tr_error("AT sync failed after PPP Disconnect");
635+
}
631636
_at.unlock();
632637
#endif // NSAPI_PPP_AVAILABLE
633638
_at.lock();
634639

635640
// deactivate a context only if we have activated
636641
if (_is_context_activated) {
642+
// CGACT and CGATT commands might take up to 3 minutes to respond.
643+
_at.set_at_timeout(180 * 1000);
637644
_is_context_active = false;
638645
size_t active_contexts_count = 0;
639646
_at.cmd_start("AT+CGACT?");
@@ -659,17 +666,27 @@ nsapi_error_t AT_CellularContext::disconnect()
659666
// 3GPP TS 27.007:
660667
// For EPS, if an attempt is made to disconnect the last PDN connection, then the MT responds with ERROR
661668
if (_is_context_active && (rat < CellularNetwork::RAT_E_UTRAN || active_contexts_count > 1)) {
669+
_at.clear_error();
662670
_at.cmd_start("AT+CGACT=0,");
663671
_at.write_int(_cid);
664672
_at.cmd_stop_read_resp();
665673
}
666-
}
667674

668-
if (!_at.get_last_error()) {
669-
_is_connected = false;
670-
call_network_cb(NSAPI_STATUS_DISCONNECTED);
675+
if (_new_context_set) {
676+
_at.clear_error();
677+
_at.cmd_start("AT+CGDCONT=");
678+
_at.write_int(_cid);
679+
_at.cmd_stop_read_resp();
680+
}
681+
_at.clear_error();
682+
_at.cmd_start("AT+CGATT=0");
683+
_at.cmd_stop_read_resp();
684+
_at.restore_at_timeout();
671685
}
672686

687+
_is_connected = false;
688+
call_network_cb(NSAPI_STATUS_DISCONNECTED);
689+
673690
return _at.unlock_return_error();
674691
}
675692

features/cellular/framework/AT/AT_CellularNetwork.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,9 @@ nsapi_error_t AT_CellularNetwork::detach()
350350
_at.cmd_start("AT+CGATT=0");
351351
_at.cmd_stop_read_resp();
352352

353+
_at.cmd_start("AT+COPS=2");
354+
_at.cmd_stop_read_resp();
355+
353356
call_network_cb(NSAPI_STATUS_DISCONNECTED);
354357

355358
return _at.unlock_return_error();

0 commit comments

Comments
 (0)