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