/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * A service that exchanges time synchronization information between
 * a master that defines a timeline and clients that follow the timeline.
 */

#define __STDC_LIMIT_MACROS
#define LOG_TAG "common_time"
#include <utils/Log.h>
#include <stdint.h>

#include <common_time/local_clock.h>
#include <assert.h>

#include "clock_recovery.h"
#include "common_clock.h"
#ifdef TIME_SERVICE_DEBUG
#include "diag_thread.h"
#endif

// Define log macro so we can make LOGV into LOGE when we are exclusively
// debugging this code.
#ifdef TIME_SERVICE_DEBUG
#define LOG_TS ALOGE
#else
#define LOG_TS ALOGV
#endif

namespace android {

ClockRecoveryLoop::ClockRecoveryLoop(LocalClock* local_clock,
                                     CommonClock* common_clock) {
    assert(NULL != local_clock);
    assert(NULL != common_clock);

    local_clock_  = local_clock;
    common_clock_ = common_clock;

    local_clock_can_slew_ = local_clock_->initCheck() &&
                           (local_clock_->setLocalSlew(0) == OK);

    reset(true, true);

#ifdef TIME_SERVICE_DEBUG
    diag_thread_ = new DiagThread(common_clock_, local_clock_);
    if (diag_thread_ != NULL) {
        status_t res = diag_thread_->startWorkThread();
        if (res != OK)
            ALOGW("Failed to start A@H clock recovery diagnostic thread.");
    } else
        ALOGW("Failed to allocate diagnostic thread.");
#endif
}

ClockRecoveryLoop::~ClockRecoveryLoop() {
#ifdef TIME_SERVICE_DEBUG
    diag_thread_->stopWorkThread();
#endif
}

// Constants.
const float ClockRecoveryLoop::dT = 1.0;
const float ClockRecoveryLoop::Kc = 1.0f;
const float ClockRecoveryLoop::Ti = 15.0f;
const float ClockRecoveryLoop::Tf = 0.05;
const float ClockRecoveryLoop::bias_Fc = 0.01;
const float ClockRecoveryLoop::bias_RC = (dT / (2 * 3.14159f * bias_Fc));
const float ClockRecoveryLoop::bias_Alpha = (dT / (bias_RC + dT));
const int64_t ClockRecoveryLoop::panic_thresh_ = 50000;
const int64_t ClockRecoveryLoop::control_thresh_ = 10000;
const float ClockRecoveryLoop::COmin = -100.0f;
const float ClockRecoveryLoop::COmax = 100.0f;

void ClockRecoveryLoop::reset(bool position, bool frequency) {
    Mutex::Autolock lock(&lock_);
    reset_l(position, frequency);
}

uint32_t ClockRecoveryLoop::findMinRTTNdx(DisciplineDataPoint* data,
                                          uint32_t count) {
    uint32_t min_rtt = 0;
    for (uint32_t i = 1; i < count; ++i)
        if (data[min_rtt].rtt > data[i].rtt)
            min_rtt = i;

    return min_rtt;
}

bool ClockRecoveryLoop::pushDisciplineEvent(int64_t local_time,
                                            int64_t nominal_common_time,
                                            int64_t rtt) {
    Mutex::Autolock lock(&lock_);

    int64_t local_common_time = 0;
    common_clock_->localToCommon(local_time, &local_common_time);
    int64_t raw_delta = nominal_common_time - local_common_time;

#ifdef TIME_SERVICE_DEBUG
    ALOGE("local=%lld, common=%lld, delta=%lld, rtt=%lld\n",
         local_common_time, nominal_common_time,
         raw_delta, rtt);
#endif

    // If we have not defined a basis for common time, then we need to use these
    // initial points to do so.  In order to avoid significant initial error
    // from a particularly bad startup data point, we collect the first N data
    // points and choose the best of them before moving on.
    if (!common_clock_->isValid()) {
        if (startup_filter_wr_ < kStartupFilterSize) {
            DisciplineDataPoint& d =  startup_filter_data_[startup_filter_wr_];
            d.local_time = local_time;
            d.nominal_common_time = nominal_common_time;
            d.rtt = rtt;
            startup_filter_wr_++;
        }

        if (startup_filter_wr_ == kStartupFilterSize) {
            uint32_t min_rtt = findMinRTTNdx(startup_filter_data_,
                    kStartupFilterSize);

            common_clock_->setBasis(
                    startup_filter_data_[min_rtt].local_time,
                    startup_filter_data_[min_rtt].nominal_common_time);
        }

        return true;
    }

    int64_t observed_common;
    int64_t delta;
    float delta_f, dCO;
    int32_t correction_cur;

    if (OK != common_clock_->localToCommon(local_time, &observed_common)) {
        // Since we just checked to make certain that this conversion was valid,
        // and no one else in the system should be messing with it, if this
        // conversion is suddenly invalid, it is a good reason to panic.
        ALOGE("Failed to convert local time to common time in %s:%d",
                __PRETTY_FUNCTION__, __LINE__);
        return false;
    }

    // Implement a filter which should match NTP filtering behavior when a
    // client is associated with only one peer of lower stratum.  Basically,
    // always use the best of the N last data points, where best is defined as
    // lowest round trip time.  NTP uses an N of 8; we use a value of 6.
    //
    // TODO(johngro) : experiment with other filter strategies.  The goal here
    // is to mitigate the effects of high RTT data points which typically have
    // large asymmetries in the TX/RX legs.  Downside of the existing NTP
    // approach (particularly because of the PID controller we are using to
    // produce the control signal from the filtered data) are that the rate at
    // which discipline events are actually acted upon becomes irregular and can
    // become drawn out (the time between actionable event can go way up).  If
    // the system receives a strong high quality data point, the proportional
    // component of the controller can produce a strong correction which is left
    // in place for too long causing overshoot.  In addition, the integral
    // component of the system currently is an approximation based on the
    // assumption of a more or less homogeneous sampling of the error.  Its
    // unclear what the effect of undermining this assumption would be right
    // now.

    // Two ideas which come to mind immediately would be to...
    // 1) Keep a history of more data points (32 or so) and ignore data points
    //    whose RTT is more than a certain number of standard deviations outside
    //    of the norm.
    // 2) Eliminate the PID controller portion of this system entirely.
    //    Instead, move to a system which uses a very wide filter (128 data
    //    points or more) with a sum-of-least-squares line fitting approach to
    //    tracking the long term drift.  This would take the place of the I
    //    component in the current PID controller.  Also use a much more narrow
    //    outlier-rejector filter (as described in #1) to drive a short term
    //    correction factor similar to the P component of the PID controller.
    assert(filter_wr_ < kFilterSize);
    filter_data_[filter_wr_].local_time           = local_time;
    filter_data_[filter_wr_].observed_common_time = observed_common;
    filter_data_[filter_wr_].nominal_common_time  = nominal_common_time;
    filter_data_[filter_wr_].rtt                  = rtt;
    filter_data_[filter_wr_].point_used           = false;
    uint32_t current_point = filter_wr_;
    filter_wr_ = (filter_wr_ + 1) % kFilterSize;
    if (!filter_wr_)
        filter_full_ = true;

    uint32_t scan_end = filter_full_ ? kFilterSize : filter_wr_;
    uint32_t min_rtt = findMinRTTNdx(filter_data_, scan_end);
    // We only use packets with low RTTs for control. If the packet RTT
    // is less than the panic threshold, we can probably eat the jitter with the
    // control loop. Otherwise, take the packet only if it better than all
    // of the packets we have in the history. That way we try to track
    // something, even if it is noisy.
    if (current_point == min_rtt || rtt < control_thresh_) {
        delta_f = delta = nominal_common_time - observed_common;

        // Compute the error then clamp to the panic threshold.  If we ever
        // exceed this amt of error, its time to panic and reset the system.
        // Given that the error in the measurement of the error could be as
        // high as the RTT of the data point, we don't actually panic until
        // the implied error (delta) is greater than the absolute panic
        // threashold plus the RTT.  IOW - we don't panic until we are
        // absoluely sure that our best case sync is worse than the absolute
        // panic threshold.
        int64_t effective_panic_thresh = panic_thresh_ + rtt;
        if ((delta > effective_panic_thresh) ||
            (delta < -effective_panic_thresh)) {
            // PANIC!!!
            reset_l(false, true);
            return false;
        }

    } else {
        // We do not have a good packet to look at, but we also do not want to
        // free-run the clock at some crazy slew rate. So we guess the
        // trajectory of the clock based on the last controller output and the
        // estimated bias of our clock against the master.
        // The net effect of this is that CO == CObias after some extended
        // period of no feedback.
        delta_f = last_delta_f_ - dT*(CO - CObias);
        delta = delta_f;
    }

    // Velocity form PI control equation.
    dCO = Kc * (1.0f + dT/Ti) * delta_f - Kc * last_delta_f_;
    CO += dCO * Tf; // Filter CO by applying gain <1 here.

    // Save error terms for later.
    last_delta_f_ = delta_f;
    last_delta_ = delta;

    // Clamp CO to +/- 100ppm.
    if (CO < COmin)
        CO = COmin;
    else if (CO > COmax)
        CO = COmax;

    // Update the controller bias.
    CObias = bias_Alpha * CO + (1.0f - bias_Alpha) * lastCObias;
    lastCObias = CObias;

    // Convert PPM to 16-bit int range. Add some guard band (-0.01) so we
    // don't get fp weirdness.
    correction_cur = CO * 327.66;

    // If there was a change in the amt of correction to use, update the
    // system.
    if (correction_cur_ != correction_cur) {
        correction_cur_ = correction_cur;
        applySlew();
    }

    LOG_TS("clock_loop %lld %f %f %f %d\n", raw_delta, delta_f, CO, CObias, correction_cur);

#ifdef TIME_SERVICE_DEBUG
    diag_thread_->pushDisciplineEvent(
            local_time,
            observed_common,
            nominal_common_time,
            correction_cur,
            rtt);
#endif

    return true;
}

int32_t ClockRecoveryLoop::getLastErrorEstimate() {
    Mutex::Autolock lock(&lock_);

    if (last_delta_valid_)
        return last_delta_;
    else
        return ICommonClock::kErrorEstimateUnknown;
}

void ClockRecoveryLoop::reset_l(bool position, bool frequency) {
    assert(NULL != common_clock_);

    if (position) {
        common_clock_->resetBasis();
        startup_filter_wr_ = 0;
    }

    if (frequency) {
        last_delta_valid_ = false;
        last_delta_ = 0;
        last_delta_f_ = 0.0;
        correction_cur_ = 0x0;
        CO = 0.0f;
        lastCObias = CObias = 0.0f;
        applySlew();
    }

    filter_wr_   = 0;
    filter_full_ = false;
}

void ClockRecoveryLoop::applySlew() {
    if (local_clock_can_slew_) {
        local_clock_->setLocalSlew(correction_cur_);
    } else {
        // The SW clock recovery implemented by the common clock class expects
        // values expressed in PPM. CO is in ppm.
        common_clock_->setSlew(local_clock_->getLocalTime(), CO);
    }
}

}  // namespace android
