16c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen/*
26c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * Copyright (C) 2012 The Android Open Source Project
36c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen *
46c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * Licensed under the Apache License, Version 2.0 (the "License");
56c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * you may not use this file except in compliance with the License.
66c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * You may obtain a copy of the License at
76c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen *
86c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen *      http://www.apache.org/licenses/LICENSE-2.0
96c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen *
106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * Unless required by applicable law or agreed to in writing, software
116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * distributed under the License is distributed on an "AS IS" BASIS,
126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * See the License for the specific language governing permissions and
146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * limitations under the License.
156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen */
166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen/*
186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * A service that exchanges time synchronization information between
196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * a master that defines a timeline and clients that follow the timeline.
206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen */
216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#define LOG_TAG "common_time"
236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <utils/Log.h>
246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <arpa/inet.h>
266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <stdint.h>
276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include "common_time_server_packets.h"
296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chennamespace android {
316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst uint32_t TimeServicePacketHeader::kMagic =
336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    (static_cast<uint32_t>('c') << 24) |
346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    (static_cast<uint32_t>('c') << 16) |
356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    (static_cast<uint32_t>('l') <<  8) |
366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen     static_cast<uint32_t>('k');
376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenconst uint16_t TimeServicePacketHeader::kCurVersion = 1;
396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#define SERIALIZE_FIELD(field_name, type, converter)        \
416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    do {                                                    \
426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if ((offset + sizeof(field_name)) > length)         \
436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return -1;                                      \
446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        *((type*)(data + offset)) = converter(field_name);  \
456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        offset += sizeof(field_name);                       \
466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } while (0)
476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#define SERIALIZE_INT16(field_name) SERIALIZE_FIELD(field_name, int16_t, htons)
486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#define SERIALIZE_INT32(field_name) SERIALIZE_FIELD(field_name, int32_t, htonl)
496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#define SERIALIZE_INT64(field_name) SERIALIZE_FIELD(field_name, int64_t, htonq)
506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#define DESERIALIZE_FIELD(field_name, type, converter)      \
526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    do {                                                    \
536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        if ((offset + sizeof(field_name)) > length)         \
546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return -1;                                      \
556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        field_name = converter(*((type*)(data + offset)));  \
566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        offset += sizeof(field_name);                       \
576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    } while (0)
586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#define DESERIALIZE_INT16(field_name) DESERIALIZE_FIELD(field_name, int16_t, ntohs)
596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#define DESERIALIZE_INT32(field_name) DESERIALIZE_FIELD(field_name, int32_t, ntohl)
606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#define DESERIALIZE_INT64(field_name) DESERIALIZE_FIELD(field_name, int64_t, ntohq)
616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#define kDevicePriorityShift 56
636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#define kDeviceIDMask ((static_cast<uint64_t>(1) << kDevicePriorityShift) - 1)
646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Cheninline uint64_t packDeviceID(uint64_t devID, uint8_t prio) {
666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return (devID & kDeviceIDMask) |
676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen           (static_cast<uint64_t>(prio) << kDevicePriorityShift);
686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Cheninline uint64_t unpackDeviceID(uint64_t packed) {
716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return (packed & kDeviceIDMask);
726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Cheninline uint8_t unpackDevicePriority(uint64_t packed) {
756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return static_cast<uint8_t>(packed >> kDevicePriorityShift);
766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenssize_t TimeServicePacketHeader::serializeHeader(uint8_t* data,
796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                                 uint32_t length) {
806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t offset = 0;
816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    int16_t pktType = static_cast<int16_t>(packetType);
826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    SERIALIZE_INT32(magic);
836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    SERIALIZE_INT16(version);
846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    SERIALIZE_INT16(pktType);
856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    SERIALIZE_INT64(timelineID);
866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    SERIALIZE_INT64(syncGroupID);
876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return offset;
886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenssize_t TimeServicePacketHeader::deserializeHeader(const uint8_t* data,
916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                                   uint32_t length) {
926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t offset = 0;
936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    int16_t tmp;
946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    DESERIALIZE_INT32(magic);
956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    DESERIALIZE_INT16(version);
966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    DESERIALIZE_INT16(tmp);
976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    DESERIALIZE_INT64(timelineID);
986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    DESERIALIZE_INT64(syncGroupID);
996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    packetType = static_cast<TimeServicePacketType>(tmp);
1006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return offset;
1016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
1026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenssize_t TimeServicePacketHeader::serializePacket(uint8_t* data,
1046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                                 uint32_t length) {
1056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t ret, tmp;
1066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ret = serializeHeader(data, length);
1086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (ret < 0)
1096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return ret;
1106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    data += ret;
1126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    length -= ret;
1136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    switch (packetType) {
1156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case TIME_PACKET_WHO_IS_MASTER_REQUEST:
1166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            tmp =((WhoIsMasterRequestPacket*)(this))->serializePacket(data,
1176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                                                      length);
1186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            break;
1196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case TIME_PACKET_WHO_IS_MASTER_RESPONSE:
1206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            tmp =((WhoIsMasterResponsePacket*)(this))->serializePacket(data,
1216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                                                       length);
1226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            break;
1236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case TIME_PACKET_SYNC_REQUEST:
1246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            tmp =((SyncRequestPacket*)(this))->serializePacket(data, length);
1256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            break;
1266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case TIME_PACKET_SYNC_RESPONSE:
1276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            tmp =((SyncResponsePacket*)(this))->serializePacket(data, length);
1286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            break;
1296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case TIME_PACKET_MASTER_ANNOUNCEMENT:
1306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            tmp =((MasterAnnouncementPacket*)(this))->serializePacket(data,
1316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                                                      length);
1326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            break;
1336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        default:
1346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return -1;
1356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
1366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (tmp < 0)
1386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return tmp;
1396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return ret + tmp;
1416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
1426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenssize_t UniversalTimeServicePacket::deserializePacket(
1446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        const uint8_t* data,
1456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        uint32_t length,
1466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        uint64_t expectedSyncGroupID) {
1476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t ret;
1486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    TimeServicePacketHeader* header;
1496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (length < 8)
1506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        return -1;
1516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    packetType = ntohs(*((uint16_t*)(data + 6)));
1536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    switch (packetType) {
1546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case TIME_PACKET_WHO_IS_MASTER_REQUEST:
1556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            ret = p.who_is_master_request.deserializePacket(data, length);
1566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            header = &p.who_is_master_request;
1576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            break;
1586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case TIME_PACKET_WHO_IS_MASTER_RESPONSE:
1596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            ret = p.who_is_master_response.deserializePacket(data, length);
1606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            header = &p.who_is_master_response;
1616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            break;
1626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case TIME_PACKET_SYNC_REQUEST:
1636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            ret = p.sync_request.deserializePacket(data, length);
1646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            header = &p.sync_request;
1656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            break;
1666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case TIME_PACKET_SYNC_RESPONSE:
1676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            ret = p.sync_response.deserializePacket(data, length);
1686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            header = &p.sync_response;
1696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            break;
1706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        case TIME_PACKET_MASTER_ANNOUNCEMENT:
1716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            ret = p.master_announcement.deserializePacket(data, length);
1726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            header = &p.master_announcement;
1736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            break;
1746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        default:
1756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen            return -1;
1766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
1776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if ((ret >= 0) && !header->checkPacket(expectedSyncGroupID))
1796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        ret = -1;
1806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return ret;
1826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
1836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenssize_t WhoIsMasterRequestPacket::serializePacket(uint8_t* data,
1856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                                  uint32_t length) {
1866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t offset = serializeHeader(data, length);
1876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (offset > 0) {
1886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        uint64_t packed = packDeviceID(senderDeviceID, senderDevicePriority);
1896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        SERIALIZE_INT64(packed);
1906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
1916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return offset;
1926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
1936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
1946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenssize_t WhoIsMasterRequestPacket::deserializePacket(const uint8_t* data,
1956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                                    uint32_t length) {
1966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t offset = deserializeHeader(data, length);
1976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (offset > 0) {
1986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        uint64_t packed;
1996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        DESERIALIZE_INT64(packed);
2006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        senderDeviceID       = unpackDeviceID(packed);
2016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        senderDevicePriority = unpackDevicePriority(packed);
2026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
2036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return offset;
2046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
2056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenssize_t WhoIsMasterResponsePacket::serializePacket(uint8_t* data,
2076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                                   uint32_t length) {
2086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t offset = serializeHeader(data, length);
2096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (offset > 0) {
2106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        uint64_t packed = packDeviceID(deviceID, devicePriority);
2116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        SERIALIZE_INT64(packed);
2126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
2136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return offset;
2146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
2156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenssize_t WhoIsMasterResponsePacket::deserializePacket(const uint8_t* data,
2176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                                     uint32_t length) {
2186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t offset = deserializeHeader(data, length);
2196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (offset > 0) {
2206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        uint64_t packed;
2216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        DESERIALIZE_INT64(packed);
2226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        deviceID       = unpackDeviceID(packed);
2236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        devicePriority = unpackDevicePriority(packed);
2246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
2256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return offset;
2266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
2276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenssize_t SyncRequestPacket::serializePacket(uint8_t* data,
2296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                           uint32_t length) {
2306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t offset = serializeHeader(data, length);
2316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (offset > 0) {
2326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        SERIALIZE_INT64(clientTxLocalTime);
2336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
2346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return offset;
2356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
2366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenssize_t SyncRequestPacket::deserializePacket(const uint8_t* data,
2386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                             uint32_t length) {
2396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t offset = deserializeHeader(data, length);
2406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (offset > 0) {
2416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        DESERIALIZE_INT64(clientTxLocalTime);
2426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
2436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return offset;
2446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
2456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenssize_t SyncResponsePacket::serializePacket(uint8_t* data,
2476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                            uint32_t length) {
2486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t offset = serializeHeader(data, length);
2496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (offset > 0) {
2506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        SERIALIZE_INT64(clientTxLocalTime);
2516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        SERIALIZE_INT64(masterRxCommonTime);
2526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        SERIALIZE_INT64(masterTxCommonTime);
2536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        SERIALIZE_INT32(nak);
2546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
2556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return offset;
2566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
2576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenssize_t SyncResponsePacket::deserializePacket(const uint8_t* data,
2596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                              uint32_t length) {
2606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t offset = deserializeHeader(data, length);
2616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (offset > 0) {
2626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        DESERIALIZE_INT64(clientTxLocalTime);
2636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        DESERIALIZE_INT64(masterRxCommonTime);
2646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        DESERIALIZE_INT64(masterTxCommonTime);
2656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        DESERIALIZE_INT32(nak);
2666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
2676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return offset;
2686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
2696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenssize_t MasterAnnouncementPacket::serializePacket(uint8_t* data,
2716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                                  uint32_t length) {
2726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t offset = serializeHeader(data, length);
2736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (offset > 0) {
2746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        uint64_t packed = packDeviceID(deviceID, devicePriority);
2756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        SERIALIZE_INT64(packed);
2766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
2776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return offset;
2786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
2796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenssize_t MasterAnnouncementPacket::deserializePacket(const uint8_t* data,
2816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen                                                    uint32_t length) {
2826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    ssize_t offset = deserializeHeader(data, length);
2836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    if (offset > 0) {
2846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        uint64_t packed;
2856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        DESERIALIZE_INT64(packed);
2866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        deviceID       = unpackDeviceID(packed);
2876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen        devicePriority = unpackDevicePriority(packed);
2886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    }
2896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen    return offset;
2906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}
2916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
2926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen}  // namespace android
2936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen
294