Skip to content

Commit 282f3c9

Browse files
author
Jarno Lamsa
committed
Add support for error cases for lwip and nanostack
1 parent 5a74826 commit 282f3c9

File tree

6 files changed

+119
-12
lines changed

6 files changed

+119
-12
lines changed

features/FEATURE_LWIP/lwip-interface/lwip_stack.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,7 @@ static void mbed_lwip_netif_link_irq(struct netif *lwip_netif)
482482

483483
} else {
484484
sys_sem_signal(&lwip_netif_unlinked);
485+
netif_set_down(lwip_netif);
485486
}
486487
}
487488

features/nanostack/FEATURE_NANOSTACK/mbed-mesh-api/mbed-mesh-api/mesh_interface_types.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,12 @@ typedef enum {
4545
*/
4646
typedef enum {
4747
MESH_CONNECTED = 0, /*<! connected to network */
48+
MESH_CONNECTED_LOCAL, /*<! connected to network, got local IP */
49+
MESH_CONNECTED_GLOBAL, /*<! connected to network, got global IP */
4850
MESH_DISCONNECTED, /*<! disconnected from network */
4951
MESH_BOOTSTRAP_START_FAILED, /*<! error during bootstrap start */
50-
MESH_BOOTSTRAP_FAILED /*<! error in bootstrap */
52+
MESH_BOOTSTRAP_FAILED, /*<! error in bootstrap */
53+
MESH_BOOTSTRAP_STARTED /*<! bootstrap started */
5154
} mesh_connection_status_t;
5255

5356
/*

features/nanostack/FEATURE_NANOSTACK/mbed-mesh-api/source/MeshInterfaceNanostack.cpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "NanostackInterface.h"
1919
#include "mesh_system.h"
2020
#include "net_interface.h"
21+
#include "thread_management_if.h"
2122

2223

2324
MeshInterfaceNanostack::MeshInterfaceNanostack()
@@ -49,20 +50,30 @@ void MeshInterfaceNanostack::mesh_network_handler(mesh_connection_status_t statu
4950
{
5051
nanostack_lock();
5152

52-
if (status == MESH_CONNECTED && _blocking) {
53+
if ((status == MESH_CONNECTED || status == MESH_CONNECTED_LOCAL ||
54+
status == MESH_CONNECTED_GLOBAL) && _blocking) {
5355
connect_semaphore.release();
5456
}
5557

5658
nanostack_unlock();
5759

5860

5961
if (status == MESH_CONNECTED) {
60-
uint8_t temp_ipv6[16];
61-
if (!arm_net_address_get(_network_interface_id, ADDR_IPV6_GP, temp_ipv6)) {
62-
_connect_status = NSAPI_STATUS_GLOBAL_UP;
63-
} else {
62+
uint8_t temp_ipv6_global[16];
63+
uint8_t temp_ipv6_local[16];
64+
if (arm_net_address_get(_network_interface_id, ADDR_IPV6_LL, temp_ipv6_local) == 0) {
6465
_connect_status = NSAPI_STATUS_LOCAL_UP;
6566
}
67+
if (arm_net_address_get(_network_interface_id, ADDR_IPV6_GP, temp_ipv6_global) == 0
68+
&& (memcmp(temp_ipv6_global, temp_ipv6_local, 16) != 0)) {
69+
_connect_status = NSAPI_STATUS_GLOBAL_UP;
70+
}
71+
} else if (status == MESH_CONNECTED_LOCAL ) {
72+
_connect_status = NSAPI_STATUS_LOCAL_UP;
73+
} else if (status == MESH_CONNECTED_GLOBAL) {
74+
_connect_status = NSAPI_STATUS_GLOBAL_UP;
75+
} else if (status == MESH_BOOTSTRAP_STARTED) {
76+
_connect_status = NSAPI_STATUS_CONNECTING;
6677
} else {
6778
_connect_status = NSAPI_STATUS_DISCONNECTED;
6879
}

features/nanostack/FEATURE_NANOSTACK/mbed-mesh-api/source/ethernet_tasklet.c

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,12 @@ typedef enum {
5858
typedef struct {
5959
void (*mesh_api_cb)(mesh_connection_status_t nwk_status);
6060
tasklet_state_t tasklet_state;
61+
mesh_connection_status_t connection_status;
62+
timeout_t *poll_network_status_timeout;
6163
int8_t node_main_tasklet_id;
6264
int8_t network_interface_id;
6365
int8_t tasklet;
66+
uint8_t ip[16];
6467
} tasklet_data_str_t;
6568

6669
/* Tasklet data */
@@ -74,7 +77,7 @@ static void enet_tasklet_main(arm_event_s *event);
7477
static void enet_tasklet_network_state_changed(mesh_connection_status_t status);
7578
static void enet_tasklet_parse_network_event(arm_event_s *event);
7679
static void enet_tasklet_configure_and_connect_to_network(void);
77-
80+
static void enet_tasklet_poll_network_status();
7881
/*
7982
* \brief A function which will be eventually called by NanoStack OS when ever the OS has an event to deliver.
8083
* @param event, describes the sender, receiver and event type.
@@ -145,18 +148,20 @@ void enet_tasklet_parse_network_event(arm_event_s *event)
145148
if (tasklet_data_ptr->tasklet_state != TASKLET_STATE_BOOTSTRAP_READY) {
146149
tr_info("IPv6 bootstrap ready");
147150
tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_READY;
148-
enet_tasklet_network_state_changed(MESH_CONNECTED);
151+
enet_tasklet_poll_network_status();
149152
}
150153
break;
151154
case ARM_NWK_IP_ADDRESS_ALLOCATION_FAIL:
152155
/* No ND Router at current Channel Stack is Already at Idle state */
153156
tr_info("Bootstrap fail");
154157
tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED;
158+
enet_tasklet_network_state_changed(MESH_DISCONNECTED);
155159
break;
156160
case ARM_NWK_NWK_CONNECTION_DOWN:
157161
/* Connection to Access point is lost wait for Scan Result */
158162
tr_info("Connection lost");
159163
tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED;
164+
enet_tasklet_network_state_changed(MESH_DISCONNECTED);
160165
break;
161166
default:
162167
tr_warn("Unknown event %d", status);
@@ -172,20 +177,47 @@ void enet_tasklet_parse_network_event(arm_event_s *event)
172177
}
173178
}
174179

180+
static void enet_tasklet_poll_network_status(void)
181+
{
182+
/* Check if we do have an IP */
183+
uint8_t temp_ipv6[16];
184+
if (arm_net_address_get(tasklet_data_ptr->network_interface_id, ADDR_IPV6_GP, temp_ipv6) == 0) {
185+
/* Check if this is link local address or not */
186+
if (memcmp(temp_ipv6, tasklet_data_ptr->ip, 16) == 0) {
187+
return;
188+
} else {
189+
memcpy(tasklet_data_ptr->ip, temp_ipv6, 16);
190+
uint8_t temp_ipv6_local[16];
191+
if (arm_net_address_get(tasklet_data_ptr->network_interface_id, ADDR_IPV6_LL, temp_ipv6_local) == 0
192+
&& (memcmp(temp_ipv6, temp_ipv6_local, 16) != 0)) {
193+
enet_tasklet_network_state_changed(MESH_CONNECTED_GLOBAL);
194+
} else {
195+
enet_tasklet_network_state_changed(MESH_CONNECTED_LOCAL);;
196+
}
197+
}
198+
} else {
199+
if (tasklet_data_ptr->connection_status != MESH_DISCONNECTED &&
200+
tasklet_data_ptr->connection_status != MESH_BOOTSTRAP_STARTED)
201+
enet_tasklet_network_state_changed(MESH_DISCONNECTED);
202+
}
203+
}
204+
175205
/*
176206
* \brief Configure and establish network connection
177207
*
178208
*/
179209
void enet_tasklet_configure_and_connect_to_network(void)
180210
{
181211
arm_nwk_interface_up(tasklet_data_ptr->network_interface_id);
212+
enet_tasklet_network_state_changed(MESH_BOOTSTRAP_STARTED);
182213
}
183214

184215
/*
185216
* Inform application about network state change
186217
*/
187218
void enet_tasklet_network_state_changed(mesh_connection_status_t status)
188219
{
220+
tasklet_data_ptr->connection_status = status;
189221
if (tasklet_data_ptr->mesh_api_cb) {
190222
(tasklet_data_ptr->mesh_api_cb)(status);
191223
}
@@ -219,6 +251,8 @@ int8_t enet_tasklet_connect(mesh_interface_cb callback, int8_t nwk_interface_id)
219251
tasklet_data_ptr->mesh_api_cb = callback;
220252
tasklet_data_ptr->network_interface_id = nwk_interface_id;
221253
tasklet_data_ptr->tasklet_state = TASKLET_STATE_INITIALIZED;
254+
tasklet_data_ptr->poll_network_status_timeout =
255+
eventOS_timeout_every_ms(enet_tasklet_poll_network_status, 2000, NULL);
222256

223257
if (re_connecting == false) {
224258
tasklet_data_ptr->tasklet = eventOS_event_handler_create(&enet_tasklet_main,
@@ -248,6 +282,7 @@ int8_t enet_tasklet_disconnect(bool send_cb)
248282
}
249283
}
250284
tasklet_data_ptr->mesh_api_cb = NULL;
285+
eventOS_timeout_cancel(tasklet_data_ptr->poll_network_status_timeout);
251286
}
252287
return status;
253288
}

features/nanostack/FEATURE_NANOSTACK/mbed-mesh-api/source/nd_tasklet.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,23 +187,28 @@ void nd_tasklet_parse_network_event(arm_event_s *event)
187187
/* Link Layer Active Scan Fail, Stack is Already at Idle state */
188188
tr_debug("Link Layer Scan Fail: No Beacons");
189189
tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED;
190+
nd_tasklet_network_state_changed(MESH_DISCONNECTED);
190191
break;
191192
case ARM_NWK_IP_ADDRESS_ALLOCATION_FAIL:
192193
/* No ND Router at current Channel Stack is Already at Idle state */
193194
tr_debug("ND Scan/ GP REG fail");
194195
tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED;
196+
nd_tasklet_network_state_changed(MESH_DISCONNECTED);
195197
break;
196198
case ARM_NWK_NWK_CONNECTION_DOWN:
197199
/* Connection to Access point is lost wait for Scan Result */
198200
tr_debug("ND/RPL scan new network");
199201
tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED;
202+
nd_tasklet_network_state_changed(MESH_DISCONNECTED);
200203
break;
201204
case ARM_NWK_NWK_PARENT_POLL_FAIL:
202205
tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED;
206+
nd_tasklet_network_state_changed(MESH_DISCONNECTED);
203207
break;
204208
case ARM_NWK_AUHTENTICATION_FAIL:
205209
tr_debug("Network authentication fail");
206210
tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED;
211+
nd_tasklet_network_state_changed(MESH_DISCONNECTED);
207212
break;
208213
default:
209214
tr_warn("Unknown event %d", status);
@@ -277,6 +282,7 @@ void nd_tasklet_configure_and_connect_to_network(void)
277282
if (status >= 0) {
278283
tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_STARTED;
279284
tr_info("Start 6LoWPAN ND Bootstrap");
285+
nd_tasklet_network_state_changed(MESH_BOOTSTRAP_STARTED);
280286
} else {
281287
tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED;
282288
tr_err("Bootstrap start failed, %d", status);

features/nanostack/FEATURE_NANOSTACK/mbed-mesh-api/source/thread_tasklet.c

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ typedef struct {
6767
void (*mesh_api_cb)(mesh_connection_status_t nwk_status);
6868
channel_list_s channel_list;
6969
tasklet_state_t tasklet_state;
70+
mesh_connection_status_t connection_status;
71+
timeout_t *poll_network_status_timeout;
7072
int8_t tasklet;
7173

7274
net_6lowpan_mode_e operating_mode;
@@ -75,7 +77,8 @@ typedef struct {
7577

7678
/** Default network ID*/
7779
uint8_t networkid[16];
78-
uint8_t extented_panid[8];
80+
uint8_t extented_panid[8];
81+
uint8_t ip[16];
7982
} thread_tasklet_data_str_t;
8083

8184

@@ -88,6 +91,7 @@ void thread_tasklet_main(arm_event_s *event);
8891
void thread_tasklet_network_state_changed(mesh_connection_status_t status);
8992
void thread_tasklet_parse_network_event(arm_event_s *event);
9093
void thread_tasklet_configure_and_connect_to_network(void);
94+
void thread_tasklet_poll_network_status();
9195
#define TRACE_THREAD_TASKLET
9296
#ifndef TRACE_THREAD_TASKLET
9397
#define thread_tasklet_trace_bootstrap_info() ((void) 0)
@@ -127,8 +131,19 @@ void thread_tasklet_main(arm_event_s *event)
127131
thread_tasklet_data_ptr->tasklet);
128132

129133
if (event->event_id == TIMER_EVENT_START_BOOTSTRAP) {
134+
int8_t status;
130135
tr_debug("Restart bootstrap");
131-
arm_nwk_interface_up(thread_tasklet_data_ptr->nwk_if_id);
136+
status = arm_nwk_interface_up(thread_tasklet_data_ptr->nwk_if_id);
137+
138+
if (status >= 0) {
139+
thread_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_STARTED;
140+
tr_info("Start Thread bootstrap (%s mode)", thread_tasklet_data_ptr->operating_mode == NET_6LOWPAN_SLEEPY_HOST ? "SED" : "Router");
141+
thread_tasklet_network_state_changed(MESH_BOOTSTRAP_STARTED);
142+
} else {
143+
thread_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED;
144+
tr_err("Bootstrap start failed, %d", status);
145+
thread_tasklet_network_state_changed(MESH_BOOTSTRAP_START_FAILED);
146+
}
132147
}
133148
break;
134149

@@ -165,30 +180,36 @@ void thread_tasklet_parse_network_event(arm_event_s *event)
165180
tr_info("Thread bootstrap ready");
166181
thread_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_READY;
167182
thread_tasklet_trace_bootstrap_info();
168-
thread_tasklet_network_state_changed(MESH_CONNECTED);
183+
/* We are connected, for Local or Global IP */
184+
thread_tasklet_poll_network_status();
169185
}
170186
break;
171187
case ARM_NWK_NWK_SCAN_FAIL:
172188
/* Link Layer Active Scan Fail, Stack is Already at Idle state */
173189
tr_debug("Link Layer Scan Fail: No Beacons");
174190
thread_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED;
191+
thread_tasklet_network_state_changed(MESH_DISCONNECTED);
175192
break;
176193
case ARM_NWK_IP_ADDRESS_ALLOCATION_FAIL:
177194
/* No ND Router at current Channel Stack is Already at Idle state */
178195
tr_debug("ND Scan/ GP REG fail");
179196
thread_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED;
197+
thread_tasklet_network_state_changed(MESH_DISCONNECTED);
180198
break;
181199
case ARM_NWK_NWK_CONNECTION_DOWN:
182200
/* Connection to Access point is lost wait for Scan Result */
183201
tr_debug("ND/RPL scan new network");
184202
thread_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED;
203+
thread_tasklet_network_state_changed(MESH_DISCONNECTED);
185204
break;
186205
case ARM_NWK_NWK_PARENT_POLL_FAIL:
187206
thread_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED;
207+
thread_tasklet_network_state_changed(MESH_DISCONNECTED);
188208
break;
189209
case ARM_NWK_AUHTENTICATION_FAIL:
190210
tr_debug("Network authentication fail");
191211
thread_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED;
212+
thread_tasklet_network_state_changed(MESH_DISCONNECTED);
192213
break;
193214
default:
194215
tr_warn("Unknown event %d", status);
@@ -204,6 +225,30 @@ void thread_tasklet_parse_network_event(arm_event_s *event)
204225
}
205226
}
206227

228+
void thread_tasklet_poll_network_status()
229+
{
230+
/* Check if we do have an IP */
231+
uint8_t temp_ipv6[16];
232+
if (arm_net_address_get(thread_tasklet_data_ptr->nwk_if_id, ADDR_IPV6_GP, temp_ipv6) == 0) {
233+
/* Check if this is the same IP than previously */
234+
if (memcmp(temp_ipv6, thread_tasklet_data_ptr->ip, 16) == 0) {
235+
return;
236+
} else {
237+
memcpy(thread_tasklet_data_ptr->ip, temp_ipv6, 16);
238+
link_configuration_s *link_cfg = thread_management_configuration_get(thread_tasklet_data_ptr->nwk_if_id);
239+
if (memcmp(thread_tasklet_data_ptr->ip, link_cfg->mesh_local_ula_prefix, 8) == 0) {
240+
thread_tasklet_network_state_changed(MESH_CONNECTED_LOCAL);
241+
} else {
242+
thread_tasklet_network_state_changed(MESH_CONNECTED_GLOBAL);
243+
}
244+
}
245+
} else {
246+
if (thread_tasklet_data_ptr->connection_status != MESH_DISCONNECTED &&
247+
thread_tasklet_data_ptr->connection_status != MESH_BOOTSTRAP_STARTED)
248+
thread_tasklet_network_state_changed(MESH_DISCONNECTED);
249+
}
250+
}
251+
207252
void read_link_configuration() {
208253

209254
thread_tasklet_data_ptr->link_config.panId = MBED_CONF_MBED_MESH_API_THREAD_CONFIG_PANID;
@@ -298,6 +343,7 @@ void thread_tasklet_configure_and_connect_to_network(void)
298343
if (status >= 0) {
299344
thread_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_STARTED;
300345
tr_info("Start Thread bootstrap (%s mode)", thread_tasklet_data_ptr->operating_mode == NET_6LOWPAN_SLEEPY_HOST ? "SED" : "Router");
346+
thread_tasklet_network_state_changed(MESH_BOOTSTRAP_STARTED);
301347
} else {
302348
thread_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED;
303349
tr_err("Bootstrap start failed, %d", status);
@@ -310,6 +356,7 @@ void thread_tasklet_configure_and_connect_to_network(void)
310356
*/
311357
void thread_tasklet_network_state_changed(mesh_connection_status_t status)
312358
{
359+
thread_tasklet_data_ptr->connection_status = status;
313360
if (thread_tasklet_data_ptr->mesh_api_cb) {
314361
(thread_tasklet_data_ptr->mesh_api_cb)(status);
315362
}
@@ -374,6 +421,8 @@ int8_t thread_tasklet_connect(mesh_interface_cb callback, int8_t nwk_interface_i
374421
thread_tasklet_data_ptr->mesh_api_cb = callback;
375422
thread_tasklet_data_ptr->nwk_if_id = nwk_interface_id;
376423
thread_tasklet_data_ptr->tasklet_state = TASKLET_STATE_INITIALIZED;
424+
thread_tasklet_data_ptr->poll_network_status_timeout =
425+
eventOS_timeout_every_ms(thread_tasklet_poll_network_status, 2000, NULL);
377426

378427
if (re_connecting == false) {
379428
thread_tasklet_data_ptr->tasklet = eventOS_event_handler_create(&thread_tasklet_main,
@@ -383,6 +432,7 @@ int8_t thread_tasklet_connect(mesh_interface_cb callback, int8_t nwk_interface_i
383432
// -2 memory allocation failure
384433
return thread_tasklet_data_ptr->tasklet;
385434
}
435+
386436
ns_event_loop_thread_start();
387437
} else {
388438
thread_tasklet_data_ptr->tasklet = tasklet;
@@ -407,6 +457,8 @@ int8_t thread_tasklet_disconnect(bool send_cb)
407457

408458
// Clear callback, it will be set again in next connect
409459
thread_tasklet_data_ptr->mesh_api_cb = NULL;
460+
// Cancel the callback timeout
461+
eventOS_timeout_cancel(thread_tasklet_data_ptr->poll_network_status_timeout);
410462
}
411463
return status;
412464
}
@@ -469,4 +521,3 @@ int8_t thread_tasklet_data_poll_rate_set(uint32_t timeout)
469521

470522
return status;
471523
}
472-

0 commit comments

Comments
 (0)