From ce36104ab33ad266109e0ef1faf25f9d0df4352c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Teppo=20J=C3=A4rvelin?= Date: Mon, 12 Aug 2019 09:39:41 +0300 Subject: [PATCH 1/3] Fix netsocket DNS test for IAR Test case printed IP address. If ip address is null, IAR compiled binary fails. Added check for printing null. If IP address is null, then it prints string 'null'. --- TESTS/netsocket/dns/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TESTS/netsocket/dns/main.cpp b/TESTS/netsocket/dns/main.cpp index 8761b1f7efa..ae2e3f5b820 100644 --- a/TESTS/netsocket/dns/main.cpp +++ b/TESTS/netsocket/dns/main.cpp @@ -160,7 +160,7 @@ static void net_bringup() net = NetworkInterface::get_default_instance(); nsapi_error_t err = net->connect(); TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, err); - printf("MBED: IP address is '%s'\n", net->get_ip_address()); + printf("MBED: IP address is '%s'\n", net->get_ip_address() ? net->get_ip_address() : "null"); } static void net_bringdown() From 6a17d74b558b8bde5bf5d27961722ec2a79245c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Teppo=20J=C3=A4rvelin?= Date: Tue, 13 Aug 2019 11:18:55 +0300 Subject: [PATCH 2/3] Cellular: notify global up after we have IP address CellularContext now tries to get an IP address after connect and before sending NSAPI_STATUS_GLOBAL_UP. Even if we don't the IP address from the modem we will send NSAPI_STATUS_GLOBAL_UP and return success. Modem has an ip address but for some reason some modems don't give it to us. --- .../at_cellularcontexttest.cpp | 4 +-- .../at_cellularstack/at_cellularstacktest.cpp | 2 +- .../AT/at_cellularstack/unittest.cmake | 1 + UNITTESTS/stubs/AT_CellularContext_stub.cpp | 4 ++- .../cellular/framework/API/CellularContext.h | 9 ++++++ .../framework/AT/AT_CellularContext.cpp | 5 ++-- .../framework/AT/AT_CellularContext.h | 4 --- .../framework/AT/AT_CellularStack.cpp | 21 ++++--------- .../framework/device/CellularContext.cpp | 30 ++++++++++++++++++- 9 files changed, 53 insertions(+), 27 deletions(-) diff --git a/UNITTESTS/features/cellular/framework/AT/at_cellularcontext/at_cellularcontexttest.cpp b/UNITTESTS/features/cellular/framework/AT/at_cellularcontext/at_cellularcontexttest.cpp index a8acae727c3..451c3a571cc 100644 --- a/UNITTESTS/features/cellular/framework/AT/at_cellularcontext/at_cellularcontexttest.cpp +++ b/UNITTESTS/features/cellular/framework/AT/at_cellularcontext/at_cellularcontexttest.cpp @@ -537,7 +537,7 @@ TEST_F(TestAT_CellularContext, connect_disconnect_sync) ATHandler_stub::read_string_index = 2; ASSERT_EQ(ctx1.connect(), NSAPI_ERROR_OK); - ASSERT_EQ(network_cb_count, 5); + ASSERT_EQ(network_cb_count, 4); ASSERT_EQ(ctx1.disconnect(), NSAPI_ERROR_OK); ATHandler_stub::resp_info_true_counter = 1; @@ -704,7 +704,7 @@ TEST_F(TestAT_CellularContext, connect_disconnect_async) data.status_data = CellularNetwork::Attached; ctx1.cellular_callback((nsapi_event_t)CellularAttachNetwork, (intptr_t)&data); - ASSERT_EQ(network_cb_count, 5); + ASSERT_EQ(network_cb_count, 4); ASSERT_EQ(ctx1.connect(), NSAPI_ERROR_IS_CONNECTED); EXPECT_TRUE(ctx1.is_connected() == true); ASSERT_EQ(ctx1.disconnect(), NSAPI_ERROR_NO_MEMORY); diff --git a/UNITTESTS/features/cellular/framework/AT/at_cellularstack/at_cellularstacktest.cpp b/UNITTESTS/features/cellular/framework/AT/at_cellularstack/at_cellularstacktest.cpp index 214ab1c8928..57ad8519f52 100644 --- a/UNITTESTS/features/cellular/framework/AT/at_cellularstack/at_cellularstacktest.cpp +++ b/UNITTESTS/features/cellular/framework/AT/at_cellularstack/at_cellularstacktest.cpp @@ -175,7 +175,7 @@ TEST_F(TestAT_CellularStack, test_AT_CellularStack_get_ip_address) ATHandler at(&fh1, que, 0, ","); MyStack st(at, 0, IPV6_STACK); - EXPECT_EQ(strlen(st.get_ip_address()), 0); + EXPECT_TRUE(st.get_ip_address() == NULL); char table[] = "1.2.3.4.5.65.7.8.9.10.11\0"; ATHandler_stub::ssize_value = -1; diff --git a/UNITTESTS/features/cellular/framework/AT/at_cellularstack/unittest.cmake b/UNITTESTS/features/cellular/framework/AT/at_cellularstack/unittest.cmake index 2f1a243e02c..f0525045d70 100644 --- a/UNITTESTS/features/cellular/framework/AT/at_cellularstack/unittest.cmake +++ b/UNITTESTS/features/cellular/framework/AT/at_cellularstack/unittest.cmake @@ -28,4 +28,5 @@ set(unittest-test-sources stubs/NetworkStack_stub.cpp stubs/SocketAddress_stub.cpp stubs/mbed_assert_stub.c + stubs/ThisThread_stub.cpp ) diff --git a/UNITTESTS/stubs/AT_CellularContext_stub.cpp b/UNITTESTS/stubs/AT_CellularContext_stub.cpp index 4f89449efaa..32c0a4dd889 100644 --- a/UNITTESTS/stubs/AT_CellularContext_stub.cpp +++ b/UNITTESTS/stubs/AT_CellularContext_stub.cpp @@ -21,7 +21,7 @@ using namespace mbed; AT_CellularContext::AT_CellularContext(ATHandler &at, CellularDevice *device, const char *apn, bool cp_req, bool nonip_req) : AT_CellularBase(at), _is_connected(false), - _current_op(OP_INVALID), _fh(0), _cp_req(cp_req), _nonip_req(nonip_req), _cp_in_use(false) + _current_op(OP_INVALID), _fh(0), _cp_req(cp_req) { _stack = NULL; _pdp_type = DEFAULT_PDP_TYPE; @@ -43,6 +43,8 @@ AT_CellularContext::AT_CellularContext(ATHandler &at, CellularDevice *device, co _is_blocking = true; _device = device; _nw = NULL; + _nonip_req = nonip_req; + _cp_in_use = false; } AT_CellularContext::~AT_CellularContext() diff --git a/features/cellular/framework/API/CellularContext.h b/features/cellular/framework/API/CellularContext.h index 7f5c1ceb40b..f2fa19c2e26 100644 --- a/features/cellular/framework/API/CellularContext.h +++ b/features/cellular/framework/API/CellularContext.h @@ -344,6 +344,11 @@ class CellularContext : public CellularInterface { */ virtual void do_connect(); + /** After we have connected successfully we must check that we have a valid IP address. + * Some modems/networks don't give IP address right after connect so we must poll it for a while. + */ + void validate_ip_address(); + // member variables needed in target override methods NetworkStack *_stack; // must be pointer because of PPP pdp_type_t _pdp_type; @@ -368,6 +373,10 @@ class CellularContext : public CellularInterface { CellularDevice *_device; CellularNetwork *_nw; bool _is_blocking; + // flag indicating if Non-IP context was requested to be setup + bool _nonip_req; + // tells if CCIOTOPTI received green from network for CP optimization use + bool _cp_in_use; }; /** diff --git a/features/cellular/framework/AT/AT_CellularContext.cpp b/features/cellular/framework/AT/AT_CellularContext.cpp index 04dbe60cb56..5539a28230a 100644 --- a/features/cellular/framework/AT/AT_CellularContext.cpp +++ b/features/cellular/framework/AT/AT_CellularContext.cpp @@ -48,10 +48,10 @@ using namespace mbed; using namespace rtos; AT_CellularContext::AT_CellularContext(ATHandler &at, CellularDevice *device, const char *apn, bool cp_req, bool nonip_req) : - AT_CellularBase(at), _is_connected(false), _current_op(OP_INVALID), _fh(0), _cp_req(cp_req), - _nonip_req(nonip_req), _cp_in_use(false) + AT_CellularBase(at), _is_connected(false), _current_op(OP_INVALID), _fh(0), _cp_req(cp_req) { tr_info("New CellularContext %s (%p)", apn ? apn : "", this); + _nonip_req = nonip_req; _apn = apn; _device = device; } @@ -587,7 +587,6 @@ void AT_CellularContext::do_connect() } #else _is_connected = true; - call_network_cb(NSAPI_STATUS_GLOBAL_UP); #endif } diff --git a/features/cellular/framework/AT/AT_CellularContext.h b/features/cellular/framework/AT/AT_CellularContext.h index 9831d9b9fab..7c3a527721c 100644 --- a/features/cellular/framework/AT/AT_CellularContext.h +++ b/features/cellular/framework/AT/AT_CellularContext.h @@ -131,10 +131,6 @@ class AT_CellularContext : public CellularContext, public AT_CellularBase { char _found_apn[MAX_APN_LENGTH]; // flag indicating if CP was requested to be setup bool _cp_req; - // flag indicating if Non-IP context was requested to be setup - bool _nonip_req; - // tells if CCIOTOPTI received green from network for CP optimization use - bool _cp_in_use; }; } // namespace mbed diff --git a/features/cellular/framework/AT/AT_CellularStack.cpp b/features/cellular/framework/AT/AT_CellularStack.cpp index 31417a98d82..a8aba5b578d 100644 --- a/features/cellular/framework/AT/AT_CellularStack.cpp +++ b/features/cellular/framework/AT/AT_CellularStack.cpp @@ -18,6 +18,7 @@ #include "AT_CellularStack.h" #include "CellularUtil.h" #include "CellularLog.h" +#include "ThisThread.h" using namespace mbed_cellular_util; using namespace mbed; @@ -54,41 +55,31 @@ int AT_CellularStack::find_socket_index(nsapi_socket_t handle) /** NetworkStack */ - const char *AT_CellularStack::get_ip_address() { _at.lock(); _at.cmd_start_stop("+CGPADDR", "=", "%d", _cid); - _at.resp_start("+CGPADDR:"); + int len = -1; if (_at.info_resp()) { - _at.skip_param(); - int len = _at.read_string(_ip, NSAPI_IPv4_SIZE); - if (len == -1) { - _ip[0] = '\0'; - _at.resp_stop(); - _at.unlock(); - // no IPV4 address, return - return NULL; - } + len = _at.read_string(_ip, PDP_IPV6_SIZE); - // in case stack type is not IPV4 only, try to look also for IPV6 address - if (_stack_type != IPV4_STACK) { + if (len != -1 && _stack_type != IPV4_STACK) { + // in case stack type is not IPV4 only, try to look also for IPV6 address (void)_at.read_string(_ip, PDP_IPV6_SIZE); } } - _at.resp_stop(); _at.unlock(); // we have at least IPV4 address convert_ipv6(_ip); - return _ip; + return len != -1 ? _ip : NULL; } nsapi_error_t AT_CellularStack::socket_stack_init() diff --git a/features/cellular/framework/device/CellularContext.cpp b/features/cellular/framework/device/CellularContext.cpp index 0b4ea68bd94..cf2746ecdbe 100644 --- a/features/cellular/framework/device/CellularContext.cpp +++ b/features/cellular/framework/device/CellularContext.cpp @@ -62,7 +62,7 @@ CellularContext::CellularContext() : _next(0), _stack(0), _pdp_type(DEFAULT_PDP_ _authentication_type(CellularContext::CHAP), _connect_status(NSAPI_STATUS_DISCONNECTED), _status_cb(0), _cid(-1), _new_context_set(false), _is_context_active(false), _is_context_activated(false), _apn(0), _uname(0), _pwd(0), _dcd_pin(NC), _active_high(false), _cp_netif(0), _retry_array_length(0), - _retry_count(0), _device(0), _nw(0), _is_blocking(true) + _retry_count(0), _device(0), _nw(0), _is_blocking(true), _nonip_req(false), _cp_in_use(false) { memset(_retry_timeout_array, 0, CELLULAR_RETRY_ARRAY_SIZE); } @@ -87,6 +87,28 @@ void CellularContext::set_authentication_type(AuthenticationType type) _authentication_type = type; } +void CellularContext::validate_ip_address() +{ + const int IP_MAX_TRIES = 10; // maximum of 2 seconds as we wait 200ms between tries + const int IP_WAIT_INTERVAL = 200; // 200 ms between retries + const char *ip = NULL; + int i = 0; + + while (1) { + ip = get_ip_address(); + if (ip || i >= IP_MAX_TRIES) { + if (ip == NULL) { + tr_warning("Connected but no local ip address"); + } else { + tr_info("Cellular local IP: %s", ip); + } + break; + } + rtos::ThisThread::sleep_for(IP_WAIT_INTERVAL); + i++; + } +} + void CellularContext::do_connect_with_retry() { if (_cb_data.final_try) { @@ -97,6 +119,12 @@ void CellularContext::do_connect_with_retry() } do_connect(); if (_cb_data.error == NSAPI_ERROR_OK) { + // Some modems don't get the ip address right after connect so we must + // validate it but even if we don't get ip we still send NSAPI_STATUS_GLOBAL_UP + if (!_nonip_req && !_cp_in_use) { // don't validate if non-ip case + validate_ip_address(); + } + call_network_cb(NSAPI_STATUS_GLOBAL_UP); return; } From 65bf17eff53c3f5fba569fa689eeb1b8b3bd5c0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Teppo=20J=C3=A4rvelin?= Date: Thu, 15 Aug 2019 15:26:36 +0300 Subject: [PATCH 3/3] Fix netsocket tests for IAR Test case printed IP address. If ip address is null, IAR compiled binary fails. Added check for printing null. If IP address is null, then it prints string 'null'. --- TESTS/netsocket/tcp/main.cpp | 2 +- TESTS/netsocket/tls/main.cpp | 2 +- TESTS/netsocket/udp/main.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/TESTS/netsocket/tcp/main.cpp b/TESTS/netsocket/tcp/main.cpp index 2f41109d863..019908cde2c 100644 --- a/TESTS/netsocket/tcp/main.cpp +++ b/TESTS/netsocket/tcp/main.cpp @@ -72,7 +72,7 @@ static void _ifup() NetworkInterface *net = NetworkInterface::get_default_instance(); nsapi_error_t err = net->connect(); TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, err); - printf("MBED: TCPClient IP address is '%s'\n", net->get_ip_address()); + printf("MBED: TCPClient IP address is '%s'\n", net->get_ip_address() ? net->get_ip_address() : "null"); } static void _ifdown() diff --git a/TESTS/netsocket/tls/main.cpp b/TESTS/netsocket/tls/main.cpp index f7ae2253578..2a8fb9033a8 100644 --- a/TESTS/netsocket/tls/main.cpp +++ b/TESTS/netsocket/tls/main.cpp @@ -94,7 +94,7 @@ static void _ifup() NetworkInterface *net = NetworkInterface::get_default_instance(); nsapi_error_t err = net->connect(); TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, err); - printf("MBED: TLSClient IP address is '%s'\n", net->get_ip_address()); + printf("MBED: TLSClient IP address is '%s'\n", net->get_ip_address() ? net->get_ip_address() : "null"); } static void _ifdown() diff --git a/TESTS/netsocket/udp/main.cpp b/TESTS/netsocket/udp/main.cpp index 38ae7a203f9..680b2cc92fd 100644 --- a/TESTS/netsocket/udp/main.cpp +++ b/TESTS/netsocket/udp/main.cpp @@ -59,7 +59,7 @@ static void _ifup() NetworkInterface *net = NetworkInterface::get_default_instance(); nsapi_error_t err = net->connect(); TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, err); - printf("MBED: UDPClient IP address is '%s'\n", net->get_ip_address()); + printf("MBED: UDPClient IP address is '%s'\n", net->get_ip_address() ? net->get_ip_address() : "null"); } static void _ifdown()