common_time_server.cpp revision f5df700e6ce056ebfa322314d970e52d6facc35a
16c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen/*
26c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * Copyright (C) 2012 The Android Open Source Project
36c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen *
46c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * Licensed under the Apache License, Version 2.0 (the "License");
56c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * you may not use this file except in compliance with the License.
66c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * You may obtain a copy of the License at
76c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen *
86c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen *      http://www.apache.org/licenses/LICENSE-2.0
96c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen *
106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * Unless required by applicable law or agreed to in writing, software
116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * distributed under the License is distributed on an "AS IS" BASIS,
126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * See the License for the specific language governing permissions and
146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * limitations under the License.
156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen */
166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen/*
186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * A service that exchanges time synchronization information between
196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * a master that defines a timeline and clients that follow the timeline.
206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen */
216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#define LOG_TAG "common_time"
236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <utils/Log.h>
246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <arpa/inet.h>
266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <assert.h>
276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <fcntl.h>
286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <linux/if_ether.h>
296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <net/if.h>
306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <net/if_arp.h>
316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <netinet/ip.h>
326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <poll.h>
336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <stdio.h>
346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <sys/eventfd.h>
356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <sys/ioctl.h>
366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <sys/stat.h>
376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <sys/types.h>
386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <sys/socket.h>
396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <common_time/local_clock.h>
416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <binder/IPCThreadState.h>
426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <binder/ProcessState.h>
436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <utils/Timers.h>
446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include "common_clock_service.h"
466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include "common_time_config_service.h"
476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include "common_time_server.h"
486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include "common_time_server_packets.h"
496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include "clock_recovery.h"
506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include "common_clock.h"
516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
52b8525e9a76d63a2dc26c87577940a058e70e3dd5John Grossman#define MAX_INT ((int)0x7FFFFFFF)
536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chennamespace android {
556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
567a947c49782165d7320a93d8685d99730286f9a7John Grossmanconst char*    CommonTimeServer::kDefaultMasterElectionAddr = "255.255.255.255";
577a947c49782165d7320a93d8685d99730286f9a7John Grossmanconst uint16_t CommonTimeServer::kDefaultMasterElectionPort = 8886;
587a947c49782165d7320a93d8685d99730286f9a7John Grossmanconst uint64_t CommonTimeServer::kDefaultSyncGroupID = 1;
596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst uint8_t  CommonTimeServer::kDefaultMasterPriority = 1;
606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst uint32_t CommonTimeServer::kDefaultMasterAnnounceIntervalMs = 10000;
616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst uint32_t CommonTimeServer::kDefaultSyncRequestIntervalMs = 1000;
626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst uint32_t CommonTimeServer::kDefaultPanicThresholdUsec = 50000;
636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst bool     CommonTimeServer::kDefaultAutoDisable = true;
646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst int      CommonTimeServer::kSetupRetryTimeoutMs = 30000;
656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst int64_t  CommonTimeServer::kNoGoodDataPanicThresholdUsec = 600000000ll;
666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst uint32_t CommonTimeServer::kRTTDiscardPanicThreshMultiplier = 5;
676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// timeout value representing an infinite timeout
696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst int CommonTimeServer::kInfiniteTimeout = -1;
706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen/*** Initial state constants ***/
726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// number of WhoIsMaster attempts sent before giving up
746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst int CommonTimeServer::kInitial_NumWhoIsMasterRetries = 6;
756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// timeout used when waiting for a response to a WhoIsMaster request
776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst int CommonTimeServer::kInitial_WhoIsMasterTimeoutMs = 500;
786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen/*** Client state constants ***/
806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// number of sync requests that can fail before a client assumes its master
826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// is dead
83e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossmanconst int CommonTimeServer::kClient_NumSyncRequestRetries = 10;
846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen/*** Master state constants ***/
866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen/*** Ronin state constants ***/
886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// number of WhoIsMaster attempts sent before declaring ourselves master
90e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossmanconst int CommonTimeServer::kRonin_NumWhoIsMasterRetries = 20;
916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// timeout used when waiting for a response to a WhoIsMaster request
936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst int CommonTimeServer::kRonin_WhoIsMasterTimeoutMs = 500;
946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen/*** WaitForElection state constants ***/
966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// how long do we wait for an announcement from a master before
986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// trying another election?
99e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossmanconst int CommonTimeServer::kWaitForElection_TimeoutMs = 12500;
1006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1016c929510474caa14dc9d56826b2c65552861d6b3Mike J. ChenCommonTimeServer::CommonTimeServer()
1026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    : Thread(false)
1036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    , mState(ICommonClock::STATE_INITIAL)
1046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    , mClockRecovery(&mLocalClock, &mCommonClock)
1056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    , mSocket(-1)
1066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    , mLastPacketRxLocalTime(0)
1076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    , mTimelineID(ICommonClock::kInvalidTimelineID)
1086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    , mClockSynced(false)
1096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    , mCommonClockHasClients(false)
11079489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    , mStateChangeLog("Recent State Change Events", 30)
11179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    , mElectionLog("Recent Master Election Traffic", 30)
11279489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    , mBadPktLog("Recent Bad Packet RX Info", 8)
1136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    , mInitial_WhoIsMasterRequestTimeouts(0)
1146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    , mClient_MasterDeviceID(0)
1156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    , mClient_MasterDevicePriority(0)
1166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    , mRonin_WhoIsMasterRequestTimeouts(0) {
1176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // zero out sync stats
1186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    resetSyncStats();
1196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Setup the master election endpoint to use the default.
1216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    struct sockaddr_in* meep =
1226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        reinterpret_cast<struct sockaddr_in*>(&mMasterElectionEP);
1236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    memset(&mMasterElectionEP, 0, sizeof(mMasterElectionEP));
1246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    inet_aton(kDefaultMasterElectionAddr, &meep->sin_addr);
1256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    meep->sin_family = AF_INET;
1266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    meep->sin_port   = htons(kDefaultMasterElectionPort);
1276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Zero out the master endpoint.
1296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    memset(&mMasterEP, 0, sizeof(mMasterEP));
1306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mMasterEPValid    = false;
1316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mBindIfaceValid   = false;
1326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    setForceLowPriority(false);
1336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Set all remaining configuration parameters to their defaults.
1356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mDeviceID                 = 0;
1366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mSyncGroupID              = kDefaultSyncGroupID;
1376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mMasterPriority           = kDefaultMasterPriority;
1386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mMasterAnnounceIntervalMs = kDefaultMasterAnnounceIntervalMs;
1396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mSyncRequestIntervalMs    = kDefaultSyncRequestIntervalMs;
1406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mPanicThresholdUsec       = kDefaultPanicThresholdUsec;
1416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mAutoDisable              = kDefaultAutoDisable;
1426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Create the eventfd we will use to signal our thread to wake up when
1446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // needed.
1456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mWakeupThreadFD = eventfd(0, EFD_NONBLOCK);
1466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // seed the random number generator (used to generated timeline IDs)
1486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    srand48(static_cast<unsigned int>(systemTime()));
1496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
1506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1516c929510474caa14dc9d56826b2c65552861d6b3Mike J. ChenCommonTimeServer::~CommonTimeServer() {
1526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    shutdownThread();
1536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // No need to grab the lock here.  We are in the destructor; if the the user
1556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // has a thread in any of the APIs while the destructor is being called,
1566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // there is a threading problem a the application level we cannot reasonably
1576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // do anything about.
1586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    cleanupSocket_l();
1596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mWakeupThreadFD >= 0) {
1616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        close(mWakeupThreadFD);
1626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mWakeupThreadFD = -1;
1636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
1646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
1656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::startServices() {
1676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // start the ICommonClock service
1686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mICommonClock = CommonClockService::instantiate(*this);
1696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mICommonClock == NULL)
1706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
1716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // start the ICommonTimeConfig service
1736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mICommonTimeConfig = CommonTimeConfigService::instantiate(*this);
1746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mICommonTimeConfig == NULL)
1756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
1766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return true;
1786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
1796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::threadLoop() {
1816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Register our service interfaces.
1826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!startServices())
1836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
1846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Hold the lock while we are in the main thread loop.  It will release the
1866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // lock when it blocks, and hold the lock at all other times.
1876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mLock.lock();
1886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    runStateMachine_l();
1896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mLock.unlock();
1906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    IPCThreadState::self()->stopProcess();
1926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return false;
1936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
1946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::runStateMachine_l() {
1966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!mLocalClock.initCheck())
1976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
1986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!mCommonClock.init(mLocalClock.getLocalFreq()))
2006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
2016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Enter the initial state.
2036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    becomeInitial("startup");
2046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // run the state machine
2066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    while (!exitPending()) {
2076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        struct pollfd pfds[2];
208c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman        int rc, timeout;
2096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int eventCnt = 0;
2106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int64_t wakeupTime;
211c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman        uint32_t t1, t2;
212c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman        bool needHandleTimeout = false;
2136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // We are always interested in our wakeup FD.
2156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        pfds[eventCnt].fd      = mWakeupThreadFD;
2166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        pfds[eventCnt].events  = POLLIN;
2176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        pfds[eventCnt].revents = 0;
2186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        eventCnt++;
2196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // If we have a valid socket, then we are interested in what it has to
2216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // say as well.
2226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (mSocket >= 0) {
2236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            pfds[eventCnt].fd      = mSocket;
2246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            pfds[eventCnt].events  = POLLIN;
2256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            pfds[eventCnt].revents = 0;
2266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            eventCnt++;
2276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
2286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
229c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman        t1 = static_cast<uint32_t>(mCurTimeout.msecTillTimeout());
230c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman        t2 = static_cast<uint32_t>(mClockRecovery.applyRateLimitedSlew());
231c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman        timeout = static_cast<int>(t1 < t2 ? t1 : t2);
232c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman
2336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // Note, we were holding mLock when this function was called.  We
2346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // release it only while we are blocking and hold it at all other times.
2356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mLock.unlock();
236c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman        rc          = poll(pfds, eventCnt, timeout);
2376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        wakeupTime  = mLocalClock.getLocalTime();
2386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mLock.lock();
2396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // Is it time to shutdown?  If so, don't hesitate... just do it.
2416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (exitPending())
2426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            break;
2436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // Did the poll fail?  This should never happen and is fatal if it does.
2456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (rc < 0) {
2466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            ALOGE("%s:%d poll failed", __PRETTY_FUNCTION__, __LINE__);
2476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return false;
2486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
2496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
250c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman        if (rc == 0) {
251c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman            needHandleTimeout = !mCurTimeout.msecTillTimeout();
252c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman            if (needHandleTimeout)
253c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman                mCurTimeout.setTimeout(kInfiniteTimeout);
254c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman        }
2556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // Were we woken up on purpose?  If so, clear the eventfd with a read.
2576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (pfds[0].revents)
2586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            clearPendingWakeupEvents_l();
2596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // Is out bind address dirty?  If so, clean up our socket (if any).
2616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // Alternatively, do we have an active socket but should be auto
2626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // disabled?  If so, release the socket and enter the proper sync state.
2636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        bool droppedSocket = false;
2646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (mBindIfaceDirty || ((mSocket >= 0) && shouldAutoDisable())) {
2656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            cleanupSocket_l();
2666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            mBindIfaceDirty = false;
2676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            droppedSocket = true;
2686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
2696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // Do we not have a socket but should have one?  If so, try to set one
2716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // up.
2726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if ((mSocket < 0) && mBindIfaceValid && !shouldAutoDisable()) {
2736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            if (setupSocket_l()) {
2746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                // Success!  We are now joining a new network (either coming
2756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                // from no network, or coming from a potentially different
2766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                // network).  Force our priority to be lower so that we defer to
2776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                // any other masters which may already be on the network we are
2786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                // joining.  Later, when we enter either the client or the
2796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                // master state, we will clear this flag and go back to our
2806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                // normal election priority.
2816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                setForceLowPriority(true);
2826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                switch (mState) {
2836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // If we were in initial (whether we had a immediately
2846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // before this network or not) we want to simply reset the
2856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // system and start again.  Forcing a transition from
2866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // INITIAL to INITIAL should do the job.
2876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    case CommonClockService::STATE_INITIAL:
2886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        becomeInitial("bound interface");
2896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        break;
2906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // If we were in the master state, then either we were the
2926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // master in a no-network situation, or we were the master
2936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // of a different network and have moved to a new interface.
294e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman                    // In either case, immediately transition to Ronin at low
295e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman                    // priority.  If there is no one in the network we just
296e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman                    // joined, we will become master soon enough.  If there is,
297e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman                    // we want to be certain to defer master status to the
298e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman                    // existing timeline currently running on the network.
299e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman                    //
3006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    case CommonClockService::STATE_MASTER:
301e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman                        becomeRonin("leaving networkless mode");
3026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        break;
3036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // If we were in any other state (CLIENT, RONIN, or
3056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // WAIT_FOR_ELECTION) then we must be moving from one
3066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // network to another.  We have lost our old master;
3076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // transition to RONIN in an attempt to find a new master.
3086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // If there are none out there, we will just assume
3096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // responsibility for the timeline we used to be a client
3106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    // of.
3116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    default:
3126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        becomeRonin("bound interface");
3136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        break;
3146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                }
3156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            } else {
3166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                // That's odd... we failed to set up our socket.  This could be
3176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                // due to some transient network change which will work itself
3186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                // out shortly; schedule a retry attempt in the near future.
3196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                mCurTimeout.setTimeout(kSetupRetryTimeoutMs);
3206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            }
3216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // One way or the other, we don't have any data to process at this
3236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // point (since we just tried to bulid a new socket).  Loop back
3246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // around and wait for the next thing to do.
3256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            continue;
3266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        } else if (droppedSocket) {
3276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // We just lost our socket, and for whatever reason (either no
3286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // config, or auto disable engaged) we are not supposed to rebuild
3296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // one at this time.  We are not going to rebuild our socket until
3306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // something about our config/auto-disabled status changes, so we
3316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // are basically in network-less mode.  If we are already in either
3326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // INITIAL or MASTER, just stay there until something changes.  If
3336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // we are in any other state (CLIENT, RONIN or WAIT_FOR_ELECTION),
3346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // then transition to either INITIAL or MASTER depending on whether
3356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            // or not our timeline is valid.
33679489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            mStateChangeLog.log(ANDROID_LOG_INFO, LOG_TAG,
33779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                    "Entering networkless mode interface is %s, "
33879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                    "shouldAutoDisable = %s",
33979489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                    mBindIfaceValid ? "valid" : "invalid",
34079489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                    shouldAutoDisable() ? "true" : "false");
3416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            if ((mState != ICommonClock::STATE_INITIAL) &&
3426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                (mState != ICommonClock::STATE_MASTER)) {
3436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                if (mTimelineID == ICommonClock::kInvalidTimelineID)
3446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    becomeInitial("network-less mode");
3456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                else
3466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    becomeMaster("network-less mode");
3476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            }
3486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            continue;
3506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
3516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
352c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman        // Time to handle the timeouts?
353c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman        if (needHandleTimeout) {
3546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            if (!handleTimeout())
3556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                ALOGE("handleTimeout failed");
3566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            continue;
3576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
3586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // Does our socket have data for us (assuming we still have one, we
3606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // may have RXed a packet at the same time as a config change telling us
3616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // to shut our socket down)?  If so, process its data.
3626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if ((mSocket >= 0) && (eventCnt > 1) && (pfds[1].revents)) {
3636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            mLastPacketRxLocalTime = wakeupTime;
3646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            if (!handlePacket())
3656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                ALOGE("handlePacket failed");
3666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
3676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
3686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    cleanupSocket_l();
3706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return true;
3716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
3726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid CommonTimeServer::clearPendingWakeupEvents_l() {
3746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    int64_t tmp;
3756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    read(mWakeupThreadFD, &tmp, sizeof(tmp));
3766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
3776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid CommonTimeServer::wakeupThread_l() {
3796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    int64_t tmp = 1;
3806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    write(mWakeupThreadFD, &tmp, sizeof(tmp));
3816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
3826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid CommonTimeServer::cleanupSocket_l() {
3846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mSocket >= 0) {
3856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        close(mSocket);
3866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mSocket = -1;
3876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
3886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
3896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid CommonTimeServer::shutdownThread() {
3916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Flag the work thread for shutdown.
3926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    this->requestExit();
3936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Signal the thread in case its sleeping.
3956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mLock.lock();
3966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    wakeupThread_l();
3976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mLock.unlock();
3986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Wait for the thread to exit.
4006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    this->join();
4016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
4026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::setupSocket_l() {
4046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    int rc;
4056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    bool ret_val = false;
4066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    struct sockaddr_in* ipv4_addr = NULL;
4076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    char masterElectionEPStr[64];
4086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    const int one = 1;
4096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // This should never be needed, but if we happened to have an old socket
4116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // lying around, be sure to not leak it before proceeding.
4126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    cleanupSocket_l();
4136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // If we don't have a valid endpoint to bind to, then how did we get here in
4156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // the first place?  Regardless, we know that we are going to fail to bind,
4166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // so don't even try.
4176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!mBindIfaceValid)
4186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
4196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    sockaddrToString(mMasterElectionEP, true, masterElectionEPStr,
4216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                     sizeof(masterElectionEPStr));
42279489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    mStateChangeLog.log(ANDROID_LOG_INFO, LOG_TAG,
42379489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                        "Building socket :: bind = %s master election = %s",
42479489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                        mBindIface.string(), masterElectionEPStr);
4256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // TODO: add proper support for IPv6.  Right now, we block IPv6 addresses at
4276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // the configuration interface level.
4286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (AF_INET != mMasterElectionEP.ss_family) {
42979489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        mStateChangeLog.log(ANDROID_LOG_WARN, LOG_TAG,
43079489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                            "TODO: add proper IPv6 support");
4316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        goto bailout;
4326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
4336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // open a UDP socket for the timeline serivce
4356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
4366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mSocket < 0) {
43779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        mStateChangeLog.log(ANDROID_LOG_ERROR, LOG_TAG,
43879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                            "Failed to create socket (errno = %d)", errno);
4396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        goto bailout;
4406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
4416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Bind to the selected interface using Linux's spiffy SO_BINDTODEVICE.
4436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    struct ifreq ifr;
4446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    memset(&ifr, 0, sizeof(ifr));
4456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", mBindIface.string());
4466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = 0;
4476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    rc = setsockopt(mSocket, SOL_SOCKET, SO_BINDTODEVICE,
4486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    (void *)&ifr, sizeof(ifr));
4496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (rc) {
45079489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        mStateChangeLog.log(ANDROID_LOG_ERROR, LOG_TAG,
45179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                            "Failed to bind socket at to interface %s "
45279489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                            "(errno = %d)", ifr.ifr_name, errno);
4536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        goto bailout;
4546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
4556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Bind our socket to INADDR_ANY and the master election port.  The
4576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // interface binding we made using SO_BINDTODEVICE should limit us to
4586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // traffic only on the interface we are interested in.  We need to bind to
4596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // INADDR_ANY and the specific master election port in order to be able to
4606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // receive both unicast traffic and master election multicast traffic with
4616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // just a single socket.
4626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    struct sockaddr_in bindAddr;
4636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ipv4_addr = reinterpret_cast<struct sockaddr_in*>(&mMasterElectionEP);
4646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    memcpy(&bindAddr, ipv4_addr, sizeof(bindAddr));
4656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    bindAddr.sin_addr.s_addr = INADDR_ANY;
4666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    rc = bind(mSocket,
4676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen              reinterpret_cast<const sockaddr *>(&bindAddr),
4686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen              sizeof(bindAddr));
4696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (rc) {
47079489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        mStateChangeLog.log(ANDROID_LOG_ERROR, LOG_TAG,
47179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                            "Failed to bind socket to port %hu (errno = %d)",
47279489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                            ntohs(bindAddr.sin_port), errno);
4736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        goto bailout;
4746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
4756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (0xE0000000 == (ntohl(ipv4_addr->sin_addr.s_addr) & 0xF0000000)) {
4776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // If our master election endpoint is a multicast address, be sure to join
4786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // the multicast group.
4796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        struct ip_mreq mreq;
4806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mreq.imr_multiaddr = ipv4_addr->sin_addr;
4816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mreq.imr_interface.s_addr = htonl(INADDR_ANY);
4826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        rc = setsockopt(mSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP,
4836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        &mreq, sizeof(mreq));
4846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (rc == -1) {
4856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            ALOGE("Failed to join multicast group at %s.  (errno = %d)",
4866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                 masterElectionEPStr, errno);
4876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            goto bailout;
4886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
4896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // disable loopback of multicast packets
4916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        const int zero = 0;
4926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        rc = setsockopt(mSocket, IPPROTO_IP, IP_MULTICAST_LOOP,
4936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        &zero, sizeof(zero));
4946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (rc == -1) {
49579489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            mStateChangeLog.log(ANDROID_LOG_ERROR, LOG_TAG,
49679489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                                "Failed to disable multicast loopback "
49779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                                "(errno = %d)", errno);
4986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            goto bailout;
4996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
5006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else
501db63260758ad795d619073e41f273184ab629bbcJason Simmons    if (ntohl(ipv4_addr->sin_addr.s_addr) == 0xFFFFFFFF) {
502db63260758ad795d619073e41f273184ab629bbcJason Simmons        // If the master election address is the broadcast address, then enable
503db63260758ad795d619073e41f273184ab629bbcJason Simmons        // the broadcast socket option
504db63260758ad795d619073e41f273184ab629bbcJason Simmons        rc = setsockopt(mSocket, SOL_SOCKET, SO_BROADCAST, &one, sizeof(one));
505db63260758ad795d619073e41f273184ab629bbcJason Simmons        if (rc == -1) {
50679489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            mStateChangeLog.log(ANDROID_LOG_ERROR, LOG_TAG,
50779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                                "Failed to enable broadcast (errno = %d)",
50879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                                errno);
509db63260758ad795d619073e41f273184ab629bbcJason Simmons            goto bailout;
510db63260758ad795d619073e41f273184ab629bbcJason Simmons        }
511db63260758ad795d619073e41f273184ab629bbcJason Simmons    } else {
5126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // If the master election address is neither broadcast, nor multicast,
5136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // then we are misconfigured.  The config API layer should prevent this
5146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // from ever happening.
5156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        goto bailout;
5166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
5176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Set the TTL of sent packets to 1.  (Time protocol sync should never leave
5196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // the local subnet)
5206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    rc = setsockopt(mSocket, IPPROTO_IP, IP_TTL, &one, sizeof(one));
5216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (rc == -1) {
52279489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        mStateChangeLog.log(ANDROID_LOG_ERROR, LOG_TAG,
52379489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                            "Failed to set TTL to %d (errno = %d)", one, errno);
5246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        goto bailout;
5256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
5266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // get the device's unique ID
5286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!assignDeviceID())
5296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        goto bailout;
5306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ret_val = true;
5326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbailout:
5346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!ret_val)
5356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        cleanupSocket_l();
5366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return ret_val;
5376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
5386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// generate a unique device ID that can be used for arbitration
5406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::assignDeviceID() {
5416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!mBindIfaceValid)
5426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
5436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    struct ifreq ifr;
5456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    memset(&ifr, 0, sizeof(ifr));
5466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ifr.ifr_addr.sa_family = AF_INET;
5476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    strlcpy(ifr.ifr_name, mBindIface.string(), IFNAMSIZ);
5486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    int rc = ioctl(mSocket, SIOCGIFHWADDR, &ifr);
5506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (rc) {
5516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ALOGE("%s:%d ioctl failed", __PRETTY_FUNCTION__, __LINE__);
5526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
5536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
5546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (ifr.ifr_addr.sa_family != ARPHRD_ETHER) {
5566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ALOGE("%s:%d got non-Ethernet address", __PRETTY_FUNCTION__, __LINE__);
5576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
5586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
5596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mDeviceID = 0;
5616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    for (int i = 0; i < ETH_ALEN; i++) {
5626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mDeviceID = (mDeviceID << 8) | ifr.ifr_hwaddr.sa_data[i];
5636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
5646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return true;
5666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
5676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// generate a new timeline ID
5696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid CommonTimeServer::assignTimelineID() {
5706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    do {
5716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mTimelineID = (static_cast<uint64_t>(lrand48()) << 32)
5726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    |  static_cast<uint64_t>(lrand48());
5736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } while (mTimelineID == ICommonClock::kInvalidTimelineID);
5746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
5756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
5766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// Select a preference between the device IDs of two potential masters.
5776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// Returns true if the first ID wins, or false if the second ID wins.
5786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::arbitrateMaster(
5796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        uint64_t deviceID1, uint8_t devicePrio1,
5806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        uint64_t deviceID2, uint8_t devicePrio2) {
5816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return ((devicePrio1 >  devicePrio2) ||
5826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen           ((devicePrio1 == devicePrio2) && (deviceID1 > deviceID2)));
5836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
5846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
58579489c4c65d3c8e628991995b4a18f2a81802ee6John Grossmanstatic void hexDumpToString(const uint8_t* src, size_t src_len,
58679489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                            char* dst, size_t dst_len) {
587f007bd3cf8cacd75287781c1bb37fe4167c79cbaJohn Grossman    size_t offset = 0;
58879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    size_t i;
58979489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman
59079489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    for (i = 0; (i < src_len) && (offset < dst_len); ++i) {
59179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        int res;
59279489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        if (0 == (i % 16)) {
593f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat            res = snprintf(dst + offset, dst_len - offset, "\n%04zx :", i);
59479489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            if (res < 0)
59579489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                break;
59679489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            offset += res;
59779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            if (offset >= dst_len)
59879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                break;
59979489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        }
60079489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman
60179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        res = snprintf(dst + offset, dst_len - offset, " %02x", src[i]);
60279489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        if (res < 0)
60379489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            break;
60479489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        offset += res;
60579489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    }
60679489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman
60779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    dst[dst_len - 1] = 0;
60879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman}
60979489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman
6106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::handlePacket() {
6116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint8_t buf[256];
6126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    struct sockaddr_storage srcAddr;
6136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    socklen_t srcAddrLen = sizeof(srcAddr);
6146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
6156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t recvBytes = recvfrom(
6166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            mSocket, buf, sizeof(buf), 0,
6176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            reinterpret_cast<const sockaddr *>(&srcAddr), &srcAddrLen);
6186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
6196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (recvBytes < 0) {
62079489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        mBadPktLog.log(ANDROID_LOG_ERROR, LOG_TAG,
62179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                       "recvfrom failed (res %d, errno %d)",
62279489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                       recvBytes, 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.
9726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int rttCommon = mCommonClock.localDurationToCommonDuration(rtt);
9736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (rttCommon > (static_cast<int64_t>(mPanicThresholdUsec) *
9746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                         kRTTDiscardPanicThreshMultiplier)) {
9756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            ALOGV("Dropping sync response with RTT of %lld uSec", rttCommon);
9766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            mClient_ExpiredSyncRespsRXedFromCurMaster++;
9776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            if (shouldPanicNotGettingGoodData())
9786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                return becomeInitial("RX panic, no good data");
9796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        } else {
98011bc45fcba96cf7ccc5f67b3c47088c2c89c8e7aKent Ryhorchuk            result = mClockRecovery.pushDisciplineEvent(avgLocal, avgCommon, rttCommon);
9816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            mClient_LastGoodSyncRX = clientRxLocalTime;
9826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
9836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            if (result) {
9846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                // indicate to listeners that we've synced to the common timeline
9856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                notifyClockSync();
9866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            } else {
9876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                ALOGE("Panic!  Observed clock sync error is too high to tolerate,"
9886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        " resetting state machine and starting over.");
9896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                notifyClockSyncLoss();
9906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                return becomeInitial("panic");
9916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            }
9926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
9936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
9946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
9956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mCurTimeout.setTimeout(mSyncRequestIntervalMs);
9966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return result;
9976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
9986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
9996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::handleMasterAnnouncement(
10006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        const MasterAnnouncementPacket* packet,
10016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        const sockaddr_storage& srcAddr) {
10026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint64_t newDeviceID   = packet->deviceID;
10036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint8_t  newDevicePrio = packet->devicePriority;
10046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint64_t newTimelineID = packet->timelineID;
10056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
10067a947c49782165d7320a93d8685d99730286f9a7John Grossman    // Skip our own messages which come back via broadcast loopback.
10077a947c49782165d7320a93d8685d99730286f9a7John Grossman    if (newDeviceID == mDeviceID)
10087a947c49782165d7320a93d8685d99730286f9a7John Grossman        return true;
10097a947c49782165d7320a93d8685d99730286f9a7John Grossman
101079489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    char srcEPStr[64];
101179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    sockaddrToString(srcAddr, true, srcEPStr, sizeof(srcEPStr));
101279489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    mElectionLog.log("RXed master announcement while in state %s.  "
101379489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                     "src %s srcDevID %lld srcPrio %u srcTID %016llx",
101479489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                     stateToString(mState), srcEPStr,
101579489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                     newDeviceID, static_cast<uint32_t>(newDevicePrio),
101679489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                     newTimelineID);
101779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman
10186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mState == ICommonClock::STATE_INITIAL ||
10196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mState == ICommonClock::STATE_RONIN ||
10206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mState == ICommonClock::STATE_WAIT_FOR_ELECTION) {
10216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // if we aren't currently following a master, then start following
10226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // this new master
10236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return becomeClient(srcAddr,
10246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            newDeviceID,
10256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            newDevicePrio,
10266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            newTimelineID,
10276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            "heard master announcement");
10286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else if (mState == ICommonClock::STATE_CLIENT) {
10296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // if the new master wins arbitration against our current master,
10306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // then become a client of the new master
10316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (arbitrateMaster(newDeviceID,
10326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            newDevicePrio,
10336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            mClient_MasterDeviceID,
10346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            mClient_MasterDevicePriority))
10356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return becomeClient(srcAddr,
10366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                newDeviceID,
10376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                newDevicePrio,
10386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                newTimelineID,
10396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                "heard master announcement");
10406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else if (mState == ICommonClock::STATE_MASTER) {
10416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // two masters are competing - if the new one wins arbitration, then
10426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // cease acting as master
10436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (arbitrateMaster(newDeviceID, newDevicePrio,
10446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                            mDeviceID, effectivePriority()))
10456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return becomeClient(srcAddr, newDeviceID,
10466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                newDevicePrio, newTimelineID,
10476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                "heard master announcement");
10486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
10496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
10506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return true;
10516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
10526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
10536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::sendWhoIsMasterRequest() {
10546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    assert(mState == ICommonClock::STATE_INITIAL || mState == ICommonClock::STATE_RONIN);
10556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
10566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // If we have no socket, then we must be in the unconfigured initial state.
10576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Don't report any errors, just don't try to send the initial who-is-master
10586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // query.  Eventually, our network will either become configured, or we will
10596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // be forced into network-less master mode by higher level code.
10606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mSocket < 0) {
10616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        assert(mState == ICommonClock::STATE_INITIAL);
10626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return true;
10636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
10646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
10656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    bool ret = false;
10666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    WhoIsMasterRequestPacket pkt;
10676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    pkt.initHeader(mSyncGroupID);
10686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    pkt.senderDeviceID = mDeviceID;
10696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    pkt.senderDevicePriority = effectivePriority();
10706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
10716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint8_t buf[256];
10726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
10736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (bufSz >= 0) {
107479489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        char dstEPStr[64];
107579489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        sockaddrToString(mMasterElectionEP, true, dstEPStr, sizeof(dstEPStr));
107679489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        mElectionLog.log("TXing WhoIs master request to %s while in state %s.  "
107779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                         "ourTID %016llx ourGID %016llx ourDID %016llx "
107879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                         "ourPrio %u",
107979489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                         dstEPStr, stateToString(mState),
108079489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                         mTimelineID, mSyncGroupID,
108179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                         pkt.senderDeviceID, pkt.senderDevicePriority);
108279489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman
10836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ssize_t sendBytes = sendto(
10846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                mSocket, buf, bufSz, 0,
10856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                reinterpret_cast<const sockaddr *>(&mMasterElectionEP),
10866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                sizeof(mMasterElectionEP));
10876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (sendBytes < 0)
10886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            ALOGE("WhoIsMaster sendto failed (errno %d)", errno);
10896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ret = true;
10906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
10916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
10926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mState == ICommonClock::STATE_INITIAL) {
10936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mCurTimeout.setTimeout(kInitial_WhoIsMasterTimeoutMs);
10946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else {
10956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mCurTimeout.setTimeout(kRonin_WhoIsMasterTimeoutMs);
10966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
10976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
10986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return ret;
10996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
11006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::sendSyncRequest() {
11026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // If we are sending sync requests, then we must be in the client state and
11036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // we must have a socket (when we have no network, we are only supposed to
11046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // be in INITIAL or MASTER)
11056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    assert(mState == ICommonClock::STATE_CLIENT);
11066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    assert(mSocket >= 0);
11076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    bool ret = false;
11096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    SyncRequestPacket pkt;
11106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    pkt.initHeader(mTimelineID, mSyncGroupID);
11116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    pkt.clientTxLocalTime = mLocalClock.getLocalTime();
11126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!mClient_FirstSyncTX)
11146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mClient_FirstSyncTX = pkt.clientTxLocalTime;
11156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClient_PacketRTTLog.logTX(pkt.clientTxLocalTime);
11176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint8_t buf[256];
11196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
11206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (bufSz >= 0) {
11216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ssize_t sendBytes = sendto(
11226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                mSocket, buf, bufSz, 0,
11236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                reinterpret_cast<const sockaddr *>(&mMasterEP),
11246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                sizeof(mMasterEP));
11256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (sendBytes < 0)
11266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            ALOGE("SyncRequest sendto failed (errno %d)", errno);
11276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ret = true;
11286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
11296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClient_SyncsSentToCurMaster++;
11316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mCurTimeout.setTimeout(mSyncRequestIntervalMs);
11326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClient_SyncRequestPending = true;
11336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return ret;
11356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
11366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::sendMasterAnnouncement() {
11386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    bool ret = false;
11396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    assert(mState == ICommonClock::STATE_MASTER);
11406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // If we are being asked to send a master announcement, but we have no
11426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // socket, we must be in network-less master mode.  Don't bother to send the
11436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // announcement, and don't bother to schedule a timeout.  When the network
11446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // comes up, the work thread will get poked and start the process of
11456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // figuring out who the current master should be.
11466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mSocket < 0) {
11476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mCurTimeout.setTimeout(kInfiniteTimeout);
11486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return true;
11496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
11506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    MasterAnnouncementPacket pkt;
11526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    pkt.initHeader(mTimelineID, mSyncGroupID);
11536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    pkt.deviceID = mDeviceID;
11546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    pkt.devicePriority = effectivePriority();
11556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint8_t buf[256];
11576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
11586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (bufSz >= 0) {
115979489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        char dstEPStr[64];
116079489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        sockaddrToString(mMasterElectionEP, true, dstEPStr, sizeof(dstEPStr));
116179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        mElectionLog.log("TXing Master announcement to %s while in state %s.  "
116279489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                         "ourTID %016llx ourGID %016llx ourDID %016llx "
116379489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                         "ourPrio %u",
116479489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                         dstEPStr, stateToString(mState),
116579489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                         mTimelineID, mSyncGroupID,
116679489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                         pkt.deviceID, pkt.devicePriority);
116779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman
11686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ssize_t sendBytes = sendto(
11696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                mSocket, buf, bufSz, 0,
11706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                reinterpret_cast<const sockaddr *>(&mMasterElectionEP),
11716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                sizeof(mMasterElectionEP));
11726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (sendBytes < 0)
11736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            ALOGE("MasterAnnouncement sendto failed (errno %d)", errno);
11746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ret = true;
11756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
11766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mCurTimeout.setTimeout(mMasterAnnounceIntervalMs);
11786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return ret;
11796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
11806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
11816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::becomeClient(const sockaddr_storage& masterEP,
11826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                    uint64_t masterDeviceID,
11836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                    uint8_t  masterDevicePriority,
11846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                    uint64_t timelineID,
11856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                    const char* cause) {
11866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    char newEPStr[64], oldEPStr[64];
11876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    sockaddrToString(masterEP, true, newEPStr, sizeof(newEPStr));
11886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    sockaddrToString(mMasterEP, mMasterEPValid, oldEPStr, sizeof(oldEPStr));
11896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
119079489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    mStateChangeLog.log(ANDROID_LOG_INFO, LOG_TAG,
119179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            "%s --> CLIENT (%s) :%s"
119279489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            " OldMaster: %02x-%014llx::%016llx::%s"
119379489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            " NewMaster: %02x-%014llx::%016llx::%s",
119479489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            stateToString(mState), cause,
119579489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            (mTimelineID != timelineID) ? " (new timeline)" : "",
119679489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            mClient_MasterDevicePriority, mClient_MasterDeviceID,
119779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            mTimelineID, oldEPStr,
119879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            masterDevicePriority, masterDeviceID,
119979489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            timelineID, newEPStr);
12006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mTimelineID != timelineID) {
12026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // start following a new timeline
12036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mTimelineID = timelineID;
12046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mClockRecovery.reset(true, true);
12056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        notifyClockSyncLoss();
12066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else {
12076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // start following a new master on the existing timeline
12086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mClockRecovery.reset(false, true);
12096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
12106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mMasterEP = masterEP;
12126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mMasterEPValid = true;
1213e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman
1214e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman    // If we are on a real network as a client of a real master, then we should
1215e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman    // no longer force low priority.  If our master disappears, we should have
1216e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman    // the high priority bit set during the election to replace the master
1217e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman    // because this group was a real group and not a singleton created in
1218e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman    // networkless mode.
12196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    setForceLowPriority(false);
12206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClient_MasterDeviceID = masterDeviceID;
12226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClient_MasterDevicePriority = masterDevicePriority;
12236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    resetSyncStats();
12246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    setState(ICommonClock::STATE_CLIENT);
12266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // add some jitter to when the various clients send their requests
12286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // in order to reduce the likelihood that a group of clients overload
12296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // the master after receiving a master announcement
12306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    usleep((lrand48() % 100) * 1000);
12316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return sendSyncRequest();
12336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
12346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::becomeMaster(const char* cause) {
12366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint64_t oldTimelineID = mTimelineID;
12376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mTimelineID == ICommonClock::kInvalidTimelineID) {
12386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // this device has not been following any existing timeline,
12396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // so it will create a new timeline and declare itself master
12406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        assert(!mCommonClock.isValid());
12416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // set the common time basis
12436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mCommonClock.setBasis(mLocalClock.getLocalTime(), 0);
12446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // assign an arbitrary timeline iD
12466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        assignTimelineID();
12476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // notify listeners that we've created a common timeline
12496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        notifyClockSync();
12506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
12516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
125279489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    mStateChangeLog.log(ANDROID_LOG_INFO, LOG_TAG,
125379489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            "%s --> MASTER (%s) : %s timeline %016llx",
125479489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            stateToString(mState), cause,
125579489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            (oldTimelineID == mTimelineID) ? "taking ownership of"
125679489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                                           : "creating new",
125779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman            mTimelineID);
12586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    memset(&mMasterEP, 0, sizeof(mMasterEP));
12606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mMasterEPValid = false;
12616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClient_MasterDevicePriority = effectivePriority();
12626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClient_MasterDeviceID = mDeviceID;
12636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClockRecovery.reset(false, true);
12646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    resetSyncStats();
12656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    setState(ICommonClock::STATE_MASTER);
12676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return sendMasterAnnouncement();
12686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
12696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::becomeRonin(const char* cause) {
12716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // If we were the client of a given timeline, but had never received even a
12726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // single time sync packet, then we transition back to Initial instead of
12736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Ronin.  If we transition to Ronin and end up becoming the new Master, we
12746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // will be unable to service requests for other clients because we never
12756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // actually knew what time it was.  By going to initial, we ensure that
12766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // other clients who know what time it is, but would lose master arbitration
12776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // in the Ronin case, will step up and become the proper new master of the
12786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // old timeline.
12796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    char oldEPStr[64];
12816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    sockaddrToString(mMasterEP, mMasterEPValid, oldEPStr, sizeof(oldEPStr));
12826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    memset(&mMasterEP, 0, sizeof(mMasterEP));
12836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mMasterEPValid = false;
12846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mCommonClock.isValid()) {
128679489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        mStateChangeLog.log(ANDROID_LOG_INFO, LOG_TAG,
128779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman             "%s --> RONIN (%s) : lost track of previously valid timeline "
12886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             "%02x-%014llx::%016llx::%s (%d TXed %d RXed %d RXExpired)",
12896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             stateToString(mState), cause,
12906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             mClient_MasterDevicePriority, mClient_MasterDeviceID,
12916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             mTimelineID, oldEPStr,
12926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             mClient_SyncsSentToCurMaster,
12936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             mClient_SyncRespsRXedFromCurMaster,
12946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             mClient_ExpiredSyncRespsRXedFromCurMaster);
12956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
12966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mRonin_WhoIsMasterRequestTimeouts = 0;
12976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        setState(ICommonClock::STATE_RONIN);
12986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return sendWhoIsMasterRequest();
12996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else {
130079489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        mStateChangeLog.log(ANDROID_LOG_INFO, LOG_TAG,
130179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman             "%s --> INITIAL (%s) : never synced timeline "
13026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             "%02x-%014llx::%016llx::%s (%d TXed %d RXed %d RXExpired)",
13036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             stateToString(mState), cause,
13046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             mClient_MasterDevicePriority, mClient_MasterDeviceID,
13056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             mTimelineID, oldEPStr,
13066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             mClient_SyncsSentToCurMaster,
13076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             mClient_SyncRespsRXedFromCurMaster,
13086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             mClient_ExpiredSyncRespsRXedFromCurMaster);
13096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return becomeInitial("ronin, no timeline");
13116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
13126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
13136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::becomeWaitForElection(const char* cause) {
131579489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    mStateChangeLog.log(ANDROID_LOG_INFO, LOG_TAG,
131679489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman         "%s --> WAIT_FOR_ELECTION (%s) : dropping out of election,"
13176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen         " waiting %d mSec for completion.",
13186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen         stateToString(mState), cause, kWaitForElection_TimeoutMs);
13196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    setState(ICommonClock::STATE_WAIT_FOR_ELECTION);
13216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mCurTimeout.setTimeout(kWaitForElection_TimeoutMs);
13226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return true;
13236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
13246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::becomeInitial(const char* cause) {
132679489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman    mStateChangeLog.log(ANDROID_LOG_INFO, LOG_TAG,
132779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                        "Entering INITIAL (%s), total reset.",
132879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman                        cause);
13296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    setState(ICommonClock::STATE_INITIAL);
13316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // reset clock recovery
13336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClockRecovery.reset(true, true);
13346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // reset internal state bookkeeping.
13366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mCurTimeout.setTimeout(kInfiniteTimeout);
13376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    memset(&mMasterEP, 0, sizeof(mMasterEP));
13386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mMasterEPValid = false;
13396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mLastPacketRxLocalTime = 0;
13406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mTimelineID = ICommonClock::kInvalidTimelineID;
13416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClockSynced = false;
13426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mInitial_WhoIsMasterRequestTimeouts = 0;
13436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClient_MasterDeviceID = 0;
13446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mClient_MasterDevicePriority = 0;
13456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mRonin_WhoIsMasterRequestTimeouts = 0;
13466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    resetSyncStats();
13476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // send the first request to discover the master
13496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return sendWhoIsMasterRequest();
13506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
13516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid CommonTimeServer::notifyClockSync() {
13536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!mClockSynced) {
13546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mClockSynced = true;
13556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mICommonClock->notifyOnTimelineChanged(mTimelineID);
13566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
13576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
13586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid CommonTimeServer::notifyClockSyncLoss() {
13606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mClockSynced) {
13616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mClockSynced = false;
13626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mICommonClock->notifyOnTimelineChanged(
13636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                ICommonClock::kInvalidTimelineID);
13646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
13656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
13666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid CommonTimeServer::setState(ICommonClock::State s) {
13686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mState = s;
13696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
13706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst char* CommonTimeServer::stateToString(ICommonClock::State s) {
13726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    switch(s) {
13736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case ICommonClock::STATE_INITIAL:
13746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return "INITIAL";
13756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case ICommonClock::STATE_CLIENT:
13766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return "CLIENT";
13776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case ICommonClock::STATE_MASTER:
13786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return "MASTER";
13796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case ICommonClock::STATE_RONIN:
13806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return "RONIN";
13816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case ICommonClock::STATE_WAIT_FOR_ELECTION:
13826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return "WAIT_FOR_ELECTION";
13836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        default:
13846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return "unknown";
13856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
13866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
13876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid CommonTimeServer::sockaddrToString(const sockaddr_storage& addr,
13896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                        bool addrValid,
13906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                        char* buf, size_t bufLen) {
13916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!bufLen || !buf)
13926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return;
13936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
13946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (addrValid) {
13956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        switch (addr.ss_family) {
13966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            case AF_INET: {
13976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                const struct sockaddr_in* sa =
13986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    reinterpret_cast<const struct sockaddr_in*>(&addr);
13996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                unsigned long a = ntohl(sa->sin_addr.s_addr);
14006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                uint16_t      p = ntohs(sa->sin_port);
14016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                snprintf(buf, bufLen, "%lu.%lu.%lu.%lu:%hu",
14026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        ((a >> 24) & 0xFF), ((a >> 16) & 0xFF),
14036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        ((a >>  8) & 0xFF),  (a        & 0xFF), p);
14046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            } break;
14056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
14066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            case AF_INET6: {
14076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                const struct sockaddr_in6* sa =
14086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    reinterpret_cast<const struct sockaddr_in6*>(&addr);
14096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                const uint8_t* a = sa->sin6_addr.s6_addr;
14106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                uint16_t       p = ntohs(sa->sin6_port);
14116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                snprintf(buf, bufLen,
14126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        "%02X%02X:%02X%02X:%02X%02X:%02X%02X:"
14136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        "%02X%02X:%02X%02X:%02X%02X:%02X%02X port %hd",
14146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        a[0], a[1], a[ 2], a[ 3], a[ 4], a[ 5], a[ 6], a[ 7],
14156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15],
14166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        p);
14176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            } break;
14186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
14196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            default:
14206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                snprintf(buf, bufLen,
14216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                         "<unknown sockaddr family %d>", addr.ss_family);
14226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                break;
14236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
14246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else {
14256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        snprintf(buf, bufLen, "<none>");
14266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
14276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
14286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    buf[bufLen - 1] = 0;
14296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
14306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
14316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::sockaddrMatch(const sockaddr_storage& a1,
14326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                     const sockaddr_storage& a2,
14336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                     bool matchAddressOnly) {
14346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (a1.ss_family != a2.ss_family)
14356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return false;
14366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
14376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    switch (a1.ss_family) {
14386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case AF_INET: {
14396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            const struct sockaddr_in* sa1 =
14406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                reinterpret_cast<const struct sockaddr_in*>(&a1);
14416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            const struct sockaddr_in* sa2 =
14426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                reinterpret_cast<const struct sockaddr_in*>(&a2);
14436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
14446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            if (sa1->sin_addr.s_addr != sa2->sin_addr.s_addr)
14456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                return false;
14466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
14476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return (matchAddressOnly || (sa1->sin_port == sa2->sin_port));
14486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        } break;
14496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
14506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case AF_INET6: {
14516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            const struct sockaddr_in6* sa1 =
14526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                reinterpret_cast<const struct sockaddr_in6*>(&a1);
14536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            const struct sockaddr_in6* sa2 =
14546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                reinterpret_cast<const struct sockaddr_in6*>(&a2);
14556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
14566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            if (memcmp(&sa1->sin6_addr, &sa2->sin6_addr, sizeof(sa2->sin6_addr)))
14576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                return false;
14586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
14596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return (matchAddressOnly || (sa1->sin6_port == sa2->sin6_port));
14606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        } break;
14616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
14626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // Huh?  We don't deal in non-IPv[46] addresses.  Not sure how we got
14636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // here, but we don't know how to comapre these addresses and simply
14646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        // default to a no-match decision.
14656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        default: return false;
14666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
14676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
14686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
14696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool CommonTimeServer::shouldPanicNotGettingGoodData() {
14706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mClient_FirstSyncTX) {
14716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int64_t now = mLocalClock.getLocalTime();
14726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int64_t delta = now - (mClient_LastGoodSyncRX
14736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                             ? mClient_LastGoodSyncRX
14746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                             : mClient_FirstSyncTX);
14756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int64_t deltaUsec = mCommonClock.localDurationToCommonDuration(delta);
14766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
14776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (deltaUsec >= kNoGoodDataPanicThresholdUsec)
14786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return true;
14796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
14806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
14816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return false;
14826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
14836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
14846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid CommonTimeServer::PacketRTTLog::logTX(int64_t txTime) {
14856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    txTimes[wrPtr] = txTime;
14866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    rxTimes[wrPtr] = 0;
14876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    wrPtr = (wrPtr + 1) % RTT_LOG_SIZE;
14886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!wrPtr)
14896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        logFull = true;
14906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
14916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
14926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid CommonTimeServer::PacketRTTLog::logRX(int64_t txTime, int64_t rxTime) {
14936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!logFull && !wrPtr)
14946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return;
14956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
14966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint32_t i = logFull ? wrPtr : 0;
14976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    do {
14986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (txTimes[i] == txTime) {
14996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            rxTimes[i] = rxTime;
15006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            break;
15016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
15026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        i = (i + 1) % RTT_LOG_SIZE;
15036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } while (i != wrPtr);
15046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
15056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
15066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}  // namespace android
1507