/services/common_time/common_time_server_packets.cpp
https://github.com/aizuzi/platform_frameworks_base · C++ · 293 lines · 237 code · 37 blank · 19 comment · 21 complexity · f3de65c0ad553c379b4148b9ff650c04 MD5 · raw file
- /*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- /*
- * A service that exchanges time synchronization information between
- * a master that defines a timeline and clients that follow the timeline.
- */
- #define LOG_TAG "common_time"
- #include <utils/Log.h>
- #include <arpa/inet.h>
- #include <stdint.h>
- #include "common_time_server_packets.h"
- namespace android {
- const uint32_t TimeServicePacketHeader::kMagic =
- (static_cast<uint32_t>('c') << 24) |
- (static_cast<uint32_t>('c') << 16) |
- (static_cast<uint32_t>('l') << 8) |
- static_cast<uint32_t>('k');
- const uint16_t TimeServicePacketHeader::kCurVersion = 1;
- #define SERIALIZE_FIELD(field_name, type, converter) \
- do { \
- if ((offset + sizeof(field_name)) > length) \
- return -1; \
- *((type*)(data + offset)) = converter(field_name); \
- offset += sizeof(field_name); \
- } while (0)
- #define SERIALIZE_INT16(field_name) SERIALIZE_FIELD(field_name, int16_t, htons)
- #define SERIALIZE_INT32(field_name) SERIALIZE_FIELD(field_name, int32_t, htonl)
- #define SERIALIZE_INT64(field_name) SERIALIZE_FIELD(field_name, int64_t, htonq)
- #define DESERIALIZE_FIELD(field_name, type, converter) \
- do { \
- if ((offset + sizeof(field_name)) > length) \
- return -1; \
- field_name = converter(*((type*)(data + offset))); \
- offset += sizeof(field_name); \
- } while (0)
- #define DESERIALIZE_INT16(field_name) DESERIALIZE_FIELD(field_name, int16_t, ntohs)
- #define DESERIALIZE_INT32(field_name) DESERIALIZE_FIELD(field_name, int32_t, ntohl)
- #define DESERIALIZE_INT64(field_name) DESERIALIZE_FIELD(field_name, int64_t, ntohq)
- #define kDevicePriorityShift 56
- #define kDeviceIDMask ((static_cast<uint64_t>(1) << kDevicePriorityShift) - 1)
- inline uint64_t packDeviceID(uint64_t devID, uint8_t prio) {
- return (devID & kDeviceIDMask) |
- (static_cast<uint64_t>(prio) << kDevicePriorityShift);
- }
- inline uint64_t unpackDeviceID(uint64_t packed) {
- return (packed & kDeviceIDMask);
- }
- inline uint8_t unpackDevicePriority(uint64_t packed) {
- return static_cast<uint8_t>(packed >> kDevicePriorityShift);
- }
- ssize_t TimeServicePacketHeader::serializeHeader(uint8_t* data,
- uint32_t length) {
- ssize_t offset = 0;
- int16_t pktType = static_cast<int16_t>(packetType);
- SERIALIZE_INT32(magic);
- SERIALIZE_INT16(version);
- SERIALIZE_INT16(pktType);
- SERIALIZE_INT64(timelineID);
- SERIALIZE_INT64(syncGroupID);
- return offset;
- }
- ssize_t TimeServicePacketHeader::deserializeHeader(const uint8_t* data,
- uint32_t length) {
- ssize_t offset = 0;
- int16_t tmp;
- DESERIALIZE_INT32(magic);
- DESERIALIZE_INT16(version);
- DESERIALIZE_INT16(tmp);
- DESERIALIZE_INT64(timelineID);
- DESERIALIZE_INT64(syncGroupID);
- packetType = static_cast<TimeServicePacketType>(tmp);
- return offset;
- }
- ssize_t TimeServicePacketHeader::serializePacket(uint8_t* data,
- uint32_t length) {
- ssize_t ret, tmp;
- ret = serializeHeader(data, length);
- if (ret < 0)
- return ret;
- data += ret;
- length -= ret;
- switch (packetType) {
- case TIME_PACKET_WHO_IS_MASTER_REQUEST:
- tmp =((WhoIsMasterRequestPacket*)(this))->serializePacket(data,
- length);
- break;
- case TIME_PACKET_WHO_IS_MASTER_RESPONSE:
- tmp =((WhoIsMasterResponsePacket*)(this))->serializePacket(data,
- length);
- break;
- case TIME_PACKET_SYNC_REQUEST:
- tmp =((SyncRequestPacket*)(this))->serializePacket(data, length);
- break;
- case TIME_PACKET_SYNC_RESPONSE:
- tmp =((SyncResponsePacket*)(this))->serializePacket(data, length);
- break;
- case TIME_PACKET_MASTER_ANNOUNCEMENT:
- tmp =((MasterAnnouncementPacket*)(this))->serializePacket(data,
- length);
- break;
- default:
- return -1;
- }
- if (tmp < 0)
- return tmp;
- return ret + tmp;
- }
- ssize_t UniversalTimeServicePacket::deserializePacket(
- const uint8_t* data,
- uint32_t length,
- uint64_t expectedSyncGroupID) {
- ssize_t ret;
- TimeServicePacketHeader* header;
- if (length < 8)
- return -1;
- packetType = ntohs(*((uint16_t*)(data + 6)));
- switch (packetType) {
- case TIME_PACKET_WHO_IS_MASTER_REQUEST:
- ret = p.who_is_master_request.deserializePacket(data, length);
- header = &p.who_is_master_request;
- break;
- case TIME_PACKET_WHO_IS_MASTER_RESPONSE:
- ret = p.who_is_master_response.deserializePacket(data, length);
- header = &p.who_is_master_response;
- break;
- case TIME_PACKET_SYNC_REQUEST:
- ret = p.sync_request.deserializePacket(data, length);
- header = &p.sync_request;
- break;
- case TIME_PACKET_SYNC_RESPONSE:
- ret = p.sync_response.deserializePacket(data, length);
- header = &p.sync_response;
- break;
- case TIME_PACKET_MASTER_ANNOUNCEMENT:
- ret = p.master_announcement.deserializePacket(data, length);
- header = &p.master_announcement;
- break;
- default:
- return -1;
- }
- if ((ret >= 0) && !header->checkPacket(expectedSyncGroupID))
- ret = -1;
- return ret;
- }
- ssize_t WhoIsMasterRequestPacket::serializePacket(uint8_t* data,
- uint32_t length) {
- ssize_t offset = serializeHeader(data, length);
- if (offset > 0) {
- uint64_t packed = packDeviceID(senderDeviceID, senderDevicePriority);
- SERIALIZE_INT64(packed);
- }
- return offset;
- }
- ssize_t WhoIsMasterRequestPacket::deserializePacket(const uint8_t* data,
- uint32_t length) {
- ssize_t offset = deserializeHeader(data, length);
- if (offset > 0) {
- uint64_t packed;
- DESERIALIZE_INT64(packed);
- senderDeviceID = unpackDeviceID(packed);
- senderDevicePriority = unpackDevicePriority(packed);
- }
- return offset;
- }
- ssize_t WhoIsMasterResponsePacket::serializePacket(uint8_t* data,
- uint32_t length) {
- ssize_t offset = serializeHeader(data, length);
- if (offset > 0) {
- uint64_t packed = packDeviceID(deviceID, devicePriority);
- SERIALIZE_INT64(packed);
- }
- return offset;
- }
- ssize_t WhoIsMasterResponsePacket::deserializePacket(const uint8_t* data,
- uint32_t length) {
- ssize_t offset = deserializeHeader(data, length);
- if (offset > 0) {
- uint64_t packed;
- DESERIALIZE_INT64(packed);
- deviceID = unpackDeviceID(packed);
- devicePriority = unpackDevicePriority(packed);
- }
- return offset;
- }
- ssize_t SyncRequestPacket::serializePacket(uint8_t* data,
- uint32_t length) {
- ssize_t offset = serializeHeader(data, length);
- if (offset > 0) {
- SERIALIZE_INT64(clientTxLocalTime);
- }
- return offset;
- }
- ssize_t SyncRequestPacket::deserializePacket(const uint8_t* data,
- uint32_t length) {
- ssize_t offset = deserializeHeader(data, length);
- if (offset > 0) {
- DESERIALIZE_INT64(clientTxLocalTime);
- }
- return offset;
- }
- ssize_t SyncResponsePacket::serializePacket(uint8_t* data,
- uint32_t length) {
- ssize_t offset = serializeHeader(data, length);
- if (offset > 0) {
- SERIALIZE_INT64(clientTxLocalTime);
- SERIALIZE_INT64(masterRxCommonTime);
- SERIALIZE_INT64(masterTxCommonTime);
- SERIALIZE_INT32(nak);
- }
- return offset;
- }
- ssize_t SyncResponsePacket::deserializePacket(const uint8_t* data,
- uint32_t length) {
- ssize_t offset = deserializeHeader(data, length);
- if (offset > 0) {
- DESERIALIZE_INT64(clientTxLocalTime);
- DESERIALIZE_INT64(masterRxCommonTime);
- DESERIALIZE_INT64(masterTxCommonTime);
- DESERIALIZE_INT32(nak);
- }
- return offset;
- }
- ssize_t MasterAnnouncementPacket::serializePacket(uint8_t* data,
- uint32_t length) {
- ssize_t offset = serializeHeader(data, length);
- if (offset > 0) {
- uint64_t packed = packDeviceID(deviceID, devicePriority);
- SERIALIZE_INT64(packed);
- }
- return offset;
- }
- ssize_t MasterAnnouncementPacket::deserializePacket(const uint8_t* data,
- uint32_t length) {
- ssize_t offset = deserializeHeader(data, length);
- if (offset > 0) {
- uint64_t packed;
- DESERIALIZE_INT64(packed);
- deviceID = unpackDeviceID(packed);
- devicePriority = unpackDevicePriority(packed);
- }
- return offset;
- }
- } // namespace android