Skip to content

Commit 8e58962

Browse files
author
Teppo Järvelin
committed
Cellular: retry logic for CellularContext connect
State machine has retry logic until device is attached to network. After this CellularContext does the context activation e.g. connect. There was no retry logic for context activation. Added logic to CellularContext level so it's available for at and (upcoming)ril layers.
1 parent ba24cb2 commit 8e58962

File tree

19 files changed

+234
-56
lines changed

19 files changed

+234
-56
lines changed

UNITTESTS/features/cellular/framework/AT/at_cellularcontext/unittest.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,5 @@ set(unittest-test-sources
4141
stubs/us_ticker_stub.cpp
4242
stubs/UARTSerial_stub.cpp
4343
stubs/SerialBase_stub.cpp
44+
stubs/CellularContext_stub.cpp
4445
)

UNITTESTS/features/cellular/framework/AT/at_cellulardevice/unittest.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ set(unittest-test-sources
4343
stubs/UARTSerial_stub.cpp
4444
stubs/SerialBase_stub.cpp
4545
stubs/CellularStateMachine_stub.cpp
46+
stubs/CellularContext_stub.cpp
4647
)
4748

4849
# defines

UNITTESTS/features/cellular/framework/device/cellulardevice/unittest.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ set(unittest-test-sources
3232
stubs/Semaphore_stub.cpp
3333
stubs/NetworkInterface_stub.cpp
3434
stubs/NetworkInterfaceDefaults_stub.cpp
35+
stubs/CellularContext_stub.cpp
3536
)
3637

3738
# defines

UNITTESTS/features/cellular/framework/device/cellularstatemachine/unittest.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ set(unittest-test-sources
3838
stubs/Mutex_stub.cpp
3939
stubs/EventQueue_stub.cpp
4040
stubs/equeue_stub.c
41+
stubs/CellularContext_stub.cpp
4142
)
4243

4344
# defines

UNITTESTS/features/netsocket/cellular/CellularNonIPSocket/test_CellularNonIPSocket.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
#include "gtest/gtest.h"
1919
#include "features/netsocket/cellular/CellularNonIPSocket.h"
20-
#include "CellularContext_stub.h"
20+
#include "myCellularContext.h"
2121

2222
using namespace mbed;
2323

@@ -34,7 +34,7 @@ class TestCellularNonIPSocket : public testing::Test {
3434
protected:
3535
CellularNonIPSocket *socket;
3636
ControlPlane_netif_stub *cp_netif;
37-
CellularContext_stub cellular_context;
37+
myCellularContext cellular_context;
3838
nsapi_size_t dataSize;
3939
char dataBuf[10];
4040

UNITTESTS/features/netsocket/cellular/CellularNonIPSocket/unittest.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,5 @@ set(unittest-test-sources
1919
stubs/NetworkStack_stub.cpp
2020
stubs/EventFlags_stub.cpp
2121
stubs/Mutex_stub.cpp
22+
stubs/CellularContext_stub.cpp
2223
)

UNITTESTS/stubs/AT_CellularContext_stub.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
using namespace mbed;
2121

2222
AT_CellularContext::AT_CellularContext(ATHandler &at, CellularDevice *device, const char *apn, bool cp_req, bool nonip_req) :
23-
AT_CellularBase(at), _is_blocking(true), _is_connected(false),
24-
_current_op(OP_INVALID), _device(device), _nw(0), _fh(0), _cp_req(cp_req), _nonip_req(nonip_req), _cp_in_use(false)
23+
AT_CellularBase(at), _is_connected(false),
24+
_current_op(OP_INVALID), _fh(0), _cp_req(cp_req), _nonip_req(nonip_req), _cp_in_use(false)
2525
{
2626
_stack = NULL;
2727
_pdp_type = DEFAULT_PDP_TYPE;
@@ -37,6 +37,12 @@ AT_CellularContext::AT_CellularContext(ATHandler &at, CellularDevice *device, co
3737
_new_context_set = false;
3838
_next = NULL;
3939
_cp_netif = NULL;
40+
memset(_retry_timeout_array, 0, CELLULAR_RETRY_ARRAY_SIZE);
41+
_retry_array_length = 0;
42+
_retry_count = 0;
43+
_is_blocking = true;
44+
_device = device;
45+
_nw = NULL;
4046
}
4147

4248
AT_CellularContext::~AT_CellularContext()
@@ -240,10 +246,6 @@ void AT_CellularContext::cellular_callback(nsapi_event_t ev, intptr_t ptr)
240246
{
241247
}
242248

243-
void AT_CellularContext::call_network_cb(nsapi_connection_status_t status)
244-
{
245-
}
246-
247249
ControlPlane_netif *AT_CellularContext::get_cp_netif()
248250
{
249251
return NULL;
@@ -270,3 +272,8 @@ void AT_CellularContext::deactivate_non_ip_context()
270272
void AT_CellularContext::set_disconnect()
271273
{
272274
}
275+
276+
void AT_CellularContext::do_connect_with_retry()
277+
{
278+
279+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright (c) 2018, Arm Limited and affiliates.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#include "CellularContext.h"
19+
20+
namespace mbed {
21+
22+
void CellularContext::cp_data_received()
23+
{
24+
_cp_netif->data_received();
25+
}
26+
27+
void CellularContext::do_connect_with_retry()
28+
{
29+
do_connect();
30+
}
31+
32+
void CellularContext::do_connect()
33+
{
34+
_cb_data.error = NSAPI_ERROR_OK;
35+
}
36+
37+
void CellularContext::call_network_cb(nsapi_connection_status_t status)
38+
{
39+
if (_connect_status != status) {
40+
_connect_status = status;
41+
if (_status_cb) {
42+
_status_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, _connect_status);
43+
}
44+
}
45+
}
46+
47+
}

UNITTESTS/stubs/CellularStateMachine_stub.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,8 @@ void CellularStateMachine::set_cellular_callback(mbed::Callback<void(nsapi_event
7474
void CellularStateMachine::cellular_event_changed(nsapi_event_t ev, intptr_t ptr)
7575
{
7676
}
77+
78+
void CellularStateMachine::get_retry_timeout_array(uint16_t *timeout, int &array_len) const
79+
{
80+
81+
}

UNITTESTS/stubs/CellularContext_stub.h renamed to UNITTESTS/target_h/myCellularContext.h

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,23 @@
1515
* limitations under the License.
1616
*/
1717

18-
#include "cellular/framework/API/CellularContext.h"
18+
#include "CellularContext.h"
1919
#include "ControlPlane_netif_stub.h"
2020

2121
namespace mbed {
2222

23-
class CellularContext_stub : public CellularContext {
23+
class myCellularContext : public CellularContext {
2424
public:
2525
std::list<nsapi_error_t> return_values;
2626
nsapi_error_t return_value;
2727
ControlPlane_netif_stub *my_cp_netif;
2828

29-
CellularContext_stub()
29+
myCellularContext()
3030
{
3131
return_value = 0;
3232
my_cp_netif = NULL;
3333
}
34-
~CellularContext_stub()
34+
~myCellularContext()
3535
{
3636
if (my_cp_netif) {
3737
delete my_cp_netif;
@@ -186,10 +186,6 @@ class CellularContext_stub : public CellularContext {
186186
{
187187
};
188188

189-
void call_network_cb(nsapi_connection_status_t status)
190-
{
191-
};
192-
193189
ControlPlane_netif_stub *get_cp_netif()
194190
{
195191
if (!my_cp_netif) {
@@ -219,6 +215,11 @@ class CellularContext_stub : public CellularContext {
219215
void set_disconnect()
220216
{
221217
};
218+
219+
void do_connect_with_retry()
220+
{
221+
};
222+
222223
};
223224

224225
}

features/cellular/framework/API/CellularContext.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,22 @@ class CellularContext : public CellularInterface {
306306
*/
307307
void cp_data_received();
308308

309+
/** Retry logic after device attached to network. Retry to find and activate pdp context or in case
310+
* of PPP find correct pdp context and open data channel. Retry logic is the same which is used in
311+
* CellularStateMachine.
312+
*/
313+
virtual void do_connect_with_retry();
314+
315+
/** Helper method to call callback function if it is provided
316+
*
317+
* @param status connection status which is parameter in callback function
318+
*/
319+
void call_network_cb(nsapi_connection_status_t status);
320+
321+
/** Find and activate pdp context or in case of PPP find correct pdp context and open data channel.
322+
*/
323+
virtual void do_connect();
324+
309325
// member variables needed in target override methods
310326
NetworkStack *_stack; // must be pointer because of PPP
311327
pdp_type_t _pdp_type;
@@ -324,6 +340,12 @@ class CellularContext : public CellularInterface {
324340
bool _active_high;
325341

326342
ControlPlane_netif *_cp_netif;
343+
uint16_t _retry_timeout_array[CELLULAR_RETRY_ARRAY_SIZE];
344+
int _retry_array_length;
345+
int _retry_count;
346+
CellularDevice *_device;
347+
CellularNetwork *_nw;
348+
bool _is_blocking;
327349
};
328350

329351
/**

features/cellular/framework/API/CellularDevice.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,16 @@ class CellularDevice {
414414
protected:
415415
friend class AT_CellularNetwork;
416416
friend class AT_CellularContext;
417+
friend class CellularContext;
418+
419+
/** Get the retry array from the CellularStateMachine. Array is used in retry logic.
420+
* Array contains seconds and retry logic uses those second to wait before trying again.
421+
*
422+
* @param timeout timeout array containing seconds for retry logic. Must have space for
423+
* CELLULAR_RETRY_ARRAY_SIZE (defined in CellularCommon.h)
424+
* @param array_len length of the timeout array on return
425+
*/
426+
void get_retry_timeout_array(uint16_t *timeout, int &array_len) const;
417427

418428
/** Cellular callback to be attached to Network and CellularStateMachine classes.
419429
* CellularContext calls this when in PPP mode to provide network changes.

features/cellular/framework/AT/AT_CellularContext.cpp

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ using namespace mbed_cellular_util;
4545
using namespace mbed;
4646

4747
AT_CellularContext::AT_CellularContext(ATHandler &at, CellularDevice *device, const char *apn, bool cp_req, bool nonip_req) :
48-
AT_CellularBase(at), _is_connected(false), _is_blocking(true),
49-
_current_op(OP_INVALID), _device(device), _nw(0), _fh(0), _cp_req(cp_req), _nonip_req(nonip_req), _cp_in_use(false)
48+
AT_CellularBase(at), _is_connected(false), _current_op(OP_INVALID), _fh(0), _cp_req(cp_req),
49+
_nonip_req(nonip_req), _cp_in_use(false)
5050
{
5151
tr_info("New CellularContext %s (%p)", apn ? apn : "", this);
5252
_stack = NULL;
@@ -65,6 +65,12 @@ AT_CellularContext::AT_CellularContext(ATHandler &at, CellularDevice *device, co
6565
_dcd_pin = NC;
6666
_active_high = false;
6767
_cp_netif = NULL;
68+
memset(_retry_timeout_array, 0, CELLULAR_RETRY_ARRAY_SIZE);
69+
_retry_array_length = 0;
70+
_retry_count = 0;
71+
_is_blocking = true;
72+
_device = device;
73+
_nw = NULL;
6874
}
6975

7076
AT_CellularContext::~AT_CellularContext()
@@ -106,6 +112,11 @@ void AT_CellularContext::enable_hup(bool enable)
106112
}
107113
}
108114

115+
void AT_CellularContext::do_connect_with_retry()
116+
{
117+
CellularContext::do_connect_with_retry();
118+
}
119+
109120
nsapi_error_t AT_CellularContext::connect()
110121
{
111122
tr_info("CellularContext connect");
@@ -116,15 +127,15 @@ nsapi_error_t AT_CellularContext::connect()
116127

117128
nsapi_error_t err = _device->attach_to_network();
118129
_cb_data.error = check_operation(err, OP_CONNECT);
119-
130+
_retry_count = 0;
120131
if (_is_blocking) {
121132
if (_cb_data.error == NSAPI_ERROR_OK || _cb_data.error == NSAPI_ERROR_ALREADY) {
122-
do_connect();
133+
do_connect_with_retry();
123134
}
124135
} else {
125136
if (_cb_data.error == NSAPI_ERROR_ALREADY) {
126137
// device is already attached, to be async we must use queue to connect and give proper callbacks
127-
int id = _device->get_queue()->call_in(0, this, &AT_CellularContext::do_connect);
138+
int id = _device->get_queue()->call_in(0, this, &AT_CellularContext::do_connect_with_retry);
128139
if (id == 0) {
129140
return NSAPI_ERROR_NO_MEMORY;
130141
}
@@ -571,8 +582,6 @@ void AT_CellularContext::do_connect()
571582
_cb_data.error = open_data_channel();
572583
_at.unlock();
573584
if (_cb_data.error != NSAPI_ERROR_OK) {
574-
tr_error("Failed to open data channel!");
575-
call_network_cb(NSAPI_STATUS_DISCONNECTED);
576585
_is_connected = false;
577586
} else {
578587
_is_context_activated = true;
@@ -970,7 +979,8 @@ void AT_CellularContext::cellular_callback(nsapi_event_t ev, intptr_t ptr)
970979
if (_status_cb) {
971980
_status_cb(ev, ptr);
972981
}
973-
do_connect();
982+
_retry_count = 0;
983+
do_connect_with_retry();
974984
return;
975985
}
976986
}
@@ -1000,19 +1010,6 @@ void AT_CellularContext::cellular_callback(nsapi_event_t ev, intptr_t ptr)
10001010
}
10011011
}
10021012

1003-
void AT_CellularContext::call_network_cb(nsapi_connection_status_t status)
1004-
{
1005-
if (_connect_status != status) {
1006-
_connect_status = status;
1007-
if (_status_cb) {
1008-
_status_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, _connect_status);
1009-
}
1010-
if (_nw && _connect_status == NSAPI_STATUS_DISCONNECTED) {
1011-
tr_info("CellularContext disconnected");
1012-
}
1013-
}
1014-
}
1015-
10161013
ControlPlane_netif *AT_CellularContext::get_cp_netif()
10171014
{
10181015
tr_error("No control plane interface available from base context!");

features/cellular/framework/AT/AT_CellularContext.h

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,6 @@ class AT_CellularContext : public CellularContext, public AT_CellularBase {
8888
*/
8989
virtual uint32_t get_timeout_for_operation(ContextOperation op) const;
9090

91-
/** Helper method to call callback function if it is provided
92-
*
93-
* @param status connection status which is parameter in callback function
94-
*/
95-
void call_network_cb(nsapi_connection_status_t status);
96-
9791
virtual nsapi_error_t activate_non_ip_context();
9892
virtual nsapi_error_t setup_control_plane_opt();
9993
virtual void deactivate_non_ip_context();
@@ -117,14 +111,11 @@ class AT_CellularContext : public CellularContext, public AT_CellularBase {
117111
nsapi_error_t check_operation(nsapi_error_t err, ContextOperation op);
118112
AT_CellularBase::CellularProperty pdp_type_t_to_cellular_property(pdp_type_t pdp_type);
119113
void ciot_opt_cb(mbed::CellularNetwork::CIoT_Supported_Opt ciot_opt);
120-
114+
virtual void do_connect_with_retry();
121115
private:
122116
bool _is_connected;
123-
bool _is_blocking;
124117
ContextOperation _current_op;
125118
char _found_apn[MAX_APN_LENGTH];
126-
CellularDevice *_device;
127-
CellularNetwork *_nw;
128119
FileHandle *_fh;
129120
rtos::Semaphore _semaphore;
130121
rtos::Semaphore _cp_opt_semaphore;

features/cellular/framework/common/CellularCommon.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
#include <stdint.h>
2222
#include "nsapi_types.h"
2323

24+
const int CELLULAR_RETRY_ARRAY_SIZE = 10;
25+
2426
struct cell_callback_data_t {
2527
nsapi_error_t error; /* possible error code */
2628
int status_data; /* cellular_event_status related enum or other info in int format. Check cellular_event_status comments.*/

0 commit comments

Comments
 (0)