1212#include <modem/modem_info.h>
1313#include <zephyr/sys/reboot.h>
1414#include <zephyr/logging/log.h>
15+ #include <zephyr/logging/log_ctrl.h>
1516#include <app_event_manager.h>
1617#include <caf/events/button_event.h>
1718#define MODULE main
1819#include <caf/events/module_state_event.h>
1920#include <net/nrf_cloud.h>
2021#include <net/nrf_cloud_rest.h>
22+ #include <zephyr/net/conn_mgr_connectivity.h>
2123
2224LOG_MODULE_REGISTER (nrf_cloud_rest_cell_location_sample ,
2325 CONFIG_NRF_CLOUD_REST_CELL_LOCATION_SAMPLE_LOG_LEVEL );
@@ -42,18 +44,25 @@ LOG_MODULE_REGISTER(nrf_cloud_rest_cell_location_sample,
4244#define MFWV_MIN_EXT_SRCH_GCI 3
4345#define MFWV_REV_EXT_SRCH_GCI 4
4446
45- /* Semaphore to indicate a button has been pressed */
46- static K_SEM_DEFINE (button_press_sem , 0 , 1 ) ;
47+ /* Network states */
48+ #define NETWORK_UP BIT(0)
49+ #define CONN_LAYER_EVENT_MASK (NET_EVENT_L4_CONNECTED | NET_EVENT_L4_DISCONNECTED)
4750
48- /* Semaphore to indicate that a network connection has been established */
49- static K_SEM_DEFINE (lte_connected_sem , 0 , 1 ) ;
51+ /* Macro called upon a fatal error, reboots the device. */
52+ #define FATAL_ERROR () \
53+ LOG_ERR("Fatal error! Rebooting the device."); \
54+ LOG_PANIC(); \
55+ IF_ENABLED(CONFIG_REBOOT, (sys_reboot(0)))
5056
5157/* Semaphore to indicate that cell info has been received */
5258static K_SEM_DEFINE (cell_info_ready_sem , 0 , 1 ) ;
5359
5460/* Mutex for cell info struct */
5561static K_MUTEX_DEFINE (cell_info_mutex );
5662
63+ /* Connection event */
64+ static K_EVENT_DEFINE (connection_events );
65+
5766/* nRF Cloud device ID */
5867static char device_id [NRF_CLOUD_CLIENT_ID_MAX_LEN + 1 ];
5968
@@ -285,8 +294,6 @@ static bool app_event_handler(const struct app_event_header *aeh)
285294
286295 process_cell_pos_type_change ();
287296
288- k_sem_give (& button_press_sem );
289-
290297 return true;
291298}
292299
@@ -347,59 +354,6 @@ static void send_device_status(void)
347354 rest_ctx .keep_alive = false;
348355}
349356
350- int init (void )
351- {
352- int err ;
353-
354- /* Application event manager is used for button press events from the
355- * common application framework (CAF) library
356- */
357- err = app_event_manager_init ();
358- if (err ) {
359- LOG_ERR ("Application Event Manager could not be initialized" );
360- return err ;
361- }
362-
363- err = nrf_modem_lib_init ();
364- if (err ) {
365- LOG_ERR ("Modem library initialization failed, error: %d" , err );
366- return err ;
367- }
368-
369- /* Modem info library is used to obtain the modem FW version
370- * and network info for single-cell requests
371- */
372- err = modem_info_init ();
373- if (err ) {
374- LOG_ERR ("Modem info initialization failed, error: %d" , err );
375- return err ;
376- }
377-
378- err = modem_info_params_init (& mdm_param );
379- if (err ) {
380- LOG_ERR ("Modem info params initialization failed, error: %d" , err );
381- return err ;
382- }
383-
384- /* Print the nRF Cloud device ID. This device ID should match the ID used
385- * to provision the device on nRF Cloud or to register a public JWT signing key.
386- */
387- err = nrf_cloud_client_id_get (device_id , sizeof (device_id ));
388- if (err ) {
389- LOG_ERR ("Failed to get device ID, error: %d" , err );
390- return err ;
391- }
392- LOG_INF ("Device ID: %s" , device_id );
393-
394- /* Check modem FW version */
395- check_modem_fw_version ();
396-
397- /* Inform the app event manager that this module is ready to receive events */
398- module_set_state (MODULE_STATE_READY );
399-
400- return 0 ;
401- }
402-
403357static void lte_handler (const struct lte_lc_evt * const evt )
404358{
405359 switch (evt -> type ) {
@@ -416,8 +370,6 @@ static void lte_handler(const struct lte_lc_evt *const evt)
416370 LOG_DBG ("Network registration status: %s" ,
417371 evt -> nw_reg_status == LTE_LC_NW_REG_REGISTERED_HOME ?
418372 "Connected - home network" : "Connected - roaming" );
419-
420- k_sem_give (& lte_connected_sem );
421373 break ;
422374 case LTE_LC_EVT_CELL_UPDATE :
423375 if (!ready || (evt -> cell .id == LTE_LC_CELL_EUTRAN_ID_INVALID )) {
@@ -486,39 +438,6 @@ static void lte_handler(const struct lte_lc_evt *const evt)
486438 }
487439}
488440
489- static void connect_to_network (void )
490- {
491- int err ;
492-
493- LOG_INF ("Waiting for network..." );
494-
495- k_sem_reset (& lte_connected_sem );
496-
497- err = lte_lc_connect_async (lte_handler );
498- if (err ) {
499- LOG_ERR ("Failed to init LTE module, unable to continue, error: %d" , err );
500- k_sleep (K_FOREVER );
501- }
502-
503- err = k_sem_take (& lte_connected_sem , K_MINUTES (NET_CONN_WAIT_MIN ));
504- if (err == 0 ) {
505- LOG_INF ("Connected to network" );
506- } else if (err == - EAGAIN ) {
507- LOG_ERR ("Failed to connect to network, rebooting in 30s..." );
508- (void )lte_lc_power_off ();
509- k_sleep (K_SECONDS (30 ));
510- sys_reboot (SYS_REBOOT_COLD );
511- } else {
512- LOG_ERR ("k_sem_take error %d, unable to continue" , err );
513- k_sleep (K_FOREVER );
514- }
515-
516- /* Modem must have valid time/date in order to generate JWTs with
517- * an expiration time
518- */
519- modem_time_wait ();
520- }
521-
522441static bool cred_check (struct nrf_cloud_credentials_status * const cs )
523442{
524443 int ret = 0 ;
@@ -560,6 +479,121 @@ static void await_credentials(void)
560479 LOG_INF ("nRF Cloud credentials detected!" );
561480}
562481
482+ int init (void )
483+ {
484+ int err = 0 ;
485+
486+ /* Application event manager is used for button press events from the
487+ * common application framework (CAF) library
488+ */
489+ err = app_event_manager_init ();
490+ if (err ) {
491+ LOG_ERR ("Application Event Manager could not be initialized" );
492+ return err ;
493+ }
494+
495+ err = nrf_modem_lib_init ();
496+ if (err ) {
497+ LOG_ERR ("Modem library initialization failed, error: %d" , err );
498+ return err ;
499+ }
500+
501+ /* Modem info library is used to obtain the modem FW version
502+ * and network info for single-cell requests
503+ */
504+ err = modem_info_init ();
505+ if (err ) {
506+ LOG_ERR ("Modem info initialization failed, error: %d" , err );
507+ return err ;
508+ }
509+
510+ err = modem_info_params_init (& mdm_param );
511+ if (err ) {
512+ LOG_ERR ("Modem info params initialization failed, error: %d" , err );
513+ return err ;
514+ }
515+
516+ /* Print the nRF Cloud device ID. This device ID should match the ID used
517+ * to provision the device on nRF Cloud or to register a public JWT signing key.
518+ */
519+ err = nrf_cloud_client_id_get (device_id , sizeof (device_id ));
520+ if (err ) {
521+ LOG_ERR ("Failed to get device ID, error: %d" , err );
522+ return err ;
523+ }
524+ LOG_INF ("Device ID: %s" , device_id );
525+
526+ /* Check modem FW version */
527+ check_modem_fw_version ();
528+
529+ /* Inform the app event manager that this module is ready to receive events */
530+ module_set_state (MODULE_STATE_READY );
531+
532+ /* Before connecting, ensure nRF Cloud credentials are installed */
533+ await_credentials ();
534+
535+ /* Initiate Connection */
536+ LOG_INF ("Enabling connectivity..." );
537+ lte_lc_register_handler (lte_handler );
538+ conn_mgr_all_if_connect (true);
539+ k_event_wait (& connection_events , NETWORK_UP , false, K_FOREVER );
540+
541+ /* Modem must have valid time/date in order to generate JWTs with
542+ * an expiration time
543+ */
544+ modem_time_wait ();
545+
546+ return err ;
547+ }
548+
549+ /* Callback to track network connectivity */
550+ static struct net_mgmt_event_callback l4_callback ;
551+ static void l4_event_handler (struct net_mgmt_event_callback * cb , uint32_t event ,
552+ struct net_if * iface )
553+ {
554+ if ((event & CONN_LAYER_EVENT_MASK ) != event ) {
555+ return ;
556+ }
557+
558+ if (event == NET_EVENT_L4_CONNECTED ) {
559+ /* Mark network as up. */
560+ LOG_INF ("Connected to network" );
561+ k_event_post (& connection_events , NETWORK_UP );
562+ }
563+
564+ if (event == NET_EVENT_L4_DISCONNECTED ) {
565+ /* Mark network as down. */
566+ LOG_INF ("Network connectivity lost!" );
567+ }
568+ }
569+
570+ /* Callback to track connectivity layer events */
571+ static struct net_mgmt_event_callback conn_cb ;
572+ static void connectivity_event_handler (struct net_mgmt_event_callback * cb ,
573+ uint32_t event ,
574+ struct net_if * iface )
575+ {
576+ if (event == NET_EVENT_CONN_IF_FATAL_ERROR ) {
577+ LOG_ERR ("NET_EVENT_CONN_IF_FATAL_ERROR" );
578+ FATAL_ERROR ();
579+ return ;
580+ }
581+ }
582+
583+ /* Start tracking network availability */
584+ static int prepare_network_tracking (void )
585+ {
586+ net_mgmt_init_event_callback (& l4_callback , l4_event_handler , CONN_LAYER_EVENT_MASK );
587+ net_mgmt_add_event_callback (& l4_callback );
588+
589+ net_mgmt_init_event_callback (& conn_cb , connectivity_event_handler , CONN_LAYER_EVENT_MASK );
590+ net_mgmt_add_event_callback (& conn_cb );
591+
592+ return 0 ;
593+ }
594+
595+ SYS_INIT (prepare_network_tracking , APPLICATION , 0 );
596+
563597int main (void )
564598{
565599 int err ;
@@ -573,11 +607,6 @@ int main(void)
573607 return 0 ;
574608 }
575609
576- /* Before connecting, ensure nRF Cloud credentials are installed */
577- await_credentials ();
578-
579- connect_to_network ();
580-
581610 /* Send the device status which contains HW/FW version info and
582611 * details about the network connection.
583612 */
0 commit comments