common_time_server.h revision 6c929510474caa14dc9d56826b2c65552861d6b3
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
34namespace android {
35
36class CommonClockService;
37class CommonTimeConfigService;
38
39/***** time service implementation *****/
40
41class CommonTimeServer : public Thread {
42  public:
43    CommonTimeServer();
44    ~CommonTimeServer();
45
46    bool startServices();
47
48    // Common Clock API methods
49    CommonClock&        getCommonClock()        { return mCommonClock; }
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:
87        PacketRTTLog() {
88            resetLog();
89        }
90
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:
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
174    inline uint8_t effectivePriority() const {
175        return (mMasterPriority & 0x7F) |
176               (mForceLowPriority ? 0x00 : 0x80);
177    }
178
179    inline bool shouldAutoDisable() const {
180        return (mAutoDisable && !mCommonClockHasClients);
181    }
182
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;
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
332