PageRenderTime 36ms CodeModel.GetById 15ms app.highlight 17ms RepoModel.GetById 1ms app.codeStats 0ms

/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
  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
 30namespace android {
 31
 32const 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
 38const 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
 65inline uint64_t packDeviceID(uint64_t devID, uint8_t prio) {
 66    return (devID & kDeviceIDMask) |
 67           (static_cast<uint64_t>(prio) << kDevicePriorityShift);
 68}
 69
 70inline uint64_t unpackDeviceID(uint64_t packed) {
 71    return (packed & kDeviceIDMask);
 72}
 73
 74inline uint8_t unpackDevicePriority(uint64_t packed) {
 75    return static_cast<uint8_t>(packed >> kDevicePriorityShift);
 76}
 77
 78ssize_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
 90ssize_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
103ssize_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
143ssize_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
184ssize_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
194ssize_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
206ssize_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
216ssize_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
228ssize_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
237ssize_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
246ssize_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
258ssize_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
270ssize_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
280ssize_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