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