Skip to content

Commit 671c061

Browse files
authored
Merge pull request #8749 from TeemuKultala/cellular_at_handler_api
Cellular: AT handler API
2 parents 4d44e1c + b87b52a commit 671c061

File tree

16 files changed

+289
-74
lines changed

16 files changed

+289
-74
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ set(unittest-includes ${unittest-includes}
1616
# Source files
1717
set(unittest-sources
1818
../features/cellular/framework/AT/AT_CellularBase.cpp
19+
../features/cellular/framework/AT/ATHandler_factory.cpp
1920
)
2021

2122
# Test files

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ set(unittest-includes ${unittest-includes}
1414
# Source files
1515
set(unittest-sources
1616
../features/cellular/framework/AT/AT_CellularContext.cpp
17+
../features/cellular/framework/AT/ATHandler_factory.cpp
1718
../features/cellular/framework/common/CellularUtil.cpp
1819
)
1920

UNITTESTS/features/cellular/framework/AT/at_cellulardevice/at_cellulardevicetest.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,16 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_get_at_handler)
6161
EXPECT_TRUE(dev.open_power(&fh1));
6262

6363
ATHandler_stub::fh_value = NULL;
64+
65+
AT_CellularDevice *dev2 = new AT_CellularDevice(&fh1);
66+
EXPECT_TRUE(dev2->open_information(&fh1));
67+
ATHandler *at = dev2->get_at_handler();
68+
EXPECT_TRUE(at->get_ref_count() == 4);
69+
delete dev2;
70+
EXPECT_TRUE(at->get_ref_count() == 3);
71+
AT_CellularDevice dev3(&fh1);
72+
EXPECT_TRUE(dev3.release_at_handler(at) == NSAPI_ERROR_OK);
73+
EXPECT_TRUE(ATHandler_stub::ref_count == 2);
6474
}
6575

6676
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_open_network)
@@ -211,7 +221,7 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_close_information)
211221
AT_CellularBase_stub::handler_value = AT_CellularBase_stub::handler_at_constructor_value;
212222

213223
dev.close_information();
214-
EXPECT_TRUE(ATHandler_stub::ref_count == 1);
224+
EXPECT_TRUE(ATHandler_stub::ref_count == kATHandler_destructor_ref_ount);
215225

216226
ATHandler_stub::fh_value = NULL;
217227
}
@@ -276,13 +286,21 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_create_delete_context)
276286
FileHandle_stub fh1;
277287
AT_CellularDevice *dev = new AT_CellularDevice(&fh1);
278288

289+
ATHandler *at = dev->get_at_handler();
290+
EXPECT_TRUE(at->get_ref_count() == 1);
291+
EXPECT_TRUE(dev->release_at_handler(at) == NSAPI_ERROR_OK);
292+
279293
CellularContext *ctx = dev->create_context(NULL);
280294
delete dev;
281295

282296
dev = new AT_CellularDevice(&fh1);
297+
at = dev->get_at_handler();
298+
EXPECT_TRUE(at->get_ref_count() == 1);
283299
ctx = dev->create_context(NULL);
284300
CellularContext *ctx1 = dev->create_context(&fh1);
301+
EXPECT_TRUE(at->get_ref_count() == 3);
285302
CellularContext *ctx2 = dev->create_context(&fh1);
303+
EXPECT_TRUE(at->get_ref_count() == 4);
286304

287305
EXPECT_TRUE(ctx);
288306
EXPECT_TRUE(ctx1);
@@ -293,13 +311,21 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_create_delete_context)
293311
EXPECT_TRUE(xx);
294312

295313
dev->delete_context(ctx);
314+
EXPECT_TRUE(at->get_ref_count() == 3);
296315
dev->delete_context(ctx1);
316+
EXPECT_TRUE(at->get_ref_count() == 2);
297317
dev->delete_context(NULL);
318+
EXPECT_TRUE(at->get_ref_count() == 2);
298319
dev->delete_context(ctx2);
320+
EXPECT_TRUE(at->get_ref_count() == 1);
299321

300322
ctx = dev->create_context(NULL);
323+
EXPECT_TRUE(at->get_ref_count() == 2);
301324
ctx1 = dev->create_context(&fh1);
325+
EXPECT_TRUE(at->get_ref_count() == 3);
302326
ctx2 = dev->create_context(&fh1);
327+
EXPECT_TRUE(at->get_ref_count() == 4);
328+
EXPECT_TRUE(dev->release_at_handler(at) == NSAPI_ERROR_OK);
303329
EXPECT_TRUE(ctx);
304330
EXPECT_TRUE(ctx1);
305331
EXPECT_TRUE(ctx1 != ctx);

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ set(unittest-includes ${unittest-includes}
1818
set(unittest-sources
1919
stubs/randLIB_stub.c
2020
../features/cellular/framework/AT/AT_CellularDevice.cpp
21+
../features/cellular/framework/AT/ATHandler_factory.cpp
2122
)
2223

2324
# Test files

UNITTESTS/features/cellular/framework/AT/athandler/athandlertest.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,38 @@ TEST_F(TestATHandler, test_ATHandler_set_file_handle)
8686
at.set_file_handle(&fh2);
8787
}
8888

89+
TEST_F(TestATHandler, test_ATHandler_list)
90+
{
91+
EventQueue que;
92+
FileHandle_stub fh1;
93+
94+
ATHandler::set_at_timeout_list(1000, false);
95+
ATHandler::set_debug_list(false);
96+
97+
ATHandler *at1 = ATHandler::get_instance(&fh1, que, 0, ",", 0, 0);
98+
EXPECT_TRUE(at1->get_ref_count() == 1);
99+
100+
ATHandler::set_at_timeout_list(1000, false);
101+
ATHandler::set_debug_list(true);
102+
103+
EXPECT_TRUE(ATHandler::get_instance(NULL, que, 0, ",", 0, 0) == NULL);
104+
105+
ATHandler *at2 = ATHandler::get_instance(&fh1, que, 0, ",", 0, 0);
106+
EXPECT_TRUE(at1->get_ref_count() == 2);
107+
EXPECT_TRUE(at2->get_ref_count() == 2);
108+
109+
ATHandler::set_at_timeout_list(2000, true);
110+
ATHandler::set_debug_list(false);
111+
112+
EXPECT_TRUE(at1->close() == NSAPI_ERROR_OK);
113+
EXPECT_TRUE(at2->get_ref_count() == 1);
114+
EXPECT_TRUE(at2->close() == NSAPI_ERROR_OK);
115+
EXPECT_TRUE(at1->close() == NSAPI_ERROR_PARAMETER);
116+
117+
ATHandler::set_at_timeout_list(1000, false);
118+
ATHandler::set_debug_list(false);
119+
}
120+
89121
TEST_F(TestATHandler, test_ATHandler_lock)
90122
{
91123
EventQueue que;

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ set(unittest-includes ${unittest-includes}
1414
# Source files
1515
set(unittest-sources
1616
../features/cellular/framework/AT/ATHandler.cpp
17+
../features/cellular/framework/AT/ATHandler_factory.cpp
1718
../features/cellular/framework/common/CellularUtil.cpp
1819
)
1920

UNITTESTS/stubs/ATHandler_stub.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,11 @@ int ATHandler_stub::urc_amount = 0;
5757
mbed::Callback<void()> ATHandler_stub::callback[kATHandler_urc_table_max_size];
5858
char *ATHandler_stub::urc_string_table[kATHandler_urc_table_max_size];
5959

60-
ATHandler::ATHandler(FileHandle *fh, EventQueue &queue, int timeout, const char *output_delimiter, uint16_t send_delay) :
60+
ATHandler::ATHandler(FileHandle *fh, EventQueue &queue, uint32_t timeout, const char *output_delimiter, uint16_t send_delay) :
6161
_nextATHandler(0),
6262
_fileHandle(fh),
63-
_queue(queue)
63+
_queue(queue),
64+
_ref_count(1)
6465
{
6566
ATHandler_stub::ref_count = 1;
6667

@@ -95,22 +96,25 @@ ATHandler::~ATHandler()
9596

9697
void ATHandler::inc_ref_count()
9798
{
98-
ATHandler_stub::ref_count++;
99+
_ref_count++;
100+
ATHandler_stub::ref_count = _ref_count;
99101
}
100102

101103
void ATHandler::dec_ref_count()
102104
{
103-
ATHandler_stub::ref_count--;
105+
_ref_count--;
106+
ATHandler_stub::ref_count = _ref_count;
104107
}
105108

106109
int ATHandler::get_ref_count()
107110
{
108-
return ATHandler_stub::ref_count;
111+
return _ref_count;
109112
}
110113

111114
FileHandle *ATHandler::get_file_handle()
112115
{
113-
return ATHandler_stub::fh_value;
116+
ATHandler_stub::fh_value = (FileHandle_stub *)_fileHandle;
117+
return _fileHandle;
114118
}
115119

116120
void ATHandler::set_file_handle(FileHandle *fh)

UNITTESTS/stubs/AT_CellularBase_stub.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ AT_CellularBase::AT_CellularBase(ATHandler &at) : _at(at)
3434

3535
ATHandler &AT_CellularBase::get_at_handler()
3636
{
37-
return *AT_CellularBase_stub::handler_value;
37+
AT_CellularBase_stub::handler_value = &_at;
38+
return _at;
3839
}
3940

4041
device_err_t AT_CellularBase::get_device_error() const

UNITTESTS/stubs/AT_CellularDevice_stub.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,22 +27,29 @@ AT_CellularDevice::AT_CellularDevice(FileHandle *fh) : CellularDevice(fh), _netw
2727
_sim(0), _power(0), _information(0), _context_list(0), _default_timeout(DEFAULT_AT_TIMEOUT),
2828
_modem_debug_on(false)
2929
{
30-
_atHandlers = new ATHandler(fh, _queue, 0, ",");
3130
}
3231

3332
AT_CellularDevice::~AT_CellularDevice()
3433
{
35-
delete _atHandlers;
3634
}
3735

3836
ATHandler *AT_CellularDevice::get_at_handler(FileHandle *fileHandle)
3937
{
40-
return _atHandlers;
38+
return ATHandler::get_instance(fileHandle, _queue, _default_timeout, "\r", get_send_delay(), _modem_debug_on);
4139
}
4240

43-
void AT_CellularDevice::release_at_handler(ATHandler *at_handler)
41+
ATHandler *AT_CellularDevice::get_at_handler()
4442
{
43+
return get_at_handler(NULL);
44+
}
4545

46+
nsapi_error_t AT_CellularDevice::release_at_handler(ATHandler *at_handler)
47+
{
48+
if (at_handler) {
49+
return at_handler->close();
50+
} else {
51+
return NSAPI_ERROR_PARAMETER;
52+
}
4653
}
4754

4855
CellularContext *create_context(FileHandle *fh = NULL, const char *apn = MBED_CONF_NSAPI_DEFAULT_CELLULAR_APN)
@@ -57,7 +64,7 @@ void delete_context(CellularContext *context)
5764

5865
CellularNetwork *AT_CellularDevice::open_network(FileHandle *fh)
5966
{
60-
return new AT_CellularNetwork(*_atHandlers);
67+
return new AT_CellularNetwork(*ATHandler::get_instance(fh, _queue, _default_timeout, "\r", get_send_delay(), _modem_debug_on));
6168
}
6269

6370
CellularSMS *AT_CellularDevice::open_sms(FileHandle *fh)

UNITTESTS/target_h/myCellularDevice.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,14 @@ class myCellularDevice : public CellularDevice {
119119
{
120120
CellularDevice::cellular_callback(ev, ptr);
121121
}
122+
virtual ATHandler *get_at_handler()
123+
{
124+
return NULL;
125+
}
126+
virtual nsapi_error_t release_at_handler(ATHandler *at_handler)
127+
{
128+
return NSAPI_ERROR_OK;
129+
}
122130
AT_CellularNetwork *_network;
123131
AT_CellularContext *_context_list;
124132
};

features/cellular/framework/API/CellularDevice.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "CellularTargets.h"
2222
#include "CellularStateMachine.h"
2323
#include "Callback.h"
24+
#include "ATHandler.h"
2425

2526
namespace mbed {
2627

@@ -249,6 +250,20 @@ class CellularDevice {
249250
*/
250251
virtual CellularContext *get_context_list() const;
251252

253+
/** Get the current ATHandler instance in use for debug purposes etc.
254+
* Once use has been finished call to release_at_handler() has to be made
255+
*
256+
* @return Pointer to the ATHandler in use
257+
*/
258+
virtual ATHandler *get_at_handler() = 0;
259+
260+
/** Release the ATHandler taken into use with get_at_handler()
261+
*
262+
* @param at_handler
263+
* @return NSAPI_ERROR_OK on success, NSAPI_ERROR_PARAMETER on failure
264+
*/
265+
virtual nsapi_error_t release_at_handler(ATHandler *at_handler) = 0;
266+
252267
protected:
253268
friend class AT_CellularNetwork;
254269
friend class AT_CellularContext;

features/cellular/framework/AT/ATHandler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ static const uint8_t map_3gpp_errors[][2] = {
6060
{ 146, 46 }, { 178, 65 }, { 179, 66 }, { 180, 48 }, { 181, 83 }, { 171, 49 },
6161
};
6262

63-
ATHandler::ATHandler(FileHandle *fh, EventQueue &queue, int timeout, const char *output_delimiter, uint16_t send_delay) :
63+
ATHandler::ATHandler(FileHandle *fh, EventQueue &queue, uint32_t timeout, const char *output_delimiter, uint16_t send_delay) :
6464
_nextATHandler(0),
6565
_fileHandle(fh),
6666
_queue(queue),

features/cellular/framework/AT/ATHandler.h

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ class ATHandler {
7474
* @param output_delimiter delimiter used when parsing at responses, "\r" should be used as output_delimiter
7575
* @param send_delay the minimum delay in ms between the end of last response and the beginning of a new command
7676
*/
77-
ATHandler(FileHandle *fh, events::EventQueue &queue, int timeout, const char *output_delimiter, uint16_t send_delay = 0);
77+
ATHandler(FileHandle *fh, events::EventQueue &queue, uint32_t timeout, const char *output_delimiter, uint16_t send_delay = 0);
7878
virtual ~ATHandler();
7979

8080
/** Return used file handle.
@@ -83,6 +83,32 @@ class ATHandler {
8383
*/
8484
FileHandle *get_file_handle();
8585

86+
/** Get a new ATHandler instance, and update the linked list. Once the use of the ATHandler
87+
* has finished, call to close() has to be made
88+
*
89+
* @param fileHandle filehandle used for reading AT responses and writing AT commands.
90+
* If there is already an ATHandler with the same fileHandle pointer,
91+
* then a pointer to that ATHandler instance will be returned with
92+
* that ATHandler's queue, timeout, delimiter, send_delay and debug_on
93+
* values
94+
* @param queue Event queue used to transfer sigio events to this thread
95+
* @param timeout Timeout when reading for AT response
96+
* @param delimiter delimiter used when parsing at responses, "\r" should be used as output_delimiter
97+
* @param send_delay the minimum delay in ms between the end of last response and the beginning of a new command
98+
* @param debug_on Set true to enable debug traces
99+
* @return NULL, if fileHandle is not set, or a pointer to an existing ATHandler, if the fileHandle is
100+
* already in use. Otherwise a pointer to a new ATHandler instance is returned
101+
*/
102+
static ATHandler *get_instance(FileHandle *fileHandle, events::EventQueue &queue, uint32_t timeout,
103+
const char *delimiter, uint16_t send_delay, bool debug_on);
104+
105+
/** Close and delete the current ATHandler instance, if the reference count to it is 0.
106+
* Close() can be only called, if the ATHandler was opened with get_instance()
107+
*
108+
* @return NSAPI_ERROR_OK on success, NSAPI_ERROR_PARAMETER on failure
109+
*/
110+
nsapi_error_t close();
111+
86112
/** Locks the mutex for file handle if AT_HANDLER_MUTEX is defined.
87113
*/
88114
void lock();
@@ -127,10 +153,14 @@ class ATHandler {
127153
device_err_t get_last_device_error() const;
128154

129155
/** Increase reference count. Used for counting references to this instance.
156+
* Note that this should be used with care, if the ATHandler was taken into use
157+
* with get_instance()
130158
*/
131159
void inc_ref_count();
132160

133161
/** Decrease reference count. Used for counting references to this instance.
162+
* Note that this should be used with care, if the ATHandler was taken into use
163+
* with get_instance()
134164
*/
135165
void dec_ref_count();
136166

@@ -147,6 +177,13 @@ class ATHandler {
147177
*/
148178
void set_at_timeout(uint32_t timeout_milliseconds, bool default_timeout = false);
149179

180+
/** Set timeout in milliseconds for all ATHandlers in the _atHandlers list
181+
*
182+
* @param timeout_milliseconds Timeout in milliseconds
183+
* @param default_timeout Store as default timeout
184+
*/
185+
static void set_at_timeout_list(uint32_t timeout_milliseconds, bool default_timeout = false);
186+
150187
/** Restore timeout to previous timeout. Handy if there is a need to change timeout temporarily.
151188
*/
152189
void restore_at_timeout();
@@ -222,6 +259,8 @@ class ATHandler {
222259
int32_t _ref_count;
223260
bool _is_fh_usable;
224261

262+
static ATHandler *_atHandlers;
263+
225264
//*************************************
226265
public:
227266

@@ -398,6 +437,12 @@ class ATHandler {
398437
*/
399438
void set_debug(bool debug_on);
400439

440+
/** Set debug_on for all ATHandlers in the _atHandlers list
441+
*
442+
* @param debug_on Set true to enable debug traces
443+
*/
444+
static void set_debug_list(bool debug_on);
445+
401446
private:
402447

403448
// should fit any prefix and int

0 commit comments

Comments
 (0)