66#include " cbor.h"
77#include " pubsub.h"
88#include " spotter.h"
9+ #include < array>
10+ #include < string>
911extern " C" {
1012#include " device.h"
1113}
@@ -139,6 +141,70 @@ static inline void cleanup_power_off_task(void) {
139141 power_off_task.handle = NULL ;
140142}
141143
144+ template <std::size_t N>
145+ static inline void run_command_get_output (const std::string &cmd,
146+ std::array<char , N> &buf) {
147+ bm_log_info (" %s: running command - %s" , __func__, cmd.c_str ());
148+ FILE *fp = popen (cmd.c_str (), " r" );
149+ if (fp == NULL ) {
150+ return ;
151+ }
152+
153+ // Only set the buffer if an error did not occur
154+ int err = ferror (fp);
155+ bm_log_info (" %s: command - %s returned %d" , __func__, cmd.c_str (), err);
156+ if (!err) {
157+ fgets (buf.data (), buf.size (), fp);
158+ // Strip newline if it exists
159+ buf.data ()[strcspn (buf.data (), " \n " )] = ' \0 ' ;
160+ }
161+ pclose (fp);
162+ }
163+
164+ static inline void wait_for_hydrotwin (void ) {
165+ // Stop cobs_to_shm
166+ const std::string cobs_to_shm = " cobs_to_shm" ;
167+ const std::string disable_cobs_to_shm =
168+ " systemctl stop " + cobs_to_shm + " .service" ;
169+ bm_log_info (" %s: disabling %s, %s" , __func__, cobs_to_shm.c_str (),
170+ disable_cobs_to_shm.c_str ());
171+ system (disable_cobs_to_shm.c_str ());
172+
173+ const std::string service_name = " hydrotwind.service" ;
174+ const std::string service_active = " systemctl is-active " + service_name;
175+ const std::string property = " ExecMainStatus" ;
176+ const std::string service_return =
177+ " systemctl show " + service_name + " -p " + property;
178+
179+ int exited_code = 1 ;
180+ std::array<char , 128 > buf = {};
181+ static constexpr int sleep_time_us = 100000 ;
182+
183+ while (exited_code) {
184+ usleep (sleep_time_us);
185+ memset (buf.data (), 0 , sizeof (buf));
186+
187+ run_command_get_output (service_active, buf);
188+
189+ // If the process is active, retry
190+ const char *p = buf.data ();
191+ bm_log_info (" %s: hydrotwin service is active? %s" , __func__, p);
192+ if (!strcmp (buf.data (), " active" )) {
193+ continue ;
194+ }
195+
196+ run_command_get_output (service_return, buf);
197+
198+ // Set exited based on the output of the command
199+ p = buf.data ();
200+ bm_log_info (" %s: hydrotwin service returned - %s" , __func__, p);
201+ const char *eq = strchr (buf.data (), ' =' );
202+ if (eq) {
203+ exited_code = atoi (eq + 1 );
204+ }
205+ }
206+ }
207+
142208static void request_power_off (void *arg) {
143209 constexpr size_t POWEROFF_SERVICE_PATH_CAP = 64 ;
144210 char poweroff_service[POWEROFF_SERVICE_PATH_CAP ] = {0 };
@@ -153,6 +219,9 @@ static void request_power_off(void *arg) {
153219 }
154220 poweroff_service_len = static_cast <size_t >(n);
155221
222+ bm_log_info (" replay_caught_up: waiting for hydrotwin service to finish" );
223+ wait_for_hydrotwin ();
224+
156225 bm_log_info (" replay_caught_up: requesting %s (timeout=%us)" , poweroff_service,
157226 POWEROFF_TIMEOUT_S );
158227
0 commit comments