16c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen/*
26c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * Copyright (C) 2012 The Android Open Source Project
36c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen *
46c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * Licensed under the Apache License, Version 2.0 (the "License");
56c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * you may not use this file except in compliance with the License.
66c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * You may obtain a copy of the License at
76c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen *
86c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen *      http://www.apache.org/licenses/LICENSE-2.0
96c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen *
106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * Unless required by applicable law or agreed to in writing, software
116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * distributed under the License is distributed on an "AS IS" BASIS,
126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * See the License for the specific language governing permissions and
146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * limitations under the License.
156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen */
166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen/*
186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * A service that exchanges time synchronization information between
196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * a master that defines a timeline and clients that follow the timeline.
206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen */
216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#define LOG_TAG "common_time"
236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <utils/Log.h>
246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <arpa/inet.h>
266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <assert.h>
276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <fcntl.h>
286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <linux/if_ether.h>
296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <net/if.h>
306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <net/if_arp.h>
316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <netinet/ip.h>
326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <poll.h>
336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <stdio.h>
346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <sys/eventfd.h>
356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <sys/ioctl.h>
366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <sys/stat.h>
376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <sys/types.h>
386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <sys/socket.h>
396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <common_time/local_clock.h>
416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <binder/IPCThreadState.h>
426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <binder/ProcessState.h>
436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <utils/Timers.h>
446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include "common_clock_service.h"
466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include "common_time_config_service.h"
476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include "common_time_server.h"
486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include "common_time_server_packets.h"
496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include "clock_recovery.h"
506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include "common_clock.h"
516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
52b8525e9a76d63a2dc26c87577940a058e70e3dd5John Grossman#define MAX_INT ((int)0x7FFFFFFF)
536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chennamespace android {
556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst char*    CommonTimeServer::kDefaultMasterElectionAddr = "239.195.128.88";
576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst uint16_t CommonTimeServer::kDefaultMasterElectionPort = 8887;
586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst uint64_t CommonTimeServer::kDefaultSyncGroupID = 0;
596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst uint8_t  CommonTimeServer::kDefaultMasterPriority = 1;
606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst uint32_t CommonTimeServer::kDefaultMasterAnnounceIntervalMs = 10000;
616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst uint32_t CommonTimeServer::kDefaultSyncRequestIntervalMs = 1000;
626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst uint32_t CommonTimeServer::kDefaultPanicThresholdUsec = 50000;
636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst bool     CommonTimeServer::kDefaultAutoDisable = true;
646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst int      CommonTimeServer::kSetupRetryTimeoutMs = 30000;
656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst int64_t  CommonTimeServer::kNoGoodDataPanicThresholdUsec = 600000000ll;
666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst uint32_t CommonTimeServer::kRTTDiscardPanicThreshMultiplier = 5;
676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// timeout value representing an infinite timeout
696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst int CommonTimeServer::kInfiniteTimeout = -1;
706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen/*** Initial state constants ***/
726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// number of WhoIsMaster attempts sent before giving up
746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst int CommonTimeServer::kInitial_NumWhoIsMasterRetries = 6;
756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// timeout used when waiting for a response to a WhoIsMaster request
776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst int CommonTimeServer::kInitial_WhoIsMasterTimeoutMs = 500;
786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen/*** Client state constants ***/
806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// number of sync requests that can fail before a client assumes its master
826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// is dead
83e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossmanconst int CommonTimeServer::kClient_NumSyncRequestRetries = 10;
846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen/*** Master state constants ***/
866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen/*** Ronin state constants ***/
886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// number of WhoIsMaster attempts sent before declaring ourselves master
90e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossmanconst int CommonTimeServer::kRonin_NumWhoIsMasterRetries = 20;
916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// timeout used when waiting for a response to a WhoIsMaster request
936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst int CommonTimeServer::kRonin_WhoIsMasterTimeoutMs = 500;
946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen/*** WaitForElection state constants ***/
966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// how long do we wait for an announcement from a master before
986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// trying another election?
99e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossmanconst int CommonTimeServer::kWaitForElection_TimeoutMs = 12500;
1006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1016c929510474caa14dc9d56826b2c65552861d6b3Mike J. ChenCommonTimeServer::CommonTimeServer()
1026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    : Thread(false)
1036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    , mState(ICommonClock::STATE_INITIAL)
1046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    , mClockRecovery(&mLocalClock, &mCommonClock)
1056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    , mSocket(-1)
1066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    , mLastPacketRxLocalTime(0)
1076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    , mTimelineID(ICommonClock::kInvalidTimelineID)
1086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    , mClockSynced(false)
1096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    , mCommonClockHasClients(false)
1106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    , mInitial_WhoIsMasterRequestTimeouts(0)
1116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    , mClient_MasterDeviceID(0)
1126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    , mClient_MasterDevicePriority(0)
1136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    , mRonin_WhoIsMasterRequestTimeouts(0) {
1146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // zero out sync stats
1156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    resetSyncStats();
1166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Setup the master election endpoint to use the default.
1186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    struct sockaddr_in* meep =
1196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        reinterpret_cast<struct sockaddr_in*>(&mMasterElectionEP);
1206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    memset(&mMasterElectionEP, 0, sizeof(mMasterElectionEP));
1216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    inet_aton(kDefaultMasterElectionAddr, &meep->sin_addr);
1226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    meep->sin_family = AF_INET;
1236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    meep->sin_port   = htons(kDefaultMasterElectionPort);
1246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Zero out the master endpoint.
1266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    memset(&mMasterEP, 0, sizeof(mMasterEP));
1276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mMasterEPValid    = false;
1286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mBindIfaceValid   = false;
1296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    setForceLowPriority(false);
1306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Set all remaining configuration parameters to their defaults.
1326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mDeviceID                 = 0;
1336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mSyncGroupID              = kDefaultSyncGroupID;
1346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mMasterPriority           = kDefaultMasterPriority;
1356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mMasterAnnounceIntervalMs = kDefaultMasterAnnounceIntervalMs;
1366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mSyncRequestIntervalMs    = kDefaultSyncRequestIntervalMs;
1376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mPanicThresholdUsec       = kDefaultPanicThresholdUsec;
1386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mAutoDisable              = kDefaultAutoDisable;
1396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Create the eventfd we will use to signal our thread to wake up when
1416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // needed.
1426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mWakeupThreadFD = eventfd(0, EFD_NONBLOCK);
1436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // seed the random number generator (used to generated timeline IDs)
1456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    srand48(static_cast<unsigned int>(systemTime()));
1466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
1476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1486c929510474caa14dc9d56826b2c65552861d6b3Mike J. ChenCommonTimeServer::~CommonTimeServer() {
1496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    shutdownThread();
1506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // No need to grab the lock here.  We are in the destructor; if the the user
1526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // has a thread in any of the APIs while the destructor is being called,
1536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // there is a threading problem a the application level we cannot reasonably
1546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // do anything about.
1556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    cleanupSocket_l();
1566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mWakeupThreadFD >= 0) {
1586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        close(mWakeupThreadFD);
1596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mWakeupThreadFD = -1;
1606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
1616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
1626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::startServices() {
1646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // start the ICommonClock service
1656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mICommonClock = CommonClockService::instantiate(*this);
1666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mICommonClock == NULL)
1676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
1686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // start the ICommonTimeConfig service
1706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mICommonTimeConfig = CommonTimeConfigService::instantiate(*this);
1716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mICommonTimeConfig == NULL)
1726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
1736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return true;
1756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
1766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::threadLoop() {
1786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Register our service interfaces.
1796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!startServices())
1806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
1816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Hold the lock while we are in the main thread loop.  It will release the
1836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // lock when it blocks, and hold the lock at all other times.
1846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mLock.lock();
1856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    runStateMachine_l();
1866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mLock.unlock();
1876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    IPCThreadState::self()->stopProcess();
1896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return false;
1906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
1916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::runStateMachine_l() {
1936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!mLocalClock.initCheck())
1946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
1956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!mCommonClock.init(mLocalClock.getLocalFreq()))
1976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
1986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Enter the initial state.
2006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    becomeInitial("startup");
2016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // run the state machine
2036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    while (!exitPending()) {
2046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        struct pollfd pfds[2];
2056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int rc;
2066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int eventCnt = 0;
2076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int64_t wakeupTime;
2086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // We are always interested in our wakeup FD.
2106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        pfds[eventCnt].fd      = mWakeupThreadFD;
2116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        pfds[eventCnt].events  = POLLIN;
2126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        pfds[eventCnt].revents = 0;
2136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        eventCnt++;
2146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // If we have a valid socket, then we are interested in what it has to
2166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // say as well.
2176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (mSocket >= 0) {
2186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            pfds[eventCnt].fd      = mSocket;
2196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            pfds[eventCnt].events  = POLLIN;
2206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            pfds[eventCnt].revents = 0;
2216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            eventCnt++;
2226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
2236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // Note, we were holding mLock when this function was called.  We
2256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // release it only while we are blocking and hold it at all other times.
2266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mLock.unlock();
2276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        rc          = poll(pfds, eventCnt, mCurTimeout.msecTillTimeout());
2286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        wakeupTime  = mLocalClock.getLocalTime();
2296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mLock.lock();
2306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // Is it time to shutdown?  If so, don't hesitate... just do it.
2326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (exitPending())
2336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            break;
2346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // Did the poll fail?  This should never happen and is fatal if it does.
2366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (rc < 0) {
2376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            ALOGE("%s:%d poll failed", __PRETTY_FUNCTION__, __LINE__);
2386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return false;
2396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
2406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (rc == 0)
2426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            mCurTimeout.setTimeout(kInfiniteTimeout);
2436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // Were we woken up on purpose?  If so, clear the eventfd with a read.
2456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (pfds[0].revents)
2466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            clearPendingWakeupEvents_l();
2476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // Is out bind address dirty?  If so, clean up our socket (if any).
2496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // Alternatively, do we have an active socket but should be auto
2506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // disabled?  If so, release the socket and enter the proper sync state.
2516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        bool droppedSocket = false;
2526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (mBindIfaceDirty || ((mSocket >= 0) && shouldAutoDisable())) {
2536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            cleanupSocket_l();
2546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            mBindIfaceDirty = false;
2556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            droppedSocket = true;
2566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
2576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // Do we not have a socket but should have one?  If so, try to set one
2596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // up.
2606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if ((mSocket < 0) && mBindIfaceValid && !shouldAutoDisable()) {
2616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            if (setupSocket_l()) {
2626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                // Success!  We are now joining a new network (either coming
2636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                // from no network, or coming from a potentially different
2646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                // network).  Force our priority to be lower so that we defer to
2656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                // any other masters which may already be on the network we are
2666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                // joining.  Later, when we enter either the client or the
2676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                // master state, we will clear this flag and go back to our
2686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                // normal election priority.
2696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                setForceLowPriority(true);
2706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                switch (mState) {
2716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // If we were in initial (whether we had a immediately
2726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // before this network or not) we want to simply reset the
2736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // system and start again.  Forcing a transition from
2746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // INITIAL to INITIAL should do the job.
2756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    case CommonClockService::STATE_INITIAL:
2766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        becomeInitial("bound interface");
2776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        break;
2786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // If we were in the master state, then either we were the
2806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // master in a no-network situation, or we were the master
2816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // of a different network and have moved to a new interface.
282e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman                    // In either case, immediately transition to Ronin at low
283e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman                    // priority.  If there is no one in the network we just
284e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman                    // joined, we will become master soon enough.  If there is,
285e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman                    // we want to be certain to defer master status to the
286e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman                    // existing timeline currently running on the network.
287e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman                    //
2886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    case CommonClockService::STATE_MASTER:
289e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman                        becomeRonin("leaving networkless mode");
2906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        break;
2916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // If we were in any other state (CLIENT, RONIN, or
2936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // WAIT_FOR_ELECTION) then we must be moving from one
2946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // network to another.  We have lost our old master;
2956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // transition to RONIN in an attempt to find a new master.
2966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // If there are none out there, we will just assume
2976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // responsibility for the timeline we used to be a client
2986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // of.
2996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    default:
3006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        becomeRonin("bound interface");
3016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        break;
3026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                }
3036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            } else {
3046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                // That's odd... we failed to set up our socket.  This could be
3056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                // due to some transient network change which will work itself
3066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                // out shortly; schedule a retry attempt in the near future.
3076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                mCurTimeout.setTimeout(kSetupRetryTimeoutMs);
3086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            }
3096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // One way or the other, we don't have any data to process at this
3116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // point (since we just tried to bulid a new socket).  Loop back
3126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // around and wait for the next thing to do.
3136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            continue;
3146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        } else if (droppedSocket) {
3156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // We just lost our socket, and for whatever reason (either no
3166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // config, or auto disable engaged) we are not supposed to rebuild
3176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // one at this time.  We are not going to rebuild our socket until
3186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // something about our config/auto-disabled status changes, so we
3196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // are basically in network-less mode.  If we are already in either
3206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // INITIAL or MASTER, just stay there until something changes.  If
3216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // we are in any other state (CLIENT, RONIN or WAIT_FOR_ELECTION),
3226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // then transition to either INITIAL or MASTER depending on whether
3236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // or not our timeline is valid.
3246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            ALOGI("Entering networkless mode interface is %s, "
3256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                 "shouldAutoDisable = %s",
3266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                 mBindIfaceValid ? "valid" : "invalid",
3276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                 shouldAutoDisable() ? "true" : "false");
3286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            if ((mState != ICommonClock::STATE_INITIAL) &&
3296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                (mState != ICommonClock::STATE_MASTER)) {
3306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                if (mTimelineID == ICommonClock::kInvalidTimelineID)
3316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    becomeInitial("network-less mode");
3326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                else
3336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    becomeMaster("network-less mode");
3346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            }
3356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            continue;
3376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
3386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // Did we wakeup with no signalled events across all of our FDs?  If so,
3406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // we must have hit our timeout.
3416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (rc == 0) {
3426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            if (!handleTimeout())
3436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                ALOGE("handleTimeout failed");
3446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            continue;
3456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
3466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // Does our socket have data for us (assuming we still have one, we
3486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // may have RXed a packet at the same time as a config change telling us
3496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // to shut our socket down)?  If so, process its data.
3506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if ((mSocket >= 0) && (eventCnt > 1) && (pfds[1].revents)) {
3516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            mLastPacketRxLocalTime = wakeupTime;
3526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            if (!handlePacket())
3536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                ALOGE("handlePacket failed");
3546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
3556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
3566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    cleanupSocket_l();
3586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return true;
3596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
3606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid CommonTimeServer::clearPendingWakeupEvents_l() {
3626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    int64_t tmp;
3636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    read(mWakeupThreadFD, &tmp, sizeof(tmp));
3646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
3656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid CommonTimeServer::wakeupThread_l() {
3676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    int64_t tmp = 1;
3686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    write(mWakeupThreadFD, &tmp, sizeof(tmp));
3696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
3706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid CommonTimeServer::cleanupSocket_l() {
3726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mSocket >= 0) {
3736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        close(mSocket);
3746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mSocket = -1;
3756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
3766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
3776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid CommonTimeServer::shutdownThread() {
3796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Flag the work thread for shutdown.
3806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    this->requestExit();
3816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Signal the thread in case its sleeping.
3836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mLock.lock();
3846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    wakeupThread_l();
3856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mLock.unlock();
3866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Wait for the thread to exit.
3886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    this->join();
3896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
3906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::setupSocket_l() {
3926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    int rc;
3936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    bool ret_val = false;
3946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    struct sockaddr_in* ipv4_addr = NULL;
3956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    char masterElectionEPStr[64];
3966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    const int one = 1;
3976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // This should never be needed, but if we happened to have an old socket
3996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // lying around, be sure to not leak it before proceeding.
4006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    cleanupSocket_l();
4016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // If we don't have a valid endpoint to bind to, then how did we get here in
4036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // the first place?  Regardless, we know that we are going to fail to bind,
4046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // so don't even try.
4056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!mBindIfaceValid)
4066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
4076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    sockaddrToString(mMasterElectionEP, true, masterElectionEPStr,
4096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                     sizeof(masterElectionEPStr));
4106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ALOGI("Building socket :: bind = %s master election = %s",
4116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen         mBindIface.string(), masterElectionEPStr);
4126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // TODO: add proper support for IPv6.  Right now, we block IPv6 addresses at
4146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // the configuration interface level.
4156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (AF_INET != mMasterElectionEP.ss_family) {
4166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ALOGW("TODO: add proper IPv6 support");
4176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        goto bailout;
4186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
4196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // open a UDP socket for the timeline serivce
4216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
4226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mSocket < 0) {
4236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ALOGE("Failed to create socket (errno = %d)", errno);
4246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        goto bailout;
4256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
4266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Bind to the selected interface using Linux's spiffy SO_BINDTODEVICE.
4286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    struct ifreq ifr;
4296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    memset(&ifr, 0, sizeof(ifr));
4306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", mBindIface.string());
4316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = 0;
4326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    rc = setsockopt(mSocket, SOL_SOCKET, SO_BINDTODEVICE,
4336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    (void *)&ifr, sizeof(ifr));
4346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (rc) {
4356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ALOGE("Failed to bind socket at to interface %s (errno = %d)",
4366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen              ifr.ifr_name, errno);
4376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        goto bailout;
4386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
4396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Bind our socket to INADDR_ANY and the master election port.  The
4416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // interface binding we made using SO_BINDTODEVICE should limit us to
4426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // traffic only on the interface we are interested in.  We need to bind to
4436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // INADDR_ANY and the specific master election port in order to be able to
4446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // receive both unicast traffic and master election multicast traffic with
4456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // just a single socket.
4466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    struct sockaddr_in bindAddr;
4476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ipv4_addr = reinterpret_cast<struct sockaddr_in*>(&mMasterElectionEP);
4486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    memcpy(&bindAddr, ipv4_addr, sizeof(bindAddr));
4496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    bindAddr.sin_addr.s_addr = INADDR_ANY;
4506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    rc = bind(mSocket,
4516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen              reinterpret_cast<const sockaddr *>(&bindAddr),
4526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen              sizeof(bindAddr));
4536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (rc) {
4546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ALOGE("Failed to bind socket to port %hu (errno = %d)",
4556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen              ntohs(bindAddr.sin_port), errno);
4566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        goto bailout;
4576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
4586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (0xE0000000 == (ntohl(ipv4_addr->sin_addr.s_addr) & 0xF0000000)) {
4606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // If our master election endpoint is a multicast address, be sure to join
4616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // the multicast group.
4626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        struct ip_mreq mreq;
4636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mreq.imr_multiaddr = ipv4_addr->sin_addr;
4646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mreq.imr_interface.s_addr = htonl(INADDR_ANY);
4656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        rc = setsockopt(mSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP,
4666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        &mreq, sizeof(mreq));
4676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (rc == -1) {
4686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            ALOGE("Failed to join multicast group at %s.  (errno = %d)",
4696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                 masterElectionEPStr, errno);
4706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            goto bailout;
4716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
4726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // disable loopback of multicast packets
4746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        const int zero = 0;
4756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        rc = setsockopt(mSocket, IPPROTO_IP, IP_MULTICAST_LOOP,
4766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        &zero, sizeof(zero));
4776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (rc == -1) {
4786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            ALOGE("Failed to disable multicast loopback (errno = %d)", errno);
4796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            goto bailout;
4806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
4816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else
4826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (ntohl(ipv4_addr->sin_addr.s_addr) != 0xFFFFFFFF) {
4836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // If the master election address is neither broadcast, nor multicast,
4846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // then we are misconfigured.  The config API layer should prevent this
4856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // from ever happening.
4866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        goto bailout;
4876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
4886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Set the TTL of sent packets to 1.  (Time protocol sync should never leave
4906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // the local subnet)
4916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    rc = setsockopt(mSocket, IPPROTO_IP, IP_TTL, &one, sizeof(one));
4926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (rc == -1) {
4936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ALOGE("Failed to set TTL to %d (errno = %d)", one, errno);
4946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        goto bailout;
4956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
4966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // get the device's unique ID
4986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!assignDeviceID())
4996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        goto bailout;
5006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ret_val = true;
5026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbailout:
5046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!ret_val)
5056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        cleanupSocket_l();
5066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return ret_val;
5076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
5086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// generate a unique device ID that can be used for arbitration
5106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::assignDeviceID() {
5116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!mBindIfaceValid)
5126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
5136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    struct ifreq ifr;
5156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    memset(&ifr, 0, sizeof(ifr));
5166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ifr.ifr_addr.sa_family = AF_INET;
5176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    strlcpy(ifr.ifr_name, mBindIface.string(), IFNAMSIZ);
5186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    int rc = ioctl(mSocket, SIOCGIFHWADDR, &ifr);
5206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (rc) {
5216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ALOGE("%s:%d ioctl failed", __PRETTY_FUNCTION__, __LINE__);
5226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
5236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
5246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (ifr.ifr_addr.sa_family != ARPHRD_ETHER) {
5266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ALOGE("%s:%d got non-Ethernet address", __PRETTY_FUNCTION__, __LINE__);
5276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
5286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
5296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mDeviceID = 0;
5316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    for (int i = 0; i < ETH_ALEN; i++) {
5326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mDeviceID = (mDeviceID << 8) | ifr.ifr_hwaddr.sa_data[i];
5336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
5346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return true;
5366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
5376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// generate a new timeline ID
5396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid CommonTimeServer::assignTimelineID() {
5406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    do {
5416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mTimelineID = (static_cast<uint64_t>(lrand48()) << 32)
5426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    |  static_cast<uint64_t>(lrand48());
5436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } while (mTimelineID == ICommonClock::kInvalidTimelineID);
5446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
5456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// Select a preference between the device IDs of two potential masters.
5476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// Returns true if the first ID wins, or false if the second ID wins.
5486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::arbitrateMaster(
5496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        uint64_t deviceID1, uint8_t devicePrio1,
5506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        uint64_t deviceID2, uint8_t devicePrio2) {
5516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return ((devicePrio1 >  devicePrio2) ||
5526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen           ((devicePrio1 == devicePrio2) && (deviceID1 > deviceID2)));
5536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
5546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::handlePacket() {
5566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint8_t buf[256];
5576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    struct sockaddr_storage srcAddr;
5586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    socklen_t srcAddrLen = sizeof(srcAddr);
5596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t recvBytes = recvfrom(
5616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            mSocket, buf, sizeof(buf), 0,
5626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            reinterpret_cast<const sockaddr *>(&srcAddr), &srcAddrLen);
5636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (recvBytes < 0) {
5656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ALOGE("%s:%d recvfrom failed", __PRETTY_FUNCTION__, __LINE__);
5666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
5676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
5686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    UniversalTimeServicePacket pkt;
5706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    recvBytes = pkt.deserializePacket(buf, recvBytes, mSyncGroupID);
5716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (recvBytes < 0)
5726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
5736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    bool result;
5756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    switch (pkt.packetType) {
5766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case TIME_PACKET_WHO_IS_MASTER_REQUEST:
5776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            result = handleWhoIsMasterRequest(&pkt.p.who_is_master_request,
5786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                              srcAddr);
5796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            break;
5806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case TIME_PACKET_WHO_IS_MASTER_RESPONSE:
5826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            result = handleWhoIsMasterResponse(&pkt.p.who_is_master_response,
5836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                               srcAddr);
5846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            break;
5856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case TIME_PACKET_SYNC_REQUEST:
5876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            result = handleSyncRequest(&pkt.p.sync_request, srcAddr);
5886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            break;
5896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case TIME_PACKET_SYNC_RESPONSE:
5916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            result = handleSyncResponse(&pkt.p.sync_response, srcAddr);
5926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            break;
5936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case TIME_PACKET_MASTER_ANNOUNCEMENT:
5956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            result = handleMasterAnnouncement(&pkt.p.master_announcement,
5966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                              srcAddr);
5976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            break;
5986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        default: {
6006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            ALOGD("%s:%d unknown packet type(%d)",
6016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    __PRETTY_FUNCTION__, __LINE__, pkt.packetType);
6026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            result = false;
6036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        } break;
6046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
6056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
6066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return result;
6076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
6086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
6096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::handleTimeout() {
6106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // If we have no socket, then this must be a timeout to retry socket setup.
6116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mSocket < 0)
6126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return true;
6136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
6146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    switch (mState) {
6156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case ICommonClock::STATE_INITIAL:
6166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return handleTimeoutInitial();
6176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case ICommonClock::STATE_CLIENT:
6186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return handleTimeoutClient();
6196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case ICommonClock::STATE_MASTER:
6206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return handleTimeoutMaster();
6216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case ICommonClock::STATE_RONIN:
6226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return handleTimeoutRonin();
6236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case ICommonClock::STATE_WAIT_FOR_ELECTION:
6246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return handleTimeoutWaitForElection();
6256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
6266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
6276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return false;
6286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
6296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
6306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::handleTimeoutInitial() {
6316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (++mInitial_WhoIsMasterRequestTimeouts ==
6326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            kInitial_NumWhoIsMasterRetries) {
6336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // none of our attempts to discover a master succeeded, so make
6346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // this device the master
6356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return becomeMaster("initial timeout");
6366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else {
6376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // retry the WhoIsMaster request
6386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return sendWhoIsMasterRequest();
6396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
6406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
6416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
6426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::handleTimeoutClient() {
6436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (shouldPanicNotGettingGoodData())
6446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return becomeInitial("timeout panic, no good data");
6456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
6466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mClient_SyncRequestPending) {
6476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mClient_SyncRequestPending = false;
6486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
6496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (++mClient_SyncRequestTimeouts < kClient_NumSyncRequestRetries) {
6506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // a sync request has timed out, so retry
6516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return sendSyncRequest();
6526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        } else {
6536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // The master has failed to respond to a sync request for too many
6546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // times in a row.  Assume the master is dead and start electing
6556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // a new master.
6566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return becomeRonin("master not responding");
6576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
6586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else {
6596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // initiate the next sync request
6606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return sendSyncRequest();
6616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
6626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
6636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
6646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::handleTimeoutMaster() {
6656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // send another announcement from the master
6666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return sendMasterAnnouncement();
6676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
6686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
6696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::handleTimeoutRonin() {
6706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (++mRonin_WhoIsMasterRequestTimeouts == kRonin_NumWhoIsMasterRetries) {
6716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // no other master is out there, so we won the election
6726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return becomeMaster("no better masters detected");
6736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else {
6746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return sendWhoIsMasterRequest();
6756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
6766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
6776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
6786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::handleTimeoutWaitForElection() {
6796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return becomeRonin("timeout waiting for election conclusion");
6806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
6816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
6826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::handleWhoIsMasterRequest(
6836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        const WhoIsMasterRequestPacket* request,
6846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        const sockaddr_storage& srcAddr) {
6856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mState == ICommonClock::STATE_MASTER) {
6866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // is this request related to this master's timeline?
6876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (request->timelineID != ICommonClock::kInvalidTimelineID &&
6886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            request->timelineID != mTimelineID)
6896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return true;
6906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
6916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        WhoIsMasterResponsePacket pkt;
6926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        pkt.initHeader(mTimelineID, mSyncGroupID);
6936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        pkt.deviceID = mDeviceID;
6946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        pkt.devicePriority = effectivePriority();
6956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
6966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        uint8_t buf[256];
6976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
6986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (bufSz < 0)
6996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return false;
7006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
7016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ssize_t sendBytes = sendto(
7026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                mSocket, buf, bufSz, 0,
7036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                reinterpret_cast<const sockaddr *>(&srcAddr),
7046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                sizeof(srcAddr));
7056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (sendBytes == -1) {
7066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            ALOGE("%s:%d sendto failed", __PRETTY_FUNCTION__, __LINE__);
7076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return false;
7086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
7096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else if (mState == ICommonClock::STATE_RONIN) {
7106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // if we hear a WhoIsMaster request from another device following
7116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // the same timeline and that device wins arbitration, then we will stop
7126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // trying to elect ourselves master and will instead wait for an
7136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // announcement from the election winner
7146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (request->timelineID != mTimelineID)
7156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return true;
7166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
7176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (arbitrateMaster(request->senderDeviceID,
7186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            request->senderDevicePriority,
7196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            mDeviceID,
7206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            effectivePriority()))
7216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return becomeWaitForElection("would lose election");
7226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
7236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return true;
7246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else if (mState == ICommonClock::STATE_INITIAL) {
7256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // If a group of devices booted simultaneously (e.g. after a power
7266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // outage) and all of them are in the initial state and there is no
7276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // master, then each device may time out and declare itself master at
7286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // the same time.  To avoid this, listen for
7296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // WhoIsMaster(InvalidTimeline) requests from peers.  If we would lose
7306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // arbitration against that peer, reset our timeout count so that the
7316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // peer has a chance to become master before we time out.
7326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (request->timelineID == ICommonClock::kInvalidTimelineID &&
7336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                arbitrateMaster(request->senderDeviceID,
7346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                request->senderDevicePriority,
7356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                mDeviceID,
7366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                effectivePriority())) {
7376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            mInitial_WhoIsMasterRequestTimeouts = 0;
7386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
7396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
7406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
7416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return true;
7426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
7436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
7446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::handleWhoIsMasterResponse(
7456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        const WhoIsMasterResponsePacket* response,
7466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        const sockaddr_storage& srcAddr) {
7476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mState == ICommonClock::STATE_INITIAL || mState == ICommonClock::STATE_RONIN) {
7486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return becomeClient(srcAddr,
7496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            response->deviceID,
7506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            response->devicePriority,
7516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            response->timelineID,
7526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            "heard whois response");
7536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else if (mState == ICommonClock::STATE_CLIENT) {
7546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // if we get multiple responses because there are multiple devices
7556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // who believe that they are master, then follow the master that
7566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // wins arbitration
7576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (arbitrateMaster(response->deviceID,
7586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            response->devicePriority,
7596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            mClient_MasterDeviceID,
7606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            mClient_MasterDevicePriority)) {
7616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return becomeClient(srcAddr,
7626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                response->deviceID,
7636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                response->devicePriority,
7646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                response->timelineID,
7656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                "heard whois response");
7666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
7676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
7686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
7696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return true;
7706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
7716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
7726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::handleSyncRequest(const SyncRequestPacket* request,
7736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                         const sockaddr_storage& srcAddr) {
7746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    SyncResponsePacket pkt;
7756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    pkt.initHeader(mTimelineID, mSyncGroupID);
7766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
7776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if ((mState == ICommonClock::STATE_MASTER) &&
7786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        (mTimelineID == request->timelineID)) {
7796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int64_t rxLocalTime = mLastPacketRxLocalTime;
7806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int64_t rxCommonTime;
7816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
7826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // If we are master on an actual network and have actual clients, then
7836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // we are no longer low priority.
7846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        setForceLowPriority(false);
7856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
7866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (OK != mCommonClock.localToCommon(rxLocalTime, &rxCommonTime)) {
7876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return false;
7886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
7896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
7906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int64_t txLocalTime = mLocalClock.getLocalTime();;
7916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int64_t txCommonTime;
7926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (OK != mCommonClock.localToCommon(txLocalTime, &txCommonTime)) {
7936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return false;
7946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
7956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
7966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        pkt.nak = 0;
7976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        pkt.clientTxLocalTime  = request->clientTxLocalTime;
7986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        pkt.masterRxCommonTime = rxCommonTime;
7996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        pkt.masterTxCommonTime = txCommonTime;
8006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else {
8016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        pkt.nak = 1;
8026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        pkt.clientTxLocalTime  = 0;
8036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        pkt.masterRxCommonTime = 0;
8046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        pkt.masterTxCommonTime = 0;
8056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
8066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
8076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint8_t buf[256];
8086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
8096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (bufSz < 0)
8106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
8116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
8126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t sendBytes = sendto(
8136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            mSocket, &buf, bufSz, 0,
8146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            reinterpret_cast<const sockaddr *>(&srcAddr),
8156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            sizeof(srcAddr));
8166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (sendBytes == -1) {
8176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ALOGE("%s:%d sendto failed", __PRETTY_FUNCTION__, __LINE__);
8186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
8196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
8206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
8216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return true;
8226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
8236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
8246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::handleSyncResponse(
8256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        const SyncResponsePacket* response,
8266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        const sockaddr_storage& srcAddr) {
8276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mState != ICommonClock::STATE_CLIENT)
8286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return true;
8296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
8306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    assert(mMasterEPValid);
8316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!sockaddrMatch(srcAddr, mMasterEP, true)) {
8326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        char srcEP[64], expectedEP[64];
8336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        sockaddrToString(srcAddr, true, srcEP, sizeof(srcEP));
8346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        sockaddrToString(mMasterEP, true, expectedEP, sizeof(expectedEP));
8356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ALOGI("Dropping sync response from unexpected address."
8366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             " Expected %s Got %s", expectedEP, srcEP);
8376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return true;
8386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
8396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
8406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (response->nak) {
8416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // if our master is no longer accepting requests, then we need to find
8426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // a new master
8436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return becomeRonin("master NAK'ed");
8446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
8456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
8466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClient_SyncRequestPending = 0;
8476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClient_SyncRequestTimeouts = 0;
8486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClient_PacketRTTLog.logRX(response->clientTxLocalTime,
8496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                               mLastPacketRxLocalTime);
8506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
8516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    bool result;
8526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!(mClient_SyncRespsRXedFromCurMaster++)) {
8536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // the first request/response exchange between a client and a master
8546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // may take unusually long due to ARP, so discard it.
8556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        result = true;
8566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else {
8576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int64_t clientTxLocalTime  = response->clientTxLocalTime;
8586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int64_t clientRxLocalTime  = mLastPacketRxLocalTime;
8596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int64_t masterTxCommonTime = response->masterTxCommonTime;
8606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int64_t masterRxCommonTime = response->masterRxCommonTime;
8616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
8626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int64_t rtt       = (clientRxLocalTime - clientTxLocalTime);
8636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int64_t avgLocal  = (clientTxLocalTime + clientRxLocalTime) >> 1;
8646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int64_t avgCommon = (masterTxCommonTime + masterRxCommonTime) >> 1;
8656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
8666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // if the RTT of the packet is significantly larger than the panic
8676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // threshold, we should simply discard it.  Its better to do nothing
8686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // than to take cues from a packet like that.
8696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int rttCommon = mCommonClock.localDurationToCommonDuration(rtt);
8706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (rttCommon > (static_cast<int64_t>(mPanicThresholdUsec) *
8716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                         kRTTDiscardPanicThreshMultiplier)) {
8726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            ALOGV("Dropping sync response with RTT of %lld uSec", rttCommon);
8736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            mClient_ExpiredSyncRespsRXedFromCurMaster++;
8746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            if (shouldPanicNotGettingGoodData())
8756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                return becomeInitial("RX panic, no good data");
8766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        } else {
87711bc45fcba96cf7ccc5f67b3c47088c2c89c8e7aKent Ryhorchuk            result = mClockRecovery.pushDisciplineEvent(avgLocal, avgCommon, rttCommon);
8786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            mClient_LastGoodSyncRX = clientRxLocalTime;
8796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
8806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            if (result) {
8816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                // indicate to listeners that we've synced to the common timeline
8826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                notifyClockSync();
8836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            } else {
8846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                ALOGE("Panic!  Observed clock sync error is too high to tolerate,"
8856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        " resetting state machine and starting over.");
8866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                notifyClockSyncLoss();
8876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                return becomeInitial("panic");
8886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            }
8896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
8906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
8916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
8926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mCurTimeout.setTimeout(mSyncRequestIntervalMs);
8936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return result;
8946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
8956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
8966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::handleMasterAnnouncement(
8976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        const MasterAnnouncementPacket* packet,
8986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        const sockaddr_storage& srcAddr) {
8996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint64_t newDeviceID   = packet->deviceID;
9006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint8_t  newDevicePrio = packet->devicePriority;
9016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint64_t newTimelineID = packet->timelineID;
9026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
9036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mState == ICommonClock::STATE_INITIAL ||
9046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mState == ICommonClock::STATE_RONIN ||
9056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mState == ICommonClock::STATE_WAIT_FOR_ELECTION) {
9066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // if we aren't currently following a master, then start following
9076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // this new master
9086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return becomeClient(srcAddr,
9096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            newDeviceID,
9106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            newDevicePrio,
9116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            newTimelineID,
9126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            "heard master announcement");
9136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else if (mState == ICommonClock::STATE_CLIENT) {
9146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // if the new master wins arbitration against our current master,
9156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // then become a client of the new master
9166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (arbitrateMaster(newDeviceID,
9176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            newDevicePrio,
9186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            mClient_MasterDeviceID,
9196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            mClient_MasterDevicePriority))
9206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return becomeClient(srcAddr,
9216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                newDeviceID,
9226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                newDevicePrio,
9236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                newTimelineID,
9246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                "heard master announcement");
9256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else if (mState == ICommonClock::STATE_MASTER) {
9266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // two masters are competing - if the new one wins arbitration, then
9276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // cease acting as master
9286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (arbitrateMaster(newDeviceID, newDevicePrio,
9296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            mDeviceID, effectivePriority()))
9306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return becomeClient(srcAddr, newDeviceID,
9316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                newDevicePrio, newTimelineID,
9326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                "heard master announcement");
9336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
9346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
9356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return true;
9366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
9376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
9386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::sendWhoIsMasterRequest() {
9396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    assert(mState == ICommonClock::STATE_INITIAL || mState == ICommonClock::STATE_RONIN);
9406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
9416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // If we have no socket, then we must be in the unconfigured initial state.
9426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Don't report any errors, just don't try to send the initial who-is-master
9436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // query.  Eventually, our network will either become configured, or we will
9446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // be forced into network-less master mode by higher level code.
9456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mSocket < 0) {
9466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        assert(mState == ICommonClock::STATE_INITIAL);
9476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return true;
9486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
9496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
9506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    bool ret = false;
9516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    WhoIsMasterRequestPacket pkt;
9526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    pkt.initHeader(mSyncGroupID);
9536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    pkt.senderDeviceID = mDeviceID;
9546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    pkt.senderDevicePriority = effectivePriority();
9556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
9566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint8_t buf[256];
9576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
9586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (bufSz >= 0) {
9596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ssize_t sendBytes = sendto(
9606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                mSocket, buf, bufSz, 0,
9616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                reinterpret_cast<const sockaddr *>(&mMasterElectionEP),
9626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                sizeof(mMasterElectionEP));
9636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (sendBytes < 0)
9646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            ALOGE("WhoIsMaster sendto failed (errno %d)", errno);
9656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ret = true;
9666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
9676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
9686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mState == ICommonClock::STATE_INITIAL) {
9696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mCurTimeout.setTimeout(kInitial_WhoIsMasterTimeoutMs);
9706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else {
9716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mCurTimeout.setTimeout(kRonin_WhoIsMasterTimeoutMs);
9726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
9736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
9746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return ret;
9756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
9766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
9776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::sendSyncRequest() {
9786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // If we are sending sync requests, then we must be in the client state and
9796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // we must have a socket (when we have no network, we are only supposed to
9806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // be in INITIAL or MASTER)
9816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    assert(mState == ICommonClock::STATE_CLIENT);
9826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    assert(mSocket >= 0);
9836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
9846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    bool ret = false;
9856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    SyncRequestPacket pkt;
9866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    pkt.initHeader(mTimelineID, mSyncGroupID);
9876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    pkt.clientTxLocalTime = mLocalClock.getLocalTime();
9886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
9896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!mClient_FirstSyncTX)
9906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mClient_FirstSyncTX = pkt.clientTxLocalTime;
9916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
9926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClient_PacketRTTLog.logTX(pkt.clientTxLocalTime);
9936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
9946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint8_t buf[256];
9956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
9966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (bufSz >= 0) {
9976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ssize_t sendBytes = sendto(
9986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                mSocket, buf, bufSz, 0,
9996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                reinterpret_cast<const sockaddr *>(&mMasterEP),
10006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                sizeof(mMasterEP));
10016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (sendBytes < 0)
10026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            ALOGE("SyncRequest sendto failed (errno %d)", errno);
10036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ret = true;
10046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
10056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
10066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClient_SyncsSentToCurMaster++;
10076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mCurTimeout.setTimeout(mSyncRequestIntervalMs);
10086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClient_SyncRequestPending = true;
10096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
10106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return ret;
10116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
10126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
10136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::sendMasterAnnouncement() {
10146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    bool ret = false;
10156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    assert(mState == ICommonClock::STATE_MASTER);
10166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
10176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // If we are being asked to send a master announcement, but we have no
10186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // socket, we must be in network-less master mode.  Don't bother to send the
10196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // announcement, and don't bother to schedule a timeout.  When the network
10206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // comes up, the work thread will get poked and start the process of
10216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // figuring out who the current master should be.
10226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mSocket < 0) {
10236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mCurTimeout.setTimeout(kInfiniteTimeout);
10246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return true;
10256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
10266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
10276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    MasterAnnouncementPacket pkt;
10286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    pkt.initHeader(mTimelineID, mSyncGroupID);
10296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    pkt.deviceID = mDeviceID;
10306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    pkt.devicePriority = effectivePriority();
10316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
10326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint8_t buf[256];
10336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
10346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (bufSz >= 0) {
10356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ssize_t sendBytes = sendto(
10366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                mSocket, buf, bufSz, 0,
10376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                reinterpret_cast<const sockaddr *>(&mMasterElectionEP),
10386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                sizeof(mMasterElectionEP));
10396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (sendBytes < 0)
10406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            ALOGE("MasterAnnouncement sendto failed (errno %d)", errno);
10416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ret = true;
10426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
10436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
10446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mCurTimeout.setTimeout(mMasterAnnounceIntervalMs);
10456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return ret;
10466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
10476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
10486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::becomeClient(const sockaddr_storage& masterEP,
10496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                    uint64_t masterDeviceID,
10506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                    uint8_t  masterDevicePriority,
10516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                    uint64_t timelineID,
10526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                    const char* cause) {
10536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    char newEPStr[64], oldEPStr[64];
10546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    sockaddrToString(masterEP, true, newEPStr, sizeof(newEPStr));
10556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    sockaddrToString(mMasterEP, mMasterEPValid, oldEPStr, sizeof(oldEPStr));
10566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
10576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ALOGI("%s --> CLIENT (%s) :%s"
10586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen         " OldMaster: %02x-%014llx::%016llx::%s"
10596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen         " NewMaster: %02x-%014llx::%016llx::%s",
10606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen         stateToString(mState), cause,
10616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen         (mTimelineID != timelineID) ? " (new timeline)" : "",
10626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen         mClient_MasterDevicePriority, mClient_MasterDeviceID,
10636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen         mTimelineID, oldEPStr,
10646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen         masterDevicePriority, masterDeviceID,
10656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen         timelineID, newEPStr);
10666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
10676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mTimelineID != timelineID) {
10686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // start following a new timeline
10696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mTimelineID = timelineID;
10706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mClockRecovery.reset(true, true);
10716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        notifyClockSyncLoss();
10726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else {
10736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // start following a new master on the existing timeline
10746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mClockRecovery.reset(false, true);
10756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
10766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
10776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mMasterEP = masterEP;
10786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mMasterEPValid = true;
1079e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman
1080e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman    // If we are on a real network as a client of a real master, then we should
1081e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman    // no longer force low priority.  If our master disappears, we should have
1082e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman    // the high priority bit set during the election to replace the master
1083e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman    // because this group was a real group and not a singleton created in
1084e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman    // networkless mode.
10856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    setForceLowPriority(false);
10866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
10876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClient_MasterDeviceID = masterDeviceID;
10886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClient_MasterDevicePriority = masterDevicePriority;
10896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    resetSyncStats();
10906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
10916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    setState(ICommonClock::STATE_CLIENT);
10926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
10936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // add some jitter to when the various clients send their requests
10946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // in order to reduce the likelihood that a group of clients overload
10956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // the master after receiving a master announcement
10966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    usleep((lrand48() % 100) * 1000);
10976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
10986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return sendSyncRequest();
10996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
11006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::becomeMaster(const char* cause) {
11026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint64_t oldTimelineID = mTimelineID;
11036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mTimelineID == ICommonClock::kInvalidTimelineID) {
11046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // this device has not been following any existing timeline,
11056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // so it will create a new timeline and declare itself master
11066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        assert(!mCommonClock.isValid());
11076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // set the common time basis
11096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mCommonClock.setBasis(mLocalClock.getLocalTime(), 0);
11106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // assign an arbitrary timeline iD
11126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        assignTimelineID();
11136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // notify listeners that we've created a common timeline
11156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        notifyClockSync();
11166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
11176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ALOGI("%s --> MASTER (%s) : %s timeline %016llx",
11196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen         stateToString(mState), cause,
11206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen         (oldTimelineID == mTimelineID) ? "taking ownership of"
11216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                        : "creating new",
11226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen         mTimelineID);
11236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    memset(&mMasterEP, 0, sizeof(mMasterEP));
11256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mMasterEPValid = false;
11266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClient_MasterDevicePriority = effectivePriority();
11276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClient_MasterDeviceID = mDeviceID;
11286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClockRecovery.reset(false, true);
11296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    resetSyncStats();
11306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    setState(ICommonClock::STATE_MASTER);
11326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return sendMasterAnnouncement();
11336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
11346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::becomeRonin(const char* cause) {
11366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // If we were the client of a given timeline, but had never received even a
11376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // single time sync packet, then we transition back to Initial instead of
11386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Ronin.  If we transition to Ronin and end up becoming the new Master, we
11396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // will be unable to service requests for other clients because we never
11406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // actually knew what time it was.  By going to initial, we ensure that
11416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // other clients who know what time it is, but would lose master arbitration
11426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // in the Ronin case, will step up and become the proper new master of the
11436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // old timeline.
11446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    char oldEPStr[64];
11466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    sockaddrToString(mMasterEP, mMasterEPValid, oldEPStr, sizeof(oldEPStr));
11476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    memset(&mMasterEP, 0, sizeof(mMasterEP));
11486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mMasterEPValid = false;
11496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mCommonClock.isValid()) {
11516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ALOGI("%s --> RONIN (%s) : lost track of previously valid timeline "
11526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             "%02x-%014llx::%016llx::%s (%d TXed %d RXed %d RXExpired)",
11536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             stateToString(mState), cause,
11546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             mClient_MasterDevicePriority, mClient_MasterDeviceID,
11556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             mTimelineID, oldEPStr,
11566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             mClient_SyncsSentToCurMaster,
11576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             mClient_SyncRespsRXedFromCurMaster,
11586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             mClient_ExpiredSyncRespsRXedFromCurMaster);
11596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mRonin_WhoIsMasterRequestTimeouts = 0;
11616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        setState(ICommonClock::STATE_RONIN);
11626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return sendWhoIsMasterRequest();
11636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else {
11646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ALOGI("%s --> INITIAL (%s) : never synced timeline "
11656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             "%02x-%014llx::%016llx::%s (%d TXed %d RXed %d RXExpired)",
11666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             stateToString(mState), cause,
11676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             mClient_MasterDevicePriority, mClient_MasterDeviceID,
11686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             mTimelineID, oldEPStr,
11696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             mClient_SyncsSentToCurMaster,
11706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             mClient_SyncRespsRXedFromCurMaster,
11716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             mClient_ExpiredSyncRespsRXedFromCurMaster);
11726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return becomeInitial("ronin, no timeline");
11746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
11756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
11766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::becomeWaitForElection(const char* cause) {
11786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ALOGI("%s --> WAIT_FOR_ELECTION (%s) : dropping out of election,"
11796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen         " waiting %d mSec for completion.",
11806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen         stateToString(mState), cause, kWaitForElection_TimeoutMs);
11816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    setState(ICommonClock::STATE_WAIT_FOR_ELECTION);
11836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mCurTimeout.setTimeout(kWaitForElection_TimeoutMs);
11846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return true;
11856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
11866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::becomeInitial(const char* cause) {
11886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ALOGI("Entering INITIAL (%s), total reset.", cause);
11896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    setState(ICommonClock::STATE_INITIAL);
11916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // reset clock recovery
11936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClockRecovery.reset(true, true);
11946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // reset internal state bookkeeping.
11966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mCurTimeout.setTimeout(kInfiniteTimeout);
11976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    memset(&mMasterEP, 0, sizeof(mMasterEP));
11986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mMasterEPValid = false;
11996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mLastPacketRxLocalTime = 0;
12006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mTimelineID = ICommonClock::kInvalidTimelineID;
12016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClockSynced = false;
12026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mInitial_WhoIsMasterRequestTimeouts = 0;
12036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClient_MasterDeviceID = 0;
12046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClient_MasterDevicePriority = 0;
12056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mRonin_WhoIsMasterRequestTimeouts = 0;
12066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    resetSyncStats();
12076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // send the first request to discover the master
12096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return sendWhoIsMasterRequest();
12106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
12116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid CommonTimeServer::notifyClockSync() {
12136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!mClockSynced) {
12146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mClockSynced = true;
12156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mICommonClock->notifyOnTimelineChanged(mTimelineID);
12166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
12176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
12186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid CommonTimeServer::notifyClockSyncLoss() {
12206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mClockSynced) {
12216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mClockSynced = false;
12226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mICommonClock->notifyOnTimelineChanged(
12236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                ICommonClock::kInvalidTimelineID);
12246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
12256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
12266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid CommonTimeServer::setState(ICommonClock::State s) {
12286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mState = s;
12296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
12306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst char* CommonTimeServer::stateToString(ICommonClock::State s) {
12326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    switch(s) {
12336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case ICommonClock::STATE_INITIAL:
12346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return "INITIAL";
12356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case ICommonClock::STATE_CLIENT:
12366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return "CLIENT";
12376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case ICommonClock::STATE_MASTER:
12386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return "MASTER";
12396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case ICommonClock::STATE_RONIN:
12406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return "RONIN";
12416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case ICommonClock::STATE_WAIT_FOR_ELECTION:
12426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return "WAIT_FOR_ELECTION";
12436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        default:
12446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return "unknown";
12456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
12466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
12476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid CommonTimeServer::sockaddrToString(const sockaddr_storage& addr,
12496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                        bool addrValid,
12506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                        char* buf, size_t bufLen) {
12516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!bufLen || !buf)
12526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return;
12536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (addrValid) {
12556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        switch (addr.ss_family) {
12566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            case AF_INET: {
12576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                const struct sockaddr_in* sa =
12586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    reinterpret_cast<const struct sockaddr_in*>(&addr);
12596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                unsigned long a = ntohl(sa->sin_addr.s_addr);
12606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                uint16_t      p = ntohs(sa->sin_port);
12616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                snprintf(buf, bufLen, "%lu.%lu.%lu.%lu:%hu",
12626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        ((a >> 24) & 0xFF), ((a >> 16) & 0xFF),
12636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        ((a >>  8) & 0xFF),  (a        & 0xFF), p);
12646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            } break;
12656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            case AF_INET6: {
12676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                const struct sockaddr_in6* sa =
12686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    reinterpret_cast<const struct sockaddr_in6*>(&addr);
12696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                const uint8_t* a = sa->sin6_addr.s6_addr;
12706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                uint16_t       p = ntohs(sa->sin6_port);
12716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                snprintf(buf, bufLen,
12726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        "%02X%02X:%02X%02X:%02X%02X:%02X%02X:"
12736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        "%02X%02X:%02X%02X:%02X%02X:%02X%02X port %hd",
12746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        a[0], a[1], a[ 2], a[ 3], a[ 4], a[ 5], a[ 6], a[ 7],
12756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15],
12766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        p);
12776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            } break;
12786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            default:
12806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                snprintf(buf, bufLen,
12816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                         "<unknown sockaddr family %d>", addr.ss_family);
12826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                break;
12836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
12846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else {
12856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        snprintf(buf, bufLen, "<none>");
12866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
12876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    buf[bufLen - 1] = 0;
12896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
12906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::sockaddrMatch(const sockaddr_storage& a1,
12926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                     const sockaddr_storage& a2,
12936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                     bool matchAddressOnly) {
12946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (a1.ss_family != a2.ss_family)
12956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
12966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    switch (a1.ss_family) {
12986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case AF_INET: {
12996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            const struct sockaddr_in* sa1 =
13006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                reinterpret_cast<const struct sockaddr_in*>(&a1);
13016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            const struct sockaddr_in* sa2 =
13026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                reinterpret_cast<const struct sockaddr_in*>(&a2);
13036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            if (sa1->sin_addr.s_addr != sa2->sin_addr.s_addr)
13056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                return false;
13066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return (matchAddressOnly || (sa1->sin_port == sa2->sin_port));
13086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        } break;
13096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case AF_INET6: {
13116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            const struct sockaddr_in6* sa1 =
13126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                reinterpret_cast<const struct sockaddr_in6*>(&a1);
13136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            const struct sockaddr_in6* sa2 =
13146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                reinterpret_cast<const struct sockaddr_in6*>(&a2);
13156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            if (memcmp(&sa1->sin6_addr, &sa2->sin6_addr, sizeof(sa2->sin6_addr)))
13176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                return false;
13186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return (matchAddressOnly || (sa1->sin6_port == sa2->sin6_port));
13206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        } break;
13216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // Huh?  We don't deal in non-IPv[46] addresses.  Not sure how we got
13236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // here, but we don't know how to comapre these addresses and simply
13246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // default to a no-match decision.
13256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        default: return false;
13266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
13276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
13286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid CommonTimeServer::TimeoutHelper::setTimeout(int msec) {
13306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mTimeoutValid = (msec >= 0);
13316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mTimeoutValid)
13326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mEndTime = systemTime() +
13336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                   (static_cast<nsecs_t>(msec) * 1000000);
13346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
13356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenint CommonTimeServer::TimeoutHelper::msecTillTimeout() {
13376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!mTimeoutValid)
13386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return kInfiniteTimeout;
13396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    nsecs_t now = systemTime();
13416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (now >= mEndTime)
13426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return 0;
13436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint64_t deltaMsec = (((mEndTime - now) + 999999) / 1000000);
13456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1346b8525e9a76d63a2dc26c87577940a058e70e3dd5John Grossman    if (deltaMsec > static_cast<uint64_t>(MAX_INT))
1347b8525e9a76d63a2dc26c87577940a058e70e3dd5John Grossman        return MAX_INT;
13486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return static_cast<int>(deltaMsec);
13506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
13516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::shouldPanicNotGettingGoodData() {
13536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mClient_FirstSyncTX) {
13546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int64_t now = mLocalClock.getLocalTime();
13556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int64_t delta = now - (mClient_LastGoodSyncRX
13566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                             ? mClient_LastGoodSyncRX
13576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                             : mClient_FirstSyncTX);
13586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int64_t deltaUsec = mCommonClock.localDurationToCommonDuration(delta);
13596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (deltaUsec >= kNoGoodDataPanicThresholdUsec)
13616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return true;
13626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
13636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return false;
13656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
13666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid CommonTimeServer::PacketRTTLog::logTX(int64_t txTime) {
13686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    txTimes[wrPtr] = txTime;
13696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    rxTimes[wrPtr] = 0;
13706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    wrPtr = (wrPtr + 1) % RTT_LOG_SIZE;
13716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!wrPtr)
13726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        logFull = true;
13736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
13746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid CommonTimeServer::PacketRTTLog::logRX(int64_t txTime, int64_t rxTime) {
13766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!logFull && !wrPtr)
13776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return;
13786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint32_t i = logFull ? wrPtr : 0;
13806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    do {
13816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (txTimes[i] == txTime) {
13826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            rxTimes[i] = rxTime;
13836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            break;
13846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
13856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        i = (i + 1) % RTT_LOG_SIZE;
13866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } while (i != wrPtr);
13876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
13886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}  // namespace android
1390