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