@@ -67,6 +67,8 @@ typedef struct {
67
67
void (* mesh_api_cb )(mesh_connection_status_t nwk_status );
68
68
channel_list_s channel_list ;
69
69
tasklet_state_t tasklet_state ;
70
+ mesh_connection_status_t connection_status ;
71
+ timeout_t * poll_network_status_timeout ;
70
72
int8_t tasklet ;
71
73
72
74
net_6lowpan_mode_e operating_mode ;
@@ -75,7 +77,8 @@ typedef struct {
75
77
76
78
/** Default network ID*/
77
79
uint8_t networkid [16 ];
78
- uint8_t extented_panid [8 ];
80
+ uint8_t extented_panid [8 ];
81
+ uint8_t ip [16 ];
79
82
} thread_tasklet_data_str_t ;
80
83
81
84
@@ -88,6 +91,7 @@ void thread_tasklet_main(arm_event_s *event);
88
91
void thread_tasklet_network_state_changed (mesh_connection_status_t status );
89
92
void thread_tasklet_parse_network_event (arm_event_s * event );
90
93
void thread_tasklet_configure_and_connect_to_network (void );
94
+ void thread_tasklet_poll_network_status ();
91
95
#define TRACE_THREAD_TASKLET
92
96
#ifndef TRACE_THREAD_TASKLET
93
97
#define thread_tasklet_trace_bootstrap_info () ((void) 0)
@@ -127,8 +131,19 @@ void thread_tasklet_main(arm_event_s *event)
127
131
thread_tasklet_data_ptr -> tasklet );
128
132
129
133
if (event -> event_id == TIMER_EVENT_START_BOOTSTRAP ) {
134
+ int8_t status ;
130
135
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
+ }
132
147
}
133
148
break ;
134
149
@@ -165,30 +180,36 @@ void thread_tasklet_parse_network_event(arm_event_s *event)
165
180
tr_info ("Thread bootstrap ready" );
166
181
thread_tasklet_data_ptr -> tasklet_state = TASKLET_STATE_BOOTSTRAP_READY ;
167
182
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 ();
169
185
}
170
186
break ;
171
187
case ARM_NWK_NWK_SCAN_FAIL :
172
188
/* Link Layer Active Scan Fail, Stack is Already at Idle state */
173
189
tr_debug ("Link Layer Scan Fail: No Beacons" );
174
190
thread_tasklet_data_ptr -> tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED ;
191
+ thread_tasklet_network_state_changed (MESH_DISCONNECTED );
175
192
break ;
176
193
case ARM_NWK_IP_ADDRESS_ALLOCATION_FAIL :
177
194
/* No ND Router at current Channel Stack is Already at Idle state */
178
195
tr_debug ("ND Scan/ GP REG fail" );
179
196
thread_tasklet_data_ptr -> tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED ;
197
+ thread_tasklet_network_state_changed (MESH_DISCONNECTED );
180
198
break ;
181
199
case ARM_NWK_NWK_CONNECTION_DOWN :
182
200
/* Connection to Access point is lost wait for Scan Result */
183
201
tr_debug ("ND/RPL scan new network" );
184
202
thread_tasklet_data_ptr -> tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED ;
203
+ thread_tasklet_network_state_changed (MESH_DISCONNECTED );
185
204
break ;
186
205
case ARM_NWK_NWK_PARENT_POLL_FAIL :
187
206
thread_tasklet_data_ptr -> tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED ;
207
+ thread_tasklet_network_state_changed (MESH_DISCONNECTED );
188
208
break ;
189
209
case ARM_NWK_AUHTENTICATION_FAIL :
190
210
tr_debug ("Network authentication fail" );
191
211
thread_tasklet_data_ptr -> tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED ;
212
+ thread_tasklet_network_state_changed (MESH_DISCONNECTED );
192
213
break ;
193
214
default :
194
215
tr_warn ("Unknown event %d" , status );
@@ -204,6 +225,30 @@ void thread_tasklet_parse_network_event(arm_event_s *event)
204
225
}
205
226
}
206
227
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
+
207
252
void read_link_configuration () {
208
253
209
254
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)
298
343
if (status >= 0 ) {
299
344
thread_tasklet_data_ptr -> tasklet_state = TASKLET_STATE_BOOTSTRAP_STARTED ;
300
345
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 );
301
347
} else {
302
348
thread_tasklet_data_ptr -> tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED ;
303
349
tr_err ("Bootstrap start failed, %d" , status );
@@ -310,6 +356,7 @@ void thread_tasklet_configure_and_connect_to_network(void)
310
356
*/
311
357
void thread_tasklet_network_state_changed (mesh_connection_status_t status )
312
358
{
359
+ thread_tasklet_data_ptr -> connection_status = status ;
313
360
if (thread_tasklet_data_ptr -> mesh_api_cb ) {
314
361
(thread_tasklet_data_ptr -> mesh_api_cb )(status );
315
362
}
@@ -374,6 +421,8 @@ int8_t thread_tasklet_connect(mesh_interface_cb callback, int8_t nwk_interface_i
374
421
thread_tasklet_data_ptr -> mesh_api_cb = callback ;
375
422
thread_tasklet_data_ptr -> nwk_if_id = nwk_interface_id ;
376
423
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 );
377
426
378
427
if (re_connecting == false) {
379
428
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
383
432
// -2 memory allocation failure
384
433
return thread_tasklet_data_ptr -> tasklet ;
385
434
}
435
+
386
436
ns_event_loop_thread_start ();
387
437
} else {
388
438
thread_tasklet_data_ptr -> tasklet = tasklet ;
@@ -407,6 +457,8 @@ int8_t thread_tasklet_disconnect(bool send_cb)
407
457
408
458
// Clear callback, it will be set again in next connect
409
459
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 );
410
462
}
411
463
return status ;
412
464
}
@@ -469,4 +521,3 @@ int8_t thread_tasklet_data_poll_rate_set(uint32_t timeout)
469
521
470
522
return status ;
471
523
}
472
-
0 commit comments