/*
 * 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

