/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. * A service that exchanges time synchronization information between
  18. * a master that defines a timeline and clients that follow the timeline.
  19. */
  20. #define LOG_TAG "common_time"
  21. #include <utils/Log.h>
  22. #include <arpa/inet.h>
  23. #include <stdint.h>
  24. #include "common_time_server_packets.h"
  25. namespace android {
  26. const uint32_t TimeServicePacketHeader::kMagic =
  27. (static_cast<uint32_t>('c') << 24) |
  28. (static_cast<uint32_t>('c') << 16) |
  29. (static_cast<uint32_t>('l') << 8) |
  30. static_cast<uint32_t>('k');
  31. const uint16_t TimeServicePacketHeader::kCurVersion = 1;
  32. #define SERIALIZE_FIELD(field_name, type, converter) \
  33. do { \
  34. if ((offset + sizeof(field_name)) > length) \
  35. return -1; \
  36. *((type*)(data + offset)) = converter(field_name); \
  37. offset += sizeof(field_name); \
  38. } while (0)
  39. #define SERIALIZE_INT16(field_name) SERIALIZE_FIELD(field_name, int16_t, htons)
  40. #define SERIALIZE_INT32(field_name) SERIALIZE_FIELD(field_name, int32_t, htonl)
  41. #define SERIALIZE_INT64(field_name) SERIALIZE_FIELD(field_name, int64_t, htonq)
  42. #define DESERIALIZE_FIELD(field_name, type, converter) \
  43. do { \
  44. if ((offset + sizeof(field_name)) > length) \
  45. return -1; \
  46. field_name = converter(*((type*)(data + offset))); \
  47. offset += sizeof(field_name); \
  48. } while (0)
  49. #define DESERIALIZE_INT16(field_name) DESERIALIZE_FIELD(field_name, int16_t, ntohs)
  50. #define DESERIALIZE_INT32(field_name) DESERIALIZE_FIELD(field_name, int32_t, ntohl)
  51. #define DESERIALIZE_INT64(field_name) DESERIALIZE_FIELD(field_name, int64_t, ntohq)
  52. #define kDevicePriorityShift 56
  53. #define kDeviceIDMask ((static_cast<uint64_t>(1) << kDevicePriorityShift) - 1)
  54. inline uint64_t packDeviceID(uint64_t devID, uint8_t prio) {
  55. return (devID & kDeviceIDMask) |
  56. (static_cast<uint64_t>(prio) << kDevicePriorityShift);
  57. }
  58. inline uint64_t unpackDeviceID(uint64_t packed) {
  59. return (packed & kDeviceIDMask);
  60. }
  61. inline uint8_t unpackDevicePriority(uint64_t packed) {
  62. return static_cast<uint8_t>(packed >> kDevicePriorityShift);
  63. }
  64. ssize_t TimeServicePacketHeader::serializeHeader(uint8_t* data,
  65. uint32_t length) {
  66. ssize_t offset = 0;
  67. int16_t pktType = static_cast<int16_t>(packetType);
  68. SERIALIZE_INT32(magic);
  69. SERIALIZE_INT16(version);
  70. SERIALIZE_INT16(pktType);
  71. SERIALIZE_INT64(timelineID);
  72. SERIALIZE_INT64(syncGroupID);
  73. return offset;
  74. }
  75. ssize_t TimeServicePacketHeader::deserializeHeader(const uint8_t* data,
  76. uint32_t length) {
  77. ssize_t offset = 0;
  78. int16_t tmp;
  79. DESERIALIZE_INT32(magic);
  80. DESERIALIZE_INT16(version);
  81. DESERIALIZE_INT16(tmp);
  82. DESERIALIZE_INT64(timelineID);
  83. DESERIALIZE_INT64(syncGroupID);
  84. packetType = static_cast<TimeServicePacketType>(tmp);
  85. return offset;
  86. }
  87. ssize_t TimeServicePacketHeader::serializePacket(uint8_t* data,
  88. uint32_t length) {
  89. ssize_t ret, tmp;
  90. ret = serializeHeader(data, length);
  91. if (ret < 0)
  92. return ret;
  93. data += ret;
  94. length -= ret;
  95. switch (packetType) {
  96. case TIME_PACKET_WHO_IS_MASTER_REQUEST:
  97. tmp =((WhoIsMasterRequestPacket*)(this))->serializePacket(data,
  98. length);
  99. break;
  100. case TIME_PACKET_WHO_IS_MASTER_RESPONSE:
  101. tmp =((WhoIsMasterResponsePacket*)(this))->serializePacket(data,
  102. length);
  103. break;
  104. case TIME_PACKET_SYNC_REQUEST:
  105. tmp =((SyncRequestPacket*)(this))->serializePacket(data, length);
  106. break;
  107. case TIME_PACKET_SYNC_RESPONSE:
  108. tmp =((SyncResponsePacket*)(this))->serializePacket(data, length);
  109. break;
  110. case TIME_PACKET_MASTER_ANNOUNCEMENT:
  111. tmp =((MasterAnnouncementPacket*)(this))->serializePacket(data,
  112. length);
  113. break;
  114. default:
  115. return -1;
  116. }
  117. if (tmp < 0)
  118. return tmp;
  119. return ret + tmp;
  120. }
  121. ssize_t UniversalTimeServicePacket::deserializePacket(
  122. const uint8_t* data,
  123. uint32_t length,
  124. uint64_t expectedSyncGroupID) {
  125. ssize_t ret;
  126. TimeServicePacketHeader* header;
  127. if (length < 8)
  128. return -1;
  129. packetType = ntohs(*((uint16_t*)(data + 6)));
  130. switch (packetType) {
  131. case TIME_PACKET_WHO_IS_MASTER_REQUEST:
  132. ret = p.who_is_master_request.deserializePacket(data, length);
  133. header = &p.who_is_master_request;
  134. break;
  135. case TIME_PACKET_WHO_IS_MASTER_RESPONSE:
  136. ret = p.who_is_master_response.deserializePacket(data, length);
  137. header = &p.who_is_master_response;
  138. break;
  139. case TIME_PACKET_SYNC_REQUEST:
  140. ret = p.sync_request.deserializePacket(data, length);
  141. header = &p.sync_request;
  142. break;
  143. case TIME_PACKET_SYNC_RESPONSE:
  144. ret = p.sync_response.deserializePacket(data, length);
  145. header = &p.sync_response;
  146. break;
  147. case TIME_PACKET_MASTER_ANNOUNCEMENT:
  148. ret = p.master_announcement.deserializePacket(data, length);
  149. header = &p.master_announcement;
  150. break;
  151. default:
  152. return -1;
  153. }
  154. if ((ret >= 0) && !header->checkPacket(expectedSyncGroupID))
  155. ret = -1;
  156. return ret;
  157. }
  158. ssize_t WhoIsMasterRequestPacket::serializePacket(uint8_t* data,
  159. uint32_t length) {
  160. ssize_t offset = serializeHeader(data, length);
  161. if (offset > 0) {
  162. uint64_t packed = packDeviceID(senderDeviceID, senderDevicePriority);
  163. SERIALIZE_INT64(packed);
  164. }
  165. return offset;
  166. }
  167. ssize_t WhoIsMasterRequestPacket::deserializePacket(const uint8_t* data,
  168. uint32_t length) {
  169. ssize_t offset = deserializeHeader(data, length);
  170. if (offset > 0) {
  171. uint64_t packed;
  172. DESERIALIZE_INT64(packed);
  173. senderDeviceID = unpackDeviceID(packed);
  174. senderDevicePriority = unpackDevicePriority(packed);
  175. }
  176. return offset;
  177. }
  178. ssize_t WhoIsMasterResponsePacket::serializePacket(uint8_t* data,
  179. uint32_t length) {
  180. ssize_t offset = serializeHeader(data, length);
  181. if (offset > 0) {
  182. uint64_t packed = packDeviceID(deviceID, devicePriority);
  183. SERIALIZE_INT64(packed);
  184. }
  185. return offset;
  186. }
  187. ssize_t WhoIsMasterResponsePacket::deserializePacket(const uint8_t* data,
  188. uint32_t length) {
  189. ssize_t offset = deserializeHeader(data, length);
  190. if (offset > 0) {
  191. uint64_t packed;
  192. DESERIALIZE_INT64(packed);
  193. deviceID = unpackDeviceID(packed);
  194. devicePriority = unpackDevicePriority(packed);
  195. }
  196. return offset;
  197. }
  198. ssize_t SyncRequestPacket::serializePacket(uint8_t* data,
  199. uint32_t length) {
  200. ssize_t offset = serializeHeader(data, length);
  201. if (offset > 0) {
  202. SERIALIZE_INT64(clientTxLocalTime);
  203. }
  204. return offset;
  205. }
  206. ssize_t SyncRequestPacket::deserializePacket(const uint8_t* data,
  207. uint32_t length) {
  208. ssize_t offset = deserializeHeader(data, length);
  209. if (offset > 0) {
  210. DESERIALIZE_INT64(clientTxLocalTime);
  211. }
  212. return offset;
  213. }
  214. ssize_t SyncResponsePacket::serializePacket(uint8_t* data,
  215. uint32_t length) {
  216. ssize_t offset = serializeHeader(data, length);
  217. if (offset > 0) {
  218. SERIALIZE_INT64(clientTxLocalTime);
  219. SERIALIZE_INT64(masterRxCommonTime);
  220. SERIALIZE_INT64(masterTxCommonTime);
  221. SERIALIZE_INT32(nak);
  222. }
  223. return offset;
  224. }
  225. ssize_t SyncResponsePacket::deserializePacket(const uint8_t* data,
  226. uint32_t length) {
  227. ssize_t offset = deserializeHeader(data, length);
  228. if (offset > 0) {
  229. DESERIALIZE_INT64(clientTxLocalTime);
  230. DESERIALIZE_INT64(masterRxCommonTime);
  231. DESERIALIZE_INT64(masterTxCommonTime);
  232. DESERIALIZE_INT32(nak);
  233. }
  234. return offset;
  235. }
  236. ssize_t MasterAnnouncementPacket::serializePacket(uint8_t* data,
  237. uint32_t length) {
  238. ssize_t offset = serializeHeader(data, length);
  239. if (offset > 0) {
  240. uint64_t packed = packDeviceID(deviceID, devicePriority);
  241. SERIALIZE_INT64(packed);
  242. }
  243. return offset;
  244. }
  245. ssize_t MasterAnnouncementPacket::deserializePacket(const uint8_t* data,
  246. uint32_t length) {
  247. ssize_t offset = deserializeHeader(data, length);
  248. if (offset > 0) {
  249. uint64_t packed;
  250. DESERIALIZE_INT64(packed);
  251. deviceID = unpackDeviceID(packed);
  252. devicePriority = unpackDevicePriority(packed);
  253. }
  254. return offset;
  255. }
  256. } // namespace android