diff --git a/UNITTESTS/features/cellular/framework/AT/at_cellularcontext/at_cellularcontexttest.cpp b/UNITTESTS/features/cellular/framework/AT/at_cellularcontext/at_cellularcontexttest.cpp index 2f5bbdb1997..4d7b80cb98a 100644 --- a/UNITTESTS/features/cellular/framework/AT/at_cellularcontext/at_cellularcontexttest.cpp +++ b/UNITTESTS/features/cellular/framework/AT/at_cellularcontext/at_cellularcontexttest.cpp @@ -53,7 +53,6 @@ class TestAT_CellularContext : public testing::Test { ATHandler_stub::bool_value = false; ATHandler_stub::uint8_value = 0; ATHandler_stub::fh_value = NULL; - ATHandler_stub::callback = NULL; ATHandler_stub::call_immediately = false; ATHandler_stub::resp_info_true_counter = false; ATHandler_stub::info_elem_true_counter = false; @@ -63,6 +62,9 @@ class TestAT_CellularContext : public testing::Test { ATHandler_stub::read_string_table[kRead_string_table_size]; ATHandler_stub::resp_stop_success_count = kResp_stop_count_default; CellularDevice_stub::connect_counter = 2; + for (int i=0; i < kATHandler_urc_table_max_size; i++) { + ATHandler_stub::callback[i] = NULL; + } } void TearDown() diff --git a/UNITTESTS/features/cellular/framework/AT/at_cellularnetwork/at_cellularnetworktest.cpp b/UNITTESTS/features/cellular/framework/AT/at_cellularnetwork/at_cellularnetworktest.cpp index 28c80e11267..9609ab39358 100644 --- a/UNITTESTS/features/cellular/framework/AT/at_cellularnetwork/at_cellularnetworktest.cpp +++ b/UNITTESTS/features/cellular/framework/AT/at_cellularnetwork/at_cellularnetworktest.cpp @@ -211,6 +211,71 @@ TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_get_registration_params) EXPECT_TRUE(reg_params_check._cell_id == -1 && reg_params_check._active_time == -1 && reg_params_check._periodic_tau == -1); } +static int disconnect_cb_count = 0; +static bool disconnect_cb_param_check = false; +static void disconnect_cb(nsapi_event_t ev, intptr_t intptr) +{ + disconnect_cb_count++; + + if (disconnect_cb_count == 3 && disconnect_cb_param_check) { + EXPECT_TRUE(ev == NSAPI_EVENT_CONNECTION_STATUS_CHANGE); + EXPECT_TRUE(intptr == NSAPI_STATUS_DISCONNECTED); + } +} + +TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_registration_status_change) +{ + EventQueue que; + FileHandle_stub fh1; + ATHandler at(&fh1, que, 0, ","); + + AT_CellularNetwork cn(at); + + + cn.attach(&disconnect_cb); + + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + ATHandler_stub::process_oob_urc = true; + + ATHandler_stub::read_string_index = 2; + ATHandler_stub::read_string_table[2] = "+CREG:"; + ATHandler_stub::read_string_table[1] = "00C3"; + ATHandler_stub::read_string_table[0] = "A13F"; + ATHandler_stub::int_count = 2; + //ATHandler_stub::int_valid_count_table[2] = 1; //URC status is skipped + ATHandler_stub::int_valid_count_table[1] = 0; //not registered + ATHandler_stub::int_valid_count_table[0] = 1; + at.process_oob(); + + disconnect_cb_count = 0; + disconnect_cb_param_check = true; + ATHandler_stub::read_string_index = 4; + ATHandler_stub::read_string_table[4] = "+CREG:"; + ATHandler_stub::read_string_table[3] = "00C3"; + ATHandler_stub::read_string_table[2] = "A13F"; + ATHandler_stub::read_string_table[1] = "FF"; + ATHandler_stub::read_string_table[0] = "FF"; + ATHandler_stub::int_count = 2; + //ATHandler_stub::int_valid_count_table[2] = 1; //URC status is skipped + ATHandler_stub::int_valid_count_table[1] = 1; //registered, home network + ATHandler_stub::int_valid_count_table[0] = 1; + at.process_oob(); + + ATHandler_stub::read_string_index = 5; + ATHandler_stub::int_count = 3; + ATHandler_stub::read_string_index = 4; + ATHandler_stub::read_string_table[4] = "+CREG:"; + ATHandler_stub::read_string_table[3] = "00C3"; + ATHandler_stub::read_string_table[2] = "A13F"; + ATHandler_stub::read_string_table[1] = "FF"; + ATHandler_stub::read_string_table[0] = "FF"; + ATHandler_stub::int_count = 2; + //ATHandler_stub::int_valid_count_table[2] = 1; //URC status is skipped + ATHandler_stub::int_valid_count_table[1] = 4; //unknown registration status + ATHandler_stub::int_valid_count_table[0] = 1; + at.process_oob(); +} + TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_get_network_registering_mode) { EventQueue que; diff --git a/UNITTESTS/stubs/ATHandler_stub.cpp b/UNITTESTS/stubs/ATHandler_stub.cpp index ff58ade4ac0..54003807f59 100644 --- a/UNITTESTS/stubs/ATHandler_stub.cpp +++ b/UNITTESTS/stubs/ATHandler_stub.cpp @@ -43,16 +43,19 @@ bool ATHandler_stub::bool_value = false; uint8_t ATHandler_stub::uint8_value = 0; FileHandle_stub *ATHandler_stub::fh_value = NULL; device_err_t ATHandler_stub::device_err_value; -Callback ATHandler_stub::callback = NULL; bool ATHandler_stub::call_immediately = false; uint8_t ATHandler_stub::resp_info_true_counter = false; uint8_t ATHandler_stub::info_elem_true_counter = false; int ATHandler_stub::int_valid_count_table[kRead_int_table_size]; 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]; int ATHandler_stub::resp_stop_success_count = kResp_stop_count_default; +int ATHandler_stub::urc_amount = 0; +mbed::Callback ATHandler_stub::callback[kATHandler_urc_table_max_size]; +char *ATHandler_stub::urc_string_table[kATHandler_urc_table_max_size]; ATHandler::ATHandler(FileHandle *fh, EventQueue &queue, int timeout, const char *output_delimiter, uint16_t send_delay) : _nextATHandler(0), @@ -60,6 +63,14 @@ ATHandler::ATHandler(FileHandle *fh, EventQueue &queue, int timeout, const char _queue(queue) { ATHandler_stub::ref_count = 1; + + ATHandler_stub::process_oob_urc = false; + ATHandler_stub::urc_amount = 0; + int i = 0; + while (i < kATHandler_urc_table_max_size) { + ATHandler_stub::callback[i] = NULL; + ATHandler_stub::urc_string_table[i++] = NULL; + } } void ATHandler::set_debug(bool debug_on) @@ -70,6 +81,16 @@ void ATHandler::set_debug(bool debug_on) ATHandler::~ATHandler() { ATHandler_stub::ref_count = kATHandler_destructor_ref_ount; + + int i = 0; + while (i < kATHandler_urc_table_max_size) { + if (ATHandler_stub::urc_string_table[i]) { + delete [] ATHandler_stub::urc_string_table[i]; + i++; + } else { + break; + } + } } void ATHandler::inc_ref_count() @@ -98,7 +119,18 @@ void ATHandler::set_file_handle(FileHandle *fh) nsapi_error_t ATHandler::set_urc_handler(const char *urc, mbed::Callback cb) { - ATHandler_stub::callback = cb; + if (ATHandler_stub::urc_amount < kATHandler_urc_table_max_size) { + ATHandler_stub::callback[ATHandler_stub::urc_amount] = cb; + ATHandler_stub::urc_string_table[ATHandler_stub::urc_amount] = new char[kATHandler_urc_string_max_size]; + if (urc) { + int bytes_to_copy = strlen(urc) < kATHandler_urc_string_max_size ? strlen(urc) : kATHandler_urc_string_max_size; + memcpy(ATHandler_stub::urc_string_table[ATHandler_stub::urc_amount], urc, bytes_to_copy); + } + ATHandler_stub::urc_amount++; + } else { + ATHandler_stub::callback[0] = cb; + MBED_ASSERT("ATHandler URC amount limit reached"); + } if (ATHandler_stub::call_immediately) { cb(); } @@ -143,6 +175,20 @@ void ATHandler::restore_at_timeout() void ATHandler::process_oob() { + if (ATHandler_stub::process_oob_urc) { + int i = 0; + while (i < ATHandler_stub::urc_amount) { + if (ATHandler_stub::read_string_index >= 0) { + if (!memcmp(ATHandler_stub::urc_string_table[i], + ATHandler_stub::read_string_table[ATHandler_stub::read_string_index], + strlen(ATHandler_stub::urc_string_table[i]))) { + ATHandler_stub::callback[i](); + break; + } + } + i++; + } + } } void ATHandler::clear_error() diff --git a/UNITTESTS/stubs/ATHandler_stub.h b/UNITTESTS/stubs/ATHandler_stub.h index c506ccf0179..e243e355ba0 100644 --- a/UNITTESTS/stubs/ATHandler_stub.h +++ b/UNITTESTS/stubs/ATHandler_stub.h @@ -31,6 +31,8 @@ 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_urc_table_max_size = 10; +static const int kATHandler_urc_string_max_size = 16; namespace ATHandler_stub { extern nsapi_error_t nsapi_error_value; @@ -50,13 +52,16 @@ extern uint8_t info_elem_true_counter; extern uint8_t uint8_value; extern mbed::FileHandle_stub *fh_value; extern mbed::device_err_t device_err_value; -extern mbed::Callback callback; +extern mbed::Callback callback[kATHandler_urc_table_max_size]; extern bool call_immediately; extern const char *read_string_table[kRead_string_table_size]; extern int read_string_index; extern int int_valid_count_table[kRead_int_table_size]; extern int int_count; extern int resp_stop_success_count; +extern bool process_oob_urc; +extern int urc_amount; +extern char *urc_string_table[kATHandler_urc_table_max_size]; } #endif diff --git a/features/cellular/framework/AT/AT_CellularNetwork.cpp b/features/cellular/framework/AT/AT_CellularNetwork.cpp index 6c84f08355c..d04de64d09b 100644 --- a/features/cellular/framework/AT/AT_CellularNetwork.cpp +++ b/features/cellular/framework/AT/AT_CellularNetwork.cpp @@ -161,9 +161,17 @@ void AT_CellularNetwork::read_reg_params_and_compare(RegistrationType type) _connection_status_cb((nsapi_event_t)CellularRadioAccessTechnologyChanged, (intptr_t)&data); } if (reg_params._status != _reg_params._status) { + RegistrationStatus previous_registration_status = _reg_params._status; _reg_params._status = reg_params._status; data.status_data = reg_params._status; _connection_status_cb((nsapi_event_t)CellularRegistrationStatusChanged, (intptr_t)&data); + if (!(reg_params._status == RegisteredHomeNetwork || + reg_params._status == RegisteredRoaming)) { + if (previous_registration_status == RegisteredHomeNetwork || + previous_registration_status == RegisteredRoaming) { + _connection_status_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_DISCONNECTED); + } + } } if (reg_params._cell_id != -1 && reg_params._cell_id != _reg_params._cell_id) { _reg_params._cell_id = reg_params._cell_id;