diff --git a/features/cellular/TESTS/api/cellular_network/main.cpp b/features/cellular/TESTS/api/cellular_network/main.cpp new file mode 100644 index 0000000000..bad4f26881 --- /dev/null +++ b/features/cellular/TESTS/api/cellular_network/main.cpp @@ -0,0 +1,418 @@ +/* + * 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_CellularNetwork.h" +#include "CellularConnectionFSM.h" +#include "CellularDevice.h" +#include "../../cellular_tests_common.h" +#include CELLULAR_STRINGIFY(CELLULAR_DEVICE.h) + +#define NETWORK_TIMEOUT (180*1000) + +static UARTSerial cellular_serial(MDMTXD, MDMRXD, MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE); +static EventQueue queue(8 * EVENTS_EVENT_SIZE); +static rtos::Semaphore network_semaphore(0); +static CellularConnectionFSM cellular; +static CellularConnectionFSM::CellularState cellular_target_state; +static CELLULAR_DEVICE *device; +static CellularNetwork* nw; + + +static bool fsm_callback(int state, int next_state) +{ + if (next_state == cellular_target_state) { + TEST_ASSERT(network_semaphore.release() == osOK); + return false; + } + return true; +} + +// test methods that are already run in state machine (CellularConnectionFSM) but as it might change +// we wan't to run these 'manually' also +static void test_network_interface_fsm() +{ +#if defined (MDMRTS) && defined (MDMCTS) + cellular_serial.set_flow_control(SerialBase::RTSCTS, MDMRTS, MDMCTS); +#endif + device = new CELLULAR_DEVICE(queue); + TEST_ASSERT(device != NULL); + + CellularNetwork* nw = device->open_network(&cellular_serial); + TEST_ASSERT(nw != NULL); + TEST_ASSERT(nw->init() == NSAPI_ERROR_OK); + + delete device; + device = NULL; +} + +static void init_network_interface() +{ + cellular.set_serial(&cellular_serial); + TEST_ASSERT(cellular.init() == NSAPI_ERROR_OK); + cellular.set_callback(&fsm_callback); + TEST_ASSERT(cellular.start_dispatch() == NSAPI_ERROR_OK); + cellular.set_sim_pin(MBED_CONF_APP_CELLULAR_SIM_PIN); +#ifdef MBED_CONF_APP_APN + CellularNetwork *network = cellular.get_network(); + TEST_ASSERT(network->set_credentials(MBED_CONF_APP_APN) == NSAPI_ERROR_OK); +#endif + cellular_target_state = CellularConnectionFSM::STATE_REGISTERING_NETWORK; + TEST_ASSERT(cellular.continue_to_state(cellular_target_state) == NSAPI_ERROR_OK); + TEST_ASSERT(network_semaphore.wait(NETWORK_TIMEOUT) == 1); +} + + +static bool get_network_registration(CellularNetwork::RegistrationType type, + CellularNetwork::RegistrationStatus &status, bool &is_registered) +{ + is_registered = false; + nsapi_error_t err = nw->get_registration_status(type, status); + TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_UNSUPPORTED); + + switch (status) { + case CellularNetwork::RegisteredRoaming: + case CellularNetwork::RegisteredHomeNetwork: + is_registered = true; + break; + case CellularNetwork::RegisteredSMSOnlyRoaming: + case CellularNetwork::RegisteredSMSOnlyHome: + case CellularNetwork::RegisteredCSFBNotPreferredRoaming: + case CellularNetwork::RegisteredCSFBNotPreferredHome: + case CellularNetwork::AttachedEmergencyOnly: + case CellularNetwork::RegistrationDenied: + case CellularNetwork::NotRegistered: + case CellularNetwork::Unknown: + case CellularNetwork::SearchingNetwork: + default: + break; + } + return true; +} + +static bool is_registered() +{ + CellularNetwork::RegistrationStatus status; + bool is_registered = false; + + for (int type = 0; type < CellularNetwork::C_MAX; type++) { + if (get_network_registration((CellularNetwork::RegistrationType) type, status, is_registered)) { + if (is_registered) { + break; + } + } + } + + return is_registered; +} + +static void nw_callback(nsapi_event_t ev, intptr_t intptr) +{ +} + +static void test_network_registration() +{ + cellular.get_device()->set_timeout(10*1000); + nw = cellular.get_network(); + TEST_ASSERT(nw != NULL); + + nw->attach(&nw_callback); + + bool success = false; + for (int type = 0; type < CellularNetwork::C_MAX; type++) { + if (!nw->set_registration_urc((CellularNetwork::RegistrationType)type, true)) { + success = true; + } + } + // each modem should support at least one registration type + TEST_ASSERT(success); + + int sanity_count = 0; + while (is_registered() == false) { + if (sanity_count == 0) { + TEST_ASSERT(nw->set_registration() == NSAPI_ERROR_OK); + } + sanity_count++; + wait(2); + TEST_ASSERT(sanity_count < 60); + } + + // device was registered right away, test set_registration call + if (sanity_count == 0) { + TEST_ASSERT(nw->set_registration() == NSAPI_ERROR_OK); + } + + CellularNetwork::NWRegisteringMode reg_mode = CellularNetwork::NWModeDeRegister; + TEST_ASSERT(nw->get_network_registering_mode(reg_mode) == NSAPI_ERROR_OK); + TEST_ASSERT(reg_mode == CellularNetwork::NWModeAutomatic); +} + +static void test_attach() +{ + TEST_ASSERT(nw->set_attach() == NSAPI_ERROR_OK); + + CellularNetwork::AttachStatus status; + TEST_ASSERT(nw->get_attach(status) == NSAPI_ERROR_OK); + TEST_ASSERT(status == CellularNetwork::Attached); +} + +static void test_activate_context() +{ + TEST_ASSERT(nw->activate_context() == NSAPI_ERROR_OK); +} + +static void test_connect() +{ + TEST_ASSERT(nw->connect() == NSAPI_ERROR_OK); + nsapi_connection_status_t st = nw->get_connection_status(); + TEST_ASSERT(st == NSAPI_STATUS_GLOBAL_UP); +} + +static void test_credentials() +{ + TEST_ASSERT(nw->set_credentials(NULL, "username", "pass") == NSAPI_ERROR_OK); + TEST_ASSERT(nw->set_credentials("internet", NULL, "pass") == NSAPI_ERROR_OK); + TEST_ASSERT(nw->set_credentials("internet", "user", NULL) == NSAPI_ERROR_OK); + TEST_ASSERT(nw->set_credentials("internet", CellularNetwork::NOAUTH, "user", "pass") == NSAPI_ERROR_OK); +} + +static void test_other() +{ + TEST_ASSERT(nw->get_3gpp_error() == 0); + + CellularNetwork::RateControlExceptionReports reports; + CellularNetwork::RateControlUplinkTimeUnit timeUnit; + int uplinkRate; + // can't test values as they are optional + nsapi_error_t err = nw->get_rate_control(reports, timeUnit, uplinkRate); + tr_error("get_rate_control: %d", err); + TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_DEVICE_ERROR); +#if CELLULAR_DEVICE != QUECTEL_BG96 // QUECTEL_BG96 does not give any specific reason for device error + if (err == NSAPI_ERROR_DEVICE_ERROR) { + TEST_ASSERT(((AT_CellularNetwork*)nw)->get_device_error().errCode == 100 && // 100 == unknown command for modem + ((AT_CellularNetwork*)nw)->get_device_error().errType == 3); // 3 == CME error from the modem + } +#endif + + uplinkRate = -1; + err = nw->get_apn_backoff_timer(uplinkRate); + TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_DEVICE_ERROR); + if (err == NSAPI_ERROR_DEVICE_ERROR) { +#if CELLULAR_DEVICE != QUECTEL_BG96 // QUECTEL_BG96 does not give any specific reason for device error + TEST_ASSERT(((AT_CellularNetwork*)nw)->get_device_error().errCode == 100 && // 100 == unknown command for modem + ((AT_CellularNetwork*)nw)->get_device_error().errType == 3); // 3 == CME error from the modem +#endif + } else { + TEST_ASSERT(uplinkRate >= 0); + } + + err = nw->set_access_technology(CellularNetwork::RAT_GSM); + TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_UNSUPPORTED); + + // scanning of operators might take a long time + cellular.get_device()->set_timeout(240*1000); + CellularNetwork::operList_t operators; + TEST_ASSERT(nw->scan_plmn(operators, uplinkRate) == NSAPI_ERROR_OK); + cellular.get_device()->set_timeout(10*1000); + + + // all current targets support IPV4 + nsapi_ip_stack_t stack_type = IPV4_STACK; + TEST_ASSERT(nw->set_stack_type(stack_type) == NSAPI_ERROR_OK); + TEST_ASSERT(nw->get_stack_type() == stack_type); + + CellularNetwork::pdpContextList_t params_list; + err = nw->get_pdpcontext_params(params_list); + + TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_DEVICE_ERROR); + if (err == NSAPI_ERROR_DEVICE_ERROR) { +#if CELLULAR_DEVICE != TELIT_HE910 // TELIT_HE910 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_CellularNetwork*)nw)->get_device_error().errCode == 100 && // 100 == unknown command for modem + ((AT_CellularNetwork*)nw)->get_device_error().errType == 3); // 3 == CME error from the modem +#endif + } else { + // should have some values, only not optional are apn and bearer id + CellularNetwork::pdpcontext_params_t* params = params_list.get_head(); + TEST_ASSERT(strlen(params->apn) > 0); + TEST_ASSERT(params->bearer_id >= 0) + } + + 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 CELLULAR_DEVICE != QUECTEL_BG96 // QUECTEL_BG96 does not give any specific reason for device error + TEST_ASSERT(((AT_CellularNetwork*)nw)->get_device_error().errCode == 100 && // 100 == unknown command for modem + ((AT_CellularNetwork*)nw)->get_device_error().errType == 3); // 3 == CME error from the modem +#endif + } 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); + 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().errCode == 100 && // 100 == unknown command for modem + ((AT_CellularNetwork*)nw)->get_device_error().errType == 3); // 3 == CME error from the modem + } else { + // test for values + TEST_ASSERT(rssi >= 0); + TEST_ASSERT(ber >= 0); + } + + int cell_id = -5; + TEST_ASSERT(nw->get_cell_id(cell_id) == NSAPI_ERROR_OK); + TEST_ASSERT(cell_id != -5); + + int format = -1; + CellularNetwork::operator_t operator_params; + // all params are optional so can't test operator_params + TEST_ASSERT(nw->get_operator_params(format, operator_params) == NSAPI_ERROR_OK); + + nsapi_connection_status_t st = nw->get_connection_status(); + TEST_ASSERT(st == NSAPI_STATUS_DISCONNECTED); + + TEST_ASSERT(nw->set_blocking(true) == NSAPI_ERROR_OK); + +#if CELLULAR_DEVICE != QUECTEL_BG96 + // 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().errCode == 4// 4 == NOT SUPPORTED BY THE MODEM + && ((AT_CellularNetwork*)nw)->get_device_error().errType == 3); // 3 == CME error from the modem + } else { + CellularNetwork::operator_names_t* opn = op_names.get_head(); + TEST_ASSERT(strlen(opn->numeric) > 0); + TEST_ASSERT(strlen(opn->alpha > 0)); + } +#endif + +#if CELLULAR_DEVICE != TELIT_HE910 + // TELIT_HE910 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 = SUPPORTED_UE_OPT_MAX; + CellularNetwork::Preferred_UE_Opt preferred_opt = PREFERRED_UE_OPT_MAX; + err = nw->get_ciot_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 + TEST_ASSERT(((AT_CellularNetwork*)nw)->get_device_error().errCode == 100 && // 100 == unknown command for modem + ((AT_CellularNetwork*)nw)->get_device_error().errType == 3); // 3 == CME error from the modem + } else { + TEST_ASSERT(supported_opt != SUPPORTED_UE_OPT_MAX); + TEST_ASSERT(preferred_opt != PREFERRED_UE_OPT_MAX); + } + + err = nw->set_ciot_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 + TEST_ASSERT(((AT_CellularNetwork*)nw)->get_device_error().errCode == 100 && // 100 == unknown command for modem + ((AT_CellularNetwork*)nw)->get_device_error().errType == 3); // 3 == CME error from the modem + } +#endif + +} + +static void test_disconnect() +{ + nsapi_connection_status_t st = nw->get_connection_status(); + TEST_ASSERT(st == NSAPI_STATUS_GLOBAL_UP); + TEST_ASSERT(nw->disconnect() == NSAPI_ERROR_OK); +} + +static void test_detach() +{ + // in PPP mode there is NO CARRIER waiting so flush it out + rtos::Thread::wait(6*1000); + ((AT_CellularNetwork*)nw)->get_at_handler().flush(); + + nsapi_connection_status_t st = nw->get_connection_status(); + TEST_ASSERT(st == NSAPI_STATUS_DISCONNECTED); + + TEST_ASSERT(nw->detach() == NSAPI_ERROR_OK); + st = nw->get_connection_status(); + TEST_ASSERT(st == NSAPI_STATUS_DISCONNECTED); +} + +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("CellularNetwork state machine methods", test_network_interface_fsm, greentea_failure_handler), + Case("CellularNetwork init", init_network_interface, greentea_failure_handler), + Case("CellularNetwork test registering", test_network_registration, greentea_failure_handler), + Case("CellularNetwork test attach", test_attach, greentea_failure_handler), + Case("CellularNetwork test activate pdp context", test_activate_context, greentea_failure_handler), + Case("CellularNetwork test other functions", test_other, greentea_failure_handler), + Case("CellularNetwork test connect", test_connect, greentea_failure_handler), + Case("CellularNetwork test credentials", test_credentials, greentea_failure_handler), + Case("CellularNetwork test disconnect", test_disconnect, greentea_failure_handler), + Case("CellularNetwork test detach", test_detach, 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; +} diff --git a/features/cellular/UNITTESTS/at/at_cellularnetwork/Makefile b/features/cellular/UNITTESTS/at/at_cellularnetwork/Makefile index 197f1186e4..f834d5787f 100644 --- a/features/cellular/UNITTESTS/at/at_cellularnetwork/Makefile +++ b/features/cellular/UNITTESTS/at/at_cellularnetwork/Makefile @@ -4,7 +4,9 @@ COMPONENT_NAME = AT_CellularNetwork_unit #This must be changed manually SRC_FILES = \ - ../../../framework/AT/AT_CellularNetwork.cpp + ../../../framework/AT/AT_CellularNetwork.cpp \ + ../../../framework/AT/AT_CellularStack.cpp \ + ../../../framework/common/CellularUtil.cpp \ TEST_SRC_FILES = \ main.cpp \ @@ -15,9 +17,11 @@ TEST_SRC_FILES = \ ../../stubs/EventQueue_stub.cpp \ ../../stubs/FileHandle_stub.cpp \ ../../stubs/NetworkInterface_stub.cpp \ - ../../stubs/CellularUtil_stub.cpp \ + ../../stubs/NetworkStack_stub.cpp \ ../../stubs/us_ticker_stub.cpp \ ../../stubs/mbed_assert_stub.cpp \ + ../../stubs/SocketAddress_stub.cpp \ + ../../stubs/randLIB_stub.cpp \ include ../../MakefileWorker.mk diff --git a/features/cellular/UNITTESTS/at/at_cellularnetwork/at_cellularnetworktest.cpp b/features/cellular/UNITTESTS/at/at_cellularnetwork/at_cellularnetworktest.cpp index 67f37eebef..9b5ebf136f 100644 --- a/features/cellular/UNITTESTS/at/at_cellularnetwork/at_cellularnetworktest.cpp +++ b/features/cellular/UNITTESTS/at/at_cellularnetwork/at_cellularnetworktest.cpp @@ -16,6 +16,7 @@ */ #include "CppUTest/TestHarness.h" #include "test_at_cellularnetwork.h" +#include "ATHandler_stub.h" TEST_GROUP(AT_CellularNetwork) { @@ -24,6 +25,9 @@ TEST_GROUP(AT_CellularNetwork) void setup() { unit = new Test_AT_CellularNetwork(); + ATHandler_stub::int_count = kRead_int_table_size; + ATHandler_stub::read_string_index = kRead_string_table_size; + ATHandler_stub::resp_stop_success_count = kResp_stop_count_default; } void teardown() @@ -42,11 +46,21 @@ TEST(AT_CellularNetwork, test_AT_CellularNetwork_constructor) unit->test_AT_CellularNetwork_constructor(); } +TEST(AT_CellularNetwork, test_AT_CellularNetwork_init) +{ + unit->test_AT_CellularNetwork_init(); +} + TEST(AT_CellularNetwork, test_AT_CellularNetwork_set_credentials) { unit->test_AT_CellularNetwork_set_credentials(); } +TEST(AT_CellularNetwork, test_AT_CellularNetwork_activate_context) +{ + unit->test_AT_CellularNetwork_activate_context(); +} + TEST(AT_CellularNetwork, test_AT_CellularNetwork_connect) { unit->test_AT_CellularNetwork_connect(); @@ -72,6 +86,16 @@ TEST(AT_CellularNetwork, test_AT_CellularNetwork_get_registration_status) unit->test_AT_CellularNetwork_get_registration_status(); } +TEST(AT_CellularNetwork, test_AT_CellularNetwork_get_network_registering_mode) +{ + unit->test_AT_CellularNetwork_get_network_registering_mode(); +} + +TEST(AT_CellularNetwork, test_AT_CellularNetwork_set_registration_urc) +{ + unit->test_AT_CellularNetwork_set_registration_urc(); +} + TEST(AT_CellularNetwork, test_AT_CellularNetwork_set_attach) { unit->test_AT_CellularNetwork_set_attach(); @@ -107,6 +131,11 @@ TEST(AT_CellularNetwork, test_AT_CellularNetwork_set_access_technology) unit->test_AT_CellularNetwork_set_access_technology(); } +TEST(AT_CellularNetwork, test_AT_CellularNetwork_get_access_technology) +{ + unit->test_AT_CellularNetwork_get_access_technology(); +} + TEST(AT_CellularNetwork, test_AT_CellularNetwork_scan_plmn) { unit->test_AT_CellularNetwork_scan_plmn(); @@ -166,3 +195,19 @@ TEST(AT_CellularNetwork, test_AT_CellularNetwork_get_operator_names) { unit->test_AT_CellularNetwork_get_operator_names(); } + +TEST(AT_CellularNetwork, test_AT_CellularNetwork_attach) +{ + unit->test_AT_CellularNetwork_attach(); +} + +TEST(AT_CellularNetwork, test_get_connection_status) +{ + unit->test_get_connection_status(); +} + +TEST(AT_CellularNetwork, test_set_blocking) +{ + unit->test_set_blocking(); +} + diff --git a/features/cellular/UNITTESTS/at/at_cellularnetwork/test_at_cellularnetwork.cpp b/features/cellular/UNITTESTS/at/at_cellularnetwork/test_at_cellularnetwork.cpp index cdd6a060a0..a33b2c06d2 100644 --- a/features/cellular/UNITTESTS/at/at_cellularnetwork/test_at_cellularnetwork.cpp +++ b/features/cellular/UNITTESTS/at/at_cellularnetwork/test_at_cellularnetwork.cpp @@ -24,20 +24,79 @@ #include "FileHandle_stub.h" #include "CellularLog.h" #include "ATHandler_stub.h" +#include "AT_CellularStack.h" using namespace mbed; using namespace events; +class my_stack :public AT_CellularStack { +public: + my_stack(ATHandler &atHandler) : AT_CellularStack(atHandler, 1, IPV4_STACK) {} + virtual int get_max_socket_count() { return 1;} + virtual int get_max_packet_size() {return 200;} + virtual bool is_protocol_supported(nsapi_protocol_t protocol) {return true;} + virtual nsapi_error_t socket_close_impl(int sock_id) {return NSAPI_ERROR_OK;} + virtual nsapi_error_t create_socket_impl(CellularSocket *socket) {return NSAPI_ERROR_OK;} + virtual nsapi_size_or_error_t socket_sendto_impl(CellularSocket *socket, const SocketAddress &address, + const void *data, nsapi_size_t size) {return 100;} + virtual nsapi_size_or_error_t socket_recvfrom_impl(CellularSocket *socket, SocketAddress *address, + void *buffer, nsapi_size_t size) {return 100;} +}; + class my_AT_CN : public AT_CellularNetwork { public: my_AT_CN(ATHandler &atHandler) : AT_CellularNetwork(atHandler) {} virtual ~my_AT_CN() {} - NetworkStack *get_stack() {return AT_CellularNetwork::get_stack();} + NetworkStack *get_stack() { + if (!_stack) { + return new my_stack(get_at_handler()); + } else { + return _stack; + }} + virtual bool has_registration(RegistrationType reg_type) { + if (reg_type == C_GREG) { + return false; + } + return true; + } + virtual nsapi_error_t set_access_technology_impl(RadioAccessTechnology op_rat) { return NSAPI_ERROR_OK;} + virtual bool get_modem_stack_type(nsapi_ip_stack_t requested_stack) { + if (requested_stack == IPV4_STACK || requested_stack == DEFAULT_STACK) { + return true; + } + return false; + } }; -void conn_stat_cb(nsapi_error_t error) -{ +class my_AT_CNipv6 : public AT_CellularNetwork { +public: + my_AT_CNipv6(ATHandler &atHandler) : AT_CellularNetwork(atHandler) {} + virtual ~my_AT_CNipv6() {} + NetworkStack *get_stack() { + if (!_stack) { + return new my_stack(get_at_handler()); + } else { + return _stack; + }} + virtual bool has_registration(RegistrationType reg_type) { + if (reg_type == C_GREG) { + return false; + } + return true; + } + virtual nsapi_error_t set_access_technology_impl(RadioAccessTechnology op_rat) { return NSAPI_ERROR_OK;} + virtual bool get_modem_stack_type(nsapi_ip_stack_t requested_stack) { + if (requested_stack == IPV6_STACK || requested_stack == DEFAULT_STACK) { + return true; + } + return false; + } +}; +static int network_cb_count; +static void network_cb(nsapi_event_t ev, intptr_t intptr) +{ + network_cb_count++; } Test_AT_CellularNetwork::Test_AT_CellularNetwork() @@ -61,6 +120,18 @@ void Test_AT_CellularNetwork::test_AT_CellularNetwork_constructor() delete cn; } +void Test_AT_CellularNetwork::test_AT_CellularNetwork_init() +{ + EventQueue que; + FileHandle_stub fh1; + ATHandler at(&fh1, que, 0, ","); + AT_CellularNetwork cn(at); + + CHECK(NSAPI_ERROR_OK == cn.init()); + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_NO_MEMORY; + CHECK(NSAPI_ERROR_NO_MEMORY == cn.init()); +} + void Test_AT_CellularNetwork::test_AT_CellularNetwork_set_credentials() { EventQueue que; @@ -68,9 +139,181 @@ void Test_AT_CellularNetwork::test_AT_CellularNetwork_set_credentials() ATHandler at(&fh1, que, 0, ","); AT_CellularNetwork cn(at); - CHECK(NSAPI_ERROR_OK == cn.set_credentials("apn", CellularNetwork::CHAP)); - CHECK(NSAPI_ERROR_OK == cn.set_credentials("apn")); + CHECK(NSAPI_ERROR_OK == cn.set_credentials("apn", CellularNetwork::CHAP)); + CHECK(NSAPI_ERROR_OK == cn.set_credentials("apn", CellularNetwork::CHAP, NULL)); + CHECK(NSAPI_ERROR_OK == cn.set_credentials("apn", CellularNetwork::CHAP, NULL, NULL)); + CHECK(NSAPI_ERROR_OK == cn.set_credentials("apn", CellularNetwork::CHAP, NULL, "passwd")); + CHECK(NSAPI_ERROR_OK == cn.set_credentials("apn", CellularNetwork::CHAP, "user", NULL)); + CHECK(NSAPI_ERROR_OK == cn.set_credentials("apn", CellularNetwork::CHAP, "user")); + CHECK(NSAPI_ERROR_OK == cn.set_credentials("apn", CellularNetwork::CHAP, "user", "passwd")); + CHECK(NSAPI_ERROR_OK == cn.set_credentials("apn", NULL)); + CHECK(NSAPI_ERROR_OK == cn.set_credentials("apn", NULL, NULL)); + CHECK(NSAPI_ERROR_OK == cn.set_credentials("apn", NULL, "passwd")); + CHECK(NSAPI_ERROR_OK == cn.set_credentials("apn", "user", NULL)); + CHECK(NSAPI_ERROR_OK == cn.set_credentials("apn", "user")); + CHECK(NSAPI_ERROR_OK == cn.set_credentials("apn", "user", "passwd")); +} + +void Test_AT_CellularNetwork::test_AT_CellularNetwork_activate_context() +{ + + EventQueue que; + FileHandle_stub fh1; + ATHandler at(&fh1, que, 0, ","); + + AT_CellularNetwork cn(at); + my_AT_CN my_cn(at); + my_AT_CNipv6 my_cnipv6(at); + + // get_context return true and new context created. But now stack and so error. + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + ATHandler_stub::bool_value = false; + CHECK(NSAPI_ERROR_UNSUPPORTED == cn.activate_context()); + + // get_context return true and new context created, also do_user_authentication called with success. + // But now stack and so error. + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + ATHandler_stub::bool_value = false; + CHECK(NSAPI_ERROR_OK == cn.set_credentials("apn", CellularNetwork::CHAP, "user", "passwd")); + CHECK(NSAPI_ERROR_UNSUPPORTED == cn.activate_context()); + + // get_context return true and new context created, also do_user_authentication called with failure. + ATHandler_stub::resp_stop_success_count = 2; + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + ATHandler_stub::bool_value = false; + CHECK(NSAPI_ERROR_OK == cn.set_credentials("apn", CellularNetwork::CHAP, "user", "passwd")); + CHECK(NSAPI_ERROR_AUTH_FAILURE == cn.activate_context()); + + + // get_context return true and new context created, also do_user_authentication called with success. + // Now there is stack. + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + ATHandler_stub::bool_value = false; + ATHandler_stub::resp_stop_success_count = kResp_stop_count_default; + CHECK(NSAPI_ERROR_OK == my_cn.set_credentials("apn", CellularNetwork::CHAP, "user", "passwd")); + CHECK(NSAPI_ERROR_OK == my_cn.activate_context()); + + // get_context return true and new context created, test delete context + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + ATHandler_stub::bool_value = false; + ATHandler_stub::resp_stop_success_count = kResp_stop_count_default; + CHECK(NSAPI_ERROR_OK == my_cn.set_credentials("apn", CellularNetwork::CHAP, "user", "passwd")); + CHECK(NSAPI_ERROR_OK == my_cn.activate_context()); + + + + // get_context pdp type gives zero len, fails with no stack + ATHandler_stub::resp_info_true_counter = 1; + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + ATHandler_stub::bool_value = false; + ATHandler_stub::read_string_index = 1; + ATHandler_stub::read_string_table[0] = ""; + ATHandler_stub::int_value = 1; + CHECK(NSAPI_ERROR_UNSUPPORTED == cn.activate_context()); + + // get_context pdp type gives proper type, apn reading fails + ATHandler_stub::resp_info_true_counter = 1; + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + ATHandler_stub::bool_value = false; + ATHandler_stub::read_string_index = 1; + ATHandler_stub::read_string_table[0] = "IPV6"; + ATHandler_stub::int_value = 1; + CHECK(NSAPI_ERROR_NO_CONNECTION == cn.activate_context()); + + // get_context pdp type gives proper type, apn does not match, now other contexts so new one created + ATHandler_stub::resp_info_true_counter = 1; + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + ATHandler_stub::bool_value = false; + ATHandler_stub::read_string_index = 2; + ATHandler_stub::read_string_table[0] = "internet"; + ATHandler_stub::read_string_table[1] = "IP"; + ATHandler_stub::int_value = 1; + CHECK(NSAPI_ERROR_OK == my_cn.set_credentials("apn", CellularNetwork::CHAP, "user", "passwd")); + CHECK(NSAPI_ERROR_OK == my_cn.activate_context()); + + // get_context pdp type gives proper type, apn match + ATHandler_stub::resp_info_true_counter = 2; // set to 2 so cgact will give that this context is active + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + ATHandler_stub::bool_value = false; + ATHandler_stub::read_string_index = 2; + ATHandler_stub::read_string_table[0] = "internet"; + ATHandler_stub::read_string_table[1] = "IPV4V6"; + ATHandler_stub::int_value = 1; + CHECK(NSAPI_ERROR_OK == my_cn.set_stack_type(IPV4_STACK)); + CHECK(NSAPI_ERROR_OK == my_cn.set_credentials("internet")); + CHECK(NSAPI_ERROR_OK == my_cn.activate_context()); + + // get_context pdp type gives proper type, apn match + ATHandler_stub::resp_info_true_counter = 1; + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + ATHandler_stub::bool_value = false; + ATHandler_stub::read_string_index = 2; + ATHandler_stub::read_string_table[0] = "internet"; + ATHandler_stub::read_string_table[1] = "IPV6"; + ATHandler_stub::int_value = 1; + CHECK(NSAPI_ERROR_OK == my_cnipv6.set_stack_type(IPV6_STACK)); + CHECK(NSAPI_ERROR_OK == my_cnipv6.set_credentials("internet")); + CHECK(NSAPI_ERROR_OK == my_cnipv6.activate_context()); + + // get_context pdp type gives proper type, apn match + ATHandler_stub::resp_info_true_counter = 1; + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + ATHandler_stub::bool_value = false; + ATHandler_stub::read_string_index = 2; + ATHandler_stub::read_string_table[0] = "internet"; + ATHandler_stub::read_string_table[1] = "IPV4V6"; + ATHandler_stub::int_value = 1; + CHECK(NSAPI_ERROR_OK ==my_cn.set_stack_type(DEFAULT_STACK)); + CHECK(NSAPI_ERROR_OK == my_cn.set_credentials("internet")); + CHECK(NSAPI_ERROR_OK == my_cn.activate_context()); + + // get_context pdp type gives proper type, apn match + ATHandler_stub::resp_info_true_counter = 1; + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + ATHandler_stub::bool_value = false; + ATHandler_stub::read_string_index = 2; + ATHandler_stub::read_string_table[0] = "internet"; + ATHandler_stub::read_string_table[1] = "IPV4V6"; + ATHandler_stub::int_value = 1; + CHECK(NSAPI_ERROR_OK ==my_cnipv6.set_stack_type(DEFAULT_STACK)); + CHECK(NSAPI_ERROR_OK == my_cnipv6.set_credentials("internet")); + CHECK(NSAPI_ERROR_OK == my_cnipv6.activate_context()); + + // get_context pdp type gives proper type, apn match + ATHandler_stub::resp_info_true_counter = 1; + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + ATHandler_stub::bool_value = false; + ATHandler_stub::read_string_index = 2; + ATHandler_stub::read_string_table[0] = "internet"; + ATHandler_stub::read_string_table[1] = "IPV6"; + ATHandler_stub::int_value = 1; + CHECK(NSAPI_ERROR_OK ==my_cnipv6.set_stack_type(DEFAULT_STACK)); + CHECK(NSAPI_ERROR_OK == my_cnipv6.set_credentials("internet")); + CHECK(NSAPI_ERROR_OK == my_cnipv6.activate_context()); + + // get_context pdp type gives proper type, apn match + ATHandler_stub::resp_info_true_counter = 1; + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + ATHandler_stub::bool_value = false; + ATHandler_stub::read_string_index = 2; + ATHandler_stub::read_string_table[0] = "internet"; + ATHandler_stub::read_string_table[1] = "IP"; + ATHandler_stub::int_value = 1; + CHECK(NSAPI_ERROR_OK ==my_cn.set_stack_type(DEFAULT_STACK)); + CHECK(NSAPI_ERROR_OK == my_cn.set_credentials("internet")); + CHECK(NSAPI_ERROR_OK == my_cn.activate_context()); + + // get_context pdp type gives proper type, apn match. Test Delete the created context. + ATHandler_stub::resp_info_true_counter = 0; + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + ATHandler_stub::bool_value = false; + ATHandler_stub::int_value = 1; + //ATHandler_stub::nsapi_error_ok_counter = 2; + ATHandler_stub::resp_stop_success_count = 2; + CHECK(NSAPI_ERROR_OK == my_cn.set_credentials(NULL, NULL, NULL)); + CHECK(NSAPI_ERROR_NO_CONNECTION == my_cn.activate_context()); + } void Test_AT_CellularNetwork::test_AT_CellularNetwork_connect() @@ -80,11 +323,30 @@ void Test_AT_CellularNetwork::test_AT_CellularNetwork_connect() ATHandler at(&fh1, que, 0, ","); AT_CellularNetwork cn(at); - cn.set_stack_type(IPV4V6_STACK); - CHECK(NSAPI_ERROR_UNSUPPORTED == cn.connect("APN", "a", "b")); - ATHandler_stub::nsapi_error_value = NSAPI_ERROR_CONNECTION_LOST; + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + // no stack so will fail + cn.attach(&network_cb); + network_cb_count = 0; + + CHECK(NSAPI_ERROR_UNSUPPORTED == cn.connect("APN", "a", "b")); + CHECK(NSAPI_STATUS_DISCONNECTED == cn.get_connection_status()); + CHECK(network_cb_count == 2); + + network_cb_count = 0; + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR; CHECK(NSAPI_ERROR_NO_CONNECTION == cn.connect("APN")); + CHECK(network_cb_count == 2); + CHECK(NSAPI_STATUS_DISCONNECTED == cn.get_connection_status()); + + my_AT_CN my_cn(at); + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + ATHandler_stub::bool_value = false; + cn.set_stack_type(IPV4_STACK); + CHECK(NSAPI_ERROR_OK == my_cn.connect()); + CHECK(network_cb_count == 2); + CHECK(NSAPI_STATUS_GLOBAL_UP == my_cn.get_connection_status()); + } void Test_AT_CellularNetwork::test_AT_CellularNetwork_disconnect() @@ -103,8 +365,10 @@ void Test_AT_CellularNetwork::test_AT_CellularNetwork_get_stack() FileHandle_stub fh1; ATHandler at(&fh1, que, 0, ","); - my_AT_CN cn(at); - CHECK(!cn.get_stack()); + my_AT_CN my_cn(at); + my_stack* mystack = (my_stack*)my_cn.get_stack(); + CHECK(mystack); + delete mystack; } void Test_AT_CellularNetwork::test_AT_CellularNetwork_set_registration() @@ -114,8 +378,18 @@ void Test_AT_CellularNetwork::test_AT_CellularNetwork_set_registration() ATHandler at(&fh1, que, 0, ","); AT_CellularNetwork cn(at); - ATHandler_stub::nsapi_error_value = NSAPI_ERROR_CONNECTION_LOST; - CHECK(NSAPI_ERROR_CONNECTION_LOST == cn.set_registration()); + + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR; + CHECK(NSAPI_ERROR_DEVICE_ERROR == cn.set_registration()); + + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + CHECK(NSAPI_ERROR_OK == cn.set_registration()); + + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR; + CHECK(NSAPI_ERROR_DEVICE_ERROR == cn.set_registration("12345")); + + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + CHECK(NSAPI_ERROR_OK == cn.set_registration("12345")); } void Test_AT_CellularNetwork::test_AT_CellularNetwork_get_registration_status() @@ -125,8 +399,122 @@ void Test_AT_CellularNetwork::test_AT_CellularNetwork_get_registration_status() ATHandler at(&fh1, que, 0, ","); AT_CellularNetwork cn(at); - CellularNetwork::RegistrationStatus stat; + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + ATHandler_stub::int_value = 3; + CellularNetwork::RegistrationStatus stat = CellularNetwork::NotRegistered; CHECK(NSAPI_ERROR_OK == cn.get_registration_status(CellularNetwork::C_EREG, stat)); + CHECK(stat == CellularNetwork::RegistrationDenied); + stat = CellularNetwork::NotRegistered; + CHECK(NSAPI_ERROR_OK == cn.get_registration_status(CellularNetwork::C_GREG, stat)); + CHECK(stat == CellularNetwork::RegistrationDenied); + + my_AT_CN nw(at); + stat = CellularNetwork::NotRegistered; + CHECK(NSAPI_ERROR_UNSUPPORTED == nw.get_registration_status(CellularNetwork::C_GREG, stat)); + CHECK(stat == CellularNetwork::NotRegistered); + CHECK(NSAPI_ERROR_OK == nw.get_registration_status(CellularNetwork::C_EREG, stat)); + CHECK(stat == CellularNetwork::RegistrationDenied); + + + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR; + stat = CellularNetwork::NotRegistered; + CHECK(NSAPI_ERROR_DEVICE_ERROR == cn.get_registration_status(CellularNetwork::C_EREG, stat)); + CHECK(stat == -1); + CHECK(NSAPI_ERROR_DEVICE_ERROR == cn.get_registration_status(CellularNetwork::C_GREG, stat)); + CHECK(stat == -1); + + stat = CellularNetwork::NotRegistered; + CHECK(NSAPI_ERROR_UNSUPPORTED == nw.get_registration_status(CellularNetwork::C_GREG, stat)); + CHECK(stat == CellularNetwork::NotRegistered); + CHECK(NSAPI_ERROR_DEVICE_ERROR == nw.get_registration_status(CellularNetwork::C_EREG, stat)); + CHECK(stat == -1); +} + +void Test_AT_CellularNetwork::test_AT_CellularNetwork_get_network_registering_mode() +{ + EventQueue que; + FileHandle_stub fh1; + ATHandler at(&fh1, que, 0, ","); + + AT_CellularNetwork cn(at); + + ATHandler_stub::int_value = 0; + CellularNetwork::NWRegisteringMode mode = CellularNetwork::NWModeManual; + CHECK(NSAPI_ERROR_OK == cn.get_network_registering_mode(mode)); + CHECK(mode == CellularNetwork::NWModeAutomatic); + + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR; + mode = CellularNetwork::NWModeManual; + CHECK(NSAPI_ERROR_DEVICE_ERROR == cn.get_network_registering_mode(mode)); + CHECK(mode == -1); +} + +void Test_AT_CellularNetwork::test_AT_CellularNetwork_set_registration_urc() +{ + EventQueue que; + FileHandle_stub fh1; + ATHandler at(&fh1, que, 0, ","); + + AT_CellularNetwork cn(at); + + CellularNetwork::RegistrationType type = CellularNetwork::C_EREG; + CHECK(NSAPI_ERROR_OK == cn.set_registration_urc(type, true)); + type = CellularNetwork::C_GREG; + CHECK(NSAPI_ERROR_OK == cn.set_registration_urc(type, true)); + type = CellularNetwork::C_REG; + CHECK(NSAPI_ERROR_OK == cn.set_registration_urc(type, true)); + + my_AT_CN nw(at); + type = CellularNetwork::C_EREG; + CHECK(NSAPI_ERROR_OK == nw.set_registration_urc(type, true)); + type = CellularNetwork::C_GREG; + CHECK(NSAPI_ERROR_UNSUPPORTED == nw.set_registration_urc(type, true)); + type = CellularNetwork::C_REG; + CHECK(NSAPI_ERROR_OK == nw.set_registration_urc(type, true)); + + type = CellularNetwork::C_EREG; + CHECK(NSAPI_ERROR_OK == cn.set_registration_urc(type, false)); + type = CellularNetwork::C_GREG; + CHECK(NSAPI_ERROR_OK == cn.set_registration_urc(type, false)); + type = CellularNetwork::C_REG; + CHECK(NSAPI_ERROR_OK == cn.set_registration_urc(type, false)); + + type = CellularNetwork::C_EREG; + CHECK(NSAPI_ERROR_OK == nw.set_registration_urc(type, false)); + type = CellularNetwork::C_GREG; + CHECK(NSAPI_ERROR_UNSUPPORTED == nw.set_registration_urc(type, false)); + type = CellularNetwork::C_REG; + CHECK(NSAPI_ERROR_OK == nw.set_registration_urc(type, false)); + + + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR; + type = CellularNetwork::C_EREG; + CHECK(NSAPI_ERROR_DEVICE_ERROR == cn.set_registration_urc(type, true)); + type = CellularNetwork::C_GREG; + CHECK(NSAPI_ERROR_DEVICE_ERROR == cn.set_registration_urc(type, true)); + type = CellularNetwork::C_REG; + CHECK(NSAPI_ERROR_DEVICE_ERROR == cn.set_registration_urc(type, true)); + + type = CellularNetwork::C_EREG; + CHECK(NSAPI_ERROR_DEVICE_ERROR == nw.set_registration_urc(type, true)); + type = CellularNetwork::C_GREG; + CHECK(NSAPI_ERROR_UNSUPPORTED == nw.set_registration_urc(type, true)); + type = CellularNetwork::C_REG; + CHECK(NSAPI_ERROR_DEVICE_ERROR == nw.set_registration_urc(type, true)); + + type = CellularNetwork::C_EREG; + CHECK(NSAPI_ERROR_DEVICE_ERROR == cn.set_registration_urc(type, false)); + type = CellularNetwork::C_GREG; + CHECK(NSAPI_ERROR_DEVICE_ERROR == cn.set_registration_urc(type, false)); + type = CellularNetwork::C_REG; + CHECK(NSAPI_ERROR_DEVICE_ERROR == cn.set_registration_urc(type, false)); + + type = CellularNetwork::C_EREG; + CHECK(NSAPI_ERROR_DEVICE_ERROR == nw.set_registration_urc(type, false)); + type = CellularNetwork::C_GREG; + CHECK(NSAPI_ERROR_UNSUPPORTED == nw.set_registration_urc(type, false)); + type = CellularNetwork::C_REG; + CHECK(NSAPI_ERROR_DEVICE_ERROR == nw.set_registration_urc(type, false)); } void Test_AT_CellularNetwork::test_AT_CellularNetwork_set_attach() @@ -136,8 +524,13 @@ void Test_AT_CellularNetwork::test_AT_CellularNetwork_set_attach() ATHandler at(&fh1, que, 0, ","); AT_CellularNetwork cn(at); - ATHandler_stub::nsapi_error_value = NSAPI_ERROR_CONNECTION_LOST; - CHECK(NSAPI_ERROR_CONNECTION_LOST == cn.set_attach()); + ATHandler_stub::int_value = 0; + CHECK(NSAPI_ERROR_OK == cn.set_attach()); + ATHandler_stub::int_value = 1; + CHECK(NSAPI_ERROR_OK == cn.set_attach()); + + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR; + CHECK(NSAPI_ERROR_DEVICE_ERROR == cn.set_attach()); } void Test_AT_CellularNetwork::test_AT_CellularNetwork_get_attach() @@ -147,9 +540,31 @@ void Test_AT_CellularNetwork::test_AT_CellularNetwork_get_attach() ATHandler at(&fh1, que, 0, ","); AT_CellularNetwork cn(at); - CellularNetwork::AttachStatus stat; - ATHandler_stub::nsapi_error_value = NSAPI_ERROR_CONNECTION_LOST; - CHECK(NSAPI_ERROR_CONNECTION_LOST == cn.get_attach(stat)); + CellularNetwork::AttachStatus stat = CellularNetwork::Detached; + ATHandler_stub::int_value = 1; + ATHandler_stub::bool_value = true; + CHECK(NSAPI_ERROR_OK == cn.get_attach(stat)); + CHECK(stat == CellularNetwork::Attached); + + ATHandler_stub::int_value = 0; + CHECK(NSAPI_ERROR_OK == cn.get_attach(stat)); + CHECK(stat == CellularNetwork::Detached); + + stat = CellularNetwork::Attached; + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR; + CHECK(NSAPI_ERROR_DEVICE_ERROR == cn.get_attach(stat)); + CHECK(stat == CellularNetwork::Detached); + + + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + ATHandler_stub::bool_value = false; + CHECK(NSAPI_ERROR_OK == cn.get_attach(stat)); + CHECK(stat == CellularNetwork::Detached); + + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR; + ATHandler_stub::bool_value = false; + CHECK(NSAPI_ERROR_DEVICE_ERROR == cn.get_attach(stat)); + CHECK(stat == CellularNetwork::Detached); } void Test_AT_CellularNetwork::test_AT_CellularNetwork_detach() @@ -158,9 +573,25 @@ void Test_AT_CellularNetwork::test_AT_CellularNetwork_detach() FileHandle_stub fh1; ATHandler at(&fh1, que, 0, ","); - AT_CellularNetwork cn(at); - ATHandler_stub::nsapi_error_value = NSAPI_ERROR_CONNECTION_LOST; - CHECK(NSAPI_ERROR_CONNECTION_LOST == cn.detach()); + my_AT_CN cn(at); + + CHECK(NSAPI_ERROR_OK == cn.detach()); + + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR; + CHECK(NSAPI_ERROR_DEVICE_ERROR == cn.detach()); + + // connect so we can test callback in detach + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + ATHandler_stub::bool_value = false; + cn.set_stack_type(IPV4_STACK); + CHECK(NSAPI_ERROR_OK == cn.connect()); + CHECK(NSAPI_STATUS_GLOBAL_UP == cn.get_connection_status()); + // attach callback + cn.attach(&network_cb); + network_cb_count = 0; + CHECK(NSAPI_ERROR_OK == cn.detach()); + CHECK(network_cb_count == 1); + CHECK(NSAPI_STATUS_DISCONNECTED == cn.get_connection_status()); } void Test_AT_CellularNetwork::test_AT_CellularNetwork_get_rate_control() @@ -170,10 +601,66 @@ void Test_AT_CellularNetwork::test_AT_CellularNetwork_get_rate_control() ATHandler at(&fh1, que, 0, ","); AT_CellularNetwork cn(at); - int ur; - CellularNetwork::RateControlExceptionReports reports; - CellularNetwork::RateControlUplinkTimeUnit timeUnit; + int ur = -1; + CellularNetwork::RateControlExceptionReports reports = CellularNetwork::NotAllowedToBeSent; + CellularNetwork::RateControlUplinkTimeUnit timeUnit = CellularNetwork::Unrestricted; + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR; + CHECK(NSAPI_ERROR_DEVICE_ERROR == cn.get_rate_control(reports, timeUnit, ur)); + CHECK(reports == CellularNetwork::NotAllowedToBeSent); + CHECK(timeUnit == CellularNetwork::Unrestricted); + CHECK(ur == -1); + + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + ATHandler_stub::int_value = 1; CHECK(NSAPI_ERROR_OK == cn.get_rate_control(reports, timeUnit, ur)); + CHECK(reports == CellularNetwork::AllowedToBeSent); + CHECK(timeUnit == CellularNetwork::Minute); + CHECK(ur == 1); + + // test second if in get_rate_control + reports = CellularNetwork::NotAllowedToBeSent; + timeUnit = CellularNetwork::Unrestricted; + ur = -1; + + ATHandler_stub::int_count = 1; + ATHandler_stub::int_valid_count_table[0] = 1; + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + CHECK(NSAPI_ERROR_DEVICE_ERROR == cn.get_rate_control(reports, timeUnit, ur)); + CHECK(reports == CellularNetwork::NotAllowedToBeSent); + CHECK(timeUnit == CellularNetwork::Unrestricted); + CHECK(ur == -1); + + // test second if in get_rate_control + ATHandler_stub::int_count = 2; + ATHandler_stub::int_valid_count_table[0] = 1; + ATHandler_stub::int_valid_count_table[1] = 1; + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + CHECK(NSAPI_ERROR_DEVICE_ERROR == cn.get_rate_control(reports, timeUnit, ur)); + CHECK(reports == CellularNetwork::AllowedToBeSent); + CHECK(timeUnit == CellularNetwork::Unrestricted); + CHECK(ur == -1); + + // test third if in get_rate_control + ATHandler_stub::int_count = 3; + ATHandler_stub::int_valid_count_table[0] = 3; + ATHandler_stub::int_valid_count_table[1] = 1; + ATHandler_stub::int_valid_count_table[2] = 1; + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + CHECK(NSAPI_ERROR_DEVICE_ERROR == cn.get_rate_control(reports, timeUnit, ur)); + CHECK(reports == CellularNetwork::AllowedToBeSent); + CHECK(timeUnit == CellularNetwork::Day); + CHECK(ur == -1); + + ATHandler_stub::int_count = 4; + ATHandler_stub::int_valid_count_table[0] = 5; + ATHandler_stub::int_valid_count_table[1] = 3; + ATHandler_stub::int_valid_count_table[2] = 1; + ATHandler_stub::int_valid_count_table[3] = 1; + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + CHECK(NSAPI_ERROR_OK == cn.get_rate_control(reports, timeUnit, ur)); + CHECK(reports == CellularNetwork::AllowedToBeSent); + CHECK(timeUnit == CellularNetwork::Day); + CHECK(ur == 5); } void Test_AT_CellularNetwork::test_AT_CellularNetwork_get_apn_backoff_timer() @@ -183,12 +670,29 @@ void Test_AT_CellularNetwork::test_AT_CellularNetwork_get_apn_backoff_timer() ATHandler at(&fh1, que, 0, ","); AT_CellularNetwork cn(at); - int time; - ATHandler_stub::nsapi_error_value = NSAPI_ERROR_CONNECTION_LOST; + int time = -1; + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR; CHECK(NSAPI_ERROR_PARAMETER == cn.get_apn_backoff_timer(time)); + CHECK(time == -1); + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + CHECK(NSAPI_ERROR_PARAMETER == cn.get_apn_backoff_timer(time)); + CHECK(time == -1); + + ATHandler_stub::resp_info_true_counter = 0; + ATHandler_stub::bool_value = false; + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; cn.set_credentials("internet", NULL, NULL); - CHECK(NSAPI_ERROR_CONNECTION_LOST == cn.get_apn_backoff_timer(time)); + CHECK(NSAPI_ERROR_OK == cn.get_apn_backoff_timer(time)); + CHECK(time == -1); + + ATHandler_stub::resp_info_true_counter = 0; + ATHandler_stub::bool_value = true; + ATHandler_stub::int_value = 55; + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + cn.set_credentials("internet", NULL, NULL); + CHECK(NSAPI_ERROR_OK == cn.get_apn_backoff_timer(time)); + CHECK(time == 55); } void Test_AT_CellularNetwork::test_AT_CellularNetwork_get_ip_address() @@ -208,10 +712,28 @@ void Test_AT_CellularNetwork::test_AT_CellularNetwork_set_access_technology() ATHandler at(&fh1, que, 0, ","); AT_CellularNetwork cn(at); + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; CHECK(NSAPI_ERROR_UNSUPPORTED == cn.set_access_technology(CellularNetwork::RAT_UNKNOWN)); CHECK(NSAPI_ERROR_UNSUPPORTED == cn.set_access_technology(CellularNetwork::RAT_GSM_COMPACT)); + + my_AT_CN my_cn(at); + CHECK(NSAPI_ERROR_OK == my_cn.set_access_technology(CellularNetwork::RAT_GSM_COMPACT)); } +void Test_AT_CellularNetwork::test_AT_CellularNetwork_get_access_technology() +{ + EventQueue que; + FileHandle_stub fh1; + ATHandler at(&fh1, que, 0, ","); + + AT_CellularNetwork cn(at); + CellularNetwork::RadioAccessTechnology rat; + + CHECK(NSAPI_ERROR_OK == cn.get_access_technology(rat)); + CHECK(CellularNetwork::RAT_UNKNOWN == rat); +} + + void Test_AT_CellularNetwork::test_AT_CellularNetwork_scan_plmn() { EventQueue que; @@ -219,10 +741,44 @@ void Test_AT_CellularNetwork::test_AT_CellularNetwork_scan_plmn() ATHandler at(&fh1, que, 0, ","); AT_CellularNetwork cn(at); - int c; + int c = -1; CellularNetwork::operList_t ops; - ATHandler_stub::nsapi_error_value = NSAPI_ERROR_CONNECTION_LOST; - CHECK(NSAPI_ERROR_CONNECTION_LOST == cn.scan_plmn(ops, c)); + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR; + CHECK(NSAPI_ERROR_DEVICE_ERROR == cn.scan_plmn(ops, c)); + CHECK(c == 0); + + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + CHECK(NSAPI_ERROR_OK == cn.scan_plmn(ops, c)); + CHECK(c == 0); + + + ATHandler_stub::read_string_index = 3; + ATHandler_stub::read_string_table[0] = "44444"; + ATHandler_stub::read_string_table[1] = "33333"; + ATHandler_stub::read_string_table[2] = "12345"; + ATHandler_stub::int_value = 1; + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + ATHandler_stub::info_elem_true_counter = 1; + ATHandler_stub::bool_value = false; + CHECK(NSAPI_ERROR_OK == cn.scan_plmn(ops, c)); + CHECK(c == 1); + CHECK(ops.get_head() != NULL); + CellularNetwork::operator_t* op = ops.get_head(); + CHECK(op->op_status == CellularNetwork::operator_t::Available); + CHECK(strcmp(op->op_long, "12345") == 0); + CHECK(strcmp(op->op_short, "33333") == 0); + CHECK(strcmp(op->op_num, "44444") == 0); + ops.delete_all(); + + ATHandler_stub::read_string_index = 3; + ATHandler_stub::int_value = 6; // RAT_HSDPA_HSUPA + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + ATHandler_stub::info_elem_true_counter = 1; + ATHandler_stub::bool_value = false; + CHECK(NSAPI_ERROR_UNSUPPORTED == cn.set_access_technology(CellularNetwork::RAT_UTRAN)); + CHECK(NSAPI_ERROR_OK == cn.scan_plmn(ops, c)); + CHECK(c == 0); + CHECK(ops.get_head() == NULL); } void Test_AT_CellularNetwork::test_AT_CellularNetwork_set_ciot_optimization_config() @@ -232,8 +788,11 @@ void Test_AT_CellularNetwork::test_AT_CellularNetwork_set_ciot_optimization_conf ATHandler at(&fh1, que, 0, ","); AT_CellularNetwork cn(at); - ATHandler_stub::nsapi_error_value = NSAPI_ERROR_CONNECTION_LOST; - CHECK(NSAPI_ERROR_CONNECTION_LOST == cn.set_ciot_optimization_config(CellularNetwork::SUPPORTED_UE_OPT_NO_SUPPORT, CellularNetwork::PREFERRED_UE_OPT_NO_PREFERENCE)); + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + CHECK(NSAPI_ERROR_OK == cn.set_ciot_optimization_config(CellularNetwork::SUPPORTED_UE_OPT_NO_SUPPORT, CellularNetwork::PREFERRED_UE_OPT_NO_PREFERENCE)); + + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR; + CHECK(NSAPI_ERROR_DEVICE_ERROR == cn.set_ciot_optimization_config(CellularNetwork::SUPPORTED_UE_OPT_NO_SUPPORT, CellularNetwork::PREFERRED_UE_OPT_NO_PREFERENCE)); } void Test_AT_CellularNetwork::test_AT_CellularNetwork_get_ciot_optimization_config() @@ -243,10 +802,21 @@ void Test_AT_CellularNetwork::test_AT_CellularNetwork_get_ciot_optimization_conf ATHandler at(&fh1, que, 0, ","); AT_CellularNetwork cn(at); - CellularNetwork::Supported_UE_Opt sup; - CellularNetwork::Preferred_UE_Opt pref; - ATHandler_stub::nsapi_error_value = NSAPI_ERROR_CONNECTION_LOST; - CHECK(NSAPI_ERROR_CONNECTION_LOST == cn.get_ciot_optimization_config(sup, pref)); + CellularNetwork::Supported_UE_Opt sup = CellularNetwork::SUPPORTED_UE_OPT_NO_SUPPORT; + CellularNetwork::Preferred_UE_Opt pref = CellularNetwork::PREFERRED_UE_OPT_NO_PREFERENCE; + ATHandler_stub::int_value = 1; + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + CHECK(NSAPI_ERROR_OK == cn.get_ciot_optimization_config(sup, pref)); + CHECK(sup == CellularNetwork::SUPPORTED_UE_OPT_CONTROL_PLANE); + CHECK(pref == CellularNetwork::PREFERRED_UE_OPT_CONTROL_PLANE); + + sup = CellularNetwork::SUPPORTED_UE_OPT_NO_SUPPORT; + pref = CellularNetwork::PREFERRED_UE_OPT_NO_PREFERENCE; + ATHandler_stub::int_value = 1; + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR; + CHECK(NSAPI_ERROR_DEVICE_ERROR == cn.get_ciot_optimization_config(sup, pref)); + CHECK(sup == CellularNetwork::SUPPORTED_UE_OPT_NO_SUPPORT); + CHECK(pref == CellularNetwork::PREFERRED_UE_OPT_NO_PREFERENCE); } void Test_AT_CellularNetwork::test_AT_CellularNetwork_set_stack_type() @@ -269,6 +839,11 @@ void Test_AT_CellularNetwork::test_AT_CellularNetwork_get_stack_type() AT_CellularNetwork cn(at); CHECK(DEFAULT_STACK == cn.get_stack_type()); + + my_AT_CN my_cn(at); + CHECK(DEFAULT_STACK == my_cn.get_stack_type()); + CHECK(NSAPI_ERROR_OK == my_cn.set_stack_type(IPV4_STACK)); + CHECK(DEFAULT_STACK == my_cn.get_stack_type()); } void Test_AT_CellularNetwork::test_AT_CellularNetwork_get_pdpcontext_params() @@ -279,8 +854,62 @@ void Test_AT_CellularNetwork::test_AT_CellularNetwork_get_pdpcontext_params() AT_CellularNetwork cn(at); CellularNetwork::pdpContextList_t list; - ATHandler_stub::nsapi_error_value = NSAPI_ERROR_CONNECTION_LOST; - CHECK(NSAPI_ERROR_CONNECTION_LOST == cn.get_pdpcontext_params(list)); + + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR; + CHECK(NSAPI_ERROR_DEVICE_ERROR == cn.get_pdpcontext_params(list)); + + // don't got to while loop + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + ATHandler_stub::bool_value = false; + ATHandler_stub::resp_info_true_counter = 0; + CHECK(NSAPI_ERROR_OK == cn.get_pdpcontext_params(list)); + CHECK(NULL == list.get_head()); + + // go to while loop and check values + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + ATHandler_stub::resp_info_true_counter = 1; + ATHandler_stub::int_count = 9; + ATHandler_stub::int_valid_count_table[8] = 1; + ATHandler_stub::int_valid_count_table[7] = 2; + ATHandler_stub::int_valid_count_table[6] = 3; + ATHandler_stub::int_valid_count_table[5] = 4; + ATHandler_stub::int_valid_count_table[4] = 5; + ATHandler_stub::int_valid_count_table[3] = 6; + ATHandler_stub::int_valid_count_table[2] = 7; + ATHandler_stub::int_valid_count_table[1] = 8; + ATHandler_stub::int_valid_count_table[0] = 9; + + ATHandler_stub::read_string_index = 7; + ATHandler_stub::read_string_table[6] = "internet"; + ATHandler_stub::read_string_table[5] = "1.2.3.4.5.6.7.8.9.10.11.112.13.14.15.16.1.2.3.44.55.6.7.8.9.10.11.12.13.14.15.16"; + ATHandler_stub::read_string_table[4] = "23.33.44.1.2.3.55.123.225.34.11.1.0.0.123.234"; + ATHandler_stub::read_string_table[3] = "1.2.3.4"; + ATHandler_stub::read_string_table[2] = "0.255.0.255"; + ATHandler_stub::read_string_table[1] = "25.66.77.88"; + ATHandler_stub::read_string_table[0] = "004.003.002.001"; + + CHECK(NSAPI_ERROR_OK == cn.get_pdpcontext_params(list)); + CellularNetwork::pdpcontext_params_t *params = list.get_head(); + CHECK(params != NULL); + CHECK(params->next == NULL); + CHECK(params->cid == 1); + CHECK(params->bearer_id == 2); + CHECK(params->im_signalling_flag == 3); + CHECK(params->lipa_indication == 4); + CHECK(params->ipv4_mtu == 5); + CHECK(params->wlan_offload == 6); + CHECK(params->local_addr_ind == 7); + CHECK(params->non_ip_mtu == 8); + CHECK(params->serving_plmn_rate_control_value == 9); + CHECK(strcmp(params->apn, "internet") == 0); + CHECK(strcmp(params->local_addr, "102:304:506:708:90A:B70:D0E:F10") == 0); + CHECK(strcmp(params->local_subnet_mask, "102:32C:3706:708:90A:B0C:D0E:F10") == 0); + CHECK(strcmp(params->gateway_addr, "1721:2C01:203:377B:E122:B01:000:7BEA") == 0); + CHECK(strcmp(params->dns_primary_addr, "1.2.3.4") == 0); + CHECK(strcmp(params->dns_secondary_addr, "0.255.0.255") == 0); + CHECK(strcmp(params->p_cscf_prim_addr, "25.66.77.88") == 0); + CHECK(strcmp(params->p_cscf_sec_addr, "004.003.002.001") == 0); + } void Test_AT_CellularNetwork::test_AT_CellularNetwork_get_extended_signal_quality() @@ -290,11 +919,15 @@ void Test_AT_CellularNetwork::test_AT_CellularNetwork_get_extended_signal_qualit ATHandler at(&fh1, que, 0, ","); AT_CellularNetwork cn(at); - int rx,be,rs,ec,rsrq,rsrp; + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR; + int rx = -1, be = -1, rs = -1, ec = -1, rsrq = -1, rsrp = -1; CHECK(NSAPI_ERROR_DEVICE_ERROR == cn.get_extended_signal_quality(rx, be,rs,ec,rsrq, rsrp)); + CHECK(rx == -1 && be == -1 && rs == -1 && ec == -1 && rsrq == -1 && rsrp == -1); - ATHandler_stub::int_value = 1; + ATHandler_stub::int_value = 5; + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; CHECK(NSAPI_ERROR_OK == cn.get_extended_signal_quality(rx, be,rs,ec,rsrq, rsrp)); + CHECK(rx == 5 && be == 5 && rs == 5 && ec == 5 && rsrq == 5 && rsrp == 5); } void Test_AT_CellularNetwork::test_AT_CellularNetwork_get_signal_quality() @@ -304,11 +937,15 @@ void Test_AT_CellularNetwork::test_AT_CellularNetwork_get_signal_quality() ATHandler at(&fh1, que, 0, ","); AT_CellularNetwork cn(at); - int rs,ber; + int rs = -1, ber = -1; + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR; CHECK(NSAPI_ERROR_DEVICE_ERROR == cn.get_signal_quality(rs,ber)); + CHECK(rs == -1 && ber == -1); ATHandler_stub::int_value = 1; + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; CHECK(NSAPI_ERROR_OK == cn.get_signal_quality(rs,ber)); + CHECK(rs == 1 && ber == 1); } void Test_AT_CellularNetwork::test_AT_CellularNetwork_get_cell_id() @@ -318,9 +955,25 @@ void Test_AT_CellularNetwork::test_AT_CellularNetwork_get_cell_id() ATHandler at(&fh1, que, 0, ","); AT_CellularNetwork cn(at); - int id; + int id = 0; CHECK(NSAPI_ERROR_OK == cn.get_cell_id(id)); CHECK(id == -1); + + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR; + CHECK(NSAPI_ERROR_OK == cn.get_cell_id(id)); + CHECK(id == -1); + + ATHandler_stub::read_string_index = 2; + ATHandler_stub::read_string_table[1] = "00C3"; + ATHandler_stub::read_string_table[0] = "1234FFC1"; //== cellid and in dec: 305463233 + ATHandler_stub::int_value = 1; + // Get registration status to modify cell_id + CellularNetwork::RegistrationType type; + CellularNetwork::RegistrationStatus status; + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + CHECK(NSAPI_ERROR_OK == cn.get_registration_status(CellularNetwork::C_EREG, status)); + CHECK(NSAPI_ERROR_OK == cn.get_cell_id(id)); + CHECK(id == 305463233); } void Test_AT_CellularNetwork::test_AT_CellularNetwork_get_3gpp_error() @@ -343,8 +996,41 @@ void Test_AT_CellularNetwork::test_AT_CellularNetwork_get_operator_params() AT_CellularNetwork cn(at); int format; CellularNetwork::operator_t ops; - ATHandler_stub::nsapi_error_value = NSAPI_ERROR_CONNECTION_LOST; - CHECK(NSAPI_ERROR_CONNECTION_LOST == cn.get_operator_params(format, ops)); + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR; + CHECK(NSAPI_ERROR_DEVICE_ERROR == cn.get_operator_params(format, ops)); + + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + ATHandler_stub::int_value = 0; + ATHandler_stub::read_string_index = 1; + ATHandler_stub::read_string_table[0] = "12345"; + CHECK(NSAPI_ERROR_OK == cn.get_operator_params(format, ops)); + CHECK(format == 0); + CHECK(strcmp(ops.op_long, "12345") == 0); + CHECK(strlen(ops.op_short) == 0); + CHECK(strlen(ops.op_num) == 0); + CHECK(ops.op_rat == CellularNetwork::RAT_GSM); + + ops.op_long[0] = 0; + ATHandler_stub::int_value = 1; + ATHandler_stub::read_string_index = 1; + ATHandler_stub::read_string_table[0] = "12345"; + CHECK(NSAPI_ERROR_OK == cn.get_operator_params(format, ops)); + CHECK(format == 1); + CHECK(strlen(ops.op_long) == 0); + CHECK(strcmp(ops.op_short, "12345") == 0); + CHECK(strlen(ops.op_num) == 0); + CHECK(ops.op_rat == CellularNetwork::RAT_GSM_COMPACT); + + ops.op_short[0] = 0; + ATHandler_stub::int_value = 2; + ATHandler_stub::read_string_index = 1; + ATHandler_stub::read_string_table[0] = "12345"; + CHECK(NSAPI_ERROR_OK == cn.get_operator_params(format, ops)); + CHECK(format == 2); + CHECK(strlen(ops.op_long) == 0); + CHECK(strlen(ops.op_short) == 0); + CHECK(strcmp(ops.op_num, "12345") == 0); + CHECK(ops.op_rat == CellularNetwork::RAT_UTRAN); } void Test_AT_CellularNetwork::test_AT_CellularNetwork_get_operator_names() @@ -356,9 +1042,84 @@ void Test_AT_CellularNetwork::test_AT_CellularNetwork_get_operator_names() AT_CellularNetwork cn(at); CellularNetwork::operator_names_list name_list; + ATHandler_stub::resp_info_true_counter = 0; + ATHandler_stub::bool_value = false; CHECK(NSAPI_ERROR_OK == cn.get_operator_names(name_list)); + CHECK(name_list.get_head() == NULL); - ATHandler_stub::nsapi_error_value = NSAPI_ERROR_CONNECTION_LOST; - CHECK(NSAPI_ERROR_CONNECTION_LOST == cn.get_operator_names(name_list)); + ATHandler_stub::resp_info_true_counter = 1; + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR; + CHECK(NSAPI_ERROR_DEVICE_ERROR == cn.get_operator_names(name_list)); + CHECK(name_list.get_head() != NULL); + CHECK(name_list.get_head()->next == NULL); + + ATHandler_stub::resp_info_true_counter = 1; + ATHandler_stub::bool_value = false; + ATHandler_stub::read_string_index = 2; + ATHandler_stub::read_string_table[1] = "12345"; + ATHandler_stub::read_string_table[0] = "56789"; + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + name_list.delete_all(); + CHECK(NSAPI_ERROR_OK == cn.get_operator_names(name_list)); + CellularNetwork::operator_names_t *op_names = name_list.get_head(); + CHECK(op_names != NULL); + CHECK(op_names->next == NULL); + CHECK(strcmp(op_names->numeric, "12345") == 0); + CHECK(strcmp(op_names->alpha, "56789") == 0); +} + +void Test_AT_CellularNetwork::test_AT_CellularNetwork_attach() +{ + EventQueue que; + FileHandle_stub fh1; + ATHandler at(&fh1, que, 0, ","); + + AT_CellularNetwork cn(at); + + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + network_cb_count = 0; + cn.attach(&network_cb); + CHECK(NSAPI_ERROR_UNSUPPORTED == cn.connect()); + CHECK(network_cb_count == 2); // check that attached callback was called twice +} + +void Test_AT_CellularNetwork::test_get_connection_status() +{ + EventQueue que; + FileHandle_stub fh1; + ATHandler at(&fh1, que, 0, ","); + + AT_CellularNetwork cn(at); + + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + network_cb_count = 0; + cn.attach(&network_cb); + CHECK(NSAPI_ERROR_UNSUPPORTED == cn.connect()); + CHECK(network_cb_count == 2); // check that attached callback was called twice + CHECK(NSAPI_STATUS_DISCONNECTED == cn.get_connection_status()); + + my_AT_CN my_cn(at); + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + ATHandler_stub::bool_value = false; + cn.set_stack_type(IPV4_STACK); + CHECK(NSAPI_ERROR_OK == my_cn.connect()); + CHECK(network_cb_count == 2); + CHECK(NSAPI_STATUS_GLOBAL_UP == my_cn.get_connection_status()); +} + +void Test_AT_CellularNetwork::test_set_blocking() +{ + EventQueue que; + FileHandle_stub fh1; + ATHandler at(&fh1, que, 0, ","); + + AT_CellularNetwork cn(at); + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; + CHECK(NSAPI_ERROR_OK == cn.set_blocking(false)); + CHECK(NSAPI_ERROR_OK == cn.set_blocking(true)); + + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR; + CHECK(NSAPI_ERROR_OK == cn.set_blocking(false)); + CHECK(NSAPI_ERROR_OK == cn.set_blocking(true)); } diff --git a/features/cellular/UNITTESTS/at/at_cellularnetwork/test_at_cellularnetwork.h b/features/cellular/UNITTESTS/at/at_cellularnetwork/test_at_cellularnetwork.h index e7775ff8be..02f0468a87 100644 --- a/features/cellular/UNITTESTS/at/at_cellularnetwork/test_at_cellularnetwork.h +++ b/features/cellular/UNITTESTS/at/at_cellularnetwork/test_at_cellularnetwork.h @@ -26,8 +26,12 @@ public: void test_AT_CellularNetwork_constructor(); + void test_AT_CellularNetwork_init(); + void test_AT_CellularNetwork_set_credentials(); + void test_AT_CellularNetwork_activate_context(); + void test_AT_CellularNetwork_connect(); void test_AT_CellularNetwork_disconnect(); @@ -38,6 +42,10 @@ public: void test_AT_CellularNetwork_get_registration_status(); + void test_AT_CellularNetwork_get_network_registering_mode(); + + void test_AT_CellularNetwork_set_registration_urc(); + void test_AT_CellularNetwork_set_attach(); void test_AT_CellularNetwork_get_attach(); @@ -52,6 +60,8 @@ public: void test_AT_CellularNetwork_set_access_technology(); + void test_AT_CellularNetwork_get_access_technology(); + void test_AT_CellularNetwork_scan_plmn(); void test_AT_CellularNetwork_set_ciot_optimization_config(); @@ -75,6 +85,12 @@ public: void test_AT_CellularNetwork_get_operator_params(); void test_AT_CellularNetwork_get_operator_names(); + + void test_AT_CellularNetwork_attach(); + + void test_get_connection_status(); + + void test_set_blocking(); }; #endif // TEST_AT_CELLULARNETWORK_H diff --git a/features/cellular/UNITTESTS/at/at_cellularsms/test_at_cellularsms.cpp b/features/cellular/UNITTESTS/at/at_cellularsms/test_at_cellularsms.cpp index 9faac21d67..94c5884a63 100644 --- a/features/cellular/UNITTESTS/at/at_cellularsms/test_at_cellularsms.cpp +++ b/features/cellular/UNITTESTS/at/at_cellularsms/test_at_cellularsms.cpp @@ -57,7 +57,7 @@ void Test_AT_CellularSMS::test_AT_CellularSMS_initialize() AT_CellularSMS sms(at); ATHandler_stub::nsapi_error_value = NSAPI_ERROR_AUTH_FAILURE; - CHECK(NSAPI_ERROR_AUTH_FAILURE == sms.initialize(CellularSMS::CellularSMSMmodeText)); + CHECK(NSAPI_ERROR_NO_MEMORY == sms.initialize(CellularSMS::CellularSMSMmodeText)); } diff --git a/features/cellular/UNITTESTS/stubs/ATHandler_stub.cpp b/features/cellular/UNITTESTS/stubs/ATHandler_stub.cpp index a4661ecfe3..3917c7a733 100644 --- a/features/cellular/UNITTESTS/stubs/ATHandler_stub.cpp +++ b/features/cellular/UNITTESTS/stubs/ATHandler_stub.cpp @@ -45,6 +45,13 @@ FileHandle_stub *ATHandler_stub::fh_value = NULL; device_err_t ATHandler_stub::device_err_value; Callback ATHandler_stub::callback = NULL; 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; + +int ATHandler_stub::read_string_index = kRead_string_table_size; +char* ATHandler_stub::read_string_table[kRead_string_table_size]; +int ATHandler_stub::resp_stop_success_count = kResp_stop_count_default; ATHandler::ATHandler(FileHandle *fh, EventQueue &queue, int timeout, const char *output_delimiter, uint16_t send_delay) : _nextATHandler(0), @@ -91,7 +98,7 @@ void ATHandler::set_file_handle(FileHandle *fh) nsapi_error_t ATHandler::set_urc_handler(const char *urc, mbed::Callback cb) { ATHandler_stub::callback = cb; - return NSAPI_ERROR_OK; + return ATHandler_stub::nsapi_error_value; } void ATHandler::remove_urc_handler(const char *prefix, mbed::Callback callback) @@ -136,6 +143,7 @@ void ATHandler::process_oob() void ATHandler::clear_error() { + ATHandler_stub::nsapi_error_ok_counter++; } void ATHandler::skip_param(uint32_t count) { @@ -153,15 +161,44 @@ ssize_t ATHandler::read_bytes(uint8_t *buf, size_t len) ssize_t ATHandler::read_string(char *buf, size_t size, bool read_even_stop_tag) { - if (ATHandler_stub::read_string_value && ATHandler_stub::ssize_value >= 0) { - memcpy(buf, ATHandler_stub::read_string_value, ATHandler_stub::ssize_value); + + if (ATHandler_stub::read_string_index == kRead_string_table_size) { + if (ATHandler_stub::read_string_value && ATHandler_stub::ssize_value >= 0) { + memcpy(buf, ATHandler_stub::read_string_value, ATHandler_stub::ssize_value); + } + return ATHandler_stub::ssize_value; } - return ATHandler_stub::ssize_value; + + ATHandler_stub::read_string_index--; + if (ATHandler_stub::read_string_index >= 0) { + char* tmp = ATHandler_stub::read_string_table[ATHandler_stub::read_string_index]; + ssize_t len = strlen(tmp); + memcpy(buf, tmp, len+1); + return len; + } + + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR; + return -1; } -int ATHandler::read_int() +int32_t ATHandler::read_int() { - return ATHandler_stub::int_value; + if (ATHandler_stub::nsapi_error_value != NSAPI_ERROR_OK) { + return -1; + } + + if (ATHandler_stub::int_count == kRead_int_table_size) { + return ATHandler_stub::int_value; + } + + //printf("ATHandler_stub::int_count: %d", ATHandler_stub::int_count); + ATHandler_stub::int_count--; + if (ATHandler_stub::int_count < kRead_int_table_size && ATHandler_stub::int_count >= 0) { + return ATHandler_stub::int_valid_count_table[ATHandler_stub::int_count]; + } + + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR; + return -1; } void ATHandler::set_delimiter(char delimiter) @@ -196,6 +233,10 @@ bool ATHandler::info_resp() bool ATHandler::info_elem(char start_tag) { + if (ATHandler_stub::info_elem_true_counter) { + ATHandler_stub::info_elem_true_counter--; + return true; + } return ATHandler_stub::bool_value; } @@ -206,13 +247,18 @@ bool ATHandler::consume_to_stop_tag() void ATHandler::resp_stop() { + if (ATHandler_stub::resp_stop_success_count > 0) { + ATHandler_stub::resp_stop_success_count--; + return; + } + ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR; } void ATHandler::cmd_start(const char* cmd) { } -void ATHandler::write_int(int param) +void ATHandler::write_int(int32_t param) { } diff --git a/features/cellular/UNITTESTS/stubs/ATHandler_stub.h b/features/cellular/UNITTESTS/stubs/ATHandler_stub.h index 0aa4be1498..0d5b3e820b 100644 --- a/features/cellular/UNITTESTS/stubs/ATHandler_stub.h +++ b/features/cellular/UNITTESTS/stubs/ATHandler_stub.h @@ -23,6 +23,9 @@ #include "FileHandle_stub.h" #include "Callback.h" +static const int kRead_string_table_size = 100; +static const int kRead_int_table_size = 100; +static const int kResp_stop_count_default = 100; namespace ATHandler_stub { extern nsapi_error_t nsapi_error_value; @@ -33,13 +36,19 @@ namespace ATHandler_stub { extern bool default_timeout; extern bool debug_on; extern ssize_t ssize_value; - extern char* read_string_value; + extern char *read_string_value; extern size_t size_value; extern size_t return_given_size; extern bool bool_value; extern uint8_t resp_info_true_counter; + 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 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; } diff --git a/features/cellular/UNITTESTS/stubs/AT_CellularBase_stub.cpp b/features/cellular/UNITTESTS/stubs/AT_CellularBase_stub.cpp index 0a6daf2d00..e7e37ac15e 100644 --- a/features/cellular/UNITTESTS/stubs/AT_CellularBase_stub.cpp +++ b/features/cellular/UNITTESTS/stubs/AT_CellularBase_stub.cpp @@ -41,3 +41,7 @@ device_err_t AT_CellularBase::get_device_error() const return AT_CellularBase_stub::device_err_value; } +bool AT_CellularBase::is_supported(SupportedFeature feature) +{ + return true; +} diff --git a/features/cellular/UNITTESTS/stubs/AT_CellularInformation_stub.cpp b/features/cellular/UNITTESTS/stubs/AT_CellularInformation_stub.cpp index a9cf1b5b0b..e9cdd24b0a 100644 --- a/features/cellular/UNITTESTS/stubs/AT_CellularInformation_stub.cpp +++ b/features/cellular/UNITTESTS/stubs/AT_CellularInformation_stub.cpp @@ -42,3 +42,8 @@ nsapi_error_t AT_CellularInformation::get_revision(char *buf, size_t buf_size) { return 0; } + +nsapi_error_t AT_CellularInformation::get_serial_number(char *buf, size_t buf_size, SerialNumberType type) +{ + return 0; +} diff --git a/features/cellular/UNITTESTS/stubs/AT_CellularSIM_stub.cpp b/features/cellular/UNITTESTS/stubs/AT_CellularSIM_stub.cpp index 85a7f04a64..ee06161aaa 100644 --- a/features/cellular/UNITTESTS/stubs/AT_CellularSIM_stub.cpp +++ b/features/cellular/UNITTESTS/stubs/AT_CellularSIM_stub.cpp @@ -52,3 +52,8 @@ 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; +} diff --git a/features/cellular/framework/API/CellularPower.h b/features/cellular/framework/API/CellularPower.h index b555bc23d1..b72470e365 100644 --- a/features/cellular/framework/API/CellularPower.h +++ b/features/cellular/framework/API/CellularPower.h @@ -92,7 +92,7 @@ public: * * @return zero on success */ - virtual nsapi_error_t set_power_level(int func_level, int do_reset = 1) = 0; + virtual nsapi_error_t set_power_level(int func_level, int do_reset = 0) = 0; /** Reset and wake-up cellular device. * diff --git a/features/cellular/framework/AT/AT_CellularNetwork.cpp b/features/cellular/framework/AT/AT_CellularNetwork.cpp index 6daa79b59a..c49bfe2e62 100644 --- a/features/cellular/framework/AT/AT_CellularNetwork.cpp +++ b/features/cellular/framework/AT/AT_CellularNetwork.cpp @@ -85,24 +85,24 @@ void AT_CellularNetwork::free_credentials() { if (_uname) { free(_uname); + _uname = NULL; } if (_pwd) { free(_pwd); + _pwd = NULL; } if (_apn) { free(_apn); + _apn = NULL; } } void AT_CellularNetwork::urc_no_carrier() { tr_error("Data call failed: no carrier"); - _connect_status = NSAPI_STATUS_DISCONNECTED; - if (_connection_status_cb) { - _connection_status_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_DISCONNECTED); - } + call_network_cb(NSAPI_STATUS_DISCONNECTED); } void AT_CellularNetwork::read_reg_params_and_compare(RegistrationType type) @@ -166,6 +166,8 @@ void AT_CellularNetwork::urc_cgreg() nsapi_error_t AT_CellularNetwork::set_credentials(const char *apn, const char *username, const char *password) { + free_credentials(); + size_t len; if (apn && (len = strlen(apn)) > 0) { _apn = (char *)malloc(len * sizeof(char) + 1); @@ -246,7 +248,7 @@ nsapi_error_t AT_CellularNetwork::activate_context() nsapi_error_t err = NSAPI_ERROR_OK; // try to find or create context with suitable stack - if(get_context()) { + if (get_context()) { // try to authenticate user before activating or modifying context err = do_user_authentication(); } else { @@ -256,11 +258,7 @@ nsapi_error_t AT_CellularNetwork::activate_context() if (err != NSAPI_ERROR_OK) { _at.unlock(); tr_error("Failed to activate network context! (%d)", err); - - _connect_status = NSAPI_STATUS_DISCONNECTED; - if (_connection_status_cb) { - _connection_status_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_DISCONNECTED); - } + call_network_cb(NSAPI_STATUS_DISCONNECTED); return err; } @@ -310,21 +308,14 @@ nsapi_error_t AT_CellularNetwork::activate_context() nsapi_error_t AT_CellularNetwork::connect() { - _connect_status = NSAPI_STATUS_CONNECTING; - if (_connection_status_cb) { - _connection_status_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_CONNECTING); - } + call_network_cb(NSAPI_STATUS_CONNECTING); nsapi_error_t err = NSAPI_ERROR_OK; if (!_is_context_active) { err = activate_context(); } if (err) { - _connect_status = NSAPI_STATUS_DISCONNECTED; - if (_connection_status_cb) { - _connection_status_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_DISCONNECTED); - } - + call_network_cb(NSAPI_STATUS_DISCONNECTED); return err; } @@ -334,17 +325,11 @@ nsapi_error_t AT_CellularNetwork::connect() _at.unlock(); if (err != NSAPI_ERROR_OK) { tr_error("Failed to open data channel!"); - _connect_status = NSAPI_STATUS_DISCONNECTED; - if (_connection_status_cb) { - _connection_status_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_DISCONNECTED); - } + call_network_cb(NSAPI_STATUS_DISCONNECTED); return err; } #else - _connect_status = NSAPI_STATUS_GLOBAL_UP; - if (_connection_status_cb) { - _connection_status_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_GLOBAL_UP); - } + call_network_cb(NSAPI_STATUS_GLOBAL_UP); #endif return NSAPI_ERROR_OK; @@ -401,15 +386,22 @@ nsapi_error_t AT_CellularNetwork::disconnect() _at.resp_stop(); _at.restore_at_timeout(); - _connect_status = NSAPI_STATUS_DISCONNECTED; - if (_connection_status_cb) { - _connection_status_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_DISCONNECTED); - } + call_network_cb(NSAPI_STATUS_DISCONNECTED); return _at.unlock_return_error(); #endif } +void AT_CellularNetwork::call_network_cb(nsapi_connection_status_t status) +{ + if (_connect_status != status) { + _connect_status = status; + if (_connection_status_cb) { + _connection_status_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, _connect_status); + } + } +} + void AT_CellularNetwork::attach(Callback status_cb) { _connection_status_cb = status_cb; @@ -575,6 +567,7 @@ bool AT_CellularNetwork::get_context() 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) { @@ -829,6 +822,8 @@ nsapi_error_t AT_CellularNetwork::detach() _at.resp_start(); _at.resp_stop(); + call_network_cb(NSAPI_STATUS_DISCONNECTED); + return _at.unlock_return_error(); } @@ -1048,10 +1043,8 @@ nsapi_error_t AT_CellularNetwork::get_rate_control( } } _at.resp_stop(); - nsapi_error_t ret = _at.get_last_error(); - _at.unlock(); - return (ret == NSAPI_ERROR_OK) ? NSAPI_ERROR_OK : NSAPI_ERROR_PARAMETER; + return _at.unlock_return_error(); } nsapi_error_t AT_CellularNetwork::get_pdpcontext_params(pdpContextList_t ¶ms_list) diff --git a/features/cellular/framework/AT/AT_CellularNetwork.h b/features/cellular/framework/AT/AT_CellularNetwork.h index c97381acc5..058e167de9 100644 --- a/features/cellular/framework/AT/AT_CellularNetwork.h +++ b/features/cellular/framework/AT/AT_CellularNetwork.h @@ -162,7 +162,8 @@ private: void read_reg_params_and_compare(RegistrationType type); void read_reg_params(RegistrationType type, RegistrationStatus ®_status, int &lac, int &cell_id, int &act); - + // calls network callback only if status was changed, updates local connection status + void call_network_cb(nsapi_connection_status_t status); #if NSAPI_PPP_AVAILABLE void ppp_status_cb(nsapi_event_t, intptr_t); #endif diff --git a/features/cellular/framework/AT/AT_CellularPower.h b/features/cellular/framework/AT/AT_CellularPower.h index 305a233a5e..eb4b2e9ab9 100644 --- a/features/cellular/framework/AT/AT_CellularPower.h +++ b/features/cellular/framework/AT/AT_CellularPower.h @@ -41,7 +41,7 @@ public: virtual nsapi_error_t set_at_mode(); - virtual nsapi_error_t set_power_level(int func_level, int do_reset = 1); + virtual nsapi_error_t set_power_level(int func_level, int do_reset = 0); virtual nsapi_error_t reset();