Merge pull request #9568 from ARMmbed/feature-cellular-refactor

Merge feature cellular refactor
pull/9655/head
Nir Sonnenschein 2019-02-07 18:17:32 +02:00 committed by GitHub
commit 8c2ad14ace
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
202 changed files with 5933 additions and 6662 deletions

View File

@ -18,7 +18,7 @@
#include "gtest/gtest.h"
#include "AT_CellularBase.h"
#include "EventQueue.h"
#include "AT_CellularBase.h"
#include "AT_CellularNetwork.h"
#include "ATHandler_stub.h"
#include "FileHandle_stub.h"
#include <string.h>
@ -33,28 +33,25 @@ public:
}
bool check_not_supported()
{
static const AT_CellularBase::SupportedFeature unsupported_features[] = {
AT_CellularBase::AT_CGSN_WITH_TYPE,
AT_CellularBase::SUPPORTED_FEATURE_END_MARK
static const intptr_t cellular_properties[AT_CellularBase::PROPERTY_MAX] = {
AT_CellularNetwork::RegistrationModeDisable,// C_EREG
AT_CellularNetwork::RegistrationModeLAC, // C_GREG
AT_CellularNetwork::RegistrationModeLAC, // C_REG
0, // AT_CGSN_WITH_TYPE
1, // AT_CGDATA
1, // AT_CGAUTH
1, // PROPERTY_IPV4_STACK
0, // PROPERTY_IPV6_STACK
0, // PROPERTY_IPV4V6_STACK
};
set_unsupported_features(unsupported_features);
return is_supported(AT_CGSN_WITH_TYPE);
set_cellular_properties(cellular_properties);
return get_property(PROPERTY_AT_CGSN_WITH_TYPE);
}
bool check_supported()
{
set_unsupported_features(NULL);
return is_supported(AT_CGSN_WITH_TYPE);
}
bool check_supported_not_found()
{
static const AT_CellularBase::SupportedFeature unsupported_features[] = {
AT_CellularBase::AT_CGSN_WITH_TYPE,
AT_CellularBase::SUPPORTED_FEATURE_END_MARK
};
set_unsupported_features(unsupported_features);
return is_supported(SUPPORTED_FEATURE_END_MARK);
return get_property(PROPERTY_AT_CGDATA);
}
};
@ -109,19 +106,25 @@ TEST_F(TestAT_CellularBase, test_AT_CellularBase_get_device_error)
ATHandler_stub::device_err_value.errCode = 0;
}
TEST_F(TestAT_CellularBase, test_AT_CellularBase_set_unsupported_features)
TEST_F(TestAT_CellularBase, test_AT_CellularBase_set_cellular_properties)
{
EventQueue eq;
FileHandle_stub fh;
ATHandler ah(&fh, eq, 0, ",");
AT_CellularBase at(ah);
static const AT_CellularBase::SupportedFeature unsupported_features[] = {
AT_CellularBase::AT_CGSN_WITH_TYPE,
AT_CellularBase::SUPPORTED_FEATURE_END_MARK
static const intptr_t cellular_properties[AT_CellularBase::PROPERTY_MAX] = {
AT_CellularNetwork::RegistrationModeDisable,// C_EREG
AT_CellularNetwork::RegistrationModeLAC, // C_GREG
AT_CellularNetwork::RegistrationModeLAC, // C_REG
0, // AT_CGSN_WITH_TYPE
1, // AT_CGDATA
1, // AT_CGAUTH
1, // PROPERTY_IPV4_STACK
0, // PROPERTY_IPV6_STACK
0, // PROPERTY_IPV4V6_STACK
};
at.set_unsupported_features(unsupported_features);
at.set_cellular_properties(cellular_properties);
}
TEST_F(TestAT_CellularBase, test_AT_CellularBase_is_supported)
@ -131,7 +134,6 @@ TEST_F(TestAT_CellularBase, test_AT_CellularBase_is_supported)
ATHandler ah(&fh, eq, 0, ",");
my_base my_at(ah);
EXPECT_TRUE(true == my_at.check_supported());
EXPECT_TRUE(true == my_at.check_supported_not_found());
EXPECT_TRUE(false == my_at.check_not_supported());
EXPECT_EQ(true, my_at.check_supported());
EXPECT_EQ(false, my_at.check_not_supported());
}

View File

@ -27,7 +27,7 @@
#include "Semaphore_stub.h"
#include "CellularDevice_stub.h"
#include "equeue_stub.h"
#include "CellularSIM.h"
#include "AT_CellularBase_stub.h"
using namespace mbed;
using namespace events;
@ -115,12 +115,12 @@ public:
class my_AT_CTX : public AT_CellularContext {
public:
my_AT_CTX(ATHandler &at, CellularDevice *device, const char *apn = MBED_CONF_NSAPI_DEFAULT_CELLULAR_APN) :
AT_CellularContext(at, device, apn), _st(at) {}
virtual ~my_AT_CTX() {}
virtual bool stack_type_supported(nsapi_ip_stack_t stack_type)
AT_CellularContext(at, device, apn), _st(at)
{
return false;
AT_CellularBase_stub::supported_bool = false;
}
virtual ~my_AT_CTX() {}
virtual NetworkStack *get_stack()
{
return &_st;
@ -142,10 +142,6 @@ public:
my_AT_CTXIPV6(ATHandler &at, CellularDevice *device, const char *apn = MBED_CONF_NSAPI_DEFAULT_CELLULAR_APN) :
AT_CellularContext(at, device, apn), _st(at) {}
virtual ~my_AT_CTXIPV6() {}
virtual bool stack_type_supported(nsapi_ip_stack_t stack_type)
{
return true;
}
virtual NetworkStack *get_stack()
{
return &_st;
@ -528,7 +524,7 @@ TEST_F(TestAT_CellularContext, set_sim_ready)
cell_callback_data_t data;
data.error = NSAPI_ERROR_OK;
ctx.cellular_callback((nsapi_event_t)CellularDeviceReady, (intptr_t)&data);
data.status_data = CellularSIM::SimStateReady;
data.status_data = CellularDevice::SimStateReady;
ctx.cellular_callback((nsapi_event_t)CellularSIMStatusChanged, (intptr_t)&data);
}

View File

@ -9,6 +9,7 @@ set(unittest-includes ${unittest-includes}
../features/cellular/framework/common
../features/cellular/framework/AT
../features/cellular/framework/device
../features/netsocket/cellular
)
# Source files
@ -33,8 +34,11 @@ set(unittest-test-sources
stubs/FileHandle_stub.cpp
stubs/mbed_assert_stub.c
stubs/NetworkInterface_stub.cpp
stubs/NetworkInterfaceDefaults_stub.cpp
stubs/NetworkStack_stub.cpp
stubs/randLIB_stub.cpp
stubs/Semaphore_stub.cpp
stubs/us_ticker_stub.cpp
stubs/UARTSerial_stub.cpp
stubs/SerialBase_stub.cpp
)

View File

@ -51,26 +51,25 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_get_at_handler)
FileHandle_stub fh1;
FileHandle_stub fh2;
FileHandle_stub fh3;
AT_CellularDevice dev(&fh1);
AT_CellularDevice dev(&fh1); // AT fh1 ref count 1
EXPECT_TRUE(dev.open_network(&fh1));
EXPECT_TRUE(dev.open_network(&fh1)); // AT fh1 ref count 2
EXPECT_TRUE(dev.open_sms(&fh2));
AT_CellularBase_stub::handler_value = AT_CellularBase_stub::handler_at_constructor_value;
EXPECT_TRUE(dev.open_sim(&fh3));
EXPECT_TRUE(dev.open_information(&fh3));
ATHandler_stub::fh_value = &fh1;
EXPECT_TRUE(dev.open_power(&fh1));
ATHandler_stub::fh_value = NULL;
AT_CellularDevice *dev2 = new AT_CellularDevice(&fh1);
EXPECT_TRUE(dev2->open_information(&fh1));
ATHandler *at = dev2->get_at_handler();
EXPECT_TRUE(at->get_ref_count() == 4);
delete dev2;
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);
delete dev2; // AT fh1 2 refs deleted -> ref count 3
EXPECT_TRUE(at->get_ref_count() == 3);
AT_CellularDevice dev3(&fh1);
EXPECT_TRUE(dev3.release_at_handler(at) == NSAPI_ERROR_OK);
EXPECT_TRUE(ATHandler_stub::ref_count == 2);
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);
}
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_open_network)
@ -99,32 +98,6 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_open_sms)
EXPECT_TRUE(sms1 == sms);
}
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_open_power)
{
FileHandle_stub fh1;
AT_CellularDevice dev(&fh1);
CellularPower *pwr = dev.open_power(NULL);
CellularPower *pwr1 = dev.open_power(&fh1);
EXPECT_TRUE(pwr);
EXPECT_TRUE(pwr1);
EXPECT_TRUE(pwr1 == pwr);
}
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_open_sim)
{
FileHandle_stub fh1;
AT_CellularDevice dev(&fh1);
CellularSIM *sim = dev.open_sim(NULL);
CellularSIM *sim1 = dev.open_sim(&fh1);
EXPECT_TRUE(sim);
EXPECT_TRUE(sim1);
EXPECT_TRUE(sim1 == sim);
}
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_open_information)
{
FileHandle_stub fh1;
@ -142,62 +115,26 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_close_network)
{
FileHandle_stub fh1;
AT_CellularDevice dev(&fh1);
ATHandler_stub::ref_count = 0;
EXPECT_TRUE(dev.open_network(&fh1));
AT_CellularBase_stub::handler_value = AT_CellularBase_stub::handler_at_constructor_value;
EXPECT_TRUE(ATHandler_stub::ref_count == 1);
EXPECT_TRUE(ATHandler_stub::ref_count == 2);
dev.close_network();
EXPECT_TRUE(ATHandler_stub::ref_count == kATHandler_destructor_ref_ount);
EXPECT_TRUE(ATHANDLER_REF_COUNT_AT_DESTRUCTOR == kATHandler_destructor_ref_ount);
}
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_close_sms)
{
FileHandle_stub fh1;
AT_CellularDevice dev(&fh1);
ATHandler_stub::ref_count = 0;
EXPECT_TRUE(dev.open_sms(&fh1));
AT_CellularBase_stub::handler_value = AT_CellularBase_stub::handler_at_constructor_value;
EXPECT_TRUE(ATHandler_stub::ref_count == 1);
EXPECT_TRUE(ATHandler_stub::ref_count == 2);
dev.close_sms();
EXPECT_TRUE(ATHandler_stub::ref_count == kATHandler_destructor_ref_ount);
}
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_close_power)
{
FileHandle_stub fh1;
AT_CellularDevice dev(&fh1);
ATHandler_stub::ref_count = 0;
EXPECT_TRUE(dev.open_power(&fh1));
AT_CellularBase_stub::handler_value = AT_CellularBase_stub::handler_at_constructor_value;
EXPECT_TRUE(ATHandler_stub::ref_count == 1);
dev.close_power();
EXPECT_TRUE(ATHandler_stub::ref_count == kATHandler_destructor_ref_ount);
}
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_close_sim)
{
FileHandle_stub fh1;
AT_CellularDevice dev(&fh1);
ATHandler_stub::ref_count = 0;
int ana = 0;
EXPECT_TRUE(dev.open_sim(&fh1));
AT_CellularBase_stub::handler_value = AT_CellularBase_stub::handler_at_constructor_value;
ana = ATHandler_stub::ref_count;
dev.close_sms(); // this should not affect to refcount as it's not opened
EXPECT_TRUE(ATHandler_stub::ref_count == 1);
ana = ATHandler_stub::ref_count;
dev.close_sim();
EXPECT_TRUE(ATHandler_stub::ref_count == kATHandler_destructor_ref_ount);
EXPECT_TRUE(ATHANDLER_REF_COUNT_AT_DESTRUCTOR == kATHandler_destructor_ref_ount);
}
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_close_information)
@ -221,7 +158,7 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_close_information)
AT_CellularBase_stub::handler_value = AT_CellularBase_stub::handler_at_constructor_value;
dev.close_information();
EXPECT_TRUE(ATHandler_stub::ref_count == kATHandler_destructor_ref_ount);
EXPECT_TRUE(ATHANDLER_REF_COUNT_AT_DESTRUCTOR == kATHandler_destructor_ref_ount);
ATHandler_stub::fh_value = NULL;
}
@ -233,19 +170,18 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_set_timeout)
ATHandler_stub::timeout = 0;
ATHandler_stub::default_timeout = false;
// no interfaces open so settings timeout should not change anything
dev.set_timeout(5000);
EXPECT_TRUE(ATHandler_stub::timeout == 0);
EXPECT_TRUE(ATHandler_stub::default_timeout == false);
EXPECT_TRUE(ATHandler_stub::timeout == 5000);
EXPECT_TRUE(ATHandler_stub::default_timeout == true);
EXPECT_TRUE(dev.open_sim(&fh1));
EXPECT_TRUE(ATHandler_stub::ref_count == 1);
EXPECT_TRUE(dev.open_sms(&fh1));
EXPECT_TRUE(ATHandler_stub::ref_count == 2);
dev.set_timeout(5000);
EXPECT_TRUE(ATHandler_stub::timeout == 5000);
EXPECT_TRUE(ATHandler_stub::default_timeout == true);
dev.close_sim();
dev.close_sms();
}
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_modem_debug_on)
@ -254,17 +190,69 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_modem_debug_on)
AT_CellularDevice dev(&fh1);
ATHandler_stub::debug_on = false;
// no interfaces open so debug toggling should not affect
dev.modem_debug_on(true);
EXPECT_TRUE(ATHandler_stub::debug_on == false);
EXPECT_TRUE(ATHandler_stub::debug_on == true);
EXPECT_TRUE(dev.open_sim(&fh1));
EXPECT_TRUE(ATHandler_stub::ref_count == 1);
EXPECT_TRUE(dev.open_sms(&fh1));
EXPECT_TRUE(ATHandler_stub::ref_count == 2);
dev.modem_debug_on(true);
EXPECT_TRUE(ATHandler_stub::debug_on == true);
dev.close_sim();
dev.close_sms();
}
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_init)
{
FileHandle_stub fh1;
AT_CellularDevice dev(&fh1);
EXPECT_EQ(dev.init(), NSAPI_ERROR_OK);
}
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_shutdown)
{
FileHandle_stub fh1;
AT_CellularDevice dev(&fh1);
EXPECT_EQ(dev.shutdown(), NSAPI_ERROR_OK);
}
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_is_ready)
{
EventQueue que;
FileHandle_stub fh1;
ATHandler at(&fh1, que, 0, ",");
AT_CellularDevice dev(&fh1);
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
EXPECT_TRUE(NSAPI_ERROR_OK == dev.is_ready());
}
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_set_power_save_mode)
{
EventQueue que;
FileHandle_stub fh1;
ATHandler at(&fh1, que, 0, ",");
AT_CellularDevice dev(&fh1);
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
EXPECT_TRUE(NSAPI_ERROR_OK == dev.set_power_save_mode(0, 0));
EXPECT_TRUE(NSAPI_ERROR_OK == dev.set_power_save_mode(10, 0));
EXPECT_TRUE(NSAPI_ERROR_OK == dev.set_power_save_mode(912, 0));
EXPECT_TRUE(NSAPI_ERROR_OK == dev.set_power_save_mode(1834, 1834));
EXPECT_TRUE(NSAPI_ERROR_OK == dev.set_power_save_mode(18345, 18345));
EXPECT_TRUE(NSAPI_ERROR_OK == dev.set_power_save_mode(101234, 101234));
EXPECT_TRUE(NSAPI_ERROR_OK == dev.set_power_save_mode(1012345, 1012345));
EXPECT_TRUE(NSAPI_ERROR_OK == dev.set_power_save_mode(39612345, 39612345));
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR;
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == dev.set_power_save_mode(0));
}
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_get_send_delay)
@ -274,20 +262,13 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_get_send_delay)
EXPECT_TRUE(0 == dev.get_send_delay());
}
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_init_module)
{
FileHandle_stub fh1;
AT_CellularDevice dev(&fh1);
EXPECT_TRUE(NSAPI_ERROR_OK == dev.init_module());
}
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_create_delete_context)
{
FileHandle_stub fh1;
AT_CellularDevice *dev = new AT_CellularDevice(&fh1);
ATHandler *at = dev->get_at_handler();
EXPECT_TRUE(at->get_ref_count() == 1);
EXPECT_TRUE(at->get_ref_count() == 2);
EXPECT_TRUE(dev->release_at_handler(at) == NSAPI_ERROR_OK);
CellularContext *ctx = dev->create_context(NULL);
@ -295,12 +276,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() == 1);
EXPECT_TRUE(at->get_ref_count() == 2);
ctx = dev->create_context(NULL);
CellularContext *ctx1 = dev->create_context(&fh1);
EXPECT_TRUE(at->get_ref_count() == 3);
CellularContext *ctx2 = dev->create_context(&fh1);
EXPECT_TRUE(at->get_ref_count() == 4);
CellularContext *ctx2 = dev->create_context(&fh1);
EXPECT_TRUE(at->get_ref_count() == 5);
EXPECT_TRUE(ctx);
EXPECT_TRUE(ctx1);
@ -311,20 +292,20 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_create_delete_context)
EXPECT_TRUE(xx);
dev->delete_context(ctx);
EXPECT_TRUE(at->get_ref_count() == 3);
EXPECT_TRUE(at->get_ref_count() == 4);
dev->delete_context(ctx1);
EXPECT_TRUE(at->get_ref_count() == 2);
EXPECT_TRUE(at->get_ref_count() == 3);
dev->delete_context(NULL);
EXPECT_TRUE(at->get_ref_count() == 2);
EXPECT_TRUE(at->get_ref_count() == 3);
dev->delete_context(ctx2);
EXPECT_TRUE(at->get_ref_count() == 1);
EXPECT_TRUE(at->get_ref_count() == 2);
ctx = dev->create_context(NULL);
EXPECT_TRUE(at->get_ref_count() == 2);
ctx1 = dev->create_context(&fh1);
EXPECT_TRUE(at->get_ref_count() == 3);
ctx2 = dev->create_context(&fh1);
ctx1 = dev->create_context(&fh1);
EXPECT_TRUE(at->get_ref_count() == 4);
ctx2 = dev->create_context(&fh1);
EXPECT_TRUE(at->get_ref_count() == 5);
EXPECT_TRUE(dev->release_at_handler(at) == NSAPI_ERROR_OK);
EXPECT_TRUE(ctx);
EXPECT_TRUE(ctx1);
@ -333,3 +314,78 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_create_delete_context)
delete dev;
}
TEST_F(TestAT_CellularDevice, TestAT_CellularDevice_set_pin)
{
FileHandle_stub fh1;
AT_CellularDevice *dev = new AT_CellularDevice(&fh1);
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
ASSERT_EQ(NSAPI_ERROR_OK, dev->set_pin("12"));
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR;
ASSERT_EQ(NSAPI_ERROR_DEVICE_ERROR, dev->set_pin("12"));
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
ATHandler_stub::read_string_value = (char *)"SIM PIN";
ATHandler_stub::ssize_value = 7;
ASSERT_EQ(NSAPI_ERROR_PARAMETER, dev->set_pin(NULL));
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
ATHandler_stub::read_string_value = (char *)"READY";
ATHandler_stub::ssize_value = 5;
ASSERT_EQ(NSAPI_ERROR_OK, dev->set_pin("12"));
ASSERT_EQ(NSAPI_ERROR_OK, dev->set_pin(NULL));
delete dev;
}
TEST_F(TestAT_CellularDevice, TestAT_CellularDevice_get_sim_state)
{
FileHandle_stub fh1;
AT_CellularDevice *dev = new AT_CellularDevice(&fh1);
CellularDevice::SimState state;
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
ATHandler_stub::ssize_value = -1;
ATHandler_stub::read_string_value = NULL;
ASSERT_EQ(NSAPI_ERROR_OK, dev->get_sim_state(state));
ASSERT_EQ(CellularDevice::SimStateUnknown, state);
ATHandler_stub::read_string_value = (char *)"READY";
ATHandler_stub::ssize_value = 5;
ASSERT_EQ(NSAPI_ERROR_OK, dev->get_sim_state(state));
ASSERT_EQ(CellularDevice::SimStateReady, state);
ATHandler_stub::read_string_value = (char *)"SIM PIN";
ATHandler_stub::ssize_value = 7;
ASSERT_EQ(NSAPI_ERROR_OK, dev->get_sim_state(state));
ASSERT_EQ(CellularDevice::SimStatePinNeeded, state);
ATHandler_stub::read_string_value = (char *)"SIM PUK";
ATHandler_stub::ssize_value = 7;
ASSERT_EQ(NSAPI_ERROR_OK, dev->get_sim_state(state));
ASSERT_EQ(CellularDevice::SimStatePukNeeded, state);
ATHandler_stub::read_string_value = (char *)"SOME CRAP";
ATHandler_stub::ssize_value = 9;
ASSERT_EQ(NSAPI_ERROR_OK, dev->get_sim_state(state));
ASSERT_EQ(CellularDevice::SimStateUnknown, state);
delete dev;
}
static void device_ready_cb()
{
}
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_set_ready_cb)
{
EventQueue que;
FileHandle_stub fh1;
AT_CellularDevice *dev = new AT_CellularDevice(&fh1);
dev->set_ready_cb(&device_ready_cb);
dev->set_ready_cb(0);
}

View File

@ -12,6 +12,7 @@ set(unittest-includes ${unittest-includes}
../features/frameworks/mbed-client-randlib/mbed-client-randlib
../drivers
../hal
../features/netsocket/cellular
)
# Source files
@ -27,12 +28,11 @@ set(unittest-test-sources
stubs/AT_CellularNetwork_stub.cpp
stubs/ATHandler_stub.cpp
stubs/AT_CellularSMS_stub.cpp
stubs/AT_CellularSIM_stub.cpp
stubs/AT_CellularPower_stub.cpp
stubs/AT_CellularInformation_stub.cpp
stubs/CellularUtil_stub.cpp
stubs/AT_CellularBase_stub.cpp
stubs/NetworkInterface_stub.cpp
stubs/NetworkInterfaceDefaults_stub.cpp
stubs/EventQueue_stub.cpp
stubs/FileHandle_stub.cpp
stubs/mbed_assert_stub.c

View File

@ -34,6 +34,10 @@ protected:
void SetUp()
{
ATHandler_stub::read_string_index = kRead_string_table_size;
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
ATHandler_stub::read_string_value = NULL;
ATHandler_stub::ssize_value = 0;
}
void TearDown()
@ -118,6 +122,8 @@ TEST_F(TestAT_CellularInformation, test_AT_CellularInformation_get_revision)
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == aci->get_revision(buf, 8));
EXPECT_TRUE(strlen(buf) == 0);
EXPECT_TRUE(NSAPI_ERROR_PARAMETER == aci->get_revision(NULL, 8));
EXPECT_TRUE(NSAPI_ERROR_PARAMETER == aci->get_revision(buf, 0));
delete aci;
}
@ -152,4 +158,59 @@ TEST_F(TestAT_CellularInformation, test_AT_CellularInformation_get_serial_number
AT_CellularBase_stub::supported_bool = true;
EXPECT_TRUE(NSAPI_ERROR_OK == aci.get_serial_number(buf, 8, CellularInformation::IMEI));
EXPECT_TRUE(strcmp("1234567", buf) == 0);
EXPECT_TRUE(NSAPI_ERROR_PARAMETER == aci.get_serial_number(NULL, 8, CellularInformation::IMEI));
EXPECT_TRUE(NSAPI_ERROR_PARAMETER == aci.get_serial_number(buf, 0, CellularInformation::IMEI));
}
TEST_F(TestAT_CellularInformation, TestAT_CellularInformation_get_imsi)
{
EventQueue eq;
FileHandle_stub fh;
ATHandler ah(&fh, eq, 0, ",");
AT_CellularInformation aci(ah);
char imsi[16];
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
ATHandler_stub::read_string_value = (char *)"123456789012345";
ATHandler_stub::ssize_value = 15;
ASSERT_EQ(NSAPI_ERROR_OK, aci.get_imsi(imsi, sizeof(imsi)));
ASSERT_STREQ(ATHandler_stub::read_string_value, imsi);
ATHandler_stub::read_string_value = NULL;
ATHandler_stub::ssize_value = -1;
ATHandler_stub::read_string_index = -1;
imsi[0] = 0;
ASSERT_EQ(NSAPI_ERROR_DEVICE_ERROR, aci.get_imsi(imsi, sizeof(imsi)));
ASSERT_EQ(strlen(imsi), 0);
ASSERT_EQ(NSAPI_ERROR_PARAMETER, aci.get_imsi(NULL, sizeof(imsi)));
char imsi2[5];
ASSERT_EQ(NSAPI_ERROR_PARAMETER, aci.get_imsi(imsi2, sizeof(imsi2)));
}
TEST_F(TestAT_CellularInformation, TestAT_CellularInformation_get_iccid)
{
EventQueue eq;
FileHandle_stub fh;
ATHandler ah(&fh, eq, 0, ",");
AT_CellularInformation aci(ah);
char buf[16];
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
ATHandler_stub::read_string_value = (char *)"123456789012345";
ATHandler_stub::ssize_value = 15;
ASSERT_EQ(NSAPI_ERROR_OK, aci.get_iccid(buf, 16));
ASSERT_STREQ(ATHandler_stub::read_string_value, buf);
buf[0] = 0;
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR;
ATHandler_stub::read_string_value = NULL;
ATHandler_stub::ssize_value = -1;
ASSERT_EQ(NSAPI_ERROR_DEVICE_ERROR, aci.get_iccid(buf, 16));
ASSERT_EQ(strlen(buf), 0);
ASSERT_EQ(NSAPI_ERROR_PARAMETER, aci.get_iccid(buf, 0));
ASSERT_EQ(NSAPI_ERROR_PARAMETER, aci.get_iccid(NULL, 16));
}

View File

@ -52,13 +52,6 @@ class my_AT_CN : public AT_CellularNetwork {
public:
my_AT_CN(ATHandler &atHandler) : AT_CellularNetwork(atHandler) {}
virtual ~my_AT_CN() {}
virtual AT_CellularNetwork::RegistrationMode has_registration(RegistrationType reg_type)
{
if (reg_type == C_GREG) {
return RegistrationModeDisable;
}
return RegistrationModeEnable;
}
virtual nsapi_error_t set_access_technology_impl(RadioAccessTechnology op_rat)
{
return NSAPI_ERROR_OK;
@ -69,13 +62,6 @@ class my_AT_CNipv6 : public AT_CellularNetwork {
public:
my_AT_CNipv6(ATHandler &atHandler) : AT_CellularNetwork(atHandler) {}
virtual ~my_AT_CNipv6() {}
virtual AT_CellularNetwork::RegistrationMode has_registration(RegistrationType reg_type)
{
if (reg_type == C_GREG) {
return RegistrationModeDisable;
}
return RegistrationModeEnable;
}
virtual nsapi_error_t set_access_technology_impl(RadioAccessTechnology op_rat)
{
return NSAPI_ERROR_OK;
@ -150,32 +136,32 @@ TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_get_registration_params)
ATHandler_stub::read_string_value = NULL;
ATHandler_stub::ssize_value = 0;
// Check get_registration_params without specifying the registration type
EXPECT_TRUE(NSAPI_ERROR_OK == cn.get_registration_params(reg_params_check));
EXPECT_TRUE(reg_params_check._status == CellularNetwork::RegistrationDenied);
EXPECT_TRUE(reg_params_check._act == CellularNetwork::RAT_EGPRS);
EXPECT_TRUE(reg_params_check._cell_id == 305463233);
EXPECT_TRUE(reg_params_check._active_time == 240);
EXPECT_TRUE(reg_params_check._periodic_tau == 70 * 60 * 60);
ASSERT_EQ(NSAPI_ERROR_OK, cn.get_registration_params(reg_params_check));
ASSERT_EQ(reg_params_check._status, CellularNetwork::RegistrationDenied);
ASSERT_EQ(reg_params_check._act, CellularNetwork::RAT_EGPRS);
ASSERT_EQ(reg_params_check._cell_id, 305463233);
ASSERT_EQ(reg_params_check._active_time, 240);
ASSERT_EQ(reg_params_check._periodic_tau, 70 * 60 * 60);
reg_params._status = CellularNetwork::NotRegistered;
reg_params._act = CellularNetwork::RAT_GSM;
reg_params._cell_id = 1;
EXPECT_TRUE(NSAPI_ERROR_OK == cn.get_registration_params(CellularNetwork::C_GREG, reg_params));
EXPECT_TRUE(reg_params._status == CellularNetwork::RegistrationDenied);
EXPECT_TRUE(reg_params._act == CellularNetwork::RAT_EGPRS);
EXPECT_TRUE(reg_params._cell_id == -1);
ASSERT_EQ(NSAPI_ERROR_OK, cn.get_registration_params(CellularNetwork::C_REG, reg_params));
ASSERT_EQ(reg_params._status, CellularNetwork::RegistrationDenied);
ASSERT_EQ(reg_params._act, CellularNetwork::RAT_EGPRS);
ASSERT_EQ(reg_params._cell_id, -1);
my_AT_CN nw(at);
reg_params._status = CellularNetwork::NotRegistered;
reg_params._act = CellularNetwork::RAT_GSM;
EXPECT_TRUE(NSAPI_ERROR_UNSUPPORTED == nw.get_registration_params(CellularNetwork::C_GREG, reg_params));
EXPECT_TRUE(reg_params._status == CellularNetwork::NotRegistered);
EXPECT_TRUE(reg_params._act == CellularNetwork::RAT_GSM);
ASSERT_EQ(NSAPI_ERROR_UNSUPPORTED, nw.get_registration_params(CellularNetwork::C_GREG, reg_params));
ASSERT_EQ(reg_params._status, CellularNetwork::NotRegistered);
ASSERT_EQ(reg_params._act, CellularNetwork::RAT_GSM);
EXPECT_TRUE(NSAPI_ERROR_OK == nw.get_registration_params(CellularNetwork::C_EREG, reg_params));
EXPECT_TRUE(reg_params._status == CellularNetwork::RegistrationDenied);
EXPECT_TRUE(reg_params._act == CellularNetwork::RAT_EGPRS);
ASSERT_EQ(NSAPI_ERROR_OK, nw.get_registration_params(CellularNetwork::C_EREG, reg_params));
ASSERT_EQ(reg_params._status, CellularNetwork::RegistrationDenied);
ASSERT_EQ(reg_params._act, CellularNetwork::RAT_EGPRS);
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR;
reg_params._status = CellularNetwork::NotRegistered;
@ -184,15 +170,15 @@ TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_get_registration_params)
reg_params._active_time = 2;
reg_params._periodic_tau = 3;
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == cn.get_registration_params(CellularNetwork::C_EREG, reg_params));
EXPECT_TRUE(reg_params._status == CellularNetwork::NotRegistered);
EXPECT_TRUE(reg_params._act == CellularNetwork::RAT_UNKNOWN);
ASSERT_EQ(NSAPI_ERROR_DEVICE_ERROR, cn.get_registration_params(CellularNetwork::C_EREG, reg_params));
ASSERT_EQ(reg_params._status, CellularNetwork::NotRegistered);
ASSERT_EQ(reg_params._act, CellularNetwork::RAT_UNKNOWN);
EXPECT_TRUE(reg_params._cell_id == -1 && reg_params._active_time == -1 && reg_params._periodic_tau == -1);
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == cn.get_registration_params(CellularNetwork::C_GREG, reg_params));
EXPECT_TRUE(reg_params._status == CellularNetwork::NotRegistered);
EXPECT_TRUE(reg_params._act == CellularNetwork::RAT_UNKNOWN);
EXPECT_TRUE(reg_params._cell_id == -1);
ASSERT_EQ(NSAPI_ERROR_DEVICE_ERROR, cn.get_registration_params(CellularNetwork::C_REG, reg_params));
ASSERT_EQ(reg_params._status, CellularNetwork::NotRegistered);
ASSERT_EQ(reg_params._act, CellularNetwork::RAT_UNKNOWN);
ASSERT_EQ(reg_params._cell_id, -1);
reg_params._status = CellularNetwork::SearchingNetwork;
reg_params._act = CellularNetwork::RAT_GSM;
@ -304,63 +290,63 @@ TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_set_registration_urc)
AT_CellularNetwork cn(at);
CellularNetwork::RegistrationType type = CellularNetwork::C_EREG;
EXPECT_TRUE(NSAPI_ERROR_OK == cn.set_registration_urc(type, true));
ASSERT_EQ(NSAPI_ERROR_OK, cn.set_registration_urc(type, true));
type = CellularNetwork::C_GREG;
EXPECT_TRUE(NSAPI_ERROR_OK == cn.set_registration_urc(type, true));
ASSERT_EQ(NSAPI_ERROR_UNSUPPORTED, cn.set_registration_urc(type, true));
type = CellularNetwork::C_REG;
EXPECT_TRUE(NSAPI_ERROR_OK == cn.set_registration_urc(type, true));
ASSERT_EQ(NSAPI_ERROR_OK, cn.set_registration_urc(type, true));
my_AT_CN nw(at);
type = CellularNetwork::C_EREG;
EXPECT_TRUE(NSAPI_ERROR_OK == nw.set_registration_urc(type, true));
ASSERT_EQ(NSAPI_ERROR_OK, nw.set_registration_urc(type, true));
type = CellularNetwork::C_GREG;
EXPECT_TRUE(NSAPI_ERROR_UNSUPPORTED == nw.set_registration_urc(type, true));
ASSERT_EQ(NSAPI_ERROR_UNSUPPORTED, nw.set_registration_urc(type, true));
type = CellularNetwork::C_REG;
EXPECT_TRUE(NSAPI_ERROR_OK == nw.set_registration_urc(type, true));
ASSERT_EQ(NSAPI_ERROR_OK, nw.set_registration_urc(type, true));
type = CellularNetwork::C_EREG;
EXPECT_TRUE(NSAPI_ERROR_OK == cn.set_registration_urc(type, false));
ASSERT_EQ(NSAPI_ERROR_OK, cn.set_registration_urc(type, false));
type = CellularNetwork::C_GREG;
EXPECT_TRUE(NSAPI_ERROR_OK == cn.set_registration_urc(type, false));
ASSERT_EQ(NSAPI_ERROR_UNSUPPORTED, cn.set_registration_urc(type, false));
type = CellularNetwork::C_REG;
EXPECT_TRUE(NSAPI_ERROR_OK == cn.set_registration_urc(type, false));
ASSERT_EQ(NSAPI_ERROR_OK, cn.set_registration_urc(type, false));
type = CellularNetwork::C_EREG;
EXPECT_TRUE(NSAPI_ERROR_OK == nw.set_registration_urc(type, false));
ASSERT_EQ(NSAPI_ERROR_OK, nw.set_registration_urc(type, false));
type = CellularNetwork::C_GREG;
EXPECT_TRUE(NSAPI_ERROR_UNSUPPORTED == nw.set_registration_urc(type, false));
ASSERT_EQ(NSAPI_ERROR_UNSUPPORTED, nw.set_registration_urc(type, false));
type = CellularNetwork::C_REG;
EXPECT_TRUE(NSAPI_ERROR_OK == nw.set_registration_urc(type, false));
ASSERT_EQ(NSAPI_ERROR_OK, nw.set_registration_urc(type, false));
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR;
type = CellularNetwork::C_EREG;
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == cn.set_registration_urc(type, true));
ASSERT_EQ(NSAPI_ERROR_DEVICE_ERROR, cn.set_registration_urc(type, true));
type = CellularNetwork::C_GREG;
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == cn.set_registration_urc(type, true));
ASSERT_EQ(NSAPI_ERROR_UNSUPPORTED, cn.set_registration_urc(type, true));
type = CellularNetwork::C_REG;
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == cn.set_registration_urc(type, true));
ASSERT_EQ(NSAPI_ERROR_DEVICE_ERROR, cn.set_registration_urc(type, true));
type = CellularNetwork::C_EREG;
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == nw.set_registration_urc(type, true));
ASSERT_EQ(NSAPI_ERROR_DEVICE_ERROR, nw.set_registration_urc(type, true));
type = CellularNetwork::C_GREG;
EXPECT_TRUE(NSAPI_ERROR_UNSUPPORTED == nw.set_registration_urc(type, true));
ASSERT_EQ(NSAPI_ERROR_UNSUPPORTED, nw.set_registration_urc(type, true));
type = CellularNetwork::C_REG;
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == nw.set_registration_urc(type, true));
ASSERT_EQ(NSAPI_ERROR_DEVICE_ERROR, nw.set_registration_urc(type, true));
type = CellularNetwork::C_EREG;
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == cn.set_registration_urc(type, false));
ASSERT_EQ(NSAPI_ERROR_DEVICE_ERROR, cn.set_registration_urc(type, false));
type = CellularNetwork::C_GREG;
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == cn.set_registration_urc(type, false));
ASSERT_EQ(NSAPI_ERROR_UNSUPPORTED, cn.set_registration_urc(type, false));
type = CellularNetwork::C_REG;
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == cn.set_registration_urc(type, false));
ASSERT_EQ(NSAPI_ERROR_DEVICE_ERROR, cn.set_registration_urc(type, false));
type = CellularNetwork::C_EREG;
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == nw.set_registration_urc(type, false));
ASSERT_EQ(NSAPI_ERROR_DEVICE_ERROR, nw.set_registration_urc(type, false));
type = CellularNetwork::C_GREG;
EXPECT_TRUE(NSAPI_ERROR_UNSUPPORTED == nw.set_registration_urc(type, false));
ASSERT_EQ(NSAPI_ERROR_UNSUPPORTED, nw.set_registration_urc(type, false));
type = CellularNetwork::C_REG;
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == nw.set_registration_urc(type, false));
ASSERT_EQ(NSAPI_ERROR_DEVICE_ERROR, nw.set_registration_urc(type, false));
}
TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_set_attach)
@ -486,8 +472,8 @@ TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_scan_plmn)
ATHandler_stub::bool_value = false;
EXPECT_TRUE(NSAPI_ERROR_UNSUPPORTED == cn.set_access_technology(CellularNetwork::RAT_UTRAN));
EXPECT_TRUE(NSAPI_ERROR_OK == cn.scan_plmn(ops, c));
EXPECT_TRUE(c == 0);
EXPECT_TRUE(ops.get_head() == NULL);
EXPECT_TRUE(c == 1);
EXPECT_TRUE(ops.get_head() != NULL);
}
TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_set_ciot_optimization_config)
@ -498,53 +484,49 @@ TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_set_ciot_optimization_con
AT_CellularNetwork cn(at);
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
EXPECT_TRUE(NSAPI_ERROR_OK == cn.set_ciot_optimization_config(CellularNetwork::SUPPORTED_UE_OPT_NO_SUPPORT, CellularNetwork::PREFERRED_UE_OPT_NO_PREFERENCE));
EXPECT_TRUE(NSAPI_ERROR_OK == cn.set_ciot_optimization_config(CellularNetwork::CIOT_OPT_NO_SUPPORT, CellularNetwork::PREFERRED_UE_OPT_NO_PREFERENCE, NULL));
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR;
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == cn.set_ciot_optimization_config(CellularNetwork::SUPPORTED_UE_OPT_NO_SUPPORT, CellularNetwork::PREFERRED_UE_OPT_NO_PREFERENCE));
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == cn.set_ciot_optimization_config(CellularNetwork::CIOT_OPT_NO_SUPPORT, CellularNetwork::PREFERRED_UE_OPT_NO_PREFERENCE, NULL));
}
TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_get_ciot_optimization_config)
TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_get_ciot_ue_optimization_config)
{
EventQueue que;
FileHandle_stub fh1;
ATHandler at(&fh1, que, 0, ",");
AT_CellularNetwork cn(at);
CellularNetwork::Supported_UE_Opt sup = CellularNetwork::SUPPORTED_UE_OPT_NO_SUPPORT;
CellularNetwork::Preferred_UE_Opt pref = CellularNetwork::PREFERRED_UE_OPT_NO_PREFERENCE;
CellularNetwork::CIoT_Supported_Opt sup = CellularNetwork::CIOT_OPT_NO_SUPPORT;
CellularNetwork::CIoT_Preferred_UE_Opt pref = CellularNetwork::PREFERRED_UE_OPT_NO_PREFERENCE;
ATHandler_stub::int_value = 1;
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
EXPECT_TRUE(NSAPI_ERROR_OK == cn.get_ciot_optimization_config(sup, pref));
EXPECT_TRUE(sup == CellularNetwork::SUPPORTED_UE_OPT_CONTROL_PLANE);
EXPECT_TRUE(NSAPI_ERROR_OK == cn.get_ciot_ue_optimization_config(sup, pref));
EXPECT_TRUE(sup == CellularNetwork::CIOT_OPT_CONTROL_PLANE);
EXPECT_TRUE(pref == CellularNetwork::PREFERRED_UE_OPT_CONTROL_PLANE);
sup = CellularNetwork::SUPPORTED_UE_OPT_NO_SUPPORT;
sup = CellularNetwork::CIOT_OPT_NO_SUPPORT;
pref = CellularNetwork::PREFERRED_UE_OPT_NO_PREFERENCE;
ATHandler_stub::int_value = 1;
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR;
ATHandler_stub::nsapi_error_ok_counter = 0;
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == cn.get_ciot_optimization_config(sup, pref));
EXPECT_TRUE(sup == CellularNetwork::SUPPORTED_UE_OPT_NO_SUPPORT);
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == cn.get_ciot_ue_optimization_config(sup, pref));
EXPECT_TRUE(sup == CellularNetwork::CIOT_OPT_NO_SUPPORT);
EXPECT_TRUE(pref == CellularNetwork::PREFERRED_UE_OPT_NO_PREFERENCE);
}
TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_get_extended_signal_quality)
TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_get_ciot_network_optimization_config)
{
EventQueue que;
FileHandle_stub fh1;
ATHandler at(&fh1, que, 0, ",");
AT_CellularNetwork cn(at);
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR;
int rx = -1, be = -1, rs = -1, ec = -1, rsrq = -1, rsrp = -1;
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == cn.get_extended_signal_quality(rx, be, rs, ec, rsrq, rsrp));
EXPECT_TRUE(rx == -1 && be == -1 && rs == -1 && ec == -1 && rsrq == -1 && rsrp == -1);
ATHandler_stub::int_value = 5;
CellularNetwork::CIoT_Supported_Opt sup = CellularNetwork::CIOT_OPT_NO_SUPPORT;
ATHandler_stub::int_value = 1;
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
EXPECT_TRUE(NSAPI_ERROR_OK == cn.get_extended_signal_quality(rx, be, rs, ec, rsrq, rsrp));
EXPECT_TRUE(rx == 5 && be == 5 && rs == 5 && ec == 5 && rsrq == 5 && rsrp == 5);
EXPECT_TRUE(NSAPI_ERROR_OK == cn.get_ciot_network_optimization_config(sup));
EXPECT_TRUE(sup == CellularNetwork::CIOT_OPT_MAX);
}
TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_get_signal_quality)
@ -556,13 +538,14 @@ TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_get_signal_quality)
AT_CellularNetwork cn(at);
int rs = -1, ber = -1;
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR;
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == cn.get_signal_quality(rs, ber));
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == cn.get_signal_quality(rs, &ber));
EXPECT_TRUE(rs == -1 && ber == -1);
ATHandler_stub::int_value = 1;
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
EXPECT_TRUE(NSAPI_ERROR_OK == cn.get_signal_quality(rs, ber));
EXPECT_TRUE(rs == -111 && ber == 1);
EXPECT_TRUE(NSAPI_ERROR_OK == cn.get_signal_quality(rs, &ber));
EXPECT_EQ(rs, -111);
EXPECT_EQ(ber, 1);
}
TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_get_3gpp_error)
@ -684,3 +667,16 @@ TEST_F(TestAT_CellularNetwork, test_get_connection_status)
EXPECT_TRUE(NSAPI_STATUS_DISCONNECTED == cn.get_connection_status());
}
TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_set_receive_period)
{
EventQueue que;
FileHandle_stub fh1;
ATHandler at(&fh1, que, 0, ",");
AT_CellularNetwork cn(at);
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
EXPECT_TRUE(NSAPI_ERROR_OK == cn.set_receive_period(1, CellularNetwork::EDRXUTRAN_Iu_mode, 3));
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR;
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == cn.set_receive_period(1, CellularNetwork::EDRXUTRAN_Iu_mode, 3));
}

View File

@ -1,201 +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 "gtest/gtest.h"
#include <string.h>
#include "AT_CellularNetwork.h"
#include "EventQueue.h"
#include "ATHandler.h"
#include "AT_CellularPower.h"
#include "FileHandle_stub.h"
#include "ATHandler_stub.h"
using namespace mbed;
using namespace events;
// AStyle ignored as the definition is not clear due to preprocessor usage
// *INDENT-OFF*
class TestAT_CellularPower : public testing::Test {
protected:
void SetUp() {
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
}
void TearDown() {
}
};
// *INDENT-ON*
static void device_ready_cb()
{
}
TEST_F(TestAT_CellularPower, Create)
{
EventQueue que;
FileHandle_stub fh1;
ATHandler at(&fh1, que, 0, ",");
AT_CellularPower *pow = new AT_CellularPower(at);
EXPECT_TRUE(pow != NULL);
delete pow;
}
TEST_F(TestAT_CellularPower, test_AT_CellularPower_on)
{
EventQueue que;
FileHandle_stub fh1;
ATHandler at(&fh1, que, 0, ",");
AT_CellularPower pow(at);
EXPECT_TRUE(NSAPI_ERROR_UNSUPPORTED == pow.on());
}
TEST_F(TestAT_CellularPower, test_AT_CellularPower_off)
{
EventQueue que;
FileHandle_stub fh1;
ATHandler at(&fh1, que, 0, ",");
AT_CellularPower pow(at);
EXPECT_TRUE(NSAPI_ERROR_UNSUPPORTED == pow.off());
}
TEST_F(TestAT_CellularPower, test_AT_CellularPower_set_at_mode)
{
EventQueue que;
FileHandle_stub fh1;
ATHandler at(&fh1, que, 0, ",");
AT_CellularPower pow(at);
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
EXPECT_TRUE(NSAPI_ERROR_OK == pow.set_at_mode());
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR;
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == pow.set_at_mode());
}
TEST_F(TestAT_CellularPower, test_AT_CellularPower_set_power_level)
{
EventQueue que;
FileHandle_stub fh1;
ATHandler at(&fh1, que, 0, ",");
AT_CellularPower pow(at);
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
EXPECT_TRUE(NSAPI_ERROR_OK == pow.set_power_level(6));
EXPECT_TRUE(NSAPI_ERROR_OK == pow.set_power_level(1, 1));
EXPECT_TRUE(NSAPI_ERROR_OK == pow.set_power_level(1, 0));
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR;
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == pow.set_power_level(6));
}
TEST_F(TestAT_CellularPower, test_AT_CellularPower_reset)
{
EventQueue que;
FileHandle_stub fh1;
ATHandler at(&fh1, que, 0, ",");
AT_CellularPower pow(at);
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
EXPECT_TRUE(NSAPI_ERROR_OK == pow.reset());
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR;
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == pow.reset());
}
TEST_F(TestAT_CellularPower, test_AT_CellularPower_opt_power_save_mode)
{
EventQueue que;
FileHandle_stub fh1;
ATHandler at(&fh1, que, 0, ",");
AT_CellularPower pow(at);
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
EXPECT_TRUE(NSAPI_ERROR_OK == pow.opt_power_save_mode(0, 0));
EXPECT_TRUE(NSAPI_ERROR_OK == pow.opt_power_save_mode(10, 0));
EXPECT_TRUE(NSAPI_ERROR_OK == pow.opt_power_save_mode(912, 0));
EXPECT_TRUE(NSAPI_ERROR_OK == pow.opt_power_save_mode(1834, 1834));
EXPECT_TRUE(NSAPI_ERROR_OK == pow.opt_power_save_mode(18345, 18345));
EXPECT_TRUE(NSAPI_ERROR_OK == pow.opt_power_save_mode(101234, 101234));
EXPECT_TRUE(NSAPI_ERROR_OK == pow.opt_power_save_mode(1012345, 1012345));
EXPECT_TRUE(NSAPI_ERROR_OK == pow.opt_power_save_mode(39612345, 39612345));
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR;
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == pow.opt_power_save_mode(0, 0));
}
TEST_F(TestAT_CellularPower, test_AT_CellularPower_opt_receive_period)
{
EventQueue que;
FileHandle_stub fh1;
ATHandler at(&fh1, que, 0, ",");
AT_CellularPower pow(at);
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
EXPECT_TRUE(NSAPI_ERROR_OK == pow.opt_receive_period(1, CellularPower::EDRXUTRAN_Iu_mode, 3));
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR;
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == pow.opt_receive_period(1, CellularPower::EDRXUTRAN_Iu_mode, 3));
}
TEST_F(TestAT_CellularPower, test_AT_CellularPower_is_device_ready)
{
EventQueue que;
FileHandle_stub fh1;
ATHandler at(&fh1, que, 0, ",");
AT_CellularPower pow(at);
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_AUTH_FAILURE;
EXPECT_TRUE(NSAPI_ERROR_AUTH_FAILURE == pow.is_device_ready());
}
TEST_F(TestAT_CellularPower, test_AT_CellularPower_set_device_ready_urc_cb)
{
EventQueue que;
FileHandle_stub fh1;
ATHandler at(&fh1, que, 0, ",");
AT_CellularPower pow(at);
EXPECT_TRUE(NSAPI_ERROR_UNSUPPORTED == pow.set_device_ready_urc_cb(&device_ready_cb));
EXPECT_TRUE(NSAPI_ERROR_UNSUPPORTED == pow.set_device_ready_urc_cb(NULL));
}
TEST_F(TestAT_CellularPower, test_AT_CellularPower_remove_device_ready_urc_cb)
{
EventQueue que;
FileHandle_stub fh1;
ATHandler at(&fh1, que, 0, ",");
AT_CellularPower pow(at);
EXPECT_TRUE(NSAPI_ERROR_UNSUPPORTED == pow.set_device_ready_urc_cb(&device_ready_cb));
pow.remove_device_ready_urc_cb(NULL);
pow.remove_device_ready_urc_cb(&device_ready_cb);
}

View File

@ -1,28 +0,0 @@
####################
# UNIT TESTS
####################
# Add test specific include paths
set(unittest-includes ${unittest-includes}
features/cellular/framework/common/util
../features/cellular/framework/common
../features/cellular/framework/AT
../features/frameworks/mbed-client-randlib/mbed-client-randlib
)
# Source files
set(unittest-sources
../features/cellular/framework/AT/AT_CellularPower.cpp
)
# Test files
set(unittest-test-sources
features/cellular/framework/AT/at_cellularpower/at_cellularpowertest.cpp
stubs/ATHandler_stub.cpp
stubs/AT_CellularBase_stub.cpp
stubs/EventQueue_stub.cpp
stubs/FileHandle_stub.cpp
stubs/CellularUtil_stub.cpp
stubs/mbed_assert_stub.c
)

View File

@ -1,204 +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 "gtest/gtest.h"
#include "ATHandler_stub.h"
#include <string.h>
#include "AT_CellularNetwork.h"
#include "EventQueue.h"
#include "ATHandler.h"
#include "AT_CellularSIM.h"
#include "FileHandle_stub.h"
#include "CellularLog.h"
#include "ATHandler_stub.h"
using namespace mbed;
using namespace events;
// AStyle ignored as the definition is not clear due to preprocessor usage
// *INDENT-OFF*
class TestAT_CellularSIM : public testing::Test {
protected:
void SetUp()
{
ATHandler_stub::read_string_index = kRead_string_table_size;
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
ATHandler_stub::read_string_value = NULL;
ATHandler_stub::ssize_value = 0;
}
void TearDown()
{
}
};
// *INDENT-ON*
TEST_F(TestAT_CellularSIM, Create)
{
EventQueue que;
FileHandle_stub fh1;
ATHandler at(&fh1, que, 0, ",");
AT_CellularSIM *sim = new AT_CellularSIM(at);
EXPECT_TRUE(sim != NULL);
delete sim;
}
TEST_F(TestAT_CellularSIM, test_AT_CellularSIM_set_pin)
{
EventQueue que;
FileHandle_stub fh1;
ATHandler at(&fh1, que, 0, ",");
AT_CellularSIM sim(at);
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
EXPECT_TRUE(NSAPI_ERROR_OK == sim.set_pin("12"));
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR;
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == sim.set_pin("12"));
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
ATHandler_stub::read_string_value = (char *)"READY";
ATHandler_stub::ssize_value = 5;
EXPECT_TRUE(NSAPI_ERROR_OK == sim.set_pin("12"));
EXPECT_TRUE(NSAPI_ERROR_OK == sim.set_pin(NULL));
}
TEST_F(TestAT_CellularSIM, test_AT_CellularSIM_change_pin)
{
EventQueue que;
FileHandle_stub fh1;
ATHandler at(&fh1, que, 0, ",");
AT_CellularSIM sim(at);
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
EXPECT_TRUE(NSAPI_ERROR_OK == sim.change_pin("12", "34"));
EXPECT_TRUE(NSAPI_ERROR_OK == sim.change_pin(NULL, "34"));
EXPECT_TRUE(NSAPI_ERROR_OK == sim.change_pin("12", NULL));
EXPECT_TRUE(NSAPI_ERROR_OK == sim.change_pin(NULL, NULL));
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR;
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == sim.change_pin("12", "34"));
}
TEST_F(TestAT_CellularSIM, test_AT_CellularSIM_set_pin_query)
{
EventQueue que;
FileHandle_stub fh1;
ATHandler at(&fh1, que, 0, ",");
AT_CellularSIM sim(at);
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
EXPECT_TRUE(NSAPI_ERROR_OK == sim.set_pin_query("12", true));
EXPECT_TRUE(NSAPI_ERROR_OK == sim.set_pin_query(NULL, true));
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
EXPECT_TRUE(NSAPI_ERROR_OK == sim.set_pin_query("12", false));
EXPECT_TRUE(NSAPI_ERROR_OK == sim.set_pin_query(NULL, false));
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR;
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == sim.set_pin_query("12", false));
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == sim.set_pin_query("12", true));
}
TEST_F(TestAT_CellularSIM, test_AT_CellularSIM_get_sim_state)
{
EventQueue que;
FileHandle_stub fh1;
ATHandler at(&fh1, que, 0, ",");
AT_CellularSIM sim(at);
CellularSIM::SimState state;
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
ATHandler_stub::ssize_value = -1;
ATHandler_stub::read_string_value = NULL;
EXPECT_TRUE(NSAPI_ERROR_OK == sim.get_sim_state(state));
EXPECT_TRUE(CellularSIM::SimStateUnknown == state);
ATHandler_stub::read_string_value = (char *)"READY";
ATHandler_stub::ssize_value = 5;
EXPECT_TRUE(NSAPI_ERROR_OK == sim.get_sim_state(state));
EXPECT_TRUE(CellularSIM::SimStateReady == state);
ATHandler_stub::read_string_value = (char *)"SIM PIN";
ATHandler_stub::ssize_value = 7;
EXPECT_TRUE(NSAPI_ERROR_OK == sim.get_sim_state(state));
EXPECT_TRUE(CellularSIM::SimStatePinNeeded == state);
ATHandler_stub::read_string_value = (char *)"SIM PUK";
ATHandler_stub::ssize_value = 7;
EXPECT_TRUE(NSAPI_ERROR_OK == sim.get_sim_state(state));
EXPECT_TRUE(CellularSIM::SimStatePukNeeded == state);
ATHandler_stub::read_string_value = (char *)"SOME CRAP";
ATHandler_stub::ssize_value = 9;
EXPECT_TRUE(NSAPI_ERROR_OK == sim.get_sim_state(state));
EXPECT_TRUE(CellularSIM::SimStateUnknown == state);
}
TEST_F(TestAT_CellularSIM, test_AT_CellularSIM_get_imsi)
{
EventQueue que;
FileHandle_stub fh1;
ATHandler at(&fh1, que, 0, ",");
char imsi[16];
AT_CellularSIM sim(at);
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
ATHandler_stub::read_string_value = (char *)"123456789012345";
ATHandler_stub::ssize_value = 15;
EXPECT_TRUE(NSAPI_ERROR_OK == sim.get_imsi(imsi));
EXPECT_TRUE(strcmp(ATHandler_stub::read_string_value, imsi) == 0);
ATHandler_stub::read_string_value = NULL;
ATHandler_stub::ssize_value = -1;
ATHandler_stub::read_string_index = -1;
imsi[0] = 0;
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == sim.get_imsi(imsi));
EXPECT_TRUE(strlen(imsi) == 0);
EXPECT_TRUE(NSAPI_ERROR_PARAMETER == sim.get_imsi(NULL));
// this would fail as get_imsi should take another param which is the size of the buffer which we could use for validation.
// Now we have improved documentation that that the given imsi buffer size must be over 15.
//char imsi2[5];
//EXPECT_TRUE(NSAPI_ERROR_PARAMETER == sim.get_imsi(imsi2));
}
TEST_F(TestAT_CellularSIM, test_AT_CellularSIM_get_iccid)
{
EventQueue que;
FileHandle_stub fh1;
ATHandler at(&fh1, que, 0, ",");
char buf[16];
AT_CellularSIM sim(at);
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
ATHandler_stub::read_string_value = (char *)"123456789012345";
ATHandler_stub::ssize_value = 15;
EXPECT_TRUE(NSAPI_ERROR_OK == sim.get_iccid(buf, 16));
EXPECT_TRUE(strcmp(ATHandler_stub::read_string_value, buf) == 0);
buf[0] = 0;
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR;
ATHandler_stub::read_string_value = NULL;
ATHandler_stub::ssize_value = -1;
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == sim.get_iccid(buf, 16));
EXPECT_TRUE(strlen(buf) == 0);
}

View File

@ -1,29 +0,0 @@
####################
# UNIT TESTS
####################
# Add test specific include paths
set(unittest-includes ${unittest-includes}
features/cellular/framework/common/util
../features/cellular/framework/common
../features/cellular/framework/AT
../features/frameworks/mbed-client-randlib/mbed-client-randlib
)
# Source files
set(unittest-sources
../features/cellular/framework/AT/AT_CellularSIM.cpp
)
# Test files
set(unittest-test-sources
features/cellular/framework/AT/at_cellularsim/at_cellularsimtest.cpp
stubs/ATHandler_stub.cpp
stubs/AT_CellularBase_stub.cpp
stubs/EventQueue_stub.cpp
stubs/FileHandle_stub.cpp
stubs/CellularUtil_stub.cpp
stubs/us_ticker_stub.cpp
stubs/mbed_assert_stub.c
)

View File

@ -71,14 +71,14 @@ TEST_F(TestAT_CellularSMS, test_AT_CellularSMS_initialize)
AT_CellularSMS sms(at);
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_AUTH_FAILURE;
EXPECT_TRUE(NSAPI_ERROR_NO_MEMORY == sms.initialize(CellularSMS::CellularSMSMmodeText));
EXPECT_EQ(NSAPI_ERROR_AUTH_FAILURE, sms.initialize(CellularSMS::CellularSMSMmodeText));
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
EXPECT_TRUE(NSAPI_ERROR_OK == sms.initialize(CellularSMS::CellularSMSMmodeText));
EXPECT_EQ(NSAPI_ERROR_OK, sms.initialize(CellularSMS::CellularSMSMmodeText));
sms.set_sms_callback(&my_callback);
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
EXPECT_TRUE(NSAPI_ERROR_OK == sms.initialize(CellularSMS::CellularSMSMmodeText));
EXPECT_EQ(NSAPI_ERROR_OK, sms.initialize(CellularSMS::CellularSMSMmodeText));
ATHandler_stub::call_immediately = false;
}

View File

@ -112,7 +112,6 @@ TEST_F(TestATHandler, test_ATHandler_list)
EXPECT_TRUE(at1->close() == NSAPI_ERROR_OK);
EXPECT_TRUE(at2->get_ref_count() == 1);
EXPECT_TRUE(at2->close() == NSAPI_ERROR_OK);
EXPECT_TRUE(at1->close() == NSAPI_ERROR_PARAMETER);
ATHandler::set_at_timeout_list(1000, false);
ATHandler::set_debug_list(false);
@ -160,7 +159,7 @@ TEST_F(TestATHandler, test_ATHandler_set_urc_handler)
at.set_urc_handler(ch, cb);
//THIS IS NOT same callback in find_urc_handler???
EXPECT_TRUE(NSAPI_ERROR_OK == at.set_urc_handler(ch, cb));
at.set_urc_handler(ch, cb);
}
TEST_F(TestATHandler, test_ATHandler_remove_urc_handler)
@ -174,8 +173,7 @@ TEST_F(TestATHandler, test_ATHandler_remove_urc_handler)
mbed::Callback<void()> cb(&urc_callback);
at.set_urc_handler(ch, cb);
//This does nothing!!!
at.remove_urc_handler(ch);
at.set_urc_handler(ch, 0);
}
TEST_F(TestATHandler, test_ATHandler_get_last_error)
@ -996,10 +994,10 @@ TEST_F(TestATHandler, test_ATHandler_resp_start)
filehandle_stub_table = table9;
filehandle_stub_table_pos = 0;
at.set_urc_handler("urc: ", &urc_callback);
at.set_urc_handler("urc: ", NULL);
at.resp_start();
// Match URC consumes to CRLF -> nothing to read after that -> ERROR
EXPECT_TRUE(at.get_last_error() == NSAPI_ERROR_DEVICE_ERROR);
EXPECT_EQ(at.get_last_error(), NSAPI_ERROR_OK);
char table10[] = "urc: info\r\ngarbage\r\nprefix: info\r\nOK\r\n\0";
at.flush();

View File

@ -138,8 +138,7 @@ TEST_F(Testutil, prefer_ipv6)
TEST_F(Testutil, separate_ip_addresses)
{
char *s = (char *)malloc(128);
char s[128] = {'\0'};
char ip[64] = {0};
char subnet[64] = {0};

View File

@ -21,7 +21,6 @@
#include "FileHandle_stub.h"
#include "myCellularDevice.h"
#include "CellularStateMachine_stub.h"
#include "CellularSIM.h"
using namespace mbed;
@ -54,7 +53,7 @@ TEST_F(TestCellularDevice, test_create_delete)
dev = NULL;
CellularDevice *dev1 = CellularDevice::get_default_instance();
EXPECT_TRUE(dev1);
EXPECT_FALSE(dev1);
}
TEST_F(TestCellularDevice, test_set_sim_pin)
@ -185,11 +184,11 @@ TEST_F(TestCellularDevice, test_get_context_list)
CellularContext *ctx = dev->create_context();
EXPECT_TRUE(dev->get_context_list());
delete dev;
dev = NULL;
dev = new myCellularDevice(&fh1);
EXPECT_TRUE(dev);
EXPECT_FALSE(dev->get_context_list());
delete dev;
}
TEST_F(TestCellularDevice, test_stop)
@ -221,7 +220,7 @@ TEST_F(TestCellularDevice, test_cellular_callback)
dev->cellular_callback((nsapi_event_t)CellularDeviceReady, (intptr_t)&data);
dev->set_sim_pin("1234");
data.status_data = CellularSIM::SimStatePinNeeded;
data.status_data = CellularDevice::SimStatePinNeeded;
dev->cellular_callback((nsapi_event_t)CellularSIMStatusChanged, (intptr_t)&data);
CellularContext *ctx = dev->create_context();
@ -229,3 +228,15 @@ TEST_F(TestCellularDevice, test_cellular_callback)
delete dev;
}
TEST_F(TestCellularDevice, test_shutdown)
{
FileHandle_stub fh1;
CellularDevice *dev = new myCellularDevice(&fh1);
EXPECT_TRUE(dev);
CellularStateMachine_stub::nsapi_error_value = NSAPI_ERROR_OK;
ASSERT_EQ(dev->shutdown(), NSAPI_ERROR_OK);
delete dev;
}

View File

@ -8,6 +8,7 @@ set(unittest-includes ${unittest-includes}
/features/cellular/framework/device/cellulardevice
../features/cellular/framework/device
../features/cellular/framework/common
../features/netsocket/cellular
)
# Source files
@ -30,6 +31,7 @@ set(unittest-test-sources
stubs/AT_CellularContext_stub.cpp
stubs/Semaphore_stub.cpp
stubs/NetworkInterface_stub.cpp
stubs/NetworkInterfaceDefaults_stub.cpp
)
# defines

View File

@ -0,0 +1,416 @@
/*
* 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 "gtest/gtest.h"
#include <string.h>
#include "CellularDevice.h"
#include "AT_CellularDevice_stub.h"
#include "FileHandle_stub.h"
#include "AT_CellularNetwork_stub.h"
#include "myCellularDevice.h"
#include "Thread_stub.h"
#include "cmsis_os2.h"
#include "equeue_stub.h"
using namespace mbed;
enum UT_CellularState {
UT_STATE_INIT = 0,
UT_STATE_POWER_ON,
UT_STATE_DEVICE_READY,
UT_STATE_SIM_PIN,
UT_STATE_REGISTERING_NETWORK,
UT_STATE_MANUAL_REGISTERING_NETWORK,
UT_STATE_ATTACHING_NETWORK,
UT_STATE_MAX_FSM_STATE
};
// AStyle ignored as the definition is not clear due to preprocessor usage
// *INDENT-OFF*
class TestCellularStateMachine : public testing::Test {
protected:
void SetUp()
{
Thread_stub::osStatus_value = osOK;
}
void TearDown()
{
}
};
static void cellular_callback(nsapi_event_t ev, intptr_t ptr)
{
}
namespace mbed {
class UT_CellularStateMachine {
public:
UT_CellularStateMachine() {
_state_machine = NULL;
}
~UT_CellularStateMachine() {
delete _state_machine;
_state_machine = NULL;
}
CellularStateMachine *create_state_machine(CellularDevice &device, events::EventQueue &queue)
{
_state_machine = new CellularStateMachine(device, queue);
return _state_machine;
}
void delete_state_machine() {
delete _state_machine;
_state_machine = NULL;
}
void set_cellular_callback(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb)
{
_state_machine->set_cellular_callback(status_cb);
}
nsapi_error_t start_dispatch()
{
return _state_machine->start_dispatch();
}
nsapi_error_t run_to_power_on()
{
return _state_machine->run_to_state(CellularStateMachine::STATE_POWER_ON);
}
nsapi_error_t run_to_device_ready()
{
return _state_machine->run_to_state(CellularStateMachine::STATE_DEVICE_READY);
}
nsapi_error_t run_to_device_sim_ready()
{
return _state_machine->run_to_state(CellularStateMachine::STATE_SIM_PIN);
}
nsapi_error_t run_to_device_registered()
{
return _state_machine->run_to_state(CellularStateMachine::STATE_REGISTERING_NETWORK);
}
nsapi_error_t run_to_device_attached()
{
return _state_machine->run_to_state(CellularStateMachine::STATE_ATTACHING_NETWORK);
}
void stop()
{
_state_machine->stop();
}
void set_sim_pin(const char *sim_pin)
{
_state_machine->set_sim_pin(sim_pin);
}
void set_retry_timeout_array(uint16_t *timeout, int array_len)
{
_state_machine->set_retry_timeout_array(timeout, array_len);
}
void set_plmn(const char *plmn)
{
_state_machine->set_plmn(plmn);
}
bool get_current_status(UT_CellularState &current_state, UT_CellularState &target_state)
{
return _state_machine->get_current_status((CellularStateMachine::CellularState&)current_state,
(CellularStateMachine::CellularState&)target_state);
}
void cellular_event_changed(nsapi_event_t ev, intptr_t ptr)
{
_state_machine->cellular_event_changed(ev, ptr);
}
void reset()
{
_state_machine->reset();
}
void ready_urc_cb()
{
_state_machine->device_ready_cb();
}
CellularStateMachine * _state_machine;
};
}
TEST_F(TestCellularStateMachine, test_create_delete)
{
UT_CellularStateMachine ut;
FileHandle_stub fh1;
CellularDevice *dev = new myCellularDevice(&fh1);
EXPECT_TRUE(dev);
CellularStateMachine *stm = ut.create_state_machine(*dev, *dev->get_queue());
EXPECT_TRUE(stm);
ut.delete_state_machine();
delete dev;
dev = NULL;
}
TEST_F(TestCellularStateMachine, test_setters)
{
UT_CellularStateMachine ut;
FileHandle_stub fh1;
CellularDevice *dev = new myCellularDevice(&fh1);
EXPECT_TRUE(dev);
CellularStateMachine *stm = ut.create_state_machine(*dev, *dev->get_queue());
EXPECT_TRUE(stm);
ut.set_cellular_callback(&cellular_callback);
ut.set_sim_pin(NULL);
ut.set_sim_pin("1234");
ut.set_plmn(NULL);
ut.set_plmn("12345");
uint16_t timeout[20] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
ut.set_retry_timeout_array(timeout, 10); // test max length
ut.set_retry_timeout_array(timeout, 20); // test too big array
ut.set_retry_timeout_array(0, 10); // null array
ut.delete_state_machine();
delete dev;
dev = NULL;
}
TEST_F(TestCellularStateMachine, test_start_dispatch)
{
UT_CellularStateMachine ut;
FileHandle_stub fh1;
CellularDevice *dev = new myCellularDevice(&fh1);
EXPECT_TRUE(dev);
CellularStateMachine *stm = ut.create_state_machine(*dev, *dev->get_queue());
EXPECT_TRUE(stm);
nsapi_error_t err = ut.start_dispatch();
ASSERT_EQ(NSAPI_ERROR_OK, err);
ut.delete_state_machine();
Thread_stub::osStatus_value = osErrorNoMemory;
stm = ut.create_state_machine(*dev, *dev->get_queue());
EXPECT_TRUE(stm);
err = ut.start_dispatch();
ASSERT_EQ(NSAPI_ERROR_NO_MEMORY, err);
ut.delete_state_machine();
delete dev;
dev = NULL;
}
TEST_F(TestCellularStateMachine, test_stop)
{
UT_CellularStateMachine ut;
FileHandle_stub fh1;
CellularDevice *dev = new AT_CellularDevice(&fh1);
EXPECT_TRUE(dev);
CellularStateMachine *stm = ut.create_state_machine(*dev, *dev->get_queue());
EXPECT_TRUE(stm);
ut.stop(); // nothing created, run through
ut.delete_state_machine();
stm = ut.create_state_machine(*dev, *dev->get_queue());
EXPECT_TRUE(stm);
nsapi_error_t err = ut.start_dispatch();
ASSERT_EQ(NSAPI_ERROR_OK, err);
ut.stop(); // thread is created, now stop will delete it
ut.delete_state_machine();
stm = ut.create_state_machine(*dev, *dev->get_queue());
EXPECT_TRUE(stm);
err = ut.start_dispatch();
ASSERT_EQ(NSAPI_ERROR_OK, err);
ut.set_cellular_callback(&cellular_callback);
struct equeue_event ptr;
equeue_stub.void_ptr = &ptr;
equeue_stub.call_cb_immediately = true;
ASSERT_EQ(NSAPI_ERROR_OK, ut.run_to_power_on());
ut.stop(); // thread and power are created, now stop will delete them
ut.delete_state_machine();
stm = ut.create_state_machine(*dev, *dev->get_queue());
EXPECT_TRUE(stm);
err = ut.start_dispatch();
ASSERT_EQ(NSAPI_ERROR_OK, err);
ut.set_cellular_callback(&cellular_callback);
ASSERT_EQ(NSAPI_ERROR_OK, ut.run_to_device_ready());
ut.stop(); // thread and network are created, now stop will delete them
ut.delete_state_machine();
delete dev;
dev = NULL;
}
TEST_F(TestCellularStateMachine, test_run_to_state)
{
UT_CellularStateMachine ut;
FileHandle_stub fh1;
CellularDevice *dev = new AT_CellularDevice(&fh1);
EXPECT_TRUE(dev);
CellularStateMachine *stm = ut.create_state_machine(*dev, *dev->get_queue());
EXPECT_TRUE(stm);
nsapi_error_t err = ut.start_dispatch();
ASSERT_EQ(NSAPI_ERROR_OK, err);
struct equeue_event ptr;
equeue_stub.void_ptr = 0;
equeue_stub.call_cb_immediately = false;
ASSERT_EQ(NSAPI_ERROR_NO_MEMORY, ut.run_to_power_on());
ut.reset();
equeue_stub.void_ptr = &ptr;
equeue_stub.call_cb_immediately = true;
ut.set_cellular_callback(&cellular_callback);
ASSERT_EQ(NSAPI_ERROR_OK, ut.run_to_power_on());
UT_CellularState current_state;
UT_CellularState target_state;
(void)ut.get_current_status(current_state, target_state);
ASSERT_EQ(UT_STATE_POWER_ON, current_state);
ASSERT_EQ(UT_STATE_POWER_ON, target_state);
ut.reset();
ASSERT_EQ(NSAPI_ERROR_OK, ut.run_to_device_ready());
(void)ut.get_current_status(current_state, target_state);
ASSERT_EQ(UT_STATE_DEVICE_READY, current_state);
ASSERT_EQ(UT_STATE_DEVICE_READY, target_state);
ut.ready_urc_cb();
ut.reset();
ASSERT_EQ(NSAPI_ERROR_OK, ut.run_to_device_ready());
(void)ut.get_current_status(current_state, target_state);
ASSERT_EQ(UT_STATE_DEVICE_READY, current_state);
ASSERT_EQ(UT_STATE_DEVICE_READY, target_state);
ut.reset();
ASSERT_EQ(NSAPI_ERROR_OK, ut.run_to_device_ready());
(void)ut.get_current_status(current_state, target_state);
ASSERT_EQ(UT_STATE_DEVICE_READY, current_state);
ASSERT_EQ(UT_STATE_DEVICE_READY, target_state);
ut.reset();
ASSERT_EQ(NSAPI_ERROR_OK, ut.run_to_device_ready());
(void)ut.get_current_status(current_state, target_state);
ASSERT_EQ(UT_STATE_DEVICE_READY, current_state);
ASSERT_EQ(UT_STATE_DEVICE_READY, target_state);
ut.reset();
AT_CellularDevice_stub::init_module_failure_count = 1;
AT_CellularNetwork_stub::set_registration_urc_fail_counter = 4;
ASSERT_EQ(NSAPI_ERROR_OK, ut.run_to_device_sim_ready());
(void) ut.get_current_status(current_state, target_state);
ASSERT_EQ(UT_STATE_SIM_PIN, current_state);
ASSERT_EQ(UT_STATE_SIM_PIN, target_state);
ut.reset();
AT_CellularDevice_stub::pin_needed = true;
ASSERT_EQ(NSAPI_ERROR_OK, ut.run_to_device_sim_ready());
(void)ut.get_current_status(current_state, target_state);
ASSERT_EQ(UT_STATE_SIM_PIN, current_state);
ASSERT_EQ(UT_STATE_SIM_PIN, target_state);
ut.reset();
ut.set_sim_pin("1234");
AT_CellularDevice_stub::pin_needed = true;
ASSERT_EQ(NSAPI_ERROR_OK, ut.run_to_device_sim_ready());
(void)ut.get_current_status(current_state, target_state);
ASSERT_EQ(UT_STATE_SIM_PIN, current_state);
ASSERT_EQ(UT_STATE_SIM_PIN, target_state);
ut.reset();
ut.set_sim_pin("1234");
AT_CellularDevice_stub::pin_needed = true;
AT_CellularDevice_stub::set_pin_failure_count = 1;
AT_CellularDevice_stub::get_sim_failure_count = 1;
ASSERT_EQ(NSAPI_ERROR_OK, ut.run_to_device_sim_ready());
(void)ut.get_current_status(current_state, target_state);
ASSERT_EQ(UT_STATE_SIM_PIN, current_state);
ASSERT_EQ(UT_STATE_SIM_PIN, target_state);
ut.reset();
cell_callback_data_t data;
data.status_data = CellularNetwork::RegisteredHomeNetwork;
AT_CellularNetwork_stub::get_registration_params_fail_counter = 10;
ASSERT_EQ(NSAPI_ERROR_OK, ut.run_to_device_registered());
(void)ut.get_current_status(current_state, target_state);
ASSERT_EQ(UT_STATE_REGISTERING_NETWORK, current_state);
ASSERT_EQ(UT_STATE_REGISTERING_NETWORK, target_state);
ut.cellular_event_changed((nsapi_event_t)CellularRegistrationStatusChanged, (intptr_t)&data);
ut.reset();
// manual registering
ut.set_plmn("12345");
ASSERT_EQ(NSAPI_ERROR_OK, ut.run_to_device_registered());
(void)ut.get_current_status(current_state, target_state);
ASSERT_EQ(UT_STATE_MANUAL_REGISTERING_NETWORK, current_state);
ASSERT_EQ(UT_STATE_MANUAL_REGISTERING_NETWORK, target_state);
ut.cellular_event_changed((nsapi_event_t)CellularRegistrationStatusChanged, (intptr_t)&data);
ut.reset();
ut.set_plmn(0);
ASSERT_EQ(NSAPI_ERROR_OK, ut.run_to_device_attached());
(void)ut.get_current_status(current_state, target_state);
ASSERT_EQ(UT_STATE_ATTACHING_NETWORK, current_state);
ASSERT_EQ(UT_STATE_ATTACHING_NETWORK, target_state);
ut.reset();
ut.delete_state_machine();
delete dev;
dev = NULL;
}

View File

@ -0,0 +1,45 @@
####################
# UNIT TESTS
####################
# Add test specific include paths
set(unittest-includes ${unittest-includes}
/features/cellular/framework/device/cellularstatemachine
../features/cellular/framework/device
../features/cellular/framework/common
../features/netsocket/cellular
)
# Source files
set(unittest-sources
../features/cellular/framework/device/CellularStateMachine.cpp
../features/cellular/framework/AT/ATHandler_factory.cpp
)
# Test files
set(unittest-test-sources
features/cellular/framework/device/cellularstatemachine/cellularstatemachinetest.cpp
stubs/FileHandle_stub.cpp
stubs/CellularDevice_stub.cpp
stubs/EventQueue_stub.cpp
stubs/mbed_assert_stub.c
stubs/UARTSerial_stub.cpp
stubs/SerialBase_stub.cpp
stubs/ATHandler_stub.cpp
stubs/AT_CellularNetwork_stub.cpp
stubs/AT_CellularBase_stub.cpp
stubs/AT_CellularContext_stub.cpp
stubs/AT_CellularDevice_stub.cpp
stubs/Semaphore_stub.cpp
stubs/NetworkInterface_stub.cpp
stubs/NetworkInterfaceDefaults_stub.cpp
stubs/Thread_stub.cpp
stubs/Mutex_stub.cpp
stubs/EventQueue_stub.cpp
stubs/equeue_stub.c
)
# defines
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DMDMRTS=PTC0 -DMDMCTS=PTC1 -DMDMTXD=NC -DMDMRXD=NC -DMBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE=115200 -DCELLULAR_DEVICE=myCellularDevice -DDEVICE_SERIAL_FC=1")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMDMRTS=PTC0 -DMDMCTS=PTC1 -DMDMTXD=NC -DMDMRXD=NC -DMBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE=115200 -DCELLULAR_DEVICE=myCellularDevice -DDEVICE_SERIAL_FC=1")

View File

@ -33,5 +33,6 @@ set(unittest-test-sources
stubs/stoip4_stub.c
stubs/ip4tos_stub.c
stubs/NetworkStack_stub.cpp
stubs/NetworkInterfaceDefaults_stub.cpp
stubs/SocketStats_Stub.cpp
)

View File

@ -25,5 +25,6 @@ set(unittest-test-sources
stubs/nsapi_dns_stub.cpp
stubs/EventFlags_stub.cpp
features/netsocket/NetworkInterface/test_NetworkInterface.cpp
stubs/NetworkInterfaceDefaults_stub.cpp
stubs/SocketStats_Stub.cpp
)

View File

@ -0,0 +1,156 @@
/*
* 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 "gtest/gtest.h"
#include "features/netsocket/cellular/CellularNonIPSocket.h"
#include "CellularContext_stub.h"
using namespace mbed;
// Control the rtos EventFlags stub. See EventFlags_stub.cpp
extern std::list<uint32_t> eventFlagsStubNextRetval;
static bool callback_is_called;
static void my_callback()
{
callback_is_called = true;
}
class TestCellularNonIPSocket : public testing::Test {
protected:
CellularNonIPSocket *socket;
ControlPlane_netif_stub *cp_netif;
CellularContext_stub cellular_context;
nsapi_size_t dataSize;
char dataBuf[10];
virtual void SetUp()
{
socket = new CellularNonIPSocket();
cp_netif = NULL;
dataSize = 10;
}
virtual void TearDown()
{
delete socket;
}
};
TEST_F(TestCellularNonIPSocket, open_null_cp_netif)
{
EXPECT_EQ(socket->open(static_cast<ControlPlane_netif *>(NULL)), NSAPI_ERROR_PARAMETER);
}
TEST_F(TestCellularNonIPSocket, open_null_context)
{
EXPECT_EQ(socket->open(static_cast<CellularContext *>(NULL)), NSAPI_ERROR_PARAMETER);
}
TEST_F(TestCellularNonIPSocket, open_context)
{
EXPECT_EQ(socket->open((CellularContext *)&cellular_context), NSAPI_ERROR_OK);
}
TEST_F(TestCellularNonIPSocket, open_cp_netif)
{
cp_netif = cellular_context.get_cp_netif();
EXPECT_EQ(socket->open((ControlPlane_netif *)cp_netif), NSAPI_ERROR_OK);
}
TEST_F(TestCellularNonIPSocket, open_twice)
{
EXPECT_EQ(socket->open((CellularContext *)&cellular_context), NSAPI_ERROR_OK);
EXPECT_EQ(socket->open((CellularContext *)&cellular_context), NSAPI_ERROR_PARAMETER);
}
TEST_F(TestCellularNonIPSocket, close)
{
socket->open((CellularContext *)&cellular_context);
EXPECT_EQ(socket->close(), NSAPI_ERROR_OK);
}
TEST_F(TestCellularNonIPSocket, close_no_open)
{
EXPECT_EQ(socket->close(), NSAPI_ERROR_NO_SOCKET);
}
TEST_F(TestCellularNonIPSocket, sigio)
{
callback_is_called = false;
socket->open((CellularContext *)&cellular_context);
socket->sigio(mbed::callback(my_callback));
socket->close(); // Trigger event;
EXPECT_EQ(callback_is_called, true);
}
/* send */
TEST_F(TestCellularNonIPSocket, send_no_open)
{
EXPECT_EQ(socket->send((char *)dataBuf, dataSize), NSAPI_ERROR_NO_SOCKET);
}
TEST_F(TestCellularNonIPSocket, send_error_would_block)
{
socket->open((CellularContext *)&cellular_context);
cp_netif = cellular_context.get_cp_netif();
cp_netif->return_value = NSAPI_ERROR_WOULD_BLOCK;
eventFlagsStubNextRetval.push_back(osFlagsError); // Break the wait loop
EXPECT_EQ(socket->send(dataBuf, dataSize), NSAPI_ERROR_WOULD_BLOCK);
}
TEST_F(TestCellularNonIPSocket, send_error_other)
{
socket->open((CellularContext *)&cellular_context);
cp_netif = cellular_context.get_cp_netif();
cp_netif->return_value = NSAPI_ERROR_NO_MEMORY;
EXPECT_EQ(socket->send(dataBuf, dataSize), NSAPI_ERROR_NO_MEMORY);
}
TEST_F(TestCellularNonIPSocket, send_error_no_timeout)
{
socket->open((CellularContext *)&cellular_context);
cp_netif = cellular_context.get_cp_netif();
cp_netif->return_value = NSAPI_ERROR_WOULD_BLOCK;
socket->set_blocking(false);
EXPECT_EQ(socket->send(dataBuf, dataSize), NSAPI_ERROR_WOULD_BLOCK);
}
TEST_F(TestCellularNonIPSocket, send)
{
socket->open((CellularContext *)&cellular_context);
cp_netif = cellular_context.get_cp_netif();
cp_netif->return_value = dataSize;
EXPECT_EQ(socket->send(dataBuf, dataSize), dataSize);
}
TEST_F(TestCellularNonIPSocket, recv)
{
EXPECT_EQ(socket->recv(&dataBuf, dataSize), NSAPI_ERROR_NO_SOCKET);
socket->open((CellularContext *)&cellular_context);
cp_netif = cellular_context.get_cp_netif();
cp_netif->return_value = 100;
EXPECT_EQ(socket->recv(&dataBuf, dataSize), 100);
cp_netif->return_value = NSAPI_ERROR_WOULD_BLOCK;
eventFlagsStubNextRetval.push_back(0);
eventFlagsStubNextRetval.push_back(osFlagsError); // Break the wait loop
EXPECT_EQ(socket->recv(&dataBuf, dataSize), NSAPI_ERROR_WOULD_BLOCK);
}

View File

@ -0,0 +1,22 @@
####################
# UNIT TESTS
####################
# Add test specific include paths
set(unittest-includes ${unittest-includes}
../features/netsocket/cellular
)
set(unittest-sources
../features/netsocket/cellular/CellularNonIPSocket.cpp
)
set(unittest-test-sources
features/netsocket/cellular/CellularNonIPSocket/test_CellularNonIPSocket.cpp
stubs/NetworkInterface_stub.cpp
stubs/NetworkInterfaceDefaults_stub.cpp
stubs/NetworkStack_stub.cpp
stubs/EventFlags_stub.cpp
stubs/Mutex_stub.cpp
)

View File

@ -51,11 +51,11 @@ int ATHandler_stub::int_count = kRead_int_table_size;
bool ATHandler_stub::process_oob_urc = false;
int ATHandler_stub::read_string_index = kRead_string_table_size;
const char *ATHandler_stub::read_string_table[kRead_string_table_size];
const char *ATHandler_stub::read_string_table[kRead_string_table_size] = {'\0'};
int ATHandler_stub::resp_stop_success_count = kResp_stop_count_default;
int ATHandler_stub::urc_amount = 0;
mbed::Callback<void()> ATHandler_stub::callback[kATHandler_urc_table_max_size];
char *ATHandler_stub::urc_string_table[kATHandler_urc_table_max_size];
char *ATHandler_stub::urc_string_table[kATHandler_urc_table_max_size] = {'\0'};
ATHandler::ATHandler(FileHandle *fh, EventQueue &queue, uint32_t timeout, const char *output_delimiter, uint16_t send_delay) :
_nextATHandler(0),
@ -121,7 +121,7 @@ void ATHandler::set_file_handle(FileHandle *fh)
{
}
nsapi_error_t ATHandler::set_urc_handler(const char *urc, mbed::Callback<void()> cb)
void ATHandler::set_urc_handler(const char *urc, mbed::Callback<void()> cb)
{
if (ATHandler_stub::urc_amount < kATHandler_urc_table_max_size) {
ATHandler_stub::callback[ATHandler_stub::urc_amount] = cb;
@ -138,7 +138,6 @@ nsapi_error_t ATHandler::set_urc_handler(const char *urc, mbed::Callback<void()>
if (ATHandler_stub::call_immediately) {
cb();
}
return ATHandler_stub::nsapi_error_value;
}
void ATHandler::remove_urc_handler(const char *prefix)

View File

@ -26,11 +26,13 @@
#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 = -909;
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;

View File

@ -16,10 +16,8 @@
*/
#include "nsapi_types.h"
#include "AT_CellularBase.h"
#include "AT_CellularBase_stub.h"
#include "AT_CellularNetwork.h"
using namespace mbed;
ATHandler *AT_CellularBase_stub::handler_value = NULL;
@ -43,7 +41,17 @@ device_err_t AT_CellularBase::get_device_error() const
return AT_CellularBase_stub::device_err_value;
}
bool AT_CellularBase::is_supported(SupportedFeature feature)
intptr_t AT_CellularBase::get_property(CellularProperty key)
{
if (key == PROPERTY_C_GREG) {
return AT_CellularNetwork::RegistrationModeDisable;
} else if (key == PROPERTY_C_REG || key == PROPERTY_C_EREG) {
return AT_CellularNetwork::RegistrationModeEnable;
} else if (key == PROPERTY_AT_CGAUTH) {
return true;
} else if (key == PROPERTY_IPV4_PDP_TYPE) {
return true;
}
return AT_CellularBase_stub::supported_bool;
}

View File

@ -15,7 +15,7 @@
* limitations under the License.
*/
#include "ATHandler.h"
#include "AT_CellularBase.h"
namespace AT_CellularBase_stub {
extern mbed::ATHandler *handler_value;

View File

@ -19,12 +19,12 @@
using namespace mbed;
AT_CellularContext::AT_CellularContext(ATHandler &at, CellularDevice *device, const char *apn) :
AT_CellularBase(at), _ip_stack_type_requested(DEFAULT_STACK), _is_connected(false), _is_blocking(true),
_current_op(OP_INVALID), _device(device), _nw(0), _fh(0)
AT_CellularContext::AT_CellularContext(ATHandler &at, CellularDevice *device, const char *apn, bool cp_req, bool nonip_req) :
AT_CellularBase(at), _is_blocking(true), _is_connected(false),
_current_op(OP_INVALID), _device(device), _nw(0), _fh(0), _cp_req(cp_req), _nonip_req(nonip_req), _cp_in_use(false)
{
_stack = NULL;
_ip_stack_type = DEFAULT_STACK;
_pdp_type = DEFAULT_PDP_TYPE;
_authentication_type = CellularContext::CHAP;
_connect_status = NSAPI_STATUS_DISCONNECTED;
_is_context_active = false;
@ -36,12 +36,21 @@ AT_CellularContext::AT_CellularContext(ATHandler &at, CellularDevice *device, co
_cid = -1;
_new_context_set = false;
_next = NULL;
_cp_netif = NULL;
}
AT_CellularContext::~AT_CellularContext()
{
}
void AT_CellularContext::set_file_handle(UARTSerial *serial, PinName dcd_pin, bool active_high)
{
}
void AT_CellularContext::enable_hup(bool enable)
{
}
void AT_CellularContext::set_file_handle(FileHandle *fh)
{
}
@ -137,19 +146,23 @@ const char *AT_CellularContext::get_gateway()
return NULL;
}
bool AT_CellularContext::stack_type_supported(nsapi_ip_stack_t stack_type)
AT_CellularBase::CellularProperty AT_CellularContext::pdp_type_t_to_cellular_property(pdp_type_t pdp_type)
{
return true;
AT_CellularBase::CellularProperty prop = PROPERTY_IPV4_PDP_TYPE;
if (pdp_type == IPV6_PDP_TYPE) {
prop = PROPERTY_IPV6_PDP_TYPE;
} else if (pdp_type == IPV4V6_PDP_TYPE) {
prop = PROPERTY_IPV4V6_PDP_TYPE;
} else if (pdp_type == NON_IP_PDP_TYPE) {
prop = PROPERTY_NON_IP_PDP_TYPE;
}
return prop;
}
nsapi_ip_stack_t AT_CellularContext::get_stack_type()
pdp_type_t AT_CellularContext::string_to_pdp_type(const char *pdp_type)
{
return IPV4V6_STACK;
}
nsapi_ip_stack_t AT_CellularContext::string_to_stack_type(const char *pdp_type)
{
return IPV4V6_STACK;
return IPV4V6_PDP_TYPE;
}
// PDP Context handling
@ -230,3 +243,30 @@ void AT_CellularContext::cellular_callback(nsapi_event_t ev, intptr_t ptr)
void AT_CellularContext::call_network_cb(nsapi_connection_status_t status)
{
}
ControlPlane_netif *AT_CellularContext::get_cp_netif()
{
return NULL;
}
nsapi_error_t AT_CellularContext::activate_non_ip_context()
{
return NSAPI_ERROR_OK;
}
nsapi_error_t AT_CellularContext::setup_control_plane_opt()
{
return NSAPI_ERROR_OK;
}
void AT_CellularContext::deactivate_ip_context()
{
}
void AT_CellularContext::deactivate_non_ip_context()
{
}
void AT_CellularContext::set_disconnect()
{
}

View File

@ -15,22 +15,30 @@
* limitations under the License.
*/
#include "AT_CellularDevice.h"
#include "AT_CellularDevice_stub.h"
#include "AT_CellularNetwork.h"
#include "AT_CellularContext.h"
#include "ATHandler.h"
const int DEFAULT_AT_TIMEOUT = 1000;
using namespace mbed;
int AT_CellularDevice_stub::failure_count = 0;
nsapi_error_t AT_CellularDevice_stub::nsapi_error_value = 0;
int AT_CellularDevice_stub::init_module_failure_count = 0;
int AT_CellularDevice_stub::set_pin_failure_count = 0;
int AT_CellularDevice_stub::get_sim_failure_count = 0;
bool AT_CellularDevice_stub::pin_needed = false;
AT_CellularDevice::AT_CellularDevice(FileHandle *fh) : CellularDevice(fh), _network(0), _sms(0),
_sim(0), _power(0), _information(0), _context_list(0), _default_timeout(DEFAULT_AT_TIMEOUT),
_modem_debug_on(false)
_information(0), _context_list(0), _default_timeout(DEFAULT_AT_TIMEOUT), _modem_debug_on(false)
{
}
AT_CellularDevice::~AT_CellularDevice()
{
delete _network;
}
ATHandler *AT_CellularDevice::get_at_handler(FileHandle *fileHandle)
@ -52,19 +60,28 @@ nsapi_error_t AT_CellularDevice::release_at_handler(ATHandler *at_handler)
}
}
CellularContext *create_context(FileHandle *fh = NULL, const char *apn = MBED_CONF_NSAPI_DEFAULT_CELLULAR_APN)
CellularContext *AT_CellularDevice::create_context(UARTSerial *serial, const char *const apn, PinName dcd_pin,
bool active_high, bool cp_req, bool nonip_req)
{
}
CellularContext *create_context(FileHandle *fh, const char *apn)
{
}
void delete_context(CellularContext *context)
{
}
CellularNetwork *AT_CellularDevice::open_network(FileHandle *fh)
{
return new AT_CellularNetwork(*ATHandler::get_instance(fh, _queue, _default_timeout, "\r", get_send_delay(), _modem_debug_on));
_network = new AT_CellularNetwork(*ATHandler::get_instance(fh,
_queue,
_default_timeout,
"\r",
get_send_delay(),
_modem_debug_on));
return _network;
}
CellularSMS *AT_CellularDevice::open_sms(FileHandle *fh)
@ -72,16 +89,6 @@ CellularSMS *AT_CellularDevice::open_sms(FileHandle *fh)
return NULL;
}
CellularSIM *AT_CellularDevice::open_sim(FileHandle *fh)
{
return NULL;
}
CellularPower *AT_CellularDevice::open_power(FileHandle *fh)
{
return NULL;
}
CellularInformation *AT_CellularDevice::open_information(FileHandle *fh)
{
return NULL;
@ -89,20 +96,15 @@ CellularInformation *AT_CellularDevice::open_information(FileHandle *fh)
void AT_CellularDevice::close_network()
{
delete _network;
_network = NULL;
}
void AT_CellularDevice::close_sms()
{
}
void AT_CellularDevice::close_power()
{
}
void AT_CellularDevice::close_sim()
{
}
void AT_CellularDevice::close_information()
{
}
@ -112,24 +114,25 @@ CellularContext *AT_CellularDevice::get_context_list() const
return NULL;
}
CellularContext *AT_CellularDevice::create_context(FileHandle *fh, const char *apn)
CellularContext *AT_CellularDevice::create_context(FileHandle *fh, const char *apn, bool cp_req, bool nonip_req)
{
return NULL;
}
AT_CellularContext *AT_CellularDevice::create_context_impl(ATHandler &at, const char *apn)
AT_CellularContext *AT_CellularDevice::create_context_impl(ATHandler &at, const char *apn, bool cp_req, bool nonip_req)
{
return NULL;
}
void AT_CellularDevice::delete_context(CellularContext *context)
{
}
AT_CellularNetwork *AT_CellularDevice::open_network_impl(ATHandler &at)
{
return new AT_CellularNetwork(at);
_network = new AT_CellularNetwork(at);
return _network;
}
AT_CellularSMS *AT_CellularDevice::open_sms_impl(ATHandler &at)
@ -137,16 +140,6 @@ AT_CellularSMS *AT_CellularDevice::open_sms_impl(ATHandler &at)
return NULL;
}
AT_CellularPower *AT_CellularDevice::open_power_impl(ATHandler &at)
{
return NULL;
}
AT_CellularSIM *AT_CellularDevice::open_sim_impl(ATHandler &at)
{
return NULL;
}
AT_CellularInformation *AT_CellularDevice::open_information_impl(ATHandler &at)
{
return NULL;
@ -168,7 +161,84 @@ void AT_CellularDevice::modem_debug_on(bool on)
}
nsapi_error_t AT_CellularDevice::init_module()
nsapi_error_t AT_CellularDevice::is_ready()
{
if (AT_CellularDevice_stub::init_module_failure_count) {
AT_CellularDevice_stub::init_module_failure_count--;
return NSAPI_ERROR_DEVICE_ERROR;
}
return AT_CellularDevice_stub::nsapi_error_value;
}
void AT_CellularDevice::set_ready_cb(mbed::Callback<void()> callback)
{
}
nsapi_error_t AT_CellularDevice::set_power_save_mode(int periodic_time, int active_time)
{
return NSAPI_ERROR_UNSUPPORTED;
}
nsapi_error_t AT_CellularDevice::init()
{
if (AT_CellularDevice_stub::init_module_failure_count) {
AT_CellularDevice_stub::init_module_failure_count--;
return NSAPI_ERROR_DEVICE_ERROR;
}
return AT_CellularDevice_stub::nsapi_error_value;
}
nsapi_error_t AT_CellularDevice::shutdown()
{
if (AT_CellularDevice_stub::init_module_failure_count) {
AT_CellularDevice_stub::init_module_failure_count--;
return NSAPI_ERROR_DEVICE_ERROR;
}
return AT_CellularDevice_stub::nsapi_error_value;
}
nsapi_error_t AT_CellularDevice::set_pin(const char *sim_pin)
{
if (AT_CellularDevice_stub::set_pin_failure_count) {
AT_CellularDevice_stub::set_pin_failure_count--;
return NSAPI_ERROR_DEVICE_ERROR;
}
return AT_CellularDevice_stub::nsapi_error_value;
}
nsapi_error_t AT_CellularDevice::get_sim_state(SimState &state)
{
if (AT_CellularDevice_stub::get_sim_failure_count) {
AT_CellularDevice_stub::get_sim_failure_count--;
return NSAPI_ERROR_DEVICE_ERROR;
}
if (AT_CellularDevice_stub::pin_needed) {
AT_CellularDevice_stub::pin_needed = false;
state = SimStatePinNeeded;
} else {
state = SimStateReady;
}
return AT_CellularDevice_stub::nsapi_error_value;
}
nsapi_error_t AT_CellularDevice::hard_power_on()
{
return NSAPI_ERROR_OK;
}
nsapi_error_t AT_CellularDevice::hard_power_off()
{
return NSAPI_ERROR_OK;
}
nsapi_error_t AT_CellularDevice::soft_power_on()
{
return NSAPI_ERROR_OK;
}
nsapi_error_t AT_CellularDevice::soft_power_off()
{
return NSAPI_ERROR_OK;
}

View File

@ -14,26 +14,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef AT_CELLULARDEVICE_STUB_H_
#define AT_CELLULARDEVICE_STUB_H_
#ifndef UBLOX_AT_CELLULARPOWER_H_
#define UBLOX_AT_CELLULARPOWER_H_
#include "AT_CellularDevice.h"
#include "AT_CellularPower.h"
namespace AT_CellularDevice_stub {
extern int failure_count;
extern nsapi_error_t nsapi_error_value;
extern int init_module_failure_count;
extern int set_pin_failure_count;
extern int get_sim_failure_count;
extern bool pin_needed;
}
namespace mbed {
class UBLOX_AT_CellularPower : public AT_CellularPower {
public:
UBLOX_AT_CellularPower(ATHandler &atHandler);
virtual ~UBLOX_AT_CellularPower();
public: //from CellularPower
virtual nsapi_error_t on();
virtual nsapi_error_t off();
};
} // namespace mbed
#endif // UBLOX_AT_CELLULARPOWER_H_
#endif /* AT_CELLULARDEVICE_STUB_H_ */

View File

@ -47,3 +47,13 @@ nsapi_error_t AT_CellularInformation::get_serial_number(char *buf, size_t buf_si
{
return NSAPI_ERROR_OK;
}
nsapi_error_t AT_CellularInformation::get_imsi(char *imsi, size_t buf_size)
{
return NSAPI_ERROR_OK;
}
nsapi_error_t AT_CellularInformation::get_iccid(char *buf, size_t buf_size)
{
return NSAPI_ERROR_OK;
}

View File

@ -15,7 +15,7 @@
* limitations under the License.
*/
#include "AT_CellularNetwork.h"
#include "AT_CellularNetwork_stub.h"
#include "CellularNetwork.h"
#include "CellularUtil.h"
#include "CellularLog.h"
@ -25,6 +25,13 @@
using namespace mbed;
using namespace mbed_cellular_util;
nsapi_error_t AT_CellularNetwork_stub::nsapi_error_value = 0;
int AT_CellularNetwork_stub::fail_counter = 0;
int AT_CellularNetwork_stub::set_registration_urc_fail_counter = 0;
int AT_CellularNetwork_stub::get_registration_params_fail_counter = 0;
AT_CellularNetwork::AT_CellularNetwork(ATHandler &atHandler) : AT_CellularBase(atHandler)
{
}
@ -44,6 +51,10 @@ nsapi_connection_status_t AT_CellularNetwork::get_connection_status() const
nsapi_error_t AT_CellularNetwork::set_registration_urc(RegistrationType type, bool urc_on)
{
if (AT_CellularNetwork_stub::set_registration_urc_fail_counter) {
AT_CellularNetwork_stub::set_registration_urc_fail_counter--;
return NSAPI_ERROR_DEVICE_ERROR;
}
return NSAPI_ERROR_OK;
}
@ -60,6 +71,12 @@ nsapi_error_t AT_CellularNetwork::set_registration(const char *plmn)
nsapi_error_t AT_CellularNetwork::get_registration_params(RegistrationType type, registration_params_t &reg_params)
{
if (AT_CellularNetwork_stub::get_registration_params_fail_counter) {
AT_CellularNetwork_stub::get_registration_params_fail_counter--;
return NSAPI_ERROR_DEVICE_ERROR;
}
reg_params._status = CellularNetwork::RegisteredHomeNetwork;
return NSAPI_ERROR_OK;
}
@ -68,11 +85,6 @@ nsapi_error_t AT_CellularNetwork::get_registration_params(registration_params_t
return NSAPI_ERROR_OK;
}
AT_CellularNetwork::RegistrationMode AT_CellularNetwork::has_registration(RegistrationType reg_type)
{
return RegistrationModeDisable;
}
nsapi_error_t AT_CellularNetwork::set_attach()
{
return NSAPI_ERROR_OK;
@ -108,24 +120,25 @@ nsapi_error_t AT_CellularNetwork::scan_plmn(operList_t &operators, int &opsCount
return NSAPI_ERROR_OK;
}
nsapi_error_t AT_CellularNetwork::set_ciot_optimization_config(Supported_UE_Opt supported_opt,
Preferred_UE_Opt preferred_opt)
nsapi_error_t AT_CellularNetwork::set_ciot_optimization_config(CIoT_Supported_Opt supported_opt,
CIoT_Preferred_UE_Opt preferred_opt,
Callback<void(CIoT_Supported_Opt)> network_support_cb)
{
return NSAPI_ERROR_OK;
}
nsapi_error_t AT_CellularNetwork::get_ciot_optimization_config(Supported_UE_Opt &supported_opt,
Preferred_UE_Opt &preferred_opt)
nsapi_error_t AT_CellularNetwork::get_ciot_ue_optimization_config(CIoT_Supported_Opt &supported_opt,
CIoT_Preferred_UE_Opt &preferred_opt)
{
return NSAPI_ERROR_OK;
}
nsapi_error_t AT_CellularNetwork::get_extended_signal_quality(int &rxlev, int &ber, int &rscp, int &ecno, int &rsrq, int &rsrp)
nsapi_error_t AT_CellularNetwork::get_ciot_network_optimization_config(CIoT_Supported_Opt &supported_opt)
{
return NSAPI_ERROR_OK;
}
nsapi_error_t AT_CellularNetwork::get_signal_quality(int &rssi, int &ber)
nsapi_error_t AT_CellularNetwork::get_signal_quality(int &rssi, int *ber)
{
return NSAPI_ERROR_OK;
}
@ -147,5 +160,10 @@ nsapi_error_t AT_CellularNetwork::get_operator_names(operator_names_list &op_nam
bool AT_CellularNetwork::is_active_context()
{
return true;
return false;
}
nsapi_error_t AT_CellularNetwork::set_receive_period(int mode, EDRXAccessTechnology act_type, uint8_t edrx_value)
{
return NSAPI_ERROR_OK;
}

View File

@ -14,22 +14,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "UBLOX_PPP_CellularContext.h"
#ifndef AT_CELLULARNETWORK_STUB_H_
#define AT_CELLULARNETWORK_STUB_H_
namespace mbed {
#include "AT_CellularNetwork.h"
UBLOX_PPP_CellularContext::UBLOX_PPP_CellularContext(ATHandler &at, CellularDevice *device, const char *apn) :
AT_CellularContext(at, device, apn)
{
namespace AT_CellularNetwork_stub {
extern nsapi_error_t nsapi_error_value;
extern int fail_counter;
extern int set_registration_urc_fail_counter;
extern int get_registration_params_fail_counter;
}
UBLOX_PPP_CellularContext::~UBLOX_PPP_CellularContext()
{
}
bool UBLOX_PPP_CellularContext::stack_type_supported(nsapi_ip_stack_t stack_type)
{
return stack_type == IPV4_STACK ? true : false;
}
} /* namespace mbed */
#endif /* AT_CELLULARNETWORK_STUB_H_ */

View File

@ -1,81 +0,0 @@
/*
* 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 "AT_CellularPower.h"
#include "CellularUtil.h"
#include "CellularLog.h"
using namespace mbed_cellular_util;
using namespace mbed;
AT_CellularPower::AT_CellularPower(ATHandler &at) : AT_CellularBase(at)
{
}
AT_CellularPower::~AT_CellularPower()
{
}
nsapi_error_t AT_CellularPower::on()
{
return NSAPI_ERROR_OK;
}
nsapi_error_t AT_CellularPower::off()
{
return NSAPI_ERROR_OK;
}
nsapi_error_t AT_CellularPower::set_at_mode()
{
return NSAPI_ERROR_OK;
}
nsapi_error_t AT_CellularPower::set_power_level(int func_level, int do_reset)
{
return NSAPI_ERROR_OK;
}
nsapi_error_t AT_CellularPower::reset()
{
return NSAPI_ERROR_OK;
}
nsapi_error_t AT_CellularPower::opt_power_save_mode(int periodic_time, int active_time)
{
return NSAPI_ERROR_OK;
}
nsapi_error_t AT_CellularPower::opt_receive_period(int mode, EDRXAccessTechnology act_type, uint8_t edrx_value)
{
return NSAPI_ERROR_OK;
}
nsapi_error_t AT_CellularPower::set_device_ready_urc_cb(mbed::Callback<void()> callback)
{
return NSAPI_ERROR_OK;
}
void AT_CellularPower::remove_device_ready_urc_cb(mbed::Callback<void()> callback)
{
}
nsapi_error_t AT_CellularPower::is_device_ready()
{
return NSAPI_ERROR_OK;
}

View File

@ -1,59 +0,0 @@
/*
* 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 "AT_CellularSIM.h"
#include "CellularLog.h"
using namespace mbed;
AT_CellularSIM::AT_CellularSIM(ATHandler &at) : AT_CellularBase(at)
{
}
AT_CellularSIM::~AT_CellularSIM()
{
}
nsapi_error_t AT_CellularSIM::get_sim_state(SimState &state)
{
return NSAPI_ERROR_OK;
}
nsapi_error_t AT_CellularSIM::set_pin(const char *sim_pin)
{
return NSAPI_ERROR_OK;
}
nsapi_error_t AT_CellularSIM::change_pin(const char *sim_pin, const char *new_pin)
{
return NSAPI_ERROR_OK;
}
nsapi_error_t AT_CellularSIM::set_pin_query(const char *sim_pin, bool query_pin)
{
return NSAPI_ERROR_OK;
}
nsapi_error_t AT_CellularSIM::get_imsi(char *imsi)
{
return NSAPI_ERROR_OK;
}
nsapi_error_t AT_CellularSIM::get_iccid(char *buf, size_t buf_size)
{
return NSAPI_ERROR_OK;
}

View File

@ -0,0 +1,224 @@
/*
* 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 "cellular/framework/API/CellularContext.h"
#include "ControlPlane_netif_stub.h"
namespace mbed {
class CellularContext_stub : public CellularContext {
public:
std::list<nsapi_error_t> return_values;
nsapi_error_t return_value;
ControlPlane_netif_stub *my_cp_netif;
CellularContext_stub()
{
return_value = 0;
my_cp_netif = NULL;
}
~CellularContext_stub()
{
if (my_cp_netif) {
delete my_cp_netif;
my_cp_netif = NULL;
}
}
void set_file_handle(UARTSerial *serial, PinName dcd_pin, bool active_high)
{
};
void enable_hup(bool enable)
{
};
void set_file_handle(FileHandle *fh)
{
};
nsapi_error_t connect()
{
return NSAPI_ERROR_OK;
};
nsapi_error_t set_device_ready()
{
return NSAPI_ERROR_OK;
};
nsapi_error_t set_sim_ready()
{
return NSAPI_ERROR_OK;
};
nsapi_error_t register_to_network()
{
return NSAPI_ERROR_OK;
};
nsapi_error_t attach_to_network()
{
return NSAPI_ERROR_OK;
};
nsapi_error_t check_operation(nsapi_error_t err, ContextOperation op)
{
return NSAPI_ERROR_OK;
};
uint32_t get_timeout_for_operation(ContextOperation op) const
{
uint32_t timeout = 10 * 60 * 1000; // default timeout is 10 minutes as registration and attach may take time
return timeout;
};
bool is_connected()
{
return true;
};
NetworkStack *get_stack()
{
return NULL;
};
const char *get_ip_address()
{
return NULL;
};
void attach(Callback<void(nsapi_event_t, intptr_t)> status_cb)
{
};
nsapi_error_t set_blocking(bool blocking)
{
return NSAPI_ERROR_OK;
};
void set_plmn(const char *plmn)
{
};
void set_sim_pin(const char *sim_pin)
{
};
nsapi_error_t connect(const char *sim_pin, const char *apn, const char *uname,
const char *pwd)
{
return NSAPI_ERROR_OK;
};
void set_credentials(const char *apn, const char *uname, const char *pwd)
{
};
const char *get_netmask()
{
return NULL;
};
const char *get_gateway()
{
return NULL;
};
bool get_context()
{
return true;
};
bool set_new_context(int cid)
{
return true;
};
nsapi_error_t do_activate_context()
{
return NSAPI_ERROR_OK;
};
void do_connect()
{
};
nsapi_error_t disconnect()
{
return NSAPI_ERROR_OK;
};
nsapi_error_t get_apn_backoff_timer(int &backoff_timer)
{
return NSAPI_ERROR_OK;
};
nsapi_error_t get_rate_control(
CellularContext::RateControlExceptionReports &reports,
CellularContext::RateControlUplinkTimeUnit &timeUnit, int &uplinkRate)
{
return NSAPI_ERROR_OK;
};
nsapi_error_t get_pdpcontext_params(pdpContextList_t &params_list)
{
return NSAPI_ERROR_OK;
};
// Called by CellularDevice for network and cellular device changes
void cellular_callback(nsapi_event_t ev, intptr_t ptr)
{
};
void call_network_cb(nsapi_connection_status_t status)
{
};
ControlPlane_netif_stub *get_cp_netif()
{
if (!my_cp_netif) {
my_cp_netif = new ControlPlane_netif_stub();
}
return my_cp_netif;
};
nsapi_error_t activate_non_ip_context()
{
return NSAPI_ERROR_OK;
};
nsapi_error_t setup_control_plane_opt()
{
return NSAPI_ERROR_OK;
};
void deactivate_ip_context()
{
};
void deactivate_non_ip_context()
{
};
void set_disconnect()
{
};
};
}

View File

@ -30,7 +30,7 @@ MBED_WEAK CellularDevice *CellularDevice::get_default_instance()
return NULL;
}
CellularDevice::CellularDevice(FileHandle *fh) : _network_ref_count(0), _sms_ref_count(0), _power_ref_count(0), _sim_ref_count(0),
CellularDevice::CellularDevice(FileHandle *fh) : _network_ref_count(0), _sms_ref_count(0),
_info_ref_count(0), _fh(fh), _queue(5 * EVENTS_EVENT_SIZE), _state_machine(0), _nw(0)
{
}
@ -87,3 +87,22 @@ nsapi_error_t CellularDevice::attach_to_network()
return NSAPI_ERROR_OK;
}
nsapi_error_t CellularDevice::set_pin(const char *sim_pin)
{
return NSAPI_ERROR_OK;
}
nsapi_error_t CellularDevice::get_sim_state(SimState &state)
{
return NSAPI_ERROR_OK;
}
nsapi_error_t CellularDevice::shutdown()
{
return NSAPI_ERROR_OK;
}
void CellularDevice::cellular_callback(nsapi_event_t ev, intptr_t ptr)
{
}

View File

@ -0,0 +1,59 @@
/*
* 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 "netsocket/cellular/ControlPlane_netif.h"
#include <list>
namespace mbed {
class ControlPlane_netif_stub : public ControlPlane_netif {
public:
std::list<nsapi_error_t> return_values;
nsapi_error_t return_value;
ControlPlane_netif_stub()
{
return_value = 0;
}
protected:
virtual nsapi_error_t send(const void *cpdata, nsapi_size_t cpdata_length)
{
if (!return_values.empty()) {
nsapi_error_t ret = return_values.front();
return_values.pop_front();
return ret;
}
return return_value;
};
virtual nsapi_error_t recv(void *cpdata, nsapi_size_t cpdata_length)
{
if (!return_values.empty()) {
nsapi_error_t ret = return_values.front();
return_values.pop_front();
return ret;
}
return return_value;
};
virtual void data_received() {};
virtual void attach(void (*callback)(void *), void *data) {};
};
}

View File

@ -0,0 +1,62 @@
/*
* Copyright (c) 2017, 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 "netsocket/NetworkInterface.h"
#include "WiFiInterface.h"
#include "CellularBase.h"
#include "MeshInterface.h"
MBED_WEAK WiFiInterface *WiFiInterface::get_default_instance()
{
return NULL;
}
MBED_WEAK MeshInterface *MeshInterface::get_default_instance()
{
return NULL;
}
MBED_WEAK CellularBase *CellularBase::get_default_instance()
{
return NULL;
}
MBED_WEAK WiFiInterface *WiFiInterface::get_target_default_instance()
{
return NULL;
}
MBED_WEAK NetworkInterface *NetworkInterface::get_default_instance()
{
return NULL;
}
void NetworkInterface::set_default_parameters()
{
}
void WiFiInterface::set_default_parameters()
{
}
void CellularBase::set_default_parameters()
{
}
MBED_WEAK NetworkInterface *NetworkInterface::get_target_default_instance()
{
return NULL;
}

View File

@ -15,13 +15,31 @@
* limitations under the License.
*/
#include "Thread.h"
#include "Thread_stub.h"
namespace rtos {
using namespace rtos;
osStatus Thread_stub::osStatus_value = osOK;
osStatus Thread::wait_until(uint64_t millisec)
{
return 0;
}
osStatus Thread::terminate()
{
return 0;
}
osStatus Thread::start(mbed::Callback<void()> task)
{
return Thread_stub::osStatus_value;
}
void Thread::constructor(osPriority priority, uint32_t stack_size, unsigned char *stack_mem, const char *name)
{
}
Thread::~Thread()
{
}

View File

@ -0,0 +1,26 @@
/*
* 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.
*/
#ifndef THREAD_STUB_H_
#define THREAD_STUB_H_
#include "Thread.h"
namespace Thread_stub {
extern osStatus osStatus_value;
}
#endif /* THREAD_STUB_H_ */

View File

@ -24,7 +24,7 @@
typedef int32_t osStatus;
#define osOK 0
#define osErrorNoMemory -5
//These are from cmsis_os2.h

View File

@ -27,9 +27,7 @@ using namespace events;
namespace mbed {
class CellularPower;
class CellularSMS;
class CellularSIM;
class CellularInformation;
class CellularContext;
class FileHandle;
@ -42,7 +40,24 @@ public:
delete _context_list;
delete _network;
}
virtual CellularContext *create_context(FileHandle *fh = NULL, const char *apn = NULL)
virtual nsapi_error_t set_pin(const char *sim_pin)
{
return NSAPI_ERROR_OK;
}
virtual nsapi_error_t get_sim_state(SimState &state)
{
return NSAPI_ERROR_OK;
}
virtual CellularContext *create_context(UARTSerial *serial, const char *const apn, PinName dcd_pin,
bool active_high, bool cp_req = false, bool nonip_req = false)
{
return NULL;
}
virtual CellularContext *create_context(FileHandle *fh = NULL, const char *apn = NULL, bool cp_req = false, bool nonip_req = false)
{
EventQueue que;
FileHandle_stub fh1;
@ -69,16 +84,6 @@ public:
return NULL;
}
virtual CellularPower *open_power(FileHandle *fh = NULL)
{
return NULL;
}
virtual CellularSIM *open_sim(FileHandle *fh = NULL)
{
return NULL;
}
virtual CellularInformation *open_information(FileHandle *fh = NULL)
{
return NULL;
@ -91,10 +96,6 @@ public:
virtual void close_sms() {}
virtual void close_power() {}
virtual void close_sim() {}
virtual void close_information() {}
virtual void set_timeout(int timeout) {}
@ -106,9 +107,48 @@ public:
virtual void modem_debug_on(bool on) {}
virtual nsapi_error_t init_module()
virtual nsapi_error_t init()
{
return 0;
return NSAPI_ERROR_OK;
}
virtual nsapi_error_t shutdown()
{
return NSAPI_ERROR_OK;
}
virtual nsapi_error_t is_ready()
{
return NSAPI_ERROR_OK;
}
virtual nsapi_error_t hard_power_on()
{
return NSAPI_ERROR_OK;
}
virtual nsapi_error_t hard_power_off()
{
return NSAPI_ERROR_OK;
}
virtual nsapi_error_t soft_power_on()
{
return NSAPI_ERROR_OK;
}
virtual nsapi_error_t soft_power_off()
{
return NSAPI_ERROR_OK;
}
virtual void set_ready_cb(Callback<void()> callback)
{
}
nsapi_error_t set_power_save_mode(int periodic_time, int active_time)
{
return NSAPI_ERROR_OK;
}
virtual CellularContext *get_context_list() const

View File

@ -15,16 +15,12 @@
* limitations under the License.
*/
#if !defined(MBED_CONF_NSAPI_PRESENT)
#error [NOT_SUPPORTED] A json configuration file is needed. Skipping this build.
#endif
#include "CellularUtil.h" // for CELLULAR_ helper macros
#include "CellularTargets.h"
#ifndef CELLULAR_DEVICE
#error [NOT_SUPPORTED] CELLULAR_DEVICE must be defined
#ifndef MBED_CONF_APP_CELLULAR_SIM_PIN
#error [NOT_SUPPORTED] SIM pin code is needed. Skipping this build.
#endif
#include "greentea-client/test_env.h"
@ -35,41 +31,47 @@
#include "CellularLog.h"
#include "CellularDevice.h"
#include CELLULAR_STRINGIFY(CELLULAR_DEVICE.h)
#include "Semaphore.h"
#include "../../cellular_tests_common.h"
static UARTSerial cellular_serial(MDMTXD, MDMRXD, MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE);
static CellularDevice *device;
static rtos::Semaphore semaphore;
const int TIME_OUT_DEVICE_READY = 5 * 60 * 1000; // 5 minutes
const int TIME_OUT_REGISTER = 10 * 60 * 1000; // 10 minutes
enum CurrentOp {
OP_DEVICE_READY,
OP_SIM_READY,
OP_REGISTER,
OP_ATTACH
};
static CurrentOp op;
static void create_device()
{
device = new CELLULAR_DEVICE(&cellular_serial);
device = CellularDevice::get_default_instance();
TEST_ASSERT(device != NULL);
}
static void open_close_interfaces()
{
CellularNetwork *nw = device->open_network(&cellular_serial);
CellularNetwork *nw = device->open_network();
TEST_ASSERT(nw != NULL);
device->close_network();
CellularSIM *sim = device->open_sim(&cellular_serial);
TEST_ASSERT(sim != NULL);
device->close_sim();
CellularInformation *info = device->open_information(&cellular_serial);
CellularInformation *info = device->open_information();
TEST_ASSERT(info != NULL);
device->close_information();
CellularPower *power = device->open_power(&cellular_serial);
TEST_ASSERT(power != NULL);
device->close_power();
CellularSMS *sms = device->open_sms(&cellular_serial);
CellularSMS *sms = device->open_sms();
TEST_ASSERT(sms != NULL);
device->close_sms();
CellularContext *ctx = device->create_context();
TEST_ASSERT(ctx != NULL);
TEST_ASSERT(device->get_context_list() == ctx);
device->delete_context(ctx);
}
@ -80,26 +82,109 @@ static void other_methods()
device->modem_debug_on(true);
device->modem_debug_on(false);
CellularNetwork *nw = device->open_network(&cellular_serial);
CellularNetwork *nw = device->open_network();
TEST_ASSERT(nw != NULL);
// then test witj open interface which is called
// then test with open interface which is called
device->set_timeout(5000);
device->modem_debug_on(true);
device->modem_debug_on(false);
TEST_ASSERT(device->get_queue() != NULL);
TEST_ASSERT(device->hard_power_on() == NSAPI_ERROR_OK);
TEST_ASSERT(device->soft_power_on() == NSAPI_ERROR_OK);
wait(5);
TEST_ASSERT_EQUAL_INT(device->init(), NSAPI_ERROR_OK);
}
static void delete_device()
static void shutdown()
{
// delete will close all opened interfaces
delete device;
device = NULL;
TEST_ASSERT(device->shutdown() == NSAPI_ERROR_OK);
TEST_ASSERT(device->soft_power_off() == NSAPI_ERROR_OK);
TEST_ASSERT(device->hard_power_off() == NSAPI_ERROR_OK);
}
static void callback_func(nsapi_event_t ev, intptr_t ptr)
{
if (ev >= NSAPI_EVENT_CELLULAR_STATUS_BASE && ev <= NSAPI_EVENT_CELLULAR_STATUS_END) {
cell_callback_data_t *ptr_data = (cell_callback_data_t *)ptr;
cellular_connection_status_t cell_ev = (cellular_connection_status_t)ev;
if (cell_ev == CellularDeviceReady && ptr_data->error == NSAPI_ERROR_OK && op == OP_DEVICE_READY) {
TEST_ASSERT_EQUAL_INT(semaphore.release(), osOK);
} else if (cell_ev == CellularSIMStatusChanged && ptr_data->error == NSAPI_ERROR_OK &&
ptr_data->status_data == CellularDevice::SimStateReady && op == OP_SIM_READY) {
TEST_ASSERT_EQUAL_INT(semaphore.release(), osOK);
} else if (cell_ev == CellularRegistrationStatusChanged &&
(ptr_data->status_data == CellularNetwork::RegisteredHomeNetwork ||
ptr_data->status_data == CellularNetwork::RegisteredRoaming ||
ptr_data->status_data == CellularNetwork::AlreadyRegistered) &&
ptr_data->error == NSAPI_ERROR_OK &&
op == OP_REGISTER) {
TEST_ASSERT_EQUAL_INT(semaphore.release(), osOK);
} else if (cell_ev == CellularAttachNetwork && ptr_data->status_data == CellularNetwork::Attached &&
ptr_data->error == NSAPI_ERROR_OK && op == OP_ATTACH) {
TEST_ASSERT_EQUAL_INT(semaphore.release(), osOK);
}
}
}
static void init_to_device_ready_state()
{
device = CellularDevice::get_default_instance();
TEST_ASSERT(device != NULL);
#ifdef MBED_CONF_APP_CELLULAR_SIM_PIN
device->set_sim_pin(MBED_CONF_APP_CELLULAR_SIM_PIN);
#endif
#ifdef MBED_CONF_APP_CELLULAR_PLMN
device->set_plmn(MBED_CONF_APP_CELLULAR_PLMN);
#endif
device->attach(&callback_func);
op = OP_DEVICE_READY;
TEST_ASSERT_EQUAL_INT(NSAPI_ERROR_OK, device->hard_power_on());
TEST_ASSERT_EQUAL_INT(NSAPI_ERROR_OK, device->soft_power_on());
TEST_ASSERT_EQUAL_INT(NSAPI_ERROR_OK, device->init());
TEST_ASSERT_EQUAL_INT(NSAPI_ERROR_OK, device->set_device_ready());
int sema_err = semaphore.wait(TIME_OUT_DEVICE_READY);
TEST_ASSERT_EQUAL_INT(1, sema_err);
}
static void continue_to_sim_ready_state()
{
op = OP_SIM_READY;
TEST_ASSERT_EQUAL_INT(NSAPI_ERROR_OK, device->set_sim_ready());
int sema_err = semaphore.wait(TIME_OUT_DEVICE_READY);
TEST_ASSERT_EQUAL_INT(1, sema_err);
}
static void continue_to_register_state()
{
op = OP_REGISTER;
TEST_ASSERT_EQUAL_INT(NSAPI_ERROR_OK, device->register_to_network());
int sema_err = semaphore.wait(TIME_OUT_REGISTER); // cellular network searching may take several minutes
TEST_ASSERT_EQUAL_INT(1, sema_err);
}
static void continue_to_attach_state()
{
op = OP_ATTACH;
TEST_ASSERT_EQUAL_INT(NSAPI_ERROR_OK, device->attach_to_network());
int sema_err = semaphore.wait(TIME_OUT_REGISTER); // cellular network attach may take several minutes
TEST_ASSERT_EQUAL_INT(1, sema_err);
}
using namespace utest::v1;
static utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason)
{
#if MBED_CONF_MBED_TRACE_ENABLE
trace_close();
#endif
greentea_case_failure_abort_handler(source, reason);
return STATUS_ABORT;
}
@ -108,7 +193,11 @@ static Case cases[] = {
Case("CellularDevice create device", create_device, greentea_failure_handler),
Case("CellularDevice Open and close interfaces", open_close_interfaces, greentea_failure_handler),
Case("CellularDevice other methods", other_methods, greentea_failure_handler),
Case("CellularDevice delete device", delete_device, greentea_failure_handler)
Case("CellularDevice init to device ready", init_to_device_ready_state, greentea_failure_handler),
Case("CellularDevice sim ready", continue_to_sim_ready_state, greentea_failure_handler),
Case("CellularDevice register", continue_to_register_state, greentea_failure_handler),
Case("CellularDevice attach", continue_to_attach_state, greentea_failure_handler),
Case("CellularDevice shutdown", shutdown, greentea_failure_handler),
};
static utest::v1::status_t test_setup(const size_t number_of_cases)
@ -121,8 +210,14 @@ static Specification specification(test_setup, cases);
int main()
{
mbed_trace_init();
#if MBED_CONF_MBED_TRACE_ENABLE
trace_open();
#endif
return Harness::run(specification);
int ret = Harness::run(specification);
#if MBED_CONF_MBED_TRACE_ENABLE
trace_close();
#endif
return ret;
}

View File

@ -23,10 +23,6 @@
#include "CellularUtil.h" // for CELLULAR_ helper macros
#include "CellularTargets.h"
#ifndef CELLULAR_DEVICE
#error [NOT_SUPPORTED] CELLULAR_DEVICE must be defined
#endif
#ifndef MBED_CONF_APP_CELLULAR_SIM_PIN
#error [NOT_SUPPORTED] SIM pin code is needed. Skipping this build.
#endif
@ -80,6 +76,12 @@ static void test_information_interface()
err = info->get_serial_number(buf, kbuf_size, CellularInformation::SVN);
TEST_ASSERT(err == NSAPI_ERROR_UNSUPPORTED || err == NSAPI_ERROR_OK);
err = info->get_imsi(buf, kbuf_size);
TEST_ASSERT(err == NSAPI_ERROR_UNSUPPORTED || err == NSAPI_ERROR_OK);
err = info->get_iccid(buf, kbuf_size);
TEST_ASSERT(err == NSAPI_ERROR_UNSUPPORTED || err == NSAPI_ERROR_OK);
dev->close_information();
delete [] buf;

View File

@ -20,21 +20,10 @@
#error [NOT_SUPPORTED] A json configuration file is needed. Skipping this build.
#endif
#include "CellularUtil.h" // for CELLULAR_ helper macros
#include "CellularTargets.h"
#ifndef CELLULAR_DEVICE
#error [NOT_SUPPORTED] CELLULAR_DEVICE must be defined
#endif
#ifndef MBED_CONF_APP_CELLULAR_SIM_PIN
#error [NOT_SUPPORTED] SIM pin code is needed. Skipping this build.
#endif
#if defined(TARGET_ADV_WISE_1570) || defined(TARGET_MTB_ADV_WISE_1570)
#error [NOT_SUPPORTED] target MTB_ADV_WISE_1570 is too unstable for network tests, IoT network is unstable
#endif
#include "greentea-client/test_env.h"
#include "unity.h"
#include "utest.h"
@ -45,7 +34,6 @@
#include "CellularContext.h"
#include "CellularDevice.h"
#include "../../cellular_tests_common.h"
#include CELLULAR_STRINGIFY(CELLULAR_DEVICE.h)
#define NETWORK_TIMEOUT (180*1000)
@ -165,7 +153,6 @@ static void test_attach()
static void test_other()
{
const char *devi = CELLULAR_STRINGIFY(CELLULAR_DEVICE);
TEST_ASSERT(nw->get_3gpp_error() == 0);
nsapi_error_t err = nw->set_access_technology(CellularNetwork::RAT_GSM);
@ -180,32 +167,14 @@ static void test_other()
TEST_ASSERT(nw->scan_plmn(operators, uplinkRate) == NSAPI_ERROR_OK);
device->set_timeout(10 * 1000);
int rxlev = -1, ber = -1, rscp = -1, ecno = -1, rsrq = -1, rsrp = -1;
err = nw->get_extended_signal_quality(rxlev, ber, rscp, ecno, rsrq, rsrp);
TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_DEVICE_ERROR);
if (err == NSAPI_ERROR_DEVICE_ERROR) {
if (strcmp(devi, "QUECTEL_BG96") != 0 && strcmp(devi, "TELIT_HE910") != 0) {// QUECTEL_BG96 does not give any specific reason for device error
TEST_ASSERT((((AT_CellularNetwork *)nw)->get_device_error().errType == 3) && // 3 == CME error from the modem
((((AT_CellularNetwork *)nw)->get_device_error().errCode == 100) || // 100 == unknown command for modem
(((AT_CellularNetwork *)nw)->get_device_error().errCode == 50))); // 50 == incorrect parameters // seen in wise_1570 for not supported commands
}
} else {
// we should have some values which are not optional
TEST_ASSERT(rxlev >= 0 && ber >= 0 && rscp >= 0 && ecno >= 0 && rsrq >= 0 && rsrp >= 0);
}
int rssi = -1;
ber = -1;
err = nw->get_signal_quality(rssi, ber);
int ber = -1;
err = nw->get_signal_quality(rssi, &ber);
TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_DEVICE_ERROR);
if (err == NSAPI_ERROR_DEVICE_ERROR) {
TEST_ASSERT((((AT_CellularNetwork *)nw)->get_device_error().errType == 3) && // 3 == CME error from the modem
((((AT_CellularNetwork *)nw)->get_device_error().errCode == 100) || // 100 == unknown command for modem
(((AT_CellularNetwork *)nw)->get_device_error().errCode == 50))); // 50 == incorrect parameters // seen in wise_1570 for not supported commands
} else {
// test for values
TEST_ASSERT(rssi >= 0);
TEST_ASSERT(ber >= 0);
}
CellularNetwork::registration_params_t reg_params;
@ -222,52 +191,14 @@ static void test_other()
nsapi_connection_status_t st = nw->get_connection_status();
TEST_ASSERT(st == NSAPI_STATUS_DISCONNECTED);
#ifndef TARGET_UBLOX_C027 // AT command is supported, but excluded as it runs out of memory easily (there can be very many operator names)
if (strcmp(devi, "QUECTEL_BG96") != 0 && strcmp(devi, "SARA4_PPP") != 0) {
// QUECTEL_BG96 timeouts with this one, tested with 3 minute timeout
CellularNetwork::operator_names_list op_names;
err = nw->get_operator_names(op_names);
TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_DEVICE_ERROR);
if (err == NSAPI_ERROR_DEVICE_ERROR) {
// if device error then we must check was that really device error or that modem/network does not support the commands
TEST_ASSERT((((AT_CellularNetwork *)nw)->get_device_error().errType == 3) && // 3 == CME error from the modem
((((AT_CellularNetwork *)nw)->get_device_error().errCode == 4) || // 4 == NOT SUPPORTED BY THE MODEM
(((AT_CellularNetwork *)nw)->get_device_error().errCode == 50))); // 50 == incorrect parameters // seen in wise_1570 for not supported commands
} else {
CellularNetwork::operator_names_t *opn = op_names.get_head();
TEST_ASSERT(strlen(opn->numeric) > 0);
TEST_ASSERT(strlen(opn->alpha) > 0);
}
}
#endif
// TELIT_HE910 and QUECTEL_BG96 just gives an error and no specific error number so we can't know is this real error or that modem/network does not support the command
CellularNetwork::Supported_UE_Opt supported_opt = CellularNetwork::SUPPORTED_UE_OPT_MAX;
CellularNetwork::Preferred_UE_Opt preferred_opt = CellularNetwork::PREFERRED_UE_OPT_MAX;
err = nw->get_ciot_optimization_config(supported_opt, preferred_opt);
CellularNetwork::CIoT_Supported_Opt supported_opt = CellularNetwork::CIOT_OPT_MAX;
CellularNetwork::CIoT_Preferred_UE_Opt preferred_opt = CellularNetwork::PREFERRED_UE_OPT_MAX;
err = nw->get_ciot_ue_optimization_config(supported_opt, preferred_opt);
TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_DEVICE_ERROR);
if (err == NSAPI_ERROR_DEVICE_ERROR) {
// if device error then we must check was that really device error or that modem/network does not support the commands
if (!(strcmp(devi, "TELIT_HE910") == 0 || strcmp(devi, "QUECTEL_BG96") == 0 || strcmp(devi, "SARA4_PPP") == 0)) {
TEST_ASSERT((((AT_CellularNetwork *)nw)->get_device_error().errType == 3) && // 3 == CME error from the modem
((((AT_CellularNetwork *)nw)->get_device_error().errCode == 100) || // 100 == unknown command for modem
(((AT_CellularNetwork *)nw)->get_device_error().errCode == 50))); // 50 == incorrect parameters // seen in wise_1570 for not supported commands
}
} else {
TEST_ASSERT(supported_opt != CellularNetwork::SUPPORTED_UE_OPT_MAX);
TEST_ASSERT(preferred_opt != CellularNetwork::PREFERRED_UE_OPT_MAX);
}
err = nw->set_ciot_optimization_config(supported_opt, preferred_opt);
err = nw->set_ciot_optimization_config(supported_opt, preferred_opt, NULL);
TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_DEVICE_ERROR);
if (err == NSAPI_ERROR_DEVICE_ERROR) {
// if device error then we must check was that really device error or that modem/network does not support the commands
if (!(strcmp(devi, "TELIT_HE910") == 0 || strcmp(devi, "QUECTEL_BG96") == 0 || strcmp(devi, "SARA4_PPP") == 0)) {
TEST_ASSERT((((AT_CellularNetwork *)nw)->get_device_error().errType == 3) && // 3 == CME error from the modem
((((AT_CellularNetwork *)nw)->get_device_error().errCode == 100) || // 100 == unknown command for modem
(((AT_CellularNetwork *)nw)->get_device_error().errCode == 50))); // 50 == incorrect parameters // seen in wise_1570 for not supported commands
}
}
}
static void test_detach()

View File

@ -1,145 +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.
*/
#if !defined(MBED_CONF_NSAPI_PRESENT)
#error [NOT_SUPPORTED] A json configuration file is needed. Skipping this build.
#endif
#include "CellularUtil.h" // for CELLULAR_ helper macros
#include "CellularTargets.h"
#ifndef CELLULAR_DEVICE
#error [NOT_SUPPORTED] CELLULAR_DEVICE must be defined
#endif
#ifndef MBED_CONF_APP_CELLULAR_SIM_PIN
#error [NOT_SUPPORTED] SIM pin code is needed. Skipping this build.
#endif
#include "greentea-client/test_env.h"
#include "unity.h"
#include "utest.h"
#include "mbed.h"
#include "AT_CellularPower.h"
#include "CellularDevice.h"
#include "../../cellular_tests_common.h"
#include CELLULAR_STRINGIFY(CELLULAR_DEVICE.h)
#define NETWORK_TIMEOUT (180*1000)
static CellularDevice *cellular_device;
static void urc_callback()
{
}
static void wait_for_power(CellularPower *pwr)
{
nsapi_error_t err = pwr->set_device_ready_urc_cb(&urc_callback);
TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_UNSUPPORTED);
int sanity_count = 0;
err = pwr->set_at_mode();
while (err != NSAPI_ERROR_OK) {
sanity_count++;
wait(1);
TEST_ASSERT(sanity_count < 40);
err = pwr->set_at_mode();
}
TEST_ASSERT(pwr->is_device_ready() == NSAPI_ERROR_OK);
pwr->remove_device_ready_urc_cb(&urc_callback);
}
static void test_power_interface()
{
const char *devi = CELLULAR_STRINGIFY(CELLULAR_DEVICE);
cellular_device = CellularDevice::get_default_instance();
cellular_device->set_timeout(9000);
CellularPower *pwr = cellular_device->open_power();
TEST_ASSERT(pwr != NULL);
nsapi_error_t err = pwr->on();
TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_UNSUPPORTED);
wait_for_power(pwr);
TEST_ASSERT(pwr->set_power_level(1, 0) == NSAPI_ERROR_OK);
err = pwr->reset();
TEST_ASSERT(err == NSAPI_ERROR_OK);
wait_for_power(pwr);
wait(1);
err = pwr->opt_power_save_mode(0, 0);
TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_DEVICE_ERROR);
if (err == NSAPI_ERROR_DEVICE_ERROR) {
if (!(strcmp(devi, "TELIT_HE910") == 0 || strcmp(devi, "QUECTEL_BG96") == 0)) { // TELIT_HE910 and QUECTEL_BG96 just gives an error and no specific error number so we can't know is this real error or that modem/network does not support the command
TEST_ASSERT(((AT_CellularPower *)pwr)->get_device_error().errCode == 100 && // 100 == unknown command for modem
((AT_CellularPower *)pwr)->get_device_error().errType == 3); // 3 == CME error from the modem
}
}
wait(1);
err = pwr->opt_receive_period(0, CellularPower::EDRXEUTRAN_NB_S1_mode, 3);
TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_DEVICE_ERROR);
if (err == NSAPI_ERROR_DEVICE_ERROR) {
if (!(strcmp(devi, "TELIT_HE910") == 0 || strcmp(devi, "QUECTEL_BG96") == 0)) { // TELIT_HE910 and QUECTEL_BG96 just gives an error and no specific error number so we can't know is this real error or that modem/network does not support the command
TEST_ASSERT(((AT_CellularPower *)pwr)->get_device_error().errCode == 100 && // 100 == unknown command for modem
((AT_CellularPower *)pwr)->get_device_error().errType == 3); // 3 == CME error from the modem
}
}
err = pwr->off();
TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_UNSUPPORTED);
}
using namespace utest::v1;
static utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason)
{
greentea_case_failure_abort_handler(source, reason);
return STATUS_ABORT;
}
static Case cases[] = {
Case("CellularPower test interface", test_power_interface, greentea_failure_handler)
};
static utest::v1::status_t test_setup(const size_t number_of_cases)
{
GREENTEA_SETUP(10 * 60, "default_auto");
return verbose_test_setup_handler(number_of_cases);
}
static Specification specification(test_setup, cases);
int main()
{
#if MBED_CONF_MBED_TRACE_ENABLE
trace_open();
#endif
int ret = Harness::run(specification);
#if MBED_CONF_MBED_TRACE_ENABLE
trace_close();
#endif
return ret;
}

View File

@ -1,128 +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.
*/
#if !defined(MBED_CONF_NSAPI_PRESENT)
#error [NOT_SUPPORTED] A json configuration file is needed. Skipping this build.
#endif
#include "CellularUtil.h" // for CELLULAR_ helper macros
#include "CellularTargets.h"
#ifndef CELLULAR_DEVICE
#error [NOT_SUPPORTED] CELLULAR_DEVICE must be defined
#endif
#ifndef MBED_CONF_APP_CELLULAR_SIM_PIN
#error [NOT_SUPPORTED] SIM pin code is needed. Skipping this build.
#endif
#include "greentea-client/test_env.h"
#include "unity.h"
#include "utest.h"
#include "mbed.h"
#include "CellularContext.h"
#include "CellularDevice.h"
#include "CellularSIM.h"
#include "../../cellular_tests_common.h"
#include CELLULAR_STRINGIFY(CELLULAR_DEVICE.h)
#define NETWORK_TIMEOUT (180*1000)
static CellularContext *ctx;
static CellularDevice *device;
static void init_to_device_ready_state()
{
ctx = CellularContext::get_default_instance();
TEST_ASSERT(ctx != NULL);
TEST_ASSERT(ctx->set_device_ready() == NSAPI_ERROR_OK);
device = CellularDevice::get_default_instance();
TEST_ASSERT(device != NULL);
}
static void test_sim_interface()
{
CellularSIM *sim = device->open_sim();
TEST_ASSERT(sim != NULL);
// set SIM at time out to 9000
device->set_timeout(9000);
wait(4); // we need to wait for some time so that SIM interface is working in all modules.
// 1. test set_pin
nsapi_error_t err = sim->set_pin(MBED_CONF_APP_CELLULAR_SIM_PIN);
MBED_ASSERT(err == NSAPI_ERROR_OK);
// 2. test set_pin_query
wait(1);
err = sim->set_pin_query(MBED_CONF_APP_CELLULAR_SIM_PIN, false);
TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_UNSUPPORTED);
wait(1);
err = sim->set_pin_query(MBED_CONF_APP_CELLULAR_SIM_PIN, true);
TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_UNSUPPORTED);
wait(1);
// 3. test get_sim_state
CellularSIM::SimState state;
err = sim->get_sim_state(state);
TEST_ASSERT(err == NSAPI_ERROR_OK);
TEST_ASSERT(state == CellularSIM::SimStateReady);
wait(1);
// 4. test get_imsi
char imsi[16] = {0};
err = sim->get_imsi(imsi);
TEST_ASSERT(err == NSAPI_ERROR_OK);
TEST_ASSERT(strlen(imsi) > 0);
}
using namespace utest::v1;
static utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason)
{
greentea_case_failure_abort_handler(source, reason);
return STATUS_ABORT;
}
static Case cases[] = {
Case("CellularSIM init", init_to_device_ready_state, greentea_failure_handler),
Case("CellularSIM test interface", test_sim_interface, greentea_failure_handler)
};
static utest::v1::status_t test_setup(const size_t number_of_cases)
{
GREENTEA_SETUP(10 * 60, "default_auto");
return verbose_test_setup_handler(number_of_cases);
}
static Specification specification(test_setup, cases);
int main()
{
#if MBED_CONF_MBED_TRACE_ENABLE
trace_open();
#endif
int ret = Harness::run(specification);
#if MBED_CONF_MBED_TRACE_ENABLE
trace_close();
#endif
return ret;
}

View File

@ -20,13 +20,6 @@
#error [NOT_SUPPORTED] A json configuration file is needed. Skipping this build.
#endif
#include "CellularUtil.h" // for CELLULAR_ helper macros
#include "CellularTargets.h"
#ifndef CELLULAR_DEVICE
#error [NOT_SUPPORTED] CELLULAR_DEVICE must be defined
#endif
#ifndef MBED_CONF_APP_CELLULAR_SIM_PIN
#error [NOT_SUPPORTED] SIM pin code is needed. Skipping this build.
#endif
@ -45,12 +38,10 @@
#include "CellularContext.h"
#include "CellularDevice.h"
#include "../../cellular_tests_common.h"
#include CELLULAR_STRINGIFY(CELLULAR_DEVICE.h)
#define NETWORK_TIMEOUT (600*1000)
#define SIM_BUSY 314
static UARTSerial cellular_serial(MDMTXD, MDMRXD, MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE);
static EventQueue queue(8 * EVENTS_EVENT_SIZE);
static CellularContext *ctx;
static CellularDevice *device;
static CellularSMS *sms;
@ -59,10 +50,10 @@ static int service_address_type;
static void create_context()
{
device = new CELLULAR_DEVICE(&cellular_serial);
device = CellularDevice::get_default_instance();
TEST_ASSERT(device != NULL);
device->set_timeout(9000);
ctx = device->create_context();
ctx = CellularContext::get_default_instance();
TEST_ASSERT(ctx != NULL);
ctx->set_sim_pin(MBED_CONF_APP_CELLULAR_SIM_PIN);
#ifdef MBED_CONF_APP_APN
@ -75,12 +66,12 @@ static void store_service_center_address()
// First we need to go SIM_PIN state to make sure that we can get service address and device ready to accept AT commands
create_context();
TEST_ASSERT(ctx->set_sim_ready() == NSAPI_ERROR_OK);
wait(1);
delete device; // will also delete context
wait(3); // some modems needs more time access sim
wait(5); // some modems needs more time access sim
ATHandler *at_init = new ATHandler(&cellular_serial, queue, 30000, "\r");
ATHandler *at_init = device->get_at_handler();
at_init->lock();
at_init->set_at_timeout(30 * 1000);
at_init->cmd_start("AT+CSCA?");
at_init->cmd_stop();
@ -90,10 +81,10 @@ static void store_service_center_address()
at_init->read_string(service_center_address, sizeof(service_center_address));
service_address_type = at_init->read_int();
at_init->resp_stop();
TEST_ASSERT(at_init->get_last_error() == NSAPI_ERROR_OK);
delete at_init;
at_init->unlock();
device->release_at_handler(at_init);
}
static void init()
@ -103,7 +94,7 @@ static void init()
create_context();
TEST_ASSERT(ctx->register_to_network() == NSAPI_ERROR_OK);
sms = device->open_sms(&cellular_serial);
sms = device->open_sms();
TEST_ASSERT(sms != NULL);
wait(3); // some modems needs more time access sim
}

View File

@ -22,18 +22,10 @@
#include "CellularUtil.h" // for CELLULAR_ helper macros
#include "CellularTargets.h"
#ifndef CELLULAR_DEVICE
#error [NOT_SUPPORTED] CELLULAR_DEVICE must be defined
#endif
#ifndef MBED_CONF_APP_CELLULAR_SIM_PIN
#error [NOT_SUPPORTED] SIM pin code is needed. Skipping this build.
#endif
#if defined(TARGET_ADV_WISE_1570) || defined(TARGET_MTB_ADV_WISE_1570)
#error [NOT_SUPPORTED] target MTB_ADV_WISE_1570 is too unstable for network tests, IoT network is unstable
#endif
#include "greentea-client/test_env.h"
#include "unity.h"
#include "utest.h"

View File

@ -4,6 +4,10 @@
"help": "PIN code",
"value": "\"1234\""
},
"cellular_plmn": {
"help": "plmn to select manual registration",
"value": 0
},
"apn": {
"help": "The APN string to use for this SIM/network, set to 0 if none",
"value": 0
@ -27,7 +31,6 @@
"nsapi.dns-response-wait-time": 30000,
"ppp-cell-iface.apn-lookup": false,
"cellular.use-apn-lookup": false,
"target.features_add": ["LWIP"],
"mbed-trace.enable": false,
"lwip.ipv4-enabled": true,
"lwip.ipv6-enabled": true,

View File

@ -19,9 +19,18 @@
#include "CellularBase.h"
#include "CellularDevice.h"
#include "ControlPlane_netif.h"
namespace mbed {
typedef enum pdp_type {
DEFAULT_PDP_TYPE = DEFAULT_STACK,
IPV4_PDP_TYPE = IPV4_STACK,
IPV6_PDP_TYPE = IPV6_STACK,
IPV4V6_PDP_TYPE = IPV4V6_STACK,
NON_IP_PDP_TYPE
} pdp_type_t;
/**
* @addtogroup cellular
* @{
@ -31,6 +40,7 @@ namespace mbed {
class CellularContext : public CellularBase {
public:
// max simultaneous PDP contexts active
static const int PDP_CONTEXT_COUNT = 4;
@ -107,7 +117,6 @@ protected:
// friend of CellularDevice, so it's the only way to close or delete this class.
friend class CellularDevice;
virtual ~CellularContext() {}
public: // from NetworkInterface
virtual nsapi_error_t set_blocking(bool blocking) = 0;
virtual NetworkStack *get_stack() = 0;
@ -135,16 +144,34 @@ public: // from NetworkInterface
virtual const char *get_netmask() = 0;
virtual const char *get_gateway() = 0;
virtual bool is_connected() = 0;
/** Same as NetworkInterface::get_default_instance()
*
* @note not to be used if get_default_nonip_instance() was already used
*
*/
static CellularContext *get_default_instance();
/** Instantiates a default Non-IP cellular interface
*
* This function creates a new Non-IP PDP context.
*
* @note not to be used if get_default_instance() was already used
*
* @return A Non-IP cellular PDP context
*
*/
static CellularContext *get_default_nonip_instance();
// Operations, can be sync/async. Also Connect() is this kind of operation, inherited from NetworkInterface above.
/** Start the interface
*
* Powers on the device and does the initializations for communication with the modem.
* Initializes the modem for communication.
* By default, this API is synchronous. API can be set to asynchronous with method set_blocking(...).
* In synchronous and asynchronous mode, the application can get result in from callback, which is set with
* In synchronous and asynchronous mode application can get result in from callback which is set with
* attach(...)
*
* @return NSAPI_ERROR_OK on success
@ -227,6 +254,19 @@ public: // from NetworkInterface
*/
virtual void set_file_handle(FileHandle *fh) = 0;
/** Set the UART serial used to communicate with the modem. Can be used to change default file handle.
* File handle set with this method will use data carrier detect to be able to detect disconnection much faster in PPP mode.
*
* @param serial UARTSerial used in communication to modem. If null then the default file handle is used.
* @param dcd_pin Pin used to set data carrier detect on/off for the given UART
* @param active_high a boolean set to true if DCD polarity is active low
*/
virtual void set_file_handle(UARTSerial *serial, PinName dcd_pin = NC, bool active_high = false) = 0;
/** Returns the control plane AT command interface
*/
virtual ControlPlane_netif *get_cp_netif() = 0;
protected: // Device specific implementations might need these so protected
enum ContextOperation {
OP_INVALID = -1,
@ -245,9 +285,23 @@ protected: // Device specific implementations might need these so protected
*/
virtual void cellular_callback(nsapi_event_t ev, intptr_t ptr) = 0;
/** Enable or disable hang-up detection
*
* When in PPP data pump mode, it is helpful if the FileHandle will signal hang-up via
* POLLHUP, e.g., if the DCD line is deasserted on a UART. During command mode, this
* signaling is not desired. enable_hup() controls whether this function should be
* active.
*/
virtual void enable_hup(bool enable) = 0;
/** Triggers control plane's operations needed when control plane data is received,
* like socket event, for example.
*/
void cp_data_received();
// member variables needed in target override methods
NetworkStack *_stack; // must be pointer because of PPP
nsapi_ip_stack_t _ip_stack_type;
pdp_type_t _pdp_type;
CellularContext::AuthenticationType _authentication_type;
nsapi_connection_status_t _connect_status;
cell_callback_data_t _cb_data;
@ -259,6 +313,10 @@ protected: // Device specific implementations might need these so protected
const char *_apn;
const char *_uname;
const char *_pwd;
PinName _dcd_pin;
bool _active_high;
ControlPlane_netif *_cp_netif;
};
/**

View File

@ -22,12 +22,11 @@
#include "CellularStateMachine.h"
#include "Callback.h"
#include "ATHandler.h"
#include "UARTSerial.h"
namespace mbed {
class CellularPower;
class CellularSMS;
class CellularSIM;
class CellularInformation;
class CellularNetwork;
class CellularContext;
@ -35,6 +34,7 @@ class FileHandle;
const int MAX_PIN_SIZE = 8;
const int MAX_PLMN_SIZE = 16;
const int MAX_SIM_READY_WAITING_TIME = 30;
/**
* @addtogroup cellular
@ -49,14 +49,31 @@ const int MAX_PLMN_SIZE = 16;
*/
class CellularDevice {
public:
/* enumeration for possible SIM states */
enum SimState {
SimStateReady = 0,
SimStatePinNeeded,
SimStatePukNeeded,
SimStateUnknown
};
/** Returns singleton instance of CellularDevice if CELLULAR_DEVICE is defined. If CELLULAR_DEVICE is not
* defined, then it returns NULL. Implementation is marked as weak.
* defined, then it returns NULL. See NetworkInterface::get_default_instance for details.
*
* @return CellularDevice* instance if any
* @remark Application may override this (non-weak) default implementation.
*
* @return default CellularDevice, NULL if not defined
*/
static CellularDevice *get_default_instance();
/** Return target onboard instance of CellularDevice
*
* @remark Mbed OS target shall override (non-weak) this function for an onboard modem.
*
* @return CellularDevice* instance, NULL if not defined
*/
static CellularDevice *get_target_default_instance();
/** Default constructor
*
* @param fh File handle used in communication with the modem.
@ -67,16 +84,114 @@ public:
*/
virtual ~CellularDevice();
/** Sets the modem up for powering on
* This is equivalent to plugging in the device, i.e., attaching power and serial port.
* In general, hard_power_on and soft_power_on provides a simple hardware abstraction layer
* on top of the modem drivers written for Mbed OS; they can be overridden
* in a derived class to perform custom power controls in a particular board configuration.
* In many boards this will be a no-op if there is no separate power supply control circuitry.
*
* @remark CellularStateMachine calls hard_power_on at first until successful,
* then soft_power_on and init until the modem responds.
* If you are not using CellularStateMachine then you need to call these functions yourself.
*
* @post You must call soft_power_on to power on the modem after calling hard_power_on.
*
* @return NSAPI_ERROR_OK on success
*/
virtual nsapi_error_t hard_power_on() = 0;
/** Sets the modem in unplugged state
*
* This is equivalent to pulling the plug off of the device, i.e.,
* detaching power and serial port.
*
* This puts the modem in the lowest power state.
*
* @remark CellularStateMachine disconnect or destruct does not shutdown or power off the modem,
* but you need to do that yourself.
*
* @pre You must call soft_power_off to power off the modem before calling hard_power_off.
*
* @return NSAPI_ERROR_OK on success
*/
virtual nsapi_error_t hard_power_off() = 0;
/** Powers up the modem
*
* This is equivalent to pressing the "power button" to activate or reset the modem
* and usually implemented as a short pulse on a dedicated GPIO signal.
* It is expected to be present to make it possible to reset the modem.
* The driver may repeat this if the modem is not responsive to AT commands.
*
* @remark CellularStateMachine calls this when requested to connect.
* If you are not using CellularStateMachine then you need to call this function yourself.
*
* @post You must call init to setup the modem.
*
* @return NSAPI_ERROR_OK on success
*/
virtual nsapi_error_t soft_power_on() = 0;
/** Powers down the modem
*
* This is equivalent to turning off the modem by button press.
*
* @remark CellularStateMachine disconnect or destruct does not shutdown or power off the modem,
* but you need to do that yourself.
*
* @pre You must call shutdown to prepare the modem for power off.
*
* @return NSAPI_ERROR_OK on success
*/
virtual nsapi_error_t soft_power_off() = 0;
/** Open the SIM card by setting the pin code for SIM.
*
* @param sim_pin PIN for the SIM card
* @return NSAPI_ERROR_OK on success
* NSAPI_ERROR_PARAMETER if sim_pin is null and sim is not ready
* NSAPI_ERROR_DEVICE_ERROR on failure
*/
virtual nsapi_error_t set_pin(const char *sim_pin) = 0;
/** Get SIM card's state
*
* @param state current state of SIM
* @return NSAPI_ERROR_OK on success
* NSAPI_ERROR_DEVICE_ERROR on failure
*/
virtual nsapi_error_t get_sim_state(SimState &state) = 0;
/** Creates a new CellularContext interface.
*
* @param fh file handle used in communication to modem. This can be, for example, UART handle. If null, then the default
* file handle is used.
* @param apn access point to use with context, can be null.
* @param cp_req flag indicating if EPS control plane optimisation is required
* @param nonip_req flag indicating if this context is required to be Non-IP
*
* @return new instance of class CellularContext or NULL in case of failure
*
*/
virtual CellularContext *create_context(FileHandle *fh = NULL, const char *apn = NULL) = 0;
virtual CellularContext *create_context(FileHandle *fh = NULL, const char *apn = NULL, bool cp_req = false, bool nonip_req = false) = 0;
/** Creates a new CellularContext interface. This API should be used if serial is UART and PPP mode used.
* CellularContext created will use data carrier detect to be able to detect disconnection much faster in PPP mode.
* UARTSerial usually is the same which was given for the CellularDevice.
*
* @param serial UARTSerial used in communication to modem. If null then the default file handle is used.
* @param apn access point to use with context, can be null.
* @param dcd_pin Pin used to set data carrier detect on/off for the given UART
* @param active_high a boolean set to true if DCD polarity is active low
* @param cp_req Flag indicating if EPS control plane optimisation is required
* @param nonip_req Flag indicating if this context is required to be Non-IP
*
* @return new instance of class CellularContext or NULL in case of failure
*
*/
virtual CellularContext *create_context(UARTSerial *serial, const char *apn, PinName dcd_pin = NC,
bool active_high = false, bool cp_req = false, bool nonip_req = false) = 0;
/** Deletes the given CellularContext instance
*
@ -89,6 +204,12 @@ public:
*/
void stop();
/** Get the current FileHandle item used when communicating with the modem.
*
* @return reference to FileHandle
*/
FileHandle &get_file_handle() const;
/** Get event queue that can be chained to main event queue.
* @return event queue
*/
@ -110,7 +231,7 @@ public:
/** Start the interface
*
* Powers on the device and does the initializations for communication with the modem.
* Initializes the modem for communication.
* API is asynchronous. Application can get results from CellularContext callback, which is set
* with attach(...), or callback, which is set by attach(...), in this class.
*
@ -154,11 +275,11 @@ public:
/** Register callback for status reporting.
*
* The specified status callback function is called on the network, and the cellular device status changes.
* The parameters on the callback are the event type and event type dependent reason parameter.
* The specified status callback function will be called on the network and cellular device status changes.
* The parameters on the callback are the event type and event-type dependent reason parameter.
*
* @remark deleting CellularDevice/CellularContext in callback is not allowed.
* @remark application should not attach to this function if it uses CellularContext::attach because it contains the
* @remark deleting CellularDevice/CellularContext in callback not allowed.
* @remark application should not attach to this function if using CellularContext::attach as it will contain the
* same information.
*
* @param status_cb The callback for status changes.
@ -181,22 +302,6 @@ public:
*/
virtual CellularSMS *open_sms(FileHandle *fh = NULL) = 0;
/** Create new CellularPower interface.
*
* @param fh file handle used in communication to modem. This can be, for example, UART handle. If null, then the default
* file handle is used.
* @return New instance of interface CellularPower.
*/
virtual CellularPower *open_power(FileHandle *fh = NULL) = 0;
/** Create new CellularSIM interface.
*
* @param fh file handle used in communication to modem. This can be, for example, UART handle. If null, then the default
* file handle is used.
* @return New instance of interface CellularSIM.
*/
virtual CellularSIM *open_sim(FileHandle *fh = NULL) = 0;
/** Create new CellularInformation interface.
*
* @param fh file handle used in communication to modem. This can be, for example, UART handle. If null, then the default
@ -213,14 +318,6 @@ public:
*/
virtual void close_sms() = 0;
/** Closes the opened CellularPower by deleting the CellularPower instance.
*/
virtual void close_power() = 0;
/** Closes the opened CellularSIM by deleting the CellularSIM instance.
*/
virtual void close_sim() = 0;
/** Closes the opened CellularInformation by deleting the CellularInformation instance.
*/
virtual void close_information() = 0;
@ -237,17 +334,58 @@ public:
*/
virtual void modem_debug_on(bool on) = 0;
/** Initialize cellular module must be called right after module is ready.
* For example, when multiple modules are supported in a single AT driver this function detects
* and adapts to an actual module at runtime.
/** Initialize cellular device must be called right after the module is ready.
*
* For example, when multiple cellular modules are supported in a single driver this function
* detects and adapts to an actual module at runtime.
*
* @remark CellularStateMachine calls soft_power_on and init repeatedly when starting to connect
* until the modem responds.
*
* @return NSAPI_ERROR_OK on success
* NSAPI_ERROR_NO_MEMORY on case of memory failure
* NSAPI_ERROR_UNSUPPORTED if current model is not detected
* NSAPI_ERROR_UNSUPPORTED if current cellular module type is not detected
* NSAPI_ERROR_DEVICE_ERROR if model information could not be read
*
*/
virtual nsapi_error_t init_module() = 0;
virtual nsapi_error_t init() = 0;
/** Shutdown cellular device to minimum functionality.
*
* Actual functionality is modem specific, for example UART may is not be responsive without
* explicit wakeup signal (such as RTS) after shutdown.
*
* @remark You must call shutdown before power off to prepare the modem and to quit cellular network.
*
* @return NSAPI_ERROR_OK on success
* NSAPI_ERROR_DEVICE_ERROR on failure
*/
virtual nsapi_error_t shutdown();
/** Check whether the device is ready to accept commands.
*
* @return NSAPI_ERROR_OK on success
* NSAPI_ERROR_DEVICE_ERROR on failure
*/
virtual nsapi_error_t is_ready() = 0;
/** Set callback function to listen when device is ready.
*
* @param callback function to call on device ready, or NULL to remove callback.
*/
virtual void set_ready_cb(Callback<void()> callback) = 0;
/** Set power save mode
*
* @remark See 3GPP TS 27.007 PSM for details
*
* @param periodic_time in seconds to enable power save, or zero to disable
* @param active_time in seconds to wait before entering power save mode
*
* @return NSAPI_ERROR_OK on success
* NSAPI_ERROR_DEVICE_ERROR on failure
*/
virtual nsapi_error_t set_power_save_mode(int periodic_time, int active_time = 0) = 0;
/** Get the linked list of CellularContext instances
*
@ -282,8 +420,6 @@ protected:
int _network_ref_count;
int _sms_ref_count;
int _power_ref_count;
int _sim_ref_count;
int _info_ref_count;
FileHandle *_fh;
events::EventQueue _queue;

View File

@ -21,6 +21,9 @@
#include <stddef.h>
#include "nsapi_types.h"
const int MAX_IMSI_LENGTH = 15;
const int MAX_ICCID_LENGTH = 20 + 1; // +1 for zero termination
namespace mbed {
/**
@ -48,6 +51,7 @@ public:
* @param buf manufacturer identification as zero terminated string
* @param buf_size max length of manufacturer identification is 2048 characters
* @return NSAPI_ERROR_OK on success
* NSAPI_ERROR_PARAMETER if buf is null or buf_size is zero
* NSAPI_ERROR_DEVICE_ERROR on failure
*/
virtual nsapi_error_t get_manufacturer(char *buf, size_t buf_size) = 0;
@ -57,6 +61,7 @@ public:
* @param buf model identification as zero terminated string
* @param buf_size max length of model identification is 2048 characters
* @return NSAPI_ERROR_OK on success
* NSAPI_ERROR_PARAMETER if buf is null or buf_size is zero
* NSAPI_ERROR_DEVICE_ERROR on failure
*/
virtual nsapi_error_t get_model(char *buf, size_t buf_size) = 0;
@ -66,6 +71,7 @@ public:
* @param buf revision identification as zero terminated string
* @param buf_size max length of revision identification is 2048 characters
* @return NSAPI_ERROR_OK on success
* NSAPI_ERROR_PARAMETER if buf is null or buf_size is zero
* NSAPI_ERROR_DEVICE_ERROR on failure
*/
virtual nsapi_error_t get_revision(char *buf, size_t buf_size) = 0;
@ -76,6 +82,7 @@ public:
* @param buf_size max length of serial number is 2048 characters
* @param type serial number type to read
* @return NSAPI_ERROR_OK on success
* NSAPI_ERROR_PARAMETER if buf is null or buf_size is zero
* NSAPI_ERROR_UNSUPPORTED if the modem does not support SerialNumberType
* NSAPI_ERROR_DEVICE_ERROR on other failures
*/
@ -85,7 +92,30 @@ public:
IMEISV = 2, // IMEI and Software Version number
SVN = 3 // Software Version Number
};
virtual nsapi_error_t get_serial_number(char *buf, size_t buf_size, SerialNumberType type = SN) = 0;
virtual nsapi_size_or_error_t get_serial_number(char *buf, size_t buf_size, SerialNumberType type = SN) = 0;
/** Get IMSI from the sim card
*
* @remark Given imsi buffer length must be 16 or more as imsi max length is 15!
*
* @param imsi preallocated char* which after successful request contains imsi
* @param buf_size size of imsi buffer
* @return NSAPI_ERROR_OK on success
* NSAPI_ERROR_PARAMETER if imsi is null or buf_size is zero or buf_size is smaller than
* MAX_IMSI_LENGTH + 1
* NSAPI_ERROR_DEVICE_ERROR on other failures
*/
virtual nsapi_error_t get_imsi(char *imsi, size_t buf_size) = 0;
/** Get serial number from the SIM card
*
* @param buf SIM ICCID as zero terminated string
* @param buf_size max length of SIM ICCID is MAX_ICCID_LENGTH
* @return NSAPI_ERROR_OK on success
* NSAPI_ERROR_PARAMETER if buf is null or buf_size is zero
* NSAPI_ERROR_DEVICE_ERROR on failure
*/
virtual nsapi_error_t get_iccid(char *buf, size_t buf_size) = 0;
};
/**

View File

@ -45,17 +45,17 @@ protected:
public:
/* Definition for Supported CIoT EPS optimizations type. */
enum Supported_UE_Opt {
SUPPORTED_UE_OPT_NO_SUPPORT = 0, /* No support. */
SUPPORTED_UE_OPT_CONTROL_PLANE, /* Support for control plane CIoT EPS optimization. */
SUPPORTED_UE_OPT_USER_PLANE, /* Support for user plane CIoT EPS optimization. */
SUPPORTED_UE_OPT_BOTH, /* Support for both control plane CIoT EPS optimization and user plane CIoT EPS
enum CIoT_Supported_Opt {
CIOT_OPT_NO_SUPPORT = 0, /* No support. */
CIOT_OPT_CONTROL_PLANE, /* Support for control plane CIoT EPS optimization. */
CIOT_OPT_USER_PLANE, /* Support for user plane CIoT EPS optimization. */
CIOT_OPT_BOTH, /* Support for both control plane CIoT EPS optimization and user plane CIoT EPS
optimization. */
SUPPORTED_UE_OPT_MAX
CIOT_OPT_MAX
};
/* Definition for Preferred CIoT EPS optimizations type. */
enum Preferred_UE_Opt {
enum CIoT_Preferred_UE_Opt {
PREFERRED_UE_OPT_NO_PREFERENCE = 0, /* No preference. */
PREFERRED_UE_OPT_CONTROL_PLANE, /* Preference for control plane CIoT EPS optimization. */
PREFERRED_UE_OPT_USER_PLANE, /* Preference for user plane CIoT EPS optimization. */
@ -257,45 +257,47 @@ public:
/** Set CIoT optimizations.
*
* @param supported_opt Supported CIoT EPS optimizations.
* @param supported_opt Supported CIoT EPS optimizations
* (the HW support can be checked with get_ciot_ue_optimization_config).
* @param preferred_opt Preferred CIoT EPS optimizations.
* @param network_support_cb This callback will be called when CIoT network optimisation support is known
* @return NSAPI_ERROR_OK on success
* NSAPI_ERROR_DEVICE_ERROR on failure
*/
virtual nsapi_error_t set_ciot_optimization_config(Supported_UE_Opt supported_opt,
Preferred_UE_Opt preferred_opt) = 0;
virtual nsapi_error_t set_ciot_optimization_config(CIoT_Supported_Opt supported_opt,
CIoT_Preferred_UE_Opt preferred_opt,
Callback<void(CIoT_Supported_Opt)> network_support_cb) = 0;
/** Get CIoT optimizations.
/** Get UE CIoT optimizations.
*
* @param supported_opt Supported CIoT EPS optimizations.
* @param preferred_opt Preferred CIoT EPS optimizations.
* @return NSAPI_ERROR_OK on success
* NSAPI_ERROR_DEVICE_ERROR on failure
*/
virtual nsapi_error_t get_ciot_optimization_config(Supported_UE_Opt &supported_opt,
Preferred_UE_Opt &preferred_opt) = 0;
virtual nsapi_error_t get_ciot_ue_optimization_config(CIoT_Supported_Opt &supported_opt,
CIoT_Preferred_UE_Opt &preferred_opt) = 0;
/** Get extended signal quality parameters.
/** Get Network CIoT optimizations.
*
* @param rxlev signal strength level
* @param ber bit error rate
* @param rscp signal code power
* @param ecno ratio of the received energy per PN chip to the total received power spectral density
* @param rsrq signal received quality
* @param rsrp signal received power
* @param supported_network_opt Supported CIoT EPS optimizations. CIOT_OPT_MAX will be returned,
* if the support is not known
* @return NSAPI_ERROR_OK on success
* NSAPI_ERROR_DEVICE_ERROR on other failures
* NSAPI_ERROR_DEVICE_ERROR on failure
*/
virtual nsapi_error_t get_extended_signal_quality(int &rxlev, int &ber, int &rscp, int &ecno, int &rsrq, int &rsrp) = 0;
virtual nsapi_error_t get_ciot_network_optimization_config(CIoT_Supported_Opt &supported_network_opt) = 0;
/** Get signal quality parameters.
*
* @param rssi signal strength level
* @param ber bit error rate
* @param rssi signal strength level as defined in 3GPP TS 27.007, range -113..-51 dBm or SignalQualityUnknown
* @param ber bit error rate as RXQUAL as defined in 3GPP TS 45.008, range 0..7 or SignalQualityUnknown
* @return NSAPI_ERROR_OK on success
* NSAPI_ERROR_DEVICE_ERROR on other failures
*/
virtual nsapi_error_t get_signal_quality(int &rssi, int &ber) = 0;
enum SignalQuality {
SignalQualityUnknown = 99
};
virtual nsapi_error_t get_signal_quality(int &rssi, int *ber = NULL) = 0;
/** Get the last 3GPP error code
* @return see 3GPP TS 27.007 error codes
@ -361,6 +363,27 @@ public:
* NSAPI_ERROR_DEVICE_ERROR on failure
*/
virtual nsapi_error_t get_registration_params(RegistrationType type, registration_params_t &reg_params) = 0;
/** Set discontinuous reception time on cellular device.
*
* @remark See 3GPP TS 27.007 eDRX for details.
*
* @param mode disable or enable the use of eDRX
* @param act_type type of access technology
* @param edrx_value requested edxr value. Extended DRX parameters information element.
*
* @return NSAPI_ERROR_OK on success
* NSAPI_ERROR_DEVICE_ERROR on failure
*/
enum EDRXAccessTechnology {
EDRXGSM_EC_GSM_IoT_mode = 1,
EDRXGSM_A_Gb_mode,
EDRXUTRAN_Iu_mode,
EDRXEUTRAN_WB_S1_mode,
EDRXEUTRAN_NB_S1_mode
};
virtual nsapi_error_t set_receive_period(int mode, EDRXAccessTechnology act_type, uint8_t edrx_value) = 0;
};
/**

View File

@ -1,158 +0,0 @@
/*
* Copyright (c) 2017, 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.
*/
#ifndef CELLULAR_API_CELLULARPOWER_H_
#define CELLULAR_API_CELLULARPOWER_H_
#include "nsapi_types.h"
#include "Callback.h"
namespace mbed {
/**
* Class CellularPower
*
* An interface that provides power handling functions for modem/module.
*/
class CellularPower {
protected:
// friend of CellularDevice so that it's the only way to close/delete this class.
friend class CellularDevice;
/**
* virtual Destructor
*/
virtual ~CellularPower() {}
public:
/* Access technology used in method opt_receive_period */
enum EDRXAccessTechnology {
EDRXGSM_EC_GSM_IoT_mode = 1,
EDRXGSM_A_Gb_mode,
EDRXUTRAN_Iu_mode,
EDRXEUTRAN_WB_S1_mode,
EDRXEUTRAN_NB_S1_mode
};
/** Set cellular device power on. Default implementation is empty.
* Device power on/off is modem/board specific behavior and must be done on inherited class if needed.
* Power on is done by toggling power pin/button.
*
* @remark set_at_mode must be called to initialise modem
*
* @return NSAPI_ERROR_OK on success
* NSAPI_ERROR_UNSUPPORTED if not overridden by the target modem
*/
virtual nsapi_error_t on() = 0;
/** Set cellular device power off. Default implementation is empty.
* Device power on/off is modem/board specific behavior and must be done on inherited class if needed.
* Power off is done by toggling power pin/button.
*
* @return NSAPI_ERROR_OK on success
* NSAPI_ERROR_UNSUPPORTED if not overridden by the target modem
*/
virtual nsapi_error_t off() = 0;
/** Set AT command mode. Blocking until success or failure.
*
* @remark must be called after power on to prepare correct AT mode
*
* @return NSAPI_ERROR_OK on success
* NSAPI_ERROR_DEVICE_ERROR on failure
*/
virtual nsapi_error_t set_at_mode() = 0;
/** Set cellular device power level by enabling/disabling functionality.
*
* @param func_level:
* 0 minimum functionality
* 1 full functionality. Enable (turn on) the transmit and receive RF circuits for all supported radio access technologies.
* For MTs supporting +CSRA, this equals the RATs indicated by the response of +CSRA=?. Current +CSRA setting is ignored.
* It is not required that the MT transmit and receive RF circuits are in a disabled state for this setting to have effect.
* 2 disable (turn off) MT transmit RF circuits only
* 3 disable (turn off) MT receive RF circuits only
* 4 disable (turn off) both MT transmit and receive RF circuits
* @param do_reset 0 for do not reset, 1 for reset the device when changing the functionality
*
* @remark See 3GPP TS 27.007 CFUN for more details
*
* @return NSAPI_ERROR_OK on success
* NSAPI_ERROR_DEVICE_ERROR on failure
*/
virtual nsapi_error_t set_power_level(int func_level, int do_reset = 0) = 0;
/** Reset and wake-up cellular device.
*
* @return NSAPI_ERROR_OK on success
* NSAPI_ERROR_DEVICE_ERROR on failure
*/
virtual nsapi_error_t reset() = 0;
/** Opt for power save setting on cellular device. If both parameters are zero, this disables PSM.
*
* @remark See 3GPP TS 27.007 PSM for details
*
* @param periodic_time Timeout in seconds IoT subsystem is not expecting messaging
* @param active_time Timeout in seconds IoT subsystem waits for response
*
* @return NSAPI_ERROR_OK on success
* NSAPI_ERROR_DEVICE_ERROR on failure
*/
virtual nsapi_error_t opt_power_save_mode(int periodic_time, int active_time) = 0;
/** Opt for discontinuous reception on cellular device.
*
* @remark See 3GPP TS 27.007 eDRX for details.
*
* @param mode disable or enable the use of eDRX
* @param act_type type of access technology
* @param edrx_value requested edxr value. Extended DRX parameters information element.
*
* @return NSAPI_ERROR_OK on success
* NSAPI_ERROR_DEVICE_ERROR on failure
*/
virtual nsapi_error_t opt_receive_period(int mode, EDRXAccessTechnology act_type, uint8_t edrx_value) = 0;
/** Check whether the device is ready to accept commands.
*
* @return NSAPI_ERROR_OK on success
* NSAPI_ERROR_DEVICE_ERROR on failure
*/
virtual nsapi_error_t is_device_ready() = 0;
/** Set URC callback function for device specific ready urc. URC is defined in device specific
* power API. Used in startup sequence to listen when device is ready
* for using at commands and possible sim.
*
* @param callback Callback function called when urc received
*
* @return NSAPI_ERROR_OK on success
* NSAPI_ERROR_NO_MEMORY on memory failure
* NSAPI_ERROR_UNSUPPORTED if not overridden by the target modem
*/
virtual nsapi_error_t set_device_ready_urc_cb(mbed::Callback<void()> callback) = 0;
/** Removes the device ready urc from the list of urc's.
*
* @param callback callback to remove from the list of urc's
*/
virtual void remove_device_ready_urc_cb(mbed::Callback<void()> callback) = 0;
};
} // namespace mbed
#endif /* CELLULAR_API_CELLULARPOWER_H_ */

View File

@ -1,110 +0,0 @@
/*
* Copyright (c) 2017, 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.
*/
#ifndef CELLULAR_SIM_H_
#define CELLULAR_SIM_H_
#include <stddef.h>
#include "nsapi_types.h"
namespace mbed {
const int MAX_SIM_READY_WAITING_TIME = 30;
const int MAX_IMSI_LENGTH = 15;
const int MAX_ICCID_LENGTH = 20 + 1; // +1 for zero termination
/**
* Class CellularSIM
*
* An abstract interface for SIM card handling.
*/
class CellularSIM {
protected:
// friend of CellularDevice so that it's the only way to close/delete this class.
friend class CellularDevice;
/**
* virtual Destructor
*/
virtual ~CellularSIM() {};
public:
/* enumeration for possible SIM states */
enum SimState {
SimStateReady = 0,
SimStatePinNeeded,
SimStatePukNeeded,
SimStateUnknown
};
/** Open the SIM card by setting the pin code for SIM.
*
* @param sim_pin PIN for the SIM card
* @return NSAPI_ERROR_OK on success
* NSAPI_ERROR_DEVICE_ERROR on failure
*/
virtual nsapi_error_t set_pin(const char *sim_pin) = 0;
/** Change SIM pin code.
*
* @param sim_pin Current PIN for SIM
* @param new_pin New PIN for SIM
* @return NSAPI_ERROR_OK on success
* NSAPI_ERROR_DEVICE_ERROR on failure
*/
virtual nsapi_error_t change_pin(const char *sim_pin, const char *new_pin) = 0;
/** Change is pin query needed after boot
*
* @param sim_pin Valid PIN for SIM card
* @param query_pin False if PIN query not needed, True if PIN query needed after boot.
* @return NSAPI_ERROR_OK on success
* NSAPI_ERROR_DEVICE_ERROR on failure
*/
virtual nsapi_error_t set_pin_query(const char *sim_pin, bool query_pin) = 0;
/** Get SIM card's state
*
* @param state current state of SIM
* @return NSAPI_ERROR_OK on success
* NSAPI_ERROR_DEVICE_ERROR on failure
*/
virtual nsapi_error_t get_sim_state(SimState &state) = 0;
/** Get IMSI from the sim card
* @remark Given imsi buffer length must be 16 or more as imsi max length is 15!
*
* @param imsi preallocated char* which after successful request contains imsi
* @return NSAPI_ERROR_OK on success
* NSAPI_ERROR_PARAMETER if imsi if null
* NSAPI_ERROR_DEVICE_ERROR on other failures
*/
virtual nsapi_error_t get_imsi(char *imsi) = 0;
/** Get serial number from the SIM card
*
* @param buf SIM ICCID as zero terminated string
* @param buf_size max length of SIM ICCID is MAX_ICCID_LENGTH
* @return NSAPI_ERROR_OK on success
* NSAPI_ERROR_DEVICE_ERROR on failure
*/
virtual nsapi_error_t get_iccid(char *buf, size_t buf_size) = 0;
};
} // namespace mbed
#endif // CELLULAR_SIM_H_

View File

@ -90,11 +90,7 @@ ATHandler::ATHandler(FileHandle *fh, EventQueue &queue, uint32_t timeout, const
if (output_delimiter) {
_output_delimiter = new char[strlen(output_delimiter) + 1];
if (!_output_delimiter) {
MBED_ASSERT(0);
} else {
memcpy(_output_delimiter, output_delimiter, strlen(output_delimiter) + 1);
}
memcpy(_output_delimiter, output_delimiter, strlen(output_delimiter) + 1);
} else {
_output_delimiter = NULL;
}
@ -158,35 +154,38 @@ void ATHandler::set_file_handle(FileHandle *fh)
void ATHandler::set_is_filehandle_usable(bool usable)
{
_is_fh_usable = usable;
if (usable) {
// set file handle sigio and blocking mode back
set_file_handle(_fileHandle);
}
}
nsapi_error_t ATHandler::set_urc_handler(const char *prefix, mbed::Callback<void()> callback)
void ATHandler::set_urc_handler(const char *prefix, Callback<void()> callback)
{
if (!callback) {
remove_urc_handler(prefix);
return;
}
if (find_urc_handler(prefix)) {
tr_warn("URC already added with prefix: %s", prefix);
return NSAPI_ERROR_OK;
return;
}
struct oob_t *oob = new struct oob_t;
if (!oob) {
return NSAPI_ERROR_NO_MEMORY;
} else {
size_t prefix_len = strlen(prefix);
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;
}
size_t prefix_len = strlen(prefix);
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 = prefix;
oob->prefix_len = prefix_len;
oob->cb = callback;
oob->next = _oobs;
_oobs = oob;
}
return NSAPI_ERROR_OK;
oob->prefix = prefix;
oob->prefix_len = prefix_len;
oob->cb = callback;
oob->next = _oobs;
_oobs = oob;
}
void ATHandler::remove_urc_handler(const char *prefix)
@ -311,7 +310,7 @@ void ATHandler::process_oob()
void ATHandler::set_filehandle_sigio()
{
_fileHandle->sigio(mbed::Callback<void()>(this, &ATHandler::event));
_fileHandle->sigio(Callback<void()>(this, &ATHandler::event));
}
void ATHandler::reset_buffer()
@ -600,13 +599,11 @@ int32_t ATHandler::read_int()
}
char buff[BUFF_SIZE];
char *first_no_digit;
if (read_string(buff, (size_t)sizeof(buff)) == 0) {
if (read_string(buff, sizeof(buff)) == 0) {
return -1;
}
return std::strtol(buff, &first_no_digit, 10);
return std::strtol(buff, NULL, 10);
}
void ATHandler::set_delimiter(char delimiter)
@ -1212,8 +1209,9 @@ void ATHandler::debug_print(const char *p, int len)
#if MBED_CONF_MBED_TRACE_ENABLE
mbed_cellular_trace::mutex_wait();
#endif
char c;
for (ssize_t i = 0; i < len; i++) {
char c = *p++;
c = *p++;
if (!isprint(c)) {
if (c == '\r') {
debug("\n");

View File

@ -120,20 +120,12 @@ public:
*/
nsapi_error_t unlock_return_error();
/** Set the urc callback for urc. If urc is found when parsing AT responses, then call if called.
* If urc is already set then it's not set twice.
/** Set callback function for URC
*
* @param prefix Register urc prefix for callback. Urc could be for example "+CMTI: "
* @param callback Callback, which is called if urc is found in AT response
* @return NSAPI_ERROR_OK or NSAPI_ERROR_NO_MEMORY if no memory
* @param prefix URC text to look for, e.g. "+CMTI:"
* @param callback function to call on prefix, or 0 to remove callback
*/
nsapi_error_t set_urc_handler(const char *prefix, mbed::Callback<void()> callback);
/** Remove urc handler from linked list of urc's
*
* @param prefix Register urc prefix for callback. Urc could be for example "+CMTI: "
*/
void remove_urc_handler(const char *prefix);
void set_urc_handler(const char *prefix, Callback<void()> callback);
ATHandler *_nextATHandler; // linked list
@ -229,6 +221,11 @@ protected:
#endif
FileHandle *_fileHandle;
private:
/** Remove urc handler from linked list of urc's
*
* @param prefix Register urc prefix for callback. Urc could be for example "+CMTI: "
*/
void remove_urc_handler(const char *prefix);
void set_error(nsapi_error_t err);
@ -242,7 +239,7 @@ private:
struct oob_t {
const char *prefix;
int prefix_len;
mbed::Callback<void()> cb;
Callback<void()> cb;
oob_t *next;
};
oob_t *_oobs;

View File

@ -34,25 +34,19 @@ device_err_t AT_CellularBase::get_device_error() const
return _at.get_last_device_error();
}
AT_CellularBase::SupportedFeature const *AT_CellularBase::_unsupported_features;
const intptr_t *AT_CellularBase::_property_array;
void AT_CellularBase::set_unsupported_features(const SupportedFeature *unsupported_features)
void AT_CellularBase::set_cellular_properties(const intptr_t *property_array)
{
_unsupported_features = unsupported_features;
}
bool AT_CellularBase::is_supported(SupportedFeature feature)
{
if (!_unsupported_features) {
return true;
if (!property_array) {
tr_warning("trying to set an empty cellular property array");
return;
}
for (int i = 0; _unsupported_features[i] != SUPPORTED_FEATURE_END_MARK; i++) {
if (_unsupported_features[i] == feature) {
tr_debug("Unsupported feature (%d)", (int)feature);
return false;
}
}
return true;
_property_array = property_array;
}
intptr_t AT_CellularBase::get_property(CellularProperty key)
{
return _property_array[key];
}

View File

@ -42,30 +42,38 @@ public:
*/
device_err_t get_device_error() const;
/** Cellular module need to define an array of unsupported features if any,
* by default all features are supported.
*
* @param features Array of type SupportedFeature with last element FEATURE_END_MARK
*/
enum SupportedFeature {
AT_CGSN_WITH_TYPE, // AT+CGSN without type is likely always supported similar to AT+GSN
AT_CGDATA, // alternative is to support only ATD*99***<cid>#
AT_CGAUTH, // APN authentication AT commands supported
SUPPORTED_FEATURE_END_MARK // must be last element in the array of features
enum CellularProperty {
PROPERTY_C_EREG, // AT_CellularNetwork::RegistrationMode. What support modem has for this registration type.
PROPERTY_C_GREG, // AT_CellularNetwork::RegistrationMode. What support modem has for this registration type.
PROPERTY_C_REG, // AT_CellularNetwork::RegistrationMode. What support modem has for this registration type.
PROPERTY_AT_CGSN_WITH_TYPE, // 0 = not supported, 1 = supported. AT+CGSN without type is likely always supported similar to AT+GSN.
PROPERTY_AT_CGDATA, // 0 = not supported, 1 = supported. Alternative is to support only ATD*99***<cid>#
PROPERTY_AT_CGAUTH, // 0 = not supported, 1 = supported. APN authentication AT commands supported
PROPERTY_IPV4_PDP_TYPE, // 0 = not supported, 1 = supported. Does modem support IPV4?
PROPERTY_IPV6_PDP_TYPE, // 0 = not supported, 1 = supported. Does modem support IPV6?
PROPERTY_IPV4V6_PDP_TYPE, // 0 = not supported, 1 = supported. Does modem support dual stack IPV4V6?
PROPERTY_NON_IP_PDP_TYPE, // 0 = not supported, 1 = supported. Does modem support Non-IP?
PROPERTY_MAX
};
static void set_unsupported_features(const SupportedFeature *unsupported_features);
/** Cellular module need to define an array of cellular properties which defines module supported property values.
*
* @param property_array array of module properties
*/
static void set_cellular_properties(const intptr_t *property_array);
protected:
static const intptr_t *_property_array;
ATHandler &_at;
/** Check if some functionality is supported by a cellular module. For example,
* most of standard AT commands are optional and not implemented by all cellular modules.
/** Get value for the given key.
*
* @param feature check for feature to support
* @return true on supported, otherwise false
* @param key key for value to be fetched
* @return property value for the given key. Value type is defined in enum CellularProperty
*/
static const SupportedFeature *_unsupported_features;
static bool is_supported(SupportedFeature feature);
static intptr_t get_property(CellularProperty key);
};
} // namespace mbed

View File

@ -20,12 +20,14 @@
#include "AT_CellularStack.h"
#include "CellularLog.h"
#include "CellularUtil.h"
#include "CellularSIM.h"
#include "UARTSerial.h"
#include "mbed_wait_api.h"
#define NETWORK_TIMEOUT 30 * 60 * 1000 // 30 minutes
#define DEVICE_TIMEOUT 5 * 60 * 1000 // 5 minutes
// Timeout to wait for URC indicating ciot optimization support from network
#define CP_OPT_NW_REPLY_TIMEOUT 3000 // 3 seconds
#if NSAPI_PPP_AVAILABLE
#define AT_SYNC_TIMEOUT 1000 // 1 second timeout
@ -35,19 +37,20 @@
#define USE_APN_LOOKUP (MBED_CONF_CELLULAR_USE_APN_LOOKUP || (NSAPI_PPP_AVAILABLE && MBED_CONF_PPP_CELL_IFACE_APN_LOOKUP))
#if USE_APN_LOOKUP
#include "CellularInformation.h"
#include "APN_db.h"
#endif //USE_APN_LOOKUP
using namespace mbed_cellular_util;
using namespace mbed;
AT_CellularContext::AT_CellularContext(ATHandler &at, CellularDevice *device, const char *apn) :
AT_CellularBase(at), _ip_stack_type_requested(DEFAULT_STACK), _is_connected(false), _is_blocking(true),
_current_op(OP_INVALID), _device(device), _nw(0), _fh(0)
AT_CellularContext::AT_CellularContext(ATHandler &at, CellularDevice *device, const char *apn, bool cp_req, bool nonip_req) :
AT_CellularBase(at), _is_connected(false), _is_blocking(true),
_current_op(OP_INVALID), _device(device), _nw(0), _fh(0), _cp_req(cp_req), _nonip_req(nonip_req), _cp_in_use(false)
{
tr_info("New CellularContext %s (%p)", apn ? apn : "", this);
_stack = NULL;
_ip_stack_type = DEFAULT_STACK;
_pdp_type = DEFAULT_PDP_TYPE;
_authentication_type = CellularContext::CHAP;
_connect_status = NSAPI_STATUS_DISCONNECTED;
_is_context_active = false;
@ -59,17 +62,24 @@ AT_CellularContext::AT_CellularContext(ATHandler &at, CellularDevice *device, co
_cid = -1;
_new_context_set = false;
_next = NULL;
_dcd_pin = NC;
_active_high = false;
_cp_netif = NULL;
}
AT_CellularContext::~AT_CellularContext()
{
tr_info("Delete CellularContext %s (%p)", _apn ? _apn : "", this);
tr_info("Delete CellularContext with apn: [%s] (%p)", _apn ? _apn : "", this);
(void)disconnect();
if (_nw) {
_device->close_network();
}
if (_cp_netif) {
delete _cp_netif;
}
}
void AT_CellularContext::set_file_handle(FileHandle *fh)
@ -79,6 +89,23 @@ void AT_CellularContext::set_file_handle(FileHandle *fh)
_at.set_file_handle(_fh);
}
void AT_CellularContext::set_file_handle(UARTSerial *serial, PinName dcd_pin, bool active_high)
{
tr_info("CellularContext serial %p", serial);
_dcd_pin = dcd_pin;
_active_high = active_high;
_fh = serial;
_at.set_file_handle(static_cast<FileHandle *>(serial));
enable_hup(false);
}
void AT_CellularContext::enable_hup(bool enable)
{
if (_dcd_pin != NC) {
static_cast<UARTSerial *>(_fh)->set_data_carrier_detect(enable ? _dcd_pin : NC, _active_high);
}
}
nsapi_error_t AT_CellularContext::connect()
{
tr_info("CellularContext connect");
@ -244,33 +271,21 @@ void AT_CellularContext::set_credentials(const char *apn, const char *uname, con
_pwd = pwd;
}
bool AT_CellularContext::stack_type_supported(nsapi_ip_stack_t stack_type)
pdp_type_t AT_CellularContext::string_to_pdp_type(const char *pdp_type_str)
{
if (stack_type == _ip_stack_type) {
return true;
} else {
return false;
pdp_type_t pdp_type = DEFAULT_PDP_TYPE;
int len = strlen(pdp_type_str);
if (len == 6 && memcmp(pdp_type_str, "IPV4V6", len) == 0) {
pdp_type = IPV4V6_PDP_TYPE;
} else if (len == 4 && memcmp(pdp_type_str, "IPV6", len) == 0) {
pdp_type = IPV6_PDP_TYPE;
} else if (len == 2 && memcmp(pdp_type_str, "IP", len) == 0) {
pdp_type = IPV4_PDP_TYPE;
} else if (len == 6 && memcmp(pdp_type_str, "Non-IP", len) == 0) {
pdp_type = NON_IP_PDP_TYPE;
}
}
nsapi_ip_stack_t AT_CellularContext::get_stack_type()
{
return _ip_stack_type;
}
nsapi_ip_stack_t AT_CellularContext::string_to_stack_type(const char *pdp_type)
{
nsapi_ip_stack_t stack = DEFAULT_STACK;
int len = strlen(pdp_type);
if (len == 6 && memcmp(pdp_type, "IPV4V6", len) == 0) {
stack = IPV4V6_STACK;
} else if (len == 4 && memcmp(pdp_type, "IPV6", len) == 0) {
stack = IPV6_STACK;
} else if (len == 2 && memcmp(pdp_type, "IP", len) == 0) {
stack = IPV4_STACK;
}
return stack;
return pdp_type;
}
// PDP Context handling
@ -294,7 +309,7 @@ nsapi_error_t AT_CellularContext::do_user_authentication()
{
// if user has defined user name and password we need to call CGAUTH before activating or modifying context
if (_pwd && _uname) {
if (!is_supported(AT_CGAUTH)) {
if (!get_property(PROPERTY_AT_CGAUTH)) {
return NSAPI_ERROR_UNSUPPORTED;
}
_at.cmd_start("AT+CGAUTH=");
@ -311,8 +326,24 @@ nsapi_error_t AT_CellularContext::do_user_authentication()
return NSAPI_ERROR_OK;
}
AT_CellularBase::CellularProperty AT_CellularContext::pdp_type_t_to_cellular_property(pdp_type_t pdp_type)
{
AT_CellularBase::CellularProperty prop = PROPERTY_IPV4_PDP_TYPE;
if (pdp_type == IPV6_PDP_TYPE) {
prop = PROPERTY_IPV6_PDP_TYPE;
} else if (pdp_type == IPV4V6_PDP_TYPE) {
prop = PROPERTY_IPV4V6_PDP_TYPE;
} else if (pdp_type == NON_IP_PDP_TYPE) {
prop = PROPERTY_NON_IP_PDP_TYPE;
}
return prop;
}
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.resp_start("+CGDCONT:");
@ -321,9 +352,6 @@ bool AT_CellularContext::get_context()
char apn[MAX_ACCESSPOINT_NAME_LENGTH];
int apn_len = 0;
bool modem_supports_ipv6 = stack_type_supported(IPV6_STACK);
bool modem_supports_ipv4 = stack_type_supported(IPV4_STACK);
while (_at.info_resp()) {
int cid = _at.read_int();
if (cid > cid_max) {
@ -337,51 +365,20 @@ bool AT_CellularContext::get_context()
if (_apn && (strcmp(apn, _apn) != 0)) {
continue;
}
nsapi_ip_stack_t pdp_stack = string_to_stack_type(pdp_type_from_context);
// Accept dual PDP context for IPv4/IPv6 only modems
if (pdp_stack != DEFAULT_STACK && (stack_type_supported(pdp_stack) || pdp_stack == IPV4V6_STACK)) {
if (_ip_stack_type_requested == IPV4_STACK) {
if (pdp_stack == IPV4_STACK || pdp_stack == IPV4V6_STACK) {
_ip_stack_type = _ip_stack_type_requested;
_cid = cid;
break;
}
} else if (_ip_stack_type_requested == IPV6_STACK) {
if (pdp_stack == IPV6_STACK || pdp_stack == IPV4V6_STACK) {
_ip_stack_type = _ip_stack_type_requested;
_cid = cid;
break;
}
} else {
// requested dual stack or stack is not specified
// If dual PDP need to check for IPV4 or IPV6 modem support. Prefer IPv6.
if (pdp_stack == IPV4V6_STACK) {
if (modem_supports_ipv6) {
_ip_stack_type = IPV6_STACK;
_cid = cid;
break;
} else if (modem_supports_ipv4) {
_ip_stack_type = IPV4_STACK;
_cid = cid;
break;
}
// If PDP is IPV4 or IPV6 they are already checked if supported
} else {
_ip_stack_type = pdp_stack;
_cid = cid;
if (pdp_stack == IPV6_STACK) {
break;
}
if (pdp_stack == IPV4_STACK && !modem_supports_ipv6) {
break;
}
}
}
// APN matched -> Check PDP type
pdp_type_t pdp_type = string_to_pdp_type(pdp_type_from_context);
// Accept exact matching PDP context type or dual PDP context for IPv4/IPv6 only modems
if (get_property(pdp_type_t_to_cellular_property(pdp_type)) ||
((pdp_type == IPV4V6_PDP_TYPE && (modem_supports_ipv4 || modem_supports_ipv6)) && !_nonip_req)) {
_pdp_type = pdp_type;
_cid = cid;
}
}
}
}
_at.resp_stop();
if (_cid == -1) { // no suitable context was found so create a new one
if (!set_new_context(cid_max + 1)) {
@ -401,75 +398,77 @@ bool AT_CellularContext::get_context()
bool AT_CellularContext::set_new_context(int cid)
{
nsapi_ip_stack_t tmp_stack = _ip_stack_type_requested;
bool modem_supports_ipv6 = get_property(PROPERTY_IPV6_PDP_TYPE);
bool modem_supports_ipv4 = get_property(PROPERTY_IPV4_PDP_TYPE);
bool modem_supports_nonip = get_property(PROPERTY_NON_IP_PDP_TYPE);
if (tmp_stack == DEFAULT_STACK) {
bool modem_supports_ipv6 = stack_type_supported(IPV6_STACK);
bool modem_supports_ipv4 = stack_type_supported(IPV4_STACK);
char pdp_type_str[8 + 1] = {0};
pdp_type_t pdp_type = IPV4_PDP_TYPE;
if (modem_supports_ipv6 && modem_supports_ipv4) {
tmp_stack = IPV4V6_STACK;
} else if (modem_supports_ipv6) {
tmp_stack = IPV6_STACK;
} else if (modem_supports_ipv4) {
tmp_stack = IPV4_STACK;
}
}
char pdp_type[8 + 1] = {0};
switch (tmp_stack) {
case IPV4_STACK:
strncpy(pdp_type, "IP", sizeof(pdp_type));
break;
case IPV6_STACK:
strncpy(pdp_type, "IPV6", sizeof(pdp_type));
break;
case IPV4V6_STACK:
strncpy(pdp_type, "IPV6", sizeof(pdp_type)); // try first IPV6 and then fall-back to IPv4
break;
default:
break;
if (_nonip_req && _cp_in_use && modem_supports_nonip) {
strncpy(pdp_type_str, "Non-IP", sizeof(pdp_type_str));
pdp_type = NON_IP_PDP_TYPE;
} else if (modem_supports_ipv6 && modem_supports_ipv4) {
strncpy(pdp_type_str, "IPV4V6", sizeof(pdp_type_str));
pdp_type = IPV4V6_PDP_TYPE;
} else if (modem_supports_ipv6) {
strncpy(pdp_type_str, "IPV6", sizeof(pdp_type_str));
pdp_type = IPV6_PDP_TYPE;
} else if (modem_supports_ipv4) {
strncpy(pdp_type_str, "IP", sizeof(pdp_type));
pdp_type = IPV4_PDP_TYPE;
} else {
return false;
}
//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);
_at.write_string(pdp_type_str);
_at.write_string(_apn);
_at.cmd_stop_read_resp();
success = (_at.get_last_error() == NSAPI_ERROR_OK);
// Fall back to ipv4
if (!success && tmp_stack == IPV4V6_STACK) {
_at.clear_error();
tmp_stack = IPV4_STACK;
_at.cmd_start("AT+FCLASS=0;+CGDCONT=");
_at.write_int(cid);
_at.write_string("IP");
_at.write_string(_apn);
_at.cmd_stop_read_resp();
success = (_at.get_last_error() == NSAPI_ERROR_OK);
}
if (success) {
_ip_stack_type = tmp_stack;
_pdp_type = pdp_type;
_cid = cid;
_new_context_set = true;
tr_info("New PDP context %d, stack %s", _cid, pdp_type);
tr_info("New PDP context %d, type %d", _cid, pdp_type);
}
return success;
}
nsapi_error_t AT_CellularContext::do_activate_context()
{
if (_nonip_req && _cp_in_use) {
return activate_non_ip_context();
}
// In IP case but also when Non-IP is requested and
// control plane optimisation is not established -> activate ip context
_nonip_req = false;
return activate_ip_context();
}
nsapi_error_t AT_CellularContext::activate_ip_context()
{
return activate_context();
}
nsapi_error_t AT_CellularContext::activate_non_ip_context()
{
return activate_context();
}
nsapi_error_t AT_CellularContext::activate_context()
{
_at.lock();
nsapi_error_t err = NSAPI_ERROR_OK;
// try to find or create context with suitable stack
// try to find or create context of suitable type
if (get_context()) {
#if NSAPI_PPP_AVAILABLE
_at.unlock();
@ -576,8 +575,14 @@ void AT_CellularContext::do_connect()
#if NSAPI_PPP_AVAILABLE
nsapi_error_t AT_CellularContext::open_data_channel()
{
// If Non-IP in use fail
if (_pdp_type == NON_IP_PDP_TYPE) {
tr_error("Attempt of PPP connect over NON-IP: failed to CONNECT");
return NSAPI_ERROR_PARAMETER;
}
tr_info("CellularContext PPP connect");
if (is_supported(AT_CGDATA)) {
if (get_property(PROPERTY_AT_CGDATA)) {
_at.cmd_start("AT+CGDATA=\"PPP\",");
_at.write_int(_cid);
} else {
@ -597,11 +602,16 @@ nsapi_error_t AT_CellularContext::open_data_channel()
}
_at.set_is_filehandle_usable(false);
enable_hup(true);
/* Initialize PPP
* If blocking: mbed_ppp_init() is a blocking call, it will block until
connected, or timeout after 30 seconds*/
return nsapi_ppp_connect(_at.get_file_handle(), callback(this, &AT_CellularContext::ppp_status_cb), _uname, _pwd, _ip_stack_type);
nsapi_error_t err = nsapi_ppp_connect(_at.get_file_handle(), callback(this, &AT_CellularContext::ppp_status_cb), _uname, _pwd, (nsapi_ip_stack_t)_pdp_type);
if (err) {
ppp_disconnected();
}
return err;
}
void AT_CellularContext::ppp_status_cb(nsapi_event_t ev, intptr_t ptr)
@ -609,6 +619,8 @@ void AT_CellularContext::ppp_status_cb(nsapi_event_t ev, intptr_t ptr)
tr_debug("ppp_status_cb: event %d, ptr %d", ev, ptr);
if (ev == NSAPI_EVENT_CONNECTION_STATUS_CHANGE && ptr == NSAPI_STATUS_GLOBAL_UP) {
_is_connected = true;
} else if (ev == NSAPI_EVENT_CONNECTION_STATUS_CHANGE && ptr == NSAPI_STATUS_DISCONNECTED) {
ppp_disconnected();
} else {
_is_connected = false;
}
@ -619,6 +631,20 @@ void AT_CellularContext::ppp_status_cb(nsapi_event_t ev, intptr_t ptr)
_device->cellular_callback(ev, ptr);
}
void AT_CellularContext::ppp_disconnected()
{
enable_hup(false);
// after ppp disconnect if we wan't to use same at handler we need to set filehandle again to athandler so it
// will set the correct sigio and nonblocking
_at.lock();
_at.set_is_filehandle_usable(true);
if (!_at.sync(AT_SYNC_TIMEOUT)) { // consume extra characters after ppp disconnect, also it may take a while until modem listens AT commands
tr_error("AT sync failed after PPP Disconnect");
}
_at.unlock();
}
#endif //#if NSAPI_PPP_AVAILABLE
nsapi_error_t AT_CellularContext::disconnect()
@ -633,63 +659,17 @@ nsapi_error_t AT_CellularContext::disconnect()
tr_error("CellularContext disconnect failed!");
// continue even in failure due to ppp disconnect in any case releases filehandle
}
// after ppp disconnect if we wan't to use same at handler we need to set filehandle again to athandler so it
// will set the correct sigio and nonblocking
_at.lock();
_at.set_file_handle(_at.get_file_handle());
_at.set_is_filehandle_usable(true);
if (!_at.sync(AT_SYNC_TIMEOUT)) { // consume extra characters after ppp disconnect, also it may take a while until modem listens AT commands
tr_error("AT sync failed after PPP Disconnect");
}
_at.unlock();
ppp_disconnected();
#endif // NSAPI_PPP_AVAILABLE
_at.lock();
// deactivate a context only if we have activated
if (_is_context_activated) {
// CGACT and CGATT commands might take up to 3 minutes to respond.
_at.set_at_timeout(180 * 1000);
_is_context_active = false;
size_t active_contexts_count = 0;
_at.cmd_start("AT+CGACT?");
_at.cmd_stop();
_at.resp_start("+CGACT:");
while (_at.info_resp()) {
int context_id = _at.read_int();
int context_activation_state = _at.read_int();
if (context_activation_state == 1) {
active_contexts_count++;
if (context_id == _cid) {
_is_context_active = true;
}
}
if (_nonip_req && _cp_in_use) {
deactivate_non_ip_context();
} else {
deactivate_ip_context();
}
_at.resp_stop();
CellularNetwork::RadioAccessTechnology rat = CellularNetwork::RAT_GSM;
// always return NSAPI_ERROR_OK
CellularNetwork::registration_params_t reg_params;
_nw->get_registration_params(reg_params);
rat = reg_params._act;
// 3GPP TS 27.007:
// For EPS, if an attempt is made to disconnect the last PDN connection, then the MT responds with ERROR
if (_is_context_active && (rat < CellularNetwork::RAT_E_UTRAN || active_contexts_count > 1)) {
_at.clear_error();
_at.cmd_start("AT+CGACT=0,");
_at.write_int(_cid);
_at.cmd_stop_read_resp();
}
if (_new_context_set) {
_at.clear_error();
_at.cmd_start("AT+CGDCONT=");
_at.write_int(_cid);
_at.cmd_stop_read_resp();
}
_at.clear_error();
_at.cmd_start("AT+CGATT=0");
_at.cmd_stop_read_resp();
_at.restore_at_timeout();
}
_is_connected = false;
@ -698,6 +678,64 @@ nsapi_error_t AT_CellularContext::disconnect()
return _at.unlock_return_error();
}
void AT_CellularContext::deactivate_ip_context()
{
deactivate_context();
}
void AT_CellularContext::deactivate_non_ip_context()
{
deactivate_context();
}
void AT_CellularContext::deactivate_context()
{
// CGACT and CGATT commands might take up to 3 minutes to respond.
_at.set_at_timeout(180 * 1000);
_is_context_active = false;
size_t active_contexts_count = 0;
_at.cmd_start("AT+CGACT?");
_at.cmd_stop();
_at.resp_start("+CGACT:");
while (_at.info_resp()) {
int context_id = _at.read_int();
int context_activation_state = _at.read_int();
if (context_activation_state == 1) {
active_contexts_count++;
if (context_id == _cid) {
_is_context_active = true;
}
}
}
_at.resp_stop();
CellularNetwork::RadioAccessTechnology rat = CellularNetwork::RAT_GSM;
// always return NSAPI_ERROR_OK
CellularNetwork::registration_params_t reg_params;
_nw->get_registration_params(reg_params);
rat = reg_params._act;
// 3GPP TS 27.007:
// For EPS, if an attempt is made to disconnect the last PDN connection, then the MT responds with ERROR
if (_is_context_active && (rat < CellularNetwork::RAT_E_UTRAN || active_contexts_count > 1)) {
_at.clear_error();
_at.cmd_start("AT+CGACT=0,");
_at.write_int(_cid);
_at.cmd_stop_read_resp();
}
if (_new_context_set) {
_at.clear_error();
_at.cmd_start("AT+CGDCONT=");
_at.write_int(_cid);
_at.cmd_stop_read_resp();
}
_at.clear_error();
_at.cmd_start("AT+CGATT=0");
_at.cmd_stop_read_resp();
_at.restore_at_timeout();
}
nsapi_error_t AT_CellularContext::get_apn_backoff_timer(int &backoff_timer)
{
// If apn is set
@ -838,14 +876,13 @@ void AT_CellularContext::cellular_callback(nsapi_event_t ev, intptr_t ptr)
cell_callback_data_t *data = (cell_callback_data_t *)ptr;
cellular_connection_status_t st = (cellular_connection_status_t)ev;
_cb_data.error = data->error;
tr_debug("CellularContext: event %d, err %d, data %d", ev, data->error, data->status_data);
#if USE_APN_LOOKUP
if (st == CellularSIMStatusChanged && data->status_data == CellularSIM::SimStateReady &&
if (st == CellularSIMStatusChanged && data->status_data == CellularDevice::SimStateReady &&
_cb_data.error == NSAPI_ERROR_OK) {
if (!_apn) {
char imsi[MAX_IMSI_LENGTH + 1];
wait(1); // need to wait to access SIM in some modems
_cb_data.error = _device->open_sim()->get_imsi(imsi);
_cb_data.error = _device->open_information()->get_imsi(imsi, sizeof(imsi));
if (_cb_data.error == NSAPI_ERROR_OK) {
const char *apn_config = apnconfig(imsi);
if (apn_config) {
@ -863,7 +900,7 @@ void AT_CellularContext::cellular_callback(nsapi_event_t ev, intptr_t ptr)
_semaphore.release();
}
}
_device->close_sim();
_device->close_information();
}
}
#endif // USE_APN_LOOKUP
@ -872,6 +909,15 @@ void AT_CellularContext::cellular_callback(nsapi_event_t ev, intptr_t ptr)
_nw = _device->open_network(_fh);
}
if (_cp_req && !_cp_in_use && (data->error == NSAPI_ERROR_OK) &&
(st == CellularSIMStatusChanged && data->status_data == CellularDevice::SimStateReady)) {
if (setup_control_plane_opt() != NSAPI_ERROR_OK) {
tr_error("Control plane SETUP failed!");
} else {
tr_info("Control plane SETUP success!");
}
}
if (_is_blocking) {
if (data->error != NSAPI_ERROR_OK) {
// operation failed, release semaphore
@ -879,7 +925,7 @@ void AT_CellularContext::cellular_callback(nsapi_event_t ev, intptr_t ptr)
} else {
if ((st == CellularDeviceReady && _current_op == OP_DEVICE_READY) ||
(st == CellularSIMStatusChanged && _current_op == OP_SIM_READY &&
data->status_data == CellularSIM::SimStateReady)) {
data->status_data == CellularDevice::SimStateReady)) {
// target reached, release semaphore
_semaphore.release();
} else if (st == CellularRegistrationStatusChanged && (data->status_data == CellularNetwork::RegisteredHomeNetwork ||
@ -905,7 +951,6 @@ void AT_CellularContext::cellular_callback(nsapi_event_t ev, intptr_t ptr)
}
}
} else {
tr_debug("CellularContext: event %d, ptr %d", ev, ptr);
#if NSAPI_PPP_AVAILABLE
if (_is_blocking) {
if (ev == NSAPI_EVENT_CONNECTION_STATUS_CHANGE && ptr == NSAPI_STATUS_GLOBAL_UP) {
@ -939,3 +984,61 @@ void AT_CellularContext::call_network_cb(nsapi_connection_status_t status)
}
}
}
ControlPlane_netif *AT_CellularContext::get_cp_netif()
{
tr_error("No control plane interface available from base context!");
return NULL;
}
nsapi_error_t AT_CellularContext::setup_control_plane_opt()
{
// check if control plane optimization already set
mbed::CellularNetwork::CIoT_Supported_Opt supported_network_opt;
if (_nw->get_ciot_network_optimization_config(supported_network_opt)) {
return NSAPI_ERROR_DEVICE_ERROR;
}
if (supported_network_opt == mbed::CellularNetwork::CIOT_OPT_CONTROL_PLANE ||
supported_network_opt == mbed::CellularNetwork::CIOT_OPT_BOTH) {
_cp_in_use = true;
return NSAPI_ERROR_OK;
}
// ciot optimization not set by app so need to set it now
nsapi_error_t ciot_opt_ret;
ciot_opt_ret = _nw->set_ciot_optimization_config(mbed::CellularNetwork::CIOT_OPT_CONTROL_PLANE,
mbed::CellularNetwork::PREFERRED_UE_OPT_CONTROL_PLANE,
callback(this, &AT_CellularContext::ciot_opt_cb));
if (ciot_opt_ret != NSAPI_ERROR_OK) {
return ciot_opt_ret;
}
//wait for control plane opt call back to release semaphore
_cp_opt_semaphore.wait(CP_OPT_NW_REPLY_TIMEOUT);
if (_cp_in_use) {
return NSAPI_ERROR_OK;
}
return NSAPI_ERROR_DEVICE_ERROR;
}
void AT_CellularContext::ciot_opt_cb(mbed::CellularNetwork::CIoT_Supported_Opt ciot_opt)
{
if (ciot_opt == mbed::CellularNetwork::CIOT_OPT_CONTROL_PLANE ||
ciot_opt == mbed::CellularNetwork::CIOT_OPT_BOTH) {
_cp_in_use = true;
}
_cp_opt_semaphore.release();
}
void AT_CellularContext::set_disconnect()
{
_is_connected = false;
cell_callback_data_t data;
data.error = NSAPI_STATUS_DISCONNECTED;
_device->cellular_callback(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, (intptr_t)&data);
}

View File

@ -27,7 +27,7 @@ namespace mbed {
class AT_CellularContext : public CellularContext, public AT_CellularBase {
public:
AT_CellularContext(ATHandler &at, CellularDevice *device, const char *apn = 0);
AT_CellularContext(ATHandler &at, CellularDevice *device, const char *apn = 0, bool cp_req = false, bool nonip_req = false);
virtual ~AT_CellularContext();
// from CellularBase/NetworkInterface
@ -58,6 +58,10 @@ public:
virtual nsapi_error_t register_to_network();
virtual nsapi_error_t attach_to_network();
virtual void set_file_handle(FileHandle *fh);
virtual void set_file_handle(UARTSerial *serial, PinName dcd_pin = NC, bool active_high = false);
virtual void enable_hup(bool enable);
virtual ControlPlane_netif *get_cp_netif();
protected:
virtual void cellular_callback(nsapi_event_t ev, intptr_t ptr);
@ -76,12 +80,6 @@ protected:
*/
virtual void do_connect();
/** Check if modem supports the given stack type. Can be overridden by the modem.
*
* @return true if supported
*/
virtual bool stack_type_supported(nsapi_ip_stack_t stack_type);
/** Get the operation specific timeout. Used in synchronous mode when setting the maximum
* waiting time. Modem specific implementation can override this to provide different timeouts.
*
@ -96,21 +94,31 @@ protected:
*/
void call_network_cb(nsapi_connection_status_t status);
virtual nsapi_error_t activate_non_ip_context();
virtual nsapi_error_t setup_control_plane_opt();
virtual void deactivate_non_ip_context();
virtual void set_disconnect();
private:
#if NSAPI_PPP_AVAILABLE
nsapi_error_t open_data_channel();
void ppp_status_cb(nsapi_event_t ev, intptr_t ptr);
void ppp_disconnected();
#endif // #if NSAPI_PPP_AVAILABLE
nsapi_error_t do_activate_context();
nsapi_error_t activate_context();
nsapi_error_t activate_ip_context();
void deactivate_context();
void deactivate_ip_context();
bool set_new_context(int cid);
bool get_context();
nsapi_error_t delete_current_context();
nsapi_ip_stack_t string_to_stack_type(const char *pdp_type);
nsapi_ip_stack_t get_stack_type();
pdp_type_t string_to_pdp_type(const char *pdp_type);
nsapi_error_t check_operation(nsapi_error_t err, ContextOperation op);
AT_CellularBase::CellularProperty pdp_type_t_to_cellular_property(pdp_type_t pdp_type);
void ciot_opt_cb(mbed::CellularNetwork::CIoT_Supported_Opt ciot_opt);
private:
nsapi_ip_stack_t _ip_stack_type_requested;
bool _is_connected;
bool _is_blocking;
ContextOperation _current_op;
@ -119,6 +127,16 @@ private:
CellularNetwork *_nw;
FileHandle *_fh;
rtos::Semaphore _semaphore;
rtos::Semaphore _cp_opt_semaphore;
protected:
// flag indicating if CP was requested to be setup
bool _cp_req;
// flag indicating if Non-IP context was requested to be setup
bool _nonip_req;
// tells if CCIOTOPTI received green from network for CP optimisation use
bool _cp_in_use;
};
} // namespace mbed

View File

@ -15,11 +15,10 @@
* limitations under the License.
*/
#include "CellularUtil.h"
#include "AT_CellularDevice.h"
#include "AT_CellularInformation.h"
#include "AT_CellularNetwork.h"
#include "AT_CellularPower.h"
#include "AT_CellularSIM.h"
#include "AT_CellularSMS.h"
#include "AT_CellularContext.h"
#include "AT_CellularStack.h"
@ -28,15 +27,20 @@
#include "UARTSerial.h"
#include "FileHandle.h"
using namespace mbed_cellular_util;
using namespace events;
using namespace mbed;
#define DEFAULT_AT_TIMEOUT 1000 // at default timeout in milliseconds
const int MAX_SIM_RESPONSE_LENGTH = 16;
AT_CellularDevice::AT_CellularDevice(FileHandle *fh) : CellularDevice(fh), _network(0), _sms(0),
_sim(0), _power(0), _information(0), _context_list(0), _default_timeout(DEFAULT_AT_TIMEOUT),
_information(0), _context_list(0), _default_timeout(DEFAULT_AT_TIMEOUT),
_modem_debug_on(false)
{
MBED_ASSERT(fh);
_at = get_at_handler(fh);
MBED_ASSERT(_at);
}
AT_CellularDevice::~AT_CellularDevice()
@ -46,14 +50,10 @@ AT_CellularDevice::~AT_CellularDevice()
// make sure that all is deleted even if somewhere close was not called and reference counting is messed up.
_network_ref_count = 1;
_sms_ref_count = 1;
_power_ref_count = 1;
_sim_ref_count = 1;
_info_ref_count = 1;
close_network();
close_sms();
close_power();
close_sim();
close_information();
AT_CellularContext *curr = _context_list;
@ -65,6 +65,28 @@ AT_CellularDevice::~AT_CellularDevice()
curr = next;
release_at_handler(at);
}
release_at_handler(_at);
}
nsapi_error_t AT_CellularDevice::hard_power_on()
{
return NSAPI_ERROR_OK;
}
nsapi_error_t AT_CellularDevice::hard_power_off()
{
return NSAPI_ERROR_OK;
}
nsapi_error_t AT_CellularDevice::soft_power_on()
{
return NSAPI_ERROR_OK;
}
nsapi_error_t AT_CellularDevice::soft_power_off()
{
return NSAPI_ERROR_OK;
}
// each parser is associated with one filehandle (that is UART)
@ -92,38 +114,115 @@ nsapi_error_t AT_CellularDevice::release_at_handler(ATHandler *at_handler)
}
}
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));
if (len != -1) {
if (len >= 5 && memcmp(simstr, "READY", 5) == 0) {
state = SimStateReady;
} else if (len >= 7 && memcmp(simstr, "SIM PIN", 7) == 0) {
state = SimStatePinNeeded;
} else if (len >= 7 && memcmp(simstr, "SIM PUK", 7) == 0) {
state = SimStatePukNeeded;
} else {
simstr[len] = '\0';
tr_error("Unknown SIM state %s", simstr);
state = SimStateUnknown;
}
} else {
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:
tr_info("SIM PIN required");
break;
case SimStatePukNeeded:
tr_error("SIM PUK required");
break;
case SimStateUnknown:
tr_warn("SIM state unknown");
break;
default:
tr_info("SIM is ready");
break;
}
#endif
return error;
}
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;
if (get_sim_state(state) == NSAPI_ERROR_OK && state == SimStateReady) {
return NSAPI_ERROR_OK;
}
if (sim_pin == NULL) {
return NSAPI_ERROR_PARAMETER;
}
_at->lock();
_at->cmd_start("AT+CPIN=");
_at->write_string(sim_pin);
_at->cmd_stop_read_resp();
return _at->unlock_return_error();
}
CellularContext *AT_CellularDevice::get_context_list() const
{
return _context_list;
}
CellularContext *AT_CellularDevice::create_context(FileHandle *fh, const char *apn)
CellularContext *AT_CellularDevice::create_context(UARTSerial *serial, const char *const apn, PinName dcd_pin,
bool active_high, bool cp_req, bool nonip_req)
{
ATHandler *atHandler = get_at_handler(fh);
if (atHandler) {
AT_CellularContext *ctx = create_context_impl(*atHandler, apn);
AT_CellularContext *curr = _context_list;
if (_context_list == NULL) {
_context_list = ctx;
return ctx;
}
AT_CellularContext *prev;
while (curr) {
prev = curr;
curr = (AT_CellularContext *)curr->_next;
}
prev->_next = ctx;
return ctx;
// Call FileHandle base version - explict upcast to avoid recursing into ourselves
CellularContext *ctx = create_context(static_cast<FileHandle *>(serial), apn, cp_req, nonip_req);
if (serial) {
ctx->set_file_handle(serial, dcd_pin, active_high);
}
return NULL;
return ctx;
}
AT_CellularContext *AT_CellularDevice::create_context_impl(ATHandler &at, const char *apn)
CellularContext *AT_CellularDevice::create_context(FileHandle *fh, const char *apn, bool cp_req, bool nonip_req)
{
return new AT_CellularContext(at, this, apn);
AT_CellularContext *ctx = create_context_impl(*get_at_handler(fh), apn, cp_req, nonip_req);
AT_CellularContext *curr = _context_list;
if (_context_list == NULL) {
_context_list = ctx;
return ctx;
}
AT_CellularContext *prev;
while (curr) {
prev = curr;
curr = (AT_CellularContext *)curr->_next;
}
prev->_next = ctx;
return ctx;
}
AT_CellularContext *AT_CellularDevice::create_context_impl(ATHandler &at, const char *apn, bool cp_req, bool nonip_req)
{
if (cp_req) {
}
return new AT_CellularContext(at, this, apn, cp_req, nonip_req);
}
void AT_CellularDevice::delete_context(CellularContext *context)
@ -153,70 +252,27 @@ void AT_CellularDevice::delete_context(CellularContext *context)
CellularNetwork *AT_CellularDevice::open_network(FileHandle *fh)
{
if (!_network) {
ATHandler *atHandler = get_at_handler(fh);
if (atHandler) {
_network = open_network_impl(*atHandler);
}
}
if (_network) {
_network_ref_count++;
_network = open_network_impl(*get_at_handler(fh));
}
_network_ref_count++;
return _network;
}
CellularSMS *AT_CellularDevice::open_sms(FileHandle *fh)
{
if (!_sms) {
ATHandler *atHandler = get_at_handler(fh);
if (atHandler) {
_sms = open_sms_impl(*atHandler);
}
}
if (_sms) {
_sms_ref_count++;
_sms = open_sms_impl(*get_at_handler(fh));
}
_sms_ref_count++;
return _sms;
}
CellularSIM *AT_CellularDevice::open_sim(FileHandle *fh)
{
if (!_sim) {
ATHandler *atHandler = get_at_handler(fh);
if (atHandler) {
_sim = open_sim_impl(*atHandler);
}
}
if (_sim) {
_sim_ref_count++;
}
return _sim;
}
CellularPower *AT_CellularDevice::open_power(FileHandle *fh)
{
if (!_power) {
ATHandler *atHandler = get_at_handler(fh);
if (atHandler) {
_power = open_power_impl(*atHandler);
}
}
if (_power) {
_power_ref_count++;
}
return _power;
}
CellularInformation *AT_CellularDevice::open_information(FileHandle *fh)
{
if (!_information) {
ATHandler *atHandler = get_at_handler(fh);
if (atHandler) {
_information = open_information_impl(*atHandler);
}
}
if (_information) {
_info_ref_count++;
_information = open_information_impl(*get_at_handler(fh));
}
_info_ref_count++;
return _information;
}
@ -230,16 +286,6 @@ AT_CellularSMS *AT_CellularDevice::open_sms_impl(ATHandler &at)
return new AT_CellularSMS(at);
}
AT_CellularPower *AT_CellularDevice::open_power_impl(ATHandler &at)
{
return new AT_CellularPower(at);
}
AT_CellularSIM *AT_CellularDevice::open_sim_impl(ATHandler &at)
{
return new AT_CellularSIM(at);
}
AT_CellularInformation *AT_CellularDevice::open_information_impl(ATHandler &at)
{
return new AT_CellularInformation(at);
@ -271,32 +317,6 @@ void AT_CellularDevice::close_sms()
}
}
void AT_CellularDevice::close_power()
{
if (_power) {
_power_ref_count--;
if (_power_ref_count == 0) {
ATHandler *atHandler = &_power->get_at_handler();
delete _power;
_power = NULL;
release_at_handler(atHandler);
}
}
}
void AT_CellularDevice::close_sim()
{
if (_sim) {
_sim_ref_count--;
if (_sim_ref_count == 0) {
ATHandler *atHandler = &_sim->get_at_handler();
delete _sim;
_sim = NULL;
release_at_handler(atHandler);
}
}
}
void AT_CellularDevice::close_information()
{
if (_information) {
@ -329,19 +349,177 @@ void AT_CellularDevice::modem_debug_on(bool on)
ATHandler::set_debug_list(_modem_debug_on);
}
nsapi_error_t AT_CellularDevice::init_module()
nsapi_error_t AT_CellularDevice::init()
{
#if MBED_CONF_MBED_TRACE_ENABLE
CellularInformation *information = open_information();
if (information) {
char *pbuf = new char[100];
nsapi_error_t ret = information->get_model(pbuf, sizeof(*pbuf));
close_information();
if (ret == NSAPI_ERROR_OK) {
tr_info("Model %s", pbuf);
}
delete[] pbuf;
}
#endif
return NSAPI_ERROR_OK;
_at->lock();
_at->flush();
_at->cmd_start("ATE0"); // echo off
_at->cmd_stop_read_resp();
_at->cmd_start("AT+CMEE=1"); // verbose responses
_at->cmd_stop_read_resp();
_at->cmd_start("AT+CFUN=1"); // set full functionality
_at->cmd_stop_read_resp();
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();
}
nsapi_error_t AT_CellularDevice::is_ready()
{
_at->lock();
_at->cmd_start("AT");
_at->cmd_stop_read_resp();
// 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();
return _at->unlock_return_error();
}
void AT_CellularDevice::set_ready_cb(Callback<void()> callback)
{
}
nsapi_error_t AT_CellularDevice::set_power_save_mode(int periodic_time, int active_time)
{
_at->lock();
if (periodic_time == 0 && active_time == 0) {
// disable PSM
_at->cmd_start("AT+CPSMS=");
_at->write_int(0);
_at->cmd_stop_read_resp();
} else {
const int PSMTimerBits = 5;
/**
Table 10.5.163a/3GPP TS 24.008: GPRS Timer 3 information element
Bits 5 to 1 represent the binary coded timer value.
Bits 6 to 8 defines the timer value unit for the GPRS timer as follows:
8 7 6
0 0 0 value is incremented in multiples of 10 minutes
0 0 1 value is incremented in multiples of 1 hour
0 1 0 value is incremented in multiples of 10 hours
0 1 1 value is incremented in multiples of 2 seconds
1 0 0 value is incremented in multiples of 30 seconds
1 0 1 value is incremented in multiples of 1 minute
1 1 0 value is incremented in multiples of 320 hours (NOTE 1)
1 1 1 value indicates that the timer is deactivated (NOTE 2).
*/
char pt[8 + 1]; // timer value encoded as 3GPP IE
const int ie_value_max = 0x1f;
uint32_t periodic_timer = 0;
if (periodic_time <= 2 * ie_value_max) { // multiples of 2 seconds
periodic_timer = periodic_time / 2;
strcpy(pt, "01100000");
} else {
if (periodic_time <= 30 * ie_value_max) { // multiples of 30 seconds
periodic_timer = periodic_time / 30;
strcpy(pt, "10000000");
} else {
if (periodic_time <= 60 * ie_value_max) { // multiples of 1 minute
periodic_timer = periodic_time / 60;
strcpy(pt, "10100000");
} else {
if (periodic_time <= 10 * 60 * ie_value_max) { // multiples of 10 minutes
periodic_timer = periodic_time / (10 * 60);
strcpy(pt, "00000000");
} else {
if (periodic_time <= 60 * 60 * ie_value_max) { // multiples of 1 hour
periodic_timer = periodic_time / (60 * 60);
strcpy(pt, "00100000");
} else {
if (periodic_time <= 10 * 60 * 60 * ie_value_max) { // multiples of 10 hours
periodic_timer = periodic_time / (10 * 60 * 60);
strcpy(pt, "01000000");
} else { // multiples of 320 hours
int t = periodic_time / (320 * 60 * 60);
if (t > ie_value_max) {
t = ie_value_max;
}
periodic_timer = t;
strcpy(pt, "11000000");
}
}
}
}
}
}
uint_to_binary_str(periodic_timer, &pt[3], sizeof(pt) - 3, PSMTimerBits);
pt[8] = '\0';
/**
Table 10.5.172/3GPP TS 24.008: GPRS Timer information element
Bits 5 to 1 represent the binary coded timer value.
Bits 6 to 8 defines the timer value unit for the GPRS timer as follows:
8 7 6
0 0 0 value is incremented in multiples of 2 seconds
0 0 1 value is incremented in multiples of 1 minute
0 1 0 value is incremented in multiples of decihours
1 1 1 value indicates that the timer is deactivated.
Other values shall be interpreted as multiples of 1 minute in this version of the protocol.
*/
char at[8 + 1];
uint32_t active_timer; // timer value encoded as 3GPP IE
if (active_time <= 2 * ie_value_max) { // multiples of 2 seconds
active_timer = active_time / 2;
strcpy(at, "00000000");
} else {
if (active_time <= 60 * ie_value_max) { // multiples of 1 minute
active_timer = (1 << 5) | (active_time / 60);
strcpy(at, "00100000");
} else { // multiples of decihours
int t = active_time / (6 * 60);
if (t > ie_value_max) {
t = ie_value_max;
}
active_timer = t;
strcpy(at, "01000000");
}
}
uint_to_binary_str(active_timer, &at[3], sizeof(at) - 3, PSMTimerBits);
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();
if (_at->get_last_error() != NSAPI_ERROR_OK) {
tr_warn("Power save mode not enabled!");
} else {
// network may not agree with power save options but
// that should be fine as timeout is not longer than requested
}
}
return _at->unlock_return_error();
}

View File

@ -25,8 +25,6 @@ namespace mbed {
class ATHandler;
class AT_CellularInformation;
class AT_CellularNetwork;
class AT_CellularPower;
class AT_CellularSIM;
class AT_CellularSMS;
class AT_CellularContext;
@ -41,27 +39,34 @@ public:
AT_CellularDevice(FileHandle *fh);
virtual ~AT_CellularDevice();
virtual CellularContext *create_context(FileHandle *fh = NULL, const char *apn = NULL);
virtual nsapi_error_t hard_power_on();
virtual nsapi_error_t hard_power_off();
virtual nsapi_error_t soft_power_on();
virtual nsapi_error_t soft_power_off();
virtual nsapi_error_t set_pin(const char *sim_pin);
virtual nsapi_error_t get_sim_state(SimState &state);
virtual CellularContext *create_context(FileHandle *fh = NULL, const char *apn = NULL, bool cp_req = false, bool nonip_req = false);
virtual CellularContext *create_context(UARTSerial *serial, const char *const apn, PinName dcd_pin = NC, bool active_high = false, bool cp_req = false, bool nonip_req = false);
virtual void delete_context(CellularContext *context);
virtual CellularNetwork *open_network(FileHandle *fh = NULL);
virtual CellularSMS *open_sms(FileHandle *fh = NULL);
virtual CellularPower *open_power(FileHandle *fh = NULL);
virtual CellularSIM *open_sim(FileHandle *fh = NULL);
virtual CellularInformation *open_information(FileHandle *fh = NULL);
virtual void close_network();
virtual void close_sms();
virtual void close_power();
virtual void close_sim();
virtual void close_information();
virtual void set_timeout(int timeout);
@ -70,7 +75,16 @@ public:
virtual void modem_debug_on(bool on);
virtual nsapi_error_t init_module();
virtual nsapi_error_t init();
virtual nsapi_error_t shutdown();
virtual nsapi_error_t is_ready();
virtual void set_ready_cb(Callback<void()> callback);
virtual nsapi_error_t set_power_save_mode(int periodic_time, int active_time = 0);
virtual ATHandler *get_at_handler(FileHandle *fh);
@ -90,7 +104,7 @@ public:
* @return new instance of class AT_CellularContext
*
*/
virtual AT_CellularContext *create_context_impl(ATHandler &at, const char *apn);
virtual AT_CellularContext *create_context_impl(ATHandler &at, const char *apn, bool cp_req = false, bool nonip_req = false);
/** Create new instance of AT_CellularNetwork or if overridden, modem specific implementation.
*
@ -106,20 +120,6 @@ public:
*/
virtual AT_CellularSMS *open_sms_impl(ATHandler &at);
/** Create new instance of AT_CellularPower or if overridden, modem specific implementation.
*
* @param at ATHandler reference for communication with the modem.
* @return new instance of class AT_CellularPower
*/
virtual AT_CellularPower *open_power_impl(ATHandler &at);
/** Create new instance of AT_CellularSIM or if overridden, modem specific implementation.
*
* @param at ATHandler reference for communication with the modem.
* @return new instance of class AT_CellularSIM
*/
virtual AT_CellularSIM *open_sim_impl(ATHandler &at);
/** Create new instance of AT_CellularInformation or if overridden, modem specific implementation.
*
* @param at ATHandler reference for communication with the modem.
@ -131,12 +131,11 @@ public:
AT_CellularNetwork *_network;
AT_CellularSMS *_sms;
AT_CellularSIM *_sim;
AT_CellularPower *_power;
AT_CellularInformation *_information;
AT_CellularContext *_context_list;
int _default_timeout;
bool _modem_debug_on;
ATHandler *_at;
};
} // namespace mbed

View File

@ -46,11 +46,15 @@ nsapi_error_t AT_CellularInformation::get_revision(char *buf, size_t buf_size)
nsapi_error_t AT_CellularInformation::get_serial_number(char *buf, size_t buf_size, SerialNumberType type)
{
if (buf == NULL || buf_size == 0) {
return NSAPI_ERROR_PARAMETER;
}
if (type == SN) {
return get_info("AT+CGSN", buf, buf_size);
}
if (!is_supported(AT_CGSN_WITH_TYPE)) {
if (!get_property(PROPERTY_AT_CGSN_WITH_TYPE)) {
return NSAPI_ERROR_UNSUPPORTED;
}
@ -66,8 +70,10 @@ nsapi_error_t AT_CellularInformation::get_serial_number(char *buf, size_t buf_si
nsapi_error_t AT_CellularInformation::get_info(const char *cmd, char *buf, size_t buf_size)
{
if (buf == NULL || buf_size == 0) {
return NSAPI_ERROR_PARAMETER;
}
_at.lock();
_at.cmd_start(cmd);
_at.cmd_stop();
_at.set_delimiter(0);
@ -75,6 +81,36 @@ nsapi_error_t AT_CellularInformation::get_info(const char *cmd, char *buf, size_
_at.read_string(buf, buf_size - 1);
_at.resp_stop();
_at.set_default_delimiter();
return _at.unlock_return_error();
}
nsapi_error_t AT_CellularInformation::get_imsi(char *imsi, size_t buf_size)
{
if (imsi == NULL || buf_size == 0 || buf_size < MAX_IMSI_LENGTH + 1) {
return NSAPI_ERROR_PARAMETER;
}
_at.lock();
_at.cmd_start("AT+CIMI");
_at.cmd_stop();
_at.resp_start();
int len = _at.read_string(imsi, MAX_IMSI_LENGTH);
if (len > 0) {
imsi[len] = '\0';
}
_at.resp_stop();
return _at.unlock_return_error();
}
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();
}

View File

@ -42,6 +42,9 @@ public:
virtual nsapi_error_t get_serial_number(char *buf, size_t buf_size, SerialNumberType type);
virtual nsapi_error_t get_imsi(char *imsi, size_t buf_size);
virtual nsapi_error_t get_iccid(char *buf, size_t buf_size);
protected:
/** Request information text from cellular device
*

View File

@ -71,7 +71,8 @@ static const char *const rat_str[AT_CellularNetwork::RAT_MAX] = {
AT_CellularNetwork::AT_CellularNetwork(ATHandler &atHandler) : AT_CellularBase(atHandler),
_connection_status_cb(NULL), _op_act(RAT_UNKNOWN), _connect_status(NSAPI_STATUS_DISCONNECTED)
_connection_status_cb(NULL), _ciotopt_network_support_cb(NULL), _op_act(RAT_UNKNOWN),
_connect_status(NSAPI_STATUS_DISCONNECTED), _supported_network_opt(CIOT_OPT_MAX)
{
_urc_funcs[C_EREG] = callback(this, &AT_CellularNetwork::urc_cereg);
@ -79,7 +80,7 @@ AT_CellularNetwork::AT_CellularNetwork(ATHandler &atHandler) : AT_CellularBase(a
_urc_funcs[C_REG] = callback(this, &AT_CellularNetwork::urc_creg);
for (int type = 0; type < CellularNetwork::C_MAX; type++) {
if (has_registration((RegistrationType)type) != RegistrationModeDisable) {
if (get_property((AT_CellularBase::CellularProperty)type) != RegistrationModeDisable) {
_at.set_urc_handler(at_reg[type].urc_prefix, _urc_funcs[type]);
}
}
@ -87,6 +88,7 @@ AT_CellularNetwork::AT_CellularNetwork(ATHandler &atHandler) : AT_CellularBase(a
_at.set_urc_handler("NO CARRIER", callback(this, &AT_CellularNetwork::urc_no_carrier));
// additional urc to get better disconnect info for application. Not critical.
_at.set_urc_handler("+CGEV:", callback(this, &AT_CellularNetwork::urc_cgev));
_at.set_urc_handler("+CCIOTOPTI:", callback(this, &AT_CellularNetwork::urc_cciotopti));
_at.lock();
_at.cmd_start("AT+CGEREP=1");// 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();
@ -101,13 +103,13 @@ AT_CellularNetwork::~AT_CellularNetwork()
_at.unlock();
for (int type = 0; type < CellularNetwork::C_MAX; type++) {
if (has_registration((RegistrationType)type) != RegistrationModeDisable) {
_at.remove_urc_handler(at_reg[type].urc_prefix);
if (get_property((AT_CellularBase::CellularProperty)type) != RegistrationModeDisable) {
_at.set_urc_handler(at_reg[type].urc_prefix, 0);
}
}
_at.remove_urc_handler("NO CARRIER");
_at.remove_urc_handler("+CGEV:");
_at.set_urc_handler("NO CARRIER", 0);
_at.set_urc_handler("+CGEV:", 0);
}
void AT_CellularNetwork::urc_no_carrier()
@ -221,7 +223,7 @@ nsapi_error_t AT_CellularNetwork::set_registration_urc(RegistrationType type, bo
int index = (int)type;
MBED_ASSERT(index >= 0 && index < C_MAX);
RegistrationMode mode = has_registration(type);
RegistrationMode mode = (RegistrationMode)get_property((AT_CellularBase::CellularProperty)type);
if (mode == RegistrationModeDisable) {
return NSAPI_ERROR_UNSUPPORTED;
} else {
@ -320,12 +322,6 @@ void AT_CellularNetwork::read_reg_params(RegistrationType type, registration_par
#endif
}
AT_CellularNetwork::RegistrationMode AT_CellularNetwork::has_registration(RegistrationType reg_type)
{
(void)reg_type;
return RegistrationModeLAC;
}
nsapi_error_t AT_CellularNetwork::set_attach()
{
_at.lock();
@ -379,6 +375,7 @@ nsapi_error_t AT_CellularNetwork::detach()
nsapi_error_t AT_CellularNetwork::set_access_technology_impl(RadioAccessTechnology opsAct)
{
_op_act = RAT_UNKNOWN;
return NSAPI_ERROR_UNSUPPORTED;
}
@ -433,14 +430,15 @@ nsapi_error_t AT_CellularNetwork::scan_plmn(operList_t &operators, int &opsCount
return _at.unlock_return_error();
}
nsapi_error_t AT_CellularNetwork::set_ciot_optimization_config(Supported_UE_Opt supported_opt,
Preferred_UE_Opt preferred_opt)
nsapi_error_t AT_CellularNetwork::set_ciot_optimization_config(CIoT_Supported_Opt supported_opt,
CIoT_Preferred_UE_Opt preferred_opt,
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(0); // disable urc
_at.write_int(1); //enable CCIOTOPTI URC
_at.write_int(supported_opt);
_at.write_int(preferred_opt);
_at.cmd_stop_read_resp();
@ -448,8 +446,17 @@ nsapi_error_t AT_CellularNetwork::set_ciot_optimization_config(Supported_UE_Opt
return _at.unlock_return_error();
}
nsapi_error_t AT_CellularNetwork::get_ciot_optimization_config(Supported_UE_Opt &supported_opt,
Preferred_UE_Opt &preferred_opt)
void AT_CellularNetwork::urc_cciotopti()
{
_supported_network_opt = (CIoT_Supported_Opt)_at.read_int();
if (_ciotopt_network_support_cb) {
_ciotopt_network_support_cb(_supported_network_opt);
}
}
nsapi_error_t AT_CellularNetwork::get_ciot_ue_optimization_config(CIoT_Supported_Opt &supported_opt,
CIoT_Preferred_UE_Opt &preferred_opt)
{
_at.lock();
@ -459,8 +466,8 @@ nsapi_error_t AT_CellularNetwork::get_ciot_optimization_config(Supported_UE_Opt
_at.resp_start("+CCIOTOPT:");
_at.read_int();
if (_at.get_last_error() == NSAPI_ERROR_OK) {
supported_opt = (Supported_UE_Opt)_at.read_int();
preferred_opt = (Preferred_UE_Opt)_at.read_int();
supported_opt = (CIoT_Supported_Opt)_at.read_int();
preferred_opt = (CIoT_Preferred_UE_Opt)_at.read_int();
}
_at.resp_stop();
@ -468,30 +475,13 @@ nsapi_error_t AT_CellularNetwork::get_ciot_optimization_config(Supported_UE_Opt
return _at.unlock_return_error();
}
nsapi_error_t AT_CellularNetwork::get_extended_signal_quality(int &rxlev, int &ber, int &rscp, int &ecno, int &rsrq, int &rsrp)
nsapi_error_t AT_CellularNetwork::get_ciot_network_optimization_config(CIoT_Supported_Opt &supported_network_opt)
{
_at.lock();
_at.cmd_start("AT+CESQ");
_at.cmd_stop();
_at.resp_start("+CESQ:");
rxlev = _at.read_int();
ber = _at.read_int();
rscp = _at.read_int();
ecno = _at.read_int();
rsrq = _at.read_int();
rsrp = _at.read_int();
_at.resp_stop();
if (rxlev < 0 || ber < 0 || rscp < 0 || ecno < 0 || rsrq < 0 || rsrp < 0) {
_at.unlock();
return NSAPI_ERROR_DEVICE_ERROR;
}
return _at.unlock_return_error();
supported_network_opt = _supported_network_opt;
return NSAPI_ERROR_OK;
}
nsapi_error_t AT_CellularNetwork::get_signal_quality(int &rssi, int &ber)
nsapi_error_t AT_CellularNetwork::get_signal_quality(int &rssi, int *ber)
{
_at.lock();
@ -499,18 +489,27 @@ nsapi_error_t AT_CellularNetwork::get_signal_quality(int &rssi, int &ber)
_at.cmd_stop();
_at.resp_start("+CSQ:");
rssi = _at.read_int();
ber = _at.read_int();
int t_rssi = _at.read_int();
int t_ber = _at.read_int();
_at.resp_stop();
if (rssi < 0 || ber < 0) {
if (t_rssi < 0 || t_ber < 0) {
_at.unlock();
return NSAPI_ERROR_DEVICE_ERROR;
}
if (rssi == 99) {
rssi = 0;
// RSSI value is returned in dBm with range from -51 to -113 dBm, see 3GPP TS 27.007
if (t_rssi == 99) {
rssi = SignalQualityUnknown;
} else {
rssi = -113 + 2 * rssi;
rssi = -113 + 2 * t_rssi;
}
if (ber) {
if (t_ber == 99) {
*ber = SignalQualityUnknown;
} else {
*ber = t_ber;
}
}
return _at.unlock_return_error();
@ -608,7 +607,7 @@ nsapi_error_t AT_CellularNetwork::get_registration_params(RegistrationType type,
int i = (int)type;
MBED_ASSERT(i >= 0 && i < C_MAX);
if (!has_registration(at_reg[i].type)) {
if (!get_property((AT_CellularBase::CellularProperty)at_reg[i].type)) {
return NSAPI_ERROR_UNSUPPORTED;
}
@ -680,3 +679,20 @@ int AT_CellularNetwork::calculate_periodic_tau(const char *periodic_tau_string,
return 0;
}
}
nsapi_error_t AT_CellularNetwork::set_receive_period(int mode, EDRXAccessTechnology act_type, uint8_t edrx_value)
{
char edrx[5];
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();
}

View File

@ -43,6 +43,12 @@ public:
// declare friend so it can access stack
friend class AT_CellularDevice;
enum RegistrationMode {
RegistrationModeDisable = 0,
RegistrationModeEnable, // <stat>
RegistrationModeLAC, // <stat>[,<[lac>,]<[ci>],[<AcT>],[<rac>]]
};
public: // CellularNetwork
virtual nsapi_error_t set_registration(const char *plmn = 0);
@ -63,15 +69,16 @@ public: // CellularNetwork
virtual nsapi_error_t scan_plmn(operList_t &operators, int &ops_count);
virtual nsapi_error_t set_ciot_optimization_config(Supported_UE_Opt supported_opt,
Preferred_UE_Opt preferred_opt);
virtual nsapi_error_t set_ciot_optimization_config(CIoT_Supported_Opt supported_opt,
CIoT_Preferred_UE_Opt preferred_opt,
Callback<void(CIoT_Supported_Opt)> network_support_cb);
virtual nsapi_error_t get_ciot_optimization_config(Supported_UE_Opt &supported_opt,
Preferred_UE_Opt &preferred_opt);
virtual nsapi_error_t get_ciot_ue_optimization_config(CIoT_Supported_Opt &supported_opt,
CIoT_Preferred_UE_Opt &preferred_opt);
virtual nsapi_error_t get_extended_signal_quality(int &rxlev, int &ber, int &rscp, int &ecno, int &rsrq, int &rsrp);
virtual nsapi_error_t get_ciot_network_optimization_config(CIoT_Supported_Opt &supported_network_opt);
virtual nsapi_error_t get_signal_quality(int &rssi, int &ber);
virtual nsapi_error_t get_signal_quality(int &rssi, int *ber = NULL);
virtual int get_3gpp_error();
@ -86,19 +93,10 @@ public: // CellularNetwork
virtual nsapi_error_t get_registration_params(registration_params_t &reg_params);
virtual nsapi_error_t get_registration_params(RegistrationType type, registration_params_t &reg_params);
protected:
/** Check if modem supports given registration type.
*
* @param reg_type enum RegistrationType
* @return mode supported on given reg_type as per 3GPP TS 27.007, 0 when unsupported
*/
enum RegistrationMode {
RegistrationModeDisable = 0,
RegistrationModeEnable, // <stat>
RegistrationModeLAC, // <stat>[,<[lac>,]<[ci>],[<AcT>],[<rac>]]
};
virtual RegistrationMode has_registration(RegistrationType reg_type);
virtual nsapi_error_t set_receive_period(int mode, EDRXAccessTechnology act_type, uint8_t edrx_value);
protected:
/** Sets access technology to be scanned. Modem specific implementation.
*
@ -115,6 +113,7 @@ private:
void urc_cereg();
void urc_cgreg();
void urc_cgev();
void urc_cciotopti();
void read_reg_params_and_compare(RegistrationType type);
void read_reg_params(RegistrationType type, registration_params_t &reg_params);
@ -130,8 +129,11 @@ private:
protected:
Callback<void(nsapi_event_t, intptr_t)> _connection_status_cb;
Callback<void(CIoT_Supported_Opt)> _ciotopt_network_support_cb;
RadioAccessTechnology _op_act;
nsapi_connection_status_t _connect_status;
CIoT_Supported_Opt _supported_network_opt;
registration_params_t _reg_params;
mbed::Callback<void()> _urc_funcs[C_MAX];
};

View File

@ -1,244 +0,0 @@
/*
* Copyright (c) 2017, 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 "AT_CellularPower.h"
#include "CellularUtil.h"
#include "CellularLog.h"
#include "CellularTargets.h"
#include "nsapi_types.h"
static const int PSMTimerBits = 5;
using namespace mbed_cellular_util;
using namespace mbed;
AT_CellularPower::AT_CellularPower(ATHandler &at) : AT_CellularBase(at)
{
}
AT_CellularPower::~AT_CellularPower()
{
}
nsapi_error_t AT_CellularPower::on()
{
return NSAPI_ERROR_UNSUPPORTED;
}
nsapi_error_t AT_CellularPower::off()
{
return NSAPI_ERROR_UNSUPPORTED;
}
nsapi_error_t AT_CellularPower::set_at_mode()
{
_at.lock();
_at.flush();
_at.cmd_start("ATE0"); // echo off
_at.cmd_stop_read_resp();
_at.cmd_start("AT+CMEE=1"); // verbose responses
_at.cmd_stop_read_resp();
return _at.unlock_return_error();
}
nsapi_error_t AT_CellularPower::set_power_level(int func_level, int do_reset)
{
_at.lock();
_at.cmd_start("AT+CFUN=");
_at.write_int(func_level);
_at.write_int(do_reset);
_at.cmd_stop_read_resp();
return _at.unlock_return_error();
}
nsapi_error_t AT_CellularPower::reset()
{
_at.lock();
_at.cmd_start("AT+CFUN=");// reset to full power levels
_at.write_int(1);
_at.write_int(1);
_at.cmd_stop_read_resp();
return _at.unlock_return_error();
}
nsapi_error_t AT_CellularPower::opt_power_save_mode(int periodic_time, int active_time)
{
_at.lock();
if (periodic_time == 0 && active_time == 0) {
// disable PSM
_at.cmd_start("AT+CPSMS=");
_at.write_int(0);
_at.cmd_stop_read_resp();
} else {
/**
Table 10.5.163a/3GPP TS 24.008: GPRS Timer 3 information element
Bits 5 to 1 represent the binary coded timer value.
Bits 6 to 8 defines the timer value unit for the GPRS timer as follows:
8 7 6
0 0 0 value is incremented in multiples of 10 minutes
0 0 1 value is incremented in multiples of 1 hour
0 1 0 value is incremented in multiples of 10 hours
0 1 1 value is incremented in multiples of 2 seconds
1 0 0 value is incremented in multiples of 30 seconds
1 0 1 value is incremented in multiples of 1 minute
1 1 0 value is incremented in multiples of 320 hours (NOTE 1)
1 1 1 value indicates that the timer is deactivated (NOTE 2).
*/
char pt[8 + 1]; // timer value encoded as 3GPP IE
const int ie_value_max = 0x1f;
uint32_t periodic_timer = 0;
if (periodic_time <= 2 * ie_value_max) { // multiples of 2 seconds
periodic_timer = periodic_time / 2;
strcpy(pt, "01100000");
} else {
if (periodic_time <= 30 * ie_value_max) { // multiples of 30 seconds
periodic_timer = periodic_time / 30;
strcpy(pt, "10000000");
} else {
if (periodic_time <= 60 * ie_value_max) { // multiples of 1 minute
periodic_timer = periodic_time / 60;
strcpy(pt, "10100000");
} else {
if (periodic_time <= 10 * 60 * ie_value_max) { // multiples of 10 minutes
periodic_timer = periodic_time / (10 * 60);
strcpy(pt, "00000000");
} else {
if (periodic_time <= 60 * 60 * ie_value_max) { // multiples of 1 hour
periodic_timer = periodic_time / (60 * 60);
strcpy(pt, "00100000");
} else {
if (periodic_time <= 10 * 60 * 60 * ie_value_max) { // multiples of 10 hours
periodic_timer = periodic_time / (10 * 60 * 60);
strcpy(pt, "01000000");
} else { // multiples of 320 hours
int t = periodic_time / (320 * 60 * 60);
if (t > ie_value_max) {
t = ie_value_max;
}
periodic_timer = t;
strcpy(pt, "11000000");
}
}
}
}
}
}
uint_to_binary_str(periodic_timer, &pt[3], sizeof(pt) - 3, PSMTimerBits);
pt[8] = '\0';
/**
Table 10.5.172/3GPP TS 24.008: GPRS Timer information element
Bits 5 to 1 represent the binary coded timer value.
Bits 6 to 8 defines the timer value unit for the GPRS timer as follows:
8 7 6
0 0 0 value is incremented in multiples of 2 seconds
0 0 1 value is incremented in multiples of 1 minute
0 1 0 value is incremented in multiples of decihours
1 1 1 value indicates that the timer is deactivated.
Other values shall be interpreted as multiples of 1 minute in this version of the protocol.
*/
char at[8 + 1];
uint32_t active_timer; // timer value encoded as 3GPP IE
if (active_time <= 2 * ie_value_max) { // multiples of 2 seconds
active_timer = active_time / 2;
strcpy(at, "00000000");
} else {
if (active_time <= 60 * ie_value_max) { // multiples of 1 minute
active_timer = (1 << 5) | (active_time / 60);
strcpy(at, "00100000");
} else { // multiples of decihours
int t = active_time / (6 * 60);
if (t > ie_value_max) {
t = ie_value_max;
}
active_timer = t;
strcpy(at, "01000000");
}
}
uint_to_binary_str(active_timer, &at[3], sizeof(at) - 3, PSMTimerBits);
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();
if (_at.get_last_error() != NSAPI_ERROR_OK) {
tr_warn("Power save mode not enabled!");
} else {
// network may not agree with power save options but
// that should be fine as timeout is not longer than requested
}
}
return _at.unlock_return_error();
}
nsapi_error_t AT_CellularPower::opt_receive_period(int mode, EDRXAccessTechnology act_type, uint8_t edrx_value)
{
char edrx[5];
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();
}
nsapi_error_t AT_CellularPower::is_device_ready()
{
_at.lock();
_at.cmd_start("AT");
_at.cmd_stop_read_resp();
// 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();
return _at.unlock_return_error();
}
nsapi_error_t AT_CellularPower::set_device_ready_urc_cb(mbed::Callback<void()> callback)
{
return NSAPI_ERROR_UNSUPPORTED;
}
void AT_CellularPower::remove_device_ready_urc_cb(mbed::Callback<void()> callback)
{
}

View File

@ -1,60 +0,0 @@
/*
* Copyright (c) 2017, 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.
*/
#ifndef AT_CELLULAR_POWER_H_
#define AT_CELLULAR_POWER_H_
#include "CellularPower.h"
#include "AT_CellularBase.h"
namespace mbed {
/**
* Class AT_CellularPower
*
* Class that provides power handling functions for modem/module.
*/
class AT_CellularPower : public CellularPower, public AT_CellularBase {
public:
AT_CellularPower(ATHandler &atHandler);
virtual ~AT_CellularPower();
public:
virtual nsapi_error_t on();
virtual nsapi_error_t off();
virtual nsapi_error_t set_at_mode();
virtual nsapi_error_t set_power_level(int func_level, int do_reset = 0);
virtual nsapi_error_t reset();
virtual nsapi_error_t opt_power_save_mode(int periodic_time, int active_time);
virtual nsapi_error_t opt_receive_period(int mode, EDRXAccessTechnology act_type, uint8_t edrx_value);
virtual nsapi_error_t is_device_ready();
virtual nsapi_error_t set_device_ready_urc_cb(mbed::Callback<void()> callback);
virtual void remove_device_ready_urc_cb(mbed::Callback<void()> callback);
};
} // namespace mbed
#endif /* AT_CELLULAR_POWER_H_ */

View File

@ -1,155 +0,0 @@
/*
* Copyright (c) 2017, 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 "AT_CellularSIM.h"
#include "CellularLog.h"
using namespace mbed;
const int MAX_SIM_RESPONSE_LENGTH = 16;
AT_CellularSIM::AT_CellularSIM(ATHandler &at) : AT_CellularBase(at)
{
}
AT_CellularSIM::~AT_CellularSIM()
{
}
nsapi_error_t AT_CellularSIM::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));
if (len != -1) {
if (len >= 5 && memcmp(simstr, "READY", 5) == 0) {
state = SimStateReady;
} else if (len >= 6 && memcmp(simstr, "SIM PIN", 6) == 0) {
state = SimStatePinNeeded;
} else if (len >= 6 && memcmp(simstr, "SIM PUK", 6) == 0) {
state = SimStatePukNeeded;
} else {
simstr[len] = '\0';
tr_error("Unknown SIM state %s", simstr);
state = SimStateUnknown;
}
} else {
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:
tr_info("SIM PIN required");
break;
case SimStatePukNeeded:
tr_error("SIM PUK required");
break;
case SimStateUnknown:
tr_warn("SIM state unknown");
break;
default:
tr_info("SIM is ready");
break;
}
#endif
return error;
}
nsapi_error_t AT_CellularSIM::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;
if (get_sim_state(state) == NSAPI_ERROR_OK && state == SimStateReady) {
return NSAPI_ERROR_OK;
}
_at.lock();
_at.cmd_start("AT+CPIN=");
_at.write_string(sim_pin);
_at.cmd_stop_read_resp();
return _at.unlock_return_error();
}
nsapi_error_t AT_CellularSIM::change_pin(const char *sim_pin, const char *new_pin)
{
_at.lock();
_at.cmd_start("AT+CPWD=");
_at.write_string("SC");
_at.write_string(sim_pin);
_at.write_string(new_pin);
_at.cmd_stop_read_resp();
return _at.unlock_return_error();
}
nsapi_error_t AT_CellularSIM::set_pin_query(const char *sim_pin, bool query_pin)
{
_at.lock();
if (query_pin) {
/* use the SIM locked */
_at.cmd_start("AT+CLCK=");
_at.write_string("SC");
_at.write_int(1);
_at.write_string(sim_pin);
_at.cmd_stop_read_resp();
} else {
/* use the SIM unlocked */
_at.cmd_start("AT+CLCK=");
_at.write_string("SC");
_at.write_int(0);
_at.write_string(sim_pin);
_at.cmd_stop_read_resp();
}
return _at.unlock_return_error();
}
nsapi_error_t AT_CellularSIM::get_imsi(char *imsi)
{
if (imsi == NULL) {
return NSAPI_ERROR_PARAMETER;
}
_at.lock();
_at.cmd_start("AT+CIMI");
_at.cmd_stop();
_at.resp_start();
int len = _at.read_string(imsi, MAX_IMSI_LENGTH);
if (len > 0) {
imsi[len] = '\0';
}
_at.resp_stop();
return _at.unlock_return_error();
}
nsapi_error_t AT_CellularSIM::get_iccid(char *buf, size_t buf_size)
{
_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();
}

View File

@ -1,53 +0,0 @@
/*
* Copyright (c) 2017, 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.
*/
#ifndef AT_CELLULAR_SIM_H_
#define AT_CELLULAR_SIM_H_
#include "CellularSIM.h"
#include "AT_CellularBase.h"
namespace mbed {
/**
* Class AT_CellularSIM
*
* Class for SIM card handling.
*/
class AT_CellularSIM : public CellularSIM, public AT_CellularBase {
public:
AT_CellularSIM(ATHandler &atHandler);
virtual ~AT_CellularSIM();
public:
virtual nsapi_error_t set_pin(const char *sim_pin);
virtual nsapi_error_t change_pin(const char *sim_pin, const char *new_pin);
virtual nsapi_error_t set_pin_query(const char *sim_pin, bool query_pin);
virtual nsapi_error_t get_sim_state(SimState &state);
virtual nsapi_error_t get_imsi(char *imsi);
virtual nsapi_error_t get_iccid(char *buf, size_t buf_size);
};
} // namespace mbed
#endif // AT_CELLULAR_SIM_H_

View File

@ -248,10 +248,8 @@ nsapi_error_t AT_CellularSMS::set_csdh(int show_header)
nsapi_error_t AT_CellularSMS::initialize(CellularSMSMmode mode)
{
if (NSAPI_ERROR_OK != _at.set_urc_handler("+CMTI:", callback(this, &AT_CellularSMS::cmti_urc)) ||
NSAPI_ERROR_OK != _at.set_urc_handler("+CMT:", callback(this, &AT_CellularSMS::cmt_urc))) {
return NSAPI_ERROR_NO_MEMORY;
}
_at.set_urc_handler("+CMTI:", callback(this, &AT_CellularSMS::cmti_urc));
_at.set_urc_handler("+CMT:", callback(this, &AT_CellularSMS::cmt_urc));
_at.lock();
set_cnmi(); //set new SMS indication
@ -1047,11 +1045,6 @@ nsapi_error_t AT_CellularSMS::list_messages()
_at.resp_start("+CMGL:");
while (_at.info_resp()) {
info = new sms_info_t();
if (!info) {
_at.resp_stop();
return NSAPI_ERROR_NO_MEMORY;
}
if (_mode == CellularSMSMmodePDU) {
//+CMGL: <index>,<stat>,[<alpha>],<length><CR><LF><pdu>[<CR><LF>
// +CMGL:<index>,<stat>,[<alpha>],<length><CR><LF><pdu>
@ -1062,11 +1055,6 @@ nsapi_error_t AT_CellularSMS::list_messages()
length = length * 2 + 20; // *2 as it's hex encoded and +20 as service center number is not included in size given by CMGL
pdu = new char[length];
memset(pdu, 0, length);
if (!pdu) {
delete info;
_at.resp_stop();
return NSAPI_ERROR_NO_MEMORY;
}
_at.read_string(pdu, length, true);
if (_at.get_last_error() == NSAPI_ERROR_OK) {
info->msg_size = get_data_from_pdu(pdu, info, &part_number);
@ -1194,9 +1182,6 @@ uint16_t AT_CellularSMS::pack_7_bit_gsm_and_hex(const char *str, uint16_t len, c
}
// convert to 7bit gsm first
char *gsm_str = new char[len];
if (!gsm_str) {
return 0;
}
for (uint16_t y = 0; y < len; y++) {
for (int x = 0; x < GSM_TO_ASCII_TABLE_SIZE; x++) {
if (gsm_to_ascii[x] == str[y]) {

View File

@ -116,11 +116,6 @@ nsapi_error_t AT_CellularStack::socket_open(nsapi_socket_t *handle, nsapi_protoc
}
_socket = new CellularSocket*[max_socket_count];
if (!_socket) {
tr_error("No memory to open socket!");
_socket_mutex.unlock();
return NSAPI_ERROR_NO_SOCKET;
}
_socket_count = max_socket_count;
for (int i = 0; i < max_socket_count; i++) {
_socket[i] = 0;

View File

@ -0,0 +1,77 @@
/*AT_ControlPlane_netif.cpp*/
#include "AT_ControlPlane_netif.h"
namespace mbed {
AT_ControlPlane_netif::AT_ControlPlane_netif(ATHandler &at, int cid) : AT_CellularBase(at),
_cid(cid), _cb(NULL), _data(NULL), _recv_len(0)
{
_at.set_urc_handler("+CRTDCP:", mbed::Callback<void()>(this, &AT_ControlPlane_netif::urc_cp_recv));
}
AT_ControlPlane_netif::~AT_ControlPlane_netif()
{}
void AT_ControlPlane_netif::urc_cp_recv()
{
//+CRTDCP: <cid>,<cpdata_length>,<cpdata>
_at.lock();
int cid = _at.read_int();
int cpdata_length = _at.read_int();
int read_len = _at.read_string(_recv_buffer, sizeof(_recv_buffer));
_at.unlock();
// cid not expected to be different because: one context - one file handle
// so this file handle cannot get urc from different context
if (read_len > 0 && read_len == cpdata_length && cid == _cid) {
_recv_len = read_len;
data_received();
}
}
nsapi_size_or_error_t AT_ControlPlane_netif::send(const void *cpdata, nsapi_size_t cpdata_length)
{
//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 AT_ControlPlane_netif::recv(void *cpdata, nsapi_size_t cpdata_length)
{
// If no data received through CRTDCP URC
if (!_recv_len) {
return NSAPI_ERROR_WOULD_BLOCK;
}
// If too small buffer for data
if (_recv_len > cpdata_length) {
return NSAPI_ERROR_DEVICE_ERROR;
}
memcpy(cpdata, _recv_buffer, _recv_len);
return _recv_len = 0;
}
void AT_ControlPlane_netif::attach(void (*callback)(void *), void *data)
{
_cb = callback;
_data = data;
}
void AT_ControlPlane_netif::data_received()
{
// call socket event
if (!_cb) {
return;
}
_cb(_data);
}
} //mbed namespace

View File

@ -0,0 +1,33 @@
#include "ControlPlane_netif.h"
#include "ATHandler.h"
#include "AT_CellularBase.h"
namespace mbed {
class AT_ControlPlane_netif: public ControlPlane_netif, public AT_CellularBase {
public:
AT_ControlPlane_netif(ATHandler &at, int cid);
virtual ~AT_ControlPlane_netif();
protected:
// ControlPlane_netif
// +CSODCP: 3GPP 27007 10.1.43
virtual nsapi_size_or_error_t send(const void *cpdata, nsapi_size_t cpdata_length);
// +CRTDCP: 3GPP 27007 10.1.44
virtual nsapi_size_or_error_t recv(void *cpdata, nsapi_size_t cpdata_length);
virtual void data_received();
virtual void attach(void (*callback)(void *), void *data);
// Id of the PDP context that enables the control plane data connection
int _cid;
private:
void (*_cb)(void *);
void *_data;
char _recv_buffer[MAX_CP_DATA_RECV_LEN];
size_t _recv_len;
void urc_cp_recv();
};
} //mbed namespace

View File

@ -50,9 +50,6 @@ public:
T *add_new()
{
T *temp = new T;
if (!temp) {
return NULL;
}
temp->next = NULL;
if (_head == NULL) {
_head = temp;

View File

@ -16,23 +16,45 @@
*/
#include "CellularContext.h"
MBED_WEAK CellularBase *CellularBase::get_target_default_instance()
{
return mbed::CellularContext::get_default_instance();
}
namespace mbed {
#ifdef CELLULAR_DEVICE
MBED_WEAK CellularContext *CellularContext::get_default_instance()
{
// Uses default APN, uname, password from mbed_app.json
static CellularDevice *dev = CellularDevice::get_default_instance();
CellularDevice *dev = CellularDevice::get_default_instance();
if (!dev) {
return NULL;
}
static CellularContext *context = dev->create_context();
static CellularContext *context = dev->create_context(NULL, NULL, MBED_CONF_CELLULAR_CONTROL_PLANE_OPT);
#if defined(MDMDCD) && defined(MDM_PIN_POLARITY)
context->set_file_handle(static_cast<UARTSerial *>(&dev->get_file_handle()), MDMDCD, MDM_PIN_POLARITY);
#endif // #if defined(MDMDCD) && defined(MDM_PIN_POLARITY)
return context;
}
#else
MBED_WEAK CellularContext *CellularContext::get_default_instance()
MBED_WEAK CellularContext *CellularContext::get_default_nonip_instance()
{
return NULL;
// Uses default APN, uname, password from mbed_app.json
CellularDevice *dev = CellularDevice::get_default_instance();
if (!dev) {
return NULL;
}
static CellularContext *context = dev->create_context(NULL, NULL, MBED_CONF_CELLULAR_CONTROL_PLANE_OPT, true);
#if defined(MDMDCD) && defined(MDM_PIN_POLARITY)
context->set_file_handle(static_cast<UARTSerial *>(&dev->get_file_handle()), MDMDCD, MDM_PIN_POLARITY);
#endif // #if defined(MDMDCD) && defined(MDM_PIN_POLARITY)
return context;
}
void CellularContext::cp_data_received()
{
_cp_netif->data_received();
}
#endif // CELLULAR_DEVICE
} // namespace mbed

View File

@ -17,48 +17,34 @@
#include "CellularDevice.h"
#include "CellularContext.h"
#include "CellularSIM.h"
#include "CellularUtil.h"
#include "CellularLog.h"
#include "CellularTargets.h"
#include "EventQueue.h"
#include "UARTSerial.h"
#ifdef CELLULAR_DEVICE
#include CELLULAR_STRINGIFY(CELLULAR_DEVICE.h)
#endif // CELLULAR_DEVICE
namespace mbed {
#ifdef CELLULAR_DEVICE
MBED_WEAK CellularDevice *CellularDevice::get_default_instance()
{
static UARTSerial serial(MDMTXD, MDMRXD, MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE);
#if DEVICE_SERIAL_FC
if (MDMRTS != NC && MDMCTS != NC) {
tr_info("_USING flow control, MDMRTS: %d MDMCTS: %d", MDMRTS, MDMCTS);
serial.set_flow_control(SerialBase::RTSCTS, MDMRTS, MDMCTS);
}
#endif
static CELLULAR_DEVICE device(&serial);
return &device;
return get_target_default_instance();
}
#else
MBED_WEAK CellularDevice *CellularDevice::get_default_instance()
MBED_WEAK CellularDevice *CellularDevice::get_target_default_instance()
{
return NULL;
}
#endif // CELLULAR_DEVICE
CellularDevice::CellularDevice(FileHandle *fh) : _network_ref_count(0), _sms_ref_count(0), _power_ref_count(0), _sim_ref_count(0),
CellularDevice::CellularDevice(FileHandle *fh) : _network_ref_count(0), _sms_ref_count(0),
_info_ref_count(0), _fh(fh), _queue(5 * EVENTS_EVENT_SIZE), _state_machine(0), _nw(0), _status_cb(0)
{
MBED_ASSERT(fh);
set_sim_pin(NULL);
set_plmn(NULL);
}
CellularDevice::~CellularDevice()
{
tr_debug("CellularDevice destruct");
}
void CellularDevice::stop()
@ -67,6 +53,11 @@ void CellularDevice::stop()
_state_machine->stop();
}
FileHandle &CellularDevice::get_file_handle() const
{
return *_fh;
}
events::EventQueue *CellularDevice::get_queue()
{
return &_queue;
@ -125,6 +116,7 @@ nsapi_error_t CellularDevice::create_state_machine()
_state_machine->set_cellular_callback(callback(this, &CellularDevice::cellular_callback));
err = _state_machine->start_dispatch();
if (err) {
tr_error("Start state machine failed.");
delete _state_machine;
_state_machine = NULL;
}
@ -184,7 +176,7 @@ void CellularDevice::cellular_callback(nsapi_event_t ev, intptr_t ptr)
_state_machine->set_plmn(_plmn);
}
} else if (cell_ev == CellularSIMStatusChanged && ptr_data->error == NSAPI_ERROR_OK &&
ptr_data->status_data == CellularSIM::SimStatePinNeeded) {
ptr_data->status_data == SimStatePinNeeded) {
if (strlen(_sim_pin)) {
_state_machine->set_sim_pin(_sim_pin);
}
@ -212,4 +204,14 @@ void CellularDevice::cellular_callback(nsapi_event_t ev, intptr_t ptr)
}
}
nsapi_error_t CellularDevice::shutdown()
{
CellularContext *curr = get_context_list();
while (curr) {
curr->cellular_callback(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_DISCONNECTED);
curr = (CellularContext *)curr->_next;
}
return NSAPI_ERROR_OK;
}
} // namespace mbed

View File

@ -17,8 +17,6 @@
#include "CellularStateMachine.h"
#include "CellularDevice.h"
#include "CellularPower.h"
#include "CellularSIM.h"
#include "CellularLog.h"
#include "Thread.h"
#include "UARTSerial.h"
@ -47,7 +45,7 @@ namespace mbed {
CellularStateMachine::CellularStateMachine(CellularDevice &device, events::EventQueue &queue) :
_cellularDevice(device), _state(STATE_INIT), _next_state(_state), _target_state(_state),
_event_status_cb(0), _network(0), _power(0), _sim(0), _queue(queue), _queue_thread(0), _sim_pin(0),
_event_status_cb(0), _network(0), _queue(queue), _queue_thread(0), _sim_pin(0),
_retry_count(0), _event_timeout(-1), _event_id(-1), _plmn(0), _command_success(false),
_plmn_network_found(false), _is_retry(false), _cb_data(), _current_event(NSAPI_EVENT_CONNECTION_STATUS_CHANGE),
_network_status(0)
@ -75,6 +73,7 @@ CellularStateMachine::CellularStateMachine(CellularDevice &device, events::Event
CellularStateMachine::~CellularStateMachine()
{
tr_debug("CellularStateMachine destruct");
stop();
}
@ -86,6 +85,7 @@ void CellularStateMachine::reset()
_plmn_network_found = false;
_is_retry = false;
_network_status = 0;
_target_state = STATE_INIT;
enter_to_state(STATE_INIT);
}
@ -101,15 +101,6 @@ void CellularStateMachine::stop()
reset();
_event_id = STM_STOPPED;
if (_power) {
_cellularDevice.close_power();
_power = NULL;
}
if (_sim) {
_cellularDevice.close_sim();
_sim = NULL;
}
if (_network) {
_cellularDevice.close_network();
@ -119,13 +110,9 @@ void CellularStateMachine::stop()
bool CellularStateMachine::power_on()
{
_cb_data.error = _power->on();
if (_cb_data.error != NSAPI_ERROR_OK && _cb_data.error != NSAPI_ERROR_UNSUPPORTED) {
tr_warn("Power on failed. Try to power off/on.");
_cb_data.error = _power->off();
if (_cb_data.error != NSAPI_ERROR_OK && _cb_data.error != NSAPI_ERROR_UNSUPPORTED) {
tr_error("Power off failed!");
}
_cb_data.error = _cellularDevice.hard_power_on();
if (_cb_data.error != NSAPI_ERROR_OK) {
tr_warn("Power on failed.");
return false;
}
return true;
@ -143,15 +130,10 @@ void CellularStateMachine::set_plmn(const char *plmn)
bool CellularStateMachine::open_sim()
{
if (!_sim) {
// can only fail with allocation with new and then it's critical error
_sim = _cellularDevice.open_sim();
}
CellularSIM::SimState state = CellularSIM::SimStateUnknown;
CellularDevice::SimState state = CellularDevice::SimStateUnknown;
// wait until SIM is readable
// here you could add wait(secs) if you know start delay of your SIM
_cb_data.error = _sim->get_sim_state(state);
_cb_data.error = _cellularDevice.get_sim_state(state);
if (_cb_data.error != NSAPI_ERROR_OK) {
tr_info("Waiting for SIM (err while reading)...");
return false;
@ -163,10 +145,10 @@ bool CellularStateMachine::open_sim()
_event_status_cb((nsapi_event_t)CellularSIMStatusChanged, (intptr_t)&_cb_data);
}
if (state == CellularSIM::SimStatePinNeeded) {
if (strlen(_sim_pin)) {
tr_info("Entering PIN to open SIM.");
_cb_data.error = _sim->set_pin(_sim_pin);
if (state == CellularDevice::SimStatePinNeeded) {
if (_sim_pin) {
tr_info("Entering PIN to open SIM");
_cb_data.error = _cellularDevice.set_pin(_sim_pin);
if (_cb_data.error) {
tr_error("Failed to set PIN: error %d", _cb_data.error);
}
@ -178,7 +160,7 @@ bool CellularStateMachine::open_sim()
}
}
return state == CellularSIM::SimStateReady;
return state == CellularDevice::SimStateReady;
}
bool CellularStateMachine::is_registered()
@ -347,10 +329,7 @@ void CellularStateMachine::state_init()
{
_cellularDevice.set_timeout(TIMEOUT_POWER_ON);
tr_info("Start connecting (timeout %d s)", TIMEOUT_POWER_ON / 1000);
if (!_power) {
_power = _cellularDevice.open_power();
}
_cb_data.error = _power->is_device_ready();
_cb_data.error = _cellularDevice.is_ready();
if (_cb_data.error != NSAPI_ERROR_OK) {
_event_timeout = _start_time;
if (_start_time > 0) {
@ -377,9 +356,6 @@ void CellularStateMachine::state_power_on()
bool CellularStateMachine::device_ready()
{
tr_info("Modem ready");
if (_cellularDevice.init_module() != NSAPI_ERROR_OK) {
return false;
}
if (!_network) {
_network = _cellularDevice.open_network();
@ -398,26 +374,25 @@ bool CellularStateMachine::device_ready()
if (_event_status_cb) {
_event_status_cb((nsapi_event_t)CellularDeviceReady, (intptr_t)&_cb_data);
}
_power->remove_device_ready_urc_cb(mbed::callback(this, &CellularStateMachine::ready_urc_cb));
_cellularDevice.close_power();
_power = NULL;
_cellularDevice.set_ready_cb(0);
return true;
}
void CellularStateMachine::state_device_ready()
{
_cellularDevice.set_timeout(TIMEOUT_POWER_ON);
_cb_data.error = _power->set_at_mode();
_cb_data.error = _cellularDevice.soft_power_on();
if (_cb_data.error == NSAPI_ERROR_OK) {
if (device_ready()) {
enter_to_state(STATE_SIM_PIN);
} else {
retry_state_or_fail();
_cb_data.error = _cellularDevice.init();
if (_cb_data.error == NSAPI_ERROR_OK) {
if (device_ready()) {
enter_to_state(STATE_SIM_PIN);
}
}
} else {
}
if (_cb_data.error != NSAPI_ERROR_OK) {
if (_retry_count == 0) {
_power->set_device_ready_urc_cb(mbed::callback(this, &CellularStateMachine::ready_urc_cb));
_cellularDevice.set_ready_cb(callback(this, &CellularStateMachine::device_ready_cb));
}
retry_state_or_fail();
}
@ -443,13 +418,13 @@ void CellularStateMachine::state_sim_pin()
}
if (_network->is_active_context()) { // check if context was already activated
tr_debug("ACTIVE CONTEXT FOUND, skip registering.");
tr_debug("Active context found.");
_network_status |= ACTIVE_PDP_CONTEXT;
}
CellularNetwork::AttachStatus status; // check if modem is already attached to a network
if (_network->get_attach(status) == NSAPI_ERROR_OK && status == CellularNetwork::Attached) {
_network_status |= ATTACHED_TO_NETWORK;
tr_debug("DEVICE IS ALREADY ATTACHED TO NETWORK, skip registering and attach.");
tr_debug("Cellular already attached.");
}
if (_plmn) {
enter_to_state(STATE_MANUAL_REGISTERING_NETWORK);
@ -512,8 +487,6 @@ void CellularStateMachine::state_attaching()
_cb_data.error = _network->set_attach();
}
if (_cb_data.error == NSAPI_ERROR_OK) {
_cellularDevice.close_sim();
_sim = NULL;
if (_event_status_cb) {
_cb_data.status_data = CellularNetwork::Attached;
_event_status_cb(_current_event, (intptr_t)&_cb_data);
@ -543,9 +516,15 @@ void CellularStateMachine::continue_from_state(CellularState state)
nsapi_error_t CellularStateMachine::run_to_state(CellularStateMachine::CellularState state)
{
_mutex.lock();
CellularState tmp_state = state;
if (_plmn && tmp_state == STATE_REGISTERING_NETWORK) {
tmp_state = STATE_MANUAL_REGISTERING_NETWORK;
}
// call pre_event via queue so that it's in same thread and it's safe to decisions
int id = _queue.call_in(0, this, &CellularStateMachine::pre_event, state);
int id = _queue.call_in(0, this, &CellularStateMachine::pre_event, tmp_state);
if (!id) {
report_failure("Failed to call queue.");
stop();
_mutex.unlock();
return NSAPI_ERROR_NO_MEMORY;
@ -586,7 +565,11 @@ bool CellularStateMachine::get_current_status(CellularStateMachine::CellularStat
_mutex.lock();
current_state = _state;
target_state = _target_state;
is_running = _event_id != -1;
if (_event_id == -1 || _event_id == STM_STOPPED) {
is_running = false;
} else {
is_running = true;
}
_mutex.unlock();
return is_running;
}
@ -596,9 +579,8 @@ void CellularStateMachine::event()
#if MBED_CONF_MBED_TRACE_ENABLE
if (_network) {
int rssi;
int ber;
if (_network->get_signal_quality(rssi, ber) == NSAPI_ERROR_OK) {
if (rssi == 0) {
if (_network->get_signal_quality(rssi) == NSAPI_ERROR_OK) {
if (rssi == CellularNetwork::SignalQualityUnknown) {
tr_info("RSSI unknown");
} else {
tr_info("RSSI %d dBm", rssi);
@ -644,7 +626,7 @@ void CellularStateMachine::event()
break;
}
if ((_target_state == _state && _cb_data.error == NSAPI_ERROR_OK && !_is_retry) || _event_id == STM_STOPPED) {
if (check_is_target_reached()) {
_event_id = -1;
return;
}
@ -675,6 +657,7 @@ nsapi_error_t CellularStateMachine::start_dispatch()
_queue_thread = new rtos::Thread(osPriorityNormal, 2048, NULL, "stm_queue");
if (_queue_thread->start(callback(&_queue, &events::EventQueue::dispatch_forever)) != osOK) {
report_failure("Failed to start thread.");
stop();
return NSAPI_ERROR_NO_MEMORY;
}
@ -687,6 +670,20 @@ void CellularStateMachine::set_cellular_callback(mbed::Callback<void(nsapi_event
_event_status_cb = status_cb;
}
bool CellularStateMachine::check_is_target_reached()
{
if (((_target_state == _state || _target_state < _next_state) && _cb_data.error == NSAPI_ERROR_OK && !_is_retry) ||
_event_id == STM_STOPPED) {
if (_target_state != _state && _target_state < _next_state) {
// we are skipping the state, update _state to current state because we have reached it
_state = _target_state;
}
_event_id = -1;
return true;
}
return false;
}
void CellularStateMachine::cellular_event_changed(nsapi_event_t ev, intptr_t ptr)
{
cell_callback_data_t *data = (cell_callback_data_t *)ptr;
@ -699,33 +696,49 @@ void CellularStateMachine::cellular_event_changed(nsapi_event_t ev, intptr_t ptr
if (!_plmn_network_found) {
_plmn_network_found = true;
_queue.cancel(_event_id);
continue_from_state(STATE_ATTACHING_NETWORK);
_is_retry = false;
_event_id = -1;
if (!check_is_target_reached()) {
continue_from_state(STATE_ATTACHING_NETWORK);
}
}
}
} else {
_queue.cancel(_event_id);
continue_from_state(STATE_ATTACHING_NETWORK);
_is_retry = false;
_event_id = -1;
if (!check_is_target_reached()) {
continue_from_state(STATE_ATTACHING_NETWORK);
}
}
}
}
}
void CellularStateMachine::ready_urc_cb()
void CellularStateMachine::device_ready_cb()
{
tr_debug("Device ready URC func called");
if (_state == STATE_DEVICE_READY && _power->set_at_mode() == NSAPI_ERROR_OK) {
tr_debug("Device ready callback");
if (_state == STATE_DEVICE_READY && _cellularDevice.init() == NSAPI_ERROR_OK) {
tr_debug("State was STATE_DEVICE_READY and at mode ready, cancel state and move to next");
_queue.cancel(_event_id);
_event_id = -1;
if (device_ready()) {
continue_from_state(STATE_SIM_PIN);
_is_retry = false;
if (!check_is_target_reached()) {
continue_from_state(STATE_SIM_PIN);
}
} else {
continue_from_state(STATE_DEVICE_READY);
}
}
}
void CellularStateMachine::set_retry_timeout_array(uint16_t timeout[], int array_len)
void CellularStateMachine::set_retry_timeout_array(const uint16_t timeout[], int array_len)
{
if (!timeout || array_len <= 0) {
tr_warn("set_retry_timeout_array, timeout array null or invalid length");
return;
}
_retry_array_length = array_len > RETRY_ARRAY_SIZE ? RETRY_ARRAY_SIZE : array_len;
for (int i = 0; i < _retry_array_length; i++) {

View File

@ -28,8 +28,6 @@ class Thread;
namespace mbed {
class CellularPower;
class CellularSIM;
class CellularDevice;
const int RETRY_ARRAY_SIZE = 10;
@ -43,6 +41,7 @@ private:
// friend of CellularDevice so that it's the only way to close/delete this class.
friend class CellularDevice;
friend class AT_CellularDevice;
friend class UT_CellularStateMachine; // for unit tests
/** Constructor
*
* @param device reference to CellularDevice
@ -99,7 +98,7 @@ private:
* @param timeout timeout array using seconds
* @param array_len length of the array
*/
void set_retry_timeout_array(uint16_t timeout[], int array_len);
void set_retry_timeout_array(const uint16_t timeout[], int array_len);
/** Sets the operator plmn which is used when registering to a network specified by plmn. If plmn is not set then automatic
* registering is used when registering to a cellular network. Does not start any operations.
@ -155,8 +154,9 @@ private:
bool is_registered_to_plmn();
void report_failure(const char *msg);
void event();
void ready_urc_cb();
void device_ready_cb();
void pre_event(CellularState state);
bool check_is_target_reached();
CellularDevice &_cellularDevice;
CellularState _state;
@ -166,8 +166,6 @@ private:
Callback<void(nsapi_event_t, intptr_t)> _event_status_cb;
CellularNetwork *_network;
CellularPower *_power;
CellularSIM *_sim;
events::EventQueue &_queue;
rtos::Thread *_queue_thread;

View File

@ -15,13 +15,12 @@
* limitations under the License.
*/
#include "GEMALTO_CINTERION_CellularNetwork.h"
#include "GEMALTO_CINTERION_CellularContext.h"
#include "GEMALTO_CINTERION_CellularInformation.h"
#include "GEMALTO_CINTERION.h"
#include "AT_CellularInformation.h"
#include "AT_CellularNetwork.h"
#include "CellularLog.h"
using namespace mbed;
using namespace events;
@ -33,22 +32,26 @@ GEMALTO_CINTERION::GEMALTO_CINTERION(FileHandle *fh) : AT_CellularDevice(fh)
{
}
GEMALTO_CINTERION::~GEMALTO_CINTERION()
AT_CellularContext *GEMALTO_CINTERION::create_context_impl(ATHandler &at, const char *apn, bool cp_req, bool nonip_req)
{
return new GEMALTO_CINTERION_CellularContext(at, this, apn, cp_req, nonip_req);
}
AT_CellularNetwork *GEMALTO_CINTERION::open_network_impl(ATHandler &at)
AT_CellularInformation *GEMALTO_CINTERION::open_information_impl(ATHandler &at)
{
return new GEMALTO_CINTERION_CellularNetwork(at);
if (_module == ModuleBGS2) {
return new GEMALTO_CINTERION_CellularInformation(at);
}
return AT_CellularDevice::open_information_impl(at);
}
AT_CellularContext *GEMALTO_CINTERION::create_context_impl(ATHandler &at, const char *apn)
nsapi_error_t GEMALTO_CINTERION::init()
{
return new GEMALTO_CINTERION_CellularContext(at, this, apn);
}
nsapi_error_t err = AT_CellularDevice::init();
if (err != NSAPI_ERROR_OK) {
return err;
}
nsapi_error_t GEMALTO_CINTERION::init_module()
{
CellularInformation *information = open_information();
if (!information) {
return NSAPI_ERROR_NO_MEMORY;
@ -89,31 +92,67 @@ GEMALTO_CINTERION::Module GEMALTO_CINTERION::get_module()
void GEMALTO_CINTERION::init_module_bgs2()
{
// BGS2-W_ATC_V00.100
static const AT_CellularBase::SupportedFeature unsupported_features[] = {
AT_CellularBase::AT_CGSN_WITH_TYPE,
AT_CellularBase::SUPPORTED_FEATURE_END_MARK
static const intptr_t cellular_properties[AT_CellularBase::PROPERTY_MAX] = {
AT_CellularNetwork::RegistrationModeDisable, // C_EREG
AT_CellularNetwork::RegistrationModeEnable, // C_GREG
AT_CellularNetwork::RegistrationModeLAC, // C_REG
0, // AT_CGSN_WITH_TYPE
1, // AT_CGDATA
1, // AT_CGAUTH
1, // PROPERTY_IPV4_STACK
0, // PROPERTY_IPV6_STACK
0, // PROPERTY_IPV4V6_STACK
};
AT_CellularBase::set_unsupported_features(unsupported_features);
AT_CellularBase::set_cellular_properties(cellular_properties);
_module = ModuleBGS2;
}
void GEMALTO_CINTERION::init_module_els61()
{
// ELS61-E2_ATC_V01.000
static const AT_CellularBase::SupportedFeature unsupported_features[] = {
AT_CellularBase::AT_CGSN_WITH_TYPE,
AT_CellularBase::SUPPORTED_FEATURE_END_MARK
static const intptr_t cellular_properties[AT_CellularBase::PROPERTY_MAX] = {
AT_CellularNetwork::RegistrationModeDisable, // C_EREG
AT_CellularNetwork::RegistrationModeEnable, // C_GREG
AT_CellularNetwork::RegistrationModeLAC, // C_REG
0, // AT_CGSN_WITH_TYPE
1, // AT_CGDATA
1, // AT_CGAUTH
1, // PROPERTY_IPV4_STACK
1, // PROPERTY_IPV6_STACK
0, // PROPERTY_IPV4V6_STACK
};
AT_CellularBase::set_unsupported_features(unsupported_features);
AT_CellularBase::set_cellular_properties(cellular_properties);
_module = ModuleELS61;
}
void GEMALTO_CINTERION::init_module_ems31()
{
// EMS31-US_ATC_V4.9.5
static const AT_CellularBase::SupportedFeature unsupported_features[] = {
AT_CellularBase::SUPPORTED_FEATURE_END_MARK
static const intptr_t cellular_properties[AT_CellularBase::PROPERTY_MAX] = {
AT_CellularNetwork::RegistrationModeLAC, // C_EREG
AT_CellularNetwork::RegistrationModeDisable, // C_GREG
AT_CellularNetwork::RegistrationModeDisable, // C_REG
1, // AT_CGSN_WITH_TYPE
1, // AT_CGDATA
1, // AT_CGAUTH
1, // PROPERTY_IPV4_STACK
1, // PROPERTY_IPV6_STACK
1, // PROPERTY_IPV4V6_STACK
};
AT_CellularBase::set_unsupported_features(unsupported_features);
AT_CellularBase::set_cellular_properties(cellular_properties);
_module = ModuleEMS31;
}
#if MBED_CONF_GEMALTO_CINTERION_PROVIDE_DEFAULT
#include "UARTSerial.h"
CellularDevice *CellularDevice::get_default_instance()
{
static UARTSerial serial(MBED_CONF_GEMALTO_CINTERION_TX, MBED_CONF_GEMALTO_CINTERION_RX, MBED_CONF_GEMALTO_CINTERION_BAUDRATE);
#if defined (MBED_CONF_UBLOX_AT_RTS) && defined(MBED_CONF_UBLOX_AT_CTS)
tr_debug("GEMALTO_CINTERION flow control: RTS %d CTS %d", MBED_CONF_GEMALTO_CINTERION_RTS, MBED_CONF_GEMALTO_CINTERION_CTS);
serial.set_flow_control(SerialBase::RTSCTS, MBED_CONF_GEMALTO_CINTERION_RTS, MBED_CONF_GEMALTO_CINTERION_CTS);
#endif
static GEMALTO_CINTERION device(&serial);
return &device;
}
#endif

View File

@ -18,22 +18,22 @@
#ifndef GEMALTO_CINTERION_H_
#define GEMALTO_CINTERION_H_
#ifdef TARGET_FF_ARDUINO
#ifndef MBED_CONF_GEMALTO_CINTERION_TX
#define MBED_CONF_GEMALTO_CINTERION_TX D1
#endif
#ifndef MBED_CONF_GEMALTO_CINTERION_RX
#define MBED_CONF_GEMALTO_CINTERION_RX D0
#endif
#endif /* TARGET_FF_ARDUINO */
#include "AT_CellularDevice.h"
namespace mbed {
class GEMALTO_CINTERION : public AT_CellularDevice {
public:
GEMALTO_CINTERION(FileHandle *fh);
virtual ~GEMALTO_CINTERION();
protected: // AT_CellularDevice
virtual AT_CellularNetwork *open_network_impl(ATHandler &at);
virtual AT_CellularContext *create_context_impl(ATHandler &at, const char *apn);
public:
virtual nsapi_error_t init_module();
virtual uint16_t get_send_delay() const;
/** Actual model of cellular module is needed to make AT command adaptation at runtime
* to support many different models in one cellular driver.
@ -46,6 +46,14 @@ public:
};
static Module get_module();
protected: // AT_CellularDevice
virtual AT_CellularContext *create_context_impl(ATHandler &at, const char *apn, bool cp_req = false, bool nonip_req = false);
virtual AT_CellularInformation *open_information_impl(ATHandler &at);
protected:
virtual uint16_t get_send_delay() const;
virtual nsapi_error_t init();
private:
static Module _module;
void init_module_bgs2();

View File

@ -16,12 +16,12 @@
*/
#include "GEMALTO_CINTERION_CellularContext.h"
#include "GEMALTO_CINTERION_CellularStack.h"
#include "GEMALTO_CINTERION.h"
#include "CellularLog.h"
namespace mbed {
GEMALTO_CINTERION_CellularContext::GEMALTO_CINTERION_CellularContext(ATHandler &at, CellularDevice *device,
const char *apn) : AT_CellularContext(at, device, apn)
const char *apn, bool cp_req, bool nonip_req) : AT_CellularContext(at, device, apn, cp_req, nonip_req)
{
}
@ -32,19 +32,16 @@ GEMALTO_CINTERION_CellularContext::~GEMALTO_CINTERION_CellularContext()
#if !NSAPI_PPP_AVAILABLE
NetworkStack *GEMALTO_CINTERION_CellularContext::get_stack()
{
if (_pdp_type == NON_IP_PDP_TYPE || _cp_in_use) {
tr_error("Requesting stack for NON-IP context! Should request control plane netif: get_cp_netif()");
return NULL;
}
if (!_stack) {
_stack = new GEMALTO_CINTERION_CellularStack(_at, _apn, _cid, _ip_stack_type);
_stack = new GEMALTO_CINTERION_CellularStack(_at, _apn, _cid, (nsapi_ip_stack_t)_pdp_type);
}
return _stack;
}
#endif // NSAPI_PPP_AVAILABLE
bool GEMALTO_CINTERION_CellularContext::stack_type_supported(nsapi_ip_stack_t requested_stack)
{
if (GEMALTO_CINTERION::get_module() == GEMALTO_CINTERION::ModuleBGS2) {
return (requested_stack == IPV4_STACK);
}
return (requested_stack == IPV4_STACK || requested_stack == IPV6_STACK);
}
} /* namespace mbed */

View File

@ -23,14 +23,13 @@ namespace mbed {
class GEMALTO_CINTERION_CellularContext: public AT_CellularContext {
public:
GEMALTO_CINTERION_CellularContext(ATHandler &at, CellularDevice *device, const char *apn);
GEMALTO_CINTERION_CellularContext(ATHandler &at, CellularDevice *device, const char *apn, bool cp_req = false, bool nonip_req = false);
virtual ~GEMALTO_CINTERION_CellularContext();
protected:
#if !NSAPI_PPP_AVAILABLE
virtual NetworkStack *get_stack();
#endif // NSAPI_PPP_AVAILABLE
virtual bool stack_type_supported(nsapi_ip_stack_t requested_stack);
};
} /* namespace mbed */

View File

@ -14,22 +14,24 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "SARA4_PPP_CellularContext.h"
#include "GEMALTO_CINTERION_CellularInformation.h"
namespace mbed {
SARA4_PPP_CellularContext::SARA4_PPP_CellularContext(ATHandler &at, CellularDevice *device, const char *apn) :
AT_CellularContext(at, device, apn)
GEMALTO_CINTERION_CellularInformation::GEMALTO_CINTERION_CellularInformation(ATHandler &at) : AT_CellularInformation(at)
{
}
SARA4_PPP_CellularContext::~SARA4_PPP_CellularContext()
nsapi_error_t GEMALTO_CINTERION_CellularInformation::get_iccid(char *buf, size_t buf_size)
{
}
bool SARA4_PPP_CellularContext::stack_type_supported(nsapi_ip_stack_t requested_stack)
{
return requested_stack == IPV4_STACK ? true : false;
_at.lock();
_at.cmd_start("AT^SCID");
_at.cmd_stop();
_at.resp_start("^SCID:");
_at.read_string(buf, buf_size);
_at.resp_stop();
return _at.unlock_return_error();
}
} /* namespace mbed */

View File

@ -14,22 +14,22 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SARA4_PPP_CELLULARCONTEXT_H_
#define SARA4_PPP_CELLULARCONTEXT_H_
#include "AT_CellularContext.h"
#ifndef GEMALTO_CINTERION_CELLULARINFORMATION_H_
#define GEMALTO_CINTERION_CELLULARINFORMATION_H_
#include "AT_CellularInformation.h"
namespace mbed {
class SARA4_PPP_CellularContext: public AT_CellularContext {
class GEMALTO_CINTERION_CellularInformation: public AT_CellularInformation {
public:
SARA4_PPP_CellularContext(ATHandler &at, CellularDevice *device, const char *apn);
virtual ~SARA4_PPP_CellularContext();
GEMALTO_CINTERION_CellularInformation(ATHandler &at);
protected:
virtual bool stack_type_supported(nsapi_ip_stack_t requested_stack);
public: // AT_CellularInformation
virtual nsapi_error_t get_iccid(char *buf, size_t buf_size);
};
} /* namespace mbed */
#endif // SARA4_PPP_CELLULARCONTEXT_H_
#endif /* GEMALTO_CINTERION_CELLULARINFORMATION_H_ */

View File

@ -1,49 +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 "GEMALTO_CINTERION_CellularNetwork.h"
#include "GEMALTO_CINTERION.h"
using namespace mbed;
GEMALTO_CINTERION_CellularNetwork::GEMALTO_CINTERION_CellularNetwork(ATHandler &atHandler) : AT_CellularNetwork(atHandler)
{
}
GEMALTO_CINTERION_CellularNetwork::~GEMALTO_CINTERION_CellularNetwork()
{
}
AT_CellularNetwork::RegistrationMode GEMALTO_CINTERION_CellularNetwork::has_registration(RegistrationType reg_type)
{
if (GEMALTO_CINTERION::get_module() == GEMALTO_CINTERION::ModuleEMS31) {
return (reg_type == C_EREG) ? RegistrationModeLAC : RegistrationModeDisable;
}
if (GEMALTO_CINTERION::get_module() == GEMALTO_CINTERION::ModuleBGS2) {
if (reg_type == C_GREG) {
return RegistrationModeEnable;
}
return (reg_type == C_REG) ? RegistrationModeLAC : RegistrationModeDisable;
}
return (reg_type == C_REG || reg_type == C_GREG || reg_type == C_EREG) ? RegistrationModeLAC : RegistrationModeDisable;
}
nsapi_error_t GEMALTO_CINTERION_CellularNetwork::set_access_technology_impl(RadioAccessTechnology opsAct)
{
_op_act = RAT_UNKNOWN;
return NSAPI_ERROR_UNSUPPORTED;
}

View File

@ -1,37 +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.
*/
#ifndef GEMALTO_CINTERION_CELLULAR_NETWORK_H_
#define GEMALTO_CINTERION_CELLULAR_NETWORK_H_
#include "AT_CellularNetwork.h"
namespace mbed {
class GEMALTO_CINTERION_CellularNetwork : public AT_CellularNetwork {
public:
GEMALTO_CINTERION_CellularNetwork(ATHandler &atHandler);
virtual ~GEMALTO_CINTERION_CellularNetwork();
protected:
virtual RegistrationMode has_registration(RegistrationType reg_type);
virtual nsapi_error_t set_access_technology_impl(RadioAccessTechnology opsAct);
};
} // namespace mbed
#endif // GEMALTO_CINTERION_CELLULAR_NETWORK_H_

View File

@ -39,9 +39,9 @@ GEMALTO_CINTERION_CellularStack::GEMALTO_CINTERION_CellularStack(ATHandler &atHa
GEMALTO_CINTERION_CellularStack::~GEMALTO_CINTERION_CellularStack()
{
_at.remove_urc_handler("^SIS:");
_at.remove_urc_handler("^SISW:");
_at.remove_urc_handler("^SISR:");
_at.set_urc_handler("^SIS:", 0);
_at.set_urc_handler("^SISW:", 0);
_at.set_urc_handler("^SISR:", 0);
}
GEMALTO_CINTERION_CellularStack::CellularSocket *GEMALTO_CINTERION_CellularStack::find_socket(int sock_id)

View File

@ -0,0 +1,29 @@
{
"name": "GEMALTO_CINTERION",
"config": {
"tx": {
"help": "TX pin for serial connection. D1 assumed if Arduino Form Factor, needs to be set/overwritten otherwise.",
"value": null
},
"rx": {
"help": "RX pin for serial connection. D0 assumed if Arduino Form Factor, needs to be set/overwritten otherwise.",
"value": null
},
"rts": {
"help": "RTS pin for serial connection",
"value": null
},
"cts": {
"help": "CTS pin for serial connection",
"value": null
},
"baudrate" : {
"help": "Serial connection baud rate",
"value": 115200
},
"provide-default": {
"help": "Provide as default CellularDevice [true/false]",
"value": false
}
}
}

View File

@ -0,0 +1,53 @@
/*
* 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 "GENERIC_AT3GPP.h"
#include "AT_CellularNetwork.h"
using namespace mbed;
// by default all properties are supported
static const intptr_t cellular_properties[AT_CellularBase::PROPERTY_MAX] = {
AT_CellularNetwork::RegistrationModeLAC, // C_EREG
AT_CellularNetwork::RegistrationModeLAC, // C_GREG
AT_CellularNetwork::RegistrationModeLAC, // C_REG
1, // AT_CGSN_WITH_TYPE
1, // AT_CGDATA
1, // AT_CGAUTH
1, // PROPERTY_IPV4_STACK
1, // PROPERTY_IPV6_STACK
1, // PROPERTY_IPV4V6_STACK
};
GENERIC_AT3GPP::GENERIC_AT3GPP(FileHandle *fh) : AT_CellularDevice(fh)
{
AT_CellularBase::set_cellular_properties(cellular_properties);
}
#if MBED_CONF_GENERIC_AT3GPP_PROVIDE_DEFAULT
#include "UARTSerial.h"
CellularDevice *CellularDevice::get_default_instance()
{
static UARTSerial serial(MBED_CONF_GENERIC_AT3GPP_TX, MBED_CONF_GENERIC_AT3GPP_RX, MBED_CONF_GENERIC_AT3GPP_BAUDRATE);
#if defined (MBED_CONF_GENERIC_AT3GPP_RTS) && defined(MBED_CONF_GENERIC_AT3GPP_CTS)
tr_debug("GENERIC_AT3GPP flow control: RTS %d CTS %d", MBED_CONF_GENERIC_AT3GPP_RTS, MBED_CONF_GENERIC_AT3GPP_CTS);
serial.set_flow_control(SerialBase::RTSCTS, MBED_CONF_GENERIC_AT3GPP_RTS, MBED_CONF_GENERIC_AT3GPP_CTS);
#endif
static GENERIC_AT3GPP device(&serial);
return &device;
}
#endif

View File

@ -0,0 +1,52 @@
/*
* 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.
*/
#ifndef GENERIC_AT3GPP_H_
#define GENERIC_AT3GPP_H_
#ifdef TARGET_FF_ARDUINO
#ifndef MBED_CONF_GENERIC_AT3GPP_TX
#define MBED_CONF_GENERIC_AT3GPP_TX D1
#endif
#ifndef MBED_CONF_GENERIC_AT3GPP_RX
#define MBED_CONF_GENERIC_AT3GPP_RX D0
#endif
#endif /* TARGET_FF_ARDUINO */
#include "AT_CellularDevice.h"
namespace mbed {
/**
* Generic Cellular module which can be used as a default module when porting new cellular module.
* GENERIC_AT3GPP uses standard 3GPP AT commands (3GPP TS 27.007 V14.5.0 (2017-09)) to communicate with the modem.
*
* GENERIC_AT3GPP can be used as a shield for example on top K64F.
* Cellular example can be used for testing: https://github.com/ARMmbed/mbed-os-example-cellular
* Define in mbed_app.json "target_overrides" correct pins and other setup for your modem.
*
* If new target don't work with GENERIC_AT3GPP then it needs some customizations.
* First thing to try can be checking/modifying cellular_properties array in GENERIC_AT3GPP.cpp, does the module support
* these commands or not? Modify array and if that's not enough then some AT_xxx classes might need to be created and
* methods overridden. Check help how other modules are done what methods they have overridden. Happy porting!
*/
class GENERIC_AT3GPP : public AT_CellularDevice {
public:
GENERIC_AT3GPP(FileHandle *fh);
};
} // namespace mbed
#endif // GENERIC_AT3GPP_H_

View File

@ -0,0 +1,29 @@
{
"name": "GENERIC_AT3GPP",
"config": {
"tx": {
"help": "TX pin for serial connection. D1 assumed if Arduino Form Factor, needs to be set/overwritten otherwise.",
"value": null
},
"rx": {
"help": "RX pin for serial connection. D0 assumed if Arduino Form Factor, needs to be set/overwritten otherwise.",
"value": null
},
"rts": {
"help": "RTS pin for serial connection",
"value": null
},
"cts": {
"help": "CTS pin for serial connection",
"value": null
},
"baudrate" : {
"help": "Serial connection baud rate",
"value": 115200
},
"provide-default": {
"help": "Provide as default CellularDevice [true/false]",
"value": false
}
}
}

View File

@ -17,25 +17,25 @@
#include "SARA4_PPP.h"
#include "SARA4_PPP_CellularNetwork.h"
#include "SARA4_PPP_CellularPower.h"
#include "SARA4_PPP_CellularContext.h"
using namespace mbed;
using namespace events;
static const AT_CellularBase::SupportedFeature unsupported_features[] = {
AT_CellularBase::AT_CGSN_WITH_TYPE,
AT_CellularBase::AT_CGDATA,
AT_CellularBase::SUPPORTED_FEATURE_END_MARK
static const intptr_t cellular_properties[AT_CellularBase::PROPERTY_MAX] = {
AT_CellularNetwork::RegistrationModeDisable,// C_EREG
AT_CellularNetwork::RegistrationModeLAC, // C_GREG
AT_CellularNetwork::RegistrationModeLAC, // C_REG
0, // AT_CGSN_WITH_TYPE
0, // AT_CGDATA
1, // AT_CGAUTH
1, // PROPERTY_IPV4_STACK
0, // PROPERTY_IPV6_STACK
0, // PROPERTY_IPV4V6_STACK
};
SARA4_PPP::SARA4_PPP(FileHandle *fh) : AT_CellularDevice(fh)
{
AT_CellularBase::set_unsupported_features(unsupported_features);
}
SARA4_PPP::~SARA4_PPP()
{
AT_CellularBase::set_cellular_properties(cellular_properties);
}
AT_CellularNetwork *SARA4_PPP::open_network_impl(ATHandler &at)
@ -43,12 +43,16 @@ AT_CellularNetwork *SARA4_PPP::open_network_impl(ATHandler &at)
return new SARA4_PPP_CellularNetwork(at);
}
AT_CellularPower *SARA4_PPP::open_power_impl(ATHandler &at)
#if MBED_CONF_SARA4_PPP_PROVIDE_DEFAULT
#include "UARTSerial.h"
CellularDevice *CellularDevice::get_default_instance()
{
return new SARA4_PPP_CellularPower(at);
}
AT_CellularContext *SARA4_PPP::create_context_impl(ATHandler &at, const char *apn)
{
return new SARA4_PPP_CellularContext(at, this, apn);
static UARTSerial serial(MBED_CONF_SARA4_PPP_TX, MBED_CONF_SARA4_PPP_RX, MBED_CONF_SARA4_PPP_BAUDRATE);
#if defined (MBED_CONF_SARA4_PPP_RTS) && defined (MBED_CONF_SARA4_PPP_CTS)
tr_debug("SARA4_PPP flow control: RTS %d CTS %d", MBED_CONF_SARA4_PPP_RTS, MBED_CONF_SARA4_PPP_CTS);
serial.set_flow_control(SerialBase::RTSCTS, MBED_CONF_SARA4_PPP_RTS, MBED_CONF_SARA4_PPP_CTS);
#endif
static SARA4_PPP device(&serial);
return &device;
}
#endif

View File

@ -18,6 +18,15 @@
#ifndef SARA4_PPP_H_
#define SARA4_PPP_H_
#ifdef TARGET_FF_ARDUINO
#ifndef MBED_CONF_SARA4_PPP_TX
#define MBED_CONF_SARA4_PPP_TX D1
#endif
#ifndef MBED_CONF_SARA4_PPP_RX
#define MBED_CONF_SARA4_PPP_RX D0
#endif
#endif /* TARGET_FF_ARDUINO */
#include "AT_CellularDevice.h"
namespace mbed {
@ -26,12 +35,9 @@ class SARA4_PPP : public AT_CellularDevice {
public:
SARA4_PPP(FileHandle *fh);
virtual ~SARA4_PPP();
public: // CellularDevice
virtual AT_CellularNetwork *open_network_impl(ATHandler &at);
virtual AT_CellularPower *open_power_impl(ATHandler &at);
virtual AT_CellularContext *create_context_impl(ATHandler &at, const char *apn);
};
} // namespace mbed

View File

@ -27,11 +27,6 @@ SARA4_PPP_CellularNetwork::~SARA4_PPP_CellularNetwork()
{
}
AT_CellularNetwork::RegistrationMode SARA4_PPP_CellularNetwork::has_registration(RegistrationType reg_type)
{
return (reg_type == C_REG || reg_type == C_GREG) ? RegistrationModeLAC : RegistrationModeDisable;
}
nsapi_error_t SARA4_PPP_CellularNetwork::set_access_technology_impl(RadioAccessTechnology opRat)
{
_op_act = RAT_CATM1;

View File

@ -28,8 +28,6 @@ public:
virtual ~SARA4_PPP_CellularNetwork();
protected:
virtual RegistrationMode has_registration(RegistrationType rat);
virtual nsapi_error_t set_access_technology_impl(RadioAccessTechnology opRat);
};

View File

@ -1,49 +0,0 @@
/*
* Copyright (c) 2017, 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 "SARA4_PPP_CellularPower.h"
#include "onboard_modem_api.h"
using namespace mbed;
SARA4_PPP_CellularPower::SARA4_PPP_CellularPower(ATHandler &atHandler) : AT_CellularPower(atHandler)
{
}
SARA4_PPP_CellularPower::~SARA4_PPP_CellularPower()
{
}
nsapi_error_t SARA4_PPP_CellularPower::on()
{
#if MODEM_ON_BOARD
::onboard_modem_init();
::onboard_modem_power_up();
#endif
return NSAPI_ERROR_OK;
}
nsapi_error_t SARA4_PPP_CellularPower::off()
{
#if MODEM_ON_BOARD
::onboard_modem_power_down();
#endif
return NSAPI_ERROR_OK;
}

View File

@ -0,0 +1,29 @@
{
"name": "SARA4_PPP",
"config": {
"tx": {
"help": "TX pin for serial connection. D1 assumed if Arduino Form Factor, needs to be set/overwritten otherwise.",
"value": null
},
"rx": {
"help": "RX pin for serial connection. D0 assumed if Arduino Form Factor, needs to be set/overwritten otherwise.",
"value": null
},
"rts": {
"help": "RTS pin for serial connection",
"value": null
},
"cts": {
"help": "CTS pin for serial connection",
"value": null
},
"baudrate" : {
"help": "Serial connection baud rate",
"value": 115200
},
"provide-default": {
"help": "Provide as default CellularDevice [true/false]",
"value": false
}
}
}

Some files were not shown because too many files have changed in this diff Show More