Home | History | Annotate | Download | only in common_time
      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
     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