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
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
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
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
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;
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