common_time_server_packets.h revision 9158825f9c41869689d6b1786d7c7aa8bdd524ce
14f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber/* 24f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * Copyright (C) 2012 The Android Open Source Project 34f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * 44f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 54f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * you may not use this file except in compliance with the License. 64f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * You may obtain a copy of the License at 74f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * 84f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 94f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * 104f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * Unless required by applicable law or agreed to in writing, software 114f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 124f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * See the License for the specific language governing permissions and 144f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * limitations under the License. 154f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber */ 164f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 174f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber#ifndef ANDROID_COMMON_TIME_SERVER_PACKETS_H 184f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber#define ANDROID_COMMON_TIME_SERVER_PACKETS_H 194f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 204f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber#include <stdint.h> 214f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber#include <common_time/ICommonClock.h> 224f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 234f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Hubernamespace android { 244f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 254f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber/***** time sync protocol packets *****/ 264f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 274f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huberenum TimeServicePacketType { 284f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber TIME_PACKET_WHO_IS_MASTER_REQUEST = 1, 294f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber TIME_PACKET_WHO_IS_MASTER_RESPONSE, 304f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber TIME_PACKET_SYNC_REQUEST, 314f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber TIME_PACKET_SYNC_RESPONSE, 324f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber TIME_PACKET_MASTER_ANNOUNCEMENT, 334f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber}; 344f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 354f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huberclass TimeServicePacketHeader { 364f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber public: 374f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber friend class UniversalTimeServicePacket; 384f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber // magic number identifying the protocol 394f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber uint32_t magic; 404f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 414f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber // protocol version of the packet 424f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber uint16_t version; 434f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 444f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber // type of the packet 454f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber TimeServicePacketType packetType; 464f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 474f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber // the timeline ID 484f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber uint64_t timelineID; 494f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 504f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber // synchronization group this packet belongs to (used to operate multiple 514f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber // synchronization domains which all use the same master election endpoint) 524f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber uint64_t syncGroupID; 534f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 544f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber ssize_t serializePacket(uint8_t* data, uint32_t length); 554f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 564f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber protected: 574f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber void initHeader(TimeServicePacketType type, 584f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber const uint64_t tlID, 594f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber const uint64_t groupID) { 604f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber magic = kMagic; 614f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber version = kCurVersion; 624f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber packetType = type; 634f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber timelineID = tlID; 644f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber syncGroupID = groupID; 654f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 664f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 674f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber bool checkPacket(uint64_t expectedSyncGroupID) const { 684f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber return ((magic == kMagic) && 694f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber (version == kCurVersion) && 704f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber (!expectedSyncGroupID || (syncGroupID == expectedSyncGroupID))); 714f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 724f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 734f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber ssize_t serializeHeader(uint8_t* data, uint32_t length); 744f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber ssize_t deserializeHeader(const uint8_t* data, uint32_t length); 754f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 764f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber private: 774f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber static const uint32_t kMagic; 784f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber static const uint16_t kCurVersion; 794f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber}; 804f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 814f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber// packet querying for a suitable master 824f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huberclass WhoIsMasterRequestPacket : public TimeServicePacketHeader { 834f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber public: 844f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber uint64_t senderDeviceID; 854f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber uint8_t senderDevicePriority; 864f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 874f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber void initHeader(const uint64_t groupID) { 884f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber TimeServicePacketHeader::initHeader(TIME_PACKET_WHO_IS_MASTER_REQUEST, 894f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber ICommonClock::kInvalidTimelineID, 904f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber groupID); 914f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 924f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 934f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber ssize_t serializePacket(uint8_t* data, uint32_t length); 944f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber ssize_t deserializePacket(const uint8_t* data, uint32_t length); 954f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber}; 964f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 974f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber// response to a WhoIsMaster request 984f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huberclass WhoIsMasterResponsePacket : public TimeServicePacketHeader { 994f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber public: 1004f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber uint64_t deviceID; 1014f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber uint8_t devicePriority; 1024f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 1034f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber void initHeader(const uint64_t tlID, const uint64_t groupID) { 1044f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber TimeServicePacketHeader::initHeader(TIME_PACKET_WHO_IS_MASTER_RESPONSE, 1054f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber tlID, groupID); 1064f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 1074f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 1084f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber ssize_t serializePacket(uint8_t* data, uint32_t length); 1094f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber ssize_t deserializePacket(const uint8_t* data, uint32_t length); 1104f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber}; 1114f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 1124f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber// packet sent by a client requesting correspondence between local 1134f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber// and common time 1144f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huberclass 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 129class 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 154class 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 169class 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