Skip to content

Cellular: AT handler API #8749

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from Dec 20, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ set(unittest-includes ${unittest-includes}
# Source files
set(unittest-sources
../features/cellular/framework/AT/AT_CellularBase.cpp
../features/cellular/framework/AT/ATHandler_factory.cpp
)

# Test files
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ set(unittest-includes ${unittest-includes}
# Source files
set(unittest-sources
../features/cellular/framework/AT/AT_CellularContext.cpp
../features/cellular/framework/AT/ATHandler_factory.cpp
../features/cellular/framework/common/CellularUtil.cpp
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,16 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_get_at_handler)
EXPECT_TRUE(dev.open_power(&fh1));

ATHandler_stub::fh_value = NULL;

AT_CellularDevice *dev2 = new AT_CellularDevice(&fh1);
EXPECT_TRUE(dev2->open_information(&fh1));
ATHandler *at = dev2->get_at_handler();
EXPECT_TRUE(at->get_ref_count() == 4);
delete dev2;
EXPECT_TRUE(at->get_ref_count() == 3);
AT_CellularDevice dev3(&fh1);
EXPECT_TRUE(dev3.release_at_handler(at) == NSAPI_ERROR_OK);
EXPECT_TRUE(ATHandler_stub::ref_count == 2);
}

TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_open_network)
Expand Down Expand Up @@ -211,7 +221,7 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_close_information)
AT_CellularBase_stub::handler_value = AT_CellularBase_stub::handler_at_constructor_value;

dev.close_information();
EXPECT_TRUE(ATHandler_stub::ref_count == 1);
EXPECT_TRUE(ATHandler_stub::ref_count == kATHandler_destructor_ref_ount);

ATHandler_stub::fh_value = NULL;
}
Expand Down Expand Up @@ -276,13 +286,21 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_create_delete_context)
FileHandle_stub fh1;
AT_CellularDevice *dev = new AT_CellularDevice(&fh1);

ATHandler *at = dev->get_at_handler();
EXPECT_TRUE(at->get_ref_count() == 1);
EXPECT_TRUE(dev->release_at_handler(at) == NSAPI_ERROR_OK);

CellularContext *ctx = dev->create_context(NULL);
delete dev;

dev = new AT_CellularDevice(&fh1);
at = dev->get_at_handler();
EXPECT_TRUE(at->get_ref_count() == 1);
ctx = dev->create_context(NULL);
CellularContext *ctx1 = dev->create_context(&fh1);
EXPECT_TRUE(at->get_ref_count() == 3);
CellularContext *ctx2 = dev->create_context(&fh1);
EXPECT_TRUE(at->get_ref_count() == 4);

EXPECT_TRUE(ctx);
EXPECT_TRUE(ctx1);
Expand All @@ -293,13 +311,21 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_create_delete_context)
EXPECT_TRUE(xx);

dev->delete_context(ctx);
EXPECT_TRUE(at->get_ref_count() == 3);
dev->delete_context(ctx1);
EXPECT_TRUE(at->get_ref_count() == 2);
dev->delete_context(NULL);
EXPECT_TRUE(at->get_ref_count() == 2);
dev->delete_context(ctx2);
EXPECT_TRUE(at->get_ref_count() == 1);

ctx = dev->create_context(NULL);
EXPECT_TRUE(at->get_ref_count() == 2);
ctx1 = dev->create_context(&fh1);
EXPECT_TRUE(at->get_ref_count() == 3);
ctx2 = dev->create_context(&fh1);
EXPECT_TRUE(at->get_ref_count() == 4);
EXPECT_TRUE(dev->release_at_handler(at) == NSAPI_ERROR_OK);
EXPECT_TRUE(ctx);
EXPECT_TRUE(ctx1);
EXPECT_TRUE(ctx1 != ctx);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ set(unittest-includes ${unittest-includes}
set(unittest-sources
stubs/randLIB_stub.c
../features/cellular/framework/AT/AT_CellularDevice.cpp
../features/cellular/framework/AT/ATHandler_factory.cpp
)

# Test files
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,38 @@ TEST_F(TestATHandler, test_ATHandler_set_file_handle)
at.set_file_handle(&fh2);
}

TEST_F(TestATHandler, test_ATHandler_list)
{
EventQueue que;
FileHandle_stub fh1;

ATHandler::set_at_timeout_list(1000, false);
ATHandler::set_debug_list(false);

ATHandler *at1 = ATHandler::get_instance(&fh1, que, 0, ",", 0, 0);
EXPECT_TRUE(at1->get_ref_count() == 1);

ATHandler::set_at_timeout_list(1000, false);
ATHandler::set_debug_list(true);

EXPECT_TRUE(ATHandler::get_instance(NULL, que, 0, ",", 0, 0) == NULL);

ATHandler *at2 = ATHandler::get_instance(&fh1, que, 0, ",", 0, 0);
EXPECT_TRUE(at1->get_ref_count() == 2);
EXPECT_TRUE(at2->get_ref_count() == 2);

ATHandler::set_at_timeout_list(2000, true);
ATHandler::set_debug_list(false);

EXPECT_TRUE(at1->close() == NSAPI_ERROR_OK);
EXPECT_TRUE(at2->get_ref_count() == 1);
EXPECT_TRUE(at2->close() == NSAPI_ERROR_OK);
EXPECT_TRUE(at1->close() == NSAPI_ERROR_PARAMETER);

ATHandler::set_at_timeout_list(1000, false);
ATHandler::set_debug_list(false);
}

TEST_F(TestATHandler, test_ATHandler_lock)
{
EventQueue que;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ set(unittest-includes ${unittest-includes}
# Source files
set(unittest-sources
../features/cellular/framework/AT/ATHandler.cpp
../features/cellular/framework/AT/ATHandler_factory.cpp
../features/cellular/framework/common/CellularUtil.cpp
)

Expand Down
16 changes: 10 additions & 6 deletions UNITTESTS/stubs/ATHandler_stub.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,11 @@ int ATHandler_stub::urc_amount = 0;
mbed::Callback<void()> ATHandler_stub::callback[kATHandler_urc_table_max_size];
char *ATHandler_stub::urc_string_table[kATHandler_urc_table_max_size];

ATHandler::ATHandler(FileHandle *fh, EventQueue &queue, int timeout, const char *output_delimiter, uint16_t send_delay) :
ATHandler::ATHandler(FileHandle *fh, EventQueue &queue, uint32_t timeout, const char *output_delimiter, uint16_t send_delay) :
_nextATHandler(0),
_fileHandle(fh),
_queue(queue)
_queue(queue),
_ref_count(1)
{
ATHandler_stub::ref_count = 1;

Expand Down Expand Up @@ -95,22 +96,25 @@ ATHandler::~ATHandler()

void ATHandler::inc_ref_count()
{
ATHandler_stub::ref_count++;
_ref_count++;
ATHandler_stub::ref_count = _ref_count;
}

void ATHandler::dec_ref_count()
{
ATHandler_stub::ref_count--;
_ref_count--;
ATHandler_stub::ref_count = _ref_count;
}

int ATHandler::get_ref_count()
{
return ATHandler_stub::ref_count;
return _ref_count;
}

FileHandle *ATHandler::get_file_handle()
{
return ATHandler_stub::fh_value;
ATHandler_stub::fh_value = (FileHandle_stub *)_fileHandle;
return _fileHandle;
}

void ATHandler::set_file_handle(FileHandle *fh)
Expand Down
3 changes: 2 additions & 1 deletion UNITTESTS/stubs/AT_CellularBase_stub.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ AT_CellularBase::AT_CellularBase(ATHandler &at) : _at(at)

ATHandler &AT_CellularBase::get_at_handler()
{
return *AT_CellularBase_stub::handler_value;
AT_CellularBase_stub::handler_value = &_at;
return _at;
}

device_err_t AT_CellularBase::get_device_error() const
Expand Down
17 changes: 12 additions & 5 deletions UNITTESTS/stubs/AT_CellularDevice_stub.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,29 @@ AT_CellularDevice::AT_CellularDevice(FileHandle *fh) : CellularDevice(fh), _netw
_sim(0), _power(0), _information(0), _context_list(0), _default_timeout(DEFAULT_AT_TIMEOUT),
_modem_debug_on(false)
{
_atHandlers = new ATHandler(fh, _queue, 0, ",");
}

AT_CellularDevice::~AT_CellularDevice()
{
delete _atHandlers;
}

ATHandler *AT_CellularDevice::get_at_handler(FileHandle *fileHandle)
{
return _atHandlers;
return ATHandler::get_instance(fileHandle, _queue, _default_timeout, "\r", get_send_delay(), _modem_debug_on);
}

void AT_CellularDevice::release_at_handler(ATHandler *at_handler)
ATHandler *AT_CellularDevice::get_at_handler()
{
return get_at_handler(NULL);
}

nsapi_error_t AT_CellularDevice::release_at_handler(ATHandler *at_handler)
{
if (at_handler) {
return at_handler->close();
} else {
return NSAPI_ERROR_PARAMETER;
}
}

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

CellularNetwork *AT_CellularDevice::open_network(FileHandle *fh)
{
return new AT_CellularNetwork(*_atHandlers);
return new AT_CellularNetwork(*ATHandler::get_instance(fh, _queue, _default_timeout, "\r", get_send_delay(), _modem_debug_on));
}

CellularSMS *AT_CellularDevice::open_sms(FileHandle *fh)
Expand Down
8 changes: 8 additions & 0 deletions UNITTESTS/target_h/myCellularDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,14 @@ class myCellularDevice : public CellularDevice {
{
CellularDevice::cellular_callback(ev, ptr);
}
virtual ATHandler *get_at_handler()
{
return NULL;
}
virtual nsapi_error_t release_at_handler(ATHandler *at_handler)
{
return NSAPI_ERROR_OK;
}
AT_CellularNetwork *_network;
AT_CellularContext *_context_list;
};
Expand Down
15 changes: 15 additions & 0 deletions features/cellular/framework/API/CellularDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "CellularTargets.h"
#include "CellularStateMachine.h"
#include "Callback.h"
#include "ATHandler.h"

namespace mbed {

Expand Down Expand Up @@ -249,6 +250,20 @@ class CellularDevice {
*/
virtual CellularContext *get_context_list() const;

/** Get the current ATHandler instance in use for debug purposes etc.
* Once use has been finished call to release_at_handler() has to be made
*
* @return Pointer to the ATHandler in use
*/
virtual ATHandler *get_at_handler() = 0;

/** Release the ATHandler taken into use with get_at_handler()
*
* @param at_handler
* @return NSAPI_ERROR_OK on success, NSAPI_ERROR_PARAMETER on failure
*/
virtual nsapi_error_t release_at_handler(ATHandler *at_handler) = 0;

protected:
friend class AT_CellularNetwork;
friend class AT_CellularContext;
Expand Down
2 changes: 1 addition & 1 deletion features/cellular/framework/AT/ATHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ static const uint8_t map_3gpp_errors[][2] = {
{ 146, 46 }, { 178, 65 }, { 179, 66 }, { 180, 48 }, { 181, 83 }, { 171, 49 },
};

ATHandler::ATHandler(FileHandle *fh, EventQueue &queue, int timeout, const char *output_delimiter, uint16_t send_delay) :
ATHandler::ATHandler(FileHandle *fh, EventQueue &queue, uint32_t timeout, const char *output_delimiter, uint16_t send_delay) :
_nextATHandler(0),
_fileHandle(fh),
_queue(queue),
Expand Down
47 changes: 46 additions & 1 deletion features/cellular/framework/AT/ATHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class ATHandler {
* @param output_delimiter delimiter used when parsing at responses, "\r" should be used as output_delimiter
* @param send_delay the minimum delay in ms between the end of last response and the beginning of a new command
*/
ATHandler(FileHandle *fh, events::EventQueue &queue, int timeout, const char *output_delimiter, uint16_t send_delay = 0);
ATHandler(FileHandle *fh, events::EventQueue &queue, uint32_t timeout, const char *output_delimiter, uint16_t send_delay = 0);
virtual ~ATHandler();

/** Return used file handle.
Expand All @@ -83,6 +83,32 @@ class ATHandler {
*/
FileHandle *get_file_handle();

/** Get a new ATHandler instance, and update the linked list. Once the use of the ATHandler
* has finished, call to close() has to be made
*
* @param fileHandle filehandle used for reading AT responses and writing AT commands.
* If there is already an ATHandler with the same fileHandle pointer,
* then a pointer to that ATHandler instance will be returned with
* that ATHandler's queue, timeout, delimiter, send_delay and debug_on
* values
* @param queue Event queue used to transfer sigio events to this thread
* @param timeout Timeout when reading for AT response
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Timeout type mismatches the constructor.

* @param delimiter delimiter used when parsing at responses, "\r" should be used as output_delimiter
* @param send_delay the minimum delay in ms between the end of last response and the beginning of a new command
* @param debug_on Set true to enable debug traces
* @return NULL, if fileHandle is not set, or a pointer to an existing ATHandler, if the fileHandle is
* already in use. Otherwise a pointer to a new ATHandler instance is returned
*/
static ATHandler *get_instance(FileHandle *fileHandle, events::EventQueue &queue, uint32_t timeout,
const char *delimiter, uint16_t send_delay, bool debug_on);

/** Close and delete the current ATHandler instance, if the reference count to it is 0.
* Close() can be only called, if the ATHandler was opened with get_instance()
*
* @return NSAPI_ERROR_OK on success, NSAPI_ERROR_PARAMETER on failure
*/
nsapi_error_t close();

/** Locks the mutex for file handle if AT_HANDLER_MUTEX is defined.
*/
void lock();
Expand Down Expand Up @@ -127,10 +153,14 @@ class ATHandler {
device_err_t get_last_device_error() const;

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

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

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

/** Set timeout in milliseconds for all ATHandlers in the _atHandlers list
*
* @param timeout_milliseconds Timeout in milliseconds
* @param default_timeout Store as default timeout
*/
static void set_at_timeout_list(uint32_t timeout_milliseconds, bool default_timeout = false);

/** Restore timeout to previous timeout. Handy if there is a need to change timeout temporarily.
*/
void restore_at_timeout();
Expand Down Expand Up @@ -222,6 +259,8 @@ class ATHandler {
int32_t _ref_count;
bool _is_fh_usable;

static ATHandler *_atHandlers;

//*************************************
public:

Expand Down Expand Up @@ -398,6 +437,12 @@ class ATHandler {
*/
void set_debug(bool debug_on);

/** Set debug_on for all ATHandlers in the _atHandlers list
*
* @param debug_on Set true to enable debug traces
*/
static void set_debug_list(bool debug_on);

private:

// should fit any prefix and int
Expand Down
Loading