blob: 57ba8a256308510c923c9a8870043e223616c72a [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#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
23namespace android {
24
25/***** time sync protocol packets *****/
26
27enum 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
35class 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
82class 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
98class 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
114class 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