Home | History | Annotate | Download | only in common_time
      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