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#ifndef ANDROID_COMMON_TIME_SERVER_PACKETS_H
186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#define ANDROID_COMMON_TIME_SERVER_PACKETS_H
196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <stdint.h>
216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <common_time/ICommonClock.h>
226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chennamespace android {
246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen/***** time sync protocol packets *****/
266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenenum TimeServicePacketType {
286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    TIME_PACKET_WHO_IS_MASTER_REQUEST = 1,
296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    TIME_PACKET_WHO_IS_MASTER_RESPONSE,
306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    TIME_PACKET_SYNC_REQUEST,
316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    TIME_PACKET_SYNC_RESPONSE,
326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    TIME_PACKET_MASTER_ANNOUNCEMENT,
336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen};
346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenclass TimeServicePacketHeader {
366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen  public:
376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    friend class UniversalTimeServicePacket;
386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // magic number identifying the protocol
396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint32_t magic;
406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // protocol version of the packet
426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint16_t version;
436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // type of the packet
456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    TimeServicePacketType packetType;
466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // the timeline ID
486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint64_t timelineID;
496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // synchronization group this packet belongs to (used to operate multiple
516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // synchronization domains which all use the same master election endpoint)
526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint64_t syncGroupID;
536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t serializePacket(uint8_t* data, uint32_t length);
556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen  protected:
576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    void initHeader(TimeServicePacketType type,
586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    const uint64_t tlID,
596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                    const uint64_t groupID) {
606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        magic              = kMagic;
616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        version            = kCurVersion;
626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        packetType         = type;
636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        timelineID         = tlID;
646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        syncGroupID        = groupID;
656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    bool checkPacket(uint64_t expectedSyncGroupID) const {
686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return ((magic       == kMagic) &&
696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                (version     == kCurVersion) &&
706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                (!expectedSyncGroupID || (syncGroupID == expectedSyncGroupID)));
716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t serializeHeader(uint8_t* data, uint32_t length);
746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t deserializeHeader(const uint8_t* data, uint32_t length);
756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen  private:
776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    static const uint32_t kMagic;
786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    static const uint16_t kCurVersion;
796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen};
806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// packet querying for a suitable master
826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenclass WhoIsMasterRequestPacket : public TimeServicePacketHeader {
836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen  public:
846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint64_t senderDeviceID;
856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint8_t senderDevicePriority;
866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    void initHeader(const uint64_t groupID) {
886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        TimeServicePacketHeader::initHeader(TIME_PACKET_WHO_IS_MASTER_REQUEST,
896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                            ICommonClock::kInvalidTimelineID,
906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                            groupID);
916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t serializePacket(uint8_t* data, uint32_t length);
946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t deserializePacket(const uint8_t* data, uint32_t length);
956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen};
966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// response to a WhoIsMaster request
986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenclass WhoIsMasterResponsePacket : public TimeServicePacketHeader {
996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen  public:
1006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint64_t deviceID;
1016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint8_t devicePriority;
1026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    void initHeader(const uint64_t tlID, const uint64_t groupID) {
1046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        TimeServicePacketHeader::initHeader(TIME_PACKET_WHO_IS_MASTER_RESPONSE,
1056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                            tlID, groupID);
1066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
1076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t serializePacket(uint8_t* data, uint32_t length);
1096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t deserializePacket(const uint8_t* data, uint32_t length);
1106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen};
1116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// packet sent by a client requesting correspondence between local
1136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// and common time
1146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenclass SyncRequestPacket : public TimeServicePacketHeader {
1156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen  public:
1166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // local time when this request was transmitted
1176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    int64_t clientTxLocalTime;
1186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    void initHeader(const uint64_t tlID, const uint64_t groupID) {
1206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        TimeServicePacketHeader::initHeader(TIME_PACKET_SYNC_REQUEST,
1216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                            tlID, groupID);
1226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
1236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t serializePacket(uint8_t* data, uint32_t length);
1256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t deserializePacket(const uint8_t* data, uint32_t length);
1266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen};
1276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// response to a sync request sent by the master
1296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenclass SyncResponsePacket : public TimeServicePacketHeader {
1306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen  public:
1316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // local time when this request was transmitted by the client
1326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    int64_t clientTxLocalTime;
1336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // common time when the master received the request
1356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    int64_t masterRxCommonTime;
1366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // common time when the master transmitted the response
1386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    int64_t masterTxCommonTime;
1396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // flag that is set if the recipient of the sync request is not acting
1416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // as a master for the requested timeline
1426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint32_t nak;
1436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    void initHeader(const uint64_t tlID, const uint64_t groupID) {
1456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        TimeServicePacketHeader::initHeader(TIME_PACKET_SYNC_RESPONSE,
1466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                            tlID, groupID);
1476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
1486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t serializePacket(uint8_t* data, uint32_t length);
1506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t deserializePacket(const uint8_t* data, uint32_t length);
1516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen};
1526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen// announcement of the master's presence
1546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenclass MasterAnnouncementPacket : public TimeServicePacketHeader {
1556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen  public:
1566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    // the master's device ID
1576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint64_t deviceID;
1586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint8_t devicePriority;
1596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    void initHeader(const uint64_t tlID, const uint64_t groupID) {
1616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        TimeServicePacketHeader::initHeader(TIME_PACKET_MASTER_ANNOUNCEMENT,
1626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                            tlID, groupID);
1636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
1646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t serializePacket(uint8_t* data, uint32_t length);
1666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t deserializePacket(const uint8_t* data, uint32_t length);
1676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen};
1686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenclass UniversalTimeServicePacket {
1706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen  public:
1716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    uint16_t packetType;
1726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    union {
1736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        WhoIsMasterRequestPacket  who_is_master_request;
1746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        WhoIsMasterResponsePacket who_is_master_response;
1756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        SyncRequestPacket         sync_request;
1766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        SyncResponsePacket        sync_response;
1776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        MasterAnnouncementPacket  master_announcement;
1786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } p;
1796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t deserializePacket(const uint8_t* data,
1816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                              uint32_t       length,
1826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                              uint64_t       expectedSyncGroupID);
1836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen};
1846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen};  // namespace android
1866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#endif  // ANDROID_COMMON_TIME_SERVER_PACKETS_H
1886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
190