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