diff --git a/UNITTESTS/features/cellular/framework/device/cellularcontext/cellularcontexttest.cpp b/UNITTESTS/features/cellular/framework/device/cellularcontext/cellularcontexttest.cpp new file mode 100644 index 0000000000..8e91358230 --- /dev/null +++ b/UNITTESTS/features/cellular/framework/device/cellularcontext/cellularcontexttest.cpp @@ -0,0 +1,307 @@ +/* + * 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 + +#include "CellularContext.h" +#include "CellularDevice_stub.h" +#include "ControlPlane_netif_stub.h" +#include "myCellularDevice.h" + +using namespace mbed; + +// AStyle ignored as the definition is not clear due to preprocessor usage +// *INDENT-OFF* +class TestCellularContext : public testing::Test { +protected: + + void SetUp() + { + CellularDevice_stub::create_in_get_default = true; + } + + void TearDown() + { + } +}; + +class testContext : public CellularContext +{ +public: + + testContext(CellularDevice *dev = NULL) + { + _device = dev; + _cp_netif = new ControlPlane_netif_stub(); + } + + ~testContext() + { + delete _cp_netif; + } + int get_retry_count() + { + return _retry_count; + } + CellularContext::AuthenticationType get_auth_type() + { + return _authentication_type; + } + nsapi_error_t set_blocking(bool blocking) + { + _is_blocking = blocking; + return NSAPI_ERROR_OK; + } + + NetworkStack *get_stack() + { + return NULL; + } + + const char *get_ip_address() + { + return NULL; + } + virtual void attach(mbed::Callback status_cb) + { + _status_cb = status_cb; + } + virtual nsapi_error_t connect() + { + return NSAPI_ERROR_OK; + } + + virtual nsapi_error_t disconnect() + { + return NSAPI_ERROR_OK; + } + + virtual void set_plmn(const char *plmn) + { + } + virtual void set_sim_pin(const char *sim_pin) + { + } + virtual nsapi_error_t connect(const char *sim_pin, const char *apn = 0, const char *uname = 0, + const char *pwd = 0) + { + return NSAPI_ERROR_OK; + } + virtual void set_credentials(const char *apn, const char *uname = 0, const char *pwd = 0) + { + } + virtual const char *get_netmask() + { + return NULL; + } + virtual const char *get_gateway() + { + return NULL; + } + virtual bool is_connected() + { + return false; + } + 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 get_rate_control(CellularContext::RateControlExceptionReports &reports, + CellularContext::RateControlUplinkTimeUnit &time_unit, int &uplink_rate) + { + return NSAPI_ERROR_OK; + } + nsapi_error_t get_pdpcontext_params(pdpContextList_t ¶ms_list) + { + return NSAPI_ERROR_OK; + } + nsapi_error_t get_apn_backoff_timer(int &backoff_timer) + { + return NSAPI_ERROR_OK; + } + void set_file_handle(FileHandle *fh) + { + + } +#if (DEVICE_SERIAL && DEVICE_INTERRUPTIN) || defined(DOXYGEN_ONLY) + virtual void set_file_handle(UARTSerial *serial, PinName dcd_pin = NC, bool active_high = false) + { + + } +#endif + ControlPlane_netif *get_cp_netif() + { + return _cp_netif; + } + void cellular_callback(nsapi_event_t ev, intptr_t ptr) + { + + } + void enable_hup(bool enable) + { + + } + + void cp_data_received() + { + CellularContext::cp_data_received(); + } + + virtual void do_connect() + { + } + + void set_cell_callback_data(cell_callback_data_t &cb_data) + { + _cb_data = cb_data; + } + + void do_connect_with_retry() + { + CellularContext::do_connect_with_retry(); + } +}; + +static int network_cb_count = 0; +static void network_cb(nsapi_event_t ev, intptr_t intptr) +{ + network_cb_count++; +} + +// *INDENT-ON* +TEST_F(TestCellularContext, test_create_delete) +{ + CellularDevice_stub::create_in_get_default = false; + CellularContext *ctx = CellularContext::get_default_instance(); + EXPECT_TRUE(ctx == NULL); + + ctx = CellularContext::get_default_nonip_instance(); + EXPECT_TRUE(ctx == NULL); + + CellularDevice_stub::create_in_get_default = true; + ctx = CellularContext::get_default_instance(); + EXPECT_TRUE(ctx != NULL); + + ctx = CellularContext::get_default_nonip_instance(); + EXPECT_TRUE(ctx != NULL); +} + +TEST_F(TestCellularContext, get_device) +{ + CellularContext *ctx = CellularContext::get_default_instance(); + EXPECT_TRUE(ctx != NULL); + + CellularDevice *dev = ctx->get_device(); + EXPECT_TRUE(dev != NULL); +} + +TEST_F(TestCellularContext, get_cid) +{ + CellularContext *ctx = CellularContext::get_default_instance(); + EXPECT_TRUE(ctx != NULL); + + int cid = ctx->get_cid(); + ASSERT_EQ(cid, -1); +} + +TEST_F(TestCellularContext, set_authentication_type) +{ + testContext *ctx = new testContext(); + EXPECT_TRUE(ctx != NULL); + + ASSERT_EQ(ctx->get_auth_type(), CellularContext::CHAP); + ctx->set_authentication_type(CellularContext::PAP); + ASSERT_EQ(ctx->get_auth_type(), CellularContext::PAP); + + delete ctx; +} + +TEST_F(TestCellularContext, cp_data_received) +{ + testContext *ctx = new testContext(); + EXPECT_TRUE(ctx != NULL); + + ControlPlane_netif_stub *netif = (ControlPlane_netif_stub *)ctx->get_cp_netif(); + EXPECT_TRUE(!netif->cp_data_received_called); + ctx->cp_data_received(); + EXPECT_TRUE(netif->cp_data_received_called); + + delete ctx; +} + +TEST_F(TestCellularContext, do_connect_with_retry) +{ + testContext *ctx = new testContext(); + EXPECT_TRUE(ctx != NULL); + ctx->attach(network_cb); + + cell_callback_data_t cb_data; + cb_data.final_try = true; + ctx->set_cell_callback_data(cb_data); + ctx->do_connect_with_retry(); + ASSERT_EQ(network_cb_count, 0); + + cb_data.error = NSAPI_ERROR_OK; + cb_data.final_try = false; + ctx->set_cell_callback_data(cb_data); + ctx->do_connect_with_retry(); + + CellularDevice_stub::retry_array_length = 2; + cb_data.error = NSAPI_ERROR_DEVICE_ERROR; + cb_data.final_try = false; + ctx->set_cell_callback_data(cb_data); + ctx->do_connect_with_retry(); + ASSERT_EQ(ctx->get_retry_count(), 2); + + delete ctx; +} + +TEST_F(TestCellularContext, do_connect_with_retry_async) +{ + myCellularDevice *dev = new myCellularDevice(0); + testContext *ctx = new testContext(dev); + EXPECT_TRUE(ctx != NULL); + ctx->attach(network_cb); + ASSERT_EQ(NSAPI_ERROR_OK, ctx->set_blocking(false)); + + cell_callback_data_t cb_data; + CellularDevice_stub::retry_array_length = 2; + cb_data.error = NSAPI_ERROR_DEVICE_ERROR; + cb_data.final_try = false; + ctx->set_cell_callback_data(cb_data); + ctx->do_connect_with_retry(); + ASSERT_EQ(ctx->get_retry_count(), 1); + + delete ctx; + delete dev; +} + + + + diff --git a/UNITTESTS/features/cellular/framework/device/cellularcontext/unittest.cmake b/UNITTESTS/features/cellular/framework/device/cellularcontext/unittest.cmake new file mode 100644 index 0000000000..b85f32586e --- /dev/null +++ b/UNITTESTS/features/cellular/framework/device/cellularcontext/unittest.cmake @@ -0,0 +1,42 @@ + +#################### +# UNIT TESTS +#################### + +# Add test specific include paths +set(unittest-includes ${unittest-includes} + /features/cellular/framework/device/cellulardevice + ../features/cellular/framework/device + ../features/cellular/framework/common + ../features/netsocket/cellular +) + +# Source files +set(unittest-sources + ../features/cellular/framework/device/CellularContext.cpp +) + +# Test files +set(unittest-test-sources + features/cellular/framework/device/cellularcontext/cellularcontexttest.cpp + stubs/FileHandle_stub.cpp + stubs/CellularStateMachine_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/Semaphore_stub.cpp + stubs/NetworkInterface_stub.cpp + stubs/NetworkInterfaceDefaults_stub.cpp + stubs/CellularDevice_stub.cpp + stubs/equeue_stub.c + stubs/ThisThread_stub.cpp +) + +# 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 -DMBED_CONF_CELLULAR_CONTROL_PLANE_OPT=0") +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 -DMBED_CONF_CELLULAR_CONTROL_PLANE_OPT=0") diff --git a/UNITTESTS/stubs/CellularContext_stub.cpp b/UNITTESTS/stubs/CellularContext_stub.cpp index 156016a03b..f976643848 100644 --- a/UNITTESTS/stubs/CellularContext_stub.cpp +++ b/UNITTESTS/stubs/CellularContext_stub.cpp @@ -43,6 +43,11 @@ int CellularContext::get_cid() const return _cid; } +void CellularContext::set_authentication_type(AuthenticationType type) +{ + _authentication_type = type; +} + void CellularContext::do_connect_with_retry() { do_connect(); diff --git a/UNITTESTS/stubs/CellularDevice_stub.cpp b/UNITTESTS/stubs/CellularDevice_stub.cpp index a0aeb850ab..0d89887cbd 100644 --- a/UNITTESTS/stubs/CellularDevice_stub.cpp +++ b/UNITTESTS/stubs/CellularDevice_stub.cpp @@ -15,19 +15,26 @@ * limitations under the License. */ -#include "CellularDevice.h" #include "CellularDevice_stub.h" #include "events/EventQueue.h" #include "CellularUtil.h" +#include "myCellularDevice.h" using namespace mbed; int CellularDevice_stub::connect_counter = -1; - +bool CellularDevice_stub::create_in_get_default = false; +uint16_t CellularDevice_stub::retry_timeout_array[CELLULAR_RETRY_ARRAY_SIZE] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; +int CellularDevice_stub::retry_array_length = 0; MBED_WEAK CellularDevice *CellularDevice::get_default_instance() { - return NULL; + if (CellularDevice_stub::create_in_get_default) { + static myCellularDevice dev(NULL); + return &dev; + } else { + return NULL; + } } CellularDevice::CellularDevice(FileHandle *fh) : _network_ref_count(0), _sms_ref_count(0), @@ -58,6 +65,17 @@ CellularContext *CellularDevice::get_context_list() const return NULL; } +void CellularDevice::get_retry_timeout_array(uint16_t *timeout, int &array_len) const +{ + array_len = CellularDevice_stub::retry_array_length; + + if (CellularDevice_stub::retry_array_length == 0) { + timeout = 0; + } else { + timeout = CellularDevice_stub::retry_timeout_array; + } +} + nsapi_error_t CellularDevice::set_device_ready() { return NSAPI_ERROR_OK; diff --git a/UNITTESTS/stubs/CellularDevice_stub.h b/UNITTESTS/stubs/CellularDevice_stub.h index 6e865e353c..b8aa69e00c 100644 --- a/UNITTESTS/stubs/CellularDevice_stub.h +++ b/UNITTESTS/stubs/CellularDevice_stub.h @@ -17,9 +17,13 @@ #ifndef CELLULARDEVICE_STUB_H_ #define CELLULARDEVICE_STUB_H_ +#include "CellularDevice.h" namespace CellularDevice_stub { extern int connect_counter; +extern bool create_in_get_default; +extern uint16_t retry_timeout_array[CELLULAR_RETRY_ARRAY_SIZE]; +extern int retry_array_length; } diff --git a/UNITTESTS/stubs/ControlPlane_netif_stub.h b/UNITTESTS/stubs/ControlPlane_netif_stub.h index 52661c52b8..d473056ec6 100644 --- a/UNITTESTS/stubs/ControlPlane_netif_stub.h +++ b/UNITTESTS/stubs/ControlPlane_netif_stub.h @@ -24,10 +24,12 @@ class ControlPlane_netif_stub : public ControlPlane_netif { public: std::list return_values; nsapi_error_t return_value; + bool cp_data_received_called; ControlPlane_netif_stub() { return_value = 0; + cp_data_received_called = false; } protected: @@ -51,7 +53,10 @@ protected: return return_value; }; - virtual void data_received() {}; + virtual void data_received() + { + cp_data_received_called = true; + }; virtual void attach(void (*callback)(void *), void *data) {}; }; diff --git a/UNITTESTS/stubs/ThisThread_stub.cpp b/UNITTESTS/stubs/ThisThread_stub.cpp index 28eb18fa8b..e829dbbdb4 100644 --- a/UNITTESTS/stubs/ThisThread_stub.cpp +++ b/UNITTESTS/stubs/ThisThread_stub.cpp @@ -23,4 +23,8 @@ void ThisThread::sleep_until(uint64_t millisec) { } +void ThisThread::sleep_for(uint32_t millisec) +{ +} + } diff --git a/UNITTESTS/target_h/myCellularDevice.h b/UNITTESTS/target_h/myCellularDevice.h index 16c96d8b28..ff99be062c 100644 --- a/UNITTESTS/target_h/myCellularDevice.h +++ b/UNITTESTS/target_h/myCellularDevice.h @@ -54,17 +54,27 @@ public: 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; + if (_context_list) { + return _context_list; + } + EventQueue que; + ATHandler at(serial, que, 0, ","); + _context_list = new AT_CellularContext(at, this); + return _context_list; } virtual CellularContext *create_context(FileHandle *fh = NULL, const char *apn = NULL, bool cp_req = false, bool nonip_req = false) { + if (_context_list) { + return _context_list; + } EventQueue que; FileHandle_stub fh1; ATHandler at(&fh1, que, 0, ","); - _context_list = new AT_CellularContext(at, NULL); + _context_list = new AT_CellularContext(at, this); return _context_list; } + virtual void delete_context(CellularContext *context) { delete _context_list; diff --git a/features/cellular/framework/API/CellularContext.h b/features/cellular/framework/API/CellularContext.h index fb8765f03c..947461f5dd 100644 --- a/features/cellular/framework/API/CellularContext.h +++ b/features/cellular/framework/API/CellularContext.h @@ -289,6 +289,12 @@ public: // from NetworkInterface */ int get_cid() const; + /** Set the authentication type to be used in user authentication if user name and password are defined + * + * @param type enum AuthenticationType + */ + void set_authentication_type(AuthenticationType type); + protected: // Device specific implementations might need these so protected enum ContextOperation { OP_INVALID = -1, diff --git a/features/cellular/framework/device/CellularContext.cpp b/features/cellular/framework/device/CellularContext.cpp index 665cc2c844..0b4ea68bd9 100644 --- a/features/cellular/framework/device/CellularContext.cpp +++ b/features/cellular/framework/device/CellularContext.cpp @@ -82,6 +82,11 @@ int CellularContext::get_cid() const return _cid; } +void CellularContext::set_authentication_type(AuthenticationType type) +{ + _authentication_type = type; +} + void CellularContext::do_connect_with_retry() { if (_cb_data.final_try) {