/*
  chronyd/chronyc - Programs for keeping computer clocks accurate.

 **********************************************************************
 * Copyright (C) Richard P. Curnow  1997-2003
 * Copyright (C) Miroslav Lichvar  2009-2012, 2014-2015, 2017
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 * 
 **********************************************************************

  =======================================================================

  Driver for systems that implement the adjtimex()/ntp_adjtime() system call
  */

#include "config.h"

#include "sysincl.h"

#include "conf.h"
#include "privops.h"
#include "sys_generic.h"
#include "sys_timex.h"
#include "logging.h"

#ifdef PRIVOPS_ADJUSTTIMEX
#define NTP_ADJTIME PRV_AdjustTimex
#define NTP_ADJTIME_NAME "ntp_adjtime"
#else
#ifdef LINUX
#define NTP_ADJTIME adjtimex
#define NTP_ADJTIME_NAME "adjtimex"
#else
#define NTP_ADJTIME ntp_adjtime
#define NTP_ADJTIME_NAME "ntp_adjtime"
#endif
#endif

/* Maximum frequency offset accepted by the kernel (in ppm) */
#define MAX_FREQ 500.0

/* Frequency scale to convert from ppm to the timex freq */
#define FREQ_SCALE (double)(1 << 16)

/* Threshold for the timex maxerror when the kernel sets the UNSYNC flag */
#define MAX_SYNC_ERROR 16.0

/* Minimum assumed rate at which the kernel updates the clock frequency */
#define MIN_TICK_RATE 100

/* Saved timex status */
static int sys_status;

/* Saved TAI-UTC offset */
static int sys_tai_offset;

/* ================================================== */

static double
convert_timex_frequency(const struct timex *txc)
{
  double freq_ppm;

  freq_ppm = txc->freq / FREQ_SCALE;

  return -freq_ppm;
}

/* ================================================== */

static double
read_frequency(void)
{
  struct timex txc;

  txc.modes = 0;

  SYS_Timex_Adjust(&txc, 0);

  return convert_timex_frequency(&txc);
}

/* ================================================== */

static double
set_frequency(double freq_ppm)
{
  struct timex txc;

  txc.modes = MOD_FREQUENCY;
  txc.freq = freq_ppm * -FREQ_SCALE;

  SYS_Timex_Adjust(&txc, 0);

  return convert_timex_frequency(&txc);
}

/* ================================================== */

static void
set_leap(int leap, int tai_offset)
{
  struct timex txc;
  int applied, prev_status;

  txc.modes = 0;
  applied = SYS_Timex_Adjust(&txc, 0) == TIME_WAIT;

  prev_status = sys_status;
  sys_status &= ~(STA_INS | STA_DEL);

  if (leap > 0)
    sys_status |= STA_INS;
  else if (leap < 0)
    sys_status |= STA_DEL;

  txc.modes = MOD_STATUS;
  txc.status = sys_status;

#ifdef MOD_TAI
  if (tai_offset) {
    txc.modes |= MOD_TAI;
    txc.constant = tai_offset;

    if (applied && !(sys_status & (STA_INS | STA_DEL)))
      sys_tai_offset += prev_status & STA_INS ? 1 : -1;

    if (sys_tai_offset != tai_offset) {
      sys_tai_offset = tai_offset;
      LOG(LOGS_INFO, "System clock TAI offset set to %d seconds", tai_offset);
    }
  }
#endif

  SYS_Timex_Adjust(&txc, 0);

  if (prev_status != sys_status) {
    LOG(LOGS_INFO, "System clock status %s leap second",
        leap ? (leap > 0 ? "set to insert" : "set to delete") :
        (applied ? "reset after" : "set to not insert/delete"));
  }
}

/* ================================================== */

static void
set_sync_status(int synchronised, double est_error, double max_error)
{
  struct timex txc;

  if (synchronised) {
    if (est_error > MAX_SYNC_ERROR)
      est_error = MAX_SYNC_ERROR;
    if (max_error >= MAX_SYNC_ERROR) {
      max_error = MAX_SYNC_ERROR;
      synchronised = 0;
    }
  } else {
    est_error = max_error = MAX_SYNC_ERROR;
  }

#ifdef LINUX
  /* On Linux clear the UNSYNC flag only if rtcsync is enabled */
  if (!CNF_GetRtcSync())
    synchronised = 0;
#endif

  if (synchronised)
    sys_status &= ~STA_UNSYNC;
  else
    sys_status |= STA_UNSYNC;

  txc.modes = MOD_STATUS | MOD_ESTERROR | MOD_MAXERROR;
  txc.status = sys_status;
  txc.esterror = est_error * 1.0e6;
  txc.maxerror = max_error * 1.0e6;

  if (SYS_Timex_Adjust(&txc, 1) < 0)
    ;
}

/* ================================================== */

static void
initialise_timex(void)
{
  struct timex txc;

  sys_status = STA_UNSYNC;
  sys_tai_offset = 0;

  /* Reset PLL offset */
  txc.modes = MOD_OFFSET | MOD_STATUS;
  txc.status = STA_PLL | sys_status;
  txc.offset = 0;
  SYS_Timex_Adjust(&txc, 0);

  /* Turn PLL off */
  txc.modes = MOD_STATUS;
  txc.status = sys_status;
  SYS_Timex_Adjust(&txc, 0);
}

/* ================================================== */

void
SYS_Timex_Initialise(void)
{
  SYS_Timex_InitialiseWithFunctions(MAX_FREQ, 1.0 / MIN_TICK_RATE, NULL, NULL, NULL,
                                    0.0, 0.0, NULL, NULL);
}

/* ================================================== */

void
SYS_Timex_InitialiseWithFunctions(double max_set_freq_ppm, double max_set_freq_delay,
                                  lcl_ReadFrequencyDriver sys_read_freq,
                                  lcl_SetFrequencyDriver sys_set_freq,
                                  lcl_ApplyStepOffsetDriver sys_apply_step_offset,
                                  double min_fastslew_offset, double max_fastslew_rate,
                                  lcl_AccrueOffsetDriver sys_accrue_offset,
                                  lcl_OffsetCorrectionDriver sys_get_offset_correction)
{
  initialise_timex();

  SYS_Generic_CompleteFreqDriver(max_set_freq_ppm, max_set_freq_delay,
                                 sys_read_freq ? sys_read_freq : read_frequency,
                                 sys_set_freq ? sys_set_freq : set_frequency,
                                 sys_apply_step_offset,
                                 min_fastslew_offset, max_fastslew_rate,
                                 sys_accrue_offset, sys_get_offset_correction,
                                 set_leap, set_sync_status);
}

/* ================================================== */

void
SYS_Timex_Finalise(void)
{
  SYS_Generic_Finalise();
}

/* ================================================== */

int
SYS_Timex_Adjust(struct timex *txc, int ignore_error)
{
  int state;

#ifdef SOLARIS
  /* The kernel seems to check the constant even when it's not being set */
  if (!(txc->modes & MOD_TIMECONST))
    txc->constant = 10;
#endif

  state = NTP_ADJTIME(txc);

  if (state < 0) {
    LOG(ignore_error ? LOGS_DEBUG : LOGS_FATAL,
        NTP_ADJTIME_NAME"(0x%x) failed : %s", txc->modes, strerror(errno));
  }

  return state;
}
