@@ -46,11 +46,10 @@ enum library_event {
46
46
EVENT_LTE_DEREGISTERED ,
47
47
EVENT_PDN_ACTIVATED ,
48
48
EVENT_PDN_DEACTIVATED ,
49
- EVENT_NETWORK_CONNECTED ,
50
- EVENT_NETWORK_DISCONNECTED ,
51
49
EVENT_BACKOFF_TIMER_EXPIRED ,
52
50
EVENT_COREDUMP_SEND_FAIL ,
53
51
EVENT_COREDUMP_SEND_SUCCESS ,
52
+ EVENT_COREDUMP_SEND_RETRY_COUNT_EXCEEDED ,
54
53
EVENT_ERROR
55
54
};
56
55
@@ -71,6 +70,8 @@ struct fsm_state_object {
71
70
72
71
bool lte_registered ;
73
72
bool pdn_active ;
73
+
74
+ bool heartbeat_triggered ;
74
75
};
75
76
76
77
/* Forward declarations: Local functions */
@@ -206,11 +207,18 @@ static void pdn_event_handler(uint8_t cid, enum pdn_event event, int reason)
206
207
{
207
208
switch (event ) {
208
209
case PDN_EVENT_ACTIVATED :
209
- event_send (EVENT_PDN_ACTIVATED );
210
+ if (cid == 0 ) {
211
+ event_send (EVENT_PDN_ACTIVATED );
212
+ }
213
+
210
214
break ;
211
- case PDN_EVENT_NETWORK_DETACH :
212
- __fallthrough ;
213
215
case PDN_EVENT_DEACTIVATED :
216
+ if (cid == 0 ) {
217
+ event_send (EVENT_PDN_DEACTIVATED );
218
+ }
219
+
220
+ break ;
221
+ case PDN_EVENT_NETWORK_DETACH :
214
222
event_send (EVENT_PDN_DEACTIVATED );
215
223
break ;
216
224
default :
@@ -219,17 +227,54 @@ static void pdn_event_handler(uint8_t cid, enum pdn_event event, int reason)
219
227
}
220
228
}
221
229
230
+ static void init_state_variables (struct fsm_state_object * state_object )
231
+ {
232
+ state_object -> lte_registered = false;
233
+ state_object -> pdn_active = false;
234
+ state_object -> retry_count = 0 ;
235
+ state_object -> heartbeat_triggered = false;
236
+ }
237
+
238
+ /* Update registration and PDN state. Returns true if the state changed. */
239
+ static bool update_connectivity (struct fsm_state_object * state_object ,
240
+ enum library_event event )
241
+ {
242
+ switch (event ) {
243
+ case EVENT_LTE_REGISTERED :
244
+ state_object -> lte_registered = true;
245
+
246
+ return true;
247
+ case EVENT_LTE_DEREGISTERED :
248
+ state_object -> lte_registered = false;
249
+
250
+ return true;
251
+ case EVENT_PDN_ACTIVATED :
252
+ state_object -> pdn_active = true;
253
+
254
+ return true;
255
+ case EVENT_PDN_DEACTIVATED :
256
+ state_object -> pdn_active = false;
257
+
258
+ return true;
259
+ default :
260
+ return false;
261
+ }
262
+ }
263
+
264
+ /* Returns true if the modem is registered and a PDN bearer is active. */
265
+ static bool is_registered_and_pdn_active (struct fsm_state_object * state_object ,
266
+ enum library_event event )
267
+ {
268
+ return state_object -> lte_registered && state_object -> pdn_active ;
269
+ }
270
+
222
271
/* SMF State Handlers */
223
272
224
273
static void state_waiting_for_nrf_modem_lib_init_entry (void * o )
225
274
{
226
275
ARG_UNUSED (o );
227
276
228
277
LOG_DBG ("state_waiting_for_nrf_modem_lib_init_entry" );
229
-
230
- state_object -> lte_registered = false;
231
- state_object -> pdn_active = false;
232
- state_object -> retry_count = 0 ;
233
278
}
234
279
235
280
static enum smf_state_result state_waiting_for_nrf_modem_lib_init_run (void * o )
@@ -238,9 +283,17 @@ static enum smf_state_result state_waiting_for_nrf_modem_lib_init_run(void *o)
238
283
239
284
LOG_DBG ("state_waiting_for_nrf_modem_lib_init_run" );
240
285
241
- if (state_object -> event == EVENT_NRF_MODEM_LIB_INITED ) {
286
+ switch (state_object -> event ) {
287
+ case EVENT_NRF_MODEM_LIB_INITED :
242
288
smf_set_state (SMF_CTX (state_object ), & states [STATE_RUNNING ]);
289
+
290
+ return SMF_EVENT_HANDLED ;
291
+
292
+ case EVENT_NRF_MODEM_LIB_SHUTDOWN :
243
293
return SMF_EVENT_HANDLED ;
294
+
295
+ default :
296
+ break ;
244
297
}
245
298
246
299
return SMF_EVENT_PROPAGATE ;
@@ -254,6 +307,8 @@ static void state_running_entry(void *o)
254
307
255
308
LOG_DBG ("state_running_entry" );
256
309
310
+ init_state_variables (state_object );
311
+
257
312
/* Subscribe to +CEREG notifications, level 5 */
258
313
err = nrf_modem_at_printf ("AT+CEREG=5" );
259
314
if (err ) {
@@ -278,12 +333,27 @@ static enum smf_state_result state_running_run(void *o)
278
333
279
334
LOG_DBG ("state_running_run" );
280
335
281
- if (state_object -> event == EVENT_NRF_MODEM_LIB_SHUTDOWN ) {
336
+ switch (state_object -> event ) {
337
+ case EVENT_NRF_MODEM_LIB_SHUTDOWN :
282
338
smf_set_state (SMF_CTX (state_object ), & states [STATE_WAITING_FOR_NRF_MODEM_LIB_INIT ]);
339
+
283
340
return SMF_EVENT_HANDLED ;
284
- } else if (state_object -> event == EVENT_ERROR ) {
341
+
342
+ case EVENT_ERROR :
285
343
smf_set_state (SMF_CTX (state_object ), & states [STATE_ERROR ]);
344
+
345
+ return SMF_EVENT_HANDLED ;
346
+
347
+ case EVENT_COREDUMP_SEND_RETRY_COUNT_EXCEEDED :
348
+ __fallthrough ;
349
+
350
+ case EVENT_COREDUMP_SEND_SUCCESS :
351
+ smf_set_state (SMF_CTX (state_object ), & states [STATE_FINISHED ]);
352
+
286
353
return SMF_EVENT_HANDLED ;
354
+
355
+ default :
356
+ break ;
287
357
}
288
358
289
359
return SMF_EVENT_PROPAGATE ;
@@ -320,26 +390,10 @@ static enum smf_state_result state_waiting_for_network_connection_run(void *o)
320
390
321
391
LOG_DBG ("state_waiting_for_network_connection_run" );
322
392
323
- switch (state_object -> event ) {
324
- case EVENT_LTE_REGISTERED :
325
- state_object -> lte_registered = true;
326
- break ;
327
- case EVENT_LTE_DEREGISTERED :
328
- state_object -> lte_registered = false;
329
- break ;
330
- case EVENT_PDN_ACTIVATED :
331
- state_object -> pdn_active = true;
332
- break ;
333
- case EVENT_PDN_DEACTIVATED :
334
- state_object -> pdn_active = false;
335
- break ;
336
- default :
337
- /* Don't care */
338
- break ;
339
- }
340
-
341
- if (state_object -> lte_registered && state_object -> pdn_active ) {
393
+ if (update_connectivity (state_object , state_object -> event ) &&
394
+ is_registered_and_pdn_active (state_object , state_object -> event )) {
342
395
smf_set_state (SMF_CTX (state_object ), & states [STATE_NETWORK_CONNECTED ]);
396
+
343
397
return SMF_EVENT_HANDLED ;
344
398
}
345
399
@@ -351,8 +405,6 @@ static void state_network_connected_entry(void *o)
351
405
ARG_UNUSED (o );
352
406
353
407
LOG_DBG ("state_network_connected_entry" );
354
-
355
- state_object -> retry_count = 0 ;
356
408
}
357
409
358
410
static enum smf_state_result state_network_connected_run (void * o )
@@ -361,15 +413,10 @@ static enum smf_state_result state_network_connected_run(void *o)
361
413
362
414
LOG_DBG ("state_network_connected_run" );
363
415
364
- if (state_object -> event == EVENT_LTE_DEREGISTERED ) {
365
- state_object -> lte_registered = false;
366
-
416
+ if (update_connectivity (state_object , state_object -> event ) &&
417
+ !is_registered_and_pdn_active (state_object , state_object -> event )) {
367
418
smf_set_state (SMF_CTX (state_object ), & states [STATE_WAITING_FOR_NETWORK_CONNECTION ]);
368
- return SMF_EVENT_HANDLED ;
369
- } else if (state_object -> event == EVENT_PDN_DEACTIVATED ) {
370
- state_object -> pdn_active = false;
371
419
372
- smf_set_state (SMF_CTX (state_object ), & states [STATE_WAITING_FOR_NETWORK_CONNECTION ]);
373
420
return SMF_EVENT_HANDLED ;
374
421
}
375
422
@@ -383,10 +430,13 @@ static void state_coredump_send_attempt_entry(void *o)
383
430
struct fsm_state_object * state_object = o ;
384
431
385
432
LOG_DBG ("state_coredump_send_attempt_entry" );
386
- LOG_DBG ("Triggering heartbeat" );
387
- LOG_DBG ("Attempting to send coredump" );
388
433
389
- memfault_metrics_heartbeat_debug_trigger ();
434
+ if (!state_object -> heartbeat_triggered ) {
435
+ LOG_DBG ("Triggering heartbeat" );
436
+ memfault_metrics_heartbeat_debug_trigger ();
437
+
438
+ state_object -> heartbeat_triggered = true;
439
+ }
390
440
391
441
if (IS_ENABLED (CONFIG_MEMFAULT_NCS_POST_MODEM_TRACE_ON_COREDUMP )) {
392
442
err = memfault_lte_coredump_modem_trace_init ();
@@ -403,6 +453,8 @@ static void state_coredump_send_attempt_entry(void *o)
403
453
}
404
454
}
405
455
456
+ LOG_DBG ("Attempting to send coredump" );
457
+
406
458
err = memfault_zephyr_port_post_data ();
407
459
if (err ) {
408
460
LOG_DBG ("Failed to post data to Memfault" );
@@ -421,9 +473,7 @@ static enum smf_state_result state_coredump_send_attempt_run(void *o)
421
473
422
474
if (state_object -> event == EVENT_COREDUMP_SEND_FAIL ) {
423
475
smf_set_state (SMF_CTX (state_object ), & states [STATE_COREDUMP_SEND_BACKOFF ]);
424
- return SMF_EVENT_HANDLED ;
425
- } else if (state_object -> event == EVENT_COREDUMP_SEND_SUCCESS ) {
426
- smf_set_state (SMF_CTX (state_object ), & states [STATE_FINISHED ]);
476
+
427
477
return SMF_EVENT_HANDLED ;
428
478
}
429
479
@@ -489,7 +539,10 @@ static void schedule_send_backoff(struct fsm_state_object *state_object)
489
539
state_object -> retry_count ++ ;
490
540
491
541
if (state_object -> retry_count >= CONFIG_MEMFAULT_NCS_POST_COREDUMP_RETRIES_MAX ) {
492
- event_send (STATE_FINISHED );
542
+ event_send (EVENT_COREDUMP_SEND_RETRY_COUNT_EXCEEDED );
543
+
544
+ LOG_DBG ("Retry count exceeded" );
545
+
493
546
return ;
494
547
}
495
548
0 commit comments