blob: 6e18050869785f1f51d35c1d202c06289a3ad59a [file] [log] [blame]
Mike J. Chen6c929512011-08-15 11:59:47 -07001/*
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>
Elliott Hughes778c8592012-09-11 18:50:25 -070022#include <sys/socket.h>
Mike J. Chen6c929512011-08-15 11:59:47 -070023
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"
John Grossmanc7f57c62012-06-26 12:50:28 -070031#include "utils.h"
Mike J. Chen6c929512011-08-15 11:59:47 -070032
33#define RTT_LOG_SIZE 30
34
35namespace android {
36
37class CommonClockService;
38class CommonTimeConfigService;
39
40/***** time service implementation *****/
41
42class CommonTimeServer : public Thread {
43 public:
44 CommonTimeServer();
45 ~CommonTimeServer();
46
47 bool startServices();
48
49 // Common Clock API methods
50 CommonClock& getCommonClock() { return mCommonClock; }
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:
88 PacketRTTLog() {
89 resetLog();
90 }
91
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
Mike J. Chen6c929512011-08-15 11:59:47 -0700108 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
163 inline uint8_t effectivePriority() const {
164 return (mMasterPriority & 0x7F) |
165 (mForceLowPriority ? 0x00 : 0x80);
166 }
167
168 inline bool shouldAutoDisable() const {
169 return (mAutoDisable && !mCommonClockHasClients);
170 }
171
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
John Grossmanc7f57c62012-06-26 12:50:28 -0700186 Timeout mCurTimeout;
Mike J. Chen6c929512011-08-15 11:59:47 -0700187
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;
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
John Grossman79489c42012-07-20 10:17:26 -0700241 // Internal logs used for dumpsys.
242 LogRing mStateChangeLog;
243 LogRing mElectionLog;
244 LogRing mBadPktLog;
245
Mike J. Chen6c929512011-08-15 11:59:47 -0700246 // 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