1 /* 2 * Copyright (c) 2024 BayLibre SAS 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 /** 8 * @file msg.h 9 * @brief PTP messages definition. 10 * 11 * References are to version 2019 of IEEE 1588, ("PTP") 12 */ 13 14 #ifndef ZEPHYR_INCLUDE_PTP_MSG_H_ 15 #define ZEPHYR_INCLUDE_PTP_MSG_H_ 16 17 #include <stdbool.h> 18 19 #include <zephyr/kernel.h> 20 #include <zephyr/net/ethernet.h> 21 #include <zephyr/net/net_ip.h> 22 #include <zephyr/net/net_pkt.h> 23 #include <zephyr/net/ptp_time.h> 24 25 #include "ddt.h" 26 27 #ifdef __cplusplus 28 extern "C" { 29 #endif 30 31 /* values of the bits of the flagField array for PTP message */ 32 #define PTP_MSG_ALT_TIME_TRANSMITTER_FLAG BIT(0) 33 #define PTP_MSG_TWO_STEP_FLAG BIT(1) 34 #define PTP_MSG_UNICAST_FLAG BIT(2) 35 36 /** 37 * @brief PTP message type. 38 */ 39 enum ptp_msg_type { 40 /* PTP event message types */ 41 PTP_MSG_SYNC = 0, 42 PTP_MSG_DELAY_REQ, 43 PTP_MSG_PDELAY_REQ, 44 PTP_MSG_PDELAY_RESP, 45 /* General PTP message types */ 46 PTP_MSG_FOLLOW_UP = 8, 47 PTP_MSG_DELAY_RESP, 48 PTP_MSG_PDELAY_RESP_FOLLOW_UP, 49 PTP_MSG_ANNOUNCE, 50 PTP_MSG_SIGNALING, 51 PTP_MSG_MANAGEMENT, 52 }; 53 54 /** 55 * @brief Common PTP message header. 56 */ 57 struct ptp_header { 58 /** PTP message type and most significant 4 bytes of SdoId. */ 59 uint8_t type_major_sdo_id; 60 /** PTP version. */ 61 uint8_t version; 62 /** Number of bytes in the message. */ 63 uint16_t msg_length; 64 /** ID number of an instance in a domain. */ 65 uint8_t domain_number; 66 /** Minor SdoId. */ 67 uint8_t minor_sdo_id; 68 /** Array of message flags. */ 69 uint8_t flags[2]; 70 /** Value of correction in nanoseconds multiplied by 2^16. */ 71 int64_t correction; 72 /** @cond INTERNAL_HIDDEN */ 73 /** Padding. */ 74 uint32_t reserved; 75 /** @endcond */ 76 /** PTP Port ID of the sender. */ 77 struct ptp_port_id src_port_id; 78 /** unique ID number of the message. */ 79 uint16_t sequence_id; 80 /** @cond INTERNAL_HIDDEN */ 81 /** Obsolete, used for padding. */ 82 uint8_t control; 83 /** @endcond */ 84 /** Logarithm base of 2 of message interval. */ 85 int8_t log_msg_interval; 86 } __packed; 87 88 /** 89 * @brief PTP Announce message header. 90 */ 91 struct ptp_announce_msg { 92 /** PTP message header. */ 93 struct ptp_header hdr; 94 /** Estimate of the PTP Instance Time of an originating Instance 95 * when message was transmitted. 96 */ 97 struct ptp_timestamp origin_timestamp; 98 /** Value of @ref ptp_time_prop_ds.current_utc_offset . */ 99 uint16_t current_utc_offset; 100 /** @cond INTERNAL_HIDDEN */ 101 /** Padding. */ 102 uint8_t reserved; 103 /** @endcond */ 104 /** Value of @ref ptp_parent_ds.gm_priority1 of transmitter. */ 105 uint8_t gm_priority1; 106 /** Value of @ref ptp_parent_ds.gm_clk_quality of transmitter. */ 107 struct ptp_clk_quality gm_clk_quality; 108 /** Value of @ref ptp_parent_ds.gm_priority2 of transmitter. */ 109 uint8_t gm_priority2; 110 /** Value of @ref ptp_parent_ds.gm_id of transmitter. */ 111 ptp_clk_id gm_id; 112 /** Value of @ref ptp_current_ds.steps_rm of transmitter. */ 113 uint16_t steps_rm; 114 /** Time source of a clock of the sender. */ 115 uint8_t time_src; 116 /** Flexible array of zero or more TLV entities. */ 117 uint8_t suffix[]; 118 } __packed; 119 120 /** 121 * @brief PTP Sync message header. 122 */ 123 struct ptp_sync_msg { 124 /** PTP message header. */ 125 struct ptp_header hdr; 126 /** PTP Instance Time of an originating PTP Instance when message was transmitted. */ 127 struct ptp_timestamp origin_timestamp; 128 /** Flexible array of zero or more TLV entities. */ 129 uint8_t suffix[]; 130 } __packed; 131 132 /** 133 * @brief PTP Delay_Req message header. 134 */ 135 struct ptp_delay_req_msg { 136 /** PTP message header. */ 137 struct ptp_header hdr; 138 /** PTP Instance Time of an originating PTP Instance when message was transmitted. */ 139 struct ptp_timestamp origin_timestamp; 140 /** Flexible array of zero or more TLV entities. */ 141 uint8_t suffix[]; 142 } __packed; 143 144 /** 145 * @brief PTP Follow_Up message header. 146 */ 147 struct ptp_follow_up_msg { 148 /** PTP message header. */ 149 struct ptp_header hdr; 150 /** Precise timestamp of Sync message corresponding to that message. */ 151 struct ptp_timestamp precise_origin_timestamp; 152 /** Flexible array of zero or more TLV entities. */ 153 uint8_t suffix[]; 154 } __packed; 155 156 /** 157 * @brief PTP Delay_Resp message header. 158 */ 159 struct ptp_delay_resp_msg { 160 /** PTP message header. */ 161 struct ptp_header hdr; 162 /** Ingress timestamp of Delay_Req message. */ 163 struct ptp_timestamp receive_timestamp; 164 /** Port's ID of the sender of Delay_Req message. */ 165 struct ptp_port_id req_port_id; 166 /** Flexible array of zero or more TLV entities. */ 167 uint8_t suffix[]; 168 } __packed; 169 170 /** 171 * @brief PTP Pdelay_Req message header. 172 */ 173 struct ptp_pdelay_req_msg { 174 /** PTP message header. */ 175 struct ptp_header hdr; 176 /** PTP Instance Time of an originating PTP Instance when message was transmitted. */ 177 struct ptp_timestamp origin_timestamp; 178 /** @cond INTERNAL_HIDDEN */ 179 /** Padding. */ 180 struct ptp_port_id reserved; /* make it the same length as ptp_pdelay_resp */ 181 /** @endcond */ 182 /** Flexible array of zero or more TLV entities. */ 183 uint8_t suffix[]; 184 } __packed; 185 186 /** 187 * @brief PTP Pdelay_Resp message header. 188 */ 189 struct ptp_pdelay_resp_msg { 190 /** PTP message header. */ 191 struct ptp_header hdr; 192 /** Ingress timestamp of Pdelay_Req message. */ 193 struct ptp_timestamp req_receipt_timestamp; 194 /** Port's ID of the sender of Pdelay_Req message. */ 195 struct ptp_port_id req_port_id; 196 /** Flexible array of zero or more TLV entities. */ 197 uint8_t suffix[]; 198 } __packed; 199 200 /** 201 * @brief PTP Pdelay_Resp_Follow_Up message header. 202 */ 203 struct ptp_pdelay_resp_follow_up_msg { 204 /** PTP message header. */ 205 struct ptp_header hdr; 206 /** Precise timestamp of Pdelay_Resp message corresponding to that message. */ 207 struct ptp_timestamp resp_origin_timestamp; 208 /** Port's ID of the sender of Pdelay_Req message. */ 209 struct ptp_port_id req_port_id; 210 /** Flexible array of zero or more TLV entities. */ 211 uint8_t suffix[]; 212 } __packed; 213 214 /** 215 * @brief PTP Signaling message header. 216 */ 217 struct ptp_signaling_msg { 218 /** PTP message header. */ 219 struct ptp_header hdr; 220 /** Port's ID to which this message is addressed. */ 221 struct ptp_port_id target_port_id; 222 /** Flexible array of zero or more TLV entities. */ 223 uint8_t suffix[]; 224 } __packed; 225 226 /** 227 * @brief PTP Management message header. 228 */ 229 struct ptp_management_msg { 230 /** PTP message header. */ 231 struct ptp_header hdr; 232 /** Port's ID to which this message is addressed. */ 233 struct ptp_port_id target_port_id; 234 /** For response it should be computed from starting_boundary_hops and boundary_hops 235 * of the requesting message. 236 */ 237 uint8_t starting_boundary_hops; 238 /** Number of successive retransmissions of the message 239 * by Boundary Clocks receiving message. 240 */ 241 uint8_t boundary_hops; 242 /** Action to be taken on receipt of the message */ 243 uint8_t action:5; 244 /** @cond INTERNAL_HIDDEN */ 245 /** Padding. */ 246 uint8_t reserved; 247 /** @endcond */ 248 /** Flexible array of zero or more TLV entities. */ 249 uint8_t suffix[]; 250 } __packed; 251 252 /** 253 * @brief Generic PTP message structure. 254 */ 255 struct ptp_msg { 256 union { 257 /** General PTP message header. */ 258 struct ptp_header header; 259 /** Announce message. */ 260 struct ptp_announce_msg announce; 261 /** Sync message. */ 262 struct ptp_sync_msg sync; 263 /** Delay_Req message. */ 264 struct ptp_delay_req_msg delay_req; 265 /** Follow_Up message. */ 266 struct ptp_follow_up_msg follow_up; 267 /** Delay_Resp message. */ 268 struct ptp_delay_resp_msg delay_resp; 269 /** Pdelay_Req message. */ 270 struct ptp_pdelay_req_msg pdelay_req; 271 /** Pdelay_Resp message. */ 272 struct ptp_pdelay_resp_msg pdelay_resp; 273 /** Pdelay_Resp_Follow_Up message. */ 274 struct ptp_pdelay_resp_follow_up_msg pdelay_resp_follow_up; 275 /** Signaling message. */ 276 struct ptp_signaling_msg signaling; 277 /** Management message. */ 278 struct ptp_management_msg management; 279 /** @cond INTERNAL_HIDEN */ 280 /** MTU. */ 281 uint8_t mtu[NET_ETH_MTU]; 282 /** @endcond */ 283 } __packed; 284 struct { 285 /** 286 * Timestamp extracted from the message in a host binary format. 287 * Depending on the message type the value comes from different 288 * field of the message. 289 */ 290 struct net_ptp_time protocol; 291 /** Ingress timestamp on the host side. */ 292 struct net_ptp_time host; 293 294 } timestamp; 295 /** Reference counter. */ 296 atomic_t ref; 297 /** List object. */ 298 sys_snode_t node; 299 /** Single-linked list of TLVs attached to the message. */ 300 sys_slist_t tlvs; 301 /** Protocol address of the sender/receiver of the message. */ 302 struct sockaddr addr; 303 }; 304 305 /** 306 * @brief Function allocating space for a new PTP message. 307 * 308 * @return Pointer to the new PTP Message. 309 */ 310 struct ptp_msg *ptp_msg_alloc(void); 311 312 /** 313 * @brief Function removing reference to the PTP message. 314 * 315 * @note If the message is not referenced anywhere, the memory space is cleared. 316 * 317 * @param[in] msg Pointer to the PTP message. 318 */ 319 void ptp_msg_unref(struct ptp_msg *msg); 320 321 /** 322 * @brief Function incrementing reference count for the PTP message. 323 * 324 * @param[in] msg Pointer to the PTP message. 325 */ 326 void ptp_msg_ref(struct ptp_msg *msg); 327 328 /** 329 * @brief Function extracting message type from it. 330 * 331 * @param[in] msg Pointer to the message. 332 * 333 * @return Type of the message. 334 */ 335 enum ptp_msg_type ptp_msg_type(const struct ptp_msg *msg); 336 337 /** 338 * @brief Function extracting PTP message from network packet. 339 * 340 * @param[in] pkt Pointer to the network packet. 341 * 342 * @note Returned message has all data in the network byte order. 343 * 344 * @return Pointer to a PTP message. 345 */ 346 struct ptp_msg *ptp_msg_from_pkt(struct net_pkt *pkt); 347 348 /** 349 * @brief Function preparing message right before transmission. 350 * 351 * @param[in] msg Pointer to the prepared PTP message. 352 */ 353 void ptp_msg_pre_send(struct ptp_msg *msg); 354 355 /** 356 * @brief Function preparing message for further processing after reception. 357 * 358 * @param[in] port Pointer to the PTP Port instance. 359 * @param[in] msg Pointer to the received PTP message. 360 * @param[in] cnt Length of the message in bytes. 361 * 362 * @return 0 on success, negative otherwise. 363 */ 364 int ptp_msg_post_recv(struct ptp_port *port, struct ptp_msg *msg, int cnt); 365 366 /** 367 * @brief Function adding TLV of specified length to the message. 368 * 369 * @param[in] msg Pointer to the message that will have TLV added. 370 * @param[in] length Length of the TLV. 371 * 372 * @return Pointer to the TLV or NULL if there was no space to append TLV to the message. 373 */ 374 struct ptp_tlv *ptp_msg_add_tlv(struct ptp_msg *msg, int length); 375 376 /** 377 * @brief Function compering content of two PTP Announce messages. 378 * 379 * @param[in] m1 Pointer to the Announce message to be compared. 380 * @param[in] m2 Pointer to the Announce message to be compared. 381 * 382 * @return Negative if m1 < m2, 0 if equal, else positive 383 */ 384 int ptp_msg_announce_cmp(const struct ptp_announce_msg *m1, const struct ptp_announce_msg *m2); 385 386 /** 387 * @brief Function checking if given message comes from current PTP Port's 388 * TimeTransmitter PTP instance. 389 * 390 * @param[in] msg Pointer to the message. 391 * 392 * @return True if the message is received from the current PTP Port's TimeTransmitter, 393 * false otherwise. 394 */ 395 bool ptp_msg_current_parent(const struct ptp_msg *msg); 396 397 #ifdef __cplusplus 398 } 399 #endif 400 401 /** 402 * @} 403 */ 404 405 #endif /* ZEPHYR_INCLUDE_PTP_MSG_H_ */ 406