• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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