/*
 * Copyright (C) 2012 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 LOG_TAG "common_time"
#include <utils/Log.h>

#include <arpa/inet.h>
#include <assert.h>
#include <fcntl.h>
#include <linux/if_ether.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <netinet/ip.h>
#include <poll.h>
#include <stdio.h>
#include <sys/eventfd.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>

#include <common_time/local_clock.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <utils/Timers.h>

#include "common_clock_service.h"
#include "common_time_config_service.h"
#include "common_time_server.h"
#include "common_time_server_packets.h"
#include "clock_recovery.h"
#include "common_clock.h"

#define MAX_INT ((int)0x7FFFFFFF)

namespace android {

const char*    CommonTimeServer::kDefaultMasterElectionAddr = "239.195.128.88";
const uint16_t CommonTimeServer::kDefaultMasterElectionPort = 8887;
const uint64_t CommonTimeServer::kDefaultSyncGroupID = 0;
const uint8_t  CommonTimeServer::kDefaultMasterPriority = 1;
const uint32_t CommonTimeServer::kDefaultMasterAnnounceIntervalMs = 10000;
const uint32_t CommonTimeServer::kDefaultSyncRequestIntervalMs = 1000;
const uint32_t CommonTimeServer::kDefaultPanicThresholdUsec = 50000;
const bool     CommonTimeServer::kDefaultAutoDisable = true;
const int      CommonTimeServer::kSetupRetryTimeoutMs = 30000;
const int64_t  CommonTimeServer::kNoGoodDataPanicThresholdUsec = 600000000ll;
const uint32_t CommonTimeServer::kRTTDiscardPanicThreshMultiplier = 5;

// timeout value representing an infinite timeout
const int CommonTimeServer::kInfiniteTimeout = -1;

/*** Initial state constants ***/

// number of WhoIsMaster attempts sent before giving up
const int CommonTimeServer::kInitial_NumWhoIsMasterRetries = 6;

// timeout used when waiting for a response to a WhoIsMaster request
const int CommonTimeServer::kInitial_WhoIsMasterTimeoutMs = 500;

/*** Client state constants ***/

// number of sync requests that can fail before a client assumes its master
// is dead
const int CommonTimeServer::kClient_NumSyncRequestRetries = 10;

/*** Master state constants ***/

/*** Ronin state constants ***/

// number of WhoIsMaster attempts sent before declaring ourselves master
const int CommonTimeServer::kRonin_NumWhoIsMasterRetries = 20;

// timeout used when waiting for a response to a WhoIsMaster request
const int CommonTimeServer::kRonin_WhoIsMasterTimeoutMs = 500;

/*** WaitForElection state constants ***/

// how long do we wait for an announcement from a master before
// trying another election?
const int CommonTimeServer::kWaitForElection_TimeoutMs = 12500;

CommonTimeServer::CommonTimeServer()
    : Thread(false)
    , mState(ICommonClock::STATE_INITIAL)
    , mClockRecovery(&mLocalClock, &mCommonClock)
    , mSocket(-1)
    , mLastPacketRxLocalTime(0)
    , mTimelineID(ICommonClock::kInvalidTimelineID)
    , mClockSynced(false)
    , mCommonClockHasClients(false)
    , mStateChangeLog("Recent State Change Events", 30)
    , mElectionLog("Recent Master Election Traffic", 30)
    , mBadPktLog("Recent Bad Packet RX Info", 8)
    , mInitial_WhoIsMasterRequestTimeouts(0)
    , mClient_MasterDeviceID(0)
    , mClient_MasterDevicePriority(0)
    , mRonin_WhoIsMasterRequestTimeouts(0) {
    // zero out sync stats
    resetSyncStats();

    // Setup the master election endpoint to use the default.
    struct sockaddr_in* meep =
        reinterpret_cast<struct sockaddr_in*>(&mMasterElectionEP);
    memset(&mMasterElectionEP, 0, sizeof(mMasterElectionEP));
    inet_aton(kDefaultMasterElectionAddr, &meep->sin_addr);
    meep->sin_family = AF_INET;
    meep->sin_port   = htons(kDefaultMasterElectionPort);

    // Zero out the master endpoint.
    memset(&mMasterEP, 0, sizeof(mMasterEP));
    mMasterEPValid    = false;
    mBindIfaceValid   = false;
    setForceLowPriority(false);

    // Set all remaining configuration parameters to their defaults.
    mDeviceID                 = 0;
    mSyncGroupID              = kDefaultSyncGroupID;
    mMasterPriority           = kDefaultMasterPriority;
    mMasterAnnounceIntervalMs = kDefaultMasterAnnounceIntervalMs;
    mSyncRequestIntervalMs    = kDefaultSyncRequestIntervalMs;
    mPanicThresholdUsec       = kDefaultPanicThresholdUsec;
    mAutoDisable              = kDefaultAutoDisable;

    // Create the eventfd we will use to signal our thread to wake up when
    // needed.
    mWakeupThreadFD = eventfd(0, EFD_NONBLOCK);

    // seed the random number generator (used to generated timeline IDs)
    srand48(static_cast<unsigned int>(systemTime()));
}

CommonTimeServer::~CommonTimeServer() {
    shutdownThread();

    // No need to grab the lock here.  We are in the destructor; if the the user
    // has a thread in any of the APIs while the destructor is being called,
    // there is a threading problem a the application level we cannot reasonably
    // do anything about.
    cleanupSocket_l();

    if (mWakeupThreadFD >= 0) {
        close(mWakeupThreadFD);
        mWakeupThreadFD = -1;
    }
}

bool CommonTimeServer::startServices() {
    // start the ICommonClock service
    mICommonClock = CommonClockService::instantiate(*this);
    if (mICommonClock == NULL)
        return false;

    // start the ICommonTimeConfig service
    mICommonTimeConfig = CommonTimeConfigService::instantiate(*this);
    if (mICommonTimeConfig == NULL)
        return false;

    return true;
}

bool CommonTimeServer::threadLoop() {
    // Register our service interfaces.
    if (!startServices())
        return false;

    // Hold the lock while we are in the main thread loop.  It will release the
    // lock when it blocks, and hold the lock at all other times.
    mLock.lock();
    runStateMachine_l();
    mLock.unlock();

    IPCThreadState::self()->stopProcess();
    return false;
}

bool CommonTimeServer::runStateMachine_l() {
    if (!mLocalClock.initCheck())
        return false;

    if (!mCommonClock.init(mLocalClock.getLocalFreq()))
        return false;

    // Enter the initial state.
    becomeInitial("startup");

    // run the state machine
    while (!exitPending()) {
        struct pollfd pfds[2];
        int rc, timeout;
        int eventCnt = 0;
        int64_t wakeupTime;
        uint32_t t1, t2;
        bool needHandleTimeout = false;

        // We are always interested in our wakeup FD.
        pfds[eventCnt].fd      = mWakeupThreadFD;
        pfds[eventCnt].events  = POLLIN;
        pfds[eventCnt].revents = 0;
        eventCnt++;

        // If we have a valid socket, then we are interested in what it has to
        // say as well.
        if (mSocket >= 0) {
            pfds[eventCnt].fd      = mSocket;
            pfds[eventCnt].events  = POLLIN;
            pfds[eventCnt].revents = 0;
            eventCnt++;
        }

        t1 = static_cast<uint32_t>(mCurTimeout.msecTillTimeout());
        t2 = static_cast<uint32_t>(mClockRecovery.applyRateLimitedSlew());
        timeout = static_cast<int>(t1 < t2 ? t1 : t2);

        // Note, we were holding mLock when this function was called.  We
        // release it only while we are blocking and hold it at all other times.
        mLock.unlock();
        rc          = poll(pfds, eventCnt, timeout);
        wakeupTime  = mLocalClock.getLocalTime();
        mLock.lock();

        // Is it time to shutdown?  If so, don't hesitate... just do it.
        if (exitPending())
            break;

        // Did the poll fail?  This should never happen and is fatal if it does.
        if (rc < 0) {
            ALOGE("%s:%d poll failed", __PRETTY_FUNCTION__, __LINE__);
            return false;
        }

        if (rc == 0) {
            needHandleTimeout = !mCurTimeout.msecTillTimeout();
            if (needHandleTimeout)
                mCurTimeout.setTimeout(kInfiniteTimeout);
        }

        // Were we woken up on purpose?  If so, clear the eventfd with a read.
        if (pfds[0].revents)
            clearPendingWakeupEvents_l();

        // Is out bind address dirty?  If so, clean up our socket (if any).
        // Alternatively, do we have an active socket but should be auto
        // disabled?  If so, release the socket and enter the proper sync state.
        bool droppedSocket = false;
        if (mBindIfaceDirty || ((mSocket >= 0) && shouldAutoDisable())) {
            cleanupSocket_l();
            mBindIfaceDirty = false;
            droppedSocket = true;
        }

        // Do we not have a socket but should have one?  If so, try to set one
        // up.
        if ((mSocket < 0) && mBindIfaceValid && !shouldAutoDisable()) {
            if (setupSocket_l()) {
                // Success!  We are now joining a new network (either coming
                // from no network, or coming from a potentially different
                // network).  Force our priority to be lower so that we defer to
                // any other masters which may already be on the network we are
                // joining.  Later, when we enter either the client or the
                // master state, we will clear this flag and go back to our
                // normal election priority.
                setForceLowPriority(true);
                switch (mState) {
                    // If we were in initial (whether we had a immediately
                    // before this network or not) we want to simply reset the
                    // system and start again.  Forcing a transition from
                    // INITIAL to INITIAL should do the job.
                    case CommonClockService::STATE_INITIAL:
                        becomeInitial("bound interface");
                        break;

                    // If we were in the master state, then either we were the
                    // master in a no-network situation, or we were the master
                    // of a different network and have moved to a new interface.
                    // In either case, immediately transition to Ronin at low
                    // priority.  If there is no one in the network we just
                    // joined, we will become master soon enough.  If there is,
                    // we want to be certain to defer master status to the
                    // existing timeline currently running on the network.
                    //
                    case CommonClockService::STATE_MASTER:
                        becomeRonin("leaving networkless mode");
                        break;

                    // If we were in any other state (CLIENT, RONIN, or
                    // WAIT_FOR_ELECTION) then we must be moving from one
                    // network to another.  We have lost our old master;
                    // transition to RONIN in an attempt to find a new master.
                    // If there are none out there, we will just assume
                    // responsibility for the timeline we used to be a client
                    // of.
                    default:
                        becomeRonin("bound interface");
                        break;
                }
            } else {
                // That's odd... we failed to set up our socket.  This could be
                // due to some transient network change which will work itself
                // out shortly; schedule a retry attempt in the near future.
                mCurTimeout.setTimeout(kSetupRetryTimeoutMs);
            }

            // One way or the other, we don't have any data to process at this
            // point (since we just tried to bulid a new socket).  Loop back
            // around and wait for the next thing to do.
            continue;
        } else if (droppedSocket) {
            // We just lost our socket, and for whatever reason (either no
            // config, or auto disable engaged) we are not supposed to rebuild
            // one at this time.  We are not going to rebuild our socket until
            // something about our config/auto-disabled status changes, so we
            // are basically in network-less mode.  If we are already in either
            // INITIAL or MASTER, just stay there until something changes.  If
            // we are in any other state (CLIENT, RONIN or WAIT_FOR_ELECTION),
            // then transition to either INITIAL or MASTER depending on whether
            // or not our timeline is valid.
            mStateChangeLog.log(ANDROID_LOG_INFO, LOG_TAG,
                    "Entering networkless mode interface is %s, "
                    "shouldAutoDisable = %s",
                    mBindIfaceValid ? "valid" : "invalid",
                    shouldAutoDisable() ? "true" : "false");
            if ((mState != ICommonClock::STATE_INITIAL) &&
                (mState != ICommonClock::STATE_MASTER)) {
                if (mTimelineID == ICommonClock::kInvalidTimelineID)
                    becomeInitial("network-less mode");
                else
                    becomeMaster("network-less mode");
            }

            continue;
        }

        // Time to handle the timeouts?
        if (needHandleTimeout) {
            if (!handleTimeout())
                ALOGE("handleTimeout failed");
            continue;
        }

        // Does our socket have data for us (assuming we still have one, we
        // may have RXed a packet at the same time as a config change telling us
        // to shut our socket down)?  If so, process its data.
        if ((mSocket >= 0) && (eventCnt > 1) && (pfds[1].revents)) {
            mLastPacketRxLocalTime = wakeupTime;
            if (!handlePacket())
                ALOGE("handlePacket failed");
        }
    }

    cleanupSocket_l();
    return true;
}

void CommonTimeServer::clearPendingWakeupEvents_l() {
    int64_t tmp;
    read(mWakeupThreadFD, &tmp, sizeof(tmp));
}

void CommonTimeServer::wakeupThread_l() {
    int64_t tmp = 1;
    write(mWakeupThreadFD, &tmp, sizeof(tmp));
}

void CommonTimeServer::cleanupSocket_l() {
    if (mSocket >= 0) {
        close(mSocket);
        mSocket = -1;
    }
}

void CommonTimeServer::shutdownThread() {
    // Flag the work thread for shutdown.
    this->requestExit();

    // Signal the thread in case its sleeping.
    mLock.lock();
    wakeupThread_l();
    mLock.unlock();

    // Wait for the thread to exit.
    this->join();
}

bool CommonTimeServer::setupSocket_l() {
    int rc;
    bool ret_val = false;
    struct sockaddr_in* ipv4_addr = NULL;
    char masterElectionEPStr[64];
    const int one = 1;

    // This should never be needed, but if we happened to have an old socket
    // lying around, be sure to not leak it before proceeding.
    cleanupSocket_l();

    // If we don't have a valid endpoint to bind to, then how did we get here in
    // the first place?  Regardless, we know that we are going to fail to bind,
    // so don't even try.
    if (!mBindIfaceValid)
        return false;

    sockaddrToString(mMasterElectionEP, true, masterElectionEPStr,
                     sizeof(masterElectionEPStr));
    mStateChangeLog.log(ANDROID_LOG_INFO, LOG_TAG,
                        "Building socket :: bind = %s master election = %s",
                        mBindIface.string(), masterElectionEPStr);

    // TODO: add proper support for IPv6.  Right now, we block IPv6 addresses at
    // the configuration interface level.
    if (AF_INET != mMasterElectionEP.ss_family) {
        mStateChangeLog.log(ANDROID_LOG_WARN, LOG_TAG,
                            "TODO: add proper IPv6 support");
        goto bailout;
    }

    // open a UDP socket for the timeline serivce
    mSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (mSocket < 0) {
        mStateChangeLog.log(ANDROID_LOG_ERROR, LOG_TAG,
                            "Failed to create socket (errno = %d)", errno);
        goto bailout;
    }

    // Bind to the selected interface using Linux's spiffy SO_BINDTODEVICE.
    struct ifreq ifr;
    memset(&ifr, 0, sizeof(ifr));
    snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", mBindIface.string());
    ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = 0;
    rc = setsockopt(mSocket, SOL_SOCKET, SO_BINDTODEVICE,
                    (void *)&ifr, sizeof(ifr));
    if (rc) {
        mStateChangeLog.log(ANDROID_LOG_ERROR, LOG_TAG,
                            "Failed to bind socket at to interface %s "
                            "(errno = %d)", ifr.ifr_name, errno);
        goto bailout;
    }

    // Bind our socket to INADDR_ANY and the master election port.  The
    // interface binding we made using SO_BINDTODEVICE should limit us to
    // traffic only on the interface we are interested in.  We need to bind to
    // INADDR_ANY and the specific master election port in order to be able to
    // receive both unicast traffic and master election multicast traffic with
    // just a single socket.
    struct sockaddr_in bindAddr;
    ipv4_addr = reinterpret_cast<struct sockaddr_in*>(&mMasterElectionEP);
    memcpy(&bindAddr, ipv4_addr, sizeof(bindAddr));
    bindAddr.sin_addr.s_addr = INADDR_ANY;
    rc = bind(mSocket,
              reinterpret_cast<const sockaddr *>(&bindAddr),
              sizeof(bindAddr));
    if (rc) {
        mStateChangeLog.log(ANDROID_LOG_ERROR, LOG_TAG,
                            "Failed to bind socket to port %hu (errno = %d)",
                            ntohs(bindAddr.sin_port), errno);
        goto bailout;
    }

    if (0xE0000000 == (ntohl(ipv4_addr->sin_addr.s_addr) & 0xF0000000)) {
        // If our master election endpoint is a multicast address, be sure to join
        // the multicast group.
        struct ip_mreq mreq;
        mreq.imr_multiaddr = ipv4_addr->sin_addr;
        mreq.imr_interface.s_addr = htonl(INADDR_ANY);
        rc = setsockopt(mSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP,
                        &mreq, sizeof(mreq));
        if (rc == -1) {
            ALOGE("Failed to join multicast group at %s.  (errno = %d)",
                 masterElectionEPStr, errno);
            goto bailout;
        }

        // disable loopback of multicast packets
        const int zero = 0;
        rc = setsockopt(mSocket, IPPROTO_IP, IP_MULTICAST_LOOP,
                        &zero, sizeof(zero));
        if (rc == -1) {
            mStateChangeLog.log(ANDROID_LOG_ERROR, LOG_TAG,
                                "Failed to disable multicast loopback "
                                "(errno = %d)", errno);
            goto bailout;
        }
    } else
    if (ntohl(ipv4_addr->sin_addr.s_addr) == 0xFFFFFFFF) {
        // If the master election address is the broadcast address, then enable
        // the broadcast socket option
        rc = setsockopt(mSocket, SOL_SOCKET, SO_BROADCAST, &one, sizeof(one));
        if (rc == -1) {
            mStateChangeLog.log(ANDROID_LOG_ERROR, LOG_TAG,
                                "Failed to enable broadcast (errno = %d)",
                                errno);
            goto bailout;
        }
    } else {
        // If the master election address is neither broadcast, nor multicast,
        // then we are misconfigured.  The config API layer should prevent this
        // from ever happening.
        goto bailout;
    }

    // Set the TTL of sent packets to 1.  (Time protocol sync should never leave
    // the local subnet)
    rc = setsockopt(mSocket, IPPROTO_IP, IP_TTL, &one, sizeof(one));
    if (rc == -1) {
        mStateChangeLog.log(ANDROID_LOG_ERROR, LOG_TAG,
                            "Failed to set TTL to %d (errno = %d)", one, errno);
        goto bailout;
    }

    // get the device's unique ID
    if (!assignDeviceID())
        goto bailout;

    ret_val = true;

bailout:
    if (!ret_val)
        cleanupSocket_l();
    return ret_val;
}

// generate a unique device ID that can be used for arbitration
bool CommonTimeServer::assignDeviceID() {
    if (!mBindIfaceValid)
        return false;

    struct ifreq ifr;
    memset(&ifr, 0, sizeof(ifr));
    ifr.ifr_addr.sa_family = AF_INET;
    strlcpy(ifr.ifr_name, mBindIface.string(), IFNAMSIZ);

    int rc = ioctl(mSocket, SIOCGIFHWADDR, &ifr);
    if (rc) {
        ALOGE("%s:%d ioctl failed", __PRETTY_FUNCTION__, __LINE__);
        return false;
    }

    if (ifr.ifr_addr.sa_family != ARPHRD_ETHER) {
        ALOGE("%s:%d got non-Ethernet address", __PRETTY_FUNCTION__, __LINE__);
        return false;
    }

    mDeviceID = 0;
    for (int i = 0; i < ETH_ALEN; i++) {
        mDeviceID = (mDeviceID << 8) | ifr.ifr_hwaddr.sa_data[i];
    }

    return true;
}

// generate a new timeline ID
void CommonTimeServer::assignTimelineID() {
    do {
        mTimelineID = (static_cast<uint64_t>(lrand48()) << 32)
                    |  static_cast<uint64_t>(lrand48());
    } while (mTimelineID == ICommonClock::kInvalidTimelineID);
}

// Select a preference between the device IDs of two potential masters.
// Returns true if the first ID wins, or false if the second ID wins.
bool CommonTimeServer::arbitrateMaster(
        uint64_t deviceID1, uint8_t devicePrio1,
        uint64_t deviceID2, uint8_t devicePrio2) {
    return ((devicePrio1 >  devicePrio2) ||
           ((devicePrio1 == devicePrio2) && (deviceID1 > deviceID2)));
}

static void hexDumpToString(const uint8_t* src, size_t src_len,
                            char* dst, size_t dst_len) {
    size_t offset;
    size_t i;

    for (i = 0; (i < src_len) && (offset < dst_len); ++i) {
        int res;
        if (0 == (i % 16)) {
            res = snprintf(dst + offset, dst_len - offset, "\n%04x :", i);
            if (res < 0)
                break;
            offset += res;
            if (offset >= dst_len)
                break;
        }

        res = snprintf(dst + offset, dst_len - offset, " %02x", src[i]);
        if (res < 0)
            break;
        offset += res;
    }

    dst[dst_len - 1] = 0;
}

bool CommonTimeServer::handlePacket() {
    uint8_t buf[256];
    struct sockaddr_storage srcAddr;
    socklen_t srcAddrLen = sizeof(srcAddr);

    ssize_t recvBytes = recvfrom(
            mSocket, buf, sizeof(buf), 0,
            reinterpret_cast<const sockaddr *>(&srcAddr), &srcAddrLen);

    if (recvBytes < 0) {
        mBadPktLog.log(ANDROID_LOG_ERROR, LOG_TAG,
                       "recvfrom failed (res %d, errno %d)",
                       recvBytes, errno);
        return false;
    }

    UniversalTimeServicePacket pkt;
    if (pkt.deserializePacket(buf, recvBytes, mSyncGroupID) < 0) {
        char hex[256];
        char srcEPStr[64];

        hexDumpToString(buf, static_cast<size_t>(recvBytes), hex, sizeof(hex));
        sockaddrToString(srcAddr, true, srcEPStr, sizeof(srcEPStr));

        mBadPktLog.log("Failed to parse %d byte packet from %s.%s",
                       recvBytes, srcEPStr, hex);
        return false;
    }

    bool result;
    switch (pkt.packetType) {
        case TIME_PACKET_WHO_IS_MASTER_REQUEST:
            result = handleWhoIsMasterRequest(&pkt.p.who_is_master_request,
                                              srcAddr);
            break;

        case TIME_PACKET_WHO_IS_MASTER_RESPONSE:
            result = handleWhoIsMasterResponse(&pkt.p.who_is_master_response,
                                               srcAddr);
            break;

        case TIME_PACKET_SYNC_REQUEST:
            result = handleSyncRequest(&pkt.p.sync_request, srcAddr);
            break;

        case TIME_PACKET_SYNC_RESPONSE:
            result = handleSyncResponse(&pkt.p.sync_response, srcAddr);
            break;

        case TIME_PACKET_MASTER_ANNOUNCEMENT:
            result = handleMasterAnnouncement(&pkt.p.master_announcement,
                                              srcAddr);
            break;

        default: {
            char srcEPStr[64];
            sockaddrToString(srcAddr, true, srcEPStr, sizeof(srcEPStr));

            mBadPktLog.log(ANDROID_LOG_WARN, LOG_TAG,
                           "unknown packet type (%d) from %s",
                           pkt.packetType, srcEPStr);

            result = false;
        } break;
    }

    return result;
}

bool CommonTimeServer::handleTimeout() {
    // If we have no socket, then this must be a timeout to retry socket setup.
    if (mSocket < 0)
        return true;

    switch (mState) {
        case ICommonClock::STATE_INITIAL:
            return handleTimeoutInitial();
        case ICommonClock::STATE_CLIENT:
            return handleTimeoutClient();
        case ICommonClock::STATE_MASTER:
            return handleTimeoutMaster();
        case ICommonClock::STATE_RONIN:
            return handleTimeoutRonin();
        case ICommonClock::STATE_WAIT_FOR_ELECTION:
            return handleTimeoutWaitForElection();
    }

    return false;
}

bool CommonTimeServer::handleTimeoutInitial() {
    if (++mInitial_WhoIsMasterRequestTimeouts ==
            kInitial_NumWhoIsMasterRetries) {
        // none of our attempts to discover a master succeeded, so make
        // this device the master
        return becomeMaster("initial timeout");
    } else {
        // retry the WhoIsMaster request
        return sendWhoIsMasterRequest();
    }
}

bool CommonTimeServer::handleTimeoutClient() {
    if (shouldPanicNotGettingGoodData())
        return becomeInitial("timeout panic, no good data");

    if (mClient_SyncRequestPending) {
        mClient_SyncRequestPending = false;

        if (++mClient_SyncRequestTimeouts < kClient_NumSyncRequestRetries) {
            // a sync request has timed out, so retry
            return sendSyncRequest();
        } else {
            // The master has failed to respond to a sync request for too many
            // times in a row.  Assume the master is dead and start electing
            // a new master.
            return becomeRonin("master not responding");
        }
    } else {
        // initiate the next sync request
        return sendSyncRequest();
    }
}

bool CommonTimeServer::handleTimeoutMaster() {
    // send another announcement from the master
    return sendMasterAnnouncement();
}

bool CommonTimeServer::handleTimeoutRonin() {
    if (++mRonin_WhoIsMasterRequestTimeouts == kRonin_NumWhoIsMasterRetries) {
        // no other master is out there, so we won the election
        return becomeMaster("no better masters detected");
    } else {
        return sendWhoIsMasterRequest();
    }
}

bool CommonTimeServer::handleTimeoutWaitForElection() {
    return becomeRonin("timeout waiting for election conclusion");
}

bool CommonTimeServer::handleWhoIsMasterRequest(
        const WhoIsMasterRequestPacket* request,
        const sockaddr_storage& srcAddr) {

    char srcEPStr[64];
    sockaddrToString(srcAddr, true, srcEPStr, sizeof(srcEPStr));
    mElectionLog.log("RXed WhoIs master request while in state %s.  "
                     "src %s reqTID %016llx ourTID %016llx",
                     stateToString(mState), srcEPStr,
                     request->timelineID, mTimelineID);

    if (mState == ICommonClock::STATE_MASTER) {
        // is this request related to this master's timeline?
        if (request->timelineID != ICommonClock::kInvalidTimelineID &&
            request->timelineID != mTimelineID)
            return true;

        WhoIsMasterResponsePacket pkt;
        pkt.initHeader(mTimelineID, mSyncGroupID);
        pkt.deviceID = mDeviceID;
        pkt.devicePriority = effectivePriority();

        mElectionLog.log("TXing WhoIs master resp to %s while in state %s.  "
                         "ourTID %016llx ourGID %016llx ourDID %016llx "
                         "ourPrio %u",
                         srcEPStr, stateToString(mState),
                         mTimelineID, mSyncGroupID,
                         pkt.deviceID, pkt.devicePriority);

        uint8_t buf[256];
        ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
        if (bufSz < 0)
            return false;

        ssize_t sendBytes = sendto(
                mSocket, buf, bufSz, 0,
                reinterpret_cast<const sockaddr *>(&srcAddr),
                sizeof(srcAddr));
        if (sendBytes == -1) {
            ALOGE("%s:%d sendto failed", __PRETTY_FUNCTION__, __LINE__);
            return false;
        }
    } else if (mState == ICommonClock::STATE_RONIN) {
        // if we hear a WhoIsMaster request from another device following
        // the same timeline and that device wins arbitration, then we will stop
        // trying to elect ourselves master and will instead wait for an
        // announcement from the election winner
        if (request->timelineID != mTimelineID)
            return true;

        if (arbitrateMaster(request->senderDeviceID,
                            request->senderDevicePriority,
                            mDeviceID,
                            effectivePriority()))
            return becomeWaitForElection("would lose election");

        return true;
    } else if (mState == ICommonClock::STATE_INITIAL) {
        // If a group of devices booted simultaneously (e.g. after a power
        // outage) and all of them are in the initial state and there is no
        // master, then each device may time out and declare itself master at
        // the same time.  To avoid this, listen for
        // WhoIsMaster(InvalidTimeline) requests from peers.  If we would lose
        // arbitration against that peer, reset our timeout count so that the
        // peer has a chance to become master before we time out.
        if (request->timelineID == ICommonClock::kInvalidTimelineID &&
                arbitrateMaster(request->senderDeviceID,
                                request->senderDevicePriority,
                                mDeviceID,
                                effectivePriority())) {
            mInitial_WhoIsMasterRequestTimeouts = 0;
        }
    }

    return true;
}

bool CommonTimeServer::handleWhoIsMasterResponse(
        const WhoIsMasterResponsePacket* response,
        const sockaddr_storage& srcAddr) {
    char srcEPStr[64];
    sockaddrToString(srcAddr, true, srcEPStr, sizeof(srcEPStr));
    mElectionLog.log("RXed WhoIs master response while in state %s.  "
                     "src %s respTID %016llx respDID %016llx respPrio %u "
                     "ourTID %016llx",
                     stateToString(mState), srcEPStr,
                     response->timelineID,
                     response->deviceID,
                     static_cast<uint32_t>(response->devicePriority),
                     mTimelineID);

    if (mState == ICommonClock::STATE_INITIAL || mState == ICommonClock::STATE_RONIN) {
        return becomeClient(srcAddr,
                            response->deviceID,
                            response->devicePriority,
                            response->timelineID,
                            "heard whois response");
    } else if (mState == ICommonClock::STATE_CLIENT) {
        // if we get multiple responses because there are multiple devices
        // who believe that they are master, then follow the master that
        // wins arbitration
        if (arbitrateMaster(response->deviceID,
                            response->devicePriority,
                            mClient_MasterDeviceID,
                            mClient_MasterDevicePriority)) {
            return becomeClient(srcAddr,
                                response->deviceID,
                                response->devicePriority,
                                response->timelineID,
                                "heard whois response");
        }
    }

    return true;
}

bool CommonTimeServer::handleSyncRequest(const SyncRequestPacket* request,
                                         const sockaddr_storage& srcAddr) {
    SyncResponsePacket pkt;
    pkt.initHeader(mTimelineID, mSyncGroupID);

    if ((mState == ICommonClock::STATE_MASTER) &&
        (mTimelineID == request->timelineID)) {
        int64_t rxLocalTime = mLastPacketRxLocalTime;
        int64_t rxCommonTime;

        // If we are master on an actual network and have actual clients, then
        // we are no longer low priority.
        setForceLowPriority(false);

        if (OK != mCommonClock.localToCommon(rxLocalTime, &rxCommonTime)) {
            return false;
        }

        int64_t txLocalTime = mLocalClock.getLocalTime();;
        int64_t txCommonTime;
        if (OK != mCommonClock.localToCommon(txLocalTime, &txCommonTime)) {
            return false;
        }

        pkt.nak = 0;
        pkt.clientTxLocalTime  = request->clientTxLocalTime;
        pkt.masterRxCommonTime = rxCommonTime;
        pkt.masterTxCommonTime = txCommonTime;
    } else {
        pkt.nak = 1;
        pkt.clientTxLocalTime  = 0;
        pkt.masterRxCommonTime = 0;
        pkt.masterTxCommonTime = 0;
    }

    uint8_t buf[256];
    ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
    if (bufSz < 0)
        return false;

    ssize_t sendBytes = sendto(
            mSocket, &buf, bufSz, 0,
            reinterpret_cast<const sockaddr *>(&srcAddr),
            sizeof(srcAddr));
    if (sendBytes == -1) {
        ALOGE("%s:%d sendto failed", __PRETTY_FUNCTION__, __LINE__);
        return false;
    }

    return true;
}

bool CommonTimeServer::handleSyncResponse(
        const SyncResponsePacket* response,
        const sockaddr_storage& srcAddr) {
    if (mState != ICommonClock::STATE_CLIENT)
        return true;

    assert(mMasterEPValid);
    if (!sockaddrMatch(srcAddr, mMasterEP, true)) {
        char srcEP[64], expectedEP[64];
        sockaddrToString(srcAddr, true, srcEP, sizeof(srcEP));
        sockaddrToString(mMasterEP, true, expectedEP, sizeof(expectedEP));
        ALOGI("Dropping sync response from unexpected address."
             " Expected %s Got %s", expectedEP, srcEP);
        return true;
    }

    if (response->nak) {
        // if our master is no longer accepting requests, then we need to find
        // a new master
        return becomeRonin("master NAK'ed");
    }

    mClient_SyncRequestPending = 0;
    mClient_SyncRequestTimeouts = 0;
    mClient_PacketRTTLog.logRX(response->clientTxLocalTime,
                               mLastPacketRxLocalTime);

    bool result;
    if (!(mClient_SyncRespsRXedFromCurMaster++)) {
        // the first request/response exchange between a client and a master
        // may take unusually long due to ARP, so discard it.
        result = true;
    } else {
        int64_t clientTxLocalTime  = response->clientTxLocalTime;
        int64_t clientRxLocalTime  = mLastPacketRxLocalTime;
        int64_t masterTxCommonTime = response->masterTxCommonTime;
        int64_t masterRxCommonTime = response->masterRxCommonTime;

        int64_t rtt       = (clientRxLocalTime - clientTxLocalTime);
        int64_t avgLocal  = (clientTxLocalTime + clientRxLocalTime) >> 1;
        int64_t avgCommon = (masterTxCommonTime + masterRxCommonTime) >> 1;

        // if the RTT of the packet is significantly larger than the panic
        // threshold, we should simply discard it.  Its better to do nothing
        // than to take cues from a packet like that.
        int rttCommon = mCommonClock.localDurationToCommonDuration(rtt);
        if (rttCommon > (static_cast<int64_t>(mPanicThresholdUsec) * 
                         kRTTDiscardPanicThreshMultiplier)) {
            ALOGV("Dropping sync response with RTT of %lld uSec", rttCommon);
            mClient_ExpiredSyncRespsRXedFromCurMaster++;
            if (shouldPanicNotGettingGoodData())
                return becomeInitial("RX panic, no good data");
        } else {
            result = mClockRecovery.pushDisciplineEvent(avgLocal, avgCommon, rttCommon);
            mClient_LastGoodSyncRX = clientRxLocalTime;

            if (result) {
                // indicate to listeners that we've synced to the common timeline
                notifyClockSync();
            } else {
                ALOGE("Panic!  Observed clock sync error is too high to tolerate,"
                        " resetting state machine and starting over.");
                notifyClockSyncLoss();
                return becomeInitial("panic");
            }
        }
    }

    mCurTimeout.setTimeout(mSyncRequestIntervalMs);
    return result;
}

bool CommonTimeServer::handleMasterAnnouncement(
        const MasterAnnouncementPacket* packet,
        const sockaddr_storage& srcAddr) {
    uint64_t newDeviceID   = packet->deviceID;
    uint8_t  newDevicePrio = packet->devicePriority;
    uint64_t newTimelineID = packet->timelineID;

    char srcEPStr[64];
    sockaddrToString(srcAddr, true, srcEPStr, sizeof(srcEPStr));
    mElectionLog.log("RXed master announcement while in state %s.  "
                     "src %s srcDevID %lld srcPrio %u srcTID %016llx",
                     stateToString(mState), srcEPStr,
                     newDeviceID, static_cast<uint32_t>(newDevicePrio),
                     newTimelineID);

    if (mState == ICommonClock::STATE_INITIAL ||
        mState == ICommonClock::STATE_RONIN ||
        mState == ICommonClock::STATE_WAIT_FOR_ELECTION) {
        // if we aren't currently following a master, then start following
        // this new master
        return becomeClient(srcAddr,
                            newDeviceID,
                            newDevicePrio,
                            newTimelineID,
                            "heard master announcement");
    } else if (mState == ICommonClock::STATE_CLIENT) {
        // if the new master wins arbitration against our current master,
        // then become a client of the new master
        if (arbitrateMaster(newDeviceID,
                            newDevicePrio,
                            mClient_MasterDeviceID,
                            mClient_MasterDevicePriority))
            return becomeClient(srcAddr,
                                newDeviceID,
                                newDevicePrio,
                                newTimelineID,
                                "heard master announcement");
    } else if (mState == ICommonClock::STATE_MASTER) {
        // two masters are competing - if the new one wins arbitration, then
        // cease acting as master
        if (arbitrateMaster(newDeviceID, newDevicePrio,
                            mDeviceID, effectivePriority()))
            return becomeClient(srcAddr, newDeviceID,
                                newDevicePrio, newTimelineID,
                                "heard master announcement");
    }

    return true;
}

bool CommonTimeServer::sendWhoIsMasterRequest() {
    assert(mState == ICommonClock::STATE_INITIAL || mState == ICommonClock::STATE_RONIN);

    // If we have no socket, then we must be in the unconfigured initial state.
    // Don't report any errors, just don't try to send the initial who-is-master
    // query.  Eventually, our network will either become configured, or we will
    // be forced into network-less master mode by higher level code.
    if (mSocket < 0) {
        assert(mState == ICommonClock::STATE_INITIAL);
        return true;
    }

    bool ret = false;
    WhoIsMasterRequestPacket pkt;
    pkt.initHeader(mSyncGroupID);
    pkt.senderDeviceID = mDeviceID;
    pkt.senderDevicePriority = effectivePriority();

    uint8_t buf[256];
    ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
    if (bufSz >= 0) {
        char dstEPStr[64];
        sockaddrToString(mMasterElectionEP, true, dstEPStr, sizeof(dstEPStr));
        mElectionLog.log("TXing WhoIs master request to %s while in state %s.  "
                         "ourTID %016llx ourGID %016llx ourDID %016llx "
                         "ourPrio %u",
                         dstEPStr, stateToString(mState),
                         mTimelineID, mSyncGroupID,
                         pkt.senderDeviceID, pkt.senderDevicePriority);

        ssize_t sendBytes = sendto(
                mSocket, buf, bufSz, 0,
                reinterpret_cast<const sockaddr *>(&mMasterElectionEP),
                sizeof(mMasterElectionEP));
        if (sendBytes < 0)
            ALOGE("WhoIsMaster sendto failed (errno %d)", errno);
        ret = true;
    }

    if (mState == ICommonClock::STATE_INITIAL) {
        mCurTimeout.setTimeout(kInitial_WhoIsMasterTimeoutMs);
    } else {
        mCurTimeout.setTimeout(kRonin_WhoIsMasterTimeoutMs);
    }

    return ret;
}

bool CommonTimeServer::sendSyncRequest() {
    // If we are sending sync requests, then we must be in the client state and
    // we must have a socket (when we have no network, we are only supposed to
    // be in INITIAL or MASTER)
    assert(mState == ICommonClock::STATE_CLIENT);
    assert(mSocket >= 0);

    bool ret = false;
    SyncRequestPacket pkt;
    pkt.initHeader(mTimelineID, mSyncGroupID);
    pkt.clientTxLocalTime = mLocalClock.getLocalTime();

    if (!mClient_FirstSyncTX)
        mClient_FirstSyncTX = pkt.clientTxLocalTime;

    mClient_PacketRTTLog.logTX(pkt.clientTxLocalTime);

    uint8_t buf[256];
    ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
    if (bufSz >= 0) {
        ssize_t sendBytes = sendto(
                mSocket, buf, bufSz, 0,
                reinterpret_cast<const sockaddr *>(&mMasterEP),
                sizeof(mMasterEP));
        if (sendBytes < 0)
            ALOGE("SyncRequest sendto failed (errno %d)", errno);
        ret = true;
    }

    mClient_SyncsSentToCurMaster++;
    mCurTimeout.setTimeout(mSyncRequestIntervalMs);
    mClient_SyncRequestPending = true;

    return ret;
}

bool CommonTimeServer::sendMasterAnnouncement() {
    bool ret = false;
    assert(mState == ICommonClock::STATE_MASTER);

    // If we are being asked to send a master announcement, but we have no
    // socket, we must be in network-less master mode.  Don't bother to send the
    // announcement, and don't bother to schedule a timeout.  When the network
    // comes up, the work thread will get poked and start the process of
    // figuring out who the current master should be.
    if (mSocket < 0) {
        mCurTimeout.setTimeout(kInfiniteTimeout);
        return true;
    }

    MasterAnnouncementPacket pkt;
    pkt.initHeader(mTimelineID, mSyncGroupID);
    pkt.deviceID = mDeviceID;
    pkt.devicePriority = effectivePriority();

    uint8_t buf[256];
    ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
    if (bufSz >= 0) {
        char dstEPStr[64];
        sockaddrToString(mMasterElectionEP, true, dstEPStr, sizeof(dstEPStr));
        mElectionLog.log("TXing Master announcement to %s while in state %s.  "
                         "ourTID %016llx ourGID %016llx ourDID %016llx "
                         "ourPrio %u",
                         dstEPStr, stateToString(mState),
                         mTimelineID, mSyncGroupID,
                         pkt.deviceID, pkt.devicePriority);

        ssize_t sendBytes = sendto(
                mSocket, buf, bufSz, 0,
                reinterpret_cast<const sockaddr *>(&mMasterElectionEP),
                sizeof(mMasterElectionEP));
        if (sendBytes < 0)
            ALOGE("MasterAnnouncement sendto failed (errno %d)", errno);
        ret = true;
    }

    mCurTimeout.setTimeout(mMasterAnnounceIntervalMs);
    return ret;
}

bool CommonTimeServer::becomeClient(const sockaddr_storage& masterEP,
                                    uint64_t masterDeviceID,
                                    uint8_t  masterDevicePriority,
                                    uint64_t timelineID,
                                    const char* cause) {
    char newEPStr[64], oldEPStr[64];
    sockaddrToString(masterEP, true, newEPStr, sizeof(newEPStr));
    sockaddrToString(mMasterEP, mMasterEPValid, oldEPStr, sizeof(oldEPStr));

    mStateChangeLog.log(ANDROID_LOG_INFO, LOG_TAG,
            "%s --> CLIENT (%s) :%s"
            " OldMaster: %02x-%014llx::%016llx::%s"
            " NewMaster: %02x-%014llx::%016llx::%s",
            stateToString(mState), cause,
            (mTimelineID != timelineID) ? " (new timeline)" : "",
            mClient_MasterDevicePriority, mClient_MasterDeviceID,
            mTimelineID, oldEPStr,
            masterDevicePriority, masterDeviceID,
            timelineID, newEPStr);

    if (mTimelineID != timelineID) {
        // start following a new timeline
        mTimelineID = timelineID;
        mClockRecovery.reset(true, true);
        notifyClockSyncLoss();
    } else {
        // start following a new master on the existing timeline
        mClockRecovery.reset(false, true);
    }

    mMasterEP = masterEP;
    mMasterEPValid = true;

    // If we are on a real network as a client of a real master, then we should
    // no longer force low priority.  If our master disappears, we should have
    // the high priority bit set during the election to replace the master
    // because this group was a real group and not a singleton created in
    // networkless mode.
    setForceLowPriority(false);

    mClient_MasterDeviceID = masterDeviceID;
    mClient_MasterDevicePriority = masterDevicePriority;
    resetSyncStats();

    setState(ICommonClock::STATE_CLIENT);

    // add some jitter to when the various clients send their requests
    // in order to reduce the likelihood that a group of clients overload
    // the master after receiving a master announcement
    usleep((lrand48() % 100) * 1000);

    return sendSyncRequest();
}

bool CommonTimeServer::becomeMaster(const char* cause) {
    uint64_t oldTimelineID = mTimelineID;
    if (mTimelineID == ICommonClock::kInvalidTimelineID) {
        // this device has not been following any existing timeline,
        // so it will create a new timeline and declare itself master
        assert(!mCommonClock.isValid());

        // set the common time basis
        mCommonClock.setBasis(mLocalClock.getLocalTime(), 0);

        // assign an arbitrary timeline iD
        assignTimelineID();

        // notify listeners that we've created a common timeline
        notifyClockSync();
    }

    mStateChangeLog.log(ANDROID_LOG_INFO, LOG_TAG,
            "%s --> MASTER (%s) : %s timeline %016llx",
            stateToString(mState), cause,
            (oldTimelineID == mTimelineID) ? "taking ownership of"
                                           : "creating new",
            mTimelineID);

    memset(&mMasterEP, 0, sizeof(mMasterEP));
    mMasterEPValid = false;
    mClient_MasterDevicePriority = effectivePriority();
    mClient_MasterDeviceID = mDeviceID;
    mClockRecovery.reset(false, true);
    resetSyncStats();

    setState(ICommonClock::STATE_MASTER);
    return sendMasterAnnouncement();
}

bool CommonTimeServer::becomeRonin(const char* cause) {
    // If we were the client of a given timeline, but had never received even a
    // single time sync packet, then we transition back to Initial instead of
    // Ronin.  If we transition to Ronin and end up becoming the new Master, we
    // will be unable to service requests for other clients because we never
    // actually knew what time it was.  By going to initial, we ensure that
    // other clients who know what time it is, but would lose master arbitration
    // in the Ronin case, will step up and become the proper new master of the
    // old timeline.

    char oldEPStr[64];
    sockaddrToString(mMasterEP, mMasterEPValid, oldEPStr, sizeof(oldEPStr));
    memset(&mMasterEP, 0, sizeof(mMasterEP));
    mMasterEPValid = false;

    if (mCommonClock.isValid()) {
        mStateChangeLog.log(ANDROID_LOG_INFO, LOG_TAG,
             "%s --> RONIN (%s) : lost track of previously valid timeline "
             "%02x-%014llx::%016llx::%s (%d TXed %d RXed %d RXExpired)",
             stateToString(mState), cause,
             mClient_MasterDevicePriority, mClient_MasterDeviceID,
             mTimelineID, oldEPStr,
             mClient_SyncsSentToCurMaster,
             mClient_SyncRespsRXedFromCurMaster,
             mClient_ExpiredSyncRespsRXedFromCurMaster);

        mRonin_WhoIsMasterRequestTimeouts = 0;
        setState(ICommonClock::STATE_RONIN);
        return sendWhoIsMasterRequest();
    } else {
        mStateChangeLog.log(ANDROID_LOG_INFO, LOG_TAG,
             "%s --> INITIAL (%s) : never synced timeline "
             "%02x-%014llx::%016llx::%s (%d TXed %d RXed %d RXExpired)",
             stateToString(mState), cause,
             mClient_MasterDevicePriority, mClient_MasterDeviceID,
             mTimelineID, oldEPStr,
             mClient_SyncsSentToCurMaster,
             mClient_SyncRespsRXedFromCurMaster,
             mClient_ExpiredSyncRespsRXedFromCurMaster);

        return becomeInitial("ronin, no timeline");
    }
}

bool CommonTimeServer::becomeWaitForElection(const char* cause) {
    mStateChangeLog.log(ANDROID_LOG_INFO, LOG_TAG,
         "%s --> WAIT_FOR_ELECTION (%s) : dropping out of election,"
         " waiting %d mSec for completion.",
         stateToString(mState), cause, kWaitForElection_TimeoutMs);

    setState(ICommonClock::STATE_WAIT_FOR_ELECTION);
    mCurTimeout.setTimeout(kWaitForElection_TimeoutMs);
    return true;
}

bool CommonTimeServer::becomeInitial(const char* cause) {
    mStateChangeLog.log(ANDROID_LOG_INFO, LOG_TAG,
                        "Entering INITIAL (%s), total reset.",
                        cause);

    setState(ICommonClock::STATE_INITIAL);

    // reset clock recovery
    mClockRecovery.reset(true, true);

    // reset internal state bookkeeping.
    mCurTimeout.setTimeout(kInfiniteTimeout);
    memset(&mMasterEP, 0, sizeof(mMasterEP));
    mMasterEPValid = false;
    mLastPacketRxLocalTime = 0;
    mTimelineID = ICommonClock::kInvalidTimelineID;
    mClockSynced = false;
    mInitial_WhoIsMasterRequestTimeouts = 0;
    mClient_MasterDeviceID = 0;
    mClient_MasterDevicePriority = 0;
    mRonin_WhoIsMasterRequestTimeouts = 0;
    resetSyncStats();

    // send the first request to discover the master
    return sendWhoIsMasterRequest();
}

void CommonTimeServer::notifyClockSync() {
    if (!mClockSynced) {
        mClockSynced = true;
        mICommonClock->notifyOnTimelineChanged(mTimelineID);
    }
}

void CommonTimeServer::notifyClockSyncLoss() {
    if (mClockSynced) {
        mClockSynced = false;
        mICommonClock->notifyOnTimelineChanged(
                ICommonClock::kInvalidTimelineID);
    }
}

void CommonTimeServer::setState(ICommonClock::State s) {
    mState = s;
}

const char* CommonTimeServer::stateToString(ICommonClock::State s) {
    switch(s) {
        case ICommonClock::STATE_INITIAL:
            return "INITIAL";
        case ICommonClock::STATE_CLIENT:
            return "CLIENT";
        case ICommonClock::STATE_MASTER:
            return "MASTER";
        case ICommonClock::STATE_RONIN:
            return "RONIN";
        case ICommonClock::STATE_WAIT_FOR_ELECTION:
            return "WAIT_FOR_ELECTION";
        default:
            return "unknown";
    }
}

void CommonTimeServer::sockaddrToString(const sockaddr_storage& addr,
                                        bool addrValid,
                                        char* buf, size_t bufLen) {
    if (!bufLen || !buf)
        return;

    if (addrValid) {
        switch (addr.ss_family) {
            case AF_INET: {
                const struct sockaddr_in* sa =
                    reinterpret_cast<const struct sockaddr_in*>(&addr);
                unsigned long a = ntohl(sa->sin_addr.s_addr);
                uint16_t      p = ntohs(sa->sin_port);
                snprintf(buf, bufLen, "%lu.%lu.%lu.%lu:%hu",
                        ((a >> 24) & 0xFF), ((a >> 16) & 0xFF),
                        ((a >>  8) & 0xFF),  (a        & 0xFF), p);
            } break;

            case AF_INET6: {
                const struct sockaddr_in6* sa =
                    reinterpret_cast<const struct sockaddr_in6*>(&addr);
                const uint8_t* a = sa->sin6_addr.s6_addr;
                uint16_t       p = ntohs(sa->sin6_port);
                snprintf(buf, bufLen,
                        "%02X%02X:%02X%02X:%02X%02X:%02X%02X:"
                        "%02X%02X:%02X%02X:%02X%02X:%02X%02X port %hd",
                        a[0], a[1], a[ 2], a[ 3], a[ 4], a[ 5], a[ 6], a[ 7],
                        a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15],
                        p);
            } break;

            default:
                snprintf(buf, bufLen,
                         "<unknown sockaddr family %d>", addr.ss_family);
                break;
        }
    } else {
        snprintf(buf, bufLen, "<none>");
    }

    buf[bufLen - 1] = 0;
}

bool CommonTimeServer::sockaddrMatch(const sockaddr_storage& a1,
                                     const sockaddr_storage& a2,
                                     bool matchAddressOnly) {
    if (a1.ss_family != a2.ss_family)
        return false;

    switch (a1.ss_family) {
        case AF_INET: {
            const struct sockaddr_in* sa1 =
                reinterpret_cast<const struct sockaddr_in*>(&a1);
            const struct sockaddr_in* sa2 =
                reinterpret_cast<const struct sockaddr_in*>(&a2);

            if (sa1->sin_addr.s_addr != sa2->sin_addr.s_addr)
                return false;

            return (matchAddressOnly || (sa1->sin_port == sa2->sin_port));
        } break;

        case AF_INET6: {
            const struct sockaddr_in6* sa1 =
                reinterpret_cast<const struct sockaddr_in6*>(&a1);
            const struct sockaddr_in6* sa2 =
                reinterpret_cast<const struct sockaddr_in6*>(&a2);

            if (memcmp(&sa1->sin6_addr, &sa2->sin6_addr, sizeof(sa2->sin6_addr)))
                return false;

            return (matchAddressOnly || (sa1->sin6_port == sa2->sin6_port));
        } break;

        // Huh?  We don't deal in non-IPv[46] addresses.  Not sure how we got
        // here, but we don't know how to comapre these addresses and simply
        // default to a no-match decision.
        default: return false;
    }
}

bool CommonTimeServer::shouldPanicNotGettingGoodData() {
    if (mClient_FirstSyncTX) {
        int64_t now = mLocalClock.getLocalTime();
        int64_t delta = now - (mClient_LastGoodSyncRX
                             ? mClient_LastGoodSyncRX
                             : mClient_FirstSyncTX);
        int64_t deltaUsec = mCommonClock.localDurationToCommonDuration(delta);

        if (deltaUsec >= kNoGoodDataPanicThresholdUsec)
            return true;
    }

    return false;
}

void CommonTimeServer::PacketRTTLog::logTX(int64_t txTime) {
    txTimes[wrPtr] = txTime;
    rxTimes[wrPtr] = 0;
    wrPtr = (wrPtr + 1) % RTT_LOG_SIZE;
    if (!wrPtr)
        logFull = true;
}

void CommonTimeServer::PacketRTTLog::logRX(int64_t txTime, int64_t rxTime) {
    if (!logFull && !wrPtr)
        return;

    uint32_t i = logFull ? wrPtr : 0;
    do {
        if (txTimes[i] == txTime) {
            rxTimes[i] = rxTime;
            break;
        }
        i = (i + 1) % RTT_LOG_SIZE;
    } while (i != wrPtr);
}

}  // namespace android
