mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #10703 from AnttiKauppila/optimisation
Cellular: Removed boilerplate codepull/10867/head
commit
6000724de6
|
@ -16,7 +16,6 @@ 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
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
#include "CellularDevice_stub.h"
|
||||
#include "equeue_stub.h"
|
||||
#include "AT_CellularBase_stub.h"
|
||||
#include "CellularUtil_stub.h"
|
||||
#include "PinNames.h"
|
||||
|
||||
using namespace mbed;
|
||||
using namespace events;
|
||||
|
@ -62,6 +64,9 @@ protected:
|
|||
ATHandler_stub::read_string_table[kRead_string_table_size];
|
||||
ATHandler_stub::resp_stop_success_count = kResp_stop_count_default;
|
||||
CellularDevice_stub::connect_counter = 2;
|
||||
|
||||
CellularUtil_stub::char_table[0] = (char *)"\0";
|
||||
CellularUtil_stub::table_idx = 0;
|
||||
}
|
||||
|
||||
void TearDown()
|
||||
|
@ -131,6 +136,16 @@ public:
|
|||
AT_CellularContext::cellular_callback(ev, ptr);
|
||||
}
|
||||
|
||||
void activ_non_ip_context()
|
||||
{
|
||||
activate_non_ip_context();
|
||||
}
|
||||
|
||||
void deactiv_non_ip_context()
|
||||
{
|
||||
deactivate_non_ip_context();
|
||||
}
|
||||
|
||||
my_stack _st;
|
||||
};
|
||||
|
||||
|
@ -150,6 +165,19 @@ public:
|
|||
my_stack _st;
|
||||
};
|
||||
|
||||
class def_AT_CTX : public AT_CellularContext {
|
||||
public:
|
||||
def_AT_CTX(ATHandler &at, CellularDevice *device, const char *apn = MBED_CONF_NSAPI_DEFAULT_CELLULAR_APN) :
|
||||
AT_CellularContext(at, device, apn) {}
|
||||
virtual ~def_AT_CTX() {}
|
||||
|
||||
uint32_t do_op()
|
||||
{
|
||||
return AT_CellularContext::get_timeout_for_operation(mbed::CellularContext::ContextOperation(_op));
|
||||
}
|
||||
int _op;
|
||||
};
|
||||
|
||||
static int network_cb_count;
|
||||
static void network_cb(nsapi_event_t ev, intptr_t intptr)
|
||||
{
|
||||
|
@ -169,6 +197,9 @@ TEST_F(TestAT_CellularContext, Create)
|
|||
|
||||
ctx = new AT_CellularContext(at, &dev);
|
||||
EXPECT_TRUE(ctx != NULL);
|
||||
|
||||
ctx->get_device();
|
||||
EXPECT_EQ(NSAPI_STATUS_DISCONNECTED, ctx->get_connection_status());
|
||||
delete ctx;
|
||||
}
|
||||
|
||||
|
@ -325,6 +356,20 @@ TEST_F(TestAT_CellularContext, get_pdpcontext_params)
|
|||
ATHandler_stub::read_string_table[1] = (char *)"25.66.77.88";
|
||||
ATHandler_stub::read_string_table[0] = (char *)"004.003.002.001";
|
||||
|
||||
CellularUtil_stub::table_idx = 12;
|
||||
CellularUtil_stub::char_table[11] = (char *)"102:304:506:708:90A:B70:D0E:F10\0";
|
||||
CellularUtil_stub::char_table[10] = (char *)"102:32C:3706:708:90A:B0C:D0E:F10\0";
|
||||
CellularUtil_stub::char_table[9] = (char *)"1721:2C01:203:377B:E122:B01:000:7BEA\0";
|
||||
CellularUtil_stub::char_table[8] = (char *)"1.2.3.4\0";
|
||||
CellularUtil_stub::char_table[7] = (char *)"1.2.3.4\0";
|
||||
CellularUtil_stub::char_table[6] = (char *)"1.2.3.4\0";
|
||||
CellularUtil_stub::char_table[5] = (char *)"0.255.0.255\0";
|
||||
CellularUtil_stub::char_table[4] = (char *)"1.2.3.4\0";
|
||||
CellularUtil_stub::char_table[3] = (char *)"25.66.77.88\0";
|
||||
CellularUtil_stub::char_table[2] = (char *)"1.2.3.4\0";
|
||||
CellularUtil_stub::char_table[1] = (char *)"004.003.002.001\0";
|
||||
CellularUtil_stub::char_table[0] = (char *)"1.2.3.4\0";
|
||||
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == cn.get_pdpcontext_params(list));
|
||||
CellularContext::pdpcontext_params_t *params = list.get_head();
|
||||
EXPECT_TRUE(params != NULL);
|
||||
|
@ -457,6 +502,11 @@ TEST_F(TestAT_CellularContext, set_file_handle)
|
|||
AT_CellularDevice dev(&fh1);
|
||||
AT_CellularContext ctx(at, &dev);
|
||||
ctx.set_file_handle(&fh1);
|
||||
|
||||
UARTSerial ss(NC, NC);
|
||||
|
||||
ctx.set_file_handle(&ss, PTC0, true);
|
||||
ctx.enable_hup(true);
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularContext, connect_disconnect_sync)
|
||||
|
@ -481,10 +531,44 @@ TEST_F(TestAT_CellularContext, connect_disconnect_sync)
|
|||
data.error = NSAPI_ERROR_OK;
|
||||
ctx1.cellular_callback((nsapi_event_t)CellularDeviceReady, (intptr_t)&data);
|
||||
|
||||
ATHandler_stub::resp_info_true_counter = 1;
|
||||
ATHandler_stub::read_string_table[0] = (char *)"APN";
|
||||
ATHandler_stub::read_string_table[1] = (char *)"IP";
|
||||
ATHandler_stub::read_string_index = 2;
|
||||
ASSERT_EQ(ctx1.connect(), NSAPI_ERROR_OK);
|
||||
|
||||
ASSERT_EQ(network_cb_count, 5);
|
||||
|
||||
ASSERT_EQ(ctx1.disconnect(), NSAPI_ERROR_OK);
|
||||
ATHandler_stub::resp_info_true_counter = 1;
|
||||
ATHandler_stub::read_string_table[1] = (char *)"Non-IP";
|
||||
ATHandler_stub::read_string_index = 2;
|
||||
ASSERT_EQ(ctx1.connect(), NSAPI_ERROR_OK);
|
||||
|
||||
ASSERT_EQ(ctx1.disconnect(), NSAPI_ERROR_OK);
|
||||
ATHandler_stub::resp_info_true_counter = 1;
|
||||
ATHandler_stub::read_string_table[1] = (char *)"IPV6";
|
||||
ATHandler_stub::read_string_index = 2;
|
||||
ASSERT_EQ(ctx1.connect(), NSAPI_ERROR_OK);
|
||||
|
||||
AT_CellularBase_stub::supported_bool = true;
|
||||
ASSERT_EQ(ctx1.disconnect(), NSAPI_ERROR_OK);
|
||||
ATHandler_stub::resp_info_true_counter = 1;
|
||||
ATHandler_stub::read_string_table[1] = (char *)"IPV4V6";
|
||||
ATHandler_stub::read_string_index = 2;
|
||||
ASSERT_EQ(ctx1.connect(), NSAPI_ERROR_OK);
|
||||
AT_CellularBase_stub::supported_bool = false;
|
||||
|
||||
ASSERT_EQ(ctx1.disconnect(), NSAPI_ERROR_OK);
|
||||
ATHandler_stub::resp_info_true_counter = 1;
|
||||
ATHandler_stub::read_string_table[0] = (char *)"APN2";
|
||||
ATHandler_stub::read_string_table[1] = (char *)"IPV4V6";
|
||||
ATHandler_stub::read_string_index = 2;
|
||||
ATHandler_stub::int_value = 10;
|
||||
ctx1.set_credentials("APN");
|
||||
ASSERT_EQ(ctx1.connect(), NSAPI_ERROR_OK);
|
||||
ATHandler_stub::int_value = -1;
|
||||
|
||||
ASSERT_EQ(ctx1.connect(), NSAPI_ERROR_IS_CONNECTED);
|
||||
|
||||
EXPECT_TRUE(ctx1.is_connected() == true);
|
||||
|
@ -519,6 +603,26 @@ TEST_F(TestAT_CellularContext, connect_disconnect_sync)
|
|||
// More connect test after we are re-writted getting of PDP context...
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularContext, de_and_activate_non_ip_context)
|
||||
{
|
||||
EventQueue que;
|
||||
FileHandle_stub fh1;
|
||||
ATHandler at(&fh1, que, 0, ",");
|
||||
AT_CellularDevice dev(&fh1);
|
||||
my_AT_CTX ctx(at, &dev);
|
||||
ctx.attach(&network_cb);
|
||||
Semaphore_stub::acquire_return_value = true;
|
||||
|
||||
// call callback so that network is opened which is needed in disconnect
|
||||
cell_callback_data_t data;
|
||||
data.error = NSAPI_ERROR_OK;
|
||||
ctx.cellular_callback((nsapi_event_t)CellularDeviceReady, (intptr_t)&data);
|
||||
|
||||
ctx.activ_non_ip_context();
|
||||
|
||||
ctx.deactiv_non_ip_context();
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularContext, set_device_ready_sync)
|
||||
{
|
||||
EventQueue que;
|
||||
|
@ -625,3 +729,22 @@ TEST_F(TestAT_CellularContext, connect_disconnect_async)
|
|||
|
||||
// More connect test after we are re-writted getting of PDP context...
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularContext, get_timeout_for_operation)
|
||||
{
|
||||
EventQueue que;
|
||||
FileHandle_stub fh1;
|
||||
ATHandler at(&fh1, que, 0, ",");
|
||||
|
||||
AT_CellularDevice dev(&fh1);
|
||||
def_AT_CTX ctx1(at, &dev);
|
||||
ctx1._op = 1;
|
||||
EXPECT_EQ(300 * 1000, ctx1.do_op());
|
||||
|
||||
ctx1._op = 0;
|
||||
EXPECT_EQ(300 * 1000, ctx1.do_op());
|
||||
|
||||
ctx1._op = -1;
|
||||
EXPECT_EQ(1800 * 1000, ctx1.do_op());
|
||||
|
||||
}
|
||||
|
|
|
@ -15,8 +15,6 @@ 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
|
||||
)
|
||||
|
||||
# Test files
|
||||
|
@ -42,4 +40,5 @@ set(unittest-test-sources
|
|||
stubs/UARTSerial_stub.cpp
|
||||
stubs/SerialBase_stub.cpp
|
||||
stubs/CellularContext_stub.cpp
|
||||
stubs/CellularUtil_stub.cpp
|
||||
)
|
||||
|
|
|
@ -28,22 +28,36 @@ protected:
|
|||
|
||||
void SetUp()
|
||||
{
|
||||
EventQueue que;
|
||||
FileHandle_stub fh1;
|
||||
filehandle_stub_table = NULL;
|
||||
filehandle_stub_table_pos = 0;
|
||||
|
||||
ATHandler at(&fh1, que, 0, ",");
|
||||
ATHandler_stub::handler = &at;
|
||||
|
||||
ATHandler_stub::read_string_index = kRead_string_table_size;
|
||||
}
|
||||
|
||||
void TearDown()
|
||||
{
|
||||
ATHandler_stub::handler = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(TestAT_CellularDevice, Create)
|
||||
{
|
||||
FileHandle_stub fh1;
|
||||
|
||||
AT_CellularDevice dev(&fh1);
|
||||
|
||||
CellularDevice *dev2 = new AT_CellularDevice(&fh1);
|
||||
|
||||
EXPECT_TRUE(dev2 != NULL);
|
||||
delete dev2;
|
||||
ATHandler *at = dev.get_at_handler(&fh1);
|
||||
dev.release_at_handler(at);
|
||||
dev.release_at_handler(at);
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_get_at_handler)
|
||||
|
@ -54,6 +68,7 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_get_at_handler)
|
|||
AT_CellularDevice dev(&fh1); // AT fh1 ref count 1
|
||||
|
||||
EXPECT_TRUE(dev.open_network(&fh1)); // AT fh1 ref count 2
|
||||
dev.modem_debug_on(true);
|
||||
EXPECT_TRUE(dev.open_sms(&fh2));
|
||||
AT_CellularBase_stub::handler_value = AT_CellularBase_stub::handler_at_constructor_value;
|
||||
EXPECT_TRUE(dev.open_information(&fh3));
|
||||
|
@ -64,12 +79,12 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_get_at_handler)
|
|||
AT_CellularDevice *dev2 = new AT_CellularDevice(&fh1); // AT fh1 ref count 3
|
||||
EXPECT_TRUE(dev2->open_information(&fh1)); // AT fh1 ref count 4
|
||||
ATHandler *at = dev2->get_at_handler(); // AT fh1 ref count 5
|
||||
EXPECT_TRUE(at->get_ref_count() == 5);
|
||||
EXPECT_EQ(at->get_ref_count(), 6);
|
||||
delete dev2; // AT fh1 2 refs deleted -> ref count 3
|
||||
EXPECT_TRUE(at->get_ref_count() == 3);
|
||||
EXPECT_EQ(at->get_ref_count(), 4);
|
||||
AT_CellularDevice dev3(&fh1); // AT fh1 ref count 4
|
||||
EXPECT_TRUE(dev3.release_at_handler(at) == NSAPI_ERROR_OK); // AT fh1 ref count 3
|
||||
EXPECT_TRUE(ATHandler_stub::ref_count == 3);
|
||||
EXPECT_EQ(ATHandler_stub::ref_count, 4);
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_open_network)
|
||||
|
@ -118,10 +133,9 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_close_network)
|
|||
|
||||
EXPECT_TRUE(dev.open_network(&fh1));
|
||||
AT_CellularBase_stub::handler_value = AT_CellularBase_stub::handler_at_constructor_value;
|
||||
EXPECT_TRUE(ATHandler_stub::ref_count == 2);
|
||||
EXPECT_EQ(ATHandler_stub::ref_count, 1);
|
||||
|
||||
dev.close_network();
|
||||
EXPECT_TRUE(ATHANDLER_REF_COUNT_AT_DESTRUCTOR == kATHandler_destructor_ref_ount);
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_close_sms)
|
||||
|
@ -131,10 +145,9 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_close_sms)
|
|||
|
||||
EXPECT_TRUE(dev.open_sms(&fh1));
|
||||
AT_CellularBase_stub::handler_value = AT_CellularBase_stub::handler_at_constructor_value;
|
||||
EXPECT_TRUE(ATHandler_stub::ref_count == 2);
|
||||
EXPECT_EQ(ATHandler_stub::ref_count, 1);
|
||||
|
||||
dev.close_sms();
|
||||
EXPECT_TRUE(ATHANDLER_REF_COUNT_AT_DESTRUCTOR == kATHandler_destructor_ref_ount);
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_close_information)
|
||||
|
@ -158,7 +171,6 @@ 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_REF_COUNT_AT_DESTRUCTOR == kATHandler_destructor_ref_ount);
|
||||
|
||||
ATHandler_stub::fh_value = NULL;
|
||||
}
|
||||
|
@ -175,7 +187,7 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_set_timeout)
|
|||
EXPECT_TRUE(ATHandler_stub::default_timeout == true);
|
||||
|
||||
EXPECT_TRUE(dev.open_sms(&fh1));
|
||||
EXPECT_TRUE(ATHandler_stub::ref_count == 2);
|
||||
EXPECT_EQ(ATHandler_stub::ref_count, 1);
|
||||
|
||||
dev.set_timeout(5000);
|
||||
EXPECT_TRUE(ATHandler_stub::timeout == 5000);
|
||||
|
@ -194,7 +206,7 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_modem_debug_on)
|
|||
EXPECT_TRUE(ATHandler_stub::debug_on == true);
|
||||
|
||||
EXPECT_TRUE(dev.open_sms(&fh1));
|
||||
EXPECT_TRUE(ATHandler_stub::ref_count == 2);
|
||||
EXPECT_EQ(ATHandler_stub::ref_count, 1);
|
||||
|
||||
dev.modem_debug_on(true);
|
||||
EXPECT_TRUE(ATHandler_stub::debug_on == true);
|
||||
|
@ -268,7 +280,7 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_create_delete_context)
|
|||
AT_CellularDevice *dev = new AT_CellularDevice(&fh1);
|
||||
|
||||
ATHandler *at = dev->get_at_handler();
|
||||
EXPECT_TRUE(at->get_ref_count() == 2);
|
||||
EXPECT_EQ(at->get_ref_count(), 1);
|
||||
EXPECT_TRUE(dev->release_at_handler(at) == NSAPI_ERROR_OK);
|
||||
|
||||
CellularContext *ctx = dev->create_context(NULL);
|
||||
|
@ -276,12 +288,12 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_create_delete_context)
|
|||
|
||||
dev = new AT_CellularDevice(&fh1);
|
||||
at = dev->get_at_handler();
|
||||
EXPECT_TRUE(at->get_ref_count() == 2);
|
||||
EXPECT_EQ(at->get_ref_count(), 1);
|
||||
ctx = dev->create_context(NULL);
|
||||
CellularContext *ctx1 = dev->create_context(&fh1);
|
||||
EXPECT_TRUE(at->get_ref_count() == 4);
|
||||
EXPECT_EQ(at->get_ref_count(), 3);
|
||||
CellularContext *ctx2 = dev->create_context(&fh1);
|
||||
EXPECT_TRUE(at->get_ref_count() == 5);
|
||||
EXPECT_EQ(at->get_ref_count(), 4);
|
||||
|
||||
EXPECT_TRUE(ctx);
|
||||
EXPECT_TRUE(ctx1);
|
||||
|
@ -292,20 +304,20 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_create_delete_context)
|
|||
EXPECT_TRUE(xx);
|
||||
|
||||
dev->delete_context(ctx);
|
||||
EXPECT_TRUE(at->get_ref_count() == 4);
|
||||
EXPECT_EQ(at->get_ref_count(), 3);
|
||||
dev->delete_context(ctx1);
|
||||
EXPECT_TRUE(at->get_ref_count() == 3);
|
||||
EXPECT_EQ(at->get_ref_count(), 2);
|
||||
dev->delete_context(NULL);
|
||||
EXPECT_TRUE(at->get_ref_count() == 3);
|
||||
EXPECT_EQ(at->get_ref_count(), 2);
|
||||
dev->delete_context(ctx2);
|
||||
EXPECT_TRUE(at->get_ref_count() == 2);
|
||||
EXPECT_EQ(at->get_ref_count(), 1);
|
||||
|
||||
ctx = dev->create_context(NULL);
|
||||
EXPECT_TRUE(at->get_ref_count() == 3);
|
||||
EXPECT_EQ(at->get_ref_count(), 2);
|
||||
ctx1 = dev->create_context(&fh1);
|
||||
EXPECT_TRUE(at->get_ref_count() == 4);
|
||||
EXPECT_EQ(at->get_ref_count(), 3);
|
||||
ctx2 = dev->create_context(&fh1);
|
||||
EXPECT_TRUE(at->get_ref_count() == 5);
|
||||
EXPECT_EQ(at->get_ref_count(), 4);
|
||||
EXPECT_TRUE(dev->release_at_handler(at) == NSAPI_ERROR_OK);
|
||||
EXPECT_TRUE(ctx);
|
||||
EXPECT_TRUE(ctx1);
|
||||
|
@ -322,6 +334,9 @@ TEST_F(TestAT_CellularDevice, TestAT_CellularDevice_set_pin_verify_debug)
|
|||
ATHandler at(&fh1, que, 0, ",");
|
||||
AT_CellularDevice *dev = new AT_CellularDevice(&fh1);
|
||||
|
||||
ATHandler_stub::ssize_value = 8;
|
||||
ATHandler_stub::read_string_value = (char *)"internet";
|
||||
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
ATHandler_stub::get_debug_clear();
|
||||
EXPECT_FALSE(ATHandler_stub::is_get_debug_run());
|
||||
|
@ -375,6 +390,9 @@ TEST_F(TestAT_CellularDevice, TestAT_CellularDevice_get_sim_state)
|
|||
FileHandle_stub fh1;
|
||||
AT_CellularDevice *dev = new AT_CellularDevice(&fh1);
|
||||
|
||||
ATHandler_stub::ssize_value = 8;
|
||||
ATHandler_stub::read_string_value = (char *)"internet";
|
||||
|
||||
CellularDevice::SimState state;
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
ATHandler_stub::ssize_value = -1;
|
||||
|
|
|
@ -19,7 +19,6 @@ 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
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "FileHandle_stub.h"
|
||||
#include "CellularLog.h"
|
||||
#include "mbed_poll_stub.h"
|
||||
#include "CellularUtil_stub.h"
|
||||
|
||||
#include "Timer_stub.h"
|
||||
|
||||
|
@ -48,6 +49,8 @@ protected:
|
|||
void SetUp()
|
||||
{
|
||||
urc_callback_count = 0;
|
||||
CellularUtil_stub::char_ptr = NULL;
|
||||
CellularUtil_stub::char_pos = 0;
|
||||
}
|
||||
|
||||
void TearDown()
|
||||
|
@ -62,6 +65,8 @@ TEST_F(TestATHandler, Create)
|
|||
FileHandle_stub fh1;
|
||||
|
||||
ATHandler *at = new ATHandler(&fh1, que, 0, ",");
|
||||
at->set_default_delimiter();
|
||||
at->use_delimiter(true);
|
||||
|
||||
delete at;
|
||||
|
||||
|
@ -774,12 +779,20 @@ TEST_F(TestATHandler, test_ATHandler_read_string)
|
|||
EXPECT_TRUE(!strncmp(buf4, "1016", 4));
|
||||
EXPECT_TRUE(4 == at.read_string(buf4, 4 + 1/*for NULL*/));
|
||||
EXPECT_TRUE(!strncmp(buf4, "39AB", 4));
|
||||
at.set_is_filehandle_usable(false);
|
||||
EXPECT_TRUE(-1 == at.read_int());
|
||||
at.set_is_filehandle_usable(true);
|
||||
at.clear_error();
|
||||
EXPECT_TRUE(9 == at.read_int());
|
||||
|
||||
// *** CRLF part of the string ***
|
||||
at.clear_error();
|
||||
char table11[] = "\"s\"\r\nOK\r\n\0";
|
||||
mbed_poll_stub::int_value = 0;
|
||||
at.set_is_filehandle_usable(false);
|
||||
at.flush();
|
||||
at.set_is_filehandle_usable(true);
|
||||
at.clear_error();
|
||||
at.flush();
|
||||
filehandle_stub_table = table11;
|
||||
filehandle_stub_table_pos = 0;
|
||||
|
@ -840,6 +853,10 @@ TEST_F(TestATHandler, test_ATHandler_read_hex_string)
|
|||
char buf1[10];
|
||||
// Set _stop_tag to resp_stop(OKCRLF)
|
||||
at.resp_start();
|
||||
char resp[] = "hello\0";
|
||||
CellularUtil_stub::char_ptr = resp;
|
||||
CellularUtil_stub::char_pos = 0;
|
||||
|
||||
EXPECT_TRUE(5 == at.read_hex_string(buf1, 5));
|
||||
EXPECT_TRUE(!strncmp(buf1, "hello", 5));
|
||||
|
||||
|
@ -854,6 +871,7 @@ TEST_F(TestATHandler, test_ATHandler_read_hex_string)
|
|||
char buf2[10];
|
||||
// Set _stop_tag to resp_stop(OKCRLF)
|
||||
at.resp_start();
|
||||
CellularUtil_stub::char_pos = 0;
|
||||
EXPECT_TRUE(5 == at.read_hex_string(buf2, 6));
|
||||
EXPECT_TRUE(!strncmp(buf2, "hello", 5));
|
||||
|
||||
|
@ -868,6 +886,8 @@ TEST_F(TestATHandler, test_ATHandler_read_hex_string)
|
|||
char buf3[6];
|
||||
// Set _stop_tag to resp_stop(OKCRLF)
|
||||
at.resp_start();
|
||||
CellularUtil_stub::char_pos = 0;
|
||||
|
||||
EXPECT_TRUE(2 == at.read_hex_string(buf3, 2 + 1/*get to stop tag match*/));
|
||||
EXPECT_TRUE(!strncmp(buf3, "he", 2));
|
||||
at.resp_stop();
|
||||
|
@ -883,6 +903,8 @@ TEST_F(TestATHandler, test_ATHandler_read_hex_string)
|
|||
char buf4[6];
|
||||
// Set _stop_tag to resp_stop(OKCRLF)
|
||||
at.resp_start();
|
||||
CellularUtil_stub::char_pos = 0;
|
||||
|
||||
EXPECT_TRUE(1 == at.read_hex_string(buf4, 2 + 1/*get to stop tag match*/));
|
||||
EXPECT_TRUE(!strncmp(buf4, "h", 1));
|
||||
}
|
||||
|
@ -1278,3 +1300,84 @@ TEST_F(TestATHandler, test_ATHandler_get_3gpp_error)
|
|||
at.get_3gpp_error();
|
||||
}
|
||||
|
||||
TEST_F(TestATHandler, test_ATHandler_cmd_start_stop)
|
||||
{
|
||||
EventQueue que;
|
||||
FileHandle_stub fh1;
|
||||
|
||||
ATHandler at(&fh1, que, 0, ",");
|
||||
uint8_t byte[] = {1, 2, 3, 4};
|
||||
at.cmd_start_stop("+CREG", "=1,", "%d%s%b", 3, "test", byte, 4);
|
||||
}
|
||||
|
||||
TEST_F(TestATHandler, test_ATHandler_at_cmd_str)
|
||||
{
|
||||
EventQueue que;
|
||||
FileHandle_stub fh1;
|
||||
|
||||
ATHandler at(&fh1, que, 0, ",");
|
||||
uint8_t byte[] = {1, 2, 3, 4};
|
||||
char ret[10];
|
||||
|
||||
char table[] = "ssssssssssssssssssssssssssssOK\r\n\0";
|
||||
filehandle_stub_table = table;
|
||||
|
||||
at.flush();
|
||||
at.clear_error();
|
||||
filehandle_stub_table_pos = 0;
|
||||
mbed_poll_stub::int_value = 1;
|
||||
fh1.short_value = POLLIN;
|
||||
|
||||
EXPECT_EQ(NSAPI_ERROR_DEVICE_ERROR, at.at_cmd_str("+CREG", "=1,", ret, 10, "%d%s%b", 3, "test", byte, 4));
|
||||
}
|
||||
|
||||
TEST_F(TestATHandler, test_ATHandler_at_cmd_int)
|
||||
{
|
||||
EventQueue que;
|
||||
FileHandle_stub fh1;
|
||||
|
||||
ATHandler at(&fh1, que, 0, ",");
|
||||
uint8_t byte[] = {1, 2, 3, 4};
|
||||
int ret;
|
||||
EXPECT_EQ(NSAPI_ERROR_DEVICE_ERROR, at.at_cmd_int("+CREG", "=1,", ret, "%d%s%b", 3, "test", byte, 4));
|
||||
}
|
||||
|
||||
TEST_F(TestATHandler, test_ATHandler_at_cmd_discard)
|
||||
{
|
||||
EventQueue que;
|
||||
FileHandle_stub fh1;
|
||||
|
||||
ATHandler at(&fh1, que, 0, ",");
|
||||
uint8_t byte[] = {1, 2, 3, 4};
|
||||
|
||||
EXPECT_EQ(NSAPI_ERROR_DEVICE_ERROR, at.at_cmd_discard("+CREG", "=1,", "%d%s%b", 3, "test", byte, 4));
|
||||
}
|
||||
|
||||
TEST_F(TestATHandler, test_ATHandler_sync)
|
||||
{
|
||||
EventQueue que;
|
||||
FileHandle_stub fh1;
|
||||
|
||||
mbed_poll_stub::revents_value = 0;
|
||||
ATHandler at(&fh1, que, 0, ",");
|
||||
at.set_is_filehandle_usable(false);
|
||||
EXPECT_EQ(false, at.sync(100));
|
||||
at.set_is_filehandle_usable(true);
|
||||
EXPECT_EQ(false, at.sync(100));
|
||||
|
||||
fh1.size_value = 8;
|
||||
char table[] = "OK\r\n\0";
|
||||
filehandle_stub_table = table;
|
||||
|
||||
at.flush();
|
||||
at.clear_error();
|
||||
filehandle_stub_table_pos = 0;
|
||||
mbed_poll_stub::revents_value = POLLIN + POLLOUT;
|
||||
fh1.size_value = 10;
|
||||
mbed_poll_stub::int_value = 1;
|
||||
filehandle_stub_short_value_counter = 1;
|
||||
fh1.short_value = POLLIN;
|
||||
|
||||
EXPECT_EQ(true, at.sync(100));
|
||||
}
|
||||
|
||||
|
|
|
@ -14,8 +14,6 @@ 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
|
||||
)
|
||||
|
||||
# Test files
|
||||
|
@ -33,6 +31,7 @@ set(unittest-test-sources
|
|||
stubs/Kernel_stub.cpp
|
||||
stubs/ThisThread_stub.cpp
|
||||
stubs/randLIB_stub.cpp
|
||||
stubs/CellularUtil_stub.cpp
|
||||
)
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DMBED_CONF_CELLULAR_DEBUG_AT=true -DOS_STACK_SIZE=2048")
|
||||
|
|
|
@ -14,7 +14,6 @@ set(unittest-includes ${unittest-includes}
|
|||
# Source files
|
||||
set(unittest-sources
|
||||
../features/cellular/framework/device/CellularStateMachine.cpp
|
||||
../features/cellular/framework/AT/ATHandler_factory.cpp
|
||||
)
|
||||
|
||||
# Test files
|
||||
|
|
|
@ -25,9 +25,11 @@ using namespace events;
|
|||
|
||||
#include "CellularLog.h"
|
||||
|
||||
const int DEFAULT_AT_TIMEOUT = 1000; // at default timeout in milliseconds
|
||||
const int DEFAULT_AT_TIMEOUT = 1000;
|
||||
const uint8_t MAX_RESP_LENGTH = 7;
|
||||
|
||||
mbed::ATHandler *ATHandler_stub::handler = NULL;
|
||||
|
||||
nsapi_error_t ATHandler_stub::nsapi_error_value = 0;
|
||||
uint8_t ATHandler_stub::nsapi_error_ok_counter = 0;
|
||||
int ATHandler_stub::int_value = -1;
|
||||
|
@ -88,8 +90,6 @@ ATHandler::ATHandler(FileHandle *fh, EventQueue &queue, uint32_t timeout, const
|
|||
_oobs(NULL),
|
||||
_max_resp_length(MAX_RESP_LENGTH)
|
||||
{
|
||||
ATHandler_stub::ref_count = 1;
|
||||
|
||||
ATHandler_stub::process_oob_urc = false;
|
||||
}
|
||||
|
||||
|
@ -108,29 +108,21 @@ bool ATHandler::get_debug() const
|
|||
|
||||
ATHandler::~ATHandler()
|
||||
{
|
||||
ATHandler_stub::ref_count = kATHandler_destructor_ref_ount;
|
||||
while (_oobs) {
|
||||
struct oob_t *oob = _oobs;
|
||||
_oobs = oob->next;
|
||||
delete oob;
|
||||
}
|
||||
}
|
||||
|
||||
void ATHandler::inc_ref_count()
|
||||
{
|
||||
_ref_count++;
|
||||
ATHandler_stub::ref_count = _ref_count;
|
||||
ATHandler_stub::ref_count++;
|
||||
}
|
||||
|
||||
void ATHandler::dec_ref_count()
|
||||
{
|
||||
_ref_count--;
|
||||
ATHandler_stub::ref_count = _ref_count;
|
||||
ATHandler_stub::ref_count--;
|
||||
}
|
||||
|
||||
int ATHandler::get_ref_count()
|
||||
{
|
||||
return _ref_count;
|
||||
return ATHandler_stub::ref_count;
|
||||
}
|
||||
|
||||
FileHandle *ATHandler::get_file_handle()
|
||||
|
@ -145,43 +137,15 @@ void ATHandler::set_file_handle(FileHandle *fh)
|
|||
|
||||
bool ATHandler::find_urc_handler(const char *prefix)
|
||||
{
|
||||
struct oob_t *oob = _oobs;
|
||||
while (oob) {
|
||||
if (strcmp(prefix, oob->prefix) == 0) {
|
||||
return true;
|
||||
}
|
||||
oob = oob->next;
|
||||
}
|
||||
|
||||
return false;
|
||||
return ATHandler_stub::bool_value;
|
||||
}
|
||||
|
||||
void ATHandler::set_urc_handler(const char *urc, mbed::Callback<void()> cb)
|
||||
{
|
||||
if (!cb) {
|
||||
remove_urc_handler(urc);
|
||||
return;
|
||||
}
|
||||
|
||||
if (find_urc_handler(urc)) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct oob_t *oob = new struct oob_t;
|
||||
size_t prefix_len = strlen(urc);
|
||||
if (prefix_len > _oob_string_max_length) {
|
||||
_oob_string_max_length = prefix_len;
|
||||
if (_oob_string_max_length > _max_resp_length) {
|
||||
_max_resp_length = _oob_string_max_length;
|
||||
}
|
||||
}
|
||||
|
||||
oob->prefix = urc;
|
||||
oob->prefix_len = prefix_len;
|
||||
oob->cb = cb;
|
||||
oob->next = _oobs;
|
||||
_oobs = oob;
|
||||
|
||||
if (ATHandler_stub::call_immediately) {
|
||||
cb();
|
||||
}
|
||||
|
@ -189,21 +153,6 @@ void ATHandler::set_urc_handler(const char *urc, mbed::Callback<void()> cb)
|
|||
|
||||
void ATHandler::remove_urc_handler(const char *prefix)
|
||||
{
|
||||
struct oob_t *current = _oobs;
|
||||
struct oob_t *prev = NULL;
|
||||
while (current) {
|
||||
if (strcmp(prefix, current->prefix) == 0) {
|
||||
if (prev) {
|
||||
prev->next = current->next;
|
||||
} else {
|
||||
_oobs = current->next;
|
||||
}
|
||||
delete current;
|
||||
break;
|
||||
}
|
||||
prev = current;
|
||||
current = prev->next;
|
||||
}
|
||||
}
|
||||
|
||||
nsapi_error_t ATHandler::get_last_error() const
|
||||
|
@ -240,16 +189,6 @@ void ATHandler::restore_at_timeout()
|
|||
|
||||
void ATHandler::process_oob()
|
||||
{
|
||||
if (ATHandler_stub::process_oob_urc) {
|
||||
size_t prefix_len = 0;
|
||||
for (struct oob_t *oob = _oobs; oob; oob = oob->next) {
|
||||
prefix_len = oob->prefix_len;
|
||||
if (!memcmp(oob->prefix, ATHandler_stub::read_string_table[ATHandler_stub::read_string_index], prefix_len)) {
|
||||
oob->cb();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ATHandler::clear_error()
|
||||
|
@ -273,7 +212,7 @@ ssize_t ATHandler::read_bytes(uint8_t *buf, size_t len)
|
|||
|
||||
ssize_t ATHandler::read_string(char *buf, size_t size, bool read_even_stop_tag)
|
||||
{
|
||||
|
||||
buf[0] = '\0';
|
||||
if (ATHandler_stub::read_string_index == kRead_string_table_size) {
|
||||
if (ATHandler_stub::read_string_value && ATHandler_stub::ssize_value >= 0) {
|
||||
memcpy(buf, ATHandler_stub::read_string_value, ATHandler_stub::ssize_value + 1);
|
||||
|
@ -305,7 +244,6 @@ int32_t ATHandler::read_int()
|
|||
return ATHandler_stub::int_value;
|
||||
}
|
||||
|
||||
//printf("ATHandler_stub::int_count: %d", ATHandler_stub::int_count);
|
||||
ATHandler_stub::int_count--;
|
||||
if (ATHandler_stub::int_count < kRead_int_table_size && ATHandler_stub::int_count >= 0) {
|
||||
return ATHandler_stub::int_valid_count_table[ATHandler_stub::int_count];
|
||||
|
@ -338,20 +276,6 @@ void ATHandler::resp_start(const char *prefix, bool stop)
|
|||
|
||||
bool ATHandler::info_resp()
|
||||
{
|
||||
//3 counter variables available here now so that in a test
|
||||
//case it is possible to have at least two while loops checking
|
||||
//specified amount of info_resps.
|
||||
//
|
||||
//For example:
|
||||
//while(athandler.info_resp())
|
||||
//{
|
||||
// resp_info_true_counter responses handled in this loop
|
||||
//}
|
||||
// resp_info_false_counter set to 1 to break out from the 1st loop
|
||||
//while(athandler.info_resp())
|
||||
//{
|
||||
// resp_info_true_counter2 responses handled in this loop
|
||||
//}
|
||||
if (ATHandler_stub::resp_info_true_counter) {
|
||||
ATHandler_stub::resp_info_true_counter--;
|
||||
return true;
|
||||
|
@ -430,3 +354,54 @@ void ATHandler::flush()
|
|||
{
|
||||
|
||||
}
|
||||
|
||||
nsapi_error_t ATHandler::at_cmd_str(const char *cmd, const char *cmd_chr, char *resp_buf,
|
||||
size_t buf_size, const char *format, ...)
|
||||
{
|
||||
read_string(resp_buf, buf_size);
|
||||
return ATHandler_stub::nsapi_error_value;
|
||||
}
|
||||
|
||||
nsapi_error_t ATHandler::at_cmd_int(const char *cmd, const char *cmd_chr, int &resp,
|
||||
const char *format, ...)
|
||||
{
|
||||
resp = read_int();
|
||||
return ATHandler_stub::nsapi_error_value;
|
||||
}
|
||||
|
||||
void ATHandler::cmd_start_stop(const char *cmd, const char *cmd_chr, const char *format, ...)
|
||||
{
|
||||
}
|
||||
|
||||
nsapi_error_t ATHandler::at_cmd_discard(const char *cmd, const char *cmd_chr,
|
||||
const char *format, ...)
|
||||
{
|
||||
return ATHandler_stub::nsapi_error_value;
|
||||
}
|
||||
|
||||
ATHandler *ATHandler::get_instance(FileHandle *fileHandle, events::EventQueue &queue, uint32_t timeout,
|
||||
const char *delimiter, uint16_t send_delay, bool debug_on)
|
||||
{
|
||||
ATHandler_stub::ref_count++;
|
||||
int a = ATHandler_stub::ref_count;
|
||||
a = 0;
|
||||
return ATHandler_stub::handler;
|
||||
}
|
||||
|
||||
nsapi_error_t ATHandler::close()
|
||||
{
|
||||
ATHandler_stub::ref_count--;
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
void ATHandler::set_at_timeout_list(uint32_t timeout_milliseconds, bool default_timeout)
|
||||
{
|
||||
ATHandler_stub::timeout = timeout_milliseconds;
|
||||
ATHandler_stub::default_timeout = default_timeout;
|
||||
}
|
||||
|
||||
void ATHandler::set_debug_list(bool debug_on)
|
||||
{
|
||||
ATHandler_stub::debug_on = debug_on;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,17 +26,14 @@
|
|||
#ifndef __AT_HANDLER_STUB_H__
|
||||
#define __AT_HANDLER_STUB_H__
|
||||
|
||||
#define ATHANDLER_REF_COUNT_AT_DESTRUCTOR -909
|
||||
|
||||
static const int kRead_string_table_size = 100;
|
||||
static const int kRead_int_table_size = 100;
|
||||
static const int kResp_stop_count_default = 100;
|
||||
// set reference count to -909 to separate it from zero so we can test that ATHandler is really deleted.
|
||||
static const int kATHandler_destructor_ref_ount = ATHANDLER_REF_COUNT_AT_DESTRUCTOR;
|
||||
static const int kATHandler_urc_table_max_size = 10;
|
||||
static const int kATHandler_urc_string_max_size = 16;
|
||||
|
||||
namespace ATHandler_stub {
|
||||
extern mbed::ATHandler *handler;
|
||||
extern nsapi_error_t nsapi_error_value;
|
||||
extern uint8_t nsapi_error_ok_counter;
|
||||
extern int int_value;
|
||||
|
|
|
@ -19,6 +19,14 @@
|
|||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "CellularUtil_stub.h"
|
||||
|
||||
int CellularUtil_stub::int_value = 0;
|
||||
uint16_t CellularUtil_stub::uint16_value = 0;
|
||||
char *CellularUtil_stub::char_ptr = NULL;
|
||||
int CellularUtil_stub::char_pos = 0;
|
||||
char *CellularUtil_stub::char_table[50] = {};
|
||||
int CellularUtil_stub::table_idx = 0;
|
||||
|
||||
namespace mbed_cellular_util {
|
||||
|
||||
|
@ -39,7 +47,7 @@ void uint_to_binary_str(uint32_t num, char *str, uint8_t str_size, uint8_t bit_c
|
|||
// converts the given str to hex string to buf
|
||||
uint16_t char_str_to_hex(const char *str, uint16_t len, char *buf, bool omit_leading_zero)
|
||||
{
|
||||
return 0;
|
||||
return CellularUtil_stub::uint16_value;
|
||||
}
|
||||
|
||||
void convert_ipv6(char *ip)
|
||||
|
@ -49,15 +57,35 @@ void convert_ipv6(char *ip)
|
|||
|
||||
char *find_dot_number(char *str, int dot_number)
|
||||
{
|
||||
return NULL;
|
||||
return CellularUtil_stub::char_ptr;
|
||||
}
|
||||
|
||||
void separate_ip4like_addresses(char *orig, char *ip, size_t ip_size, char *ip2, size_t ip2_size)
|
||||
{
|
||||
if (CellularUtil_stub::table_idx > 1) {
|
||||
CellularUtil_stub::table_idx--;
|
||||
memcpy(ip, CellularUtil_stub::char_table[CellularUtil_stub::table_idx],
|
||||
strlen(CellularUtil_stub::char_table[CellularUtil_stub::table_idx]));
|
||||
ip[strlen(CellularUtil_stub::char_table[CellularUtil_stub::table_idx])] = '\0';
|
||||
CellularUtil_stub::table_idx--;
|
||||
memcpy(ip2, CellularUtil_stub::char_table[CellularUtil_stub::table_idx],
|
||||
strlen(CellularUtil_stub::char_table[CellularUtil_stub::table_idx]));
|
||||
ip2[strlen(CellularUtil_stub::char_table[CellularUtil_stub::table_idx])] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
void separate_ip_addresses(char *orig, char *ip, size_t ip_size, char *ip2, size_t ip2_size)
|
||||
{
|
||||
if (CellularUtil_stub::table_idx > 1) {
|
||||
CellularUtil_stub::table_idx--;
|
||||
memcpy(ip, CellularUtil_stub::char_table[CellularUtil_stub::table_idx],
|
||||
strlen(CellularUtil_stub::char_table[CellularUtil_stub::table_idx]));
|
||||
ip[strlen(CellularUtil_stub::char_table[CellularUtil_stub::table_idx])] = '\0';
|
||||
CellularUtil_stub::table_idx--;
|
||||
memcpy(ip2, CellularUtil_stub::char_table[CellularUtil_stub::table_idx],
|
||||
strlen(CellularUtil_stub::char_table[CellularUtil_stub::table_idx]));
|
||||
ip2[strlen(CellularUtil_stub::char_table[CellularUtil_stub::table_idx])] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
void prefer_ipv6(char *ip, size_t ip_size, char *ip2, size_t ip2_size)
|
||||
|
@ -72,12 +100,13 @@ void int_to_hex_str(uint8_t num, char *buf)
|
|||
|
||||
int hex_str_to_int(const char *hex_string, int hex_string_length)
|
||||
{
|
||||
return 0;
|
||||
return CellularUtil_stub::int_value;
|
||||
}
|
||||
|
||||
int hex_str_to_char_str(const char *str, uint16_t len, char *buf)
|
||||
{
|
||||
return 0;
|
||||
buf[0] = CellularUtil_stub::char_ptr[CellularUtil_stub::char_pos++];
|
||||
return 1;
|
||||
}
|
||||
|
||||
void uint_to_binary_str(uint32_t num, char *str, int str_size, int bit_cnt)
|
||||
|
@ -87,28 +116,12 @@ void uint_to_binary_str(uint32_t num, char *str, int str_size, int bit_cnt)
|
|||
|
||||
int char_str_to_hex_str(const char *str, uint16_t len, char *buf, bool omit_leading_zero)
|
||||
{
|
||||
//The code is dependent on this, so this is easiest just to put here
|
||||
if (!str || !buf) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *ptr = buf;
|
||||
int i = 0;
|
||||
while (i < len) {
|
||||
if (omit_leading_zero == true && i == 0 && !(str[i] >> 4 & 0x0F)) {
|
||||
*ptr++ = hex_values[(str[i]) & 0x0F];
|
||||
} else {
|
||||
*ptr++ = hex_values[((str[i]) >> 4) & 0x0F];
|
||||
*ptr++ = hex_values[(str[i]) & 0x0F];
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return ptr - buf;
|
||||
return CellularUtil_stub::int_value;
|
||||
}
|
||||
|
||||
uint16_t get_dynamic_ip_port()
|
||||
{
|
||||
return 0;
|
||||
return CellularUtil_stub::uint16_value;
|
||||
}
|
||||
|
||||
} // namespace mbed_cellular_util
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (c) , Arm Limited and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "CellularUtil.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace CellularUtil_stub {
|
||||
extern int int_value;
|
||||
extern uint16_t uint16_value;
|
||||
extern char *char_ptr;
|
||||
extern int char_pos;
|
||||
extern char *char_table[50];
|
||||
extern int table_idx;
|
||||
|
||||
|
||||
} // namespace mbed_cellular_util
|
|
@ -22,3 +22,4 @@ void mbed_assert_internal(const char *expr, const char *file, int line)
|
|||
{
|
||||
fprintf(stderr, "mbed assertation failed: %s, file: %s, line %d \n", expr, file, line);
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
#include "rtos/ThisThread.h"
|
||||
#include "Kernel.h"
|
||||
#include "CellularUtil.h"
|
||||
#include <stdarg.h>
|
||||
#include "SingletonPtr.h"
|
||||
|
||||
using namespace mbed;
|
||||
using namespace events;
|
||||
|
@ -61,6 +63,104 @@ static const uint8_t map_3gpp_errors[][2] = {
|
|||
{ 146, 46 }, { 178, 65 }, { 179, 66 }, { 180, 48 }, { 181, 83 }, { 171, 49 },
|
||||
};
|
||||
|
||||
ATHandler *ATHandler::_atHandlers = NULL;
|
||||
|
||||
// each parser is associated with one filehandle (that is UART)
|
||||
ATHandler *ATHandler::get_instance(FileHandle *fileHandle, events::EventQueue &queue, uint32_t timeout,
|
||||
const char *delimiter, uint16_t send_delay, bool debug_on)
|
||||
{
|
||||
if (!fileHandle) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
singleton_lock();
|
||||
ATHandler *atHandler = _atHandlers;
|
||||
while (atHandler) {
|
||||
if (atHandler->get_file_handle() == fileHandle) {
|
||||
atHandler->inc_ref_count();
|
||||
singleton_unlock();
|
||||
return atHandler;
|
||||
}
|
||||
atHandler = atHandler->_nextATHandler;
|
||||
}
|
||||
|
||||
atHandler = new ATHandler(fileHandle, queue, timeout, delimiter, send_delay);
|
||||
if (debug_on) {
|
||||
atHandler->set_debug(debug_on);
|
||||
}
|
||||
atHandler->_nextATHandler = _atHandlers;
|
||||
_atHandlers = atHandler;
|
||||
|
||||
singleton_unlock();
|
||||
return atHandler;
|
||||
}
|
||||
|
||||
nsapi_error_t ATHandler::close()
|
||||
{
|
||||
if (get_ref_count() == 0) {
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
|
||||
singleton_lock();
|
||||
dec_ref_count();
|
||||
if (get_ref_count() == 0) {
|
||||
// we can delete this at_handler
|
||||
ATHandler *atHandler = _atHandlers;
|
||||
ATHandler *prev = NULL;
|
||||
while (atHandler) {
|
||||
if (atHandler == this) {
|
||||
if (prev == NULL) {
|
||||
_atHandlers = _atHandlers->_nextATHandler;
|
||||
} else {
|
||||
prev->_nextATHandler = atHandler->_nextATHandler;
|
||||
}
|
||||
delete this;
|
||||
break;
|
||||
} else {
|
||||
prev = atHandler;
|
||||
atHandler = atHandler->_nextATHandler;
|
||||
}
|
||||
}
|
||||
}
|
||||
singleton_unlock();
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
void ATHandler::set_at_timeout_list(uint32_t timeout_milliseconds, bool default_timeout)
|
||||
{
|
||||
ATHandler *atHandler = _atHandlers;
|
||||
singleton_lock();
|
||||
while (atHandler) {
|
||||
atHandler->set_at_timeout(timeout_milliseconds, default_timeout);
|
||||
atHandler = atHandler->_nextATHandler;
|
||||
}
|
||||
singleton_unlock();
|
||||
}
|
||||
|
||||
void ATHandler::set_debug_list(bool debug_on)
|
||||
{
|
||||
ATHandler *atHandler = _atHandlers;
|
||||
singleton_lock();
|
||||
while (atHandler) {
|
||||
atHandler->set_debug(debug_on);
|
||||
atHandler = atHandler->_nextATHandler;
|
||||
}
|
||||
singleton_unlock();
|
||||
}
|
||||
|
||||
bool ATHandler::ok_to_proceed()
|
||||
{
|
||||
if (_last_err != NSAPI_ERROR_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_is_fh_usable) {
|
||||
_last_err = NSAPI_ERROR_BUSY;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ATHandler::ATHandler(FileHandle *fh, EventQueue &queue, uint32_t timeout, const char *output_delimiter, uint16_t send_delay) :
|
||||
_nextATHandler(0),
|
||||
_fileHandle(NULL), // filehandle is set by set_file_handle()
|
||||
|
@ -404,12 +504,7 @@ int ATHandler::get_char()
|
|||
|
||||
void ATHandler::skip_param(uint32_t count)
|
||||
{
|
||||
if (_last_err || !_stop_tag || _stop_tag->found) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_is_fh_usable) {
|
||||
_last_err = NSAPI_ERROR_BUSY;
|
||||
if (!ok_to_proceed() || !_stop_tag || _stop_tag->found) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -438,11 +533,7 @@ void ATHandler::skip_param(uint32_t count)
|
|||
|
||||
void ATHandler::skip_param(ssize_t len, uint32_t count)
|
||||
{
|
||||
if (_last_err || !_stop_tag || _stop_tag->found) {
|
||||
return;
|
||||
}
|
||||
if (!_is_fh_usable) {
|
||||
_last_err = NSAPI_ERROR_BUSY;
|
||||
if (!ok_to_proceed() || !_stop_tag || _stop_tag->found) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -462,11 +553,7 @@ void ATHandler::skip_param(ssize_t len, uint32_t count)
|
|||
|
||||
ssize_t ATHandler::read_bytes(uint8_t *buf, size_t len)
|
||||
{
|
||||
if (_last_err) {
|
||||
return -1;
|
||||
}
|
||||
if (!_is_fh_usable) {
|
||||
_last_err = NSAPI_ERROR_BUSY;
|
||||
if (!ok_to_proceed()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -490,11 +577,7 @@ ssize_t ATHandler::read_bytes(uint8_t *buf, size_t len)
|
|||
|
||||
ssize_t ATHandler::read_string(char *buf, size_t size, bool read_even_stop_tag)
|
||||
{
|
||||
if (_last_err || !_stop_tag || (_stop_tag->found && read_even_stop_tag == false)) {
|
||||
return -1;
|
||||
}
|
||||
if (!_is_fh_usable) {
|
||||
_last_err = NSAPI_ERROR_BUSY;
|
||||
if (!ok_to_proceed() || !_stop_tag || (_stop_tag->found && read_even_stop_tag == false)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -560,11 +643,7 @@ ssize_t ATHandler::read_string(char *buf, size_t size, bool read_even_stop_tag)
|
|||
|
||||
ssize_t ATHandler::read_hex_string(char *buf, size_t size)
|
||||
{
|
||||
if (_last_err || !_stop_tag || _stop_tag->found) {
|
||||
return -1;
|
||||
}
|
||||
if (!_is_fh_usable) {
|
||||
_last_err = NSAPI_ERROR_BUSY;
|
||||
if (!ok_to_proceed() || !_stop_tag || _stop_tag->found) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -636,11 +715,7 @@ ssize_t ATHandler::read_hex_string(char *buf, size_t size)
|
|||
|
||||
int32_t ATHandler::read_int()
|
||||
{
|
||||
if (_last_err || !_stop_tag || _stop_tag->found) {
|
||||
return -1;
|
||||
}
|
||||
if (!_is_fh_usable) {
|
||||
_last_err = NSAPI_ERROR_BUSY;
|
||||
if (!ok_to_proceed() || !_stop_tag || _stop_tag->found) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -671,7 +746,8 @@ void ATHandler::set_tag(tag_t *tag_dst, const char *tag_seq)
|
|||
{
|
||||
if (tag_seq) {
|
||||
size_t tag_len = strlen(tag_seq);
|
||||
set_string(tag_dst->tag, tag_seq, tag_len);
|
||||
memcpy(tag_dst->tag, tag_seq, tag_len);
|
||||
tag_dst->tag[tag_len] = '\0';
|
||||
tag_dst->len = tag_len;
|
||||
tag_dst->found = false;
|
||||
} else {
|
||||
|
@ -899,11 +975,7 @@ void ATHandler::resp(const char *prefix, bool check_urc)
|
|||
|
||||
void ATHandler::resp_start(const char *prefix, bool stop)
|
||||
{
|
||||
if (_last_err) {
|
||||
return;
|
||||
}
|
||||
if (!_is_fh_usable) {
|
||||
_last_err = NSAPI_ERROR_BUSY;
|
||||
if (!ok_to_proceed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -929,11 +1001,7 @@ void ATHandler::resp_start(const char *prefix, bool stop)
|
|||
// check urc because of error as urc
|
||||
bool ATHandler::info_resp()
|
||||
{
|
||||
if (_last_err || _resp_stop.found) {
|
||||
return false;
|
||||
}
|
||||
if (!_is_fh_usable) {
|
||||
_last_err = NSAPI_ERROR_BUSY;
|
||||
if (!ok_to_proceed() || _resp_stop.found) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -963,11 +1031,7 @@ bool ATHandler::info_resp()
|
|||
|
||||
bool ATHandler::info_elem(char start_tag)
|
||||
{
|
||||
if (_last_err) {
|
||||
return false;
|
||||
}
|
||||
if (!_is_fh_usable) {
|
||||
_last_err = NSAPI_ERROR_BUSY;
|
||||
if (!ok_to_proceed()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1132,12 +1196,6 @@ ATHandler::ScopeType ATHandler::get_scope()
|
|||
return _current_scope;
|
||||
}
|
||||
|
||||
void ATHandler::set_string(char *dest, const char *src, size_t src_len)
|
||||
{
|
||||
memcpy(dest, src, src_len);
|
||||
dest[src_len] = '\0';
|
||||
}
|
||||
|
||||
const char *ATHandler::mem_str(const char *dest, size_t dest_len, const char *src, size_t src_len)
|
||||
{
|
||||
if (dest_len >= src_len) {
|
||||
|
@ -1152,11 +1210,7 @@ const char *ATHandler::mem_str(const char *dest, size_t dest_len, const char *sr
|
|||
|
||||
void ATHandler::cmd_start(const char *cmd)
|
||||
{
|
||||
if (_last_err != NSAPI_ERROR_OK) {
|
||||
return;
|
||||
}
|
||||
if (!_is_fh_usable) {
|
||||
_last_err = NSAPI_ERROR_BUSY;
|
||||
if (!ok_to_proceed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1169,6 +1223,127 @@ void ATHandler::cmd_start(const char *cmd)
|
|||
_cmd_start = true;
|
||||
}
|
||||
|
||||
void ATHandler::handle_args(const char *format, va_list list)
|
||||
{
|
||||
while (*format != '\0') {
|
||||
if (*format == 'd') {
|
||||
int i = va_arg(list, int);
|
||||
write_int(i);
|
||||
} else if (*format == 's') {
|
||||
char *str = (char *)va_arg(list, char *);
|
||||
write_string(str);
|
||||
} else if (*format == 'b') {
|
||||
uint8_t *bytes = va_arg(list, uint8_t *);
|
||||
int size = va_arg(list, int);
|
||||
write_bytes(bytes, size);
|
||||
}
|
||||
++format;
|
||||
}
|
||||
}
|
||||
|
||||
void ATHandler::handle_start(const char *cmd, const char *cmd_chr)
|
||||
{
|
||||
int len = 0;
|
||||
memcpy(_cmd_buffer, "AT", 2);
|
||||
len += 2;
|
||||
int cmd_char_len = 0;
|
||||
if (cmd_chr) {
|
||||
cmd_char_len = strlen(cmd_chr);
|
||||
}
|
||||
MBED_ASSERT((3 + strlen(cmd) + cmd_char_len) < BUFF_SIZE);
|
||||
|
||||
memcpy(_cmd_buffer + len, cmd, strlen(cmd));
|
||||
len += strlen(cmd);
|
||||
|
||||
if (cmd_char_len) {
|
||||
memcpy(_cmd_buffer + len, cmd_chr, cmd_char_len);
|
||||
len += cmd_char_len;
|
||||
}
|
||||
_cmd_buffer[len] = '\0';
|
||||
|
||||
const bool temp_state = get_debug();
|
||||
set_debug(true);
|
||||
|
||||
cmd_start(_cmd_buffer);
|
||||
|
||||
set_debug(temp_state);
|
||||
}
|
||||
|
||||
void ATHandler::cmd_start_stop(const char *cmd, const char *cmd_chr, const char *format, ...)
|
||||
{
|
||||
handle_start(cmd, cmd_chr);
|
||||
|
||||
va_list list;
|
||||
va_start(list, format);
|
||||
handle_args(format, list);
|
||||
va_end(list);
|
||||
|
||||
cmd_stop();
|
||||
}
|
||||
|
||||
nsapi_error_t ATHandler::at_cmd_str(const char *cmd, const char *cmd_chr, char *resp_buf, size_t buf_size, const char *format, ...)
|
||||
{
|
||||
lock();
|
||||
|
||||
handle_start(cmd, cmd_chr);
|
||||
|
||||
va_list list;
|
||||
va_start(list, format);
|
||||
handle_args(format, list);
|
||||
va_end(list);
|
||||
|
||||
cmd_stop();
|
||||
|
||||
memcpy(_cmd_buffer, cmd, strlen(cmd));
|
||||
_cmd_buffer[strlen(cmd)] = ':';
|
||||
_cmd_buffer[strlen(cmd) + 1] = '\0';
|
||||
resp_start(_cmd_buffer);
|
||||
|
||||
resp_buf[0] = '\0';
|
||||
read_string(resp_buf, buf_size);
|
||||
resp_stop();
|
||||
return unlock_return_error();
|
||||
}
|
||||
|
||||
nsapi_error_t ATHandler::at_cmd_int(const char *cmd, const char *cmd_chr, int &resp, const char *format, ...)
|
||||
{
|
||||
lock();
|
||||
|
||||
handle_start(cmd, cmd_chr);
|
||||
|
||||
va_list list;
|
||||
va_start(list, format);
|
||||
handle_args(format, list);
|
||||
va_end(list);
|
||||
|
||||
cmd_stop();
|
||||
char temp[16];
|
||||
size_t len = strlen(cmd);
|
||||
memcpy(temp, cmd, len);
|
||||
temp[len] = ':';
|
||||
temp[len + 1] = '\0';
|
||||
resp_start(temp);
|
||||
|
||||
resp = read_int();
|
||||
resp_stop();
|
||||
return unlock_return_error();
|
||||
}
|
||||
|
||||
nsapi_error_t ATHandler::at_cmd_discard(const char *cmd, const char *cmd_chr, const char *format, ...)
|
||||
{
|
||||
lock();
|
||||
|
||||
handle_start(cmd, cmd_chr);
|
||||
|
||||
va_list list;
|
||||
va_start(list, format);
|
||||
handle_args(format, list);
|
||||
va_end(list);
|
||||
|
||||
cmd_stop_read_resp();
|
||||
return unlock_return_error();
|
||||
}
|
||||
|
||||
void ATHandler::write_int(int32_t param)
|
||||
{
|
||||
// do common checks before sending subparameter
|
||||
|
@ -1207,11 +1382,7 @@ void ATHandler::write_string(const char *param, bool useQuotations)
|
|||
|
||||
void ATHandler::cmd_stop()
|
||||
{
|
||||
if (_last_err != NSAPI_ERROR_OK) {
|
||||
return;
|
||||
}
|
||||
if (!_is_fh_usable) {
|
||||
_last_err = NSAPI_ERROR_BUSY;
|
||||
if (!ok_to_proceed()) {
|
||||
return;
|
||||
}
|
||||
// Finish with CR
|
||||
|
@ -1227,11 +1398,7 @@ void ATHandler::cmd_stop_read_resp()
|
|||
|
||||
size_t ATHandler::write_bytes(const uint8_t *data, size_t len)
|
||||
{
|
||||
if (_last_err != NSAPI_ERROR_OK) {
|
||||
return 0;
|
||||
}
|
||||
if (!_is_fh_usable) {
|
||||
_last_err = NSAPI_ERROR_BUSY;
|
||||
if (!ok_to_proceed()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1275,25 +1442,18 @@ size_t ATHandler::write(const void *data, size_t len)
|
|||
// do common checks before sending subparameters
|
||||
bool ATHandler::check_cmd_send()
|
||||
{
|
||||
if (_last_err != NSAPI_ERROR_OK) {
|
||||
if (!ok_to_proceed()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_is_fh_usable) {
|
||||
_last_err = NSAPI_ERROR_BUSY;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't write delimiter if flag was set so
|
||||
if (!_use_delimiter) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Don't write delimiter if this is the first subparameter
|
||||
if (_cmd_start) {
|
||||
_cmd_start = false;
|
||||
} else {
|
||||
if (write(&_delimiter, 1) != 1) {
|
||||
if (_use_delimiter && write(&_delimiter, 1) != 1) {
|
||||
// writing of delimiter failed, return. write() already have set the _last_err
|
||||
return false;
|
||||
}
|
||||
|
@ -1374,10 +1534,7 @@ bool ATHandler::sync(int timeout_ms)
|
|||
// especially a common response like OK could be response to previous request.
|
||||
clear_error();
|
||||
_start_time = rtos::Kernel::get_ms_count();
|
||||
cmd_start("AT+CMEE?");
|
||||
cmd_stop();
|
||||
resp_start("+CMEE:");
|
||||
resp_stop();
|
||||
at_cmd_discard("+CMEE", "?");
|
||||
if (!_last_err) {
|
||||
_at_timeout = timeout;
|
||||
unlock();
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include "PlatformMutex.h"
|
||||
#include "Callback.h"
|
||||
#include <cstdarg>
|
||||
|
||||
namespace mbed {
|
||||
|
||||
|
@ -260,6 +261,53 @@ public:
|
|||
*/
|
||||
virtual void cmd_start(const char *cmd);
|
||||
|
||||
/**
|
||||
* @brief cmd_start_stop Starts an AT command, writes given variadic arguments and stops the command. Use this
|
||||
* command when you need multiple response parameters to be handled.
|
||||
* NOTE: Does not lock ATHandler for process!
|
||||
*
|
||||
* @param cmd AT command in form +<CMD> (will be used also in response reading, no extra chars allowed)
|
||||
* @param cmd_chr Char to be added to specific AT command: '?', '=' or ''. Will be used as such so '=1' is valid as well.
|
||||
* @param format Format string for variadic arguments to be added to AT command; No separator needed.
|
||||
* Use %d for integer, %s for string and %b for byte string (requires 2 arguments: string and length)
|
||||
*/
|
||||
void cmd_start_stop(const char *cmd, const char *cmd_chr, const char *format = "", ...);
|
||||
|
||||
/**
|
||||
* @brief at_cmd_str Send an AT command and read a single string response. Locks and unlocks ATHandler for operation
|
||||
* @param cmd AT command in form +<CMD> (will be used also in response reading, no extra chars allowed)
|
||||
* @param cmd_chr Char to be added to specific AT command: '?', '=' or ''. Will be used as such so '=1' is valid as well.
|
||||
* @param resp_buf Response buffer
|
||||
* @param resp_buf_size Response buffer size
|
||||
* @param format Format string for variadic arguments to be added to AT command; No separator needed.
|
||||
* Use %d for integer, %s for string and %b for byte string (requires 2 arguments: string and length)
|
||||
* @return last error that happened when parsing AT responses
|
||||
*/
|
||||
nsapi_error_t at_cmd_str(const char *cmd, const char *cmd_chr, char *resp_buf, size_t resp_buf_size, const char *format = "", ...);
|
||||
|
||||
/**
|
||||
* @brief at_cmd_int Send an AT command and read a single integer response. Locks and unlocks ATHandler for operation
|
||||
* @param cmd AT command in form +<CMD> (will be used also in response reading, no extra chars allowed)
|
||||
* @param cmd_chr Char to be added to specific AT command: '?', '=' or ''. Will be used as such so '=1' is valid as well.
|
||||
* @param resp Integer to hold response
|
||||
* @param format Format string for variadic arguments to be added to AT command; No separator needed.
|
||||
* Use %d for integer, %s for string and %b for byte string (requires 2 arguments: string and length)
|
||||
* @return last error that happened when parsing AT responses
|
||||
*/
|
||||
nsapi_error_t at_cmd_int(const char *cmd, const char *cmd_chr, int &resp, const char *format = "", ...);
|
||||
|
||||
/**
|
||||
* @brief at_cmd_discard Send an AT command and read and discard a response. Locks and unlocks ATHandler for operation
|
||||
* @param cmd AT command in form +<CMD> (will be used also in response reading, no extra chars allowed)
|
||||
* @param cmd_chr Char to be added to specific AT command: '?', '=' or ''. Will be used as such so '=1' is valid as well.
|
||||
* @param format Format string for variadic arguments to be added to AT command; No separator needed.
|
||||
* Use %d for integer, %s for string and %b for byte string (requires 2 arguments: string and length)
|
||||
* @return last error that happened when parsing AT responses
|
||||
*/
|
||||
nsapi_error_t at_cmd_discard(const char *cmd, const char *cmd_chr, const char *format = "", ...);
|
||||
|
||||
public:
|
||||
|
||||
/** Writes integer type AT command subparameter. Starts with the delimiter if not the first param after cmd_start.
|
||||
* In case of failure when writing, the last error is set to NSAPI_ERROR_DEVICE_ERROR.
|
||||
*
|
||||
|
@ -497,6 +545,19 @@ private:
|
|||
// time when a command or an URC processing was started
|
||||
uint64_t _start_time;
|
||||
|
||||
char _cmd_buffer[BUFF_SIZE];
|
||||
|
||||
private:
|
||||
//Handles the arguments from given variadic list
|
||||
void handle_args(const char *format, va_list list);
|
||||
|
||||
//Starts an AT command based on given parameters
|
||||
void handle_start(const char *cmd, const char *cmd_chr);
|
||||
|
||||
//Checks that ATHandler does not have a pending error condition and filehandle is usable
|
||||
bool ok_to_proceed();
|
||||
|
||||
private:
|
||||
// Gets char from receiving buffer.
|
||||
// Resets and fills the buffer if all are already read (receiving position equals receiving length).
|
||||
// Returns a next char or -1 on failure (also sets error flag)
|
||||
|
@ -551,15 +612,6 @@ private:
|
|||
bool check_cmd_send();
|
||||
size_t write(const void *data, size_t len);
|
||||
|
||||
/** Copy content of one char buffer to another buffer and sets NULL terminator
|
||||
*
|
||||
* @param dest destination char buffer
|
||||
* @param src source char buffer
|
||||
* @param src_len number of bytes to copy
|
||||
*
|
||||
*/
|
||||
void set_string(char *dest, const char *src, size_t src_len);
|
||||
|
||||
/** Finds occurrence of one char buffer inside another char buffer.
|
||||
*
|
||||
* @param dest destination char buffer
|
||||
|
|
|
@ -1,106 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018, Arm Limited and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ATHandler.h"
|
||||
#include "SingletonPtr.h"
|
||||
|
||||
using namespace mbed;
|
||||
|
||||
ATHandler *ATHandler::_atHandlers = NULL;
|
||||
|
||||
// each parser is associated with one filehandle (that is UART)
|
||||
ATHandler *ATHandler::get_instance(FileHandle *fileHandle, events::EventQueue &queue, uint32_t timeout,
|
||||
const char *delimiter, uint16_t send_delay, bool debug_on)
|
||||
{
|
||||
if (!fileHandle) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
singleton_lock();
|
||||
ATHandler *atHandler = _atHandlers;
|
||||
while (atHandler) {
|
||||
if (atHandler->get_file_handle() == fileHandle) {
|
||||
atHandler->inc_ref_count();
|
||||
singleton_unlock();
|
||||
return atHandler;
|
||||
}
|
||||
atHandler = atHandler->_nextATHandler;
|
||||
}
|
||||
|
||||
atHandler = new ATHandler(fileHandle, queue, timeout, delimiter, send_delay);
|
||||
if (debug_on) {
|
||||
atHandler->set_debug(debug_on);
|
||||
}
|
||||
atHandler->_nextATHandler = _atHandlers;
|
||||
_atHandlers = atHandler;
|
||||
|
||||
singleton_unlock();
|
||||
return atHandler;
|
||||
}
|
||||
|
||||
nsapi_error_t ATHandler::close()
|
||||
{
|
||||
if (get_ref_count() == 0) {
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
|
||||
singleton_lock();
|
||||
dec_ref_count();
|
||||
if (get_ref_count() == 0) {
|
||||
// we can delete this at_handler
|
||||
ATHandler *atHandler = _atHandlers;
|
||||
ATHandler *prev = NULL;
|
||||
while (atHandler) {
|
||||
if (atHandler == this) {
|
||||
if (prev == NULL) {
|
||||
_atHandlers = _atHandlers->_nextATHandler;
|
||||
} else {
|
||||
prev->_nextATHandler = atHandler->_nextATHandler;
|
||||
}
|
||||
delete this;
|
||||
break;
|
||||
} else {
|
||||
prev = atHandler;
|
||||
atHandler = atHandler->_nextATHandler;
|
||||
}
|
||||
}
|
||||
}
|
||||
singleton_unlock();
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
void ATHandler::set_at_timeout_list(uint32_t timeout_milliseconds, bool default_timeout)
|
||||
{
|
||||
ATHandler *atHandler = _atHandlers;
|
||||
singleton_lock();
|
||||
while (atHandler) {
|
||||
atHandler->set_at_timeout(timeout_milliseconds, default_timeout);
|
||||
atHandler = atHandler->_nextATHandler;
|
||||
}
|
||||
singleton_unlock();
|
||||
}
|
||||
|
||||
void ATHandler::set_debug_list(bool debug_on)
|
||||
{
|
||||
ATHandler *atHandler = _atHandlers;
|
||||
singleton_lock();
|
||||
while (atHandler) {
|
||||
atHandler->set_debug(debug_on);
|
||||
atHandler = atHandler->_nextATHandler;
|
||||
}
|
||||
singleton_unlock();
|
||||
}
|
|
@ -302,9 +302,8 @@ nsapi_error_t AT_CellularContext::delete_current_context()
|
|||
{
|
||||
tr_info("Delete context %d", _cid);
|
||||
_at.clear_error();
|
||||
_at.cmd_start("AT+CGDCONT=");
|
||||
_at.write_int(_cid);
|
||||
_at.cmd_stop_read_resp();
|
||||
|
||||
_at.at_cmd_discard("+CGDCONT", "=", "%d", _cid);
|
||||
|
||||
if (_at.get_last_error() == NSAPI_ERROR_OK) {
|
||||
_cid = -1;
|
||||
|
@ -321,19 +320,13 @@ nsapi_error_t AT_CellularContext::do_user_authentication()
|
|||
if (!get_property(PROPERTY_AT_CGAUTH)) {
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
_at.cmd_start("AT+CGAUTH=");
|
||||
_at.write_int(_cid);
|
||||
_at.write_int(_authentication_type);
|
||||
|
||||
const bool stored_debug_state = _at.get_debug();
|
||||
_at.set_debug(false);
|
||||
|
||||
_at.write_string(_uname);
|
||||
_at.write_string(_pwd);
|
||||
_at.at_cmd_discard("+CGAUTH", "=", "%d%d%s%s", _cid, _authentication_type, _uname, _pwd);
|
||||
|
||||
_at.set_debug(stored_debug_state);
|
||||
|
||||
_at.cmd_stop_read_resp();
|
||||
if (_at.get_last_error() != NSAPI_ERROR_OK) {
|
||||
return NSAPI_ERROR_AUTH_FAILURE;
|
||||
}
|
||||
|
@ -360,8 +353,8 @@ bool AT_CellularContext::get_context()
|
|||
{
|
||||
bool modem_supports_ipv6 = get_property(PROPERTY_IPV6_PDP_TYPE);
|
||||
bool modem_supports_ipv4 = get_property(PROPERTY_IPV4_PDP_TYPE);
|
||||
_at.cmd_start("AT+CGDCONT?");
|
||||
_at.cmd_stop();
|
||||
|
||||
_at.cmd_start_stop("+CGDCONT", "?");
|
||||
_at.resp_start("+CGDCONT:");
|
||||
_cid = -1;
|
||||
int cid_max = 0; // needed when creating new context
|
||||
|
@ -438,13 +431,8 @@ bool AT_CellularContext::set_new_context(int cid)
|
|||
}
|
||||
|
||||
//apn: "If the value is null or omitted, then the subscription value will be requested."
|
||||
bool success = false;
|
||||
_at.cmd_start("AT+CGDCONT=");
|
||||
_at.write_int(cid);
|
||||
_at.write_string(pdp_type_str);
|
||||
_at.write_string(_apn);
|
||||
_at.cmd_stop_read_resp();
|
||||
success = (_at.get_last_error() == NSAPI_ERROR_OK);
|
||||
|
||||
bool success = (_at.at_cmd_discard("+CGDCONT", "=", "%d%s%s", cid, pdp_type_str, _apn) == NSAPI_ERROR_OK);
|
||||
|
||||
if (success) {
|
||||
_pdp_type = pdp_type;
|
||||
|
@ -481,9 +469,7 @@ nsapi_error_t AT_CellularContext::activate_non_ip_context()
|
|||
void AT_CellularContext::activate_context()
|
||||
{
|
||||
tr_info("Activate PDP context %d", _cid);
|
||||
_at.cmd_start("AT+CGACT=1,");
|
||||
_at.write_int(_cid);
|
||||
_at.cmd_stop_read_resp();
|
||||
_at.at_cmd_discard("+CGACT", "=1,", "%d", _cid);
|
||||
if (_at.get_last_error() == NSAPI_ERROR_OK) {
|
||||
_is_context_activated = true;
|
||||
}
|
||||
|
@ -590,8 +576,7 @@ nsapi_error_t AT_CellularContext::open_data_channel()
|
|||
|
||||
tr_info("CellularContext PPP connect");
|
||||
if (get_property(PROPERTY_AT_CGDATA)) {
|
||||
_at.cmd_start("AT+CGDATA=\"PPP\",");
|
||||
_at.write_int(_cid);
|
||||
_at.cmd_start_stop("+CGDATA", "=\"PPP\",", "%d", _cid);
|
||||
} else {
|
||||
MBED_ASSERT(_cid >= 0 && _cid <= 99);
|
||||
_at.cmd_start("ATD*99***");
|
||||
|
@ -599,8 +584,8 @@ nsapi_error_t AT_CellularContext::open_data_channel()
|
|||
_at.write_int(_cid);
|
||||
_at.write_string("#", false);
|
||||
_at.use_delimiter(true);
|
||||
_at.cmd_stop();
|
||||
}
|
||||
_at.cmd_stop();
|
||||
|
||||
_at.resp_start("CONNECT", true);
|
||||
if (_at.get_last_error()) {
|
||||
|
@ -733,9 +718,7 @@ void AT_CellularContext::deactivate_non_ip_context()
|
|||
|
||||
void AT_CellularContext::deactivate_context()
|
||||
{
|
||||
_at.cmd_start("AT+CGACT=0,");
|
||||
_at.write_int(_cid);
|
||||
_at.cmd_stop_read_resp();
|
||||
_at.at_cmd_discard("+CGACT", "=0,", "%d", _cid);
|
||||
}
|
||||
|
||||
void AT_CellularContext::check_and_deactivate_context()
|
||||
|
@ -759,9 +742,7 @@ void AT_CellularContext::check_and_deactivate_context()
|
|||
|
||||
if (_new_context_set) {
|
||||
_at.clear_error();
|
||||
_at.cmd_start("AT+CGDCONT=");
|
||||
_at.write_int(_cid);
|
||||
_at.cmd_stop_read_resp();
|
||||
_at.at_cmd_discard("+CGDCONT", "=", "%d", _cid);
|
||||
}
|
||||
|
||||
_at.restore_at_timeout();
|
||||
|
@ -772,9 +753,7 @@ nsapi_error_t AT_CellularContext::get_apn_backoff_timer(int &backoff_timer)
|
|||
// If apn is set
|
||||
if (_apn) {
|
||||
_at.lock();
|
||||
_at.cmd_start("AT+CABTRDP=");
|
||||
_at.write_string(_apn);
|
||||
_at.cmd_stop();
|
||||
_at.cmd_start_stop("+CABTRDP", "=", "%s", _apn);
|
||||
_at.resp_start("+CABTRDP:");
|
||||
if (_at.info_resp()) {
|
||||
_at.skip_param();
|
||||
|
@ -792,10 +771,7 @@ nsapi_error_t AT_CellularContext::get_rate_control(
|
|||
CellularContext::RateControlUplinkTimeUnit &timeUnit, int &uplinkRate)
|
||||
{
|
||||
_at.lock();
|
||||
|
||||
_at.cmd_start("AT+CGAPNRC=");
|
||||
_at.write_int(_cid);
|
||||
_at.cmd_stop();
|
||||
_at.cmd_start_stop("+CGAPNRC", "=", "%d", _cid);
|
||||
|
||||
_at.resp_start("+CGAPNRC:");
|
||||
_at.read_int();
|
||||
|
@ -837,9 +813,7 @@ nsapi_error_t AT_CellularContext::get_pdpcontext_params(pdpContextList_t ¶ms
|
|||
|
||||
_at.lock();
|
||||
|
||||
_at.cmd_start("AT+CGCONTRDP=");
|
||||
_at.write_int(_cid);
|
||||
_at.cmd_stop();
|
||||
_at.cmd_start_stop("+CGCONTRDP", "=", "%d", _cid);
|
||||
|
||||
_at.resp_start("+CGCONTRDP:");
|
||||
pdpcontext_params_t *params = NULL;
|
||||
|
|
|
@ -184,10 +184,10 @@ nsapi_error_t AT_CellularDevice::get_sim_state(SimState &state)
|
|||
char simstr[MAX_SIM_RESPONSE_LENGTH];
|
||||
_at->lock();
|
||||
_at->flush();
|
||||
_at->cmd_start("AT+CPIN?");
|
||||
_at->cmd_stop();
|
||||
_at->resp_start("+CPIN:");
|
||||
ssize_t len = _at->read_string(simstr, sizeof(simstr));
|
||||
nsapi_error_t error = _at->at_cmd_str("+CPIN", "?", simstr, sizeof(simstr));
|
||||
ssize_t len = strlen(simstr);
|
||||
_at->unlock();
|
||||
|
||||
if (len != -1) {
|
||||
if (len >= 5 && memcmp(simstr, "READY", 5) == 0) {
|
||||
state = SimStateReady;
|
||||
|
@ -204,9 +204,6 @@ nsapi_error_t AT_CellularDevice::get_sim_state(SimState &state)
|
|||
tr_warn("SIM not readable.");
|
||||
state = SimStateUnknown; // SIM may not be ready yet or +CPIN may be unsupported command
|
||||
}
|
||||
_at->resp_stop();
|
||||
nsapi_error_t error = _at->get_last_error();
|
||||
_at->unlock();
|
||||
#if MBED_CONF_MBED_TRACE_ENABLE
|
||||
switch (state) {
|
||||
case SimStatePinNeeded:
|
||||
|
@ -230,7 +227,7 @@ nsapi_error_t AT_CellularDevice::set_pin(const char *sim_pin)
|
|||
{
|
||||
// if SIM is already in ready state then settings the PIN
|
||||
// will return error so let's check the state before settings the pin.
|
||||
SimState state;
|
||||
SimState state = SimStateUnknown;
|
||||
if (get_sim_state(state) == NSAPI_ERROR_OK && state == SimStateReady) {
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
@ -240,16 +237,14 @@ nsapi_error_t AT_CellularDevice::set_pin(const char *sim_pin)
|
|||
}
|
||||
|
||||
_at->lock();
|
||||
_at->cmd_start("AT+CPIN=");
|
||||
|
||||
const bool stored_debug_state = _at->get_debug();
|
||||
_at->set_debug(false);
|
||||
|
||||
_at->write_string(sim_pin);
|
||||
_at->at_cmd_discard("+CPIN", "=,", "%s", sim_pin);
|
||||
|
||||
_at->set_debug(stored_debug_state);
|
||||
|
||||
_at->cmd_stop_read_resp();
|
||||
return _at->unlock_return_error();
|
||||
}
|
||||
|
||||
|
@ -431,41 +426,34 @@ nsapi_error_t AT_CellularDevice::init()
|
|||
{
|
||||
_at->lock();
|
||||
_at->flush();
|
||||
_at->cmd_start("ATE0"); // echo off
|
||||
_at->cmd_stop_read_resp();
|
||||
_at->at_cmd_discard("E0", "");
|
||||
|
||||
_at->cmd_start("AT+CMEE=1"); // verbose responses
|
||||
_at->cmd_stop_read_resp();
|
||||
_at->at_cmd_discard("+CMEE", "=1");
|
||||
|
||||
_at->cmd_start("AT+CFUN=1"); // set full functionality
|
||||
_at->cmd_stop_read_resp();
|
||||
_at->at_cmd_discard("+CFUN", "=1");
|
||||
|
||||
return _at->unlock_return_error();
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularDevice::shutdown()
|
||||
{
|
||||
_at->lock();
|
||||
if (_state_machine) {
|
||||
_state_machine->reset();
|
||||
}
|
||||
CellularDevice::shutdown();
|
||||
_at->cmd_start("AT+CFUN=0");// set to minimum functionality
|
||||
_at->cmd_stop_read_resp();
|
||||
return _at->unlock_return_error();
|
||||
|
||||
return _at->at_cmd_discard("+CFUN", "=0");
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularDevice::is_ready()
|
||||
{
|
||||
_at->lock();
|
||||
_at->cmd_start("AT");
|
||||
_at->cmd_stop_read_resp();
|
||||
_at->at_cmd_discard("", "");
|
||||
|
||||
// we need to do this twice because for example after data mode the first 'AT' command will give modem a
|
||||
// stimulus that we are back to command mode.
|
||||
_at->clear_error();
|
||||
_at->cmd_start("AT");
|
||||
_at->cmd_stop_read_resp();
|
||||
_at->at_cmd_discard("", "");
|
||||
|
||||
return _at->unlock_return_error();
|
||||
}
|
||||
|
@ -480,9 +468,7 @@ nsapi_error_t AT_CellularDevice::set_power_save_mode(int periodic_time, int acti
|
|||
|
||||
if (periodic_time == 0 && active_time == 0) {
|
||||
// disable PSM
|
||||
_at->cmd_start("AT+CPSMS=");
|
||||
_at->write_int(0);
|
||||
_at->cmd_stop_read_resp();
|
||||
_at->at_cmd_discard("+CPSMS", "=0");
|
||||
} else {
|
||||
const int PSMTimerBits = 5;
|
||||
|
||||
|
@ -583,13 +569,8 @@ nsapi_error_t AT_CellularDevice::set_power_save_mode(int periodic_time, int acti
|
|||
at[8] = '\0';
|
||||
|
||||
// request for both GPRS and LTE
|
||||
_at->cmd_start("AT+CPSMS=");
|
||||
_at->write_int(1);
|
||||
_at->write_string(pt);
|
||||
_at->write_string(at);
|
||||
_at->write_string(pt);
|
||||
_at->write_string(at);
|
||||
_at->cmd_stop_read_resp();
|
||||
|
||||
_at->at_cmd_discard("+CPSMS", "=1,", "%s%s%s%s", pt, at, pt, at);
|
||||
|
||||
if (_at->get_last_error() != NSAPI_ERROR_OK) {
|
||||
tr_warn("Power save mode not enabled!");
|
||||
|
|
|
@ -58,14 +58,7 @@ nsapi_error_t AT_CellularInformation::get_serial_number(char *buf, size_t buf_si
|
|||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
_at.lock();
|
||||
_at.cmd_start("AT+CGSN=");
|
||||
_at.write_int(type);
|
||||
_at.cmd_stop();
|
||||
_at.resp_start("+CGSN:");
|
||||
_at.read_string(buf, buf_size);
|
||||
_at.resp_stop();
|
||||
return _at.unlock_return_error();
|
||||
return _at.at_cmd_str("+CGSN", "=", buf, buf_size, "%d", type);
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularInformation::get_info(const char *cmd, char *buf, size_t buf_size)
|
||||
|
@ -103,11 +96,5 @@ nsapi_error_t AT_CellularInformation::get_iccid(char *buf, size_t buf_size)
|
|||
if (buf == NULL || buf_size == 0) {
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
_at.lock();
|
||||
_at.cmd_start("AT+CCID?");
|
||||
_at.cmd_stop();
|
||||
_at.resp_start("+CCID:");
|
||||
_at.read_string(buf, buf_size);
|
||||
_at.resp_stop();
|
||||
return _at.unlock_return_error();
|
||||
return _at.at_cmd_str("+CCID", "?", buf, buf_size);
|
||||
}
|
||||
|
|
|
@ -32,9 +32,9 @@ struct at_reg_t {
|
|||
};
|
||||
|
||||
static const at_reg_t at_reg[] = {
|
||||
{ CellularNetwork::C_EREG, "AT+CEREG", "+CEREG:"},
|
||||
{ CellularNetwork::C_GREG, "AT+CGREG", "+CGREG:"},
|
||||
{ CellularNetwork::C_REG, "AT+CREG", "+CREG:"}
|
||||
{ CellularNetwork::C_EREG, "+CEREG", "+CEREG:"},
|
||||
{ CellularNetwork::C_GREG, "+CGREG", "+CGREG:"},
|
||||
{ CellularNetwork::C_REG, "+CREG", "+CREG:"}
|
||||
};
|
||||
|
||||
#if MBED_CONF_MBED_TRACE_ENABLE
|
||||
|
@ -189,61 +189,42 @@ nsapi_error_t AT_CellularNetwork::set_registration_urc(RegistrationType type, bo
|
|||
if (mode == RegistrationModeDisable) {
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
} else {
|
||||
_at.lock();
|
||||
if (urc_on) {
|
||||
_at.cmd_start(at_reg[index].cmd);
|
||||
const uint8_t ch_eq = '=';
|
||||
_at.write_bytes(&ch_eq, 1);
|
||||
_at.write_int((int)mode);
|
||||
return _at.at_cmd_discard(at_reg[index].cmd, "=", "%d", mode);
|
||||
} else {
|
||||
_at.cmd_start(at_reg[index].cmd);
|
||||
_at.write_string("=0", false);
|
||||
return _at.at_cmd_discard(at_reg[index].cmd, "=0");
|
||||
}
|
||||
|
||||
_at.cmd_stop_read_resp();
|
||||
return _at.unlock_return_error();
|
||||
}
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::get_network_registering_mode(NWRegisteringMode &mode)
|
||||
{
|
||||
_at.lock();
|
||||
_at.cmd_start("AT+COPS?");
|
||||
_at.cmd_stop();
|
||||
_at.resp_start("+COPS:");
|
||||
mode = (NWRegisteringMode)_at.read_int();
|
||||
_at.resp_stop();
|
||||
|
||||
return _at.unlock_return_error();
|
||||
int ret;
|
||||
nsapi_error_t error = _at.at_cmd_int("+COPS", "?", ret);
|
||||
mode = (NWRegisteringMode)ret;
|
||||
return error;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::set_registration(const char *plmn)
|
||||
{
|
||||
_at.lock();
|
||||
|
||||
if (!plmn) {
|
||||
tr_debug("Automatic network registration");
|
||||
_at.cmd_start("AT+COPS?");
|
||||
_at.cmd_stop();
|
||||
_at.resp_start("+COPS:");
|
||||
int mode = _at.read_int();
|
||||
_at.resp_stop();
|
||||
if (mode != 0) {
|
||||
_at.clear_error();
|
||||
_at.cmd_start("AT+COPS=0");
|
||||
_at.cmd_stop_read_resp();
|
||||
NWRegisteringMode mode;
|
||||
get_network_registering_mode(mode);
|
||||
|
||||
if (mode != NWModeAutomatic) {
|
||||
return _at.at_cmd_discard("+COPS", "=0");
|
||||
}
|
||||
return NSAPI_ERROR_OK;
|
||||
} else {
|
||||
tr_debug("Manual network registration to %s", plmn);
|
||||
_at.cmd_start("AT+COPS=1,2,");
|
||||
_at.write_string(plmn);
|
||||
if (_op_act != RAT_UNKNOWN) {
|
||||
_at.write_int(_op_act);
|
||||
return _at.at_cmd_discard("+COPS", "=1,2,", "%s%d", plmn, _op_act);
|
||||
} else {
|
||||
return _at.at_cmd_discard("+COPS", "=1,2", "%s", plmn);
|
||||
}
|
||||
_at.cmd_stop_read_resp();
|
||||
}
|
||||
|
||||
return _at.unlock_return_error();
|
||||
}
|
||||
|
||||
void AT_CellularNetwork::read_reg_params(RegistrationType type, registration_params_t ®_params)
|
||||
|
@ -290,16 +271,12 @@ void AT_CellularNetwork::read_reg_params(RegistrationType type, registration_par
|
|||
nsapi_error_t AT_CellularNetwork::set_attach()
|
||||
{
|
||||
_at.lock();
|
||||
AttachStatus status;
|
||||
get_attach(status);
|
||||
|
||||
_at.cmd_start("AT+CGATT?");
|
||||
_at.cmd_stop();
|
||||
_at.resp_start("+CGATT:");
|
||||
int attached_state = _at.read_int();
|
||||
_at.resp_stop();
|
||||
if (attached_state != 1) {
|
||||
if (status == Detached) {
|
||||
tr_debug("Network attach");
|
||||
_at.cmd_start("AT+CGATT=1");
|
||||
_at.cmd_stop_read_resp();
|
||||
_at.at_cmd_discard("+CGATT", "=1");
|
||||
}
|
||||
|
||||
return _at.unlock_return_error();
|
||||
|
@ -307,31 +284,19 @@ nsapi_error_t AT_CellularNetwork::set_attach()
|
|||
|
||||
nsapi_error_t AT_CellularNetwork::get_attach(AttachStatus &status)
|
||||
{
|
||||
_at.lock();
|
||||
int attach_status;
|
||||
nsapi_error_t err = _at.at_cmd_int("+CGATT", "?", attach_status);
|
||||
status = (attach_status == 1) ? Attached : Detached;
|
||||
|
||||
_at.cmd_start("AT+CGATT?");
|
||||
_at.cmd_stop();
|
||||
|
||||
_at.resp_start("+CGATT:");
|
||||
if (_at.info_resp()) {
|
||||
int attach_status = _at.read_int();
|
||||
status = (attach_status == 1) ? Attached : Detached;
|
||||
}
|
||||
_at.resp_stop();
|
||||
|
||||
return _at.unlock_return_error();
|
||||
return err;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::detach()
|
||||
{
|
||||
_at.lock();
|
||||
|
||||
tr_debug("Network detach");
|
||||
_at.cmd_start("AT+CGATT=0");
|
||||
_at.cmd_stop_read_resp();
|
||||
_at.at_cmd_discard("+CGATT", "=0");
|
||||
|
||||
_at.cmd_start("AT+COPS=2");
|
||||
_at.cmd_stop_read_resp();
|
||||
_at.at_cmd_discard("+COPS", "=2");
|
||||
|
||||
call_network_cb(NSAPI_STATUS_DISCONNECTED);
|
||||
|
||||
|
@ -361,8 +326,7 @@ nsapi_error_t AT_CellularNetwork::scan_plmn(operList_t &operators, int &opsCount
|
|||
|
||||
_at.lock();
|
||||
|
||||
_at.cmd_start("AT+COPS=?");
|
||||
_at.cmd_stop();
|
||||
_at.cmd_start_stop("+COPS", "=?");
|
||||
|
||||
_at.resp_start("+COPS:");
|
||||
|
||||
|
@ -400,15 +364,7 @@ nsapi_error_t AT_CellularNetwork::set_ciot_optimization_config(CIoT_Supported_Op
|
|||
Callback<void(CIoT_Supported_Opt)> network_support_cb)
|
||||
{
|
||||
_ciotopt_network_support_cb = network_support_cb;
|
||||
_at.lock();
|
||||
|
||||
_at.cmd_start("AT+CCIOTOPT=");
|
||||
_at.write_int(1); //enable CCIOTOPTI URC
|
||||
_at.write_int(supported_opt);
|
||||
_at.write_int(preferred_opt);
|
||||
_at.cmd_stop_read_resp();
|
||||
|
||||
return _at.unlock_return_error();
|
||||
return _at.at_cmd_discard("+CCIOTOPT", "=1,", "%d%d", supported_opt, preferred_opt);
|
||||
}
|
||||
|
||||
void AT_CellularNetwork::urc_cciotopti()
|
||||
|
@ -425,8 +381,7 @@ nsapi_error_t AT_CellularNetwork::get_ciot_ue_optimization_config(CIoT_Supported
|
|||
{
|
||||
_at.lock();
|
||||
|
||||
_at.cmd_start("AT+CCIOTOPT?");
|
||||
_at.cmd_stop();
|
||||
_at.cmd_start_stop("+CCIOTOPT", "?");
|
||||
|
||||
_at.resp_start("+CCIOTOPT:");
|
||||
_at.read_int();
|
||||
|
@ -450,8 +405,7 @@ nsapi_error_t AT_CellularNetwork::get_signal_quality(int &rssi, int *ber)
|
|||
{
|
||||
_at.lock();
|
||||
|
||||
_at.cmd_start("AT+CSQ");
|
||||
_at.cmd_stop();
|
||||
_at.cmd_start_stop("+CSQ", "");
|
||||
|
||||
_at.resp_start("+CSQ:");
|
||||
int t_rssi = _at.read_int();
|
||||
|
@ -492,8 +446,7 @@ nsapi_error_t AT_CellularNetwork::get_operator_params(int &format, operator_t &o
|
|||
{
|
||||
_at.lock();
|
||||
|
||||
_at.cmd_start("AT+COPS?");
|
||||
_at.cmd_stop();
|
||||
_at.cmd_start_stop("+COPS", "?");
|
||||
|
||||
_at.resp_start("+COPS:");
|
||||
_at.read_int(); //ignore mode
|
||||
|
@ -523,8 +476,7 @@ nsapi_error_t AT_CellularNetwork::get_operator_names(operator_names_list &op_nam
|
|||
{
|
||||
_at.lock();
|
||||
|
||||
_at.cmd_start("AT+COPN");
|
||||
_at.cmd_stop();
|
||||
_at.cmd_start_stop("+COPN", "");
|
||||
|
||||
_at.resp_start("+COPN:");
|
||||
operator_names_t *names = NULL;
|
||||
|
@ -540,8 +492,7 @@ nsapi_error_t AT_CellularNetwork::get_operator_names(operator_names_list &op_nam
|
|||
|
||||
void AT_CellularNetwork::get_context_state_command()
|
||||
{
|
||||
_at.cmd_start("AT+CGACT?");
|
||||
_at.cmd_stop();
|
||||
_at.cmd_start_stop("+CGACT", "?");
|
||||
_at.resp_start("+CGACT:");
|
||||
}
|
||||
|
||||
|
@ -597,12 +548,9 @@ nsapi_error_t AT_CellularNetwork::get_registration_params(RegistrationType type,
|
|||
|
||||
_at.lock();
|
||||
|
||||
const char *rsp[] = { "+CEREG:", "+CGREG:", "+CREG:"};
|
||||
_at.cmd_start(at_reg[i].cmd);
|
||||
_at.write_string("?", false);
|
||||
_at.cmd_stop();
|
||||
_at.resp_start(rsp[i]);
|
||||
_at.cmd_start_stop(at_reg[i].cmd, "?");
|
||||
|
||||
_at.resp_start(at_reg[i].urc_prefix);
|
||||
(void)_at.read_int(); // ignore urc mode subparam
|
||||
read_reg_params(type, reg_params);
|
||||
_at.resp_stop();
|
||||
|
@ -670,15 +618,7 @@ nsapi_error_t AT_CellularNetwork::set_receive_period(int mode, EDRXAccessTechnol
|
|||
uint_to_binary_str(edrx_value, edrx, 5, 4);
|
||||
edrx[4] = '\0';
|
||||
|
||||
_at.lock();
|
||||
|
||||
_at.cmd_start("AT+CEDRXS=");
|
||||
_at.write_int(mode);
|
||||
_at.write_int(act_type);
|
||||
_at.write_string(edrx);
|
||||
_at.cmd_stop_read_resp();
|
||||
|
||||
return _at.unlock_return_error();
|
||||
return _at.at_cmd_discard("+CEDRXS", "=", "%d%d%s", mode, act_type, edrx);
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::set_packet_domain_event_reporting(bool on)
|
||||
|
@ -687,10 +627,5 @@ nsapi_error_t AT_CellularNetwork::set_packet_domain_event_reporting(bool on)
|
|||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
_at.lock();
|
||||
_at.cmd_start("AT+CGEREP=");
|
||||
_at.write_int(on ? 1 : 0); // discard unsolicited result codes when MT TE link is reserved (e.g. in on line data mode); otherwise forward them directly to the TE
|
||||
_at.cmd_stop_read_resp();
|
||||
|
||||
return _at.unlock_return_error();
|
||||
return _at.at_cmd_discard("+CGEREP", "=", "%d", on ? 1 : 0);
|
||||
}
|
||||
|
|
|
@ -213,10 +213,8 @@ nsapi_error_t AT_CellularSMS::set_cnmi()
|
|||
if (!get_property(PROPERTY_AT_CNMI)) {
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
_at.lock();
|
||||
_at.cmd_start("AT+CNMI=2,1");
|
||||
_at.cmd_stop_read_resp();
|
||||
return _at.unlock_return_error();
|
||||
|
||||
return _at.at_cmd_discard("+CNMI", "=2,1");
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularSMS::set_cmgf(int msg_format)
|
||||
|
@ -224,11 +222,8 @@ nsapi_error_t AT_CellularSMS::set_cmgf(int msg_format)
|
|||
if (!get_property(PROPERTY_AT_CMGF)) {
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
_at.lock();
|
||||
_at.cmd_start("AT+CMGF=");
|
||||
_at.write_int(msg_format);
|
||||
_at.cmd_stop_read_resp();
|
||||
return _at.unlock_return_error();
|
||||
|
||||
return _at.at_cmd_discard("+CMGF", "=", "%d", msg_format);
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularSMS::set_csmp(int fo, int vp, int pid, int dcs)
|
||||
|
@ -236,14 +231,8 @@ nsapi_error_t AT_CellularSMS::set_csmp(int fo, int vp, int pid, int dcs)
|
|||
if (!get_property(PROPERTY_AT_CSMP)) {
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
_at.lock();
|
||||
_at.cmd_start("AT+CSMP=");
|
||||
_at.write_int(fo);
|
||||
_at.write_int(vp);
|
||||
_at.write_int(pid);
|
||||
_at.write_int(dcs);
|
||||
_at.cmd_stop_read_resp();
|
||||
return _at.unlock_return_error();
|
||||
|
||||
return _at.at_cmd_discard("+CSMP", "=", "%d%d%d%d", fo, vp, pid, dcs);
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularSMS::set_csdh(int show_header)
|
||||
|
@ -251,11 +240,8 @@ nsapi_error_t AT_CellularSMS::set_csdh(int show_header)
|
|||
if (!get_property(PROPERTY_AT_CSDH)) {
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
_at.lock();
|
||||
_at.cmd_start("AT+CSDH=");
|
||||
_at.write_int(show_header);
|
||||
_at.cmd_stop_read_resp();
|
||||
return _at.unlock_return_error();
|
||||
|
||||
return _at.at_cmd_discard("+CSDH", "=", "%d", show_header);
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularSMS::initialize(CellularSMSMmode mode)
|
||||
|
@ -408,7 +394,8 @@ char *AT_CellularSMS::create_pdu(const char *phone_number, const char *message,
|
|||
|
||||
nsapi_size_or_error_t AT_CellularSMS::send_sms(const char *phone_number, const char *message, int msg_len)
|
||||
{
|
||||
int single_sms_max_length = _use_8bit_encoding ? SMS_MAX_SIZE_8BIT_SINGLE_SMS_SIZE :
|
||||
int single_sms_max_length = _use_8bit_encoding ?
|
||||
SMS_MAX_SIZE_8BIT_SINGLE_SMS_SIZE :
|
||||
SMS_MAX_SIZE_GSM7_SINGLE_SMS_SIZE;
|
||||
if ((_mode == CellularSMSMmodeText && msg_len > single_sms_max_length) || !phone_number) {
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
|
@ -422,9 +409,7 @@ nsapi_size_or_error_t AT_CellularSMS::send_sms(const char *phone_number, const c
|
|||
wait_ms(_sim_wait_time);
|
||||
|
||||
if (_mode == CellularSMSMmodeText) {
|
||||
_at.cmd_start("AT+CMGS=");
|
||||
_at.write_string(phone_number + remove_plus_sign);
|
||||
_at.cmd_stop();
|
||||
_at.cmd_start_stop("+CMGS", "=", "%s", phone_number + remove_plus_sign);
|
||||
|
||||
wait_ms(_sim_wait_time);
|
||||
_at.resp_start("> ", true);
|
||||
|
@ -448,7 +433,8 @@ nsapi_size_or_error_t AT_CellularSMS::send_sms(const char *phone_number, const c
|
|||
// supports uncompressed 8 bit data and GSM 7 bit default alphabet data. Current implementation uses only
|
||||
// GSM 7 bit default but support is done for 8 bit data.
|
||||
int sms_count;
|
||||
int concatenated_sms_length = _use_8bit_encoding ? SMS_MAX_8BIT_CONCATENATED_SINGLE_SMS_SIZE :
|
||||
int concatenated_sms_length = _use_8bit_encoding ?
|
||||
SMS_MAX_8BIT_CONCATENATED_SINGLE_SMS_SIZE :
|
||||
SMS_MAX_GSM7_CONCATENATED_SINGLE_SMS_SIZE;
|
||||
|
||||
if (msg_len <= single_sms_max_length) {
|
||||
|
@ -485,9 +471,8 @@ nsapi_size_or_error_t AT_CellularSMS::send_sms(const char *phone_number, const c
|
|||
pdu_len = strlen(pdu_str);
|
||||
|
||||
// specification says that service center number should not be included so we subtract -2 from pdu_len as we use '00' for automatic service center number
|
||||
_at.cmd_start("AT+CMGS=");
|
||||
_at.write_int((pdu_len - 2) / 2);
|
||||
_at.cmd_stop();
|
||||
|
||||
_at.cmd_start_stop("+CMGS", "=", "%d", (pdu_len - 2) / 2);
|
||||
|
||||
wait_ms(_sim_wait_time);
|
||||
_at.resp_start("> ", true);
|
||||
|
@ -540,44 +525,24 @@ void AT_CellularSMS::set_sms_callback(Callback<void()> func)
|
|||
|
||||
nsapi_error_t AT_CellularSMS::set_cpms(const char *memr, const char *memw, const char *mems)
|
||||
{
|
||||
_at.lock();
|
||||
_at.cmd_start("AT+CPMS=");
|
||||
_at.write_string(memr);
|
||||
_at.write_string(memw);
|
||||
_at.write_string(mems);
|
||||
_at.cmd_stop_read_resp();
|
||||
|
||||
return _at.unlock_return_error();
|
||||
return _at.at_cmd_discard("+CPMS", "=", "%s%s%s", memr, memw, mems);
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularSMS::set_csca(const char *sca, int type)
|
||||
{
|
||||
_at.lock();
|
||||
_at.cmd_start("AT+CSCA=");
|
||||
_at.write_string(sca);
|
||||
_at.write_int(type);
|
||||
_at.cmd_stop_read_resp();
|
||||
|
||||
return _at.unlock_return_error();
|
||||
return _at.at_cmd_discard("+CSCA", "=", "%s%d", sca, type);
|
||||
}
|
||||
|
||||
nsapi_size_or_error_t AT_CellularSMS::set_cscs(const char *chr_set)
|
||||
{
|
||||
_at.lock();
|
||||
_at.cmd_start("AT+CSCS=");
|
||||
_at.write_string(chr_set);
|
||||
_at.cmd_stop_read_resp();
|
||||
|
||||
return _at.unlock_return_error();
|
||||
return _at.at_cmd_discard("+CSCS", "=", "%s", chr_set);
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularSMS::delete_sms(sms_info_t *sms)
|
||||
{
|
||||
_at.lock();
|
||||
for (int i = 0; i < sms->parts; i++) {
|
||||
_at.cmd_start("AT+CMGD=");
|
||||
_at.write_int(sms->msg_index[i]);
|
||||
_at.cmd_stop_read_resp();
|
||||
_at.at_cmd_discard("+CMGD", "=", "%d", sms->msg_index[i]);
|
||||
}
|
||||
|
||||
return _at.unlock_return_error();
|
||||
|
@ -589,10 +554,7 @@ nsapi_error_t AT_CellularSMS::delete_sms(sms_info_t *sms)
|
|||
// that was corrupted. So we need to have delete all messages.
|
||||
nsapi_error_t AT_CellularSMS::delete_all_messages()
|
||||
{
|
||||
_at.lock();
|
||||
_at.cmd_start("AT+CMGD=1,4");
|
||||
_at.cmd_stop_read_resp();
|
||||
return _at.unlock_return_error();
|
||||
return _at.at_cmd_discard("+CMGD", "=1,4");
|
||||
}
|
||||
|
||||
// read msg in text mode
|
||||
|
@ -603,9 +565,7 @@ nsapi_size_or_error_t AT_CellularSMS::read_sms_from_index(int msg_index, char *b
|
|||
* +CMGR: <stat>,<oa>,<alpha>,<scts>[,<tooa>,<fo>,<pid>,<dcs>,<sca>,<tosca>,<length>]<CR><LF><data><CR><LF>OK<CR><LF>
|
||||
*/
|
||||
wait_ms(_sim_wait_time);
|
||||
_at.cmd_start("AT+CMGR=");
|
||||
_at.write_int(msg_index);
|
||||
_at.cmd_stop();
|
||||
_at.cmd_start_stop("+CMGR", "=", "%d", msg_index);
|
||||
|
||||
// TODO: NOTE: If the selected <mem1> can contain different types of SMs (e.g. SMS-DELIVERs, SMS-SUBMITs, SMS-STATUS-REPORTs and SMS-COMMANDs),
|
||||
// the response may be a mix of the responses of different SM types. TE application can recognize the response format by examining the third response parameter.
|
||||
|
@ -662,9 +622,7 @@ nsapi_size_or_error_t AT_CellularSMS::read_sms(sms_info_t *sms, char *buf, char
|
|||
|
||||
for (int i = 0; i < sms->parts; i++) {
|
||||
wait_ms(_sim_wait_time);
|
||||
_at.cmd_start("AT+CMGR=");
|
||||
_at.write_int(sms->msg_index[i]);
|
||||
_at.cmd_stop();
|
||||
_at.cmd_start_stop("+CMGR", "=", "%d", sms->msg_index[i]);
|
||||
_at.resp_start("+CMGR:");
|
||||
|
||||
if (_at.info_resp()) {
|
||||
|
@ -1041,11 +999,10 @@ nsapi_error_t AT_CellularSMS::list_messages()
|
|||
// the response may be a mix of the responses of different SM types. TE application can recognize the response format by examining the third response parameter.
|
||||
// for now we assume that only SMS-DELIVER messages are read.
|
||||
if (_mode == CellularSMSMmodePDU) {
|
||||
_at.cmd_start("AT+CMGL=4");
|
||||
_at.cmd_start_stop("+CMGL", "=4");
|
||||
} else {
|
||||
_at.cmd_start("AT+CMGL=\"ALL\"");
|
||||
_at.cmd_start_stop("+CMGL", "=\"ALL\"");
|
||||
}
|
||||
_at.cmd_stop();
|
||||
|
||||
sms_info_t *info = NULL;
|
||||
// init for 1 so that in text mode we will add to the correct place without any additional logic in addInfo() in text mode
|
||||
|
|
|
@ -59,9 +59,7 @@ const char *AT_CellularStack::get_ip_address()
|
|||
{
|
||||
_at.lock();
|
||||
|
||||
_at.cmd_start("AT+CGPADDR=");
|
||||
_at.write_int(_cid);
|
||||
_at.cmd_stop();
|
||||
_at.cmd_start_stop("+CGPADDR", "=", "%d", _cid);
|
||||
|
||||
_at.resp_start("+CGPADDR:");
|
||||
|
||||
|
|
|
@ -34,12 +34,10 @@ nsapi_size_or_error_t AT_ControlPlane_netif::send(const void *cpdata, nsapi_size
|
|||
{
|
||||
//CSODCP
|
||||
_at.lock();
|
||||
_at.cmd_start("AT+CSODCP=");
|
||||
_at.write_int(_cid);
|
||||
_at.write_int(cpdata_length);
|
||||
_at.write_bytes((uint8_t *)cpdata, cpdata_length);
|
||||
|
||||
return _at.unlock_return_error();
|
||||
nsapi_size_or_error_t err = _at.at_cmd_discard("+CSODCP", "=", "%d%d%b", _cid, cpdata_length, cpdata, cpdata_length);
|
||||
|
||||
return (err == NSAPI_ERROR_OK) ? cpdata_length : err;
|
||||
}
|
||||
|
||||
nsapi_size_or_error_t AT_ControlPlane_netif::recv(void *cpdata, nsapi_size_t cpdata_length)
|
||||
|
@ -55,8 +53,9 @@ nsapi_size_or_error_t AT_ControlPlane_netif::recv(void *cpdata, nsapi_size_t cpd
|
|||
}
|
||||
|
||||
memcpy(cpdata, _recv_buffer, _recv_len);
|
||||
|
||||
return _recv_len = 0;
|
||||
size_t recv = _recv_len;
|
||||
_recv_len = 0;
|
||||
return recv;
|
||||
}
|
||||
|
||||
void AT_ControlPlane_netif::attach(void (*callback)(void *), void *data)
|
||||
|
|
|
@ -70,17 +70,8 @@ ControlPlane_netif *QUECTEL_BG96_CellularContext::get_cp_netif()
|
|||
nsapi_error_t QUECTEL_BG96_CellularContext::do_user_authentication()
|
||||
{
|
||||
if (_pwd && _uname) {
|
||||
_at.cmd_start("AT+QICSGP=");
|
||||
_at.write_int(_cid);
|
||||
_at.write_int(1); // IPv4
|
||||
_at.write_string(_apn);
|
||||
_at.write_string(_uname);
|
||||
_at.write_string(_pwd);
|
||||
_at.write_int(_authentication_type);
|
||||
_at.cmd_stop();
|
||||
_at.resp_start();
|
||||
_at.resp_stop();
|
||||
if (_at.get_last_error() != NSAPI_ERROR_OK) {
|
||||
if (_at.at_cmd_discard("+QICSGP", "=", "%d%d%s%s%s%d", _cid, 1,
|
||||
_apn, _uname, _pwd, _authentication_type) != NSAPI_ERROR_OK) {
|
||||
return NSAPI_ERROR_AUTH_FAILURE;
|
||||
}
|
||||
}
|
||||
|
@ -90,17 +81,9 @@ nsapi_error_t QUECTEL_BG96_CellularContext::do_user_authentication()
|
|||
|
||||
nsapi_error_t QUECTEL_BG96_CellularContext::activate_non_ip_context()
|
||||
{
|
||||
_at.lock();
|
||||
|
||||
// Open the NIDD connection
|
||||
_at.cmd_start("AT+QCFGEXT=\"nipd\",1");
|
||||
_at.cmd_stop();
|
||||
_at.resp_start();
|
||||
_at.resp_stop();
|
||||
|
||||
nsapi_size_or_error_t ret = _at.get_last_error();
|
||||
|
||||
_at.unlock();
|
||||
nsapi_size_or_error_t ret = _at.at_cmd_discard("+QCFGEXT", "=\"nipd\",1");
|
||||
|
||||
if (ret == NSAPI_ERROR_OK) {
|
||||
_semaphore.try_acquire_for(NIDD_OPEN_URC_TIMEOUT);
|
||||
|
@ -115,28 +98,21 @@ nsapi_error_t QUECTEL_BG96_CellularContext::activate_non_ip_context()
|
|||
void QUECTEL_BG96_CellularContext::activate_context()
|
||||
{
|
||||
tr_info("Activate PDP context %d", _cid);
|
||||
_at.cmd_start("AT+QIACT=");
|
||||
_at.write_int(_cid);
|
||||
_at.cmd_stop_read_resp();
|
||||
if (_at.get_last_error() == NSAPI_ERROR_OK) {
|
||||
|
||||
if (_at.at_cmd_discard("+QIACT", "=", "%d", _cid) == NSAPI_ERROR_OK) {
|
||||
_is_context_activated = true;
|
||||
}
|
||||
}
|
||||
|
||||
void QUECTEL_BG96_CellularContext::deactivate_context()
|
||||
{
|
||||
_at.cmd_start("AT+QIDEACT=");
|
||||
_at.write_int(_cid);
|
||||
_at.cmd_stop_read_resp();
|
||||
_at.at_cmd_discard("+QIDEACT", "=", "%d", _cid);
|
||||
}
|
||||
|
||||
void QUECTEL_BG96_CellularContext::deactivate_non_ip_context()
|
||||
{
|
||||
// Close the NIDD connection
|
||||
_at.cmd_start("AT+QCFGEXT=\"nipd\",0");
|
||||
_at.cmd_stop();
|
||||
_at.resp_start();
|
||||
_at.resp_stop();
|
||||
_at.at_cmd_discard("+QCFGEXT", "=\"nipd\",0");
|
||||
}
|
||||
|
||||
void QUECTEL_BG96_CellularContext::urc_nidd()
|
||||
|
@ -178,30 +154,16 @@ nsapi_error_t QUECTEL_BG96_CellularContext::setup_control_plane_opt()
|
|||
{
|
||||
_at.lock();
|
||||
|
||||
_at.cmd_start("AT+QCFGEXT=\"pdp_type\",");
|
||||
_at.write_int(NIDD_PDP_CONTEXT_ID);
|
||||
_at.write_string("Non-IP");
|
||||
_at.write_string(_apn);
|
||||
_at.cmd_stop();
|
||||
_at.resp_start();
|
||||
_at.resp_stop();
|
||||
_at.cmd_start("AT+CFUN=0");
|
||||
_at.cmd_stop();
|
||||
_at.resp_start();
|
||||
_at.resp_stop();
|
||||
_at.cmd_start("AT+CFUN=1");
|
||||
_at.cmd_stop();
|
||||
_at.resp_start();
|
||||
_at.resp_stop();
|
||||
_at.at_cmd_discard("+QCFGEXT", "=\"pdp_type\",", "%d%s%s", NIDD_PDP_CONTEXT_ID, "Non-IP", _apn);
|
||||
|
||||
_at.at_cmd_discard("+CFUN", "=0");
|
||||
|
||||
_at.at_cmd_discard("+CFUN", "=1");
|
||||
|
||||
// Configure Non-IP outgoing data type - 0 for no exception data
|
||||
_at.cmd_start("AT+QCFGEXT=\"nipdcfg\",0,");
|
||||
_at.write_string(_apn);
|
||||
_at.cmd_stop();
|
||||
_at.resp_start();
|
||||
_at.resp_stop();
|
||||
nsapi_error_t err = _at.at_cmd_discard("+QCFGEXT", "=\"nipdcfg\",0,", "%s", _apn);
|
||||
|
||||
if (_at.get_last_error() == NSAPI_ERROR_OK) {
|
||||
if (err == NSAPI_ERROR_OK) {
|
||||
_cp_in_use = true;
|
||||
if (_nonip_req) {
|
||||
_pdp_type = NON_IP_PDP_TYPE;
|
||||
|
|
|
@ -29,13 +29,7 @@ QUECTEL_BG96_CellularInformation::~QUECTEL_BG96_CellularInformation()
|
|||
// According to BG96_AT_Commands_Manual_V2.0
|
||||
nsapi_error_t QUECTEL_BG96_CellularInformation::get_iccid(char *buf, size_t buf_size)
|
||||
{
|
||||
_at.lock();
|
||||
_at.cmd_start("AT+QCCID");
|
||||
_at.cmd_stop();
|
||||
_at.resp_start("+QCCID:");
|
||||
_at.read_string(buf, buf_size);
|
||||
_at.resp_stop();
|
||||
return _at.unlock_return_error();
|
||||
return _at.at_cmd_str("+QCCID", "", buf, buf_size);
|
||||
}
|
||||
|
||||
} /* namespace mbed */
|
||||
|
|
|
@ -35,37 +35,27 @@ nsapi_error_t QUECTEL_BG96_CellularNetwork::set_access_technology_impl(RadioAcce
|
|||
|
||||
switch (opsAct) {
|
||||
case RAT_CATM1:
|
||||
_at.cmd_start("AT+QCFG=\"nwscanseq\",020301");
|
||||
_at.cmd_stop_read_resp();
|
||||
_at.cmd_start("AT+QCFG=\"nwscanmode\",3,1");
|
||||
_at.cmd_stop_read_resp();
|
||||
_at.cmd_start("AT+QCFG=\"iotopmode\",0,1");
|
||||
_at.cmd_stop_read_resp();
|
||||
_at.at_cmd_discard("+QCFG", "=\"nwscanseq\",020301");
|
||||
_at.at_cmd_discard("+QCFG", "=\"nwscanmode\",3,1");
|
||||
_at.at_cmd_discard("+QCFG", "=\"iotopmode\",0,1");
|
||||
break;
|
||||
case RAT_NB1:
|
||||
_at.cmd_start("AT+QCFG=\"nwscanseq\",030201");
|
||||
_at.cmd_stop_read_resp();
|
||||
_at.cmd_start("AT+QCFG=\"nwscanmode\",3,1");
|
||||
_at.cmd_stop_read_resp();
|
||||
_at.cmd_start("AT+QCFG=\"iotopmode\",1,1");
|
||||
_at.cmd_stop_read_resp();
|
||||
_at.at_cmd_discard("+QCFG", "=\"nwscanseq\",030201");
|
||||
_at.at_cmd_discard("+QCFG", "=\"nwscanmode\",3,1");
|
||||
_at.at_cmd_discard("+QCFG", "=\"iotopmode\",1,1");
|
||||
break;
|
||||
case RAT_GSM:
|
||||
case RAT_GSM_COMPACT:
|
||||
case RAT_UTRAN:
|
||||
case RAT_EGPRS:
|
||||
_at.cmd_start("AT+QCFG=\"nwscanseq\",010203");
|
||||
_at.cmd_stop_read_resp();
|
||||
_at.cmd_start("AT+QCFG=\"nwscanmode\",1,1");
|
||||
_at.cmd_stop_read_resp();
|
||||
_at.at_cmd_discard("+QCFG", "=\"nwscanseq\",010203");
|
||||
_at.at_cmd_discard("+QCFG", "=\"nwscanmode\",1,1");
|
||||
break;
|
||||
default:
|
||||
_at.cmd_start("AT+QCFG=\"nwscanseq\",020301");
|
||||
_at.cmd_stop_read_resp();
|
||||
_at.cmd_start("AT+QCFG=\"nwscanmode\",0,1"); //auto mode
|
||||
_at.cmd_stop_read_resp();
|
||||
_at.cmd_start("AT+QCFG=\"iotopmode\",2,1"); //auto mode
|
||||
_at.cmd_stop_read_resp();
|
||||
_at.at_cmd_discard("+QCFG", "=\"nwscanseq\",020301");
|
||||
_at.at_cmd_discard("+QCFG", "=\"nwscanmode\",0,1");
|
||||
_at.at_cmd_discard("+QCFG", "=\"iotopmode\",2,1");
|
||||
|
||||
_at.unlock();
|
||||
_op_act = RAT_UNKNOWN;
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
|
@ -77,8 +67,7 @@ nsapi_error_t QUECTEL_BG96_CellularNetwork::set_access_technology_impl(RadioAcce
|
|||
void QUECTEL_BG96_CellularNetwork::get_context_state_command()
|
||||
{
|
||||
// read active contexts
|
||||
_at.cmd_start("AT+QIACT?");
|
||||
_at.cmd_stop();
|
||||
_at.cmd_start_stop("+QIACT", "?");
|
||||
_at.resp_start("+QIACT:");
|
||||
}
|
||||
|
||||
|
|
|
@ -59,15 +59,8 @@ nsapi_error_t QUECTEL_BG96_CellularStack::socket_connect(nsapi_socket_t handle,
|
|||
|
||||
_at.lock();
|
||||
if (socket->proto == NSAPI_TCP) {
|
||||
_at.cmd_start("AT+QIOPEN=");
|
||||
_at.write_int(_cid);
|
||||
_at.write_int(request_connect_id);
|
||||
_at.write_string("TCP");
|
||||
_at.write_string(address.get_ip_address());
|
||||
_at.write_int(address.get_port());
|
||||
_at.write_int(socket->localAddress.get_port());
|
||||
_at.write_int(0);
|
||||
_at.cmd_stop();
|
||||
_at.at_cmd_discard("+QIOPEN", "=", "%d%d%s%s%d%d%d", _cid, request_connect_id, "TCP",
|
||||
address.get_ip_address(), address.get_port(), socket->localAddress.get_port(), 0);
|
||||
|
||||
handle_open_socket_response(modem_connect_id, err);
|
||||
|
||||
|
@ -77,21 +70,10 @@ nsapi_error_t QUECTEL_BG96_CellularStack::socket_connect(nsapi_socket_t handle,
|
|||
_at.unlock();
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
_at.cmd_start("AT+QICLOSE=");
|
||||
_at.write_int(modem_connect_id);
|
||||
_at.cmd_stop();
|
||||
_at.resp_start();
|
||||
_at.resp_stop();
|
||||
_at.at_cmd_discard("+QICLOSE", "=", "%d", modem_connect_id);
|
||||
|
||||
_at.cmd_start("AT+QIOPEN=");
|
||||
_at.write_int(_cid);
|
||||
_at.write_int(request_connect_id);
|
||||
_at.write_string("TCP");
|
||||
_at.write_string(address.get_ip_address());
|
||||
_at.write_int(address.get_port());
|
||||
_at.write_int(socket->localAddress.get_port());
|
||||
_at.write_int(0);
|
||||
_at.cmd_stop();
|
||||
_at.at_cmd_discard("+QIOPEN", "=", "%d%d%s%s%d%d%d", _cid, request_connect_id, "TCP",
|
||||
address.get_ip_address(), address.get_port(), socket->localAddress.get_port(), 0);
|
||||
|
||||
handle_open_socket_response(modem_connect_id, err);
|
||||
}
|
||||
|
@ -99,11 +81,7 @@ nsapi_error_t QUECTEL_BG96_CellularStack::socket_connect(nsapi_socket_t handle,
|
|||
|
||||
// If opened successfully BUT not requested one, close it
|
||||
if (!err && (modem_connect_id != request_connect_id)) {
|
||||
_at.cmd_start("AT+QICLOSE=");
|
||||
_at.write_int(modem_connect_id);
|
||||
_at.cmd_stop();
|
||||
_at.resp_start();
|
||||
_at.resp_stop();
|
||||
_at.at_cmd_discard("+QICLOSE", "=", "%d", modem_connect_id);
|
||||
}
|
||||
|
||||
nsapi_error_t ret_val = _at.get_last_error();
|
||||
|
@ -162,19 +140,15 @@ bool QUECTEL_BG96_CellularStack::is_protocol_supported(nsapi_protocol_t protocol
|
|||
nsapi_error_t QUECTEL_BG96_CellularStack::socket_close_impl(int sock_id)
|
||||
{
|
||||
_at.set_at_timeout(BG96_CLOSE_SOCKET_TIMEOUT);
|
||||
_at.cmd_start("AT+QICLOSE=");
|
||||
_at.write_int(sock_id);
|
||||
_at.cmd_stop_read_resp();
|
||||
nsapi_error_t err = _at.at_cmd_discard("+QICLOSE", "=", "%d", sock_id);
|
||||
_at.restore_at_timeout();
|
||||
|
||||
return _at.get_last_error();
|
||||
return err;
|
||||
}
|
||||
|
||||
void QUECTEL_BG96_CellularStack::handle_open_socket_response(int &modem_connect_id, int &err)
|
||||
{
|
||||
// OK
|
||||
_at.resp_start();
|
||||
_at.resp_stop();
|
||||
// QIOPEN -> should be handled as URC?
|
||||
_at.set_at_timeout(BG96_CREATE_SOCKET_TIMEOUT);
|
||||
_at.resp_start("+QIOPEN:");
|
||||
|
@ -195,19 +169,9 @@ nsapi_error_t QUECTEL_BG96_CellularStack::create_socket_impl(CellularSocket *soc
|
|||
MBED_ASSERT(request_connect_id != -1);
|
||||
|
||||
if (socket->proto == NSAPI_UDP && !socket->connected) {
|
||||
_at.cmd_start("AT+QIOPEN=");
|
||||
_at.write_int(_cid);
|
||||
_at.write_int(request_connect_id);
|
||||
_at.write_string("UDP SERVICE");
|
||||
if (_stack_type == IPV4_STACK) {
|
||||
_at.write_string("127.0.0.1");
|
||||
} else if (_stack_type == IPV6_STACK || _stack_type == IPV4V6_STACK) {
|
||||
_at.write_string("0:0:0:0:0:0:0:1");
|
||||
}
|
||||
_at.write_int(remote_port);
|
||||
_at.write_int(socket->localAddress.get_port());
|
||||
_at.write_int(0);
|
||||
_at.cmd_stop();
|
||||
_at.at_cmd_discard("+QIOPEN", "=", "%d%d%s%s%d%d%d", _cid, request_connect_id, "UDP SERVICE",
|
||||
(_stack_type == IPV4_STACK) ? "127.0.0.1" : "0:0:0:0:0:0:0:1",
|
||||
remote_port, socket->localAddress.get_port(), 0);
|
||||
|
||||
handle_open_socket_response(modem_connect_id, err);
|
||||
|
||||
|
@ -218,31 +182,15 @@ nsapi_error_t QUECTEL_BG96_CellularStack::create_socket_impl(CellularSocket *soc
|
|||
}
|
||||
socket_close_impl(modem_connect_id);
|
||||
|
||||
_at.cmd_start("AT+QIOPEN=");
|
||||
_at.write_int(_cid);
|
||||
_at.write_int(request_connect_id);
|
||||
_at.write_string("UDP SERVICE");
|
||||
|
||||
if (_stack_type == IPV4_STACK) {
|
||||
_at.write_string("127.0.0.1");
|
||||
} else if (_stack_type == IPV6_STACK || _stack_type == IPV4V6_STACK) {
|
||||
_at.write_string("0:0:0:0:0:0:0:1");
|
||||
}
|
||||
_at.write_int(remote_port);
|
||||
_at.write_int(socket->localAddress.get_port());
|
||||
_at.write_int(0);
|
||||
_at.cmd_stop();
|
||||
_at.at_cmd_discard("+QIOPEN", "=", "%d%d%s%s%d%d%d", _cid, request_connect_id, "UDP SERVICE",
|
||||
(_stack_type == IPV4_STACK) ? "127.0.0.1" : "0:0:0:0:0:0:0:1",
|
||||
remote_port, socket->localAddress.get_port(), 0);
|
||||
|
||||
handle_open_socket_response(modem_connect_id, err);
|
||||
}
|
||||
} else if (socket->proto == NSAPI_UDP && socket->connected) {
|
||||
_at.cmd_start("AT+QIOPEN=");
|
||||
_at.write_int(_cid);
|
||||
_at.write_int(request_connect_id);
|
||||
_at.write_string("UDP");
|
||||
_at.write_string(socket->remoteAddress.get_ip_address());
|
||||
_at.write_int(socket->remoteAddress.get_port());
|
||||
_at.cmd_stop();
|
||||
_at.at_cmd_discard("+QIOPEN", "=", "%d%d%s%s%d", _cid, request_connect_id, "UDP",
|
||||
socket->remoteAddress.get_ip_address(), socket->remoteAddress.get_port());
|
||||
|
||||
handle_open_socket_response(modem_connect_id, err);
|
||||
|
||||
|
@ -253,13 +201,8 @@ nsapi_error_t QUECTEL_BG96_CellularStack::create_socket_impl(CellularSocket *soc
|
|||
}
|
||||
socket_close_impl(modem_connect_id);
|
||||
|
||||
_at.cmd_start("AT+QIOPEN=");
|
||||
_at.write_int(_cid);
|
||||
_at.write_int(request_connect_id);
|
||||
_at.write_string("UDP");
|
||||
_at.write_string(socket->remoteAddress.get_ip_address());
|
||||
_at.write_int(socket->remoteAddress.get_port());
|
||||
_at.cmd_stop();
|
||||
_at.at_cmd_discard("+QIOPEN", "=", "%d%d%s%s%d", _cid, request_connect_id, "UDP",
|
||||
socket->remoteAddress.get_ip_address(), socket->remoteAddress.get_port());
|
||||
|
||||
handle_open_socket_response(modem_connect_id, err);
|
||||
}
|
||||
|
@ -291,24 +234,15 @@ nsapi_size_or_error_t QUECTEL_BG96_CellularStack::socket_sendto_impl(CellularSoc
|
|||
int sent_len_after = 0;
|
||||
|
||||
// Get the sent count before sending
|
||||
_at.cmd_start("AT+QISEND=");
|
||||
_at.write_int(socket->id);
|
||||
_at.write_int(0);
|
||||
_at.cmd_stop();
|
||||
|
||||
_at.resp_start("+QISEND:");
|
||||
sent_len_before = _at.read_int();
|
||||
_at.resp_stop();
|
||||
_at.at_cmd_int("+QISEND", "=", sent_len_before, "%d%d", socket->id, 0);
|
||||
|
||||
// Send
|
||||
_at.cmd_start("AT+QISEND=");
|
||||
_at.write_int(socket->id);
|
||||
_at.write_int(size);
|
||||
if (socket->proto == NSAPI_UDP) {
|
||||
_at.write_string(address.get_ip_address());
|
||||
_at.write_int(address.get_port());
|
||||
_at.cmd_start_stop("+QISEND", "=", "%d%d%s%d", socket->id, size,
|
||||
address.get_ip_address(), address.get_port());
|
||||
} else {
|
||||
_at.cmd_start_stop("+QISEND", "=", "%d%d", socket->id, size);
|
||||
}
|
||||
_at.cmd_stop();
|
||||
|
||||
_at.resp_start(">");
|
||||
_at.write_bytes((uint8_t *)data, size);
|
||||
|
@ -317,21 +251,15 @@ nsapi_size_or_error_t QUECTEL_BG96_CellularStack::socket_sendto_impl(CellularSoc
|
|||
_at.resp_stop();
|
||||
|
||||
// Get the sent count after sending
|
||||
_at.cmd_start("AT+QISEND=");
|
||||
_at.write_int(socket->id);
|
||||
_at.write_int(0);
|
||||
_at.cmd_stop();
|
||||
|
||||
_at.resp_start("+QISEND:");
|
||||
sent_len_after = _at.read_int();
|
||||
_at.resp_stop();
|
||||
nsapi_size_or_error_t err = _at.at_cmd_int("+QISEND", "=", sent_len_after, "%d%d", socket->id, 0);
|
||||
|
||||
if (_at.get_last_error() == NSAPI_ERROR_OK) {
|
||||
if (err == NSAPI_ERROR_OK) {
|
||||
sent_len = sent_len_after - sent_len_before;
|
||||
return sent_len;
|
||||
}
|
||||
|
||||
return _at.get_last_error();
|
||||
return err;
|
||||
}
|
||||
|
||||
nsapi_size_or_error_t QUECTEL_BG96_CellularStack::socket_recvfrom_impl(CellularSocket *socket, SocketAddress *address,
|
||||
|
@ -341,14 +269,13 @@ nsapi_size_or_error_t QUECTEL_BG96_CellularStack::socket_recvfrom_impl(CellularS
|
|||
int port;
|
||||
char ip_address[NSAPI_IP_SIZE + 1];
|
||||
|
||||
_at.cmd_start("AT+QIRD=");
|
||||
_at.write_int(socket->id);
|
||||
if (socket->proto == NSAPI_TCP) {
|
||||
// do not read more than max size
|
||||
size = size > BG96_MAX_RECV_SIZE ? BG96_MAX_RECV_SIZE : size;
|
||||
_at.write_int(size);
|
||||
_at.cmd_start_stop("+QIRD", "=", "%d%d", socket->id, size);
|
||||
} else {
|
||||
_at.cmd_start_stop("+QIRD", "=", "%d", socket->id);
|
||||
}
|
||||
_at.cmd_stop();
|
||||
|
||||
_at.resp_start("+QIRD:");
|
||||
recv_len = _at.read_int();
|
||||
|
|
|
@ -7,18 +7,7 @@ QUECTEL_BG96_ControlPlane_netif::QUECTEL_BG96_ControlPlane_netif(ATHandler &at,
|
|||
|
||||
nsapi_size_or_error_t QUECTEL_BG96_ControlPlane_netif::send(const void *data, nsapi_size_t size)
|
||||
{
|
||||
_at.lock();
|
||||
|
||||
_at.cmd_start("AT+QCFGEXT=\"nipds\",0,");
|
||||
_at.write_string((char *)data);
|
||||
_at.write_int(size);
|
||||
_at.cmd_stop();
|
||||
_at.resp_start();
|
||||
_at.resp_stop();
|
||||
|
||||
nsapi_error_t err = _at.get_last_error();
|
||||
|
||||
_at.unlock();
|
||||
nsapi_size_or_error_t err = _at.at_cmd_discard("+QCFGEXT", "=\"nipds\",0,", "%s%d", data, size);
|
||||
|
||||
if (err == NSAPI_ERROR_OK) {
|
||||
return size;
|
||||
|
|
Loading…
Reference in New Issue