57 PeriodNP[0].
fill(
"PERIOD",
"Period (s)",
"%.f", 0, 3600, 60.0, 0);
82 TimeTP[1].
fill(
"OFFSET",
"UTC Offset",
nullptr);
176 else if (
PeriodNP[0].getValue() > 0)
194 restoreNTPOnDisconnect();
210 double prevPeriod =
PeriodNP[0].getValue();
232 "Updating system-wide time repeatedly may lead to undesirable side-effects.");
271 "Updating system time on refresh may lead to undesirable effects on system time accuracy.");
285 disableNTPForGPSTime();
288 const std::string usec = std::to_string(
static_cast<int64_t
>(raw_time) * 1000000LL);
289 if (!timedateCall({
"call",
"org.freedesktop.timedate1",
"/org/freedesktop/timedate1",
"org.freedesktop.timedate1",
"SetTime",
"xbb", usec,
"false",
"false"},
290 {
"--method",
"org.freedesktop.timedate1.SetTime", usec,
"false",
"false"}))
293 "Failed to update system time via org.freedesktop.timedate1 SetTime. "
294 "Ensure polkit allows org.freedesktop.timedate1.set-time for this user.");
308bool GPSInterface::runCommand(
const std::vector<std::string> &args, std::string *output)
311 std::vector<char *> argv;
312 for (
const auto &arg : args)
313 argv.push_back(const_cast<char *>(arg.c_str()));
314 argv.push_back(
nullptr);
316 int pipefd[2] = {-1, -1};
317 if (output !=
nullptr && pipe(pipefd) != 0)
324 int devnull = open(
"/dev/null", O_RDWR);
326 dup2(devnull, STDIN_FILENO);
327 if (output !=
nullptr)
330 dup2(pipefd[1], STDOUT_FILENO);
333 else if (devnull >= 0)
334 dup2(devnull, STDOUT_FILENO);
335 if (devnull > STDERR_FILENO)
338 execvp(argv[0], argv.data());
344 "Failed to fork for command %s: %s", argv[0], strerror(
errno));
345 if (output !=
nullptr)
353 if (output !=
nullptr)
359 while ((n = read(pipefd[0], buffer,
sizeof(buffer))) != 0)
362 output->append(buffer, n);
363 else if (
errno != EINTR)
370 while (waitpid(pid, &status, 0) < 0 &&
errno == EINTR);
371 return WIFEXITED(status) && WEXITSTATUS(status) == 0;
377bool GPSInterface::timedateCall(
const std::vector<std::string> &busctlArgs,
const std::vector<std::string> &gdbusArgs,
380 std::vector<std::string> args;
382 if (getenv(
"FLATPAK_ID") ==
nullptr)
385 args.insert(args.end(), busctlArgs.begin(), busctlArgs.end());
386 return runCommand(args, output);
391 if (access(
"/run/dbus/system_bus_socket", F_OK) == 0)
393 args = {
"gdbus",
"call",
"--system",
"--dest",
"org.freedesktop.timedate1",
"--object-path",
"/org/freedesktop/timedate1"};
394 args.insert(args.end(), gdbusArgs.begin(), gdbusArgs.end());
395 if (runCommand(args, output))
400 args = {
"flatpak-spawn",
"--host",
"busctl"};
401 args.insert(args.end(), busctlArgs.begin(), busctlArgs.end());
402 return runCommand(args, output);
408bool GPSInterface::isNTPActive()
411 if (!timedateCall({
"get-property",
"org.freedesktop.timedate1",
"/org/freedesktop/timedate1",
"org.freedesktop.timedate1",
"NTP"},
412 {
"--method",
"org.freedesktop.DBus.Properties.Get",
"org.freedesktop.timedate1",
"NTP"},
417 return output.find(
"true") != std::string::npos;
423bool GPSInterface::setNTPEnabled(
bool enabled)
425 const std::string value = enabled ?
"true" :
"false";
426 return timedateCall({
"call",
"org.freedesktop.timedate1",
"/org/freedesktop/timedate1",
"org.freedesktop.timedate1",
"SetNTP",
"bb", value,
"false"},
427 {
"--method",
"org.freedesktop.timedate1.SetNTP", value,
"false"});
433void GPSInterface::disableNTPForGPSTime()
439 "NTP is active; disabling for GPS time authority...");
440 if (!setNTPEnabled(
false))
449 for (
int i = 0; i < 10 && isNTPActive(); i++)
458void GPSInterface::restoreNTPOnDisconnect()
463 "Restoring NTP after GPS disconnect...");
464 if (setNTPEnabled(
true))
473 "Failed to re-enable NTP.");
486 "updateGPS() must be implemented in GPS device child class to update TIME_UTC and GEOGRAPHIC_COORD properties.");
const char * getDeviceName() const
Class to provide extended functionality for devices in addition to the functionality provided by INDI...
virtual bool deleteProperty(const char *propertyName)
Delete a property and unregister it. It will also be deleted from all clients.
void defineProperty(INumberVectorProperty *property)
INDI::PropertyNumber LocationNP
void checkGPSState()
checkGPSState Check and update GPS state
DefaultDevice * m_DefaultDevice
bool setSystemTime(time_t &raw_time)
SetSystemTime Update system-wide time.
bool updateProperties()
updateProperties Define or Delete Rotator properties based on the connection status of the base devic...
virtual IPState updateGPS()
updateGPS Retrieve Location & Time from GPS. Update LocationNP & TimeTP properties (value and state) ...
INDI::PropertyNumber PeriodNP
bool processSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Process focus switch properties.
INDI::PropertySwitch SystemTimeUpdateSP
bool processNumber(const char *dev, const char *name, double values[], char *names[], int n)
Process focus number properties.
virtual bool saveConfigItems(FILE *fp)
saveConfigItems save focuser properties defined in the interface in config file
INDI::Timer m_UpdateTimer
INDI::PropertyText TimeTP
INDI::PropertySwitch RefreshSP
void initProperties(const char *groupName)
Initialize focuser properties. It is recommended to call this function within initProperties() of you...
GPSInterface(DefaultDevice *defaultDevice)
void setState(IPState state)
void apply(const char *format,...) const ATTRIBUTE_FORMAT_PRINTF(2
bool load()
load Attempt to load property values from configuration file.
void save(FILE *f) const
save Save property to configuration file.
bool isNameMatch(const char *otherName) const
bool update(const double values[], const char *const names[], int n)
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, double timeout, IPState state)
bool update(const ISState states[], const char *const names[], int n)
int findOnSwitchIndex() const
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, ISRule rule, double timeout, IPState state)
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, double timeout, IPState state)
void setSingleShot(bool singleShot)
Set whether the timer is a single-shot timer.
void callOnTimeout(const std::function< void()> &callback)
void start()
Starts or restarts the timer with the timeout specified in interval.
bool isActive() const
Returns true if the timer is running (pending); otherwise returns false.
void setInterval(int msec)
Set the timeout interval in milliseconds.
void stop()
Stops the timer.
#define DEBUGDEVICE(device, priority, msg)
#define DEBUGFDEVICE(device, priority, msg,...)
std::vector< uint8_t > buffer
Namespace to encapsulate INDI client, drivers, and mediator classes.