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>
284c57eda9f4c87bb22eb0acdd2dab4d1757d4280bAndreas Gampe#include <inttypes.h>
296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <linux/if_ether.h>
306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <net/if.h>
316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <net/if_arp.h>
326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <netinet/ip.h>
336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <poll.h>
346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <stdio.h>
356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <sys/eventfd.h>
366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <sys/ioctl.h>
376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <sys/stat.h>
386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <sys/types.h>
396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <sys/socket.h>
406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <common_time/local_clock.h>
426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <binder/IPCThreadState.h>
436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <binder/ProcessState.h>
446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <utils/Timers.h>
456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include "common_clock_service.h"
476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include "common_time_config_service.h"
486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include "common_time_server.h"
496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include "common_time_server_packets.h"
506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include "clock_recovery.h"
516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include "common_clock.h"
526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
53b8525e9a76d63a2dc26c87577940a058e70e3dd5John Grossman#define MAX_INT ((int)0x7FFFFFFF)
546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chennamespace android {
566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
577a947c49782165d7320a93d8685d99730286f9a7John Grossmanconst char*    CommonTimeServer::kDefaultMasterElectionAddr = "255.255.255.255";
587a947c49782165d7320a93d8685d99730286f9a7John Grossmanconst uint16_t CommonTimeServer::kDefaultMasterElectionPort = 8886;
597a947c49782165d7320a93d8685d99730286f9a7John Grossmanconst uint64_t CommonTimeServer::kDefaultSyncGroupID = 1;
606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst uint8_t  CommonTimeServer::kDefaultMasterPriority = 1;
616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst uint32_t CommonTimeServer::kDefaultMasterAnnounceIntervalMs = 10000;
626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst uint32_t CommonTimeServer::kDefaultSyncRequestIntervalMs = 1000;
636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst uint32_t CommonTimeServer::kDefaultPanicThresholdUsec = 50000;
646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst bool     CommonTimeServer::kDefaultAutoDisable = true;
656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst int      CommonTimeServer::kSetupRetryTimeoutMs = 30000;
666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst int64_t  CommonTimeServer::kNoGoodDataPanicThresholdUsec = 600000000ll;
676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst uint32_t CommonTimeServer::kRTTDiscardPanicThreshMultiplier = 5;
686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// timeout value representing an infinite timeout
706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst int CommonTimeServer::kInfiniteTimeout = -1;
716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen/*** Initial state constants ***/
736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// number of WhoIsMaster attempts sent before giving up
756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst int CommonTimeServer::kInitial_NumWhoIsMasterRetries = 6;
766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// timeout used when waiting for a response to a WhoIsMaster request
786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst int CommonTimeServer::kInitial_WhoIsMasterTimeoutMs = 500;
796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen/*** Client state constants ***/
816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// number of sync requests that can fail before a client assumes its master
836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// is dead
84e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossmanconst int CommonTimeServer::kClient_NumSyncRequestRetries = 10;
856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen/*** Master state constants ***/
876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen/*** Ronin state constants ***/
896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// number of WhoIsMaster attempts sent before declaring ourselves master
91e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossmanconst int CommonTimeServer::kRonin_NumWhoIsMasterRetries = 20;
926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// timeout used when waiting for a response to a WhoIsMaster request
946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst int CommonTimeServer::kRonin_WhoIsMasterTimeoutMs = 500;
956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen/*** WaitForElection state constants ***/
976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// how long do we wait for an announcement from a master before
996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// trying another election?
100e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossmanconst int CommonTimeServer::kWaitForElection_TimeoutMs = 12500;
1016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1026c929510474caa14dc9d56826b2c65552861d6b3Mike J. ChenCommonTimeServer::CommonTimeServer()
1036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    : Thread(false)
1046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    , mState(ICommonClock::STATE_INITIAL)
1056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    , mClockRecovery(&mLocalClock, &mCommonClock)
1066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    , mSocket(-1)
1076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    , mLastPacketRxLocalTime(0)
1086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    , mTimelineID(ICommonClock::kInvalidTimelineID)
1096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    , mClockSynced(false)
1106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    , mCommonClockHasClients(false)
11179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    , mStateChangeLog("Recent State Change Events", 30)
11279489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    , mElectionLog("Recent Master Election Traffic", 30)
11379489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    , mBadPktLog("Recent Bad Packet RX Info", 8)
1146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    , mInitial_WhoIsMasterRequestTimeouts(0)
1156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    , mClient_MasterDeviceID(0)
1166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    , mClient_MasterDevicePriority(0)
1176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    , mRonin_WhoIsMasterRequestTimeouts(0) {
1186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // zero out sync stats
1196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    resetSyncStats();
1206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Setup the master election endpoint to use the default.
1226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    struct sockaddr_in* meep =
1236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        reinterpret_cast<struct sockaddr_in*>(&mMasterElectionEP);
1246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    memset(&mMasterElectionEP, 0, sizeof(mMasterElectionEP));
1256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    inet_aton(kDefaultMasterElectionAddr, &meep->sin_addr);
1266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    meep->sin_family = AF_INET;
1276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    meep->sin_port   = htons(kDefaultMasterElectionPort);
1286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Zero out the master endpoint.
1306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    memset(&mMasterEP, 0, sizeof(mMasterEP));
1316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mMasterEPValid    = false;
1326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mBindIfaceValid   = false;
1336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    setForceLowPriority(false);
1346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Set all remaining configuration parameters to their defaults.
1366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mDeviceID                 = 0;
1376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mSyncGroupID              = kDefaultSyncGroupID;
1386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mMasterPriority           = kDefaultMasterPriority;
1396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mMasterAnnounceIntervalMs = kDefaultMasterAnnounceIntervalMs;
1406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mSyncRequestIntervalMs    = kDefaultSyncRequestIntervalMs;
1416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mPanicThresholdUsec       = kDefaultPanicThresholdUsec;
1426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mAutoDisable              = kDefaultAutoDisable;
1436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Create the eventfd we will use to signal our thread to wake up when
1456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // needed.
146a0468e3361fd35f2d271db4c7e27ff79498ecc80Nick Kralevich    mWakeupThreadFD = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
1476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // seed the random number generator (used to generated timeline IDs)
1496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    srand48(static_cast<unsigned int>(systemTime()));
1506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
1516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1526c929510474caa14dc9d56826b2c65552861d6b3Mike J. ChenCommonTimeServer::~CommonTimeServer() {
1536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    shutdownThread();
1546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // No need to grab the lock here.  We are in the destructor; if the the user
1566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // has a thread in any of the APIs while the destructor is being called,
1576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // there is a threading problem a the application level we cannot reasonably
1586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // do anything about.
1596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    cleanupSocket_l();
1606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mWakeupThreadFD >= 0) {
1626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        close(mWakeupThreadFD);
1636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mWakeupThreadFD = -1;
1646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
1656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
1666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::startServices() {
1686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // start the ICommonClock service
1696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mICommonClock = CommonClockService::instantiate(*this);
1706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mICommonClock == NULL)
1716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
1726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // start the ICommonTimeConfig service
1746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mICommonTimeConfig = CommonTimeConfigService::instantiate(*this);
1756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mICommonTimeConfig == NULL)
1766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
1776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return true;
1796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
1806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::threadLoop() {
1826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Register our service interfaces.
1836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!startServices())
1846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
1856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Hold the lock while we are in the main thread loop.  It will release the
1876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // lock when it blocks, and hold the lock at all other times.
1886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mLock.lock();
1896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    runStateMachine_l();
1906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mLock.unlock();
1916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    IPCThreadState::self()->stopProcess();
1936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return false;
1946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
1956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::runStateMachine_l() {
1976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!mLocalClock.initCheck())
1986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
1996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!mCommonClock.init(mLocalClock.getLocalFreq()))
2016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
2026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Enter the initial state.
2046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    becomeInitial("startup");
2056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // run the state machine
2076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    while (!exitPending()) {
2086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        struct pollfd pfds[2];
209c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman        int rc, timeout;
2106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int eventCnt = 0;
2116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int64_t wakeupTime;
212c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman        uint32_t t1, t2;
213c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman        bool needHandleTimeout = false;
2146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // We are always interested in our wakeup FD.
2166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        pfds[eventCnt].fd      = mWakeupThreadFD;
2176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        pfds[eventCnt].events  = POLLIN;
2186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        pfds[eventCnt].revents = 0;
2196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        eventCnt++;
2206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // If we have a valid socket, then we are interested in what it has to
2226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // say as well.
2236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (mSocket >= 0) {
2246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            pfds[eventCnt].fd      = mSocket;
2256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            pfds[eventCnt].events  = POLLIN;
2266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            pfds[eventCnt].revents = 0;
2276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            eventCnt++;
2286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
2296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
230c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman        t1 = static_cast<uint32_t>(mCurTimeout.msecTillTimeout());
231c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman        t2 = static_cast<uint32_t>(mClockRecovery.applyRateLimitedSlew());
232c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman        timeout = static_cast<int>(t1 < t2 ? t1 : t2);
233c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman
2346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // Note, we were holding mLock when this function was called.  We
2356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // release it only while we are blocking and hold it at all other times.
2366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mLock.unlock();
237c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman        rc          = poll(pfds, eventCnt, timeout);
2386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        wakeupTime  = mLocalClock.getLocalTime();
2396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mLock.lock();
2406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // Is it time to shutdown?  If so, don't hesitate... just do it.
2426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (exitPending())
2436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            break;
2446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // Did the poll fail?  This should never happen and is fatal if it does.
2466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (rc < 0) {
2476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            ALOGE("%s:%d poll failed", __PRETTY_FUNCTION__, __LINE__);
2486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return false;
2496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
2506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
251c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman        if (rc == 0) {
252c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman            needHandleTimeout = !mCurTimeout.msecTillTimeout();
253c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman            if (needHandleTimeout)
254c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman                mCurTimeout.setTimeout(kInfiniteTimeout);
255c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman        }
2566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // Were we woken up on purpose?  If so, clear the eventfd with a read.
2586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (pfds[0].revents)
2596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            clearPendingWakeupEvents_l();
2606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // Is out bind address dirty?  If so, clean up our socket (if any).
2626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // Alternatively, do we have an active socket but should be auto
2636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // disabled?  If so, release the socket and enter the proper sync state.
2646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        bool droppedSocket = false;
2656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (mBindIfaceDirty || ((mSocket >= 0) && shouldAutoDisable())) {
2666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            cleanupSocket_l();
2676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            mBindIfaceDirty = false;
2686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            droppedSocket = true;
2696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
2706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // Do we not have a socket but should have one?  If so, try to set one
2726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // up.
2736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if ((mSocket < 0) && mBindIfaceValid && !shouldAutoDisable()) {
2746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            if (setupSocket_l()) {
2756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                // Success!  We are now joining a new network (either coming
2766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                // from no network, or coming from a potentially different
2776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                // network).  Force our priority to be lower so that we defer to
2786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                // any other masters which may already be on the network we are
2796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                // joining.  Later, when we enter either the client or the
2806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                // master state, we will clear this flag and go back to our
2816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                // normal election priority.
2826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                setForceLowPriority(true);
2836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                switch (mState) {
2846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // If we were in initial (whether we had a immediately
2856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // before this network or not) we want to simply reset the
2866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // system and start again.  Forcing a transition from
2876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // INITIAL to INITIAL should do the job.
2886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    case CommonClockService::STATE_INITIAL:
2896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        becomeInitial("bound interface");
2906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        break;
2916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // If we were in the master state, then either we were the
2936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // master in a no-network situation, or we were the master
2946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // of a different network and have moved to a new interface.
295e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman                    // In either case, immediately transition to Ronin at low
296e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman                    // priority.  If there is no one in the network we just
297e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman                    // joined, we will become master soon enough.  If there is,
298e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman                    // we want to be certain to defer master status to the
299e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman                    // existing timeline currently running on the network.
300e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman                    //
3016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    case CommonClockService::STATE_MASTER:
302e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman                        becomeRonin("leaving networkless mode");
3036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        break;
3046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // If we were in any other state (CLIENT, RONIN, or
3066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // WAIT_FOR_ELECTION) then we must be moving from one
3076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // network to another.  We have lost our old master;
3086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // transition to RONIN in an attempt to find a new master.
3096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // If there are none out there, we will just assume
3106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // responsibility for the timeline we used to be a client
3116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // of.
3126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    default:
3136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        becomeRonin("bound interface");
3146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        break;
3156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                }
3166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            } else {
3176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                // That's odd... we failed to set up our socket.  This could be
3186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                // due to some transient network change which will work itself
3196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                // out shortly; schedule a retry attempt in the near future.
3206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                mCurTimeout.setTimeout(kSetupRetryTimeoutMs);
3216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            }
3226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // One way or the other, we don't have any data to process at this
3246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // point (since we just tried to bulid a new socket).  Loop back
3256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // around and wait for the next thing to do.
3266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            continue;
3276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        } else if (droppedSocket) {
3286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // We just lost our socket, and for whatever reason (either no
3296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // config, or auto disable engaged) we are not supposed to rebuild
3306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // one at this time.  We are not going to rebuild our socket until
3316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // something about our config/auto-disabled status changes, so we
3326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // are basically in network-less mode.  If we are already in either
3336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // INITIAL or MASTER, just stay there until something changes.  If
3346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // we are in any other state (CLIENT, RONIN or WAIT_FOR_ELECTION),
3356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // then transition to either INITIAL or MASTER depending on whether
3366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // or not our timeline is valid.
33779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            mStateChangeLog.log(ANDROID_LOG_INFO, LOG_TAG,
33879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                    "Entering networkless mode interface is %s, "
33979489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                    "shouldAutoDisable = %s",
34079489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                    mBindIfaceValid ? "valid" : "invalid",
34179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                    shouldAutoDisable() ? "true" : "false");
3426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            if ((mState != ICommonClock::STATE_INITIAL) &&
3436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                (mState != ICommonClock::STATE_MASTER)) {
3446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                if (mTimelineID == ICommonClock::kInvalidTimelineID)
3456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    becomeInitial("network-less mode");
3466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                else
3476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    becomeMaster("network-less mode");
3486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            }
3496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            continue;
3516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
3526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
353c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman        // Time to handle the timeouts?
354c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman        if (needHandleTimeout) {
3556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            if (!handleTimeout())
3566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                ALOGE("handleTimeout failed");
3576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            continue;
3586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
3596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // Does our socket have data for us (assuming we still have one, we
3616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // may have RXed a packet at the same time as a config change telling us
3626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // to shut our socket down)?  If so, process its data.
3636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if ((mSocket >= 0) && (eventCnt > 1) && (pfds[1].revents)) {
3646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            mLastPacketRxLocalTime = wakeupTime;
3656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            if (!handlePacket())
3666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                ALOGE("handlePacket failed");
3676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
3686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
3696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    cleanupSocket_l();
3716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return true;
3726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
3736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid CommonTimeServer::clearPendingWakeupEvents_l() {
3756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    int64_t tmp;
3766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    read(mWakeupThreadFD, &tmp, sizeof(tmp));
3776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
3786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid CommonTimeServer::wakeupThread_l() {
3806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    int64_t tmp = 1;
3816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    write(mWakeupThreadFD, &tmp, sizeof(tmp));
3826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
3836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid CommonTimeServer::cleanupSocket_l() {
3856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mSocket >= 0) {
3866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        close(mSocket);
3876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mSocket = -1;
3886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
3896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
3906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid CommonTimeServer::shutdownThread() {
3926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Flag the work thread for shutdown.
3936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    this->requestExit();
3946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Signal the thread in case its sleeping.
3966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mLock.lock();
3976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    wakeupThread_l();
3986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mLock.unlock();
3996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Wait for the thread to exit.
4016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    this->join();
4026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
4036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::setupSocket_l() {
4056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    int rc;
4066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    bool ret_val = false;
4076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    struct sockaddr_in* ipv4_addr = NULL;
4086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    char masterElectionEPStr[64];
4096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    const int one = 1;
4106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // This should never be needed, but if we happened to have an old socket
4126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // lying around, be sure to not leak it before proceeding.
4136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    cleanupSocket_l();
4146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // If we don't have a valid endpoint to bind to, then how did we get here in
4166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // the first place?  Regardless, we know that we are going to fail to bind,
4176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // so don't even try.
4186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!mBindIfaceValid)
4196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
4206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    sockaddrToString(mMasterElectionEP, true, masterElectionEPStr,
4226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                     sizeof(masterElectionEPStr));
42379489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    mStateChangeLog.log(ANDROID_LOG_INFO, LOG_TAG,
42479489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                        "Building socket :: bind = %s master election = %s",
42579489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                        mBindIface.string(), masterElectionEPStr);
4266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // TODO: add proper support for IPv6.  Right now, we block IPv6 addresses at
4286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // the configuration interface level.
4296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (AF_INET != mMasterElectionEP.ss_family) {
43079489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        mStateChangeLog.log(ANDROID_LOG_WARN, LOG_TAG,
43179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                            "TODO: add proper IPv6 support");
4326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        goto bailout;
4336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
4346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // open a UDP socket for the timeline serivce
4366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
4376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mSocket < 0) {
43879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        mStateChangeLog.log(ANDROID_LOG_ERROR, LOG_TAG,
43979489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                            "Failed to create socket (errno = %d)", errno);
4406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        goto bailout;
4416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
4426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Bind to the selected interface using Linux's spiffy SO_BINDTODEVICE.
4446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    struct ifreq ifr;
4456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    memset(&ifr, 0, sizeof(ifr));
4466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", mBindIface.string());
4476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = 0;
4486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    rc = setsockopt(mSocket, SOL_SOCKET, SO_BINDTODEVICE,
4496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    (void *)&ifr, sizeof(ifr));
4506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (rc) {
45179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        mStateChangeLog.log(ANDROID_LOG_ERROR, LOG_TAG,
45279489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                            "Failed to bind socket at to interface %s "
45379489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                            "(errno = %d)", ifr.ifr_name, errno);
4546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        goto bailout;
4556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
4566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Bind our socket to INADDR_ANY and the master election port.  The
4586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // interface binding we made using SO_BINDTODEVICE should limit us to
4596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // traffic only on the interface we are interested in.  We need to bind to
4606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // INADDR_ANY and the specific master election port in order to be able to
4616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // receive both unicast traffic and master election multicast traffic with
4626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // just a single socket.
4636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    struct sockaddr_in bindAddr;
4646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ipv4_addr = reinterpret_cast<struct sockaddr_in*>(&mMasterElectionEP);
4656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    memcpy(&bindAddr, ipv4_addr, sizeof(bindAddr));
4666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    bindAddr.sin_addr.s_addr = INADDR_ANY;
4676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    rc = bind(mSocket,
4686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen              reinterpret_cast<const sockaddr *>(&bindAddr),
4696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen              sizeof(bindAddr));
4706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (rc) {
47179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        mStateChangeLog.log(ANDROID_LOG_ERROR, LOG_TAG,
47279489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                            "Failed to bind socket to port %hu (errno = %d)",
47379489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                            ntohs(bindAddr.sin_port), errno);
4746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        goto bailout;
4756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
4766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (0xE0000000 == (ntohl(ipv4_addr->sin_addr.s_addr) & 0xF0000000)) {
4786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // If our master election endpoint is a multicast address, be sure to join
4796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // the multicast group.
4806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        struct ip_mreq mreq;
4816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mreq.imr_multiaddr = ipv4_addr->sin_addr;
4826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mreq.imr_interface.s_addr = htonl(INADDR_ANY);
4836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        rc = setsockopt(mSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP,
4846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        &mreq, sizeof(mreq));
4856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (rc == -1) {
4866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            ALOGE("Failed to join multicast group at %s.  (errno = %d)",
4876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                 masterElectionEPStr, errno);
4886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            goto bailout;
4896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
4906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // disable loopback of multicast packets
4926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        const int zero = 0;
4936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        rc = setsockopt(mSocket, IPPROTO_IP, IP_MULTICAST_LOOP,
4946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        &zero, sizeof(zero));
4956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (rc == -1) {
49679489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            mStateChangeLog.log(ANDROID_LOG_ERROR, LOG_TAG,
49779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                                "Failed to disable multicast loopback "
49879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                                "(errno = %d)", errno);
4996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            goto bailout;
5006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
5016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else
502db63260758ad795d619073e41f273184ab629bbcJason Simmons    if (ntohl(ipv4_addr->sin_addr.s_addr) == 0xFFFFFFFF) {
503db63260758ad795d619073e41f273184ab629bbcJason Simmons        // If the master election address is the broadcast address, then enable
504db63260758ad795d619073e41f273184ab629bbcJason Simmons        // the broadcast socket option
505db63260758ad795d619073e41f273184ab629bbcJason Simmons        rc = setsockopt(mSocket, SOL_SOCKET, SO_BROADCAST, &one, sizeof(one));
506db63260758ad795d619073e41f273184ab629bbcJason Simmons        if (rc == -1) {
50779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            mStateChangeLog.log(ANDROID_LOG_ERROR, LOG_TAG,
50879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                                "Failed to enable broadcast (errno = %d)",
50979489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                                errno);
510db63260758ad795d619073e41f273184ab629bbcJason Simmons            goto bailout;
511db63260758ad795d619073e41f273184ab629bbcJason Simmons        }
512db63260758ad795d619073e41f273184ab629bbcJason Simmons    } else {
5136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // If the master election address is neither broadcast, nor multicast,
5146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // then we are misconfigured.  The config API layer should prevent this
5156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // from ever happening.
5166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        goto bailout;
5176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
5186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Set the TTL of sent packets to 1.  (Time protocol sync should never leave
5206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // the local subnet)
5216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    rc = setsockopt(mSocket, IPPROTO_IP, IP_TTL, &one, sizeof(one));
5226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (rc == -1) {
52379489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        mStateChangeLog.log(ANDROID_LOG_ERROR, LOG_TAG,
52479489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                            "Failed to set TTL to %d (errno = %d)", one, errno);
5256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        goto bailout;
5266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
5276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // get the device's unique ID
5296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!assignDeviceID())
5306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        goto bailout;
5316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ret_val = true;
5336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbailout:
5356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!ret_val)
5366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        cleanupSocket_l();
5376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return ret_val;
5386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
5396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// generate a unique device ID that can be used for arbitration
5416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::assignDeviceID() {
5426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!mBindIfaceValid)
5436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
5446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    struct ifreq ifr;
5466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    memset(&ifr, 0, sizeof(ifr));
5476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ifr.ifr_addr.sa_family = AF_INET;
5486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    strlcpy(ifr.ifr_name, mBindIface.string(), IFNAMSIZ);
5496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    int rc = ioctl(mSocket, SIOCGIFHWADDR, &ifr);
5516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (rc) {
5526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ALOGE("%s:%d ioctl failed", __PRETTY_FUNCTION__, __LINE__);
5536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
5546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
5556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (ifr.ifr_addr.sa_family != ARPHRD_ETHER) {
5576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ALOGE("%s:%d got non-Ethernet address", __PRETTY_FUNCTION__, __LINE__);
5586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
5596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
5606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mDeviceID = 0;
5626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    for (int i = 0; i < ETH_ALEN; i++) {
5636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mDeviceID = (mDeviceID << 8) | ifr.ifr_hwaddr.sa_data[i];
5646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
5656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return true;
5676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
5686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// generate a new timeline ID
5706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid CommonTimeServer::assignTimelineID() {
5716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    do {
5726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mTimelineID = (static_cast<uint64_t>(lrand48()) << 32)
5736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    |  static_cast<uint64_t>(lrand48());
5746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } while (mTimelineID == ICommonClock::kInvalidTimelineID);
5756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
5766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// Select a preference between the device IDs of two potential masters.
5786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// Returns true if the first ID wins, or false if the second ID wins.
5796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::arbitrateMaster(
5806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        uint64_t deviceID1, uint8_t devicePrio1,
5816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        uint64_t deviceID2, uint8_t devicePrio2) {
5826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return ((devicePrio1 >  devicePrio2) ||
5836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen           ((devicePrio1 == devicePrio2) && (deviceID1 > deviceID2)));
5846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
5856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
58679489c4c65d3c8e628991995b4a18f2a81802ee6John Grossmanstatic void hexDumpToString(const uint8_t* src, size_t src_len,
58779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                            char* dst, size_t dst_len) {
588f007bd3cf8cacd75287781c1bb37fe4167c79cbaJohn Grossman    size_t offset = 0;
58979489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    size_t i;
59079489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman
59179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    for (i = 0; (i < src_len) && (offset < dst_len); ++i) {
59279489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        int res;
59379489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        if (0 == (i % 16)) {
594f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat            res = snprintf(dst + offset, dst_len - offset, "\n%04zx :", i);
59579489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            if (res < 0)
59679489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                break;
59779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            offset += res;
59879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            if (offset >= dst_len)
59979489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                break;
60079489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        }
60179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman
60279489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        res = snprintf(dst + offset, dst_len - offset, " %02x", src[i]);
60379489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        if (res < 0)
60479489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            break;
60579489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        offset += res;
60679489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    }
60779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman
60879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    dst[dst_len - 1] = 0;
60979489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman}
61079489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman
6116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::handlePacket() {
6126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint8_t buf[256];
6136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    struct sockaddr_storage srcAddr;
6146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    socklen_t srcAddrLen = sizeof(srcAddr);
6156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
6166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t recvBytes = recvfrom(
6176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            mSocket, buf, sizeof(buf), 0,
6182fa54ef232ef7bb267e5fa53bf556d19564f4c32Elliott Hughes            reinterpret_cast<sockaddr *>(&srcAddr), &srcAddrLen);
6196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
6206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (recvBytes < 0) {
6212fa54ef232ef7bb267e5fa53bf556d19564f4c32Elliott Hughes        mBadPktLog.log(ANDROID_LOG_ERROR, LOG_TAG, "recvfrom failed (%s)",
6222fa54ef232ef7bb267e5fa53bf556d19564f4c32Elliott Hughes                       strerror(errno));
6236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
6246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
6256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
6266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    UniversalTimeServicePacket pkt;
62779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    if (pkt.deserializePacket(buf, recvBytes, mSyncGroupID) < 0) {
62879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        char hex[256];
62979489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        char srcEPStr[64];
63079489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman
63179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        hexDumpToString(buf, static_cast<size_t>(recvBytes), hex, sizeof(hex));
63279489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        sockaddrToString(srcAddr, true, srcEPStr, sizeof(srcEPStr));
63379489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman
63479489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        mBadPktLog.log("Failed to parse %d byte packet from %s.%s",
63579489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                       recvBytes, srcEPStr, hex);
6366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
63779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    }
6386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
6396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    bool result;
6406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    switch (pkt.packetType) {
6416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case TIME_PACKET_WHO_IS_MASTER_REQUEST:
6426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            result = handleWhoIsMasterRequest(&pkt.p.who_is_master_request,
6436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                              srcAddr);
6446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            break;
6456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
6466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case TIME_PACKET_WHO_IS_MASTER_RESPONSE:
6476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            result = handleWhoIsMasterResponse(&pkt.p.who_is_master_response,
6486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                               srcAddr);
6496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            break;
6506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
6516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case TIME_PACKET_SYNC_REQUEST:
6526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            result = handleSyncRequest(&pkt.p.sync_request, srcAddr);
6536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            break;
6546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
6556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case TIME_PACKET_SYNC_RESPONSE:
6566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            result = handleSyncResponse(&pkt.p.sync_response, srcAddr);
6576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            break;
6586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
6596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case TIME_PACKET_MASTER_ANNOUNCEMENT:
6606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            result = handleMasterAnnouncement(&pkt.p.master_announcement,
6616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                              srcAddr);
6626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            break;
6636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
6646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        default: {
66579489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            char srcEPStr[64];
66679489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            sockaddrToString(srcAddr, true, srcEPStr, sizeof(srcEPStr));
66779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman
66879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            mBadPktLog.log(ANDROID_LOG_WARN, LOG_TAG,
66979489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                           "unknown packet type (%d) from %s",
67079489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                           pkt.packetType, srcEPStr);
67179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman
6726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            result = false;
6736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        } break;
6746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
6756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
6766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return result;
6776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
6786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
6796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::handleTimeout() {
6806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // If we have no socket, then this must be a timeout to retry socket setup.
6816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mSocket < 0)
6826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return true;
6836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
6846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    switch (mState) {
6856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case ICommonClock::STATE_INITIAL:
6866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return handleTimeoutInitial();
6876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case ICommonClock::STATE_CLIENT:
6886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return handleTimeoutClient();
6896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case ICommonClock::STATE_MASTER:
6906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return handleTimeoutMaster();
6916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case ICommonClock::STATE_RONIN:
6926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return handleTimeoutRonin();
6936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case ICommonClock::STATE_WAIT_FOR_ELECTION:
6946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return handleTimeoutWaitForElection();
6956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
6966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
6976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return false;
6986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
6996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
7006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::handleTimeoutInitial() {
7016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (++mInitial_WhoIsMasterRequestTimeouts ==
7026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            kInitial_NumWhoIsMasterRetries) {
7036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // none of our attempts to discover a master succeeded, so make
7046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // this device the master
7056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return becomeMaster("initial timeout");
7066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else {
7076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // retry the WhoIsMaster request
7086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return sendWhoIsMasterRequest();
7096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
7106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
7116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
7126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::handleTimeoutClient() {
7136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (shouldPanicNotGettingGoodData())
7146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return becomeInitial("timeout panic, no good data");
7156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
7166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mClient_SyncRequestPending) {
7176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mClient_SyncRequestPending = false;
7186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
7196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (++mClient_SyncRequestTimeouts < kClient_NumSyncRequestRetries) {
7206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // a sync request has timed out, so retry
7216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return sendSyncRequest();
7226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        } else {
7236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // The master has failed to respond to a sync request for too many
7246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // times in a row.  Assume the master is dead and start electing
7256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // a new master.
7266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return becomeRonin("master not responding");
7276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
7286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else {
7296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // initiate the next sync request
7306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return sendSyncRequest();
7316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
7326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
7336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
7346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::handleTimeoutMaster() {
7356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // send another announcement from the master
7366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return sendMasterAnnouncement();
7376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
7386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
7396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::handleTimeoutRonin() {
7406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (++mRonin_WhoIsMasterRequestTimeouts == kRonin_NumWhoIsMasterRetries) {
7416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // no other master is out there, so we won the election
7426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return becomeMaster("no better masters detected");
7436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else {
7446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return sendWhoIsMasterRequest();
7456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
7466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
7476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
7486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::handleTimeoutWaitForElection() {
7496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return becomeRonin("timeout waiting for election conclusion");
7506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
7516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
7526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::handleWhoIsMasterRequest(
7536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        const WhoIsMasterRequestPacket* request,
7546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        const sockaddr_storage& srcAddr) {
7557a947c49782165d7320a93d8685d99730286f9a7John Grossman    // Skip our own messages which come back via broadcast loopback.
7567a947c49782165d7320a93d8685d99730286f9a7John Grossman    if (request->senderDeviceID == mDeviceID)
7577a947c49782165d7320a93d8685d99730286f9a7John Grossman        return true;
75879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman
75979489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    char srcEPStr[64];
76079489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    sockaddrToString(srcAddr, true, srcEPStr, sizeof(srcEPStr));
76179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    mElectionLog.log("RXed WhoIs master request while in state %s.  "
76279489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                     "src %s reqTID %016llx ourTID %016llx",
76379489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                     stateToString(mState), srcEPStr,
76479489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                     request->timelineID, mTimelineID);
76579489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman
7666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mState == ICommonClock::STATE_MASTER) {
7676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // is this request related to this master's timeline?
7686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (request->timelineID != ICommonClock::kInvalidTimelineID &&
7696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            request->timelineID != mTimelineID)
7706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return true;
7716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
7726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        WhoIsMasterResponsePacket pkt;
7736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        pkt.initHeader(mTimelineID, mSyncGroupID);
7746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        pkt.deviceID = mDeviceID;
7756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        pkt.devicePriority = effectivePriority();
7766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
77779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        mElectionLog.log("TXing WhoIs master resp to %s while in state %s.  "
77879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                         "ourTID %016llx ourGID %016llx ourDID %016llx "
77979489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                         "ourPrio %u",
78079489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                         srcEPStr, stateToString(mState),
78179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                         mTimelineID, mSyncGroupID,
78279489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                         pkt.deviceID, pkt.devicePriority);
78379489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman
7846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        uint8_t buf[256];
7856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
7866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (bufSz < 0)
7876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return false;
7886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
7896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ssize_t sendBytes = sendto(
7906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                mSocket, buf, bufSz, 0,
7916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                reinterpret_cast<const sockaddr *>(&srcAddr),
7926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                sizeof(srcAddr));
7936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (sendBytes == -1) {
7946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            ALOGE("%s:%d sendto failed", __PRETTY_FUNCTION__, __LINE__);
7956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return false;
7966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
7976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else if (mState == ICommonClock::STATE_RONIN) {
7986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // if we hear a WhoIsMaster request from another device following
7996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // the same timeline and that device wins arbitration, then we will stop
8006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // trying to elect ourselves master and will instead wait for an
8016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // announcement from the election winner
8026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (request->timelineID != mTimelineID)
8036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return true;
8046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
8056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (arbitrateMaster(request->senderDeviceID,
8066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            request->senderDevicePriority,
8076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            mDeviceID,
8086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            effectivePriority()))
8096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return becomeWaitForElection("would lose election");
8106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
8116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return true;
8126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else if (mState == ICommonClock::STATE_INITIAL) {
8136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // If a group of devices booted simultaneously (e.g. after a power
8146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // outage) and all of them are in the initial state and there is no
8156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // master, then each device may time out and declare itself master at
8166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // the same time.  To avoid this, listen for
8176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // WhoIsMaster(InvalidTimeline) requests from peers.  If we would lose
8186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // arbitration against that peer, reset our timeout count so that the
8196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // peer has a chance to become master before we time out.
8206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (request->timelineID == ICommonClock::kInvalidTimelineID &&
8216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                arbitrateMaster(request->senderDeviceID,
8226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                request->senderDevicePriority,
8236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                mDeviceID,
8246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                effectivePriority())) {
8256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            mInitial_WhoIsMasterRequestTimeouts = 0;
8266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
8276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
8286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
8296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return true;
8306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
8316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
8326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::handleWhoIsMasterResponse(
8336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        const WhoIsMasterResponsePacket* response,
8346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        const sockaddr_storage& srcAddr) {
8357a947c49782165d7320a93d8685d99730286f9a7John Grossman    // Skip our own messages which come back via broadcast loopback.
8367a947c49782165d7320a93d8685d99730286f9a7John Grossman    if (response->deviceID == mDeviceID)
8377a947c49782165d7320a93d8685d99730286f9a7John Grossman        return true;
8387a947c49782165d7320a93d8685d99730286f9a7John Grossman
83979489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    char srcEPStr[64];
84079489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    sockaddrToString(srcAddr, true, srcEPStr, sizeof(srcEPStr));
84179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    mElectionLog.log("RXed WhoIs master response while in state %s.  "
84279489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                     "src %s respTID %016llx respDID %016llx respPrio %u "
84379489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                     "ourTID %016llx",
84479489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                     stateToString(mState), srcEPStr,
84579489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                     response->timelineID,
84679489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                     response->deviceID,
84779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                     static_cast<uint32_t>(response->devicePriority),
84879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                     mTimelineID);
84979489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman
8506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mState == ICommonClock::STATE_INITIAL || mState == ICommonClock::STATE_RONIN) {
8516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return becomeClient(srcAddr,
8526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            response->deviceID,
8536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            response->devicePriority,
8546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            response->timelineID,
8556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            "heard whois response");
8566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else if (mState == ICommonClock::STATE_CLIENT) {
8576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // if we get multiple responses because there are multiple devices
8586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // who believe that they are master, then follow the master that
8596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // wins arbitration
8606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (arbitrateMaster(response->deviceID,
8616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            response->devicePriority,
8626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            mClient_MasterDeviceID,
8636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            mClient_MasterDevicePriority)) {
8646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return becomeClient(srcAddr,
8656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                response->deviceID,
8666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                response->devicePriority,
8676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                response->timelineID,
8686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                "heard whois response");
8696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
8706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
8716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
8726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return true;
8736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
8746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
8756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::handleSyncRequest(const SyncRequestPacket* request,
8766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                         const sockaddr_storage& srcAddr) {
8776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    SyncResponsePacket pkt;
8786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    pkt.initHeader(mTimelineID, mSyncGroupID);
8796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
8806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if ((mState == ICommonClock::STATE_MASTER) &&
8816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        (mTimelineID == request->timelineID)) {
8826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int64_t rxLocalTime = mLastPacketRxLocalTime;
8836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int64_t rxCommonTime;
8846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
8856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // If we are master on an actual network and have actual clients, then
8866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // we are no longer low priority.
8876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        setForceLowPriority(false);
8886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
8896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (OK != mCommonClock.localToCommon(rxLocalTime, &rxCommonTime)) {
8906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return false;
8916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
8926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
8936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int64_t txLocalTime = mLocalClock.getLocalTime();;
8946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int64_t txCommonTime;
8956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (OK != mCommonClock.localToCommon(txLocalTime, &txCommonTime)) {
8966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return false;
8976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
8986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
8996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        pkt.nak = 0;
9006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        pkt.clientTxLocalTime  = request->clientTxLocalTime;
9016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        pkt.masterRxCommonTime = rxCommonTime;
9026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        pkt.masterTxCommonTime = txCommonTime;
9036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else {
9046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        pkt.nak = 1;
9056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        pkt.clientTxLocalTime  = 0;
9066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        pkt.masterRxCommonTime = 0;
9076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        pkt.masterTxCommonTime = 0;
9086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
9096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
9106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint8_t buf[256];
9116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
9126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (bufSz < 0)
9136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
9146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
9156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t sendBytes = sendto(
9166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            mSocket, &buf, bufSz, 0,
9176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            reinterpret_cast<const sockaddr *>(&srcAddr),
9186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            sizeof(srcAddr));
9196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (sendBytes == -1) {
9206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ALOGE("%s:%d sendto failed", __PRETTY_FUNCTION__, __LINE__);
9216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
9226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
9236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
9246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return true;
9256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
9266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
9276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::handleSyncResponse(
9286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        const SyncResponsePacket* response,
9296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        const sockaddr_storage& srcAddr) {
9306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mState != ICommonClock::STATE_CLIENT)
9316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return true;
9326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
9336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    assert(mMasterEPValid);
9346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!sockaddrMatch(srcAddr, mMasterEP, true)) {
9356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        char srcEP[64], expectedEP[64];
9366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        sockaddrToString(srcAddr, true, srcEP, sizeof(srcEP));
9376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        sockaddrToString(mMasterEP, true, expectedEP, sizeof(expectedEP));
9386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ALOGI("Dropping sync response from unexpected address."
9396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             " Expected %s Got %s", expectedEP, srcEP);
9406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return true;
9416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
9426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
9436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (response->nak) {
9446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // if our master is no longer accepting requests, then we need to find
9456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // a new master
9466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return becomeRonin("master NAK'ed");
9476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
9486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
9496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClient_SyncRequestPending = 0;
9506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClient_SyncRequestTimeouts = 0;
9516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClient_PacketRTTLog.logRX(response->clientTxLocalTime,
9526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                               mLastPacketRxLocalTime);
9536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
9546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    bool result;
9556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!(mClient_SyncRespsRXedFromCurMaster++)) {
9566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // the first request/response exchange between a client and a master
9576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // may take unusually long due to ARP, so discard it.
9586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        result = true;
9596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else {
9606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int64_t clientTxLocalTime  = response->clientTxLocalTime;
9616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int64_t clientRxLocalTime  = mLastPacketRxLocalTime;
9626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int64_t masterTxCommonTime = response->masterTxCommonTime;
9636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int64_t masterRxCommonTime = response->masterRxCommonTime;
9646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
9656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int64_t rtt       = (clientRxLocalTime - clientTxLocalTime);
9666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int64_t avgLocal  = (clientTxLocalTime + clientRxLocalTime) >> 1;
9676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int64_t avgCommon = (masterTxCommonTime + masterRxCommonTime) >> 1;
9686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
9696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // if the RTT of the packet is significantly larger than the panic
9706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // threshold, we should simply discard it.  Its better to do nothing
9716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // than to take cues from a packet like that.
9724c57eda9f4c87bb22eb0acdd2dab4d1757d4280bAndreas Gampe        int64_t rttCommon = mCommonClock.localDurationToCommonDuration(rtt);
9736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (rttCommon > (static_cast<int64_t>(mPanicThresholdUsec) *
9746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                         kRTTDiscardPanicThreshMultiplier)) {
9754c57eda9f4c87bb22eb0acdd2dab4d1757d4280bAndreas Gampe            ALOGV("Dropping sync response with RTT of %" PRId64 " uSec", rttCommon);
9766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            mClient_ExpiredSyncRespsRXedFromCurMaster++;
9776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            if (shouldPanicNotGettingGoodData())
9786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                return becomeInitial("RX panic, no good data");
9794c57eda9f4c87bb22eb0acdd2dab4d1757d4280bAndreas Gampe            return true;
9806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        } else {
98111bc45fcba96cf7ccc5f67b3c47088c2c89c8e7aKent Ryhorchuk            result = mClockRecovery.pushDisciplineEvent(avgLocal, avgCommon, rttCommon);
9826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            mClient_LastGoodSyncRX = clientRxLocalTime;
9836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
9846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            if (result) {
9856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                // indicate to listeners that we've synced to the common timeline
9866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                notifyClockSync();
9876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            } else {
9886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                ALOGE("Panic!  Observed clock sync error is too high to tolerate,"
9896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        " resetting state machine and starting over.");
9906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                notifyClockSyncLoss();
9916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                return becomeInitial("panic");
9926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            }
9936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
9946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
9956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
9966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mCurTimeout.setTimeout(mSyncRequestIntervalMs);
9976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return result;
9986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
9996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
10006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::handleMasterAnnouncement(
10016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        const MasterAnnouncementPacket* packet,
10026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        const sockaddr_storage& srcAddr) {
10036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint64_t newDeviceID   = packet->deviceID;
10046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint8_t  newDevicePrio = packet->devicePriority;
10056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint64_t newTimelineID = packet->timelineID;
10066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
10077a947c49782165d7320a93d8685d99730286f9a7John Grossman    // Skip our own messages which come back via broadcast loopback.
10087a947c49782165d7320a93d8685d99730286f9a7John Grossman    if (newDeviceID == mDeviceID)
10097a947c49782165d7320a93d8685d99730286f9a7John Grossman        return true;
10107a947c49782165d7320a93d8685d99730286f9a7John Grossman
101179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    char srcEPStr[64];
101279489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    sockaddrToString(srcAddr, true, srcEPStr, sizeof(srcEPStr));
101379489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    mElectionLog.log("RXed master announcement while in state %s.  "
101479489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                     "src %s srcDevID %lld srcPrio %u srcTID %016llx",
101579489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                     stateToString(mState), srcEPStr,
101679489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                     newDeviceID, static_cast<uint32_t>(newDevicePrio),
101779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                     newTimelineID);
101879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman
10196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mState == ICommonClock::STATE_INITIAL ||
10206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mState == ICommonClock::STATE_RONIN ||
10216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mState == ICommonClock::STATE_WAIT_FOR_ELECTION) {
10226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // if we aren't currently following a master, then start following
10236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // this new master
10246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return becomeClient(srcAddr,
10256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            newDeviceID,
10266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            newDevicePrio,
10276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            newTimelineID,
10286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            "heard master announcement");
10296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else if (mState == ICommonClock::STATE_CLIENT) {
10306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // if the new master wins arbitration against our current master,
10316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // then become a client of the new master
10326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (arbitrateMaster(newDeviceID,
10336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            newDevicePrio,
10346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            mClient_MasterDeviceID,
10356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            mClient_MasterDevicePriority))
10366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return becomeClient(srcAddr,
10376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                newDeviceID,
10386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                newDevicePrio,
10396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                newTimelineID,
10406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                "heard master announcement");
10416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else if (mState == ICommonClock::STATE_MASTER) {
10426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // two masters are competing - if the new one wins arbitration, then
10436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // cease acting as master
10446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (arbitrateMaster(newDeviceID, newDevicePrio,
10456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            mDeviceID, effectivePriority()))
10466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return becomeClient(srcAddr, newDeviceID,
10476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                newDevicePrio, newTimelineID,
10486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                "heard master announcement");
10496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
10506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
10516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return true;
10526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
10536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
10546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::sendWhoIsMasterRequest() {
10556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    assert(mState == ICommonClock::STATE_INITIAL || mState == ICommonClock::STATE_RONIN);
10566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
10576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // If we have no socket, then we must be in the unconfigured initial state.
10586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Don't report any errors, just don't try to send the initial who-is-master
10596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // query.  Eventually, our network will either become configured, or we will
10606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // be forced into network-less master mode by higher level code.
10616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mSocket < 0) {
10626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        assert(mState == ICommonClock::STATE_INITIAL);
10636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return true;
10646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
10656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
10666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    bool ret = false;
10676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    WhoIsMasterRequestPacket pkt;
10686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    pkt.initHeader(mSyncGroupID);
10696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    pkt.senderDeviceID = mDeviceID;
10706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    pkt.senderDevicePriority = effectivePriority();
10716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
10726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint8_t buf[256];
10736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
10746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (bufSz >= 0) {
107579489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        char dstEPStr[64];
107679489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        sockaddrToString(mMasterElectionEP, true, dstEPStr, sizeof(dstEPStr));
107779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        mElectionLog.log("TXing WhoIs master request to %s while in state %s.  "
107879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                         "ourTID %016llx ourGID %016llx ourDID %016llx "
107979489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                         "ourPrio %u",
108079489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                         dstEPStr, stateToString(mState),
108179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                         mTimelineID, mSyncGroupID,
108279489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                         pkt.senderDeviceID, pkt.senderDevicePriority);
108379489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman
10846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ssize_t sendBytes = sendto(
10856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                mSocket, buf, bufSz, 0,
10866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                reinterpret_cast<const sockaddr *>(&mMasterElectionEP),
10876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                sizeof(mMasterElectionEP));
10886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (sendBytes < 0)
10896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            ALOGE("WhoIsMaster sendto failed (errno %d)", errno);
10906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ret = true;
10916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
10926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
10936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mState == ICommonClock::STATE_INITIAL) {
10946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mCurTimeout.setTimeout(kInitial_WhoIsMasterTimeoutMs);
10956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else {
10966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mCurTimeout.setTimeout(kRonin_WhoIsMasterTimeoutMs);
10976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
10986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
10996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return ret;
11006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
11016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::sendSyncRequest() {
11036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // If we are sending sync requests, then we must be in the client state and
11046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // we must have a socket (when we have no network, we are only supposed to
11056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // be in INITIAL or MASTER)
11066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    assert(mState == ICommonClock::STATE_CLIENT);
11076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    assert(mSocket >= 0);
11086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    bool ret = false;
11106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    SyncRequestPacket pkt;
11116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    pkt.initHeader(mTimelineID, mSyncGroupID);
11126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    pkt.clientTxLocalTime = mLocalClock.getLocalTime();
11136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!mClient_FirstSyncTX)
11156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mClient_FirstSyncTX = pkt.clientTxLocalTime;
11166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClient_PacketRTTLog.logTX(pkt.clientTxLocalTime);
11186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint8_t buf[256];
11206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
11216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (bufSz >= 0) {
11226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ssize_t sendBytes = sendto(
11236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                mSocket, buf, bufSz, 0,
11246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                reinterpret_cast<const sockaddr *>(&mMasterEP),
11256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                sizeof(mMasterEP));
11266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (sendBytes < 0)
11276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            ALOGE("SyncRequest sendto failed (errno %d)", errno);
11286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ret = true;
11296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
11306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClient_SyncsSentToCurMaster++;
11326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mCurTimeout.setTimeout(mSyncRequestIntervalMs);
11336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClient_SyncRequestPending = true;
11346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return ret;
11366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
11376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::sendMasterAnnouncement() {
11396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    bool ret = false;
11406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    assert(mState == ICommonClock::STATE_MASTER);
11416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // If we are being asked to send a master announcement, but we have no
11436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // socket, we must be in network-less master mode.  Don't bother to send the
11446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // announcement, and don't bother to schedule a timeout.  When the network
11456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // comes up, the work thread will get poked and start the process of
11466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // figuring out who the current master should be.
11476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mSocket < 0) {
11486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mCurTimeout.setTimeout(kInfiniteTimeout);
11496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return true;
11506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
11516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    MasterAnnouncementPacket pkt;
11536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    pkt.initHeader(mTimelineID, mSyncGroupID);
11546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    pkt.deviceID = mDeviceID;
11556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    pkt.devicePriority = effectivePriority();
11566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint8_t buf[256];
11586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
11596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (bufSz >= 0) {
116079489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        char dstEPStr[64];
116179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        sockaddrToString(mMasterElectionEP, true, dstEPStr, sizeof(dstEPStr));
116279489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        mElectionLog.log("TXing Master announcement to %s while in state %s.  "
116379489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                         "ourTID %016llx ourGID %016llx ourDID %016llx "
116479489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                         "ourPrio %u",
116579489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                         dstEPStr, stateToString(mState),
116679489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                         mTimelineID, mSyncGroupID,
116779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                         pkt.deviceID, pkt.devicePriority);
116879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman
11696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ssize_t sendBytes = sendto(
11706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                mSocket, buf, bufSz, 0,
11716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                reinterpret_cast<const sockaddr *>(&mMasterElectionEP),
11726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                sizeof(mMasterElectionEP));
11736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (sendBytes < 0)
11746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            ALOGE("MasterAnnouncement sendto failed (errno %d)", errno);
11756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ret = true;
11766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
11776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mCurTimeout.setTimeout(mMasterAnnounceIntervalMs);
11796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return ret;
11806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
11816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::becomeClient(const sockaddr_storage& masterEP,
11836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                    uint64_t masterDeviceID,
11846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                    uint8_t  masterDevicePriority,
11856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                    uint64_t timelineID,
11866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                    const char* cause) {
11876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    char newEPStr[64], oldEPStr[64];
11886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    sockaddrToString(masterEP, true, newEPStr, sizeof(newEPStr));
11896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    sockaddrToString(mMasterEP, mMasterEPValid, oldEPStr, sizeof(oldEPStr));
11906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
119179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    mStateChangeLog.log(ANDROID_LOG_INFO, LOG_TAG,
119279489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            "%s --> CLIENT (%s) :%s"
119379489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            " OldMaster: %02x-%014llx::%016llx::%s"
119479489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            " NewMaster: %02x-%014llx::%016llx::%s",
119579489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            stateToString(mState), cause,
119679489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            (mTimelineID != timelineID) ? " (new timeline)" : "",
119779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            mClient_MasterDevicePriority, mClient_MasterDeviceID,
119879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            mTimelineID, oldEPStr,
119979489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            masterDevicePriority, masterDeviceID,
120079489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            timelineID, newEPStr);
12016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mTimelineID != timelineID) {
12036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // start following a new timeline
12046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mTimelineID = timelineID;
12056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mClockRecovery.reset(true, true);
12066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        notifyClockSyncLoss();
12076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else {
12086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // start following a new master on the existing timeline
12096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mClockRecovery.reset(false, true);
12106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
12116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mMasterEP = masterEP;
12136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mMasterEPValid = true;
1214e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman
1215e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman    // If we are on a real network as a client of a real master, then we should
1216e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman    // no longer force low priority.  If our master disappears, we should have
1217e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman    // the high priority bit set during the election to replace the master
1218e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman    // because this group was a real group and not a singleton created in
1219e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman    // networkless mode.
12206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    setForceLowPriority(false);
12216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClient_MasterDeviceID = masterDeviceID;
12236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClient_MasterDevicePriority = masterDevicePriority;
12246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    resetSyncStats();
12256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    setState(ICommonClock::STATE_CLIENT);
12276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // add some jitter to when the various clients send their requests
12296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // in order to reduce the likelihood that a group of clients overload
12306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // the master after receiving a master announcement
12316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    usleep((lrand48() % 100) * 1000);
12326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return sendSyncRequest();
12346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
12356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::becomeMaster(const char* cause) {
12376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint64_t oldTimelineID = mTimelineID;
12386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mTimelineID == ICommonClock::kInvalidTimelineID) {
12396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // this device has not been following any existing timeline,
12406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // so it will create a new timeline and declare itself master
12416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        assert(!mCommonClock.isValid());
12426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // set the common time basis
12446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mCommonClock.setBasis(mLocalClock.getLocalTime(), 0);
12456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // assign an arbitrary timeline iD
12476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        assignTimelineID();
12486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // notify listeners that we've created a common timeline
12506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        notifyClockSync();
12516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
12526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
125379489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    mStateChangeLog.log(ANDROID_LOG_INFO, LOG_TAG,
125479489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            "%s --> MASTER (%s) : %s timeline %016llx",
125579489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            stateToString(mState), cause,
125679489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            (oldTimelineID == mTimelineID) ? "taking ownership of"
125779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                                           : "creating new",
125879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            mTimelineID);
12596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    memset(&mMasterEP, 0, sizeof(mMasterEP));
12616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mMasterEPValid = false;
12626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClient_MasterDevicePriority = effectivePriority();
12636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClient_MasterDeviceID = mDeviceID;
12646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClockRecovery.reset(false, true);
12656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    resetSyncStats();
12666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    setState(ICommonClock::STATE_MASTER);
12686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return sendMasterAnnouncement();
12696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
12706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::becomeRonin(const char* cause) {
12726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // If we were the client of a given timeline, but had never received even a
12736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // single time sync packet, then we transition back to Initial instead of
12746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Ronin.  If we transition to Ronin and end up becoming the new Master, we
12756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // will be unable to service requests for other clients because we never
12766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // actually knew what time it was.  By going to initial, we ensure that
12776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // other clients who know what time it is, but would lose master arbitration
12786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // in the Ronin case, will step up and become the proper new master of the
12796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // old timeline.
12806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    char oldEPStr[64];
12826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    sockaddrToString(mMasterEP, mMasterEPValid, oldEPStr, sizeof(oldEPStr));
12836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    memset(&mMasterEP, 0, sizeof(mMasterEP));
12846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mMasterEPValid = false;
12856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mCommonClock.isValid()) {
128779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        mStateChangeLog.log(ANDROID_LOG_INFO, LOG_TAG,
128879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman             "%s --> RONIN (%s) : lost track of previously valid timeline "
12896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             "%02x-%014llx::%016llx::%s (%d TXed %d RXed %d RXExpired)",
12906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             stateToString(mState), cause,
12916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             mClient_MasterDevicePriority, mClient_MasterDeviceID,
12926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             mTimelineID, oldEPStr,
12936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             mClient_SyncsSentToCurMaster,
12946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             mClient_SyncRespsRXedFromCurMaster,
12956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             mClient_ExpiredSyncRespsRXedFromCurMaster);
12966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mRonin_WhoIsMasterRequestTimeouts = 0;
12986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        setState(ICommonClock::STATE_RONIN);
12996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return sendWhoIsMasterRequest();
13006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else {
130179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        mStateChangeLog.log(ANDROID_LOG_INFO, LOG_TAG,
130279489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman             "%s --> INITIAL (%s) : never synced timeline "
13036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             "%02x-%014llx::%016llx::%s (%d TXed %d RXed %d RXExpired)",
13046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             stateToString(mState), cause,
13056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             mClient_MasterDevicePriority, mClient_MasterDeviceID,
13066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             mTimelineID, oldEPStr,
13076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             mClient_SyncsSentToCurMaster,
13086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             mClient_SyncRespsRXedFromCurMaster,
13096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             mClient_ExpiredSyncRespsRXedFromCurMaster);
13106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return becomeInitial("ronin, no timeline");
13126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
13136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
13146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::becomeWaitForElection(const char* cause) {
131679489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    mStateChangeLog.log(ANDROID_LOG_INFO, LOG_TAG,
131779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman         "%s --> WAIT_FOR_ELECTION (%s) : dropping out of election,"
13186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen         " waiting %d mSec for completion.",
13196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen         stateToString(mState), cause, kWaitForElection_TimeoutMs);
13206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    setState(ICommonClock::STATE_WAIT_FOR_ELECTION);
13226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mCurTimeout.setTimeout(kWaitForElection_TimeoutMs);
13236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return true;
13246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
13256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::becomeInitial(const char* cause) {
132779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    mStateChangeLog.log(ANDROID_LOG_INFO, LOG_TAG,
132879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                        "Entering INITIAL (%s), total reset.",
132979489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                        cause);
13306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    setState(ICommonClock::STATE_INITIAL);
13326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // reset clock recovery
13346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClockRecovery.reset(true, true);
13356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // reset internal state bookkeeping.
13376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mCurTimeout.setTimeout(kInfiniteTimeout);
13386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    memset(&mMasterEP, 0, sizeof(mMasterEP));
13396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mMasterEPValid = false;
13406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mLastPacketRxLocalTime = 0;
13416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mTimelineID = ICommonClock::kInvalidTimelineID;
13426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClockSynced = false;
13436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mInitial_WhoIsMasterRequestTimeouts = 0;
13446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClient_MasterDeviceID = 0;
13456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClient_MasterDevicePriority = 0;
13466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mRonin_WhoIsMasterRequestTimeouts = 0;
13476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    resetSyncStats();
13486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // send the first request to discover the master
13506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return sendWhoIsMasterRequest();
13516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
13526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid CommonTimeServer::notifyClockSync() {
13546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!mClockSynced) {
13556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mClockSynced = true;
13566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mICommonClock->notifyOnTimelineChanged(mTimelineID);
13576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
13586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
13596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid CommonTimeServer::notifyClockSyncLoss() {
13616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mClockSynced) {
13626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mClockSynced = false;
13636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mICommonClock->notifyOnTimelineChanged(
13646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                ICommonClock::kInvalidTimelineID);
13656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
13666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
13676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid CommonTimeServer::setState(ICommonClock::State s) {
13696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mState = s;
13706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
13716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst char* CommonTimeServer::stateToString(ICommonClock::State s) {
13736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    switch(s) {
13746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case ICommonClock::STATE_INITIAL:
13756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return "INITIAL";
13766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case ICommonClock::STATE_CLIENT:
13776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return "CLIENT";
13786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case ICommonClock::STATE_MASTER:
13796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return "MASTER";
13806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case ICommonClock::STATE_RONIN:
13816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return "RONIN";
13826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case ICommonClock::STATE_WAIT_FOR_ELECTION:
13836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return "WAIT_FOR_ELECTION";
13846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        default:
13856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return "unknown";
13866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
13876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
13886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid CommonTimeServer::sockaddrToString(const sockaddr_storage& addr,
13906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                        bool addrValid,
13916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                        char* buf, size_t bufLen) {
13926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!bufLen || !buf)
13936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return;
13946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (addrValid) {
13966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        switch (addr.ss_family) {
13976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            case AF_INET: {
13986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                const struct sockaddr_in* sa =
13996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    reinterpret_cast<const struct sockaddr_in*>(&addr);
14006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                unsigned long a = ntohl(sa->sin_addr.s_addr);
14016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                uint16_t      p = ntohs(sa->sin_port);
14026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                snprintf(buf, bufLen, "%lu.%lu.%lu.%lu:%hu",
14036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        ((a >> 24) & 0xFF), ((a >> 16) & 0xFF),
14046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        ((a >>  8) & 0xFF),  (a        & 0xFF), p);
14056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            } break;
14066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
14076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            case AF_INET6: {
14086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                const struct sockaddr_in6* sa =
14096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    reinterpret_cast<const struct sockaddr_in6*>(&addr);
14106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                const uint8_t* a = sa->sin6_addr.s6_addr;
14116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                uint16_t       p = ntohs(sa->sin6_port);
14126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                snprintf(buf, bufLen,
14136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        "%02X%02X:%02X%02X:%02X%02X:%02X%02X:"
14146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        "%02X%02X:%02X%02X:%02X%02X:%02X%02X port %hd",
14156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        a[0], a[1], a[ 2], a[ 3], a[ 4], a[ 5], a[ 6], a[ 7],
14166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15],
14176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        p);
14186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            } break;
14196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
14206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            default:
14216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                snprintf(buf, bufLen,
14226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                         "<unknown sockaddr family %d>", addr.ss_family);
14236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                break;
14246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
14256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else {
14266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        snprintf(buf, bufLen, "<none>");
14276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
14286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
14296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    buf[bufLen - 1] = 0;
14306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
14316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
14326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::sockaddrMatch(const sockaddr_storage& a1,
14336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                     const sockaddr_storage& a2,
14346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                     bool matchAddressOnly) {
14356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (a1.ss_family != a2.ss_family)
14366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
14376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
14386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    switch (a1.ss_family) {
14396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case AF_INET: {
14406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            const struct sockaddr_in* sa1 =
14416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                reinterpret_cast<const struct sockaddr_in*>(&a1);
14426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            const struct sockaddr_in* sa2 =
14436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                reinterpret_cast<const struct sockaddr_in*>(&a2);
14446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
14456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            if (sa1->sin_addr.s_addr != sa2->sin_addr.s_addr)
14466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                return false;
14476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
14486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return (matchAddressOnly || (sa1->sin_port == sa2->sin_port));
14496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        } break;
14506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
14516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case AF_INET6: {
14526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            const struct sockaddr_in6* sa1 =
14536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                reinterpret_cast<const struct sockaddr_in6*>(&a1);
14546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            const struct sockaddr_in6* sa2 =
14556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                reinterpret_cast<const struct sockaddr_in6*>(&a2);
14566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
14576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            if (memcmp(&sa1->sin6_addr, &sa2->sin6_addr, sizeof(sa2->sin6_addr)))
14586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                return false;
14596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
14606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return (matchAddressOnly || (sa1->sin6_port == sa2->sin6_port));
14616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        } break;
14626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
14636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // Huh?  We don't deal in non-IPv[46] addresses.  Not sure how we got
14646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // here, but we don't know how to comapre these addresses and simply
14656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // default to a no-match decision.
14666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        default: return false;
14676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
14686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
14696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
14706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::shouldPanicNotGettingGoodData() {
14716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mClient_FirstSyncTX) {
14726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int64_t now = mLocalClock.getLocalTime();
14736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int64_t delta = now - (mClient_LastGoodSyncRX
14746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                             ? mClient_LastGoodSyncRX
14756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                             : mClient_FirstSyncTX);
14766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int64_t deltaUsec = mCommonClock.localDurationToCommonDuration(delta);
14776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
14786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (deltaUsec >= kNoGoodDataPanicThresholdUsec)
14796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return true;
14806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
14816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
14826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return false;
14836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
14846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
14856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid CommonTimeServer::PacketRTTLog::logTX(int64_t txTime) {
14866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    txTimes[wrPtr] = txTime;
14876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    rxTimes[wrPtr] = 0;
14886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    wrPtr = (wrPtr + 1) % RTT_LOG_SIZE;
14896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!wrPtr)
14906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        logFull = true;
14916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
14926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
14936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid CommonTimeServer::PacketRTTLog::logRX(int64_t txTime, int64_t rxTime) {
14946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!logFull && !wrPtr)
14956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return;
14966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
14976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint32_t i = logFull ? wrPtr : 0;
14986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    do {
14996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (txTimes[i] == txTime) {
15006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            rxTimes[i] = rxTime;
15016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            break;
15026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
15036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        i = (i + 1) % RTT_LOG_SIZE;
15046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } while (i != wrPtr);
15056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
15066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
15076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}  // namespace android
1508