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 65 inline uint64_t packDeviceID(uint64_t devID, uint8_t prio) { 66 return (devID & kDeviceIDMask) | 67 (static_cast<uint64_t>(prio) << kDevicePriorityShift); 68 } 69 70 inline uint64_t unpackDeviceID(uint64_t packed) { 71 return (packed & kDeviceIDMask); 72 } 73 74 inline uint8_t unpackDevicePriority(uint64_t packed) { 75 return static_cast<uint8_t>(packed >> kDevicePriorityShift); 76 } 77 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 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 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 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 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 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 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 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 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 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 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 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 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 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