Skip to content

Commit 84bb815

Browse files
author
Teppo Järvelin
committed
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.
1 parent ce36104 commit 84bb815

File tree

7 files changed

+43
-19
lines changed

7 files changed

+43
-19
lines changed

UNITTESTS/features/cellular/framework/AT/at_cellularcontext/at_cellularcontexttest.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@ TEST_F(TestAT_CellularContext, connect_disconnect_sync)
537537
ATHandler_stub::read_string_index = 2;
538538
ASSERT_EQ(ctx1.connect(), NSAPI_ERROR_OK);
539539

540-
ASSERT_EQ(network_cb_count, 5);
540+
ASSERT_EQ(network_cb_count, 4);
541541

542542
ASSERT_EQ(ctx1.disconnect(), NSAPI_ERROR_OK);
543543
ATHandler_stub::resp_info_true_counter = 1;
@@ -704,7 +704,7 @@ TEST_F(TestAT_CellularContext, connect_disconnect_async)
704704
data.status_data = CellularNetwork::Attached;
705705
ctx1.cellular_callback((nsapi_event_t)CellularAttachNetwork, (intptr_t)&data);
706706

707-
ASSERT_EQ(network_cb_count, 5);
707+
ASSERT_EQ(network_cb_count, 4);
708708
ASSERT_EQ(ctx1.connect(), NSAPI_ERROR_IS_CONNECTED);
709709
EXPECT_TRUE(ctx1.is_connected() == true);
710710
ASSERT_EQ(ctx1.disconnect(), NSAPI_ERROR_NO_MEMORY);

UNITTESTS/features/cellular/framework/AT/at_cellularstack/at_cellularstacktest.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ TEST_F(TestAT_CellularStack, test_AT_CellularStack_get_ip_address)
175175
ATHandler at(&fh1, que, 0, ",");
176176

177177
MyStack st(at, 0, IPV6_STACK);
178-
EXPECT_EQ(strlen(st.get_ip_address()), 0);
178+
EXPECT_TRUE(st.get_ip_address() == NULL);
179179

180180
char table[] = "1.2.3.4.5.65.7.8.9.10.11\0";
181181
ATHandler_stub::ssize_value = -1;

UNITTESTS/features/cellular/framework/AT/at_cellularstack/unittest.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,5 @@ set(unittest-test-sources
2828
stubs/NetworkStack_stub.cpp
2929
stubs/SocketAddress_stub.cpp
3030
stubs/mbed_assert_stub.c
31+
stubs/ThisThread_stub.cpp
3132
)

features/cellular/framework/API/CellularContext.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,12 @@ class CellularContext : public CellularInterface {
344344
*/
345345
virtual void do_connect();
346346

347+
/** After we have connected successfully we must check that we have a valid IP address.
348+
* Some modems/networks don't give IP address right after connect so we must poll it for a while.
349+
* Whether we get IP address or not, this methods sends NSAPI_STATUS_GLOBAL_UP to application.
350+
*/
351+
void validate_ip_address();
352+
347353
// member variables needed in target override methods
348354
NetworkStack *_stack; // must be pointer because of PPP
349355
pdp_type_t _pdp_type;

features/cellular/framework/AT/AT_CellularContext.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -587,7 +587,6 @@ void AT_CellularContext::do_connect()
587587
}
588588
#else
589589
_is_connected = true;
590-
call_network_cb(NSAPI_STATUS_GLOBAL_UP);
591590
#endif
592591
}
593592

features/cellular/framework/AT/AT_CellularStack.cpp

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "AT_CellularStack.h"
1919
#include "CellularUtil.h"
2020
#include "CellularLog.h"
21+
#include "ThisThread.h"
2122

2223
using namespace mbed_cellular_util;
2324
using namespace mbed;
@@ -54,41 +55,31 @@ int AT_CellularStack::find_socket_index(nsapi_socket_t handle)
5455

5556
/** NetworkStack
5657
*/
57-
5858
const char *AT_CellularStack::get_ip_address()
5959
{
6060
_at.lock();
6161

6262
_at.cmd_start_stop("+CGPADDR", "=", "%d", _cid);
63-
6463
_at.resp_start("+CGPADDR:");
6564

65+
int len = -1;
6666
if (_at.info_resp()) {
67-
6867
_at.skip_param();
6968

70-
int len = _at.read_string(_ip, NSAPI_IPv4_SIZE);
71-
if (len == -1) {
72-
_ip[0] = '\0';
73-
_at.resp_stop();
74-
_at.unlock();
75-
// no IPV4 address, return
76-
return NULL;
77-
}
69+
len = _at.read_string(_ip, NSAPI_IPv4_SIZE);
7870

79-
// in case stack type is not IPV4 only, try to look also for IPV6 address
80-
if (_stack_type != IPV4_STACK) {
71+
if (len != -1 && _stack_type != IPV4_STACK) {
72+
// in case stack type is not IPV4 only, try to look also for IPV6 address
8173
(void)_at.read_string(_ip, PDP_IPV6_SIZE);
8274
}
8375
}
84-
8576
_at.resp_stop();
8677
_at.unlock();
8778

8879
// we have at least IPV4 address
8980
convert_ipv6(_ip);
9081

91-
return _ip;
82+
return len != -1 ? _ip : NULL;
9283
}
9384

9485
nsapi_error_t AT_CellularStack::socket_stack_init()

features/cellular/framework/device/CellularContext.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,30 @@ void CellularContext::set_authentication_type(AuthenticationType type)
8787
_authentication_type = type;
8888
}
8989

90+
void CellularContext::validate_ip_address()
91+
{
92+
const int IP_MAX_TRIES = 10; // maximum of 2 seconds as we wait 200ms between tries
93+
const int IP_WAIT_INTERVAL = 200; // 200 ms between retries
94+
const char *ip = NULL;
95+
int i = 0;
96+
97+
while (1) {
98+
ip = get_ip_address();
99+
if (ip || i >= IP_MAX_TRIES) {
100+
if (ip == NULL) {
101+
tr_warning("Connected but no local ip address");
102+
} else {
103+
tr_info("Cellular local IP: %s", ip);
104+
}
105+
break;
106+
}
107+
rtos::ThisThread::sleep_for(IP_WAIT_INTERVAL);
108+
i++;
109+
}
110+
111+
call_network_cb(NSAPI_STATUS_GLOBAL_UP);
112+
}
113+
90114
void CellularContext::do_connect_with_retry()
91115
{
92116
if (_cb_data.final_try) {
@@ -97,6 +121,9 @@ void CellularContext::do_connect_with_retry()
97121
}
98122
do_connect();
99123
if (_cb_data.error == NSAPI_ERROR_OK) {
124+
// Some modems don't get the ip address right after connect so we must
125+
// validate it but even if we don't get ip we still send NSAPI_STATUS_GLOBAL_UP
126+
validate_ip_address();
100127
return;
101128
}
102129

0 commit comments

Comments
 (0)