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