common_time_server.cpp revision 6c929510474caa14dc9d56826b2c65552861d6b3
14aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy/*
24aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * Copyright (C) 2012 The Android Open Source Project
34aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy *
44aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * Licensed under the Apache License, Version 2.0 (the "License");
54aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * you may not use this file except in compliance with the License.
64aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * You may obtain a copy of the License at
74aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy *
84aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy *      http://www.apache.org/licenses/LICENSE-2.0
94aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy *
104aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * Unless required by applicable law or agreed to in writing, software
114aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * distributed under the License is distributed on an "AS IS" BASIS,
124aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * See the License for the specific language governing permissions and
144aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * limitations under the License.
154aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy */
164aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
174aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy/*
184aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * A service that exchanges time synchronization information between
19d5a85fb63d91a9297e8d9a11016f3b3ed60dfbabRomain Guy * a master that defines a timeline and clients that follow the timeline.
209c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase */
216554943a1dd6854c0f4976900956e556767b49e1Romain Guy
226554943a1dd6854c0f4976900956e556767b49e1Romain Guy#define LOG_TAG "common_time"
230776a6069365bdea83855db154fa2d37f9d1d808Chris Craik#include <utils/Log.h>
24c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik
259c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase#include <arpa/inet.h>
262af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik#include <assert.h>
274aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy#include <fcntl.h>
289c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase#include <limits>
2913631f3da855f200a151e7837ed9f6b079622b58Romain Guy#include <linux/if_ether.h>
304aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy#include <net/if.h>
314aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy#include <net/if_arp.h>
324aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy#include <netinet/ip.h>
3358ecc204fbcacef34806290492384677a330d4d4Romain Guy#include <poll.h>
342af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik#include <stdio.h>
3554c1a64d5441a964890b44280e4457e11f4f924aRomain Guy#include <sys/eventfd.h>
3654c1a64d5441a964890b44280e4457e11f4f924aRomain Guy#include <sys/ioctl.h>
374aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy#include <sys/stat.h>
384aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy#include <sys/types.h>
394aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy#include <sys/socket.h>
404aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
414aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy#include <common_time/local_clock.h>
424aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy#include <binder/IPCThreadState.h>
434aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy#include <binder/ProcessState.h>
442af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik#include <utils/Timers.h>
4558ecc204fbcacef34806290492384677a330d4d4Romain Guy
4658ecc204fbcacef34806290492384677a330d4d4Romain Guy#include "common_clock_service.h"
475c13d89c1332fcc499379b9064b891187b75ca32Chet Haase#include "common_time_config_service.h"
4858ecc204fbcacef34806290492384677a330d4d4Romain Guy#include "common_time_server.h"
495c13d89c1332fcc499379b9064b891187b75ca32Chet Haase#include "common_time_server_packets.h"
50d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase#include "clock_recovery.h"
5149c5fc0b9e850497233e189ff9dcc71a78ebe6e7Romain Guy#include "common_clock.h"
5258ecc204fbcacef34806290492384677a330d4d4Romain Guy
5349c5fc0b9e850497233e189ff9dcc71a78ebe6e7Romain Guyusing std::numeric_limits;
5449c5fc0b9e850497233e189ff9dcc71a78ebe6e7Romain Guy
55d586ad9c9fec80aa1d24d6b53cd2c8d5b47fe868Romain Guynamespace android {
5658ecc204fbcacef34806290492384677a330d4d4Romain Guy
57d586ad9c9fec80aa1d24d6b53cd2c8d5b47fe868Romain Guyconst char*    CommonTimeServer::kDefaultMasterElectionAddr = "239.195.128.88";
58d586ad9c9fec80aa1d24d6b53cd2c8d5b47fe868Romain Guyconst uint16_t CommonTimeServer::kDefaultMasterElectionPort = 8887;
5943ccf4663c822ddd435b7683cc05221f6169c6c3Romain Guyconst uint64_t CommonTimeServer::kDefaultSyncGroupID = 0;
6058ecc204fbcacef34806290492384677a330d4d4Romain Guyconst uint8_t  CommonTimeServer::kDefaultMasterPriority = 1;
6143ccf4663c822ddd435b7683cc05221f6169c6c3Romain Guyconst uint32_t CommonTimeServer::kDefaultMasterAnnounceIntervalMs = 10000;
6243ccf4663c822ddd435b7683cc05221f6169c6c3Romain Guyconst uint32_t CommonTimeServer::kDefaultSyncRequestIntervalMs = 1000;
63d34dd71800d9a1077e58c3b7f2511c46848da417Chet Haaseconst uint32_t CommonTimeServer::kDefaultPanicThresholdUsec = 50000;
6458ecc204fbcacef34806290492384677a330d4d4Romain Guyconst bool     CommonTimeServer::kDefaultAutoDisable = true;
65d34dd71800d9a1077e58c3b7f2511c46848da417Chet Haaseconst int      CommonTimeServer::kSetupRetryTimeoutMs = 30000;
6658ecc204fbcacef34806290492384677a330d4d4Romain Guyconst int64_t  CommonTimeServer::kNoGoodDataPanicThresholdUsec = 600000000ll;
67603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haaseconst uint32_t CommonTimeServer::kRTTDiscardPanicThreshMultiplier = 5;
68603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haase
69603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haase// timeout value representing an infinite timeout
70603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haaseconst int CommonTimeServer::kInfiniteTimeout = -1;
7158ecc204fbcacef34806290492384677a330d4d4Romain Guy
7258ecc204fbcacef34806290492384677a330d4d4Romain Guy/*** Initial state constants ***/
7358ecc204fbcacef34806290492384677a330d4d4Romain Guy
7458ecc204fbcacef34806290492384677a330d4d4Romain Guy// number of WhoIsMaster attempts sent before giving up
7558ecc204fbcacef34806290492384677a330d4d4Romain Guyconst int CommonTimeServer::kInitial_NumWhoIsMasterRetries = 6;
76d34dd71800d9a1077e58c3b7f2511c46848da417Chet Haase
77d34dd71800d9a1077e58c3b7f2511c46848da417Chet Haase// timeout used when waiting for a response to a WhoIsMaster request
7858ecc204fbcacef34806290492384677a330d4d4Romain Guyconst int CommonTimeServer::kInitial_WhoIsMasterTimeoutMs = 500;
7958ecc204fbcacef34806290492384677a330d4d4Romain Guy
8058ecc204fbcacef34806290492384677a330d4d4Romain Guy/*** Client state constants ***/
8143ccf4663c822ddd435b7683cc05221f6169c6c3Romain Guy
8243ccf4663c822ddd435b7683cc05221f6169c6c3Romain Guy// number of sync requests that can fail before a client assumes its master
83d586ad9c9fec80aa1d24d6b53cd2c8d5b47fe868Romain Guy// is dead
84735738c4ddf3229caa5f6e634bf591953ac29944Romain Guyconst int CommonTimeServer::kClient_NumSyncRequestRetries = 5;
85735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy
86735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy/*** Master state constants ***/
872fc941e4650d618ff6e122f28b616d9032ffa134Romain Guy
882fc941e4650d618ff6e122f28b616d9032ffa134Romain Guy/*** Ronin state constants ***/
89d586ad9c9fec80aa1d24d6b53cd2c8d5b47fe868Romain Guy
90d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase// number of WhoIsMaster attempts sent before declaring ourselves master
9104c9d8c2ffd028c35c750bac0a4a7b79e48059b5Romain Guyconst int CommonTimeServer::kRonin_NumWhoIsMasterRetries = 4;
92603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haase
93603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haase// timeout used when waiting for a response to a WhoIsMaster request
9404c9d8c2ffd028c35c750bac0a4a7b79e48059b5Romain Guyconst int CommonTimeServer::kRonin_WhoIsMasterTimeoutMs = 500;
9554c1a64d5441a964890b44280e4457e11f4f924aRomain Guy
964aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy/*** WaitForElection state constants ***/
974aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
984aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy// how long do we wait for an announcement from a master before
994aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy// trying another election?
1004aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guyconst int CommonTimeServer::kWaitForElection_TimeoutMs = 5000;
1014aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
102162a0217563f4665da6eb183dfce0fef740f641fJeff BrownCommonTimeServer::CommonTimeServer()
103162a0217563f4665da6eb183dfce0fef740f641fJeff Brown    : Thread(false)
104162a0217563f4665da6eb183dfce0fef740f641fJeff Brown    , mState(ICommonClock::STATE_INITIAL)
1055977baa1fa24125c148a72699b53e62abaf08960Chet Haase    , mClockRecovery(&mLocalClock, &mCommonClock)
106162a0217563f4665da6eb183dfce0fef740f641fJeff Brown    , mSocket(-1)
1075977baa1fa24125c148a72699b53e62abaf08960Chet Haase    , mLastPacketRxLocalTime(0)
10804c9d8c2ffd028c35c750bac0a4a7b79e48059b5Romain Guy    , mTimelineID(ICommonClock::kInvalidTimelineID)
109162a0217563f4665da6eb183dfce0fef740f641fJeff Brown    , mClockSynced(false)
1105977baa1fa24125c148a72699b53e62abaf08960Chet Haase    , mCommonClockHasClients(false)
1115977baa1fa24125c148a72699b53e62abaf08960Chet Haase    , mInitial_WhoIsMasterRequestTimeouts(0)
11249c5fc0b9e850497233e189ff9dcc71a78ebe6e7Romain Guy    , mClient_MasterDeviceID(0)
11349c5fc0b9e850497233e189ff9dcc71a78ebe6e7Romain Guy    , mClient_MasterDevicePriority(0)
11449c5fc0b9e850497233e189ff9dcc71a78ebe6e7Romain Guy    , mRonin_WhoIsMasterRequestTimeouts(0) {
11549c5fc0b9e850497233e189ff9dcc71a78ebe6e7Romain Guy    // zero out sync stats
116b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    resetSyncStats();
117b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy
118b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    // Setup the master election endpoint to use the default.
119b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    struct sockaddr_in* meep =
120b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy        reinterpret_cast<struct sockaddr_in*>(&mMasterElectionEP);
121b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    memset(&mMasterElectionEP, 0, sizeof(mMasterElectionEP));
122b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    inet_aton(kDefaultMasterElectionAddr, &meep->sin_addr);
1237c25aab491707f7324f9941b8cfa9bd2b4b97e76Romain Guy    meep->sin_family = AF_INET;
1247d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy    meep->sin_port   = htons(kDefaultMasterElectionPort);
125b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy
126b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    // Zero out the master endpoint.
127b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    memset(&mMasterEP, 0, sizeof(mMasterEP));
12845e4c3df6c00ac98ff6144de9af574877d4fff19Romain Guy    mMasterEPValid    = false;
129b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    mBindIfaceValid   = false;
13045e4c3df6c00ac98ff6144de9af574877d4fff19Romain Guy    setForceLowPriority(false);
13145e4c3df6c00ac98ff6144de9af574877d4fff19Romain Guy
13227454a42de8b3c54cdd3b2b2a12446c2c10c8cb9Romain Guy    // Set all remaining configuration parameters to their defaults.
13345e4c3df6c00ac98ff6144de9af574877d4fff19Romain Guy    mDeviceID                 = 0;
13444b2fe3fc114ee5f7273c6b0fee2cc999bf244a2Chet Haase    mSyncGroupID              = kDefaultSyncGroupID;
13527454a42de8b3c54cdd3b2b2a12446c2c10c8cb9Romain Guy    mMasterPriority           = kDefaultMasterPriority;
13627454a42de8b3c54cdd3b2b2a12446c2c10c8cb9Romain Guy    mMasterAnnounceIntervalMs = kDefaultMasterAnnounceIntervalMs;
13727454a42de8b3c54cdd3b2b2a12446c2c10c8cb9Romain Guy    mSyncRequestIntervalMs    = kDefaultSyncRequestIntervalMs;
13827454a42de8b3c54cdd3b2b2a12446c2c10c8cb9Romain Guy    mPanicThresholdUsec       = kDefaultPanicThresholdUsec;
1392af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    mAutoDisable              = kDefaultAutoDisable;
140b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy
141b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    // Create the eventfd we will use to signal our thread to wake up when
142daf98e941e140e8739458126640183b9f296a2abChet Haase    // needed.
143daf98e941e140e8739458126640183b9f296a2abChet Haase    mWakeupThreadFD = eventfd(0, EFD_NONBLOCK);
144daf98e941e140e8739458126640183b9f296a2abChet Haase
1452b1847ea60650a9f68372abe860415f18b55081dRomain Guy    // seed the random number generator (used to generated timeline IDs)
1464aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy    srand48(static_cast<unsigned int>(systemTime()));
1474aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
1486554943a1dd6854c0f4976900956e556767b49e1Romain Guy
149cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain GuyCommonTimeServer::~CommonTimeServer() {
1502af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    shutdownThread();
15154c1a64d5441a964890b44280e4457e11f4f924aRomain Guy
1526554943a1dd6854c0f4976900956e556767b49e1Romain Guy    // No need to grab the lock here.  We are in the destructor; if the the user
153daf98e941e140e8739458126640183b9f296a2abChet Haase    // has a thread in any of the APIs while the destructor is being called,
154daf98e941e140e8739458126640183b9f296a2abChet Haase    // there is a threading problem a the application level we cannot reasonably
1554aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy    // do anything about.
1562af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    cleanupSocket_l();
1574aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
1584aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy    if (mWakeupThreadFD >= 0) {
1594aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy        close(mWakeupThreadFD);
1604aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy        mWakeupThreadFD = -1;
16104c9d8c2ffd028c35c750bac0a4a7b79e48059b5Romain Guy    }
16233f6beb10f98e8ba96250e284876d607055d278dRomain Guy}
16333f6beb10f98e8ba96250e284876d607055d278dRomain Guy
16404c9d8c2ffd028c35c750bac0a4a7b79e48059b5Romain Guybool CommonTimeServer::startServices() {
16533f6beb10f98e8ba96250e284876d607055d278dRomain Guy    // start the ICommonClock service
16633f6beb10f98e8ba96250e284876d607055d278dRomain Guy    mICommonClock = CommonClockService::instantiate(*this);
1672af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    if (mICommonClock == NULL)
1684aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy        return false;
1694aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
1704aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy    // start the ICommonTimeConfig service
1714aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy    mICommonTimeConfig = CommonTimeConfigService::instantiate(*this);
17227454a42de8b3c54cdd3b2b2a12446c2c10c8cb9Romain Guy    if (mICommonTimeConfig == NULL)
1732af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        return false;
1744aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
1754aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy    return true;
1764aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
1774aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
1785c13d89c1332fcc499379b9064b891187b75ca32Chet Haasebool CommonTimeServer::threadLoop() {
1792af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    // Register our service interfaces.
180b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    if (!startServices())
1814aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy        return false;
1824aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
1835b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    // Hold the lock while we are in the main thread loop.  It will release the
1845b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    // lock when it blocks, and hold the lock at all other times.
1852af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    mLock.lock();
1865b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    runStateMachine_l();
1875b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    mLock.unlock();
1885b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
1894aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy    IPCThreadState::self()->stopProcess();
19033f6beb10f98e8ba96250e284876d607055d278dRomain Guy    return false;
19133f6beb10f98e8ba96250e284876d607055d278dRomain Guy}
19233f6beb10f98e8ba96250e284876d607055d278dRomain Guy
19333f6beb10f98e8ba96250e284876d607055d278dRomain Guybool CommonTimeServer::runStateMachine_l() {
1944aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy    if (!mLocalClock.initCheck())
1954aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy        return false;
1964aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
1974aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy    if (!mCommonClock.init(mLocalClock.getLocalFreq()))
1982af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        return false;
1994aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
2004aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy    // Enter the initial state.
2014aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy    becomeInitial("startup");
2024aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
2032af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    // run the state machine
2044aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy    while (!exitPending()) {
2054aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy        struct pollfd pfds[2];
2064aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy        int rc;
207807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy        int eventCnt = 0;
2082af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        int64_t wakeupTime;
209807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy
210807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy        // We are always interested in our wakeup FD.
211807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy        pfds[eventCnt].fd      = mWakeupThreadFD;
2124aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy        pfds[eventCnt].events  = POLLIN;
2132af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        pfds[eventCnt].revents = 0;
2142af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        eventCnt++;
2154aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
2164aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy        // If we have a valid socket, then we are interested in what it has to
2174aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy        // say as well.
2184aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy        if (mSocket >= 0) {
2192af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik            pfds[eventCnt].fd      = mSocket;
2202af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik            pfds[eventCnt].events  = POLLIN;
2214aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy            pfds[eventCnt].revents = 0;
2224aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy            eventCnt++;
2234aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy        }
2244aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
2254aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy        // Note, we were holding mLock when this function was called.  We
2262af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        // release it only while we are blocking and hold it at all other times.
2274aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy        mLock.unlock();
2284aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy        rc          = poll(pfds, eventCnt, mCurTimeout.msecTillTimeout());
2294aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy        wakeupTime  = mLocalClock.getLocalTime();
230735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy        mLock.lock();
2312af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
2322af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        // Is it time to shutdown?  If so, don't hesitate... just do it.
233735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy        if (exitPending())
234735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy            break;
235735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy
236735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy        // Did the poll fail?  This should never happen and is fatal if it does.
2372af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        if (rc < 0) {
2382af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik            ALOGE("%s:%d poll failed", __PRETTY_FUNCTION__, __LINE__);
239735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy            return false;
240735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy        }
241735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy
2426554943a1dd6854c0f4976900956e556767b49e1Romain Guy        if (rc == 0)
243c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik            mCurTimeout.setTimeout(kInfiniteTimeout);
244cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy
245cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy        // Were we woken up on purpose?  If so, clear the eventfd with a read.
246b85967b9af76e1e60f7a96603e2567a6449d2e04Chet Haase        if (pfds[0].revents)
2472af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik            clearPendingWakeupEvents_l();
2482af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
2492af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        // Is out bind address dirty?  If so, clean up our socket (if any).
2502af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        // Alternatively, do we have an active socket but should be auto
2512af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        // disabled?  If so, release the socket and enter the proper sync state.
2526554943a1dd6854c0f4976900956e556767b49e1Romain Guy        bool droppedSocket = false;
2530fe478ea04720a57ef3919dbc23711bc7eba517fRomain Guy        if (mBindIfaceDirty || ((mSocket >= 0) && shouldAutoDisable())) {
2540fe478ea04720a57ef3919dbc23711bc7eba517fRomain Guy            cleanupSocket_l();
255486590963e2207d68eebd6944fec70d50d41116aChet Haase            mBindIfaceDirty = false;
2562af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik            droppedSocket = true;
2572af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        }
2582af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
2592af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        // Do we not have a socket but should have one?  If so, try to set one
2602af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        // up.
261486590963e2207d68eebd6944fec70d50d41116aChet Haase        if ((mSocket < 0) && mBindIfaceValid && !shouldAutoDisable()) {
2626c319ca1275c8db892c39b48fc54864c949f9171Romain Guy            if (setupSocket_l()) {
2636c319ca1275c8db892c39b48fc54864c949f9171Romain Guy                // Success!  We are now joining a new network (either coming
264486590963e2207d68eebd6944fec70d50d41116aChet Haase                // from no network, or coming from a potentially different
2652af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik                // network).  Force our priority to be lower so that we defer to
2662af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik                // any other masters which may already be on the network we are
2672af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik                // joining.  Later, when we enter either the client or the
2682af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik                // master state, we will clear this flag and go back to our
269486590963e2207d68eebd6944fec70d50d41116aChet Haase                // normal election priority.
2704aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy                setForceLowPriority(true);
2714aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy                switch (mState) {
272486590963e2207d68eebd6944fec70d50d41116aChet Haase                    // If we were in initial (whether we had a immediately
2732af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik                    // before this network or not) we want to simply reset the
2742af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik                    // system and start again.  Forcing a transition from
2752af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik                    // INITIAL to INITIAL should do the job.
2762af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik                    case CommonClockService::STATE_INITIAL:
2772af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik                        becomeInitial("bound interface");
278486590963e2207d68eebd6944fec70d50d41116aChet Haase                        break;
2794aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
2804aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy                    // If we were in the master state, then either we were the
281486590963e2207d68eebd6944fec70d50d41116aChet Haase                    // master in a no-network situation, or we were the master
2824aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy                    // of a different network and have moved to a new interface.
2835c13d89c1332fcc499379b9064b891187b75ca32Chet Haase                    // In either case, immediately send out a master
2842af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik                    // announcement at low priority.
2852af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik                    case CommonClockService::STATE_MASTER:
2862af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik                        sendMasterAnnouncement();
2872af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik                        break;
2882af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
2892af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik                    // If we were in any other state (CLIENT, RONIN, or
290486590963e2207d68eebd6944fec70d50d41116aChet Haase                    // WAIT_FOR_ELECTION) then we must be moving from one
2914aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy                    // network to another.  We have lost our old master;
2924aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy                    // transition to RONIN in an attempt to find a new master.
293486590963e2207d68eebd6944fec70d50d41116aChet Haase                    // If there are none out there, we will just assume
294486590963e2207d68eebd6944fec70d50d41116aChet Haase                    // responsibility for the timeline we used to be a client
2952af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik                    // of.
2962af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik                    default:
2972af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik                        becomeRonin("bound interface");
2982af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik                        break;
299486590963e2207d68eebd6944fec70d50d41116aChet Haase                }
300e651cc6239616a202f6e96ebc2ed93b4b8b3627cRomain Guy            } else {
301e651cc6239616a202f6e96ebc2ed93b4b8b3627cRomain Guy                // That's odd... we failed to set up our socket.  This could be
302486590963e2207d68eebd6944fec70d50d41116aChet Haase                // due to some transient network change which will work itself
3035a7b466a2b4b7ced739bd5c31e022de61650545aRomain Guy                // out shortly; schedule a retry attempt in the near future.
3042af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik                mCurTimeout.setTimeout(kSetupRetryTimeoutMs);
3052af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik            }
3062af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
3072af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik            // One way or the other, we don't have any data to process at this
3082af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik            // point (since we just tried to bulid a new socket).  Loop back
3092af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik            // around and wait for the next thing to do.
3102af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik            continue;
3112af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        } else if (droppedSocket) {
312486590963e2207d68eebd6944fec70d50d41116aChet Haase            // We just lost our socket, and for whatever reason (either no
3135a7b466a2b4b7ced739bd5c31e022de61650545aRomain Guy            // config, or auto disable engaged) we are not supposed to rebuild
3145a7b466a2b4b7ced739bd5c31e022de61650545aRomain Guy            // one at this time.  We are not going to rebuild our socket until
315486590963e2207d68eebd6944fec70d50d41116aChet Haase            // something about our config/auto-disabled status changes, so we
316486590963e2207d68eebd6944fec70d50d41116aChet Haase            // are basically in network-less mode.  If we are already in either
317486590963e2207d68eebd6944fec70d50d41116aChet Haase            // INITIAL or MASTER, just stay there until something changes.  If
318be6f9dc1e71b425b7ac1c40c0a2c72d03eb9fbeeRomain Guy            // we are in any other state (CLIENT, RONIN or WAIT_FOR_ELECTION),
319be6f9dc1e71b425b7ac1c40c0a2c72d03eb9fbeeRomain Guy            // then transition to either INITIAL or MASTER depending on whether
320be6f9dc1e71b425b7ac1c40c0a2c72d03eb9fbeeRomain Guy            // or not our timeline is valid.
321be6f9dc1e71b425b7ac1c40c0a2c72d03eb9fbeeRomain Guy            ALOGI("Entering networkless mode interface is %s, "
3222af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik                 "shouldAutoDisable = %s",
3232af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik                 mBindIfaceValid ? "valid" : "invalid",
3242af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik                 shouldAutoDisable() ? "true" : "false");
3252af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik            if ((mState != ICommonClock::STATE_INITIAL) &&
3262af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik                (mState != ICommonClock::STATE_MASTER)) {
3272af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik                if (mTimelineID == ICommonClock::kInvalidTimelineID)
3282af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik                    becomeInitial("network-less mode");
329486590963e2207d68eebd6944fec70d50d41116aChet Haase                else
3304aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy                    becomeMaster("network-less mode");
3314aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy            }
332486590963e2207d68eebd6944fec70d50d41116aChet Haase
3332af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik            continue;
334486590963e2207d68eebd6944fec70d50d41116aChet Haase        }
3354aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
3364aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy        // Did we wakeup with no signalled events across all of our FDs?  If so,
337486590963e2207d68eebd6944fec70d50d41116aChet Haase        // we must have hit our timeout.
3385c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        if (rc == 0) {
3392af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik            if (!handleTimeout())
3402af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik                ALOGE("handleTimeout failed");
341486590963e2207d68eebd6944fec70d50d41116aChet Haase            continue;
3424aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy        }
3434aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
344486590963e2207d68eebd6944fec70d50d41116aChet Haase        // Does our socket have data for us (assuming we still have one, we
345a1cff5043d0fbd78fcf9c48e7658e56a5b0c2de3Chet Haase        // may have RXed a packet at the same time as a config change telling us
3462af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        // to shut our socket down)?  If so, process its data.
3472af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        if ((mSocket >= 0) && (eventCnt > 1) && (pfds[1].revents)) {
348486590963e2207d68eebd6944fec70d50d41116aChet Haase            mLastPacketRxLocalTime = wakeupTime;
34901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy            if (!handlePacket())
35001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy                ALOGE("handlePacket failed");
351486590963e2207d68eebd6944fec70d50d41116aChet Haase        }
3522af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    }
3532af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
354486590963e2207d68eebd6944fec70d50d41116aChet Haase    cleanupSocket_l();
35501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy    return true;
35601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy}
357486590963e2207d68eebd6944fec70d50d41116aChet Haase
358c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guyvoid CommonTimeServer::clearPendingWakeupEvents_l() {
3592af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    int64_t tmp;
3602af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    read(mWakeupThreadFD, &tmp, sizeof(tmp));
361486590963e2207d68eebd6944fec70d50d41116aChet Haase}
362c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy
363c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guyvoid CommonTimeServer::wakeupThread_l() {
364486590963e2207d68eebd6944fec70d50d41116aChet Haase    int64_t tmp = 1;
3658b2f5267f16c295f12faab810527cd6311997e34Romain Guy    write(mWakeupThreadFD, &tmp, sizeof(tmp));
3662af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}
3672af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
3682af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikvoid CommonTimeServer::cleanupSocket_l() {
369486590963e2207d68eebd6944fec70d50d41116aChet Haase    if (mSocket >= 0) {
3708b2f5267f16c295f12faab810527cd6311997e34Romain Guy        close(mSocket);
3718b2f5267f16c295f12faab810527cd6311997e34Romain Guy        mSocket = -1;
372486590963e2207d68eebd6944fec70d50d41116aChet Haase    }
3732af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}
3742af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
3752af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikvoid CommonTimeServer::shutdownThread() {
3762af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    // Flag the work thread for shutdown.
377486590963e2207d68eebd6944fec70d50d41116aChet Haase    this->requestExit();
3784aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
3794aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy    // Signal the thread in case its sleeping.
380486590963e2207d68eebd6944fec70d50d41116aChet Haase    mLock.lock();
3812af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    wakeupThread_l();
3822af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    mLock.unlock();
3832af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
3842af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    // Wait for the thread to exit.
385486590963e2207d68eebd6944fec70d50d41116aChet Haase    this->join();
386ed6fcb034b44d9a6ac2fc72fee6030417811f234Romain Guy}
387ed6fcb034b44d9a6ac2fc72fee6030417811f234Romain Guy
388486590963e2207d68eebd6944fec70d50d41116aChet Haasebool CommonTimeServer::setupSocket_l() {
3892af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    int rc;
3902af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    bool ret_val = false;
3912af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    struct sockaddr_in* ipv4_addr = NULL;
3922af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    char masterElectionEPStr[64];
393486590963e2207d68eebd6944fec70d50d41116aChet Haase    const int one = 1;
3944aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
3954aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy    // This should never be needed, but if we happened to have an old socket
396996e57c84368058be793897ebc355b917a59abc2Raph Levien    // lying around, be sure to not leak it before proceeding.
397996e57c84368058be793897ebc355b917a59abc2Raph Levien    cleanupSocket_l();
398996e57c84368058be793897ebc355b917a59abc2Raph Levien
3992af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    // If we don't have a valid endpoint to bind to, then how did we get here in
4002af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    // the first place?  Regardless, we know that we are going to fail to bind,
4012af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    // so don't even try.
4022af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    if (!mBindIfaceValid)
4032af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        return false;
4042af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
4052af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    sockaddrToString(mMasterElectionEP, true, masterElectionEPStr,
4060f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy                     sizeof(masterElectionEPStr));
407996e57c84368058be793897ebc355b917a59abc2Raph Levien    ALOGI("Building socket :: bind = %s master election = %s",
408996e57c84368058be793897ebc355b917a59abc2Raph Levien         mBindIface.string(), masterElectionEPStr);
409996e57c84368058be793897ebc355b917a59abc2Raph Levien
410996e57c84368058be793897ebc355b917a59abc2Raph Levien    // TODO: add proper support for IPv6.  Right now, we block IPv6 addresses at
411996e57c84368058be793897ebc355b917a59abc2Raph Levien    // the configuration interface level.
412996e57c84368058be793897ebc355b917a59abc2Raph Levien    if (AF_INET != mMasterElectionEP.ss_family) {
4132af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        ALOGW("TODO: add proper IPv6 support");
4142af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        goto bailout;
4152af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    }
4162af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
4172af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    // open a UDP socket for the timeline serivce
4182af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    mSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
4190f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy    if (mSocket < 0) {
420996e57c84368058be793897ebc355b917a59abc2Raph Levien        ALOGE("Failed to create socket (errno = %d)", errno);
421996e57c84368058be793897ebc355b917a59abc2Raph Levien        goto bailout;
422996e57c84368058be793897ebc355b917a59abc2Raph Levien    }
423c25259519f1b74bb62a2b051b74537f073436b5cRomain Guy
424996e57c84368058be793897ebc355b917a59abc2Raph Levien    // Bind to the selected interface using Linux's spiffy SO_BINDTODEVICE.
425486590963e2207d68eebd6944fec70d50d41116aChet Haase    struct ifreq ifr;
42633f6beb10f98e8ba96250e284876d607055d278dRomain Guy    memset(&ifr, 0, sizeof(ifr));
42733f6beb10f98e8ba96250e284876d607055d278dRomain Guy    snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", mBindIface.string());
42833f6beb10f98e8ba96250e284876d607055d278dRomain Guy    ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = 0;
4292af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    rc = setsockopt(mSocket, SOL_SOCKET, SO_BINDTODEVICE,
4302af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik                    (void *)&ifr, sizeof(ifr));
4312af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    if (rc) {
43233f6beb10f98e8ba96250e284876d607055d278dRomain Guy        ALOGE("Failed to bind socket at to interface %s (errno = %d)",
4332af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik              ifr.ifr_name, errno);
4340f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy        goto bailout;
435486590963e2207d68eebd6944fec70d50d41116aChet Haase    }
436672433d90fab7383cd28beac9d4485b566a90940Romain Guy
437672433d90fab7383cd28beac9d4485b566a90940Romain Guy    // Bind our socket to INADDR_ANY and the master election port.  The
438672433d90fab7383cd28beac9d4485b566a90940Romain Guy    // interface binding we made using SO_BINDTODEVICE should limit us to
439672433d90fab7383cd28beac9d4485b566a90940Romain Guy    // traffic only on the interface we are interested in.  We need to bind to
440672433d90fab7383cd28beac9d4485b566a90940Romain Guy    // INADDR_ANY and the specific master election port in order to be able to
4412af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    // receive both unicast traffic and master election multicast traffic with
4422af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    // just a single socket.
4432af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    struct sockaddr_in bindAddr;
444672433d90fab7383cd28beac9d4485b566a90940Romain Guy    ipv4_addr = reinterpret_cast<struct sockaddr_in*>(&mMasterElectionEP);
445eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guy    memcpy(&bindAddr, ipv4_addr, sizeof(bindAddr));
446eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guy    bindAddr.sin_addr.s_addr = INADDR_ANY;
4474aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy    rc = bind(mSocket,
4482af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik              reinterpret_cast<const sockaddr *>(&bindAddr),
4494aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy              sizeof(bindAddr));
4504aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy    if (rc) {
4514aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy        ALOGE("Failed to bind socket to port %hu (errno = %d)",
4522af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik              ntohs(bindAddr.sin_port), errno);
4532af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        goto bailout;
4544aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy    }
4554aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
4564aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy    if (0xE0000000 == (ntohl(ipv4_addr->sin_addr.s_addr) & 0xF0000000)) {
4572af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        // If our master election endpoint is a multicast address, be sure to join
4584aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy        // the multicast group.
4594aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy        struct ip_mreq mreq;
4604aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy        mreq.imr_multiaddr = ipv4_addr->sin_addr;
4612af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        mreq.imr_interface.s_addr = htonl(INADDR_ANY);
4622af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        rc = setsockopt(mSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP,
4634aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy                        &mreq, sizeof(mreq));
4644aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy        if (rc == -1) {
4654aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy            ALOGE("Failed to join multicast group at %s.  (errno = %d)",
4662af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik                 masterElectionEPStr, errno);
4674aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy            goto bailout;
4684aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy        }
4694aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
4702af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        // disable loopback of multicast packets
4714aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy        const int zero = 0;
4724aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy        rc = setsockopt(mSocket, IPPROTO_IP, IP_MULTICAST_LOOP,
4735ff9df658230d49e42c43586997a02d8e4dd417eRomain Guy                        &zero, sizeof(zero));
4742af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        if (rc == -1) {
4755ff9df658230d49e42c43586997a02d8e4dd417eRomain Guy            ALOGE("Failed to disable multicast loopback (errno = %d)", errno);
4765ff9df658230d49e42c43586997a02d8e4dd417eRomain Guy            goto bailout;
4775ff9df658230d49e42c43586997a02d8e4dd417eRomain Guy        }
4782af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    } else
4792af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    if (ntohl(ipv4_addr->sin_addr.s_addr) != 0xFFFFFFFF) {
4802af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        // If the master election address is neither broadcast, nor multicast,
4812af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        // then we are misconfigured.  The config API layer should prevent this
4822af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        // from ever happening.
4832af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        goto bailout;
4842af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    }
4852af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
4862af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    // Set the TTL of sent packets to 1.  (Time protocol sync should never leave
4872af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    // the local subnet)
4882af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    rc = setsockopt(mSocket, IPPROTO_IP, IP_TTL, &one, sizeof(one));
4892af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    if (rc == -1) {
4902af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        ALOGE("Failed to set TTL to %d (errno = %d)", one, errno);
4912af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        goto bailout;
4922af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    }
4932af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
4942af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    // get the device's unique ID
4952af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    if (!assignDeviceID())
4962af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        goto bailout;
4972af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
4982af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    ret_val = true;
4992af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
5002af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikbailout:
5012af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    if (!ret_val)
5022af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        cleanupSocket_l();
5032af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    return ret_val;
5040f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy}
5052af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
5062af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik// generate a unique device ID that can be used for arbitration
5070f6675332c04c74909425d1d328f02b32c0ff40eRomain Guybool CommonTimeServer::assignDeviceID() {
5082af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    if (!mBindIfaceValid)
5092af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        return false;
5102af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
5112af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    struct ifreq ifr;
5122af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    memset(&ifr, 0, sizeof(ifr));
5135ff9df658230d49e42c43586997a02d8e4dd417eRomain Guy    ifr.ifr_addr.sa_family = AF_INET;
5145ff9df658230d49e42c43586997a02d8e4dd417eRomain Guy    strlcpy(ifr.ifr_name, mBindIface.string(), IFNAMSIZ);
5154aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
5164aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy    int rc = ioctl(mSocket, SIOCGIFHWADDR, &ifr);
517    if (rc) {
518        ALOGE("%s:%d ioctl failed", __PRETTY_FUNCTION__, __LINE__);
519        return false;
520    }
521
522    if (ifr.ifr_addr.sa_family != ARPHRD_ETHER) {
523        ALOGE("%s:%d got non-Ethernet address", __PRETTY_FUNCTION__, __LINE__);
524        return false;
525    }
526
527    mDeviceID = 0;
528    for (int i = 0; i < ETH_ALEN; i++) {
529        mDeviceID = (mDeviceID << 8) | ifr.ifr_hwaddr.sa_data[i];
530    }
531
532    return true;
533}
534
535// generate a new timeline ID
536void CommonTimeServer::assignTimelineID() {
537    do {
538        mTimelineID = (static_cast<uint64_t>(lrand48()) << 32)
539                    |  static_cast<uint64_t>(lrand48());
540    } while (mTimelineID == ICommonClock::kInvalidTimelineID);
541}
542
543// Select a preference between the device IDs of two potential masters.
544// Returns true if the first ID wins, or false if the second ID wins.
545bool CommonTimeServer::arbitrateMaster(
546        uint64_t deviceID1, uint8_t devicePrio1,
547        uint64_t deviceID2, uint8_t devicePrio2) {
548    return ((devicePrio1 >  devicePrio2) ||
549           ((devicePrio1 == devicePrio2) && (deviceID1 > deviceID2)));
550}
551
552bool CommonTimeServer::handlePacket() {
553    uint8_t buf[256];
554    struct sockaddr_storage srcAddr;
555    socklen_t srcAddrLen = sizeof(srcAddr);
556
557    ssize_t recvBytes = recvfrom(
558            mSocket, buf, sizeof(buf), 0,
559            reinterpret_cast<const sockaddr *>(&srcAddr), &srcAddrLen);
560
561    if (recvBytes < 0) {
562        ALOGE("%s:%d recvfrom failed", __PRETTY_FUNCTION__, __LINE__);
563        return false;
564    }
565
566    UniversalTimeServicePacket pkt;
567    recvBytes = pkt.deserializePacket(buf, recvBytes, mSyncGroupID);
568    if (recvBytes < 0)
569        return false;
570
571    bool result;
572    switch (pkt.packetType) {
573        case TIME_PACKET_WHO_IS_MASTER_REQUEST:
574            result = handleWhoIsMasterRequest(&pkt.p.who_is_master_request,
575                                              srcAddr);
576            break;
577
578        case TIME_PACKET_WHO_IS_MASTER_RESPONSE:
579            result = handleWhoIsMasterResponse(&pkt.p.who_is_master_response,
580                                               srcAddr);
581            break;
582
583        case TIME_PACKET_SYNC_REQUEST:
584            result = handleSyncRequest(&pkt.p.sync_request, srcAddr);
585            break;
586
587        case TIME_PACKET_SYNC_RESPONSE:
588            result = handleSyncResponse(&pkt.p.sync_response, srcAddr);
589            break;
590
591        case TIME_PACKET_MASTER_ANNOUNCEMENT:
592            result = handleMasterAnnouncement(&pkt.p.master_announcement,
593                                              srcAddr);
594            break;
595
596        default: {
597            ALOGD("%s:%d unknown packet type(%d)",
598                    __PRETTY_FUNCTION__, __LINE__, pkt.packetType);
599            result = false;
600        } break;
601    }
602
603    return result;
604}
605
606bool CommonTimeServer::handleTimeout() {
607    // If we have no socket, then this must be a timeout to retry socket setup.
608    if (mSocket < 0)
609        return true;
610
611    switch (mState) {
612        case ICommonClock::STATE_INITIAL:
613            return handleTimeoutInitial();
614        case ICommonClock::STATE_CLIENT:
615            return handleTimeoutClient();
616        case ICommonClock::STATE_MASTER:
617            return handleTimeoutMaster();
618        case ICommonClock::STATE_RONIN:
619            return handleTimeoutRonin();
620        case ICommonClock::STATE_WAIT_FOR_ELECTION:
621            return handleTimeoutWaitForElection();
622    }
623
624    return false;
625}
626
627bool CommonTimeServer::handleTimeoutInitial() {
628    if (++mInitial_WhoIsMasterRequestTimeouts ==
629            kInitial_NumWhoIsMasterRetries) {
630        // none of our attempts to discover a master succeeded, so make
631        // this device the master
632        return becomeMaster("initial timeout");
633    } else {
634        // retry the WhoIsMaster request
635        return sendWhoIsMasterRequest();
636    }
637}
638
639bool CommonTimeServer::handleTimeoutClient() {
640    if (shouldPanicNotGettingGoodData())
641        return becomeInitial("timeout panic, no good data");
642
643    if (mClient_SyncRequestPending) {
644        mClient_SyncRequestPending = false;
645
646        if (++mClient_SyncRequestTimeouts < kClient_NumSyncRequestRetries) {
647            // a sync request has timed out, so retry
648            return sendSyncRequest();
649        } else {
650            // The master has failed to respond to a sync request for too many
651            // times in a row.  Assume the master is dead and start electing
652            // a new master.
653            return becomeRonin("master not responding");
654        }
655    } else {
656        // initiate the next sync request
657        return sendSyncRequest();
658    }
659}
660
661bool CommonTimeServer::handleTimeoutMaster() {
662    // send another announcement from the master
663    return sendMasterAnnouncement();
664}
665
666bool CommonTimeServer::handleTimeoutRonin() {
667    if (++mRonin_WhoIsMasterRequestTimeouts == kRonin_NumWhoIsMasterRetries) {
668        // no other master is out there, so we won the election
669        return becomeMaster("no better masters detected");
670    } else {
671        return sendWhoIsMasterRequest();
672    }
673}
674
675bool CommonTimeServer::handleTimeoutWaitForElection() {
676    return becomeRonin("timeout waiting for election conclusion");
677}
678
679bool CommonTimeServer::handleWhoIsMasterRequest(
680        const WhoIsMasterRequestPacket* request,
681        const sockaddr_storage& srcAddr) {
682    if (mState == ICommonClock::STATE_MASTER) {
683        // is this request related to this master's timeline?
684        if (request->timelineID != ICommonClock::kInvalidTimelineID &&
685            request->timelineID != mTimelineID)
686            return true;
687
688        WhoIsMasterResponsePacket pkt;
689        pkt.initHeader(mTimelineID, mSyncGroupID);
690        pkt.deviceID = mDeviceID;
691        pkt.devicePriority = effectivePriority();
692
693        uint8_t buf[256];
694        ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
695        if (bufSz < 0)
696            return false;
697
698        ssize_t sendBytes = sendto(
699                mSocket, buf, bufSz, 0,
700                reinterpret_cast<const sockaddr *>(&srcAddr),
701                sizeof(srcAddr));
702        if (sendBytes == -1) {
703            ALOGE("%s:%d sendto failed", __PRETTY_FUNCTION__, __LINE__);
704            return false;
705        }
706    } else if (mState == ICommonClock::STATE_RONIN) {
707        // if we hear a WhoIsMaster request from another device following
708        // the same timeline and that device wins arbitration, then we will stop
709        // trying to elect ourselves master and will instead wait for an
710        // announcement from the election winner
711        if (request->timelineID != mTimelineID)
712            return true;
713
714        if (arbitrateMaster(request->senderDeviceID,
715                            request->senderDevicePriority,
716                            mDeviceID,
717                            effectivePriority()))
718            return becomeWaitForElection("would lose election");
719
720        return true;
721    } else if (mState == ICommonClock::STATE_INITIAL) {
722        // If a group of devices booted simultaneously (e.g. after a power
723        // outage) and all of them are in the initial state and there is no
724        // master, then each device may time out and declare itself master at
725        // the same time.  To avoid this, listen for
726        // WhoIsMaster(InvalidTimeline) requests from peers.  If we would lose
727        // arbitration against that peer, reset our timeout count so that the
728        // peer has a chance to become master before we time out.
729        if (request->timelineID == ICommonClock::kInvalidTimelineID &&
730                arbitrateMaster(request->senderDeviceID,
731                                request->senderDevicePriority,
732                                mDeviceID,
733                                effectivePriority())) {
734            mInitial_WhoIsMasterRequestTimeouts = 0;
735        }
736    }
737
738    return true;
739}
740
741bool CommonTimeServer::handleWhoIsMasterResponse(
742        const WhoIsMasterResponsePacket* response,
743        const sockaddr_storage& srcAddr) {
744    if (mState == ICommonClock::STATE_INITIAL || mState == ICommonClock::STATE_RONIN) {
745        return becomeClient(srcAddr,
746                            response->deviceID,
747                            response->devicePriority,
748                            response->timelineID,
749                            "heard whois response");
750    } else if (mState == ICommonClock::STATE_CLIENT) {
751        // if we get multiple responses because there are multiple devices
752        // who believe that they are master, then follow the master that
753        // wins arbitration
754        if (arbitrateMaster(response->deviceID,
755                            response->devicePriority,
756                            mClient_MasterDeviceID,
757                            mClient_MasterDevicePriority)) {
758            return becomeClient(srcAddr,
759                                response->deviceID,
760                                response->devicePriority,
761                                response->timelineID,
762                                "heard whois response");
763        }
764    }
765
766    return true;
767}
768
769bool CommonTimeServer::handleSyncRequest(const SyncRequestPacket* request,
770                                         const sockaddr_storage& srcAddr) {
771    SyncResponsePacket pkt;
772    pkt.initHeader(mTimelineID, mSyncGroupID);
773
774    if ((mState == ICommonClock::STATE_MASTER) &&
775        (mTimelineID == request->timelineID)) {
776        int64_t rxLocalTime = mLastPacketRxLocalTime;
777        int64_t rxCommonTime;
778
779        // If we are master on an actual network and have actual clients, then
780        // we are no longer low priority.
781        setForceLowPriority(false);
782
783        if (OK != mCommonClock.localToCommon(rxLocalTime, &rxCommonTime)) {
784            return false;
785        }
786
787        int64_t txLocalTime = mLocalClock.getLocalTime();;
788        int64_t txCommonTime;
789        if (OK != mCommonClock.localToCommon(txLocalTime, &txCommonTime)) {
790            return false;
791        }
792
793        pkt.nak = 0;
794        pkt.clientTxLocalTime  = request->clientTxLocalTime;
795        pkt.masterRxCommonTime = rxCommonTime;
796        pkt.masterTxCommonTime = txCommonTime;
797    } else {
798        pkt.nak = 1;
799        pkt.clientTxLocalTime  = 0;
800        pkt.masterRxCommonTime = 0;
801        pkt.masterTxCommonTime = 0;
802    }
803
804    uint8_t buf[256];
805    ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
806    if (bufSz < 0)
807        return false;
808
809    ssize_t sendBytes = sendto(
810            mSocket, &buf, bufSz, 0,
811            reinterpret_cast<const sockaddr *>(&srcAddr),
812            sizeof(srcAddr));
813    if (sendBytes == -1) {
814        ALOGE("%s:%d sendto failed", __PRETTY_FUNCTION__, __LINE__);
815        return false;
816    }
817
818    return true;
819}
820
821bool CommonTimeServer::handleSyncResponse(
822        const SyncResponsePacket* response,
823        const sockaddr_storage& srcAddr) {
824    if (mState != ICommonClock::STATE_CLIENT)
825        return true;
826
827    assert(mMasterEPValid);
828    if (!sockaddrMatch(srcAddr, mMasterEP, true)) {
829        char srcEP[64], expectedEP[64];
830        sockaddrToString(srcAddr, true, srcEP, sizeof(srcEP));
831        sockaddrToString(mMasterEP, true, expectedEP, sizeof(expectedEP));
832        ALOGI("Dropping sync response from unexpected address."
833             " Expected %s Got %s", expectedEP, srcEP);
834        return true;
835    }
836
837    if (response->nak) {
838        // if our master is no longer accepting requests, then we need to find
839        // a new master
840        return becomeRonin("master NAK'ed");
841    }
842
843    mClient_SyncRequestPending = 0;
844    mClient_SyncRequestTimeouts = 0;
845    mClient_PacketRTTLog.logRX(response->clientTxLocalTime,
846                               mLastPacketRxLocalTime);
847
848    bool result;
849    if (!(mClient_SyncRespsRXedFromCurMaster++)) {
850        // the first request/response exchange between a client and a master
851        // may take unusually long due to ARP, so discard it.
852        result = true;
853    } else {
854        int64_t clientTxLocalTime  = response->clientTxLocalTime;
855        int64_t clientRxLocalTime  = mLastPacketRxLocalTime;
856        int64_t masterTxCommonTime = response->masterTxCommonTime;
857        int64_t masterRxCommonTime = response->masterRxCommonTime;
858
859        int64_t rtt       = (clientRxLocalTime - clientTxLocalTime);
860        int64_t avgLocal  = (clientTxLocalTime + clientRxLocalTime) >> 1;
861        int64_t avgCommon = (masterTxCommonTime + masterRxCommonTime) >> 1;
862
863        // if the RTT of the packet is significantly larger than the panic
864        // threshold, we should simply discard it.  Its better to do nothing
865        // than to take cues from a packet like that.
866        int rttCommon = mCommonClock.localDurationToCommonDuration(rtt);
867        if (rttCommon > (static_cast<int64_t>(mPanicThresholdUsec) *
868                         kRTTDiscardPanicThreshMultiplier)) {
869            ALOGV("Dropping sync response with RTT of %lld uSec", rttCommon);
870            mClient_ExpiredSyncRespsRXedFromCurMaster++;
871            if (shouldPanicNotGettingGoodData())
872                return becomeInitial("RX panic, no good data");
873        } else {
874            result = mClockRecovery.pushDisciplineEvent(avgLocal, avgCommon, rtt);
875            mClient_LastGoodSyncRX = clientRxLocalTime;
876
877            if (result) {
878                // indicate to listeners that we've synced to the common timeline
879                notifyClockSync();
880            } else {
881                ALOGE("Panic!  Observed clock sync error is too high to tolerate,"
882                        " resetting state machine and starting over.");
883                notifyClockSyncLoss();
884                return becomeInitial("panic");
885            }
886        }
887    }
888
889    mCurTimeout.setTimeout(mSyncRequestIntervalMs);
890    return result;
891}
892
893bool CommonTimeServer::handleMasterAnnouncement(
894        const MasterAnnouncementPacket* packet,
895        const sockaddr_storage& srcAddr) {
896    uint64_t newDeviceID   = packet->deviceID;
897    uint8_t  newDevicePrio = packet->devicePriority;
898    uint64_t newTimelineID = packet->timelineID;
899
900    if (mState == ICommonClock::STATE_INITIAL ||
901        mState == ICommonClock::STATE_RONIN ||
902        mState == ICommonClock::STATE_WAIT_FOR_ELECTION) {
903        // if we aren't currently following a master, then start following
904        // this new master
905        return becomeClient(srcAddr,
906                            newDeviceID,
907                            newDevicePrio,
908                            newTimelineID,
909                            "heard master announcement");
910    } else if (mState == ICommonClock::STATE_CLIENT) {
911        // if the new master wins arbitration against our current master,
912        // then become a client of the new master
913        if (arbitrateMaster(newDeviceID,
914                            newDevicePrio,
915                            mClient_MasterDeviceID,
916                            mClient_MasterDevicePriority))
917            return becomeClient(srcAddr,
918                                newDeviceID,
919                                newDevicePrio,
920                                newTimelineID,
921                                "heard master announcement");
922    } else if (mState == ICommonClock::STATE_MASTER) {
923        // two masters are competing - if the new one wins arbitration, then
924        // cease acting as master
925        if (arbitrateMaster(newDeviceID, newDevicePrio,
926                            mDeviceID, effectivePriority()))
927            return becomeClient(srcAddr, newDeviceID,
928                                newDevicePrio, newTimelineID,
929                                "heard master announcement");
930    }
931
932    return true;
933}
934
935bool CommonTimeServer::sendWhoIsMasterRequest() {
936    assert(mState == ICommonClock::STATE_INITIAL || mState == ICommonClock::STATE_RONIN);
937
938    // If we have no socket, then we must be in the unconfigured initial state.
939    // Don't report any errors, just don't try to send the initial who-is-master
940    // query.  Eventually, our network will either become configured, or we will
941    // be forced into network-less master mode by higher level code.
942    if (mSocket < 0) {
943        assert(mState == ICommonClock::STATE_INITIAL);
944        return true;
945    }
946
947    bool ret = false;
948    WhoIsMasterRequestPacket pkt;
949    pkt.initHeader(mSyncGroupID);
950    pkt.senderDeviceID = mDeviceID;
951    pkt.senderDevicePriority = effectivePriority();
952
953    uint8_t buf[256];
954    ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
955    if (bufSz >= 0) {
956        ssize_t sendBytes = sendto(
957                mSocket, buf, bufSz, 0,
958                reinterpret_cast<const sockaddr *>(&mMasterElectionEP),
959                sizeof(mMasterElectionEP));
960        if (sendBytes < 0)
961            ALOGE("WhoIsMaster sendto failed (errno %d)", errno);
962        ret = true;
963    }
964
965    if (mState == ICommonClock::STATE_INITIAL) {
966        mCurTimeout.setTimeout(kInitial_WhoIsMasterTimeoutMs);
967    } else {
968        mCurTimeout.setTimeout(kRonin_WhoIsMasterTimeoutMs);
969    }
970
971    return ret;
972}
973
974bool CommonTimeServer::sendSyncRequest() {
975    // If we are sending sync requests, then we must be in the client state and
976    // we must have a socket (when we have no network, we are only supposed to
977    // be in INITIAL or MASTER)
978    assert(mState == ICommonClock::STATE_CLIENT);
979    assert(mSocket >= 0);
980
981    bool ret = false;
982    SyncRequestPacket pkt;
983    pkt.initHeader(mTimelineID, mSyncGroupID);
984    pkt.clientTxLocalTime = mLocalClock.getLocalTime();
985
986    if (!mClient_FirstSyncTX)
987        mClient_FirstSyncTX = pkt.clientTxLocalTime;
988
989    mClient_PacketRTTLog.logTX(pkt.clientTxLocalTime);
990
991    uint8_t buf[256];
992    ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
993    if (bufSz >= 0) {
994        ssize_t sendBytes = sendto(
995                mSocket, buf, bufSz, 0,
996                reinterpret_cast<const sockaddr *>(&mMasterEP),
997                sizeof(mMasterEP));
998        if (sendBytes < 0)
999            ALOGE("SyncRequest sendto failed (errno %d)", errno);
1000        ret = true;
1001    }
1002
1003    mClient_SyncsSentToCurMaster++;
1004    mCurTimeout.setTimeout(mSyncRequestIntervalMs);
1005    mClient_SyncRequestPending = true;
1006
1007    return ret;
1008}
1009
1010bool CommonTimeServer::sendMasterAnnouncement() {
1011    bool ret = false;
1012    assert(mState == ICommonClock::STATE_MASTER);
1013
1014    // If we are being asked to send a master announcement, but we have no
1015    // socket, we must be in network-less master mode.  Don't bother to send the
1016    // announcement, and don't bother to schedule a timeout.  When the network
1017    // comes up, the work thread will get poked and start the process of
1018    // figuring out who the current master should be.
1019    if (mSocket < 0) {
1020        mCurTimeout.setTimeout(kInfiniteTimeout);
1021        return true;
1022    }
1023
1024    MasterAnnouncementPacket pkt;
1025    pkt.initHeader(mTimelineID, mSyncGroupID);
1026    pkt.deviceID = mDeviceID;
1027    pkt.devicePriority = effectivePriority();
1028
1029    uint8_t buf[256];
1030    ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
1031    if (bufSz >= 0) {
1032        ssize_t sendBytes = sendto(
1033                mSocket, buf, bufSz, 0,
1034                reinterpret_cast<const sockaddr *>(&mMasterElectionEP),
1035                sizeof(mMasterElectionEP));
1036        if (sendBytes < 0)
1037            ALOGE("MasterAnnouncement sendto failed (errno %d)", errno);
1038        ret = true;
1039    }
1040
1041    mCurTimeout.setTimeout(mMasterAnnounceIntervalMs);
1042    return ret;
1043}
1044
1045bool CommonTimeServer::becomeClient(const sockaddr_storage& masterEP,
1046                                    uint64_t masterDeviceID,
1047                                    uint8_t  masterDevicePriority,
1048                                    uint64_t timelineID,
1049                                    const char* cause) {
1050    char newEPStr[64], oldEPStr[64];
1051    sockaddrToString(masterEP, true, newEPStr, sizeof(newEPStr));
1052    sockaddrToString(mMasterEP, mMasterEPValid, oldEPStr, sizeof(oldEPStr));
1053
1054    ALOGI("%s --> CLIENT (%s) :%s"
1055         " OldMaster: %02x-%014llx::%016llx::%s"
1056         " NewMaster: %02x-%014llx::%016llx::%s",
1057         stateToString(mState), cause,
1058         (mTimelineID != timelineID) ? " (new timeline)" : "",
1059         mClient_MasterDevicePriority, mClient_MasterDeviceID,
1060         mTimelineID, oldEPStr,
1061         masterDevicePriority, masterDeviceID,
1062         timelineID, newEPStr);
1063
1064    if (mTimelineID != timelineID) {
1065        // start following a new timeline
1066        mTimelineID = timelineID;
1067        mClockRecovery.reset(true, true);
1068        notifyClockSyncLoss();
1069    } else {
1070        // start following a new master on the existing timeline
1071        mClockRecovery.reset(false, true);
1072    }
1073
1074    mMasterEP = masterEP;
1075    mMasterEPValid = true;
1076    setForceLowPriority(false);
1077
1078    mClient_MasterDeviceID = masterDeviceID;
1079    mClient_MasterDevicePriority = masterDevicePriority;
1080    resetSyncStats();
1081
1082    setState(ICommonClock::STATE_CLIENT);
1083
1084    // add some jitter to when the various clients send their requests
1085    // in order to reduce the likelihood that a group of clients overload
1086    // the master after receiving a master announcement
1087    usleep((lrand48() % 100) * 1000);
1088
1089    return sendSyncRequest();
1090}
1091
1092bool CommonTimeServer::becomeMaster(const char* cause) {
1093    uint64_t oldTimelineID = mTimelineID;
1094    if (mTimelineID == ICommonClock::kInvalidTimelineID) {
1095        // this device has not been following any existing timeline,
1096        // so it will create a new timeline and declare itself master
1097        assert(!mCommonClock.isValid());
1098
1099        // set the common time basis
1100        mCommonClock.setBasis(mLocalClock.getLocalTime(), 0);
1101
1102        // assign an arbitrary timeline iD
1103        assignTimelineID();
1104
1105        // notify listeners that we've created a common timeline
1106        notifyClockSync();
1107    }
1108
1109    ALOGI("%s --> MASTER (%s) : %s timeline %016llx",
1110         stateToString(mState), cause,
1111         (oldTimelineID == mTimelineID) ? "taking ownership of"
1112                                        : "creating new",
1113         mTimelineID);
1114
1115    memset(&mMasterEP, 0, sizeof(mMasterEP));
1116    mMasterEPValid = false;
1117    setForceLowPriority(false);
1118    mClient_MasterDevicePriority = effectivePriority();
1119    mClient_MasterDeviceID = mDeviceID;
1120    mClockRecovery.reset(false, true);
1121    resetSyncStats();
1122
1123    setState(ICommonClock::STATE_MASTER);
1124    return sendMasterAnnouncement();
1125}
1126
1127bool CommonTimeServer::becomeRonin(const char* cause) {
1128    // If we were the client of a given timeline, but had never received even a
1129    // single time sync packet, then we transition back to Initial instead of
1130    // Ronin.  If we transition to Ronin and end up becoming the new Master, we
1131    // will be unable to service requests for other clients because we never
1132    // actually knew what time it was.  By going to initial, we ensure that
1133    // other clients who know what time it is, but would lose master arbitration
1134    // in the Ronin case, will step up and become the proper new master of the
1135    // old timeline.
1136
1137    char oldEPStr[64];
1138    sockaddrToString(mMasterEP, mMasterEPValid, oldEPStr, sizeof(oldEPStr));
1139    memset(&mMasterEP, 0, sizeof(mMasterEP));
1140    mMasterEPValid = false;
1141
1142    if (mCommonClock.isValid()) {
1143        ALOGI("%s --> RONIN (%s) : lost track of previously valid timeline "
1144             "%02x-%014llx::%016llx::%s (%d TXed %d RXed %d RXExpired)",
1145             stateToString(mState), cause,
1146             mClient_MasterDevicePriority, mClient_MasterDeviceID,
1147             mTimelineID, oldEPStr,
1148             mClient_SyncsSentToCurMaster,
1149             mClient_SyncRespsRXedFromCurMaster,
1150             mClient_ExpiredSyncRespsRXedFromCurMaster);
1151
1152        mRonin_WhoIsMasterRequestTimeouts = 0;
1153        setState(ICommonClock::STATE_RONIN);
1154        return sendWhoIsMasterRequest();
1155    } else {
1156        ALOGI("%s --> INITIAL (%s) : never synced timeline "
1157             "%02x-%014llx::%016llx::%s (%d TXed %d RXed %d RXExpired)",
1158             stateToString(mState), cause,
1159             mClient_MasterDevicePriority, mClient_MasterDeviceID,
1160             mTimelineID, oldEPStr,
1161             mClient_SyncsSentToCurMaster,
1162             mClient_SyncRespsRXedFromCurMaster,
1163             mClient_ExpiredSyncRespsRXedFromCurMaster);
1164
1165        return becomeInitial("ronin, no timeline");
1166    }
1167}
1168
1169bool CommonTimeServer::becomeWaitForElection(const char* cause) {
1170    ALOGI("%s --> WAIT_FOR_ELECTION (%s) : dropping out of election,"
1171         " waiting %d mSec for completion.",
1172         stateToString(mState), cause, kWaitForElection_TimeoutMs);
1173
1174    setState(ICommonClock::STATE_WAIT_FOR_ELECTION);
1175    mCurTimeout.setTimeout(kWaitForElection_TimeoutMs);
1176    return true;
1177}
1178
1179bool CommonTimeServer::becomeInitial(const char* cause) {
1180    ALOGI("Entering INITIAL (%s), total reset.", cause);
1181
1182    setState(ICommonClock::STATE_INITIAL);
1183
1184    // reset clock recovery
1185    mClockRecovery.reset(true, true);
1186
1187    // reset internal state bookkeeping.
1188    mCurTimeout.setTimeout(kInfiniteTimeout);
1189    memset(&mMasterEP, 0, sizeof(mMasterEP));
1190    mMasterEPValid = false;
1191    mLastPacketRxLocalTime = 0;
1192    mTimelineID = ICommonClock::kInvalidTimelineID;
1193    mClockSynced = false;
1194    mInitial_WhoIsMasterRequestTimeouts = 0;
1195    mClient_MasterDeviceID = 0;
1196    mClient_MasterDevicePriority = 0;
1197    mRonin_WhoIsMasterRequestTimeouts = 0;
1198    resetSyncStats();
1199
1200    // send the first request to discover the master
1201    return sendWhoIsMasterRequest();
1202}
1203
1204void CommonTimeServer::notifyClockSync() {
1205    if (!mClockSynced) {
1206        mClockSynced = true;
1207        mICommonClock->notifyOnTimelineChanged(mTimelineID);
1208    }
1209}
1210
1211void CommonTimeServer::notifyClockSyncLoss() {
1212    if (mClockSynced) {
1213        mClockSynced = false;
1214        mICommonClock->notifyOnTimelineChanged(
1215                ICommonClock::kInvalidTimelineID);
1216    }
1217}
1218
1219void CommonTimeServer::setState(ICommonClock::State s) {
1220    mState = s;
1221}
1222
1223const char* CommonTimeServer::stateToString(ICommonClock::State s) {
1224    switch(s) {
1225        case ICommonClock::STATE_INITIAL:
1226            return "INITIAL";
1227        case ICommonClock::STATE_CLIENT:
1228            return "CLIENT";
1229        case ICommonClock::STATE_MASTER:
1230            return "MASTER";
1231        case ICommonClock::STATE_RONIN:
1232            return "RONIN";
1233        case ICommonClock::STATE_WAIT_FOR_ELECTION:
1234            return "WAIT_FOR_ELECTION";
1235        default:
1236            return "unknown";
1237    }
1238}
1239
1240void CommonTimeServer::sockaddrToString(const sockaddr_storage& addr,
1241                                        bool addrValid,
1242                                        char* buf, size_t bufLen) {
1243    if (!bufLen || !buf)
1244        return;
1245
1246    if (addrValid) {
1247        switch (addr.ss_family) {
1248            case AF_INET: {
1249                const struct sockaddr_in* sa =
1250                    reinterpret_cast<const struct sockaddr_in*>(&addr);
1251                unsigned long a = ntohl(sa->sin_addr.s_addr);
1252                uint16_t      p = ntohs(sa->sin_port);
1253                snprintf(buf, bufLen, "%lu.%lu.%lu.%lu:%hu",
1254                        ((a >> 24) & 0xFF), ((a >> 16) & 0xFF),
1255                        ((a >>  8) & 0xFF),  (a        & 0xFF), p);
1256            } break;
1257
1258            case AF_INET6: {
1259                const struct sockaddr_in6* sa =
1260                    reinterpret_cast<const struct sockaddr_in6*>(&addr);
1261                const uint8_t* a = sa->sin6_addr.s6_addr;
1262                uint16_t       p = ntohs(sa->sin6_port);
1263                snprintf(buf, bufLen,
1264                        "%02X%02X:%02X%02X:%02X%02X:%02X%02X:"
1265                        "%02X%02X:%02X%02X:%02X%02X:%02X%02X port %hd",
1266                        a[0], a[1], a[ 2], a[ 3], a[ 4], a[ 5], a[ 6], a[ 7],
1267                        a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15],
1268                        p);
1269            } break;
1270
1271            default:
1272                snprintf(buf, bufLen,
1273                         "<unknown sockaddr family %d>", addr.ss_family);
1274                break;
1275        }
1276    } else {
1277        snprintf(buf, bufLen, "<none>");
1278    }
1279
1280    buf[bufLen - 1] = 0;
1281}
1282
1283bool CommonTimeServer::sockaddrMatch(const sockaddr_storage& a1,
1284                                     const sockaddr_storage& a2,
1285                                     bool matchAddressOnly) {
1286    if (a1.ss_family != a2.ss_family)
1287        return false;
1288
1289    switch (a1.ss_family) {
1290        case AF_INET: {
1291            const struct sockaddr_in* sa1 =
1292                reinterpret_cast<const struct sockaddr_in*>(&a1);
1293            const struct sockaddr_in* sa2 =
1294                reinterpret_cast<const struct sockaddr_in*>(&a2);
1295
1296            if (sa1->sin_addr.s_addr != sa2->sin_addr.s_addr)
1297                return false;
1298
1299            return (matchAddressOnly || (sa1->sin_port == sa2->sin_port));
1300        } break;
1301
1302        case AF_INET6: {
1303            const struct sockaddr_in6* sa1 =
1304                reinterpret_cast<const struct sockaddr_in6*>(&a1);
1305            const struct sockaddr_in6* sa2 =
1306                reinterpret_cast<const struct sockaddr_in6*>(&a2);
1307
1308            if (memcmp(&sa1->sin6_addr, &sa2->sin6_addr, sizeof(sa2->sin6_addr)))
1309                return false;
1310
1311            return (matchAddressOnly || (sa1->sin6_port == sa2->sin6_port));
1312        } break;
1313
1314        // Huh?  We don't deal in non-IPv[46] addresses.  Not sure how we got
1315        // here, but we don't know how to comapre these addresses and simply
1316        // default to a no-match decision.
1317        default: return false;
1318    }
1319}
1320
1321void CommonTimeServer::TimeoutHelper::setTimeout(int msec) {
1322    mTimeoutValid = (msec >= 0);
1323    if (mTimeoutValid)
1324        mEndTime = systemTime() +
1325                   (static_cast<nsecs_t>(msec) * 1000000);
1326}
1327
1328int CommonTimeServer::TimeoutHelper::msecTillTimeout() {
1329    if (!mTimeoutValid)
1330        return kInfiniteTimeout;
1331
1332    nsecs_t now = systemTime();
1333    if (now >= mEndTime)
1334        return 0;
1335
1336    uint64_t deltaMsec = (((mEndTime - now) + 999999) / 1000000);
1337
1338    if (deltaMsec > static_cast<uint64_t>(std::numeric_limits<int>::max()))
1339        return std::numeric_limits<int>::max();
1340
1341    return static_cast<int>(deltaMsec);
1342}
1343
1344bool CommonTimeServer::shouldPanicNotGettingGoodData() {
1345    if (mClient_FirstSyncTX) {
1346        int64_t now = mLocalClock.getLocalTime();
1347        int64_t delta = now - (mClient_LastGoodSyncRX
1348                             ? mClient_LastGoodSyncRX
1349                             : mClient_FirstSyncTX);
1350        int64_t deltaUsec = mCommonClock.localDurationToCommonDuration(delta);
1351
1352        if (deltaUsec >= kNoGoodDataPanicThresholdUsec)
1353            return true;
1354    }
1355
1356    return false;
1357}
1358
1359void CommonTimeServer::PacketRTTLog::logTX(int64_t txTime) {
1360    txTimes[wrPtr] = txTime;
1361    rxTimes[wrPtr] = 0;
1362    wrPtr = (wrPtr + 1) % RTT_LOG_SIZE;
1363    if (!wrPtr)
1364        logFull = true;
1365}
1366
1367void CommonTimeServer::PacketRTTLog::logRX(int64_t txTime, int64_t rxTime) {
1368    if (!logFull && !wrPtr)
1369        return;
1370
1371    uint32_t i = logFull ? wrPtr : 0;
1372    do {
1373        if (txTimes[i] == txTime) {
1374            rxTimes[i] = rxTime;
1375            break;
1376        }
1377        i = (i + 1) % RTT_LOG_SIZE;
1378    } while (i != wrPtr);
1379}
1380
1381}  // namespace android
1382