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