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