Skip to content

Commit eebffa8

Browse files
author
Ari Parkkila
committed
Cellular: Add API to clear CellularDevice
A new API `CellularDevice::clear()` to clean-up the modem to a default initial state. Function is virtual so it can be overridden. The default implementation clears all PDP contexts, but the the first one if that has APN defined as `nsapi.default-cellular-apn`. CellularStateMachine calls `clear()` to clean-up the modem on initial `connect()`, if the flag `cellular.clear-on-connect: true` is defined.
1 parent 409ef04 commit eebffa8

File tree

8 files changed

+109
-0
lines changed

8 files changed

+109
-0
lines changed

features/cellular/framework/API/CellularDevice.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,18 @@ class CellularDevice {
9090
*/
9191
virtual ~CellularDevice();
9292

93+
/** Clear modem to a default initial state
94+
*
95+
* Clear persistent user data from the modem, such as PDP contexts.
96+
*
97+
* @pre All open network services on modem, such as contexts and sockets, must be closed.
98+
* @post Modem power off/on may be needed to clear modem's runtime state.
99+
* @remark CellularStateMachine calls this on connect when `cellular.clear-on-connect: true`.
100+
*
101+
* @return NSAPI_ERROR_OK on success, otherwise modem may be need power cycling
102+
*/
103+
virtual nsapi_error_t clear();
104+
93105
/** Sets the modem up for powering on
94106
* This is equivalent to plugging in the device, i.e., attaching power and serial port.
95107
* In general, hard_power_on and soft_power_on provides a simple hardware abstraction layer

features/cellular/framework/AT/AT_CellularDevice.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,3 +613,12 @@ void AT_CellularDevice::cellular_callback(nsapi_event_t ev, intptr_t ptr, Cellul
613613
}
614614
CellularDevice::cellular_callback(ev, ptr, ctx);
615615
}
616+
617+
nsapi_error_t AT_CellularDevice::clear()
618+
{
619+
AT_CellularNetwork *net = static_cast<AT_CellularNetwork *>(open_network());
620+
nsapi_error_t err = net->clear();
621+
close_network();
622+
623+
return err;
624+
}

features/cellular/framework/AT/AT_CellularDevice.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ class AT_CellularDevice : public CellularDevice {
3939
AT_CellularDevice(FileHandle *fh);
4040
virtual ~AT_CellularDevice();
4141

42+
virtual nsapi_error_t clear();
43+
4244
virtual nsapi_error_t hard_power_on();
4345

4446
virtual nsapi_error_t hard_power_off();

features/cellular/framework/AT/AT_CellularNetwork.cpp

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,3 +630,63 @@ nsapi_error_t AT_CellularNetwork::set_packet_domain_event_reporting(bool on)
630630

631631
return _at.at_cmd_discard("+CGEREP", "=", "%d", on ? 1 : 0);
632632
}
633+
634+
nsapi_error_t AT_CellularNetwork::clear()
635+
{
636+
tr_info("AT_CellularNetwork::clear");
637+
638+
_at.lock();
639+
_at.cmd_start_stop("+CGDCONT", "?");
640+
_at.resp_start("+CGDCONT:");
641+
642+
struct context_s {
643+
context_s() : id(-1), next(0)
644+
{
645+
}
646+
int id;
647+
context_s *next;
648+
};
649+
CellularList<context_s> contexts;
650+
while (_at.info_resp()) {
651+
int cid = _at.read_int();
652+
// clear all but the default context
653+
if (cid <= 0) {
654+
continue;
655+
} else if (cid == 1) {
656+
#ifndef MBED_CONF_NSAPI_DEFAULT_CELLULAR_APN
657+
continue;
658+
#else
659+
char pdp_type_from_context[10];
660+
int pdp_type_len = _at.read_string(pdp_type_from_context, sizeof(pdp_type_from_context));
661+
if (pdp_type_len > 0) {
662+
char apn[MAX_ACCESSPOINT_NAME_LENGTH];
663+
int apn_len = _at.read_string(apn, sizeof(apn));
664+
if (apn_len >= 0) {
665+
if (strcmp(apn, MBED_CONF_NSAPI_DEFAULT_CELLULAR_APN) == 0) {
666+
continue;
667+
}
668+
}
669+
}
670+
#endif
671+
}
672+
contexts.add_new()->id = cid;
673+
}
674+
_at.resp_stop();
675+
if (contexts.get_head()) {
676+
// detach from network before delete contexts
677+
CellularNetwork::AttachStatus status = CellularNetwork::Detached;
678+
if (get_attach(status) == NSAPI_ERROR_OK && status == CellularNetwork::Attached) {
679+
if (_at.at_cmd_discard("+CGATT", "=0") != NSAPI_ERROR_OK) {
680+
tr_warn("Failed to detach from network");
681+
}
682+
}
683+
context_s *context = contexts.get_head();
684+
while (context) {
685+
if (_at.at_cmd_discard("+CGDCONT", "=", "%d", context->id) != NSAPI_ERROR_OK) {
686+
tr_warn("Clear context %d failed", context->id);
687+
}
688+
context = context->next;
689+
}
690+
}
691+
return _at.unlock_return_error();
692+
}

features/cellular/framework/AT/AT_CellularNetwork.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,13 @@ class AT_CellularNetwork : public CellularNetwork, public AT_CellularBase {
110110
* Can be overridden by the target class.
111111
*/
112112
virtual void get_context_state_command();
113+
114+
/** Clear the network and contexts to a known default state
115+
*
116+
* @return NSAPI_ERROR_OK on success
117+
*/
118+
nsapi_error_t clear();
119+
113120
private:
114121
void urc_creg();
115122
void urc_cereg();

features/cellular/framework/device/CellularDevice.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,4 +247,9 @@ void CellularDevice::set_retry_timeout_array(const uint16_t timeout[], int array
247247
}
248248
}
249249

250+
nsapi_error_t CellularDevice::clear()
251+
{
252+
return NSAPI_ERROR_OK;
253+
}
254+
250255
} // namespace mbed

features/cellular/framework/device/CellularStateMachine.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,16 @@ bool CellularStateMachine::device_ready()
345345
}
346346
#endif // MBED_CONF_CELLULAR_DEBUG_AT
347347

348+
#ifdef MBED_CONF_CELLULAR_CLEAR_ON_CONNECT
349+
if (_cellularDevice.clear() != NSAPI_ERROR_OK) {
350+
tr_warning("Failed to clear cellular device, now power cycling");
351+
(void) _cellularDevice.shutdown();
352+
(void) _cellularDevice.soft_power_off();
353+
(void) _cellularDevice.hard_power_off();
354+
return false;
355+
}
356+
#endif
357+
348358
send_event_cb(CellularDeviceReady);
349359
_cellularDevice.set_ready_cb(0);
350360

features/cellular/mbed_lib.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@
2424
"offload-dns-queries" : {
2525
"help": "Use modem IP stack for DNS queries, null or numeric simultaneous queries",
2626
"value": null
27+
},
28+
"clear-on-connect" : {
29+
"help": "Clear modem to a known default state on connect()",
30+
"value": true
2731
}
2832
}
2933
}

0 commit comments

Comments
 (0)