1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ANDROID_COMMON_TIME_SERVER_H 18 #define ANDROID_COMMON_TIME_SERVER_H 19 20 #include <arpa/inet.h> 21 #include <stdint.h> 22 #include <sys/socket.h> 23 24 #include <common_time/ICommonClock.h> 25 #include <common_time/local_clock.h> 26 #include <utils/String8.h> 27 28 #include "clock_recovery.h" 29 #include "common_clock.h" 30 #include "common_time_server_packets.h" 31 #include "utils.h" 32 33 #define RTT_LOG_SIZE 30 34 35 namespace android { 36 37 class CommonClockService; 38 class CommonTimeConfigService; 39 40 /***** time service implementation *****/ 41 42 class CommonTimeServer : public Thread { 43 public: 44 CommonTimeServer(); 45 ~CommonTimeServer(); 46 47 bool startServices(); 48 49 // Common Clock API methods getCommonClock()50 CommonClock& getCommonClock() { return mCommonClock; } getLocalClock()51 LocalClock& getLocalClock() { return mLocalClock; } 52 uint64_t getTimelineID(); 53 int32_t getEstimatedError(); 54 ICommonClock::State getState(); 55 status_t getMasterAddr(struct sockaddr_storage* addr); 56 status_t isCommonTimeValid(bool* valid, uint32_t* timelineID); 57 58 // Config API methods 59 status_t getMasterElectionPriority(uint8_t *priority); 60 status_t setMasterElectionPriority(uint8_t priority); 61 status_t getMasterElectionEndpoint(struct sockaddr_storage *addr); 62 status_t setMasterElectionEndpoint(const struct sockaddr_storage *addr); 63 status_t getMasterElectionGroupId(uint64_t *id); 64 status_t setMasterElectionGroupId(uint64_t id); 65 status_t getInterfaceBinding(String8& ifaceName); 66 status_t setInterfaceBinding(const String8& ifaceName); 67 status_t getMasterAnnounceInterval(int *interval); 68 status_t setMasterAnnounceInterval(int interval); 69 status_t getClientSyncInterval(int *interval); 70 status_t setClientSyncInterval(int interval); 71 status_t getPanicThreshold(int *threshold); 72 status_t setPanicThreshold(int threshold); 73 status_t getAutoDisable(bool *autoDisable); 74 status_t setAutoDisable(bool autoDisable); 75 status_t forceNetworklessMasterMode(); 76 77 // Method used by the CommonClockService to notify the core service about 78 // changes in the number of active common clock clients. 79 void reevaluateAutoDisableState(bool commonClockHasClients); 80 81 status_t dumpClockInterface(int fd, const Vector<String16>& args, 82 size_t activeClients); 83 status_t dumpConfigInterface(int fd, const Vector<String16>& args); 84 85 private: 86 class PacketRTTLog { 87 public: PacketRTTLog()88 PacketRTTLog() { 89 resetLog(); 90 } 91 resetLog()92 void resetLog() { 93 wrPtr = 0; 94 logFull = 0; 95 } 96 97 void logTX(int64_t txTime); 98 void logRX(int64_t txTime, int64_t rxTime); 99 void dumpLog(int fd, const CommonClock& cclk); 100 101 private: 102 uint32_t wrPtr; 103 bool logFull; 104 int64_t txTimes[RTT_LOG_SIZE]; 105 int64_t rxTimes[RTT_LOG_SIZE]; 106 }; 107 108 bool threadLoop(); 109 110 bool runStateMachine_l(); 111 bool setupSocket_l(); 112 113 void assignTimelineID(); 114 bool assignDeviceID(); 115 116 static bool arbitrateMaster(uint64_t deviceID1, uint8_t devicePrio1, 117 uint64_t deviceID2, uint8_t devicePrio2); 118 119 bool handlePacket(); 120 bool handleWhoIsMasterRequest (const WhoIsMasterRequestPacket* request, 121 const sockaddr_storage& srcAddr); 122 bool handleWhoIsMasterResponse(const WhoIsMasterResponsePacket* response, 123 const sockaddr_storage& srcAddr); 124 bool handleSyncRequest (const SyncRequestPacket* request, 125 const sockaddr_storage& srcAddr); 126 bool handleSyncResponse (const SyncResponsePacket* response, 127 const sockaddr_storage& srcAddr); 128 bool handleMasterAnnouncement (const MasterAnnouncementPacket* packet, 129 const sockaddr_storage& srcAddr); 130 131 bool handleTimeout(); 132 bool handleTimeoutInitial(); 133 bool handleTimeoutClient(); 134 bool handleTimeoutMaster(); 135 bool handleTimeoutRonin(); 136 bool handleTimeoutWaitForElection(); 137 138 bool sendWhoIsMasterRequest(); 139 bool sendSyncRequest(); 140 bool sendMasterAnnouncement(); 141 142 bool becomeClient(const sockaddr_storage& masterAddr, 143 uint64_t masterDeviceID, 144 uint8_t masterDevicePriority, 145 uint64_t timelineID, 146 const char* cause); 147 bool becomeMaster(const char* cause); 148 bool becomeRonin(const char* cause); 149 bool becomeWaitForElection(const char* cause); 150 bool becomeInitial(const char* cause); 151 152 void notifyClockSync(); 153 void notifyClockSyncLoss(); 154 155 ICommonClock::State mState; 156 void setState(ICommonClock::State s); 157 158 void clearPendingWakeupEvents_l(); 159 void wakeupThread_l(); 160 void cleanupSocket_l(); 161 void shutdownThread(); 162 effectivePriority()163 inline uint8_t effectivePriority() const { 164 return (mMasterPriority & 0x7F) | 165 (mForceLowPriority ? 0x00 : 0x80); 166 } 167 shouldAutoDisable()168 inline bool shouldAutoDisable() const { 169 return (mAutoDisable && !mCommonClockHasClients); 170 } 171 resetSyncStats()172 inline void resetSyncStats() { 173 mClient_SyncRequestPending = false; 174 mClient_SyncRequestTimeouts = 0; 175 mClient_SyncsSentToCurMaster = 0; 176 mClient_SyncRespsRXedFromCurMaster = 0; 177 mClient_ExpiredSyncRespsRXedFromCurMaster = 0; 178 mClient_FirstSyncTX = 0; 179 mClient_LastGoodSyncRX = 0; 180 mClient_PacketRTTLog.resetLog(); 181 } 182 183 bool shouldPanicNotGettingGoodData(); 184 185 // Helper to keep track of the state machine's current timeout 186 Timeout mCurTimeout; 187 188 // common clock, local clock abstraction, and clock recovery loop 189 CommonClock mCommonClock; 190 LocalClock mLocalClock; 191 ClockRecoveryLoop mClockRecovery; 192 193 // implementation of ICommonClock 194 sp<CommonClockService> mICommonClock; 195 196 // implementation of ICommonTimeConfig 197 sp<CommonTimeConfigService> mICommonTimeConfig; 198 199 // UDP socket for the time sync protocol 200 int mSocket; 201 202 // eventfd used to wakeup the work thread in response to configuration 203 // changes. 204 int mWakeupThreadFD; 205 206 // timestamp captured when a packet is received 207 int64_t mLastPacketRxLocalTime; 208 209 // ID of the timeline that this device is following 210 uint64_t mTimelineID; 211 212 // flag for whether the clock has been synced to a timeline 213 bool mClockSynced; 214 215 // flag used to indicate that clients should be considered to be lower 216 // priority than all of their peers during elections. This flag is set and 217 // cleared by the state machine. It is set when the client joins a new 218 // network. If the client had been a master in the old network (or an 219 // isolated master with no network connectivity) it should defer to any 220 // masters which may already be on the network. It will be cleared whenever 221 // the state machine transitions to the master state. 222 bool mForceLowPriority; setForceLowPriority(bool val)223 inline void setForceLowPriority(bool val) { 224 mForceLowPriority = val; 225 if (mState == ICommonClock::STATE_MASTER) 226 mClient_MasterDevicePriority = effectivePriority(); 227 } 228 229 // Lock to synchronize access to internal state and configuration. 230 Mutex mLock; 231 232 // Flag updated by the common clock service to indicate that it does or does 233 // not currently have registered clients. When the the auto disable flag is 234 // cleared on the common time service, the service will participate in 235 // network synchronization whenever it has a valid network interface to bind 236 // to. When the auto disable flag is set on the common time service, it 237 // will only participate in network synchronization when it has both a valid 238 // interface AND currently active common clock clients. 239 bool mCommonClockHasClients; 240 241 // Internal logs used for dumpsys. 242 LogRing mStateChangeLog; 243 LogRing mElectionLog; 244 LogRing mBadPktLog; 245 246 // Configuration info 247 struct sockaddr_storage mMasterElectionEP; // Endpoint over which we conduct master election 248 String8 mBindIface; // Endpoint for the service to bind to. 249 bool mBindIfaceValid; // whether or not the bind Iface is valid. 250 bool mBindIfaceDirty; // whether or not the bind Iface is valid. 251 struct sockaddr_storage mMasterEP; // Endpoint of our current master (if any) 252 bool mMasterEPValid; 253 uint64_t mDeviceID; // unique ID of this device 254 uint64_t mSyncGroupID; // synchronization group ID of this device. 255 uint8_t mMasterPriority; // Priority of this device in master election. 256 uint32_t mMasterAnnounceIntervalMs; 257 uint32_t mSyncRequestIntervalMs; 258 uint32_t mPanicThresholdUsec; 259 bool mAutoDisable; 260 261 // Config defaults. 262 static const char* kDefaultMasterElectionAddr; 263 static const uint16_t kDefaultMasterElectionPort; 264 static const uint64_t kDefaultSyncGroupID; 265 static const uint8_t kDefaultMasterPriority; 266 static const uint32_t kDefaultMasterAnnounceIntervalMs; 267 static const uint32_t kDefaultSyncRequestIntervalMs; 268 static const uint32_t kDefaultPanicThresholdUsec; 269 static const bool kDefaultAutoDisable; 270 271 // Priority mask and shift fields. 272 static const uint64_t kDeviceIDMask; 273 static const uint8_t kDevicePriorityMask; 274 static const uint8_t kDevicePriorityHiLowBit; 275 static const uint32_t kDevicePriorityShift; 276 277 // Unconfgurable constants 278 static const int kSetupRetryTimeoutMs; 279 static const int64_t kNoGoodDataPanicThresholdUsec; 280 static const uint32_t kRTTDiscardPanicThreshMultiplier; 281 282 /*** status while in the Initial state ***/ 283 int mInitial_WhoIsMasterRequestTimeouts; 284 static const int kInitial_NumWhoIsMasterRetries; 285 static const int kInitial_WhoIsMasterTimeoutMs; 286 287 /*** status while in the Client state ***/ 288 uint64_t mClient_MasterDeviceID; 289 uint8_t mClient_MasterDevicePriority; 290 bool mClient_SyncRequestPending; 291 int mClient_SyncRequestTimeouts; 292 uint32_t mClient_SyncsSentToCurMaster; 293 uint32_t mClient_SyncRespsRXedFromCurMaster; 294 uint32_t mClient_ExpiredSyncRespsRXedFromCurMaster; 295 int64_t mClient_FirstSyncTX; 296 int64_t mClient_LastGoodSyncRX; 297 PacketRTTLog mClient_PacketRTTLog; 298 static const int kClient_NumSyncRequestRetries; 299 300 301 /*** status while in the Master state ***/ 302 static const uint32_t kDefaultMaster_AnnouncementIntervalMs; 303 304 /*** status while in the Ronin state ***/ 305 int mRonin_WhoIsMasterRequestTimeouts; 306 static const int kRonin_NumWhoIsMasterRetries; 307 static const int kRonin_WhoIsMasterTimeoutMs; 308 309 /*** status while in the WaitForElection state ***/ 310 static const int kWaitForElection_TimeoutMs; 311 312 static const int kInfiniteTimeout; 313 314 static const char* stateToString(ICommonClock::State s); 315 static void sockaddrToString(const sockaddr_storage& addr, bool addrValid, 316 char* buf, size_t bufLen); 317 static bool sockaddrMatch(const sockaddr_storage& a1, 318 const sockaddr_storage& a2, 319 bool matchAddressOnly); 320 }; 321 322 } // namespace android 323 324 #endif // ANDROID_COMMON_TIME_SERVER_H 325