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 /*
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 <stdint.h>
27 
28 #include "common_time_server_packets.h"
29 
30 namespace android {
31 
32 const uint32_t TimeServicePacketHeader::kMagic =
33     (static_cast<uint32_t>('c') << 24) |
34     (static_cast<uint32_t>('c') << 16) |
35     (static_cast<uint32_t>('l') <<  8) |
36      static_cast<uint32_t>('k');
37 
38 const uint16_t TimeServicePacketHeader::kCurVersion = 1;
39 
40 #define SERIALIZE_FIELD(field_name, type, converter)        \
41     do {                                                    \
42         if ((offset + sizeof(field_name)) > length)         \
43             return -1;                                      \
44         *((type*)(data + offset)) = converter(field_name);  \
45         offset += sizeof(field_name);                       \
46     } while (0)
47 #define SERIALIZE_INT16(field_name) SERIALIZE_FIELD(field_name, int16_t, htons)
48 #define SERIALIZE_INT32(field_name) SERIALIZE_FIELD(field_name, int32_t, htonl)
49 #define SERIALIZE_INT64(field_name) SERIALIZE_FIELD(field_name, int64_t, htonq)
50 
51 #define DESERIALIZE_FIELD(field_name, type, converter)      \
52     do {                                                    \
53         if ((offset + sizeof(field_name)) > length)         \
54             return -1;                                      \
55         field_name = converter(*((type*)(data + offset)));  \
56         offset += sizeof(field_name);                       \
57     } while (0)
58 #define DESERIALIZE_INT16(field_name) DESERIALIZE_FIELD(field_name, int16_t, ntohs)
59 #define DESERIALIZE_INT32(field_name) DESERIALIZE_FIELD(field_name, int32_t, ntohl)
60 #define DESERIALIZE_INT64(field_name) DESERIALIZE_FIELD(field_name, int64_t, ntohq)
61 
62 #define kDevicePriorityShift 56
63 #define kDeviceIDMask ((static_cast<uint64_t>(1) << kDevicePriorityShift) - 1)
64 
packDeviceID(uint64_t devID,uint8_t prio)65 inline uint64_t packDeviceID(uint64_t devID, uint8_t prio) {
66     return (devID & kDeviceIDMask) |
67            (static_cast<uint64_t>(prio) << kDevicePriorityShift);
68 }
69 
unpackDeviceID(uint64_t packed)70 inline uint64_t unpackDeviceID(uint64_t packed) {
71     return (packed & kDeviceIDMask);
72 }
73 
unpackDevicePriority(uint64_t packed)74 inline uint8_t unpackDevicePriority(uint64_t packed) {
75     return static_cast<uint8_t>(packed >> kDevicePriorityShift);
76 }
77 
serializeHeader(uint8_t * data,uint32_t length)78 ssize_t TimeServicePacketHeader::serializeHeader(uint8_t* data,
79                                                  uint32_t length) {
80     ssize_t offset = 0;
81     int16_t pktType = static_cast<int16_t>(packetType);
82     SERIALIZE_INT32(magic);
83     SERIALIZE_INT16(version);
84     SERIALIZE_INT16(pktType);
85     SERIALIZE_INT64(timelineID);
86     SERIALIZE_INT64(syncGroupID);
87     return offset;
88 }
89 
deserializeHeader(const uint8_t * data,uint32_t length)90 ssize_t TimeServicePacketHeader::deserializeHeader(const uint8_t* data,
91                                                    uint32_t length) {
92     ssize_t offset = 0;
93     int16_t tmp;
94     DESERIALIZE_INT32(magic);
95     DESERIALIZE_INT16(version);
96     DESERIALIZE_INT16(tmp);
97     DESERIALIZE_INT64(timelineID);
98     DESERIALIZE_INT64(syncGroupID);
99     packetType = static_cast<TimeServicePacketType>(tmp);
100     return offset;
101 }
102 
serializePacket(uint8_t * data,uint32_t length)103 ssize_t TimeServicePacketHeader::serializePacket(uint8_t* data,
104                                                  uint32_t length) {
105     ssize_t ret, tmp;
106 
107     ret = serializeHeader(data, length);
108     if (ret < 0)
109         return ret;
110 
111     data += ret;
112     length -= ret;
113 
114     switch (packetType) {
115         case TIME_PACKET_WHO_IS_MASTER_REQUEST:
116             tmp =((WhoIsMasterRequestPacket*)(this))->serializePacket(data,
117                                                                       length);
118             break;
119         case TIME_PACKET_WHO_IS_MASTER_RESPONSE:
120             tmp =((WhoIsMasterResponsePacket*)(this))->serializePacket(data,
121                                                                        length);
122             break;
123         case TIME_PACKET_SYNC_REQUEST:
124             tmp =((SyncRequestPacket*)(this))->serializePacket(data, length);
125             break;
126         case TIME_PACKET_SYNC_RESPONSE:
127             tmp =((SyncResponsePacket*)(this))->serializePacket(data, length);
128             break;
129         case TIME_PACKET_MASTER_ANNOUNCEMENT:
130             tmp =((MasterAnnouncementPacket*)(this))->serializePacket(data,
131                                                                       length);
132             break;
133         default:
134             return -1;
135     }
136 
137     if (tmp < 0)
138         return tmp;
139 
140     return ret + tmp;
141 }
142 
deserializePacket(const uint8_t * data,uint32_t length,uint64_t expectedSyncGroupID)143 ssize_t UniversalTimeServicePacket::deserializePacket(
144         const uint8_t* data,
145         uint32_t length,
146         uint64_t expectedSyncGroupID) {
147     ssize_t ret;
148     TimeServicePacketHeader* header;
149     if (length < 8)
150         return -1;
151 
152     packetType = ntohs(*((uint16_t*)(data + 6)));
153     switch (packetType) {
154         case TIME_PACKET_WHO_IS_MASTER_REQUEST:
155             ret = p.who_is_master_request.deserializePacket(data, length);
156             header = &p.who_is_master_request;
157             break;
158         case TIME_PACKET_WHO_IS_MASTER_RESPONSE:
159             ret = p.who_is_master_response.deserializePacket(data, length);
160             header = &p.who_is_master_response;
161             break;
162         case TIME_PACKET_SYNC_REQUEST:
163             ret = p.sync_request.deserializePacket(data, length);
164             header = &p.sync_request;
165             break;
166         case TIME_PACKET_SYNC_RESPONSE:
167             ret = p.sync_response.deserializePacket(data, length);
168             header = &p.sync_response;
169             break;
170         case TIME_PACKET_MASTER_ANNOUNCEMENT:
171             ret = p.master_announcement.deserializePacket(data, length);
172             header = &p.master_announcement;
173             break;
174         default:
175             return -1;
176     }
177 
178     if ((ret >= 0) && !header->checkPacket(expectedSyncGroupID))
179         ret = -1;
180 
181     return ret;
182 }
183 
serializePacket(uint8_t * data,uint32_t length)184 ssize_t WhoIsMasterRequestPacket::serializePacket(uint8_t* data,
185                                                   uint32_t length) {
186     ssize_t offset = serializeHeader(data, length);
187     if (offset > 0) {
188         uint64_t packed = packDeviceID(senderDeviceID, senderDevicePriority);
189         SERIALIZE_INT64(packed);
190     }
191     return offset;
192 }
193 
deserializePacket(const uint8_t * data,uint32_t length)194 ssize_t WhoIsMasterRequestPacket::deserializePacket(const uint8_t* data,
195                                                     uint32_t length) {
196     ssize_t offset = deserializeHeader(data, length);
197     if (offset > 0) {
198         uint64_t packed;
199         DESERIALIZE_INT64(packed);
200         senderDeviceID       = unpackDeviceID(packed);
201         senderDevicePriority = unpackDevicePriority(packed);
202     }
203     return offset;
204 }
205 
serializePacket(uint8_t * data,uint32_t length)206 ssize_t WhoIsMasterResponsePacket::serializePacket(uint8_t* data,
207                                                    uint32_t length) {
208     ssize_t offset = serializeHeader(data, length);
209     if (offset > 0) {
210         uint64_t packed = packDeviceID(deviceID, devicePriority);
211         SERIALIZE_INT64(packed);
212     }
213     return offset;
214 }
215 
deserializePacket(const uint8_t * data,uint32_t length)216 ssize_t WhoIsMasterResponsePacket::deserializePacket(const uint8_t* data,
217                                                      uint32_t length) {
218     ssize_t offset = deserializeHeader(data, length);
219     if (offset > 0) {
220         uint64_t packed;
221         DESERIALIZE_INT64(packed);
222         deviceID       = unpackDeviceID(packed);
223         devicePriority = unpackDevicePriority(packed);
224     }
225     return offset;
226 }
227 
serializePacket(uint8_t * data,uint32_t length)228 ssize_t SyncRequestPacket::serializePacket(uint8_t* data,
229                                            uint32_t length) {
230     ssize_t offset = serializeHeader(data, length);
231     if (offset > 0) {
232         SERIALIZE_INT64(clientTxLocalTime);
233     }
234     return offset;
235 }
236 
deserializePacket(const uint8_t * data,uint32_t length)237 ssize_t SyncRequestPacket::deserializePacket(const uint8_t* data,
238                                              uint32_t length) {
239     ssize_t offset = deserializeHeader(data, length);
240     if (offset > 0) {
241         DESERIALIZE_INT64(clientTxLocalTime);
242     }
243     return offset;
244 }
245 
serializePacket(uint8_t * data,uint32_t length)246 ssize_t SyncResponsePacket::serializePacket(uint8_t* data,
247                                             uint32_t length) {
248     ssize_t offset = serializeHeader(data, length);
249     if (offset > 0) {
250         SERIALIZE_INT64(clientTxLocalTime);
251         SERIALIZE_INT64(masterRxCommonTime);
252         SERIALIZE_INT64(masterTxCommonTime);
253         SERIALIZE_INT32(nak);
254     }
255     return offset;
256 }
257 
deserializePacket(const uint8_t * data,uint32_t length)258 ssize_t SyncResponsePacket::deserializePacket(const uint8_t* data,
259                                               uint32_t length) {
260     ssize_t offset = deserializeHeader(data, length);
261     if (offset > 0) {
262         DESERIALIZE_INT64(clientTxLocalTime);
263         DESERIALIZE_INT64(masterRxCommonTime);
264         DESERIALIZE_INT64(masterTxCommonTime);
265         DESERIALIZE_INT32(nak);
266     }
267     return offset;
268 }
269 
serializePacket(uint8_t * data,uint32_t length)270 ssize_t MasterAnnouncementPacket::serializePacket(uint8_t* data,
271                                                   uint32_t length) {
272     ssize_t offset = serializeHeader(data, length);
273     if (offset > 0) {
274         uint64_t packed = packDeviceID(deviceID, devicePriority);
275         SERIALIZE_INT64(packed);
276     }
277     return offset;
278 }
279 
deserializePacket(const uint8_t * data,uint32_t length)280 ssize_t MasterAnnouncementPacket::deserializePacket(const uint8_t* data,
281                                                     uint32_t length) {
282     ssize_t offset = deserializeHeader(data, length);
283     if (offset > 0) {
284         uint64_t packed;
285         DESERIALIZE_INT64(packed);
286         deviceID       = unpackDeviceID(packed);
287         devicePriority = unpackDevicePriority(packed);
288     }
289     return offset;
290 }
291 
292 }  // namespace android
293 
294