Home | History | Annotate | Download | only in common_time
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef ANDROID_COMMON_TIME_SERVER_PACKETS_H
     18 #define ANDROID_COMMON_TIME_SERVER_PACKETS_H
     19 
     20 #include <stdint.h>
     21 #include <common_time/ICommonClock.h>
     22 
     23 namespace android {
     24 
     25 /***** time sync protocol packets *****/
     26 
     27 enum TimeServicePacketType {
     28     TIME_PACKET_WHO_IS_MASTER_REQUEST = 1,
     29     TIME_PACKET_WHO_IS_MASTER_RESPONSE,
     30     TIME_PACKET_SYNC_REQUEST,
     31     TIME_PACKET_SYNC_RESPONSE,
     32     TIME_PACKET_MASTER_ANNOUNCEMENT,
     33 };
     34 
     35 class TimeServicePacketHeader {
     36   public:
     37     friend class UniversalTimeServicePacket;
     38     // magic number identifying the protocol
     39     uint32_t magic;
     40 
     41     // protocol version of the packet
     42     uint16_t version;
     43 
     44     // type of the packet
     45     TimeServicePacketType packetType;
     46 
     47     // the timeline ID
     48     uint64_t timelineID;
     49 
     50     // synchronization group this packet belongs to (used to operate multiple
     51     // synchronization domains which all use the same master election endpoint)
     52     uint64_t syncGroupID;
     53 
     54     ssize_t serializePacket(uint8_t* data, uint32_t length);
     55 
     56   protected:
     57     void initHeader(TimeServicePacketType type,
     58                     const uint64_t tlID,
     59                     const uint64_t groupID) {
     60         magic              = kMagic;
     61         version            = kCurVersion;
     62         packetType         = type;
     63         timelineID         = tlID;
     64         syncGroupID        = groupID;
     65     }
     66 
     67     bool checkPacket(uint64_t expectedSyncGroupID) const {
     68         return ((magic       == kMagic) &&
     69                 (version     == kCurVersion) &&
     70                 (!expectedSyncGroupID || (syncGroupID == expectedSyncGroupID)));
     71     }
     72 
     73     ssize_t serializeHeader(uint8_t* data, uint32_t length);
     74     ssize_t deserializeHeader(const uint8_t* data, uint32_t length);
     75 
     76   private:
     77     static const uint32_t kMagic;
     78     static const uint16_t kCurVersion;
     79 };
     80 
     81 // packet querying for a suitable master
     82 class WhoIsMasterRequestPacket : public TimeServicePacketHeader {
     83   public:
     84     uint64_t senderDeviceID;
     85     uint8_t senderDevicePriority;
     86 
     87     void initHeader(const uint64_t groupID) {
     88         TimeServicePacketHeader::initHeader(TIME_PACKET_WHO_IS_MASTER_REQUEST,
     89                                             ICommonClock::kInvalidTimelineID,
     90                                             groupID);
     91     }
     92 
     93     ssize_t serializePacket(uint8_t* data, uint32_t length);
     94     ssize_t deserializePacket(const uint8_t* data, uint32_t length);
     95 };
     96 
     97 // response to a WhoIsMaster request
     98 class WhoIsMasterResponsePacket : public TimeServicePacketHeader {
     99   public:
    100     uint64_t deviceID;
    101     uint8_t devicePriority;
    102 
    103     void initHeader(const uint64_t tlID, const uint64_t groupID) {
    104         TimeServicePacketHeader::initHeader(TIME_PACKET_WHO_IS_MASTER_RESPONSE,
    105                                             tlID, groupID);
    106     }
    107 
    108     ssize_t serializePacket(uint8_t* data, uint32_t length);
    109     ssize_t deserializePacket(const uint8_t* data, uint32_t length);
    110 };
    111 
    112 // packet sent by a client requesting correspondence between local
    113 // and common time
    114 class SyncRequestPacket : public TimeServicePacketHeader {
    115   public:
    116     // local time when this request was transmitted
    117     int64_t clientTxLocalTime;
    118 
    119     void initHeader(const uint64_t tlID, const uint64_t groupID) {
    120         TimeServicePacketHeader::initHeader(TIME_PACKET_SYNC_REQUEST,
    121                                             tlID, groupID);
    122     }
    123 
    124     ssize_t serializePacket(uint8_t* data, uint32_t length);
    125     ssize_t deserializePacket(const uint8_t* data, uint32_t length);
    126 };
    127 
    128 // response to a sync request sent by the master
    129 class SyncResponsePacket : public TimeServicePacketHeader {
    130   public:
    131     // local time when this request was transmitted by the client
    132     int64_t clientTxLocalTime;
    133 
    134     // common time when the master received the request
    135     int64_t masterRxCommonTime;
    136 
    137     // common time when the master transmitted the response
    138     int64_t masterTxCommonTime;
    139 
    140     // flag that is set if the recipient of the sync request is not acting
    141     // as a master for the requested timeline
    142     uint32_t nak;
    143 
    144     void initHeader(const uint64_t tlID, const uint64_t groupID) {
    145         TimeServicePacketHeader::initHeader(TIME_PACKET_SYNC_RESPONSE,
    146                                             tlID, groupID);
    147     }
    148 
    149     ssize_t serializePacket(uint8_t* data, uint32_t length);
    150     ssize_t deserializePacket(const uint8_t* data, uint32_t length);
    151 };
    152 
    153 // announcement of the master's presence
    154 class MasterAnnouncementPacket : public TimeServicePacketHeader {
    155   public:
    156     // the master's device ID
    157     uint64_t deviceID;
    158     uint8_t devicePriority;
    159 
    160     void initHeader(const uint64_t tlID, const uint64_t groupID) {
    161         TimeServicePacketHeader::initHeader(TIME_PACKET_MASTER_ANNOUNCEMENT,
    162                                             tlID, groupID);
    163     }
    164 
    165     ssize_t serializePacket(uint8_t* data, uint32_t length);
    166     ssize_t deserializePacket(const uint8_t* data, uint32_t length);
    167 };
    168 
    169 class UniversalTimeServicePacket {
    170   public:
    171     uint16_t packetType;
    172     union {
    173         WhoIsMasterRequestPacket  who_is_master_request;
    174         WhoIsMasterResponsePacket who_is_master_response;
    175         SyncRequestPacket         sync_request;
    176         SyncResponsePacket        sync_response;
    177         MasterAnnouncementPacket  master_announcement;
    178     } p;
    179 
    180     ssize_t deserializePacket(const uint8_t* data,
    181                               uint32_t       length,
    182                               uint64_t       expectedSyncGroupID);
    183 };
    184 
    185 };  // namespace android
    186 
    187 #endif  // ANDROID_COMMON_TIME_SERVER_PACKETS_H
    188 
    189 
    190