16c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen/*
26c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * Copyright (C) 2012 The Android Open Source Project
36c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen *
46c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * Licensed under the Apache License, Version 2.0 (the "License");
56c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * you may not use this file except in compliance with the License.
66c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * You may obtain a copy of the License at
76c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen *
86c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen *      http://www.apache.org/licenses/LICENSE-2.0
96c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen *
106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * Unless required by applicable law or agreed to in writing, software
116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * distributed under the License is distributed on an "AS IS" BASIS,
126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * See the License for the specific language governing permissions and
146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * limitations under the License.
156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen */
166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen/*
186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * A service that exchanges time synchronization information between
196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * a master that defines a timeline and clients that follow the timeline.
206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen */
216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#define LOG_TAG "common_time"
236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <utils/Log.h>
246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <binder/IServiceManager.h>
266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <binder/IPCThreadState.h>
276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include "common_time_server.h"
296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chennamespace android {
316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen//
336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// Clock API
346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen//
356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenuint64_t CommonTimeServer::getTimelineID() {
366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    AutoMutex _lock(&mLock);
376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return mTimelineID;
386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
406c929510474caa14dc9d56826b2c65552861d6b3Mike J. ChenICommonClock::State CommonTimeServer::getState() {
416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    AutoMutex _lock(&mLock);
426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return mState;
436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenstatus_t CommonTimeServer::getMasterAddr(struct sockaddr_storage* addr) {
466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    AutoMutex _lock(&mLock);
476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mMasterEPValid) {
486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        memcpy(addr, &mMasterEP, sizeof(*addr));
496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return OK;
506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return UNKNOWN_ERROR;
536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenint32_t CommonTimeServer::getEstimatedError() {
566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    AutoMutex _lock(&mLock);
576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (ICommonClock::STATE_MASTER == mState)
596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return 0;
606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!mClockSynced)
626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return ICommonClock::kErrorEstimateUnknown;
636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return mClockRecovery.getLastErrorEstimate();
656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenstatus_t CommonTimeServer::isCommonTimeValid(bool* valid,
686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                             uint32_t* timelineID) {
696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    AutoMutex _lock(&mLock);
706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    *valid = mCommonClock.isValid();
716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    *timelineID = mTimelineID;
726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return OK;
736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen//
766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// Config API
776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen//
786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenstatus_t CommonTimeServer::getMasterElectionPriority(uint8_t *priority) {
796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    AutoMutex _lock(&mLock);
806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    *priority = mMasterPriority;
816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return OK;
826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenstatus_t CommonTimeServer::setMasterElectionPriority(uint8_t priority) {
856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    AutoMutex _lock(&mLock);
866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (priority > 0x7F)
886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return BAD_VALUE;
896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mMasterPriority = priority;
916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return OK;
926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenstatus_t CommonTimeServer::getMasterElectionEndpoint(
956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        struct sockaddr_storage *addr) {
966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    AutoMutex _lock(&mLock);
976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    memcpy(addr, &mMasterElectionEP, sizeof(*addr));
986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return OK;
996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
1006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenstatus_t CommonTimeServer::setMasterElectionEndpoint(
1026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        const struct sockaddr_storage *addr) {
1036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    AutoMutex _lock(&mLock);
1046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!addr)
1066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return BAD_VALUE;
1076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // TODO: add proper support for IPv6
1096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (addr->ss_family != AF_INET)
1106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return BAD_VALUE;
1116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Only multicast and broadcast endpoints with explicit ports are allowed.
1136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint16_t ipv4Port = ntohs(
1146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        reinterpret_cast<const struct sockaddr_in*>(addr)->sin_port);
1156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!ipv4Port)
1166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return BAD_VALUE;
1176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint32_t ipv4Addr = ntohl(
1196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        reinterpret_cast<const struct sockaddr_in*>(addr)->sin_addr.s_addr);
1206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if ((ipv4Addr != 0xFFFFFFFF) && (0xE0000000 != (ipv4Addr & 0xF0000000)))
1216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return BAD_VALUE;
1226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    memcpy(&mMasterElectionEP, addr, sizeof(mMasterElectionEP));
1246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Force a rebind in order to change election enpoints.
1266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mBindIfaceDirty = true;
1276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    wakeupThread_l();
1286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return OK;
1296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
1306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenstatus_t CommonTimeServer::getMasterElectionGroupId(uint64_t *id) {
1326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    AutoMutex _lock(&mLock);
1336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    *id = mSyncGroupID;
1346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return OK;
1356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
1366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenstatus_t CommonTimeServer::setMasterElectionGroupId(uint64_t id) {
1386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    AutoMutex _lock(&mLock);
1396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mSyncGroupID = id;
1406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return OK;
1416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
1426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenstatus_t CommonTimeServer::getInterfaceBinding(String8& ifaceName) {
1446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    AutoMutex _lock(&mLock);
1456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!mBindIfaceValid)
1466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return INVALID_OPERATION;
1476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ifaceName = mBindIface;
1486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return OK;
1496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
1506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenstatus_t CommonTimeServer::setInterfaceBinding(const String8& ifaceName) {
1526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    AutoMutex _lock(&mLock);
1536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mBindIfaceDirty = true;
1556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (ifaceName.size()) {
1566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mBindIfaceValid = true;
1576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mBindIface = ifaceName;
1586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else {
1596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mBindIfaceValid = false;
1606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mBindIface.clear();
1616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
1626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    wakeupThread_l();
1646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return OK;
1656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
1666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenstatus_t CommonTimeServer::getMasterAnnounceInterval(int *interval) {
1686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    AutoMutex _lock(&mLock);
1696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    *interval = mMasterAnnounceIntervalMs;
1706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return OK;
1716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
1726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenstatus_t CommonTimeServer::setMasterAnnounceInterval(int interval) {
1746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    AutoMutex _lock(&mLock);
1756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (interval > (6 *3600000)) // Max interval is once every 6 hrs
1776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return BAD_VALUE;
1786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (interval < 500) // Min interval is once per 0.5 seconds
1806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return BAD_VALUE;
1816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mMasterAnnounceIntervalMs = interval;
1836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (ICommonClock::STATE_MASTER == mState) {
1846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int pendingTimeout = mCurTimeout.msecTillTimeout();
1856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if ((kInfiniteTimeout == pendingTimeout) ||
1866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            (pendingTimeout > interval)) {
1876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            mCurTimeout.setTimeout(mMasterAnnounceIntervalMs);
1886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            wakeupThread_l();
1896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
1906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
1916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return OK;
1936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
1946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenstatus_t CommonTimeServer::getClientSyncInterval(int *interval) {
1966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    AutoMutex _lock(&mLock);
1976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    *interval = mSyncRequestIntervalMs;
1986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return OK;
1996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
2006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenstatus_t CommonTimeServer::setClientSyncInterval(int interval) {
2026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    AutoMutex _lock(&mLock);
2036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (interval > (3600000)) // Max interval is once every 60 min
2056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return BAD_VALUE;
2066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (interval < 250) // Min interval is once per 0.25 seconds
2086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return BAD_VALUE;
2096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mSyncRequestIntervalMs = interval;
2116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (ICommonClock::STATE_CLIENT == mState) {
2126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int pendingTimeout = mCurTimeout.msecTillTimeout();
2136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if ((kInfiniteTimeout == pendingTimeout) ||
2146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            (pendingTimeout > interval)) {
2156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            mCurTimeout.setTimeout(mSyncRequestIntervalMs);
2166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            wakeupThread_l();
2176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
2186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
2196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return OK;
2216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
2226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenstatus_t CommonTimeServer::getPanicThreshold(int *threshold) {
2246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    AutoMutex _lock(&mLock);
2256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    *threshold = mPanicThresholdUsec;
2266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return OK;
2276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
2286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenstatus_t CommonTimeServer::setPanicThreshold(int threshold) {
2306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    AutoMutex _lock(&mLock);
2316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (threshold < 1000) // Min threshold is 1mSec
2336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return BAD_VALUE;
2346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mPanicThresholdUsec = threshold;
2366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return OK;
2376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
2386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenstatus_t CommonTimeServer::getAutoDisable(bool *autoDisable) {
2406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    AutoMutex _lock(&mLock);
2416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    *autoDisable = mAutoDisable;
2426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return OK;
2436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
2446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenstatus_t CommonTimeServer::setAutoDisable(bool autoDisable) {
2466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    AutoMutex _lock(&mLock);
2476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mAutoDisable = autoDisable;
2486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    wakeupThread_l();
2496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return OK;
2506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
2516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenstatus_t CommonTimeServer::forceNetworklessMasterMode() {
2536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    AutoMutex _lock(&mLock);
2546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // Can't force networkless master mode if we are currently bound to a
2566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // network.
2576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (mSocket >= 0)
2586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return INVALID_OPERATION;
2596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    becomeMaster("force networkless");
2616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return OK;
2636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
2646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid CommonTimeServer::reevaluateAutoDisableState(bool commonClockHasClients) {
2666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    AutoMutex _lock(&mLock);
2676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    bool needWakeup = (mAutoDisable && mMasterEPValid &&
2686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                      (commonClockHasClients != mCommonClockHasClients));
2696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    mCommonClockHasClients = commonClockHasClients;
2716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (needWakeup) {
2736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ALOGI("Waking up service, auto-disable is engaged and service now has%s"
2746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen             " clients", mCommonClockHasClients ? "" : " no");
2756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        wakeupThread_l();
2766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
2776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
2786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#define dump_printf(a, b...) do {                 \
2806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    int res;                                      \
2816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    res = snprintf(buffer, sizeof(buffer), a, b); \
2826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    buffer[sizeof(buffer) - 1] = 0;               \
2836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (res > 0)                                  \
2846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        write(fd, buffer, res);                   \
2856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen} while (0)
2866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#define checked_percentage(a, b) ((0 == b) ? 0.0f : ((100.0f * a) / b))
2876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenstatus_t CommonTimeServer::dumpClockInterface(int fd,
2896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                              const Vector<String16>& args,
2906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                              size_t activeClients) {
2916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    AutoMutex _lock(&mLock);
2926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    const size_t SIZE = 256;
2936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    char buffer[SIZE];
2946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
2966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        snprintf(buffer, SIZE, "Permission Denial: "
2976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                 "can't dump CommonClockService from pid=%d, uid=%d\n",
2986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                 IPCThreadState::self()->getCallingPid(),
2996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                 IPCThreadState::self()->getCallingUid());
3006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        write(fd, buffer, strlen(buffer));
3016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else {
3026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int64_t commonTime;
3036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        int64_t localTime;
3046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        bool    synced;
3056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        char maStr[64];
3066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        localTime  = mLocalClock.getLocalTime();
3086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        synced     = (OK == mCommonClock.localToCommon(localTime, &commonTime));
3096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        sockaddrToString(mMasterEP, mMasterEPValid, maStr, sizeof(maStr));
3106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        dump_printf("Common Clock Service Status\nLocal time     : %lld\n",
3126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    localTime);
3136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (synced)
3156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            dump_printf("Common time    : %lld\n", commonTime);
3166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        else
3176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            dump_printf("Common time    : %s\n", "not synced");
3186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        dump_printf("Timeline ID    : %016llx\n", mTimelineID);
3206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        dump_printf("State          : %s\n", stateToString(mState));
3216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        dump_printf("Master Addr    : %s\n", maStr);
3226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (synced) {
3256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            int32_t est = (ICommonClock::STATE_MASTER != mState)
3266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        ? mClockRecovery.getLastErrorEstimate()
3276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        : 0;
3286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            dump_printf("Error Est.     : %.3f msec\n",
3296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        static_cast<float>(est) / 1000.0);
3306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        } else {
3316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            dump_printf("Error Est.     : %s\n", "unknown");
3326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
3336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        dump_printf("Syncs TXes     : %u\n", mClient_SyncsSentToCurMaster);
3356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        dump_printf("Syncs RXes     : %u (%.2f%%)\n",
3366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    mClient_SyncRespsRXedFromCurMaster,
3376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    checked_percentage(
3386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        mClient_SyncRespsRXedFromCurMaster,
3396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        mClient_SyncsSentToCurMaster));
3406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        dump_printf("RXs Expired    : %u (%.2f%%)\n",
3416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    mClient_ExpiredSyncRespsRXedFromCurMaster,
3426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    checked_percentage(
3436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        mClient_ExpiredSyncRespsRXedFromCurMaster,
3446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        mClient_SyncsSentToCurMaster));
3456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (!mClient_LastGoodSyncRX) {
3476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            dump_printf("Last Good RX   : %s\n", "unknown");
3486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        } else {
3496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            int64_t localDelta, usecDelta;
3506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            localDelta = localTime - mClient_LastGoodSyncRX;
3516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            usecDelta  = mCommonClock.localDurationToCommonDuration(localDelta);
3526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            dump_printf("Last Good RX   : %lld uSec ago\n", usecDelta);
3536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
3546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        dump_printf("Active Clients : %u\n", activeClients);
3566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        mClient_PacketRTTLog.dumpLog(fd, mCommonClock);
35779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        mStateChangeLog.dumpLog(fd);
35879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        mElectionLog.dumpLog(fd);
35979489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman        mBadPktLog.dumpLog(fd);
3606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
3616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return NO_ERROR;
3636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
3646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenstatus_t CommonTimeServer::dumpConfigInterface(int fd,
3666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                               const Vector<String16>& args) {
3676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    AutoMutex _lock(&mLock);
3686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    const size_t SIZE = 256;
3696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    char buffer[SIZE];
3706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
3726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        snprintf(buffer, SIZE, "Permission Denial: "
3736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                 "can't dump CommonTimeConfigService from pid=%d, uid=%d\n",
3746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                 IPCThreadState::self()->getCallingPid(),
3756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                 IPCThreadState::self()->getCallingUid());
3766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        write(fd, buffer, strlen(buffer));
3776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } else {
3786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        char meStr[64];
3796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        sockaddrToString(mMasterElectionEP, true, meStr, sizeof(meStr));
3816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
3826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        dump_printf("Common Time Config Service Status\n"
3836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    "Bound Interface           : %s\n",
3846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    mBindIfaceValid ? mBindIface.string() : "<unbound>");
3856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        dump_printf("Master Election Endpoint  : %s\n", meStr);
3866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        dump_printf("Master Election Group ID  : %016llx\n", mSyncGroupID);
3876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        dump_printf("Master Announce Interval  : %d mSec\n",
3886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    mMasterAnnounceIntervalMs);
3896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        dump_printf("Client Sync Interval      : %d mSec\n",
3906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    mSyncRequestIntervalMs);
3916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        dump_printf("Panic Threshold           : %d uSec\n",
3926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    mPanicThresholdUsec);
3936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        dump_printf("Base ME Prio              : 0x%02x\n",
3946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    static_cast<uint32_t>(mMasterPriority));
3956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        dump_printf("Effective ME Prio         : 0x%02x\n",
3966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    static_cast<uint32_t>(effectivePriority()));
3976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        dump_printf("Auto Disable Allowed      : %s\n",
3986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    mAutoDisable ? "yes" : "no");
3996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        dump_printf("Auto Disable Engaged      : %s\n",
4006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    shouldAutoDisable() ? "yes" : "no");
4016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
4026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return NO_ERROR;
4046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
4056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid CommonTimeServer::PacketRTTLog::dumpLog(int fd, const CommonClock& cclk) {
4076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    const size_t SIZE = 256;
4086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    char buffer[SIZE];
4096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint32_t avail = !logFull ? wrPtr : RTT_LOG_SIZE;
4106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (!avail)
4126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return;
4136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    dump_printf("\nPacket Log (%d entries)\n", avail);
4156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint32_t ndx = 0;
4176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint32_t i = logFull ? wrPtr : 0;
4186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    do {
4196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if (rxTimes[i]) {
4206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            int64_t delta = rxTimes[i] - txTimes[i];
4216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            int64_t deltaUsec = cclk.localDurationToCommonDuration(delta);
4226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            dump_printf("pkt[%2d] : localTX %12lld localRX %12lld "
4236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        "(%.3f msec RTT)\n",
4246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        ndx, txTimes[i], rxTimes[i],
4256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        static_cast<float>(deltaUsec) / 1000.0);
4266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        } else {
4276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            dump_printf("pkt[%2d] : localTX %12lld localRX never\n",
4286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                        ndx, txTimes[i]);
4296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        }
4306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        i = (i + 1) % RTT_LOG_SIZE;
4316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ndx++;
4326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } while (i != wrPtr);
4336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
4346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#undef dump_printf
4366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#undef checked_percentage
4376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
4386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}  // namespace android
439