blob: 0125709b5556875c81fae57571fbe16fed63b79f [file] [log] [blame]
Mike J. Chen6c929512011-08-15 11:59:47 -07001/*
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/*
18 * A service that exchanges time synchronization information between
19 * a master that defines a timeline and clients that follow the timeline.
20 */
21
22#define LOG_TAG "common_time"
23#include <utils/Log.h>
24
25#include <arpa/inet.h>
26#include <assert.h>
27#include <fcntl.h>
Mike J. Chen6c929512011-08-15 11:59:47 -070028#include <linux/if_ether.h>
29#include <net/if.h>
30#include <net/if_arp.h>
31#include <netinet/ip.h>
32#include <poll.h>
33#include <stdio.h>
34#include <sys/eventfd.h>
35#include <sys/ioctl.h>
36#include <sys/stat.h>
37#include <sys/types.h>
38#include <sys/socket.h>
39
40#include <common_time/local_clock.h>
41#include <binder/IPCThreadState.h>
42#include <binder/ProcessState.h>
43#include <utils/Timers.h>
44
45#include "common_clock_service.h"
46#include "common_time_config_service.h"
47#include "common_time_server.h"
48#include "common_time_server_packets.h"
49#include "clock_recovery.h"
50#include "common_clock.h"
51
John Grossmanb8525e92012-02-16 14:53:24 -080052#define MAX_INT ((int)0x7FFFFFFF)
Mike J. Chen6c929512011-08-15 11:59:47 -070053
54namespace android {
55
56const char* CommonTimeServer::kDefaultMasterElectionAddr = "239.195.128.88";
57const uint16_t CommonTimeServer::kDefaultMasterElectionPort = 8887;
58const uint64_t CommonTimeServer::kDefaultSyncGroupID = 0;
59const uint8_t CommonTimeServer::kDefaultMasterPriority = 1;
60const uint32_t CommonTimeServer::kDefaultMasterAnnounceIntervalMs = 10000;
61const uint32_t CommonTimeServer::kDefaultSyncRequestIntervalMs = 1000;
62const uint32_t CommonTimeServer::kDefaultPanicThresholdUsec = 50000;
63const bool CommonTimeServer::kDefaultAutoDisable = true;
64const int CommonTimeServer::kSetupRetryTimeoutMs = 30000;
65const int64_t CommonTimeServer::kNoGoodDataPanicThresholdUsec = 600000000ll;
66const uint32_t CommonTimeServer::kRTTDiscardPanicThreshMultiplier = 5;
67
68// timeout value representing an infinite timeout
69const int CommonTimeServer::kInfiniteTimeout = -1;
70
71/*** Initial state constants ***/
72
73// number of WhoIsMaster attempts sent before giving up
74const int CommonTimeServer::kInitial_NumWhoIsMasterRetries = 6;
75
76// timeout used when waiting for a response to a WhoIsMaster request
77const int CommonTimeServer::kInitial_WhoIsMasterTimeoutMs = 500;
78
79/*** Client state constants ***/
80
81// number of sync requests that can fail before a client assumes its master
82// is dead
John Grossmane1d6c082012-04-09 11:26:16 -070083const int CommonTimeServer::kClient_NumSyncRequestRetries = 10;
Mike J. Chen6c929512011-08-15 11:59:47 -070084
85/*** Master state constants ***/
86
87/*** Ronin state constants ***/
88
89// number of WhoIsMaster attempts sent before declaring ourselves master
John Grossmane1d6c082012-04-09 11:26:16 -070090const int CommonTimeServer::kRonin_NumWhoIsMasterRetries = 20;
Mike J. Chen6c929512011-08-15 11:59:47 -070091
92// timeout used when waiting for a response to a WhoIsMaster request
93const int CommonTimeServer::kRonin_WhoIsMasterTimeoutMs = 500;
94
95/*** WaitForElection state constants ***/
96
97// how long do we wait for an announcement from a master before
98// trying another election?
John Grossmane1d6c082012-04-09 11:26:16 -070099const int CommonTimeServer::kWaitForElection_TimeoutMs = 12500;
Mike J. Chen6c929512011-08-15 11:59:47 -0700100
101CommonTimeServer::CommonTimeServer()
102 : Thread(false)
103 , mState(ICommonClock::STATE_INITIAL)
104 , mClockRecovery(&mLocalClock, &mCommonClock)
105 , mSocket(-1)
106 , mLastPacketRxLocalTime(0)
107 , mTimelineID(ICommonClock::kInvalidTimelineID)
108 , mClockSynced(false)
109 , mCommonClockHasClients(false)
110 , mInitial_WhoIsMasterRequestTimeouts(0)
111 , mClient_MasterDeviceID(0)
112 , mClient_MasterDevicePriority(0)
113 , mRonin_WhoIsMasterRequestTimeouts(0) {
114 // zero out sync stats
115 resetSyncStats();
116
117 // Setup the master election endpoint to use the default.
118 struct sockaddr_in* meep =
119 reinterpret_cast<struct sockaddr_in*>(&mMasterElectionEP);
120 memset(&mMasterElectionEP, 0, sizeof(mMasterElectionEP));
121 inet_aton(kDefaultMasterElectionAddr, &meep->sin_addr);
122 meep->sin_family = AF_INET;
123 meep->sin_port = htons(kDefaultMasterElectionPort);
124
125 // Zero out the master endpoint.
126 memset(&mMasterEP, 0, sizeof(mMasterEP));
127 mMasterEPValid = false;
128 mBindIfaceValid = false;
129 setForceLowPriority(false);
130
131 // Set all remaining configuration parameters to their defaults.
132 mDeviceID = 0;
133 mSyncGroupID = kDefaultSyncGroupID;
134 mMasterPriority = kDefaultMasterPriority;
135 mMasterAnnounceIntervalMs = kDefaultMasterAnnounceIntervalMs;
136 mSyncRequestIntervalMs = kDefaultSyncRequestIntervalMs;
137 mPanicThresholdUsec = kDefaultPanicThresholdUsec;
138 mAutoDisable = kDefaultAutoDisable;
139
140 // Create the eventfd we will use to signal our thread to wake up when
141 // needed.
142 mWakeupThreadFD = eventfd(0, EFD_NONBLOCK);
143
144 // seed the random number generator (used to generated timeline IDs)
145 srand48(static_cast<unsigned int>(systemTime()));
146}
147
148CommonTimeServer::~CommonTimeServer() {
149 shutdownThread();
150
151 // No need to grab the lock here. We are in the destructor; if the the user
152 // has a thread in any of the APIs while the destructor is being called,
153 // there is a threading problem a the application level we cannot reasonably
154 // do anything about.
155 cleanupSocket_l();
156
157 if (mWakeupThreadFD >= 0) {
158 close(mWakeupThreadFD);
159 mWakeupThreadFD = -1;
160 }
161}
162
163bool CommonTimeServer::startServices() {
164 // start the ICommonClock service
165 mICommonClock = CommonClockService::instantiate(*this);
166 if (mICommonClock == NULL)
167 return false;
168
169 // start the ICommonTimeConfig service
170 mICommonTimeConfig = CommonTimeConfigService::instantiate(*this);
171 if (mICommonTimeConfig == NULL)
172 return false;
173
174 return true;
175}
176
177bool CommonTimeServer::threadLoop() {
178 // Register our service interfaces.
179 if (!startServices())
180 return false;
181
182 // Hold the lock while we are in the main thread loop. It will release the
183 // lock when it blocks, and hold the lock at all other times.
184 mLock.lock();
185 runStateMachine_l();
186 mLock.unlock();
187
188 IPCThreadState::self()->stopProcess();
189 return false;
190}
191
192bool CommonTimeServer::runStateMachine_l() {
193 if (!mLocalClock.initCheck())
194 return false;
195
196 if (!mCommonClock.init(mLocalClock.getLocalFreq()))
197 return false;
198
199 // Enter the initial state.
200 becomeInitial("startup");
201
202 // run the state machine
203 while (!exitPending()) {
204 struct pollfd pfds[2];
John Grossmanc7f57c62012-06-26 12:50:28 -0700205 int rc, timeout;
Mike J. Chen6c929512011-08-15 11:59:47 -0700206 int eventCnt = 0;
207 int64_t wakeupTime;
John Grossmanc7f57c62012-06-26 12:50:28 -0700208 uint32_t t1, t2;
209 bool needHandleTimeout = false;
Mike J. Chen6c929512011-08-15 11:59:47 -0700210
211 // We are always interested in our wakeup FD.
212 pfds[eventCnt].fd = mWakeupThreadFD;
213 pfds[eventCnt].events = POLLIN;
214 pfds[eventCnt].revents = 0;
215 eventCnt++;
216
217 // If we have a valid socket, then we are interested in what it has to
218 // say as well.
219 if (mSocket >= 0) {
220 pfds[eventCnt].fd = mSocket;
221 pfds[eventCnt].events = POLLIN;
222 pfds[eventCnt].revents = 0;
223 eventCnt++;
224 }
225
John Grossmanc7f57c62012-06-26 12:50:28 -0700226 t1 = static_cast<uint32_t>(mCurTimeout.msecTillTimeout());
227 t2 = static_cast<uint32_t>(mClockRecovery.applyRateLimitedSlew());
228 timeout = static_cast<int>(t1 < t2 ? t1 : t2);
229
Mike J. Chen6c929512011-08-15 11:59:47 -0700230 // Note, we were holding mLock when this function was called. We
231 // release it only while we are blocking and hold it at all other times.
232 mLock.unlock();
John Grossmanc7f57c62012-06-26 12:50:28 -0700233 rc = poll(pfds, eventCnt, timeout);
Mike J. Chen6c929512011-08-15 11:59:47 -0700234 wakeupTime = mLocalClock.getLocalTime();
235 mLock.lock();
236
237 // Is it time to shutdown? If so, don't hesitate... just do it.
238 if (exitPending())
239 break;
240
241 // Did the poll fail? This should never happen and is fatal if it does.
242 if (rc < 0) {
243 ALOGE("%s:%d poll failed", __PRETTY_FUNCTION__, __LINE__);
244 return false;
245 }
246
John Grossmanc7f57c62012-06-26 12:50:28 -0700247 if (rc == 0) {
248 needHandleTimeout = !mCurTimeout.msecTillTimeout();
249 if (needHandleTimeout)
250 mCurTimeout.setTimeout(kInfiniteTimeout);
251 }
Mike J. Chen6c929512011-08-15 11:59:47 -0700252
253 // Were we woken up on purpose? If so, clear the eventfd with a read.
254 if (pfds[0].revents)
255 clearPendingWakeupEvents_l();
256
257 // Is out bind address dirty? If so, clean up our socket (if any).
258 // Alternatively, do we have an active socket but should be auto
259 // disabled? If so, release the socket and enter the proper sync state.
260 bool droppedSocket = false;
261 if (mBindIfaceDirty || ((mSocket >= 0) && shouldAutoDisable())) {
262 cleanupSocket_l();
263 mBindIfaceDirty = false;
264 droppedSocket = true;
265 }
266
267 // Do we not have a socket but should have one? If so, try to set one
268 // up.
269 if ((mSocket < 0) && mBindIfaceValid && !shouldAutoDisable()) {
270 if (setupSocket_l()) {
271 // Success! We are now joining a new network (either coming
272 // from no network, or coming from a potentially different
273 // network). Force our priority to be lower so that we defer to
274 // any other masters which may already be on the network we are
275 // joining. Later, when we enter either the client or the
276 // master state, we will clear this flag and go back to our
277 // normal election priority.
278 setForceLowPriority(true);
279 switch (mState) {
280 // If we were in initial (whether we had a immediately
281 // before this network or not) we want to simply reset the
282 // system and start again. Forcing a transition from
283 // INITIAL to INITIAL should do the job.
284 case CommonClockService::STATE_INITIAL:
285 becomeInitial("bound interface");
286 break;
287
288 // If we were in the master state, then either we were the
289 // master in a no-network situation, or we were the master
290 // of a different network and have moved to a new interface.
John Grossmane1d6c082012-04-09 11:26:16 -0700291 // In either case, immediately transition to Ronin at low
292 // priority. If there is no one in the network we just
293 // joined, we will become master soon enough. If there is,
294 // we want to be certain to defer master status to the
295 // existing timeline currently running on the network.
296 //
Mike J. Chen6c929512011-08-15 11:59:47 -0700297 case CommonClockService::STATE_MASTER:
John Grossmane1d6c082012-04-09 11:26:16 -0700298 becomeRonin("leaving networkless mode");
Mike J. Chen6c929512011-08-15 11:59:47 -0700299 break;
300
301 // If we were in any other state (CLIENT, RONIN, or
302 // WAIT_FOR_ELECTION) then we must be moving from one
303 // network to another. We have lost our old master;
304 // transition to RONIN in an attempt to find a new master.
305 // If there are none out there, we will just assume
306 // responsibility for the timeline we used to be a client
307 // of.
308 default:
309 becomeRonin("bound interface");
310 break;
311 }
312 } else {
313 // That's odd... we failed to set up our socket. This could be
314 // due to some transient network change which will work itself
315 // out shortly; schedule a retry attempt in the near future.
316 mCurTimeout.setTimeout(kSetupRetryTimeoutMs);
317 }
318
319 // One way or the other, we don't have any data to process at this
320 // point (since we just tried to bulid a new socket). Loop back
321 // around and wait for the next thing to do.
322 continue;
323 } else if (droppedSocket) {
324 // We just lost our socket, and for whatever reason (either no
325 // config, or auto disable engaged) we are not supposed to rebuild
326 // one at this time. We are not going to rebuild our socket until
327 // something about our config/auto-disabled status changes, so we
328 // are basically in network-less mode. If we are already in either
329 // INITIAL or MASTER, just stay there until something changes. If
330 // we are in any other state (CLIENT, RONIN or WAIT_FOR_ELECTION),
331 // then transition to either INITIAL or MASTER depending on whether
332 // or not our timeline is valid.
333 ALOGI("Entering networkless mode interface is %s, "
334 "shouldAutoDisable = %s",
335 mBindIfaceValid ? "valid" : "invalid",
336 shouldAutoDisable() ? "true" : "false");
337 if ((mState != ICommonClock::STATE_INITIAL) &&
338 (mState != ICommonClock::STATE_MASTER)) {
339 if (mTimelineID == ICommonClock::kInvalidTimelineID)
340 becomeInitial("network-less mode");
341 else
342 becomeMaster("network-less mode");
343 }
344
345 continue;
346 }
347
John Grossmanc7f57c62012-06-26 12:50:28 -0700348 // Time to handle the timeouts?
349 if (needHandleTimeout) {
Mike J. Chen6c929512011-08-15 11:59:47 -0700350 if (!handleTimeout())
351 ALOGE("handleTimeout failed");
352 continue;
353 }
354
355 // Does our socket have data for us (assuming we still have one, we
356 // may have RXed a packet at the same time as a config change telling us
357 // to shut our socket down)? If so, process its data.
358 if ((mSocket >= 0) && (eventCnt > 1) && (pfds[1].revents)) {
359 mLastPacketRxLocalTime = wakeupTime;
360 if (!handlePacket())
361 ALOGE("handlePacket failed");
362 }
363 }
364
365 cleanupSocket_l();
366 return true;
367}
368
369void CommonTimeServer::clearPendingWakeupEvents_l() {
370 int64_t tmp;
371 read(mWakeupThreadFD, &tmp, sizeof(tmp));
372}
373
374void CommonTimeServer::wakeupThread_l() {
375 int64_t tmp = 1;
376 write(mWakeupThreadFD, &tmp, sizeof(tmp));
377}
378
379void CommonTimeServer::cleanupSocket_l() {
380 if (mSocket >= 0) {
381 close(mSocket);
382 mSocket = -1;
383 }
384}
385
386void CommonTimeServer::shutdownThread() {
387 // Flag the work thread for shutdown.
388 this->requestExit();
389
390 // Signal the thread in case its sleeping.
391 mLock.lock();
392 wakeupThread_l();
393 mLock.unlock();
394
395 // Wait for the thread to exit.
396 this->join();
397}
398
399bool CommonTimeServer::setupSocket_l() {
400 int rc;
401 bool ret_val = false;
402 struct sockaddr_in* ipv4_addr = NULL;
403 char masterElectionEPStr[64];
404 const int one = 1;
405
406 // This should never be needed, but if we happened to have an old socket
407 // lying around, be sure to not leak it before proceeding.
408 cleanupSocket_l();
409
410 // If we don't have a valid endpoint to bind to, then how did we get here in
411 // the first place? Regardless, we know that we are going to fail to bind,
412 // so don't even try.
413 if (!mBindIfaceValid)
414 return false;
415
416 sockaddrToString(mMasterElectionEP, true, masterElectionEPStr,
417 sizeof(masterElectionEPStr));
418 ALOGI("Building socket :: bind = %s master election = %s",
419 mBindIface.string(), masterElectionEPStr);
420
421 // TODO: add proper support for IPv6. Right now, we block IPv6 addresses at
422 // the configuration interface level.
423 if (AF_INET != mMasterElectionEP.ss_family) {
424 ALOGW("TODO: add proper IPv6 support");
425 goto bailout;
426 }
427
428 // open a UDP socket for the timeline serivce
429 mSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
430 if (mSocket < 0) {
431 ALOGE("Failed to create socket (errno = %d)", errno);
432 goto bailout;
433 }
434
435 // Bind to the selected interface using Linux's spiffy SO_BINDTODEVICE.
436 struct ifreq ifr;
437 memset(&ifr, 0, sizeof(ifr));
438 snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", mBindIface.string());
439 ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = 0;
440 rc = setsockopt(mSocket, SOL_SOCKET, SO_BINDTODEVICE,
441 (void *)&ifr, sizeof(ifr));
442 if (rc) {
443 ALOGE("Failed to bind socket at to interface %s (errno = %d)",
444 ifr.ifr_name, errno);
445 goto bailout;
446 }
447
448 // Bind our socket to INADDR_ANY and the master election port. The
449 // interface binding we made using SO_BINDTODEVICE should limit us to
450 // traffic only on the interface we are interested in. We need to bind to
451 // INADDR_ANY and the specific master election port in order to be able to
452 // receive both unicast traffic and master election multicast traffic with
453 // just a single socket.
454 struct sockaddr_in bindAddr;
455 ipv4_addr = reinterpret_cast<struct sockaddr_in*>(&mMasterElectionEP);
456 memcpy(&bindAddr, ipv4_addr, sizeof(bindAddr));
457 bindAddr.sin_addr.s_addr = INADDR_ANY;
458 rc = bind(mSocket,
459 reinterpret_cast<const sockaddr *>(&bindAddr),
460 sizeof(bindAddr));
461 if (rc) {
462 ALOGE("Failed to bind socket to port %hu (errno = %d)",
463 ntohs(bindAddr.sin_port), errno);
464 goto bailout;
465 }
466
467 if (0xE0000000 == (ntohl(ipv4_addr->sin_addr.s_addr) & 0xF0000000)) {
468 // If our master election endpoint is a multicast address, be sure to join
469 // the multicast group.
470 struct ip_mreq mreq;
471 mreq.imr_multiaddr = ipv4_addr->sin_addr;
472 mreq.imr_interface.s_addr = htonl(INADDR_ANY);
473 rc = setsockopt(mSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP,
474 &mreq, sizeof(mreq));
475 if (rc == -1) {
476 ALOGE("Failed to join multicast group at %s. (errno = %d)",
477 masterElectionEPStr, errno);
478 goto bailout;
479 }
480
481 // disable loopback of multicast packets
482 const int zero = 0;
483 rc = setsockopt(mSocket, IPPROTO_IP, IP_MULTICAST_LOOP,
484 &zero, sizeof(zero));
485 if (rc == -1) {
486 ALOGE("Failed to disable multicast loopback (errno = %d)", errno);
487 goto bailout;
488 }
489 } else
Jason Simmonsdb632602012-07-17 15:48:53 -0700490 if (ntohl(ipv4_addr->sin_addr.s_addr) == 0xFFFFFFFF) {
491 // If the master election address is the broadcast address, then enable
492 // the broadcast socket option
493 const int one = 1;
494 rc = setsockopt(mSocket, SOL_SOCKET, SO_BROADCAST, &one, sizeof(one));
495 if (rc == -1) {
496 ALOGE("Failed to enable broadcast (errno = %d)", errno);
497 goto bailout;
498 }
499 } else {
Mike J. Chen6c929512011-08-15 11:59:47 -0700500 // If the master election address is neither broadcast, nor multicast,
501 // then we are misconfigured. The config API layer should prevent this
502 // from ever happening.
503 goto bailout;
504 }
505
506 // Set the TTL of sent packets to 1. (Time protocol sync should never leave
507 // the local subnet)
508 rc = setsockopt(mSocket, IPPROTO_IP, IP_TTL, &one, sizeof(one));
509 if (rc == -1) {
510 ALOGE("Failed to set TTL to %d (errno = %d)", one, errno);
511 goto bailout;
512 }
513
514 // get the device's unique ID
515 if (!assignDeviceID())
516 goto bailout;
517
518 ret_val = true;
519
520bailout:
521 if (!ret_val)
522 cleanupSocket_l();
523 return ret_val;
524}
525
526// generate a unique device ID that can be used for arbitration
527bool CommonTimeServer::assignDeviceID() {
528 if (!mBindIfaceValid)
529 return false;
530
531 struct ifreq ifr;
532 memset(&ifr, 0, sizeof(ifr));
533 ifr.ifr_addr.sa_family = AF_INET;
534 strlcpy(ifr.ifr_name, mBindIface.string(), IFNAMSIZ);
535
536 int rc = ioctl(mSocket, SIOCGIFHWADDR, &ifr);
537 if (rc) {
538 ALOGE("%s:%d ioctl failed", __PRETTY_FUNCTION__, __LINE__);
539 return false;
540 }
541
542 if (ifr.ifr_addr.sa_family != ARPHRD_ETHER) {
543 ALOGE("%s:%d got non-Ethernet address", __PRETTY_FUNCTION__, __LINE__);
544 return false;
545 }
546
547 mDeviceID = 0;
548 for (int i = 0; i < ETH_ALEN; i++) {
549 mDeviceID = (mDeviceID << 8) | ifr.ifr_hwaddr.sa_data[i];
550 }
551
552 return true;
553}
554
555// generate a new timeline ID
556void CommonTimeServer::assignTimelineID() {
557 do {
558 mTimelineID = (static_cast<uint64_t>(lrand48()) << 32)
559 | static_cast<uint64_t>(lrand48());
560 } while (mTimelineID == ICommonClock::kInvalidTimelineID);
561}
562
563// Select a preference between the device IDs of two potential masters.
564// Returns true if the first ID wins, or false if the second ID wins.
565bool CommonTimeServer::arbitrateMaster(
566 uint64_t deviceID1, uint8_t devicePrio1,
567 uint64_t deviceID2, uint8_t devicePrio2) {
568 return ((devicePrio1 > devicePrio2) ||
569 ((devicePrio1 == devicePrio2) && (deviceID1 > deviceID2)));
570}
571
572bool CommonTimeServer::handlePacket() {
573 uint8_t buf[256];
574 struct sockaddr_storage srcAddr;
575 socklen_t srcAddrLen = sizeof(srcAddr);
576
577 ssize_t recvBytes = recvfrom(
578 mSocket, buf, sizeof(buf), 0,
579 reinterpret_cast<const sockaddr *>(&srcAddr), &srcAddrLen);
580
581 if (recvBytes < 0) {
582 ALOGE("%s:%d recvfrom failed", __PRETTY_FUNCTION__, __LINE__);
583 return false;
584 }
585
586 UniversalTimeServicePacket pkt;
587 recvBytes = pkt.deserializePacket(buf, recvBytes, mSyncGroupID);
588 if (recvBytes < 0)
589 return false;
590
591 bool result;
592 switch (pkt.packetType) {
593 case TIME_PACKET_WHO_IS_MASTER_REQUEST:
594 result = handleWhoIsMasterRequest(&pkt.p.who_is_master_request,
595 srcAddr);
596 break;
597
598 case TIME_PACKET_WHO_IS_MASTER_RESPONSE:
599 result = handleWhoIsMasterResponse(&pkt.p.who_is_master_response,
600 srcAddr);
601 break;
602
603 case TIME_PACKET_SYNC_REQUEST:
604 result = handleSyncRequest(&pkt.p.sync_request, srcAddr);
605 break;
606
607 case TIME_PACKET_SYNC_RESPONSE:
608 result = handleSyncResponse(&pkt.p.sync_response, srcAddr);
609 break;
610
611 case TIME_PACKET_MASTER_ANNOUNCEMENT:
612 result = handleMasterAnnouncement(&pkt.p.master_announcement,
613 srcAddr);
614 break;
615
616 default: {
617 ALOGD("%s:%d unknown packet type(%d)",
618 __PRETTY_FUNCTION__, __LINE__, pkt.packetType);
619 result = false;
620 } break;
621 }
622
623 return result;
624}
625
626bool CommonTimeServer::handleTimeout() {
627 // If we have no socket, then this must be a timeout to retry socket setup.
628 if (mSocket < 0)
629 return true;
630
631 switch (mState) {
632 case ICommonClock::STATE_INITIAL:
633 return handleTimeoutInitial();
634 case ICommonClock::STATE_CLIENT:
635 return handleTimeoutClient();
636 case ICommonClock::STATE_MASTER:
637 return handleTimeoutMaster();
638 case ICommonClock::STATE_RONIN:
639 return handleTimeoutRonin();
640 case ICommonClock::STATE_WAIT_FOR_ELECTION:
641 return handleTimeoutWaitForElection();
642 }
643
644 return false;
645}
646
647bool CommonTimeServer::handleTimeoutInitial() {
648 if (++mInitial_WhoIsMasterRequestTimeouts ==
649 kInitial_NumWhoIsMasterRetries) {
650 // none of our attempts to discover a master succeeded, so make
651 // this device the master
652 return becomeMaster("initial timeout");
653 } else {
654 // retry the WhoIsMaster request
655 return sendWhoIsMasterRequest();
656 }
657}
658
659bool CommonTimeServer::handleTimeoutClient() {
660 if (shouldPanicNotGettingGoodData())
661 return becomeInitial("timeout panic, no good data");
662
663 if (mClient_SyncRequestPending) {
664 mClient_SyncRequestPending = false;
665
666 if (++mClient_SyncRequestTimeouts < kClient_NumSyncRequestRetries) {
667 // a sync request has timed out, so retry
668 return sendSyncRequest();
669 } else {
670 // The master has failed to respond to a sync request for too many
671 // times in a row. Assume the master is dead and start electing
672 // a new master.
673 return becomeRonin("master not responding");
674 }
675 } else {
676 // initiate the next sync request
677 return sendSyncRequest();
678 }
679}
680
681bool CommonTimeServer::handleTimeoutMaster() {
682 // send another announcement from the master
683 return sendMasterAnnouncement();
684}
685
686bool CommonTimeServer::handleTimeoutRonin() {
687 if (++mRonin_WhoIsMasterRequestTimeouts == kRonin_NumWhoIsMasterRetries) {
688 // no other master is out there, so we won the election
689 return becomeMaster("no better masters detected");
690 } else {
691 return sendWhoIsMasterRequest();
692 }
693}
694
695bool CommonTimeServer::handleTimeoutWaitForElection() {
696 return becomeRonin("timeout waiting for election conclusion");
697}
698
699bool CommonTimeServer::handleWhoIsMasterRequest(
700 const WhoIsMasterRequestPacket* request,
701 const sockaddr_storage& srcAddr) {
702 if (mState == ICommonClock::STATE_MASTER) {
703 // is this request related to this master's timeline?
704 if (request->timelineID != ICommonClock::kInvalidTimelineID &&
705 request->timelineID != mTimelineID)
706 return true;
707
708 WhoIsMasterResponsePacket pkt;
709 pkt.initHeader(mTimelineID, mSyncGroupID);
710 pkt.deviceID = mDeviceID;
711 pkt.devicePriority = effectivePriority();
712
713 uint8_t buf[256];
714 ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
715 if (bufSz < 0)
716 return false;
717
718 ssize_t sendBytes = sendto(
719 mSocket, buf, bufSz, 0,
720 reinterpret_cast<const sockaddr *>(&srcAddr),
721 sizeof(srcAddr));
722 if (sendBytes == -1) {
723 ALOGE("%s:%d sendto failed", __PRETTY_FUNCTION__, __LINE__);
724 return false;
725 }
726 } else if (mState == ICommonClock::STATE_RONIN) {
727 // if we hear a WhoIsMaster request from another device following
728 // the same timeline and that device wins arbitration, then we will stop
729 // trying to elect ourselves master and will instead wait for an
730 // announcement from the election winner
731 if (request->timelineID != mTimelineID)
732 return true;
733
734 if (arbitrateMaster(request->senderDeviceID,
735 request->senderDevicePriority,
736 mDeviceID,
737 effectivePriority()))
738 return becomeWaitForElection("would lose election");
739
740 return true;
741 } else if (mState == ICommonClock::STATE_INITIAL) {
742 // If a group of devices booted simultaneously (e.g. after a power
743 // outage) and all of them are in the initial state and there is no
744 // master, then each device may time out and declare itself master at
745 // the same time. To avoid this, listen for
746 // WhoIsMaster(InvalidTimeline) requests from peers. If we would lose
747 // arbitration against that peer, reset our timeout count so that the
748 // peer has a chance to become master before we time out.
749 if (request->timelineID == ICommonClock::kInvalidTimelineID &&
750 arbitrateMaster(request->senderDeviceID,
751 request->senderDevicePriority,
752 mDeviceID,
753 effectivePriority())) {
754 mInitial_WhoIsMasterRequestTimeouts = 0;
755 }
756 }
757
758 return true;
759}
760
761bool CommonTimeServer::handleWhoIsMasterResponse(
762 const WhoIsMasterResponsePacket* response,
763 const sockaddr_storage& srcAddr) {
764 if (mState == ICommonClock::STATE_INITIAL || mState == ICommonClock::STATE_RONIN) {
765 return becomeClient(srcAddr,
766 response->deviceID,
767 response->devicePriority,
768 response->timelineID,
769 "heard whois response");
770 } else if (mState == ICommonClock::STATE_CLIENT) {
771 // if we get multiple responses because there are multiple devices
772 // who believe that they are master, then follow the master that
773 // wins arbitration
774 if (arbitrateMaster(response->deviceID,
775 response->devicePriority,
776 mClient_MasterDeviceID,
777 mClient_MasterDevicePriority)) {
778 return becomeClient(srcAddr,
779 response->deviceID,
780 response->devicePriority,
781 response->timelineID,
782 "heard whois response");
783 }
784 }
785
786 return true;
787}
788
789bool CommonTimeServer::handleSyncRequest(const SyncRequestPacket* request,
790 const sockaddr_storage& srcAddr) {
791 SyncResponsePacket pkt;
792 pkt.initHeader(mTimelineID, mSyncGroupID);
793
794 if ((mState == ICommonClock::STATE_MASTER) &&
795 (mTimelineID == request->timelineID)) {
796 int64_t rxLocalTime = mLastPacketRxLocalTime;
797 int64_t rxCommonTime;
798
799 // If we are master on an actual network and have actual clients, then
800 // we are no longer low priority.
801 setForceLowPriority(false);
802
803 if (OK != mCommonClock.localToCommon(rxLocalTime, &rxCommonTime)) {
804 return false;
805 }
806
807 int64_t txLocalTime = mLocalClock.getLocalTime();;
808 int64_t txCommonTime;
809 if (OK != mCommonClock.localToCommon(txLocalTime, &txCommonTime)) {
810 return false;
811 }
812
813 pkt.nak = 0;
814 pkt.clientTxLocalTime = request->clientTxLocalTime;
815 pkt.masterRxCommonTime = rxCommonTime;
816 pkt.masterTxCommonTime = txCommonTime;
817 } else {
818 pkt.nak = 1;
819 pkt.clientTxLocalTime = 0;
820 pkt.masterRxCommonTime = 0;
821 pkt.masterTxCommonTime = 0;
822 }
823
824 uint8_t buf[256];
825 ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
826 if (bufSz < 0)
827 return false;
828
829 ssize_t sendBytes = sendto(
830 mSocket, &buf, bufSz, 0,
831 reinterpret_cast<const sockaddr *>(&srcAddr),
832 sizeof(srcAddr));
833 if (sendBytes == -1) {
834 ALOGE("%s:%d sendto failed", __PRETTY_FUNCTION__, __LINE__);
835 return false;
836 }
837
838 return true;
839}
840
841bool CommonTimeServer::handleSyncResponse(
842 const SyncResponsePacket* response,
843 const sockaddr_storage& srcAddr) {
844 if (mState != ICommonClock::STATE_CLIENT)
845 return true;
846
847 assert(mMasterEPValid);
848 if (!sockaddrMatch(srcAddr, mMasterEP, true)) {
849 char srcEP[64], expectedEP[64];
850 sockaddrToString(srcAddr, true, srcEP, sizeof(srcEP));
851 sockaddrToString(mMasterEP, true, expectedEP, sizeof(expectedEP));
852 ALOGI("Dropping sync response from unexpected address."
853 " Expected %s Got %s", expectedEP, srcEP);
854 return true;
855 }
856
857 if (response->nak) {
858 // if our master is no longer accepting requests, then we need to find
859 // a new master
860 return becomeRonin("master NAK'ed");
861 }
862
863 mClient_SyncRequestPending = 0;
864 mClient_SyncRequestTimeouts = 0;
865 mClient_PacketRTTLog.logRX(response->clientTxLocalTime,
866 mLastPacketRxLocalTime);
867
868 bool result;
869 if (!(mClient_SyncRespsRXedFromCurMaster++)) {
870 // the first request/response exchange between a client and a master
871 // may take unusually long due to ARP, so discard it.
872 result = true;
873 } else {
874 int64_t clientTxLocalTime = response->clientTxLocalTime;
875 int64_t clientRxLocalTime = mLastPacketRxLocalTime;
876 int64_t masterTxCommonTime = response->masterTxCommonTime;
877 int64_t masterRxCommonTime = response->masterRxCommonTime;
878
879 int64_t rtt = (clientRxLocalTime - clientTxLocalTime);
880 int64_t avgLocal = (clientTxLocalTime + clientRxLocalTime) >> 1;
881 int64_t avgCommon = (masterTxCommonTime + masterRxCommonTime) >> 1;
882
883 // if the RTT of the packet is significantly larger than the panic
884 // threshold, we should simply discard it. Its better to do nothing
885 // than to take cues from a packet like that.
886 int rttCommon = mCommonClock.localDurationToCommonDuration(rtt);
887 if (rttCommon > (static_cast<int64_t>(mPanicThresholdUsec) *
888 kRTTDiscardPanicThreshMultiplier)) {
889 ALOGV("Dropping sync response with RTT of %lld uSec", rttCommon);
890 mClient_ExpiredSyncRespsRXedFromCurMaster++;
891 if (shouldPanicNotGettingGoodData())
892 return becomeInitial("RX panic, no good data");
893 } else {
Kent Ryhorchuk11bc45f2012-02-13 16:24:29 -0800894 result = mClockRecovery.pushDisciplineEvent(avgLocal, avgCommon, rttCommon);
Mike J. Chen6c929512011-08-15 11:59:47 -0700895 mClient_LastGoodSyncRX = clientRxLocalTime;
896
897 if (result) {
898 // indicate to listeners that we've synced to the common timeline
899 notifyClockSync();
900 } else {
901 ALOGE("Panic! Observed clock sync error is too high to tolerate,"
902 " resetting state machine and starting over.");
903 notifyClockSyncLoss();
904 return becomeInitial("panic");
905 }
906 }
907 }
908
909 mCurTimeout.setTimeout(mSyncRequestIntervalMs);
910 return result;
911}
912
913bool CommonTimeServer::handleMasterAnnouncement(
914 const MasterAnnouncementPacket* packet,
915 const sockaddr_storage& srcAddr) {
916 uint64_t newDeviceID = packet->deviceID;
917 uint8_t newDevicePrio = packet->devicePriority;
918 uint64_t newTimelineID = packet->timelineID;
919
920 if (mState == ICommonClock::STATE_INITIAL ||
921 mState == ICommonClock::STATE_RONIN ||
922 mState == ICommonClock::STATE_WAIT_FOR_ELECTION) {
923 // if we aren't currently following a master, then start following
924 // this new master
925 return becomeClient(srcAddr,
926 newDeviceID,
927 newDevicePrio,
928 newTimelineID,
929 "heard master announcement");
930 } else if (mState == ICommonClock::STATE_CLIENT) {
931 // if the new master wins arbitration against our current master,
932 // then become a client of the new master
933 if (arbitrateMaster(newDeviceID,
934 newDevicePrio,
935 mClient_MasterDeviceID,
936 mClient_MasterDevicePriority))
937 return becomeClient(srcAddr,
938 newDeviceID,
939 newDevicePrio,
940 newTimelineID,
941 "heard master announcement");
942 } else if (mState == ICommonClock::STATE_MASTER) {
943 // two masters are competing - if the new one wins arbitration, then
944 // cease acting as master
945 if (arbitrateMaster(newDeviceID, newDevicePrio,
946 mDeviceID, effectivePriority()))
947 return becomeClient(srcAddr, newDeviceID,
948 newDevicePrio, newTimelineID,
949 "heard master announcement");
950 }
951
952 return true;
953}
954
955bool CommonTimeServer::sendWhoIsMasterRequest() {
956 assert(mState == ICommonClock::STATE_INITIAL || mState == ICommonClock::STATE_RONIN);
957
958 // If we have no socket, then we must be in the unconfigured initial state.
959 // Don't report any errors, just don't try to send the initial who-is-master
960 // query. Eventually, our network will either become configured, or we will
961 // be forced into network-less master mode by higher level code.
962 if (mSocket < 0) {
963 assert(mState == ICommonClock::STATE_INITIAL);
964 return true;
965 }
966
967 bool ret = false;
968 WhoIsMasterRequestPacket pkt;
969 pkt.initHeader(mSyncGroupID);
970 pkt.senderDeviceID = mDeviceID;
971 pkt.senderDevicePriority = effectivePriority();
972
973 uint8_t buf[256];
974 ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
975 if (bufSz >= 0) {
976 ssize_t sendBytes = sendto(
977 mSocket, buf, bufSz, 0,
978 reinterpret_cast<const sockaddr *>(&mMasterElectionEP),
979 sizeof(mMasterElectionEP));
980 if (sendBytes < 0)
981 ALOGE("WhoIsMaster sendto failed (errno %d)", errno);
982 ret = true;
983 }
984
985 if (mState == ICommonClock::STATE_INITIAL) {
986 mCurTimeout.setTimeout(kInitial_WhoIsMasterTimeoutMs);
987 } else {
988 mCurTimeout.setTimeout(kRonin_WhoIsMasterTimeoutMs);
989 }
990
991 return ret;
992}
993
994bool CommonTimeServer::sendSyncRequest() {
995 // If we are sending sync requests, then we must be in the client state and
996 // we must have a socket (when we have no network, we are only supposed to
997 // be in INITIAL or MASTER)
998 assert(mState == ICommonClock::STATE_CLIENT);
999 assert(mSocket >= 0);
1000
1001 bool ret = false;
1002 SyncRequestPacket pkt;
1003 pkt.initHeader(mTimelineID, mSyncGroupID);
1004 pkt.clientTxLocalTime = mLocalClock.getLocalTime();
1005
1006 if (!mClient_FirstSyncTX)
1007 mClient_FirstSyncTX = pkt.clientTxLocalTime;
1008
1009 mClient_PacketRTTLog.logTX(pkt.clientTxLocalTime);
1010
1011 uint8_t buf[256];
1012 ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
1013 if (bufSz >= 0) {
1014 ssize_t sendBytes = sendto(
1015 mSocket, buf, bufSz, 0,
1016 reinterpret_cast<const sockaddr *>(&mMasterEP),
1017 sizeof(mMasterEP));
1018 if (sendBytes < 0)
1019 ALOGE("SyncRequest sendto failed (errno %d)", errno);
1020 ret = true;
1021 }
1022
1023 mClient_SyncsSentToCurMaster++;
1024 mCurTimeout.setTimeout(mSyncRequestIntervalMs);
1025 mClient_SyncRequestPending = true;
1026
1027 return ret;
1028}
1029
1030bool CommonTimeServer::sendMasterAnnouncement() {
1031 bool ret = false;
1032 assert(mState == ICommonClock::STATE_MASTER);
1033
1034 // If we are being asked to send a master announcement, but we have no
1035 // socket, we must be in network-less master mode. Don't bother to send the
1036 // announcement, and don't bother to schedule a timeout. When the network
1037 // comes up, the work thread will get poked and start the process of
1038 // figuring out who the current master should be.
1039 if (mSocket < 0) {
1040 mCurTimeout.setTimeout(kInfiniteTimeout);
1041 return true;
1042 }
1043
1044 MasterAnnouncementPacket pkt;
1045 pkt.initHeader(mTimelineID, mSyncGroupID);
1046 pkt.deviceID = mDeviceID;
1047 pkt.devicePriority = effectivePriority();
1048
1049 uint8_t buf[256];
1050 ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
1051 if (bufSz >= 0) {
1052 ssize_t sendBytes = sendto(
1053 mSocket, buf, bufSz, 0,
1054 reinterpret_cast<const sockaddr *>(&mMasterElectionEP),
1055 sizeof(mMasterElectionEP));
1056 if (sendBytes < 0)
1057 ALOGE("MasterAnnouncement sendto failed (errno %d)", errno);
1058 ret = true;
1059 }
1060
1061 mCurTimeout.setTimeout(mMasterAnnounceIntervalMs);
1062 return ret;
1063}
1064
1065bool CommonTimeServer::becomeClient(const sockaddr_storage& masterEP,
1066 uint64_t masterDeviceID,
1067 uint8_t masterDevicePriority,
1068 uint64_t timelineID,
1069 const char* cause) {
1070 char newEPStr[64], oldEPStr[64];
1071 sockaddrToString(masterEP, true, newEPStr, sizeof(newEPStr));
1072 sockaddrToString(mMasterEP, mMasterEPValid, oldEPStr, sizeof(oldEPStr));
1073
1074 ALOGI("%s --> CLIENT (%s) :%s"
1075 " OldMaster: %02x-%014llx::%016llx::%s"
1076 " NewMaster: %02x-%014llx::%016llx::%s",
1077 stateToString(mState), cause,
1078 (mTimelineID != timelineID) ? " (new timeline)" : "",
1079 mClient_MasterDevicePriority, mClient_MasterDeviceID,
1080 mTimelineID, oldEPStr,
1081 masterDevicePriority, masterDeviceID,
1082 timelineID, newEPStr);
1083
1084 if (mTimelineID != timelineID) {
1085 // start following a new timeline
1086 mTimelineID = timelineID;
1087 mClockRecovery.reset(true, true);
1088 notifyClockSyncLoss();
1089 } else {
1090 // start following a new master on the existing timeline
1091 mClockRecovery.reset(false, true);
1092 }
1093
1094 mMasterEP = masterEP;
1095 mMasterEPValid = true;
John Grossmane1d6c082012-04-09 11:26:16 -07001096
1097 // If we are on a real network as a client of a real master, then we should
1098 // no longer force low priority. If our master disappears, we should have
1099 // the high priority bit set during the election to replace the master
1100 // because this group was a real group and not a singleton created in
1101 // networkless mode.
Mike J. Chen6c929512011-08-15 11:59:47 -07001102 setForceLowPriority(false);
1103
1104 mClient_MasterDeviceID = masterDeviceID;
1105 mClient_MasterDevicePriority = masterDevicePriority;
1106 resetSyncStats();
1107
1108 setState(ICommonClock::STATE_CLIENT);
1109
1110 // add some jitter to when the various clients send their requests
1111 // in order to reduce the likelihood that a group of clients overload
1112 // the master after receiving a master announcement
1113 usleep((lrand48() % 100) * 1000);
1114
1115 return sendSyncRequest();
1116}
1117
1118bool CommonTimeServer::becomeMaster(const char* cause) {
1119 uint64_t oldTimelineID = mTimelineID;
1120 if (mTimelineID == ICommonClock::kInvalidTimelineID) {
1121 // this device has not been following any existing timeline,
1122 // so it will create a new timeline and declare itself master
1123 assert(!mCommonClock.isValid());
1124
1125 // set the common time basis
1126 mCommonClock.setBasis(mLocalClock.getLocalTime(), 0);
1127
1128 // assign an arbitrary timeline iD
1129 assignTimelineID();
1130
1131 // notify listeners that we've created a common timeline
1132 notifyClockSync();
1133 }
1134
1135 ALOGI("%s --> MASTER (%s) : %s timeline %016llx",
1136 stateToString(mState), cause,
1137 (oldTimelineID == mTimelineID) ? "taking ownership of"
1138 : "creating new",
1139 mTimelineID);
1140
1141 memset(&mMasterEP, 0, sizeof(mMasterEP));
1142 mMasterEPValid = false;
Mike J. Chen6c929512011-08-15 11:59:47 -07001143 mClient_MasterDevicePriority = effectivePriority();
1144 mClient_MasterDeviceID = mDeviceID;
1145 mClockRecovery.reset(false, true);
1146 resetSyncStats();
1147
1148 setState(ICommonClock::STATE_MASTER);
1149 return sendMasterAnnouncement();
1150}
1151
1152bool CommonTimeServer::becomeRonin(const char* cause) {
1153 // If we were the client of a given timeline, but had never received even a
1154 // single time sync packet, then we transition back to Initial instead of
1155 // Ronin. If we transition to Ronin and end up becoming the new Master, we
1156 // will be unable to service requests for other clients because we never
1157 // actually knew what time it was. By going to initial, we ensure that
1158 // other clients who know what time it is, but would lose master arbitration
1159 // in the Ronin case, will step up and become the proper new master of the
1160 // old timeline.
1161
1162 char oldEPStr[64];
1163 sockaddrToString(mMasterEP, mMasterEPValid, oldEPStr, sizeof(oldEPStr));
1164 memset(&mMasterEP, 0, sizeof(mMasterEP));
1165 mMasterEPValid = false;
1166
1167 if (mCommonClock.isValid()) {
1168 ALOGI("%s --> RONIN (%s) : lost track of previously valid timeline "
1169 "%02x-%014llx::%016llx::%s (%d TXed %d RXed %d RXExpired)",
1170 stateToString(mState), cause,
1171 mClient_MasterDevicePriority, mClient_MasterDeviceID,
1172 mTimelineID, oldEPStr,
1173 mClient_SyncsSentToCurMaster,
1174 mClient_SyncRespsRXedFromCurMaster,
1175 mClient_ExpiredSyncRespsRXedFromCurMaster);
1176
1177 mRonin_WhoIsMasterRequestTimeouts = 0;
1178 setState(ICommonClock::STATE_RONIN);
1179 return sendWhoIsMasterRequest();
1180 } else {
1181 ALOGI("%s --> INITIAL (%s) : never synced timeline "
1182 "%02x-%014llx::%016llx::%s (%d TXed %d RXed %d RXExpired)",
1183 stateToString(mState), cause,
1184 mClient_MasterDevicePriority, mClient_MasterDeviceID,
1185 mTimelineID, oldEPStr,
1186 mClient_SyncsSentToCurMaster,
1187 mClient_SyncRespsRXedFromCurMaster,
1188 mClient_ExpiredSyncRespsRXedFromCurMaster);
1189
1190 return becomeInitial("ronin, no timeline");
1191 }
1192}
1193
1194bool CommonTimeServer::becomeWaitForElection(const char* cause) {
1195 ALOGI("%s --> WAIT_FOR_ELECTION (%s) : dropping out of election,"
1196 " waiting %d mSec for completion.",
1197 stateToString(mState), cause, kWaitForElection_TimeoutMs);
1198
1199 setState(ICommonClock::STATE_WAIT_FOR_ELECTION);
1200 mCurTimeout.setTimeout(kWaitForElection_TimeoutMs);
1201 return true;
1202}
1203
1204bool CommonTimeServer::becomeInitial(const char* cause) {
1205 ALOGI("Entering INITIAL (%s), total reset.", cause);
1206
1207 setState(ICommonClock::STATE_INITIAL);
1208
1209 // reset clock recovery
1210 mClockRecovery.reset(true, true);
1211
1212 // reset internal state bookkeeping.
1213 mCurTimeout.setTimeout(kInfiniteTimeout);
1214 memset(&mMasterEP, 0, sizeof(mMasterEP));
1215 mMasterEPValid = false;
1216 mLastPacketRxLocalTime = 0;
1217 mTimelineID = ICommonClock::kInvalidTimelineID;
1218 mClockSynced = false;
1219 mInitial_WhoIsMasterRequestTimeouts = 0;
1220 mClient_MasterDeviceID = 0;
1221 mClient_MasterDevicePriority = 0;
1222 mRonin_WhoIsMasterRequestTimeouts = 0;
1223 resetSyncStats();
1224
1225 // send the first request to discover the master
1226 return sendWhoIsMasterRequest();
1227}
1228
1229void CommonTimeServer::notifyClockSync() {
1230 if (!mClockSynced) {
1231 mClockSynced = true;
1232 mICommonClock->notifyOnTimelineChanged(mTimelineID);
1233 }
1234}
1235
1236void CommonTimeServer::notifyClockSyncLoss() {
1237 if (mClockSynced) {
1238 mClockSynced = false;
1239 mICommonClock->notifyOnTimelineChanged(
1240 ICommonClock::kInvalidTimelineID);
1241 }
1242}
1243
1244void CommonTimeServer::setState(ICommonClock::State s) {
1245 mState = s;
1246}
1247
1248const char* CommonTimeServer::stateToString(ICommonClock::State s) {
1249 switch(s) {
1250 case ICommonClock::STATE_INITIAL:
1251 return "INITIAL";
1252 case ICommonClock::STATE_CLIENT:
1253 return "CLIENT";
1254 case ICommonClock::STATE_MASTER:
1255 return "MASTER";
1256 case ICommonClock::STATE_RONIN:
1257 return "RONIN";
1258 case ICommonClock::STATE_WAIT_FOR_ELECTION:
1259 return "WAIT_FOR_ELECTION";
1260 default:
1261 return "unknown";
1262 }
1263}
1264
1265void CommonTimeServer::sockaddrToString(const sockaddr_storage& addr,
1266 bool addrValid,
1267 char* buf, size_t bufLen) {
1268 if (!bufLen || !buf)
1269 return;
1270
1271 if (addrValid) {
1272 switch (addr.ss_family) {
1273 case AF_INET: {
1274 const struct sockaddr_in* sa =
1275 reinterpret_cast<const struct sockaddr_in*>(&addr);
1276 unsigned long a = ntohl(sa->sin_addr.s_addr);
1277 uint16_t p = ntohs(sa->sin_port);
1278 snprintf(buf, bufLen, "%lu.%lu.%lu.%lu:%hu",
1279 ((a >> 24) & 0xFF), ((a >> 16) & 0xFF),
1280 ((a >> 8) & 0xFF), (a & 0xFF), p);
1281 } break;
1282
1283 case AF_INET6: {
1284 const struct sockaddr_in6* sa =
1285 reinterpret_cast<const struct sockaddr_in6*>(&addr);
1286 const uint8_t* a = sa->sin6_addr.s6_addr;
1287 uint16_t p = ntohs(sa->sin6_port);
1288 snprintf(buf, bufLen,
1289 "%02X%02X:%02X%02X:%02X%02X:%02X%02X:"
1290 "%02X%02X:%02X%02X:%02X%02X:%02X%02X port %hd",
1291 a[0], a[1], a[ 2], a[ 3], a[ 4], a[ 5], a[ 6], a[ 7],
1292 a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15],
1293 p);
1294 } break;
1295
1296 default:
1297 snprintf(buf, bufLen,
1298 "<unknown sockaddr family %d>", addr.ss_family);
1299 break;
1300 }
1301 } else {
1302 snprintf(buf, bufLen, "<none>");
1303 }
1304
1305 buf[bufLen - 1] = 0;
1306}
1307
1308bool CommonTimeServer::sockaddrMatch(const sockaddr_storage& a1,
1309 const sockaddr_storage& a2,
1310 bool matchAddressOnly) {
1311 if (a1.ss_family != a2.ss_family)
1312 return false;
1313
1314 switch (a1.ss_family) {
1315 case AF_INET: {
1316 const struct sockaddr_in* sa1 =
1317 reinterpret_cast<const struct sockaddr_in*>(&a1);
1318 const struct sockaddr_in* sa2 =
1319 reinterpret_cast<const struct sockaddr_in*>(&a2);
1320
1321 if (sa1->sin_addr.s_addr != sa2->sin_addr.s_addr)
1322 return false;
1323
1324 return (matchAddressOnly || (sa1->sin_port == sa2->sin_port));
1325 } break;
1326
1327 case AF_INET6: {
1328 const struct sockaddr_in6* sa1 =
1329 reinterpret_cast<const struct sockaddr_in6*>(&a1);
1330 const struct sockaddr_in6* sa2 =
1331 reinterpret_cast<const struct sockaddr_in6*>(&a2);
1332
1333 if (memcmp(&sa1->sin6_addr, &sa2->sin6_addr, sizeof(sa2->sin6_addr)))
1334 return false;
1335
1336 return (matchAddressOnly || (sa1->sin6_port == sa2->sin6_port));
1337 } break;
1338
1339 // Huh? We don't deal in non-IPv[46] addresses. Not sure how we got
1340 // here, but we don't know how to comapre these addresses and simply
1341 // default to a no-match decision.
1342 default: return false;
1343 }
1344}
1345
Mike J. Chen6c929512011-08-15 11:59:47 -07001346bool CommonTimeServer::shouldPanicNotGettingGoodData() {
1347 if (mClient_FirstSyncTX) {
1348 int64_t now = mLocalClock.getLocalTime();
1349 int64_t delta = now - (mClient_LastGoodSyncRX
1350 ? mClient_LastGoodSyncRX
1351 : mClient_FirstSyncTX);
1352 int64_t deltaUsec = mCommonClock.localDurationToCommonDuration(delta);
1353
1354 if (deltaUsec >= kNoGoodDataPanicThresholdUsec)
1355 return true;
1356 }
1357
1358 return false;
1359}
1360
1361void CommonTimeServer::PacketRTTLog::logTX(int64_t txTime) {
1362 txTimes[wrPtr] = txTime;
1363 rxTimes[wrPtr] = 0;
1364 wrPtr = (wrPtr + 1) % RTT_LOG_SIZE;
1365 if (!wrPtr)
1366 logFull = true;
1367}
1368
1369void CommonTimeServer::PacketRTTLog::logRX(int64_t txTime, int64_t rxTime) {
1370 if (!logFull && !wrPtr)
1371 return;
1372
1373 uint32_t i = logFull ? wrPtr : 0;
1374 do {
1375 if (txTimes[i] == txTime) {
1376 rxTimes[i] = rxTime;
1377 break;
1378 }
1379 i = (i + 1) % RTT_LOG_SIZE;
1380 } while (i != wrPtr);
1381}
1382
1383} // namespace android