99#include <zephyr/task_wdt/task_wdt.h>
1010#include <zephyr/zbus/zbus.h>
1111#include <zephyr/init.h>
12+ #include <zephyr/smf.h>
1213#include <modem/location.h>
1314#include <nrf_modem_gnss.h>
1415#include <date_time.h>
@@ -48,7 +49,44 @@ ZBUS_CHAN_ADD_OBS(NETWORK_CHAN, location, 0);
4849 (MAX(sizeof(struct cloud_msg), \
4950 sizeof(struct network_msg)))))
5051
51- static bool gnss_initialized ;
52+ /* State machine definitions */
53+ static const struct smf_state states [];
54+
55+ /* Forward declarations */
56+ static void state_running_entry (void * o );
57+ static void state_running_run (void * o );
58+
59+ /* Single state for the location module */
60+ enum location_module_state {
61+ STATE_RUNNING ,
62+ };
63+
64+ /* Construct state table */
65+ static const struct smf_state states [] = {
66+ [STATE_RUNNING ] =
67+ SMF_CREATE_STATE (state_running_entry ,
68+ state_running_run ,
69+ NULL ,
70+ NULL ,
71+ NULL ),
72+ };
73+
74+ /* Location module state object.
75+ * Used to transfer data between state changes.
76+ */
77+ struct location_state {
78+ /* This must be first */
79+ struct smf_ctx ctx ;
80+
81+ /* Last channel type that a message was received on */
82+ const struct zbus_channel * chan ;
83+
84+ /* Last received message */
85+ uint8_t msg_buf [MAX_MSG_SIZE ];
86+
87+ /* GNSS initialization status */
88+ bool gnss_initialized ;
89+ };
5290
5391static void location_event_handler (const struct location_event_data * event_data );
5492
@@ -90,9 +128,9 @@ void trigger_location_update(void)
90128 }
91129}
92130
93- void handle_network_chan (struct network_msg msg )
131+ void handle_network_chan (struct network_msg msg , struct location_state * state )
94132{
95- if (gnss_initialized ) {
133+ if (state -> gnss_initialized ) {
96134 return ;
97135 }
98136
@@ -105,7 +143,7 @@ void handle_network_chan(struct network_msg msg)
105143 LOG_ERR ("Unable to init GNSS: %d" , err );
106144 SEND_FATAL_ERROR ();
107145 } else {
108- gnss_initialized = true;
146+ state -> gnss_initialized = true;
109147 LOG_DBG ("GNSS initialized" );
110148 }
111149 }
@@ -119,6 +157,38 @@ void handle_location_chan(enum location_msg_type location_msg_type)
119157 }
120158}
121159
160+ /* State machine handlers */
161+ static void state_running_entry (void * o )
162+ {
163+ int err ;
164+ struct location_state * state = (struct location_state * )o ;
165+
166+ LOG_DBG ("%s" , __func__ );
167+
168+ err = location_init (location_event_handler );
169+ if (err ) {
170+ LOG_ERR ("Unable to init location library: %d" , err );
171+ SEND_FATAL_ERROR ();
172+ return ;
173+ }
174+
175+ LOG_DBG ("Location library initialized" );
176+ state -> gnss_initialized = false;
177+ }
178+
179+ static void state_running_run (void * o )
180+ {
181+ struct location_state * state = (struct location_state * )o ;
182+
183+ if (state -> chan == & NETWORK_CHAN ) {
184+ handle_network_chan (MSG_TO_NETWORK_MSG (state -> msg_buf ), state );
185+ }
186+
187+ if (state -> chan == & LOCATION_CHAN ) {
188+ handle_location_chan (MSG_TO_LOCATION_TYPE (state -> msg_buf ));
189+ }
190+ }
191+
122192static void location_print_data_details (enum location_method method ,
123193 const struct location_data_details * details )
124194{
@@ -222,14 +292,13 @@ static void location_event_handler(const struct location_event_data *event_data)
222292static void location_module_thread (void )
223293{
224294 int err ;
225- const struct zbus_channel * chan ;
226295 int task_wdt_id ;
227296 const uint32_t wdt_timeout_ms =
228297 (CONFIG_APP_LOCATION_WATCHDOG_TIMEOUT_SECONDS * MSEC_PER_SEC );
229298 const uint32_t execution_time_ms =
230299 (CONFIG_APP_LOCATION_MSG_PROCESSING_TIMEOUT_SECONDS * MSEC_PER_SEC );
231300 const k_timeout_t zbus_wait_ms = K_MSEC (wdt_timeout_ms - execution_time_ms );
232- uint8_t msg_buf [ MAX_MSG_SIZE ] ;
301+ struct location_state location_state = { 0 } ;
233302
234303 LOG_DBG ("Location module task started" );
235304
@@ -240,14 +309,8 @@ static void location_module_thread(void)
240309 return ;
241310 }
242311
243- err = location_init (location_event_handler );
244- if (err ) {
245- LOG_ERR ("Unable to init location library: %d" , err );
246- SEND_FATAL_ERROR ();
247- return ;
248- }
249-
250- LOG_DBG ("location library initialized" );
312+ /* Initialize the state machine */
313+ smf_set_initial (SMF_CTX (& location_state ), & states [STATE_RUNNING ]);
251314
252315 while (true) {
253316 err = task_wdt_feed (task_wdt_id );
@@ -257,7 +320,8 @@ static void location_module_thread(void)
257320 return ;
258321 }
259322
260- err = zbus_sub_wait_msg (& location , & chan , & msg_buf , zbus_wait_ms );
323+ err = zbus_sub_wait_msg (& location , & location_state .chan ,
324+ location_state .msg_buf , zbus_wait_ms );
261325 if (err == - ENOMSG ) {
262326 continue ;
263327 } else if (err ) {
@@ -266,12 +330,11 @@ static void location_module_thread(void)
266330 return ;
267331 }
268332
269- if (& NETWORK_CHAN == chan ) {
270- handle_network_chan (MSG_TO_NETWORK_MSG (& msg_buf ));
271- }
272-
273- if (& LOCATION_CHAN == chan ) {
274- handle_location_chan (MSG_TO_LOCATION_TYPE (& msg_buf ));
333+ err = smf_run_state (SMF_CTX (& location_state ));
334+ if (err ) {
335+ LOG_ERR ("smf_run_state(), error: %d" , err );
336+ SEND_FATAL_ERROR ();
337+ return ;
275338 }
276339 }
277340}
0 commit comments